npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

odata-client

v0.8.0

Published

odata client

Downloads

8,525

Readme

odata-client

A client library for accessing odata resources using node. HTTP queries return a promise.

Installation

npm install odata-client

Usage

const odata = require('odata-client');
var q = odata({service: 'https://example.com', resources: 'Customers'});
q.top(5).skip(10).filter('Balance gt 5000').and('CreditLimit', '<', 10000).get()
.then(function(response) {
  ...
});

** Note on the request library **

As the request library is now deprecated, this project has switched to using got. However, request is listed as a peer dependency and odata-client will use request in preference to got if it's found.

odata object

  • odata(config)

The odata(config) function produces a query object for the construction of queries. config is an object with the following options:

  1. service - the base URL of the service

  2. resources - the resource part of the URL for the query, e.g. Customers or Customers('ACME01')/Orders. You can also add resource parts using the resource method of the query function

  3. custom - optional object containing addition query parameters, e.g. {access_token:'123456'} will append ?access_token=123456 to the query URL.

  4. version - set OData-Version HTTP header

  5. maxVersion - set OData-MaxVersion HTTP header

  6. format - specify response format (e.g. json)

  • expression(left, op, right)

Used to produce subexpressions in a filter. For example, q.filter('CreditBalance', '>', odata.expression('OrderValue', '+', 100)) produces $filter=CreditBalance gt (OrderValue add 100). The arguments are the same as for q.filter, see below.

Expressions can be chained, eg

