UNPKG

odata-client

Version:
475 lines (442 loc) 11.2 kB
'use strict'; const Expression = require('./expression'); const _ = require('lodash'); const Promise = require('bluebird'); const escape = require('./escape'); const Identifier = require('./identifier'); const Literal = require('./literal'); const request = require('./request'); const Lambda = require('./lambda'); const Url = require('./url'); var Odata = function(config) { this.config = config || {}; this.url = new Url(this.config.service || ''); if(config.resources) { this.url.addPathComponent(config.resources); } if(config.custom) { this.url.addQueryParameter(config.custom); } this._headers = config.headers || {}; this._nextLambda = 0; if(config.version) { this._headers['OData-Version'] = config.version; } if(config.maxVersion) { this._headers['OData-MaxVersion'] = config.maxVersion; } return this; }; Odata.prototype.top = function(top) { this.addQueryParameter('$top', top); return this; }; Odata.prototype.skip = function(skip) { this.addQueryParameter('$skip', skip); return this; }; Odata.prototype.filter = function(field, op, value) { if(this._batch) { this._batch.filter(field, op, value); } else { let E; if(field instanceof Array) { E = new Expression(); E.and(field); } else if(field instanceof Expression && op === undefined && value === undefined) { E = field; } else { E = new Expression(field, op, value); } if(E.exp) { if(this._filter) { this._filter = this._filter.and(E); } else { this._filter = E; } } } return this; }; Odata.prototype.and = function(field, op, value) { return this.filter(field, op, value); }; Odata.prototype.or = function(field, op, value) { if(this._batch) { this._batch.or(field, op, value); } else { let E; if(field instanceof Array) { E = new Expression(); E.or(field); } else if(field instanceof Expression && op === undefined && value === undefined) { E = field; } else { E = new Expression(field, op, value); } if(E.exp) { if(this._filter) { this._filter = this._filter.or(E); } else { this._filter = E; } } } return this; }; Odata.prototype.not = function(field, op, value) { if(this._batch) { this._batch.not(field, op, value); return this; } return this.filter(`not ${new Expression(field, op, value).toString()}`); }; Odata.prototype.all = function(field, property, op, value) { if(this._batch) { this._batch.all(field, property, op, value); return this; } return this.filter(new Lambda('all', field, `p${this._nextLambda++}`, property), op, value); }; Odata.prototype.any = function(field, property, op, value) { if(this._batch) { this._batch.any(field, property, op, value); return this; } return this.filter(new Lambda('any', field, `p${this._nextLambda++}`, property), op, value); }; Odata.prototype.resource = function(resource, value) { if(this._batch) { this._batch.resource(resource, value); return this; } var component = resource; if(value !== undefined) { if(_.isPlainObject(value)) { var clauses = _.map(_.keys(value), function(k) { return `${escape(k, true)}=${escape(value[k])}`; }); component += `(${encodeURIComponent(clauses.join())})`; } else { component += `(${encodeURIComponent(escape(value))})`; } } this.addPathComponent(component); return this; }; Odata.prototype.fn = function(name, args) { if(this._batch) { this._batch.fn(name, args); return this; } this.addPathComponent(encodeURIComponent(`${name}(${_.join(_.map(args || {}, (v, k) => { return `${k}=${escape(v)}`; }))})`)); return this; } Odata.prototype.select = function(items) { if(this._batch) { if(_.isArray(items)) { this._batch.select(items); } else { this._batch.select(Array.prototype.slice.call(arguments)); } return this; } this._select = this._select || []; if(_.isArray(items)) { Array.prototype.push.apply(this._select, items); } else { Array.prototype.push.apply(this._select, arguments); } return this; }; Odata.prototype.count = function(param) { if(this._batch) { this._batch.count(param); return this; } this._count = param?'param':true; return this; }; Odata.prototype.orderby = function(item, dir) { if(this._batch) { this._batch.orderby(item, dir); return this; } var self = this; this._order = this._order || ''; var add = function(item, dir) { if(self._order !== '') { self._order += ','; } if(dir === undefined) { self._order += `${escape(item, true)}`; } else { if(!dir || dir.toString().toLowerCase() === 'desc') { dir = 'desc'; } else { dir = 'asc'; } self._order += `${escape(item, true)} ${dir}`; } } if(_.isArray(item)) { for(let i = 0; i < arguments.length; i++) { let arg = arguments[i]; if(_.isArray(arg)) { if(arg.length >= 2) { add(arg[0], arg[1]); } else { add(arg[0]); } } else { add(arg); } } } else { add(item, dir); } return this; }; Odata.prototype.expand = function(item) { if(this._batch) { this._batch.expand(item); return this; } this._expand = this._expand || []; if(_.isArray(item)) { Array.prototype.push.apply(this._expand, item); } else { Array.prototype.push.apply(this._expand, arguments); } return this; }; Odata.prototype.search = function(search) { if(this._batch) { return this._batch.search(search); return this; } this._search = search; return this; }; Odata.prototype.custom = function(name, value) { this.addQueryParameter(name, value); return this; }; Odata.prototype.addPathComponent = function(component) { if(this._batch) { this._batch.addPathComponent(component); } else { this.url.addPathComponent(component); } return; }; Odata.prototype.addQueryParameter = function(name, value) { if(this._batch) { this._batch.addQueryParameter(name, value); } else { this.url.addQueryParameter(name, value); } return; }; Odata.prototype.batch = function() { this._batch = new require('./batch')(this); return this; }; Odata.prototype.query = function() { if(this._count) { if(this._count === 'param') { this.addQueryParameter('$count', 'true'); } else { this.addPathComponent('%24count'); } } if((this.config && this.config.format) !== undefined && this._count === undefined) { this.addQueryParameter('$format', this.config.format); } if(this._filter !== undefined) { this.addQueryParameter('$filter', this._filter.toString()); } if(this._select) { this.addQueryParameter('$select', _.map(this._select, function(item) { return escape(item, true); }).join()); } if(this._expand) { this.addQueryParameter('$expand', _.map(this._expand, function(item) { return escape(item, true); }).join()); } if(this._search) { this.addQueryParameter('$search', this._search); } if(this._order !== undefined) { this.addQueryParameter('$orderby', this._order); } return this.url.get(); }; Odata.prototype.get = function(options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.get(options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); options.method = 'GET'; return request(options); }; Odata.prototype.post = function(body, options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.post(body, options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); if(_.isPlainObject(body)) { options.body = JSON.stringify(body); options.headers['Content-Type'] = 'application/json'; } else { options.body = body; } options.method = 'POST'; return request(options); }; Odata.prototype.put = function(body, options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.put(body, options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); if(_.isPlainObject(body)) { options.body = JSON.stringify(body); options.headers['Content-Type'] = 'application/json'; } else { options.body = body; } options.method = 'PUT'; return request(options); }; Odata.prototype.patch = function(body, options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.patch(body, options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); if(_.isPlainObject(body)) { options.body = JSON.stringify(body); options.headers['Content-Type'] = 'application/json'; } else { options.body = body; } options.method = 'PATCH'; return request(options); }; Odata.prototype.merge = function(body, options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.merge(body, options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); if(_.isPlainObject(body)) { options.body = JSON.stringify(body); options.headers['Content-Type'] = 'application/json'; } else { options.body = body; } options.method = 'MERGE'; return request(options); }; Odata.prototype.delete = function(options) { options = options || {}; options.headers = options.headers || {}; if(options.content_id) { options.headers['Content-ID'] = options.content_id; } if(this._batch) { this._batch.delete(options); return this; } options.url = this.query(); options.headers = _.assign({}, this._headers, options.headers); options.method = 'DELETE'; return request(options); }; Odata.prototype.body = function() { if(this._batch) { return this._batch.body().toString(); } return ''; }; Odata.prototype.send = function() { if(!this._batch) { return this; } var u = this.url.clone(); u.addPathComponent('%24batch'); var options = { url: u.get(), headers: _.assign({}, this._headers, {'Content-Type': `multipart/mixed; boundary=${this._batch.boundary}`}), body: this._batch.body() }; options.method = 'POST' return request(options); }; module.exports = Odata;