0.0.10 • Published 2 years ago

@dichioniccolo/odata-filter-parser v0.0.10

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

OData Filter Parser

This library parses an odata complaint string and returns an object.

Installation

Installation with npm

npm i @dichioniccolo/odata-filter-parser

Installation with yarn

yarn add @dichioniccolo/odata-filter-parser

Usage

import { parse } from '@dichioniccolo/odata-filter-parser'

const filter = "contains(a/b,'c') and contains(d/e, 'f') and g eq 1 and h eq false";

const parsed = parse(filter);

/*
The result will be an object like this:
{
  a: { b: { contains: "c" } },
  d: { e: { contains: "f" } },
  g: { equals: 1 },
  h: { equals: false },
}
*/
console.log(parsed);

Custom parsers can also be used. They will have precedence over builtin ones. Every custom parser should extend from the Parser class provided by the package

import { parse, Parser, Operators } from '@dichioniccolo/odata-filter-parser'

class DateParser extends Parser {
  // This is an example regex. A good regex would also check for the date based on the month.
  static DATE_REGEX =
    /(.*) (eq) ((19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])T\d{2}:\d{2}:\d{2}.\d{3}Z)/;

  constructor(protected value: string) {
    super(value, "");
  }

  static isOfType(value: string): boolean {
    return !!value.match(DateParser.DATE_REGEX);
  }

  parse(previous: unknown): Record<string, any> {
    const match = this.value.match(DateParser.DATE_REGEX);

    if (!match) {
      return {};
    }

    const [, left, operator, right] = match;

    const methods = [Operators.GREATER_THAN_EQUAL, Operators.LESS_THAN_EQUAL];
    const values = [right, `${right.substring(0, 10)}T23:59:59.999Z`];

    return this.setDeepValue(previous, this.leftValue(left), methods, values);
  }

  setDeepValue(
    obj: any,
    [prop, ...path]: Array<string>,
    methods: string[],
    values: string[]
  ) {
    if (!path.length) {
      methods.forEach((method, index) => {
        obj[prop] = {
          ...obj[prop],
          [method]: values[index],
        };
      });
    } else {
      if (!(prop in obj)) {
        obj[prop] = {};
      }

      this.setDeepValue(obj[prop], path, methods, values);
    }

    return obj;
  }
}

const filter = "createdAt eq 2021-11-29T00:00:00.000Z and contains(a,'string')";

const parsed = parse(filter, { DateParser });

/*
The result will be an object like this:
{
  createdAt: {
    gte: '2021-11-29T00:00:00.000Z',
    lte: '2021-11-29T23:59:59.999Z',
  },
  a: {
    contains: 'string'
  }
}
*/
console.log(parsed);

Roadmap

[] Add all available operators

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago