Giter Site home page Giter Site logo

node-odata-parser's Introduction

OData query string parser for node.js based on pegjs.

Build Status

Installation

npm install odata-parser

Usage

var parser = require("odata-parser");

var ast = parser.parse("$top=10&$skip=5&$select=foo")

util.inspect(ast)

will result in:

{
  '$top': 10,
  '$skip': 5,
  '$select': [ 'foo' ]
}

Filters like:

parser.parse("$filter=Name eq 'John' and LastName lt 'Doe'")

results in:

{
    $filter: {
        type: 'and',
        left: {
            type: 'eq',
            left: {
                type: 'property',
                name: 'Name'
            },
            right: {
                type: 'literal',
                value: 'John'
            }
        },
        right: {
            type: 'lt',
            left: {
                type: 'property',
                name: 'LastName'
            },
            right: {
                type: 'literal',
                value: 'Doe'
            }
        }
    }
}

Using functions in filters

parser.parse("$filter=substringof('nginx', Servers)")

restuls in:

{
    $filter: {
        type: 'functioncall',
        func: 'substringof',
        args: [{
            type: 'literal',
            value: 'nginx'
        }, {
            type: 'property',
            name: 'Servers'
        }]
    }
}

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.

node-odata-parser's People

Contributors

andozw avatar jayprakash1 avatar jdiamond avatar jfromaniello avatar korvent avatar mnahkies avatar molipet avatar ntotten avatar prantlf avatar stanislavklenin avatar utamas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-odata-parser's Issues

$filter parsing throws error for some filters

I wrote a little script to generate the ast for all of the sample $filter strings from chapter 4.5 of http://www.odata.org/documentation/odata-version-2-0/uri-conventions/#. When running the script I get errors for some of the filters, e.g. $filter=Price add 5 gt 10

odata-parser.js:5341
        throw new this.SyntaxError(
        ^
SyntaxError: Expected "and" or "or" but "g" found.

Have a look at the commented lines of the attached script for all erroneous filters.

Regards Helmut
index.js.txt

ignore non-odata parameters

var parser = require("odata-parser");
var ast = parser.parse("myparam=3&$top=10&$skip=5&$select=foo")
console.log(ast)

SyntaxError: Expected "$", "$callback=", "$expand=", "$filter=", "$format=", "$inlinecount=", "$orderby=", "$select=", "$skip=" or "$top=" but "m" found.

Indeed sending non-odata parameters could be as a no-no and non conforming to the standard, but I think if you could add a "strict:true/false" parameter when parsing might work towards making it more flexible.

DateTimeOffset (odata 4.0) filter raises error: expects single quotes

Hi,

There seem to be a discrepancy between your parser expectation for DateTimeOffset type and the oData 4.0 specification:

Example oData 4.0 url: $filter=UPD_DATE gt 2015-08-22T19:27:13Z. This raises an error in your parser. Could this be corrected?

Thanks in advance.

How to handle complex or and ands

Is it possible to handle a case where we need to handle complex or and and filters as the filter below?

$filter=Name eq 'John' and LastName eq 'Doe' or MiddleName eq 'mdle' and emailAddress eq '[email protected]'

Here I am trying to do the following

select * from sometable where Name='John' and (LastName='Doe' or MiddleName='mdle') and emailAddress='[email protected]'

Readme Errors

I noticed two things about README.md:

  • the second 'results' is a typo as 'restuls'
  • the Author link is broken

I'm new to GitHub and if possible would like to be added as a collaborator so that I could create the branch/pull request to fix this. It'd be a learning experience for me and would count towards #hacktoberfest for me!


Just learned I can make the PR via forking

Singles not parsing correctly

Hey guys,

Floats/Singles are being parsed as strings and this is causing me issues. I need to move on for now so when I come back to this if there isn't a fix I will look to patch it and PR.

There is no test case for this in the unit tests...

Thanks,
Mark

contains filter option is not supported

For openUI5 usage is would be really helpful if contains filter option will be added. it could be the same as substringof but with 8 characters long. thank you

Ordering of properties in $orderby is lost.

Since $orderby is parsed into an object, the ordering of the properties to order by is lost. Would it be OK to change this to use an array instead of an object?

This would be break compatibility with anybody currently expecting an object. =(

Bug in $format Parsing

I noticed that if the $format parameter is present, it doesn't respect any potential following parameters:

console.log(oData.parse('$select=foo,bar&$top=10&$format=application/json&$skip=42'));

{
  '$select': [ 'foo', 'bar ],
  '$top': 10,
  '$format': 'application/json&$skip=42'
}

However, if I move $skip to precede $format everything is parsed as expected:

console.log(oData.parse('$select=foo,bar&$top=10&$skip=42&$format=application/json'));

{
  '$select': [ 'foo', 'bar', 'baz' ],
  '$top': 10,
  '$skip': 42,
  '$format': 'application/json'
}

Numbers

There seem to be some issues in your parsing of numbers. It appears your logic to determine types fails particularly on bytes. You may want to take a look at the spec for abstract types at http://www.odata.org/documentation/overview/#AbstractTypeSystem. You will probably have to reorder your logic for detection.

For example. $filter=Field1 eq 9999 captures 999 as a byte when its not. The format for bytes is 2 characters [A-Fa-f0-9]+ so this results in a failure for the call.

Error when trying to reference a sub-object

I have this JSON:

{
"test": "123",
"object": { "subobject": "567", "another": "xyz"}
}

trying to get:

{
"object": {"subobject": "567"}
}

My query is: '$select=object.subobject'

But parser.parse('$select=object.subobject') gives me the following error: [TypeError: Object subobject has no method 'unshift'].

Any suggestion for how/where I can fix it?

SyntaxError when trying to order by child

Using an order by where I'd like to sort on a child will result in a syntax error.

For example:
?$orderby=Rating,Category/Name desc

Will result in:

{ [SyntaxError: Expected " ", "&", ",", "." or [a-zA-Z0-9\-_] but "/" found.]
  name: 'SyntaxError',
  expected: [ '" "', '"&"', '","', '"."', '[a-zA-Z0-9\\-_]' ],
  found: '/',
  message: 'Expected " ", "&", ",", "." or [a-zA-Z0-9\\-_] but "/" found.',
  offset: 33,
  line: 1,
  column: 34 }

It's however specified as being valid according to these docs:
http://www.odata.org/documentation/odata-version-2-0/uri-conventions/

Support for enums?

Is there support for parsing fully qualified enums for odata $filter with this pegjs code?
Seems not.
odata v4 syntax is:
$filter=enumAttribute eq ''

qualifiedEnumTypeName = namespace "." enumerationTypeName

example:
messageType eq XCommunicator.Messaging.MessageTypeEnum'Mail'

value inside SQUOTE's probably needs to support multiple values separated with COMMA as well.

Parse URL path according to the OData specification too

Breaking the path into resources and predicates would be helpful too when processing the OData URL, because hre can be expressions inside the path. For example, /Customers(123)/ContactName could be parsed into a JSON object with a schema similar to the query parsing output:

[
  {
    "name": "Customers",
    "predicates": [
      {
        "type": "literal",
        "value": 123
      }
    ]
  },
  {
    "name": "ContactName"
  }
]

Another example for /Orders(CustomerID=123,Pending=true) could be:

[
  {
    "name": "Orders",
    "predicates": [
      {
        "type": "property",
        "name": "CustomerID",
        "value": 123
      },
      {
        "type": "property",
        "name": "Pending",
        "value": true
      }
    ]
  }
]

There could be either a separate parsing function for the path, or the current odata-parser module could support both; the path with an optional query or the query alone.

I tried the former in the parse-path-separate branch with the extended interface in lib/index.js:

module.exports = {
  parse: require('./odata-parser').parse,
  parsePath: require('./odata-path-parser').parse
};

I could not find a real advantage of having handling the two URL parts separated. A disadvantage was duplicating a big part of the PEG grammar in the URL path handling file. Parsing can handle all three possibilities (path, path + query, query) with a simpler interface (just a single parse method) and the only challenge is how to return the path without breaking the current interface. I tried adding a new key - $path - to the output map in the parse-path-integrated branch; it is not a reserved OData field and the parse method has a common result schema:

{
  "$path": [
    // array of resources from the first and second samples above
  ],
  "$select": [
    "Name"
  ],
  ...
}

What do you think? Thanks!

Bug in $format Parsing

I noticed that if the $format parameter is present, it doesn't respect any potential following parameters:

console.log(oData.parse('$select=foo,bar&$top=10&$format=application/json&$skip=42'));

{
  '$select': [ 'foo', 'bar' ],
  '$top': 10,
  '$format': 'application/json&$skip=42'
}

Note how $skip is not parsed and is instead concatenated to $format.

However, if I move $skip to precede $format everything is parsed as expected:

console.log(oData.parse('$select=foo,bar&$top=10&$skip=42&$format=application/json'));

{
  '$select': [ 'foo', 'bar' ],
  '$top': 10,
  '$skip': 42,
  '$format': 'application/json'
}

Brackets

Consider following queries:
$filter=name eq 'John' or name lt 'Doe' and address gt 'x1234'
$filter=(name eq 'John' or name lt 'Doe') and name gt 'x1234'
AST for these queries is the same.

{
    "type": "or",
    "left": {
        "type": "eq",
        "left": {
            "type": "property",
            "name": "name"
        },
        "right": {
            "type": "literal",
            "value": "John"
        }
    },
    "right": {
        "type": "and",
        "left": {
            "type": "lt",
            "left": {
                "type": "property",
                "name": "name"
            },
            "right": {
                "type": "literal",
                "value": "Doe"
            }
        },
        "right": {
            "type": "gt",
            "left": {
                "type": "property",
                "name": "address"
            },
            "right": {
                "type": "literal",
                "value": "x1234"
            }
        }
    }
}

OData parsed to SQL sentence

Hi there,

I'm looking for a solution, idea or even a component to convert OData query (mainly the filter part) into SQL sentence.

parser.parse("$filter=Name eq 'John' and LastName lt 'Doe'") would end-up with a WHERE close such as WHERE( Name='John' AND LastName='Doe')

tnx

pegjs ENOENT

Hello,

When installing node-odata-parser pegjs is used in preinstall script but fails with a ENOENT error. Maybe because it is defined as a dev dep ? Anyway builds are broken.

Is it really necessary to have it both at prepublish and preinstall steps ?

Arithmetic Operators (Feature Request or Bug)

Hi,

I saw arithmetic operators in source code. However I cannot understand how to use. When I use the example below from http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398108

$filter=Price add 2.45 eq 5.00

I got:

SyntaxError: Expected "and" or "or" but "e" found.

I'm not sure is it a bug or is not supported in node-odata-parser. If it is not supported, could you please add this feature.

Best Rehards,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.