/scim2-parse-filter

RFC7643 SCIM(System for Cross-domain Identity Management) 2.0 filter parser.

Primary LanguageTypeScriptThe UnlicenseUnlicense

scim2-parse-filter

npm version Build Status Downloads

RFC7643 SCIM(System for Cross-domain Identity Management) 2.0 filter parser. see section 3.4.2.2. Filtering.

This implements filter syntax parser and json filter function.

This is a fork https://www.npmjs.com/package/scim2-filter version 0.2.0 with bug correction.

usage

parse

You can parse filter query and get ast.

import {parse} from 'scim2-parse-filter';

const f = parse(`userType eq "Employee" and emails[type eq "work" and value co "@example.com"]`);
assert.deepEqual(f, {
  op:"and",
  filters:[
    {
      op:"eq",
      attrPath:"userType",
      compValue:"Employee"
    },
    {
      op:"[]",
      attrPath:"emails",
      valFilter:{
        op:"and",
        filters:[
          {
            op:"eq",
            attrPath:"type",
            compValue:"work"
          },
          {
            op:"co",
            attrPath:"value",
            compValue:"@example.com"
          }
        ]
      }
    }
  ]
});

filter

and You can use filter in json.

import {parse, filter} from 'scim2-parse-filter';

const f = filter(parse(`userName eq "test1@example.com"`));
const users = [
  { userName: "test1@example.com" },
  { userName: "test2@example.com" }
];
const ret = users.filter(f);
assert.deepEqual(ret, [users[0]]);

stringify

and you can convert an AST back into a SCIM query.

import { Filter, stringify } from 'scim2-parse-filter';

const ast: Filter = {
  op:"and",
  filters:[
    {
      op:"eq",
      attrPath:"userType",
      compValue:"Employee"
    },
    {
      op:"[]",
      attrPath:"emails",
      valFilter:{
        op:"and",
        filters:[
          {
            op:"eq",
            attrPath:"type",
            compValue:"work"
          },
          {
            op:"co",
            attrPath:"value",
            compValue:"@example.com"
          }
        ]
      }
    }
  ]
};

assert.deepEqual(stringify(ast), 'userType eq "Employee" and emails[type eq "work" and value co "@example.com"]');

expand

and you can expand an AST's and and [] nodes.

const f = parse(`userType eq "Employee" and emails[type eq "work" or value co "@example.com"]`);

assert.deepEqual(expand(f), {
  op:"or",
  filters:[
    {
      op: "and",
      filters: [
        {
          op:"eq",
          attrPath:"userType",
          compValue:"Employee"
        },
        {
          op:"eq",
          attrPath:"emails.type",
          compValue:"work"
        },
      ]
    },
    {
      op: "and",
      filters: [
        {
          op:"eq",
          attrPath:"userType",
          compValue:"Employee"
        },
        {
          op:"co",
          attrPath:"emails.value",
          compValue:"@example.com"
        }
    ]
    }
  ]
});

flatten

and you can flatten an AST's nodes.

const f = parse(
  `userType eq "Employee" and (userName eq "bob" and email ew "@example.com")`
);

assert.deepEqual(flatten(f), {
  op: "and",
  filters: [
    {
      op: "eq",
      attrPath: "userType",
      compValue: "Employee",
    },
    {
      op: "eq",
      attrPath: "userName",
      compValue: "bob",
    },
    {
      op: "ew",
      attrPath: "email",
      compValue: "@example.com",
    },
  ],
});