UNPKG

ts-odatajs

Version:

The Olingo OData Client for JavaScript (and TypeScript) is a new cross-browser library that enables data-centric web applications by leveraging modern protocols such as JSON and OData and HTML5-enabled browser features. It's designed to be small, fast and

206 lines (180 loc) 7.26 kB
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ 'use strict'; /** @module cache/source */ var utils = require("./../utils.js"); var odataRequest = require("./../odata.js"); var parseInt10 = utils.parseInt10; var normalizeURICase = utils.normalizeURICase; /** Appends the specified escaped query option to the specified URI. * @param {String} uri - URI to append option to. * @param {String} queryOption - Escaped query option to append. */ function appendQueryOption(uri, queryOption) { var separator = (uri.indexOf("?") >= 0) ? "&" : "?"; return uri + separator + queryOption; } /** Appends the specified segment to the given URI. * @param {String} uri - URI to append a segment to. * @param {String} segment - Segment to append. * @returns {String} The original URI with a new segment appended. */ function appendSegment(uri, segment) { var index = uri.indexOf("?"); var queryPortion = ""; if (index >= 0) { queryPortion = uri.substr(index); uri = uri.substr(0, index); } if (uri[uri.length - 1] !== "/") { uri += "/"; } return uri + segment + queryPortion; } /** Builds a request object to GET the specified URI. * @param {String} uri - URI for request. * @param {Object} options - Additional options. */ function buildODataRequest(uri, options) { return { method: "GET", requestUri: uri, user: options.user, password: options.password, enableJsonpCallback: options.enableJsonpCallback, callbackParameterName: options.callbackParameterName, formatQueryString: options.formatQueryString }; } /** Finds the index where the value of a query option starts. * @param {String} uri - URI to search in. * @param {String} name - Name to look for. * @returns {Number} The index where the query option starts. */ function findQueryOptionStart(uri, name) { var result = -1; var queryIndex = uri.indexOf("?"); if (queryIndex !== -1) { var start = uri.indexOf("?" + name + "=", queryIndex); if (start === -1) { start = uri.indexOf("&" + name + "=", queryIndex); } if (start !== -1) { result = start + name.length + 2; } } return result; } /** Gets data from an OData service. * @param {String} uri - URI to the OData service. * @param {Object} options - Object with additional well-known request options. * @param {Function} success - Success callback. * @param {Function} error - Error callback. * @returns {Object} Object with an abort method. */ function queryForData (uri, options, success, error) { return queryForDataInternal(uri, options, {}, success, error); } /** Gets data from an OData service taking into consideration server side paging. * @param {String} uri - URI to the OData service. * @param {Object} options - Object with additional well-known request options. * @param {Array} data - Array that stores the data provided by the OData service. * @param {Function} success - Success callback. * @param {Function} error - Error callback. * @returns {Object} Object with an abort method. */ function queryForDataInternal(uri, options, data, success, error) { var request = buildODataRequest(uri, options); var currentRequest = odataRequest.request(request, function (newData) { var nextLink = newData["@odata.nextLink"]; if (nextLink) { var index = uri.indexOf(".svc/", 0); if (index != -1) { nextLink = uri.substring(0, index + 5) + nextLink; } } if (data.value && newData.value) { data.value = data.value.concat(newData.value); } else { for (var property in newData) { if (property != "@odata.nextLink") { data[property] = newData[property]; } } } if (nextLink) { currentRequest = queryForDataInternal(nextLink, options, data, success, error); } else { success(data); } }, error, undefined, options.httpClient, options.metadata); return { abort: function () { currentRequest.abort(); } }; } /** Creates a data cache source object for requesting data from an OData service. * @class ODataCacheSource * @param options - Options for the cache data source. * @returns {ODataCacheSource} A new data cache source instance. */ function ODataCacheSource (options) { var that = this; var uri = options.source; that.identifier = normalizeURICase(encodeURI(decodeURI(uri))); that.options = options; /** Gets the number of items in the collection. * @method ODataCacheSource#count * @param {Function} success - Success callback with the item count. * @param {Function} error - Error callback. * @returns {Object} Request object with an abort method. */ that.count = function (success, error) { var options = that.options; return odataRequest.request( buildODataRequest(appendSegment(uri, "$count"), options), function (data) { var count = parseInt10(data.toString()); if (isNaN(count)) { error({ message: "Count is NaN", count: count }); } else { success(count); } }, error, undefined, options.httpClient, options.metadata ); }; /** Gets a number of consecutive items from the collection. * @method ODataCacheSource#read * @param {Number} index - Zero-based index of the items to retrieve. * @param {Number} count - Number of items to retrieve. * @param {Function} success - Success callback with the requested items. * @param {Function} error - Error callback. * @returns {Object} Request object with an abort method. */ that.read = function (index, count, success, error) { var queryOptions = "$skip=" + index + "&$top=" + count; return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error); }; return that; } /** ODataCacheSource (see {@link ODataCacheSource}) */ exports.ODataCacheSource = ODataCacheSource;