expression('Balance', '>', 500').and('CreditLimit', '=', 0) // (Balance gt 500) and (CreditLimit eq 0)
expression('Balance', '+', 1000).lt('CreditLimit') // (Balance add 1000) lt (CreditLimit)
  • identifier(string)
  • literal(string)
  • exact(string)

In a filter expression part, the left argument is normally treated as an identifier (i.e., if it's a string it isn't surrounded by quotes) whereas the right argument is assumed to be a literal (strings are surrounded by quotes). These methods allow you to override this. e.g.

q.filter(odata.literal('Customer'), '=', odata.identifer('Type')) // $filter='Customer' eq Type

exact allows you to place the string in the query exactly as intended.

  • type(type, value)

Allows prefixing the value with a type name, such as an enum. e.g.

q.filter('DurationValue', odata.type('duration', 'P10D')) // $filter=DurationValue eq duration'P10D'
  • fn(name, args)

A fn method produces a function for use in a filter or expression. name is the name of the function while args is an object with the objwct keys being the parameter names. e.g.

q.filter(odata.fn('SalesRegion', { City: odata.identifier('$it/City') }), '=', 'West'); // $filter=SalesRegion(City=$it/City) eq 'West'

query object

The query object has the following methods:

  • resource(resource, value)

Adds a new part to the resource section. e.g.

odata({service: 'https://example.com'}).resource('Customers').resource('Orders'); // https://example.com/Customers/Orders
odata({service: 'https://example.com'}).resource('Customers', 'ACME01').resource('Orders'); // https://example.com/Customers('ACME01')/Orders
odata({service: 'https://example.com'}).resource('Customers', {account:'ACME01'}).resource('Orders'); // https://example.com/Customers(account='ACME01')/Orders
  • fn(name, args)

Add a function component to the resource section. name is the name of the function whereas args is an object with the keys being the parameter names. e.g.

odata({service: 'https://example.com'}).fn('Customer', { Account: 'ACME01' }); // https://example.com/Customer(Account='ACME01')
  • top(n)

Adds a $top=n query parameter.

  • skip(n)

Adds a $skip=n query parameter.

  • filter(left, op, right)

Used for constructing $filter requests. There are several ways to call this method:

  1. If called with a string as the sole argument, the string is used as a literal filter, e.g. q.filter("Account eq 'ACME01'")

  2. If all three arguments are specified, op should be one of the usual odata operations such as eq or add, or the symbolic equivalents such as = or +. e.g. q.filter('Account', '=', 'ACME01'). The left and right arguments can be odata.expressions for building nested queries.

  3. If called with two arguments, the operator is assumed to be eq, e.g. q.filter('Account', 'ACME01')

  4. If called with an array of expressions as the first argument, and the expressions together. e.g.

q.filter([ Odata.expression('key1', 'abc'), Odata.expression('key2', 'def') ])

or, as a shortcut,

q.filter([['key1', 'abc'], ['key2', 'def']])

The left argument is assumed to be an identifier while right is assumed to be a literal, which affects the quoting of strings. You can override this behaviour with the odata.literal and odata.identifier functions, see above.

If two or more filters are chained, they are anded together. q.filter('Balance gt 1000').filter('Status', 'stop') profduces $filter=(Balance gt 1000) and (Status eq 'stop').

  • and(left, op, right)

Synonym for filter.

  • or(left, op, right)

Adds an or clause to the filter being built. If called with an array of expressions, or the expressions together. For example

q.or([ Odata.expression('key1', 'abc'), Odata.expression('key2', 'def') ])

or, as a shortcut,

q.or([['key1', 'abc'], ['key2', 'def']])

You can also pass an array of objects:

q.or([{ key1: 'abc', key2: '123' }, { key1: 'def', key2: '456' }]) // (key1 eq 'abc' and key2 eq '123') or (key1 eq 'def' and key2 eq 456)
  • not(left, op, right)

Adds a not clause to the filter

  • all(field, property, op, value)

Adds an all filter, e.g.

q.all('Orders', 'Value', '<', 50) // ?$filter=Orders/all(p0:p0/Value lt 50)
  • any(field, property, op, value)

Adds an any filter, e.g.

q.any('Orders', 'Lines/$count', '>=', 10) // ?$filter=Orders/any(p0:p0/Lines/$count ge 10)
  • select(items)

Adds a $select clause to the filter, e.g. q.select('Account', 'Status') produces $select=Account,Status.

  • expand(item)

Adds an item to $expand

  • search(term)

Sets the term for $search.

  • count(param)

Adds a $count clause to the query. If param is true, adds the count clause as a query parameter instead of a pth component (#14)

  • orderby(item, dir)

Adds an $orderby clause to the query. There are several ways to call this function:

  1. q.orderby('Account') produces $orderby=Account

  2. q.orderby('Account', 'desc') produces $orderby=Account desc

  3. q.orderby(['Status', 'desc'], ['Account']) produces $orderby=Status desc,Account

  • custom(name, value)

Adds custom query prameters to the query using either a pair of parameters or an object, e.q.

q.custom('access_token', '123456') // ?access_token=123456
q.custom({access_token: '123456', version: '1.2'}) // ?access_token=123456&version=1.2
  • query

Produces the query string, e.g.

odata({service: 'https://example.com/Customers'}).top(5).query() // 'https://example.com/Customers?$top=5'
  • get(options)
  • post(body, options)
  • put(body, options)
  • patch(body, options)
  • merge(body, options)
  • delete(options)

Perform an HTTP operation. For non-batched queries, these will return a promise which resolves to an HTTP response. The options argument is passed to the underlying got (or request) library.

For batched queries, requests are accumulated into a single document which is sent with the send function.

As a convenience when using batch functions, the content_id property of options is copied to the Content-ID header, e.g.

q.batch()...get({content_id: 1})
  • batch

Sets up batch processing. When batch processing is enabled and an HTTP request function is called, instead of being sent immediately the request is held in a queue. When the send function is called, all the requests are sent in one document.

The code

q.resource('Customers', 'ACME01').batch();
q.resource('Orders', 1).get();
q.resource('Orders', 2).get();
q.send();

will batch the queries /Customers('ACME01')/Orders(1) and /Customers('ACME01')/Orders(2) into one and send them as one document.

  • send

Will send a batched query, returning a promise that resolves to an HTTP response.