summaryrefslogtreecommitdiffstats
path: root/services/common/kinto-http-client.js
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2018-02-02 09:21:33 -0500
committerMatt A. Tobin <email@mattatobin.com>2018-02-02 09:21:33 -0500
commit9627f18cebab38cdfe45592d83371ee7bbc62cfa (patch)
tree9ac98ca9a764666bd0edd4cfd59ae970705b98a3 /services/common/kinto-http-client.js
parentc28c5b704fb3f3af6e7846abd73f63da1e35921f (diff)
downloadUXP-9627f18cebab38cdfe45592d83371ee7bbc62cfa.tar
UXP-9627f18cebab38cdfe45592d83371ee7bbc62cfa.tar.gz
UXP-9627f18cebab38cdfe45592d83371ee7bbc62cfa.tar.lz
UXP-9627f18cebab38cdfe45592d83371ee7bbc62cfa.tar.xz
UXP-9627f18cebab38cdfe45592d83371ee7bbc62cfa.zip
Remove kinto client, Firefox kinto storage adapter, blocklist update client and integration with sync, OneCRL and the custom time check for derives system time.
Diffstat (limited to 'services/common/kinto-http-client.js')
-rw-r--r--services/common/kinto-http-client.js1891
1 files changed, 0 insertions, 1891 deletions
diff --git a/services/common/kinto-http-client.js b/services/common/kinto-http-client.js
deleted file mode 100644
index 57f6946d1..000000000
--- a/services/common/kinto-http-client.js
+++ /dev/null
@@ -1,1891 +0,0 @@
-/*
- *
- * Licensed 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.
- */
-
-/*
- * This file is generated from kinto-http.js - do not modify directly.
- */
-
-this.EXPORTED_SYMBOLS = ["KintoHttpClient"];
-
-/*
- * Version 2.0.0 - 61435f3
- */
-
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.KintoHttpClient = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/*
- *
- * Licensed 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";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = undefined;
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _base = require("../src/base");
-
-var _base2 = _interopRequireDefault(_base);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Timer.jsm");
-Cu.importGlobalProperties(['fetch']);
-const { EventEmitter } = Cu.import("resource://devtools/shared/event-emitter.js", {});
-
-let KintoHttpClient = class KintoHttpClient extends _base2.default {
- constructor(remote, options = {}) {
- const events = {};
- EventEmitter.decorate(events);
- super(remote, _extends({ events }, options));
- }
-};
-
-// This fixes compatibility with CommonJS required by browserify.
-// See http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default/33683495#33683495
-
-exports.default = KintoHttpClient;
-if (typeof module === "object") {
- module.exports = KintoHttpClient;
-}
-
-},{"../src/base":2}],2:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = exports.SUPPORTED_PROTOCOL_VERSION = undefined;
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _desc, _value, _class;
-
-var _utils = require("./utils");
-
-var _http = require("./http");
-
-var _http2 = _interopRequireDefault(_http);
-
-var _endpoint = require("./endpoint");
-
-var _endpoint2 = _interopRequireDefault(_endpoint);
-
-var _requests = require("./requests");
-
-var requests = _interopRequireWildcard(_requests);
-
-var _batch = require("./batch");
-
-var _bucket = require("./bucket");
-
-var _bucket2 = _interopRequireDefault(_bucket);
-
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
- var desc = {};
- Object['ke' + 'ys'](descriptor).forEach(function (key) {
- desc[key] = descriptor[key];
- });
- desc.enumerable = !!desc.enumerable;
- desc.configurable = !!desc.configurable;
-
- if ('value' in desc || desc.initializer) {
- desc.writable = true;
- }
-
- desc = decorators.slice().reverse().reduce(function (desc, decorator) {
- return decorator(target, property, desc) || desc;
- }, desc);
-
- if (context && desc.initializer !== void 0) {
- desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
- desc.initializer = undefined;
- }
-
- if (desc.initializer === void 0) {
- Object['define' + 'Property'](target, property, desc);
- desc = null;
- }
-
- return desc;
-}
-
-/**
- * Currently supported protocol version.
- * @type {String}
- */
-const SUPPORTED_PROTOCOL_VERSION = exports.SUPPORTED_PROTOCOL_VERSION = "v1";
-
-/**
- * High level HTTP client for the Kinto API.
- *
- * @example
- * const client = new KintoClient("https://kinto.dev.mozaws.net/v1");
- * client.bucket("default")
-* .collection("my-blog")
-* .createRecord({title: "First article"})
- * .then(console.log.bind(console))
- * .catch(console.error.bind(console));
- */
-let KintoClientBase = (_dec = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec2 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec3 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec4 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec5 = (0, _utils.nobatch)("Can't use batch within a batch!"), _dec6 = (0, _utils.support)("1.4", "2.0"), (_class = class KintoClientBase {
- /**
- * Constructor.
- *
- * @param {String} remote The remote URL.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.safe=true] Adds concurrency headers to every requests.
- * @param {EventEmitter} [options.events=EventEmitter] The events handler instance.
- * @param {Object} [options.headers={}] The key-value headers to pass to each request.
- * @param {String} [options.bucket="default"] The default bucket to use.
- * @param {String} [options.requestMode="cors"] The HTTP request mode (from ES6 fetch spec).
- * @param {Number} [options.timeout=5000] The requests timeout in ms.
- */
- constructor(remote, options = {}) {
- if (typeof remote !== "string" || !remote.length) {
- throw new Error("Invalid remote URL: " + remote);
- }
- if (remote[remote.length - 1] === "/") {
- remote = remote.slice(0, -1);
- }
- this._backoffReleaseTime = null;
-
- /**
- * Default request options container.
- * @private
- * @type {Object}
- */
- this.defaultReqOptions = {
- bucket: options.bucket || "default",
- headers: options.headers || {},
- safe: !!options.safe
- };
-
- this._options = options;
- this._requests = [];
- this._isBatch = !!options.batch;
-
- // public properties
- /**
- * The remote server base URL.
- * @type {String}
- */
- this.remote = remote;
- /**
- * Current server information.
- * @ignore
- * @type {Object|null}
- */
- this.serverInfo = null;
- /**
- * The event emitter instance. Should comply with the `EventEmitter`
- * interface.
- * @ignore
- * @type {Class}
- */
- this.events = options.events;
-
- const { requestMode, timeout } = options;
- /**
- * The HTTP instance.
- * @ignore
- * @type {HTTP}
- */
- this.http = new _http2.default(this.events, { requestMode, timeout });
- this._registerHTTPEvents();
- }
-
- /**
- * The remote endpoint base URL. Setting the value will also extract and
- * validate the version.
- * @type {String}
- */
- get remote() {
- return this._remote;
- }
-
- /**
- * @ignore
- */
- set remote(url) {
- let version;
- try {
- version = url.match(/\/(v\d+)\/?$/)[1];
- } catch (err) {
- throw new Error("The remote URL must contain the version: " + url);
- }
- if (version !== SUPPORTED_PROTOCOL_VERSION) {
- throw new Error(`Unsupported protocol version: ${ version }`);
- }
- this._remote = url;
- this._version = version;
- }
-
- /**
- * The current server protocol version, eg. `v1`.
- * @type {String}
- */
- get version() {
- return this._version;
- }
-
- /**
- * Backoff remaining time, in milliseconds. Defaults to zero if no backoff is
- * ongoing.
- *
- * @type {Number}
- */
- get backoff() {
- const currentTime = new Date().getTime();
- if (this._backoffReleaseTime && currentTime < this._backoffReleaseTime) {
- return this._backoffReleaseTime - currentTime;
- }
- return 0;
- }
-
- /**
- * Registers HTTP events.
- * @private
- */
- _registerHTTPEvents() {
- // Prevent registering event from a batch client instance
- if (!this._isBatch) {
- this.events.on("backoff", backoffMs => {
- this._backoffReleaseTime = backoffMs;
- });
- }
- }
-
- /**
- * Retrieve a bucket object to perform operations on it.
- *
- * @param {String} name The bucket name.
- * @param {Object} [options={}] The request options.
- * @param {Boolean} [options.safe] The resulting safe option.
- * @param {String} [options.bucket] The resulting bucket name option.
- * @param {Object} [options.headers] The extended headers object option.
- * @return {Bucket}
- */
- bucket(name, options = {}) {
- const bucketOptions = (0, _utils.omit)(this._getRequestOptions(options), "bucket");
- return new _bucket2.default(this, name, bucketOptions);
- }
-
- /**
- * Generates a request options object, deeply merging the client configured
- * defaults with the ones provided as argument.
- *
- * Note: Headers won't be overriden but merged with instance default ones.
- *
- * @private
- * @param {Object} [options={}] The request options.
- * @property {Boolean} [options.safe] The resulting safe option.
- * @property {String} [options.bucket] The resulting bucket name option.
- * @property {Object} [options.headers] The extended headers object option.
- * @return {Object}
- */
- _getRequestOptions(options = {}) {
- return _extends({}, this.defaultReqOptions, options, {
- batch: this._isBatch,
- // Note: headers should never be overriden but extended
- headers: _extends({}, this.defaultReqOptions.headers, options.headers)
- });
- }
-
- /**
- * Retrieves server information and persist them locally. This operation is
- * usually performed a single time during the instance lifecycle.
- *
- * @param {Object} [options={}] The request options.
- * @return {Promise<Object, Error>}
- */
- fetchServerInfo(options = {}) {
- if (this.serverInfo) {
- return Promise.resolve(this.serverInfo);
- }
- return this.http.request(this.remote + (0, _endpoint2.default)("root"), {
- headers: _extends({}, this.defaultReqOptions.headers, options.headers)
- }).then(({ json }) => {
- this.serverInfo = json;
- return this.serverInfo;
- });
- }
-
- /**
- * Retrieves Kinto server settings.
- *
- * @param {Object} [options={}] The request options.
- * @return {Promise<Object, Error>}
- */
-
- fetchServerSettings(options = {}) {
- return this.fetchServerInfo(options).then(({ settings }) => settings);
- }
-
- /**
- * Retrieve server capabilities information.
- *
- * @param {Object} [options={}] The request options.
- * @return {Promise<Object, Error>}
- */
-
- fetchServerCapabilities(options = {}) {
- return this.fetchServerInfo(options).then(({ capabilities }) => capabilities);
- }
-
- /**
- * Retrieve authenticated user information.
- *
- * @param {Object} [options={}] The request options.
- * @return {Promise<Object, Error>}
- */
-
- fetchUser(options = {}) {
- return this.fetchServerInfo(options).then(({ user }) => user);
- }
-
- /**
- * Retrieve authenticated user information.
- *
- * @param {Object} [options={}] The request options.
- * @return {Promise<Object, Error>}
- */
-
- fetchHTTPApiVersion(options = {}) {
- return this.fetchServerInfo(options).then(({ http_api_version }) => {
- return http_api_version;
- });
- }
-
- /**
- * Process batch requests, chunking them according to the batch_max_requests
- * server setting when needed.
- *
- * @param {Array} requests The list of batch subrequests to perform.
- * @param {Object} [options={}] The options object.
- * @return {Promise<Object, Error>}
- */
- _batchRequests(requests, options = {}) {
- const headers = _extends({}, this.defaultReqOptions.headers, options.headers);
- if (!requests.length) {
- return Promise.resolve([]);
- }
- return this.fetchServerSettings().then(serverSettings => {
- const maxRequests = serverSettings["batch_max_requests"];
- if (maxRequests && requests.length > maxRequests) {
- const chunks = (0, _utils.partition)(requests, maxRequests);
- return (0, _utils.pMap)(chunks, chunk => this._batchRequests(chunk, options));
- }
- return this.execute({
- path: (0, _endpoint2.default)("batch"),
- method: "POST",
- headers: headers,
- body: {
- defaults: { headers },
- requests: requests
- }
- })
- // we only care about the responses
- .then(({ responses }) => responses);
- });
- }
-
- /**
- * Sends batch requests to the remote server.
- *
- * Note: Reserved for internal use only.
- *
- * @ignore
- * @param {Function} fn The function to use for describing batch ops.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {String} [options.bucket] The bucket name option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.aggregate=false] Produces an aggregated result object.
- * @return {Promise<Object, Error>}
- */
-
- batch(fn, options = {}) {
- const rootBatch = new KintoClientBase(this.remote, _extends({}, this._options, this._getRequestOptions(options), {
- batch: true
- }));
- let bucketBatch, collBatch;
- if (options.bucket) {
- bucketBatch = rootBatch.bucket(options.bucket);
- if (options.collection) {
- collBatch = bucketBatch.collection(options.collection);
- }
- }
- const batchClient = collBatch || bucketBatch || rootBatch;
- try {
- fn(batchClient);
- } catch (err) {
- return Promise.reject(err);
- }
- return this._batchRequests(rootBatch._requests, options).then(responses => {
- if (options.aggregate) {
- return (0, _batch.aggregate)(responses, rootBatch._requests);
- }
- return responses;
- });
- }
-
- /**
- * Executes an atomic HTTP request.
- *
- * @private
- * @param {Object} request The request object.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.raw=false] If true, resolve with full response object, including json body and headers instead of just json.
- * @return {Promise<Object, Error>}
- */
- execute(request, options = { raw: false }) {
- // If we're within a batch, add the request to the stack to send at once.
- if (this._isBatch) {
- this._requests.push(request);
- // Resolve with a message in case people attempt at consuming the result
- // from within a batch operation.
- const msg = "This result is generated from within a batch " + "operation and should not be consumed.";
- return Promise.resolve(options.raw ? { json: msg } : msg);
- }
- const promise = this.fetchServerSettings().then(_ => {
- return this.http.request(this.remote + request.path, _extends({}, request, {
- body: JSON.stringify(request.body)
- }));
- });
- return options.raw ? promise : promise.then(({ json }) => json);
- }
-
- /**
- * Retrieves the list of buckets.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object[], Error>}
- */
- listBuckets(options = {}) {
- return this.execute({
- path: (0, _endpoint2.default)("bucket"),
- headers: _extends({}, this.defaultReqOptions.headers, options.headers)
- });
- }
-
- /**
- * Creates a new bucket on the server.
- *
- * @param {String} id The bucket name.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.data] The bucket data option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- createBucket(id, options = {}) {
- if (!id) {
- throw new Error("A bucket id is required.");
- }
- // Note that we simply ignore any "bucket" option passed here, as the one
- // we're interested in is the one provided as a required argument.
- const reqOptions = this._getRequestOptions(options);
- const { data = {}, permissions } = reqOptions;
- data.id = id;
- const path = (0, _endpoint2.default)("bucket", id);
- return this.execute(requests.createRequest(path, { data, permissions }, reqOptions));
- }
-
- /**
- * Deletes a bucket from the server.
- *
- * @ignore
- * @param {Object|String} bucket The bucket to delete.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- deleteBucket(bucket, options = {}) {
- const bucketObj = (0, _utils.toDataBody)(bucket);
- if (!bucketObj.id) {
- throw new Error("A bucket id is required.");
- }
- const path = (0, _endpoint2.default)("bucket", bucketObj.id);
- const { last_modified } = { bucketObj };
- const reqOptions = this._getRequestOptions(_extends({ last_modified }, options));
- return this.execute(requests.deleteRequest(path, reqOptions));
- }
-
- /**
- * Deletes all buckets on the server.
- *
- * @ignore
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
-
- deleteBuckets(options = {}) {
- const reqOptions = this._getRequestOptions(options);
- const path = (0, _endpoint2.default)("bucket");
- return this.execute(requests.deleteRequest(path, reqOptions));
- }
-}, (_applyDecoratedDescriptor(_class.prototype, "fetchServerSettings", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerSettings"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "fetchServerCapabilities", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerCapabilities"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "fetchUser", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "fetchUser"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "fetchHTTPApiVersion", [_dec4], Object.getOwnPropertyDescriptor(_class.prototype, "fetchHTTPApiVersion"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "batch", [_dec5], Object.getOwnPropertyDescriptor(_class.prototype, "batch"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deleteBuckets", [_dec6], Object.getOwnPropertyDescriptor(_class.prototype, "deleteBuckets"), _class.prototype)), _class));
-exports.default = KintoClientBase;
-
-},{"./batch":3,"./bucket":4,"./endpoint":6,"./http":8,"./requests":9,"./utils":10}],3:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.aggregate = aggregate;
-/**
- * Exports batch responses as a result object.
- *
- * @private
- * @param {Array} responses The batch subrequest responses.
- * @param {Array} requests The initial issued requests.
- * @return {Object}
- */
-function aggregate(responses = [], requests = []) {
- if (responses.length !== requests.length) {
- throw new Error("Responses length should match requests one.");
- }
- const results = {
- errors: [],
- published: [],
- conflicts: [],
- skipped: []
- };
- return responses.reduce((acc, response, index) => {
- const { status } = response;
- if (status >= 200 && status < 400) {
- acc.published.push(response.body);
- } else if (status === 404) {
- acc.skipped.push(response.body);
- } else if (status === 412) {
- acc.conflicts.push({
- // XXX: specifying the type is probably superfluous
- type: "outgoing",
- local: requests[index].body,
- remote: response.body.details && response.body.details.existing || null
- });
- } else {
- acc.errors.push({
- path: response.path,
- sent: requests[index],
- error: response.body
- });
- }
- return acc;
- }, results);
-}
-
-},{}],4:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = undefined;
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _utils = require("./utils");
-
-var _collection = require("./collection");
-
-var _collection2 = _interopRequireDefault(_collection);
-
-var _requests = require("./requests");
-
-var requests = _interopRequireWildcard(_requests);
-
-var _endpoint = require("./endpoint");
-
-var _endpoint2 = _interopRequireDefault(_endpoint);
-
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-/**
- * Abstract representation of a selected bucket.
- *
- */
-let Bucket = class Bucket {
- /**
- * Constructor.
- *
- * @param {KintoClient} client The client instance.
- * @param {String} name The bucket name.
- * @param {Object} [options={}] The headers object option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- */
- constructor(client, name, options = {}) {
- /**
- * @ignore
- */
- this.client = client;
- /**
- * The bucket name.
- * @type {String}
- */
- this.name = name;
- /**
- * The default options object.
- * @ignore
- * @type {Object}
- */
- this.options = options;
- /**
- * @ignore
- */
- this._isBatch = !!options.batch;
- }
-
- /**
- * Merges passed request options with default bucket ones, if any.
- *
- * @private
- * @param {Object} [options={}] The options to merge.
- * @return {Object} The merged options.
- */
- _bucketOptions(options = {}) {
- const headers = _extends({}, this.options && this.options.headers, options.headers);
- return _extends({}, this.options, options, {
- headers,
- bucket: this.name,
- batch: this._isBatch
- });
- }
-
- /**
- * Selects a collection.
- *
- * @param {String} name The collection name.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @return {Collection}
- */
- collection(name, options = {}) {
- return new _collection2.default(this.client, this, name, this._bucketOptions(options));
- }
-
- /**
- * Retrieves bucket data.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getData(options = {}) {
- return this.client.execute({
- path: (0, _endpoint2.default)("bucket", this.name),
- headers: _extends({}, this.options.headers, options.headers)
- }).then(res => res.data);
- }
-
- /**
- * Set bucket data.
- * @param {Object} data The bucket data object.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Boolean} [options.patch] The patch option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- setData(data, options = {}) {
- if (!(0, _utils.isObject)(data)) {
- throw new Error("A bucket object is required.");
- }
-
- const bucket = _extends({}, data, { id: this.name });
-
- // For default bucket, we need to drop the id from the data object.
- // Bug in Kinto < 3.1.1
- const bucketId = bucket.id;
- if (bucket.id === "default") {
- delete bucket.id;
- }
-
- const path = (0, _endpoint2.default)("bucket", bucketId);
- const { permissions } = options;
- const reqOptions = _extends({}, this._bucketOptions(options));
- const request = requests.updateRequest(path, { data: bucket, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Retrieves the list of collections in the current bucket.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Array<Object>, Error>}
- */
- listCollections(options = {}) {
- return this.client.execute({
- path: (0, _endpoint2.default)("collection", this.name),
- headers: _extends({}, this.options.headers, options.headers)
- });
- }
-
- /**
- * Creates a new collection in current bucket.
- *
- * @param {String|undefined} id The collection id.
- * @param {Object} [options={}] The options object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Object} [options.permissions] The permissions object.
- * @param {Object} [options.data] The data object.
- * @return {Promise<Object, Error>}
- */
- createCollection(id, options = {}) {
- const reqOptions = this._bucketOptions(options);
- const { permissions, data = {} } = reqOptions;
- data.id = id;
- const path = (0, _endpoint2.default)("collection", this.name, id);
- const request = requests.createRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Deletes a collection from the current bucket.
- *
- * @param {Object|String} collection The collection to delete.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- deleteCollection(collection, options = {}) {
- const collectionObj = (0, _utils.toDataBody)(collection);
- if (!collectionObj.id) {
- throw new Error("A collection id is required.");
- }
- const { id, last_modified } = collectionObj;
- const reqOptions = this._bucketOptions(_extends({ last_modified }, options));
- const path = (0, _endpoint2.default)("collection", this.name, id);
- const request = requests.deleteRequest(path, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Retrieves the list of groups in the current bucket.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Array<Object>, Error>}
- */
- listGroups(options = {}) {
- return this.client.execute({
- path: (0, _endpoint2.default)("group", this.name),
- headers: _extends({}, this.options.headers, options.headers)
- });
- }
-
- /**
- * Creates a new group in current bucket.
- *
- * @param {String} id The group id.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getGroup(id, options = {}) {
- return this.client.execute({
- path: (0, _endpoint2.default)("group", this.name, id),
- headers: _extends({}, this.options.headers, options.headers)
- });
- }
-
- /**
- * Creates a new group in current bucket.
- *
- * @param {String|undefined} id The group id.
- * @param {Array<String>} [members=[]] The list of principals.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.data] The data object.
- * @param {Object} [options.permissions] The permissions object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- createGroup(id, members = [], options = {}) {
- const reqOptions = this._bucketOptions(options);
- const data = _extends({}, options.data, {
- id,
- members
- });
- const path = (0, _endpoint2.default)("group", this.name, id);
- const { permissions } = options;
- const request = requests.createRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Updates an existing group in current bucket.
- *
- * @param {Object} group The group object.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.data] The data object.
- * @param {Object} [options.permissions] The permissions object.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- updateGroup(group, options = {}) {
- if (!(0, _utils.isObject)(group)) {
- throw new Error("A group object is required.");
- }
- if (!group.id) {
- throw new Error("A group id is required.");
- }
- const reqOptions = this._bucketOptions(options);
- const data = _extends({}, options.data, group);
- const path = (0, _endpoint2.default)("group", this.name, group.id);
- const { permissions } = options;
- const request = requests.updateRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Deletes a group from the current bucket.
- *
- * @param {Object|String} group The group to delete.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- deleteGroup(group, options = {}) {
- const groupObj = (0, _utils.toDataBody)(group);
- const { id, last_modified } = groupObj;
- const reqOptions = this._bucketOptions(_extends({ last_modified }, options));
- const path = (0, _endpoint2.default)("group", this.name, id);
- const request = requests.deleteRequest(path, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Retrieves the list of permissions for this bucket.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getPermissions(options = {}) {
- return this.client.execute({
- path: (0, _endpoint2.default)("bucket", this.name),
- headers: _extends({}, this.options.headers, options.headers)
- }).then(res => res.permissions);
- }
-
- /**
- * Replaces all existing bucket permissions with the ones provided.
- *
- * @param {Object} permissions The permissions object.
- * @param {Object} [options={}] The options object
- * @param {Boolean} [options.safe] The safe option.
- * @param {Object} [options.headers] The headers object option.
- * @param {Object} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- setPermissions(permissions, options = {}) {
- if (!(0, _utils.isObject)(permissions)) {
- throw new Error("A permissions object is required.");
- }
- const path = (0, _endpoint2.default)("bucket", this.name);
- const reqOptions = _extends({}, this._bucketOptions(options));
- const { last_modified } = options;
- const data = { last_modified };
- const request = requests.updateRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Performs batch operations at the current bucket level.
- *
- * @param {Function} fn The batch operation function.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Boolean} [options.aggregate] Produces a grouped result object.
- * @return {Promise<Object, Error>}
- */
- batch(fn, options = {}) {
- return this.client.batch(fn, this._bucketOptions(options));
- }
-};
-exports.default = Bucket;
-
-},{"./collection":5,"./endpoint":6,"./requests":9,"./utils":10}],5:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = undefined;
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-var _utils = require("./utils");
-
-var _requests = require("./requests");
-
-var requests = _interopRequireWildcard(_requests);
-
-var _endpoint = require("./endpoint");
-
-var _endpoint2 = _interopRequireDefault(_endpoint);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
-/**
- * Abstract representation of a selected collection.
- *
- */
-let Collection = class Collection {
- /**
- * Constructor.
- *
- * @param {KintoClient} client The client instance.
- * @param {Bucket} bucket The bucket instance.
- * @param {String} name The collection name.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- */
- constructor(client, bucket, name, options = {}) {
- /**
- * @ignore
- */
- this.client = client;
- /**
- * @ignore
- */
- this.bucket = bucket;
- /**
- * The collection name.
- * @type {String}
- */
- this.name = name;
-
- /**
- * The default collection options object, embedding the default bucket ones.
- * @ignore
- * @type {Object}
- */
- this.options = _extends({}, this.bucket.options, options, {
- headers: _extends({}, this.bucket.options && this.bucket.options.headers, options.headers)
- });
- /**
- * @ignore
- */
- this._isBatch = !!options.batch;
- }
-
- /**
- * Merges passed request options with default bucket and collection ones, if
- * any.
- *
- * @private
- * @param {Object} [options={}] The options to merge.
- * @return {Object} The merged options.
- */
- _collOptions(options = {}) {
- const headers = _extends({}, this.options && this.options.headers, options.headers);
- return _extends({}, this.options, options, {
- headers
- });
- }
-
- /**
- * Retrieves collection data.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getData(options = {}) {
- const { headers } = this._collOptions(options);
- return this.client.execute({
- path: (0, _endpoint2.default)("collection", this.bucket.name, this.name),
- headers
- }).then(res => res.data);
- }
-
- /**
- * Set collection data.
- * @param {Object} data The collection data object.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Boolean} [options.patch] The patch option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- setData(data, options = {}) {
- if (!(0, _utils.isObject)(data)) {
- throw new Error("A collection object is required.");
- }
- const reqOptions = this._collOptions(options);
- const { permissions } = reqOptions;
-
- const path = (0, _endpoint2.default)("collection", this.bucket.name, this.name);
- const request = requests.updateRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Retrieves the list of permissions for this collection.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getPermissions(options = {}) {
- const { headers } = this._collOptions(options);
- return this.client.execute({
- path: (0, _endpoint2.default)("collection", this.bucket.name, this.name),
- headers
- }).then(res => res.permissions);
- }
-
- /**
- * Replaces all existing collection permissions with the ones provided.
- *
- * @param {Object} permissions The permissions object.
- * @param {Object} [options={}] The options object
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- setPermissions(permissions, options = {}) {
- if (!(0, _utils.isObject)(permissions)) {
- throw new Error("A permissions object is required.");
- }
- const reqOptions = this._collOptions(options);
- const path = (0, _endpoint2.default)("collection", this.bucket.name, this.name);
- const data = { last_modified: options.last_modified };
- const request = requests.updateRequest(path, { data, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Creates a record in current collection.
- *
- * @param {Object} record The record to create.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @return {Promise<Object, Error>}
- */
- createRecord(record, options = {}) {
- const reqOptions = this._collOptions(options);
- const { permissions } = reqOptions;
- const path = (0, _endpoint2.default)("record", this.bucket.name, this.name, record.id);
- const request = requests.createRequest(path, { data: record, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Updates a record in current collection.
- *
- * @param {Object} record The record to update.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- updateRecord(record, options = {}) {
- if (!(0, _utils.isObject)(record)) {
- throw new Error("A record object is required.");
- }
- if (!record.id) {
- throw new Error("A record id is required.");
- }
- const reqOptions = this._collOptions(options);
- const { permissions } = reqOptions;
- const path = (0, _endpoint2.default)("record", this.bucket.name, this.name, record.id);
- const request = requests.updateRequest(path, { data: record, permissions }, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Deletes a record from the current collection.
- *
- * @param {Object|String} record The record to delete.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Number} [options.last_modified] The last_modified option.
- * @return {Promise<Object, Error>}
- */
- deleteRecord(record, options = {}) {
- const recordObj = (0, _utils.toDataBody)(record);
- if (!recordObj.id) {
- throw new Error("A record id is required.");
- }
- const { id, last_modified } = recordObj;
- const reqOptions = this._collOptions(_extends({ last_modified }, options));
- const path = (0, _endpoint2.default)("record", this.bucket.name, this.name, id);
- const request = requests.deleteRequest(path, reqOptions);
- return this.client.execute(request);
- }
-
- /**
- * Retrieves a record from the current collection.
- *
- * @param {String} id The record id to retrieve.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @return {Promise<Object, Error>}
- */
- getRecord(id, options = {}) {
- return this.client.execute(_extends({
- path: (0, _endpoint2.default)("record", this.bucket.name, this.name, id)
- }, this._collOptions(options)));
- }
-
- /**
- * Lists records from the current collection.
- *
- * Sorting is done by passing a `sort` string option:
- *
- * - The field to order the results by, prefixed with `-` for descending.
- * Default: `-last_modified`.
- *
- * @see http://kinto.readthedocs.io/en/stable/core/api/resource.html#sorting
- *
- * Filtering is done by passing a `filters` option object:
- *
- * - `{fieldname: "value"}`
- * - `{min_fieldname: 4000}`
- * - `{in_fieldname: "1,2,3"}`
- * - `{not_fieldname: 0}`
- * - `{exclude_fieldname: "0,1"}`
- *
- * @see http://kinto.readthedocs.io/en/stable/core/api/resource.html#filtering
- *
- * Paginating is done by passing a `limit` option, then calling the `next()`
- * method from the resolved result object to fetch the next page, if any.
- *
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Object} [options.filters=[]] The filters object.
- * @param {String} [options.sort="-last_modified"] The sort field.
- * @param {String} [options.limit=null] The limit field.
- * @param {String} [options.pages=1] The number of result pages to aggregate.
- * @param {Number} [options.since=null] Only retrieve records modified since the provided timestamp.
- * @return {Promise<Object, Error>}
- */
- listRecords(options = {}) {
- const { http } = this.client;
- const { sort, filters, limit, pages, since } = _extends({
- sort: "-last_modified"
- }, options);
- // Safety/Consistency check on ETag value.
- if (since && typeof since !== "string") {
- throw new Error(`Invalid value for since (${ since }), should be ETag value.`);
- }
- const collHeaders = this.options.headers;
- const path = (0, _endpoint2.default)("record", this.bucket.name, this.name);
- const querystring = (0, _utils.qsify)(_extends({}, filters, {
- _sort: sort,
- _limit: limit,
- _since: since
- }));
- let results = [],
- current = 0;
-
- const next = function (nextPage) {
- if (!nextPage) {
- throw new Error("Pagination exhausted.");
- }
- return processNextPage(nextPage);
- };
-
- const processNextPage = nextPage => {
- return http.request(nextPage, { headers: collHeaders }).then(handleResponse);
- };
-
- const pageResults = (results, nextPage, etag) => {
- // ETag string is supposed to be opaque and stored «as-is».
- // ETag header values are quoted (because of * and W/"foo").
- return {
- last_modified: etag ? etag.replace(/"/g, "") : etag,
- data: results,
- next: next.bind(null, nextPage)
- };
- };
-
- const handleResponse = ({ headers, json }) => {
- const nextPage = headers.get("Next-Page");
- const etag = headers.get("ETag");
- if (!pages) {
- return pageResults(json.data, nextPage, etag);
- }
- // Aggregate new results with previous ones
- results = results.concat(json.data);
- current += 1;
- if (current >= pages || !nextPage) {
- // Pagination exhausted
- return pageResults(results, nextPage, etag);
- }
- // Follow next page
- return processNextPage(nextPage);
- };
-
- return this.client.execute(_extends({
- path: path + "?" + querystring
- }, this._collOptions(options)), { raw: true }).then(handleResponse);
- }
-
- /**
- * Performs batch operations at the current collection level.
- *
- * @param {Function} fn The batch operation function.
- * @param {Object} [options={}] The options object.
- * @param {Object} [options.headers] The headers object option.
- * @param {Boolean} [options.safe] The safe option.
- * @param {Boolean} [options.aggregate] Produces a grouped result object.
- * @return {Promise<Object, Error>}
- */
- batch(fn, options = {}) {
- const reqOptions = this._collOptions(options);
- return this.client.batch(fn, _extends({}, reqOptions, {
- bucket: this.bucket.name,
- collection: this.name
- }));
- }
-};
-exports.default = Collection;
-
-},{"./endpoint":6,"./requests":9,"./utils":10}],6:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = endpoint;
-/**
- * Endpoints templates.
- * @type {Object}
- */
-const ENDPOINTS = {
- root: () => "/",
- batch: () => "/batch",
- bucket: bucket => "/buckets" + (bucket ? `/${ bucket }` : ""),
- collection: (bucket, coll) => `${ ENDPOINTS.bucket(bucket) }/collections` + (coll ? `/${ coll }` : ""),
- group: (bucket, group) => `${ ENDPOINTS.bucket(bucket) }/groups` + (group ? `/${ group }` : ""),
- record: (bucket, coll, id) => `${ ENDPOINTS.collection(bucket, coll) }/records` + (id ? `/${ id }` : "")
-};
-
-/**
- * Retrieves a server enpoint by its name.
- *
- * @private
- * @param {String} name The endpoint name.
- * @param {...string} args The endpoint parameters.
- * @return {String}
- */
-function endpoint(name, ...args) {
- return ENDPOINTS[name](...args);
-}
-
-},{}],7:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-/**
- * Kinto server error code descriptors.
- * @type {Object}
- */
-exports.default = {
- 104: "Missing Authorization Token",
- 105: "Invalid Authorization Token",
- 106: "Request body was not valid JSON",
- 107: "Invalid request parameter",
- 108: "Missing request parameter",
- 109: "Invalid posted data",
- 110: "Invalid Token / id",
- 111: "Missing Token / id",
- 112: "Content-Length header was not provided",
- 113: "Request body too large",
- 114: "Resource was modified meanwhile",
- 115: "Method not allowed on this end point (hint: server may be readonly)",
- 116: "Requested version not available on this server",
- 117: "Client has sent too many requests",
- 121: "Resource access is forbidden for this user",
- 122: "Another resource violates constraint",
- 201: "Service Temporary unavailable due to high load",
- 202: "Service deprecated",
- 999: "Internal Server Error"
-};
-
-},{}],8:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = undefined;
-
-var _errors = require("./errors");
-
-var _errors2 = _interopRequireDefault(_errors);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-/**
- * Enhanced HTTP client for the Kinto protocol.
- * @private
- */
-let HTTP = class HTTP {
- /**
- * Default HTTP request headers applied to each outgoing request.
- *
- * @type {Object}
- */
- static get DEFAULT_REQUEST_HEADERS() {
- return {
- "Accept": "application/json",
- "Content-Type": "application/json"
- };
- }
-
- /**
- * Default options.
- *
- * @type {Object}
- */
- static get defaultOptions() {
- return { timeout: 5000, requestMode: "cors" };
- }
-
- /**
- * Constructor.
- *
- * @param {EventEmitter} events The event handler.
- * @param {Object} [options={}} The options object.
- * @param {Number} [options.timeout=5000] The request timeout in ms (default: `5000`).
- * @param {String} [options.requestMode="cors"] The HTTP request mode (default: `"cors"`).
- */
- constructor(events, options = {}) {
- // public properties
- /**
- * The event emitter instance.
- * @type {EventEmitter}
- */
- if (!events) {
- throw new Error("No events handler provided");
- }
- this.events = events;
-
- /**
- * The request mode.
- * @see https://fetch.spec.whatwg.org/#requestmode
- * @type {String}
- */
- this.requestMode = options.requestMode || HTTP.defaultOptions.requestMode;
-
- /**
- * The request timeout.
- * @type {Number}
- */
- this.timeout = options.timeout || HTTP.defaultOptions.timeout;
- }
-
- /**
- * Performs an HTTP request to the Kinto server.
- *
- * Resolves with an objet containing the following HTTP response properties:
- * - `{Number} status` The HTTP status code.
- * - `{Object} json` The JSON response body.
- * - `{Headers} headers` The response headers object; see the ES6 fetch() spec.
- *
- * @param {String} url The URL.
- * @param {Object} [options={}] The fetch() options object.
- * @param {Object} [options.headers] The request headers object (default: {})
- * @return {Promise}
- */
- request(url, options = { headers: {} }) {
- let response, status, statusText, headers, hasTimedout;
- // Ensure default request headers are always set
- options.headers = Object.assign({}, HTTP.DEFAULT_REQUEST_HEADERS, options.headers);
- options.mode = this.requestMode;
- return new Promise((resolve, reject) => {
- const _timeoutId = setTimeout(() => {
- hasTimedout = true;
- reject(new Error("Request timeout."));
- }, this.timeout);
- fetch(url, options).then(res => {
- if (!hasTimedout) {
- clearTimeout(_timeoutId);
- resolve(res);
- }
- }).catch(err => {
- if (!hasTimedout) {
- clearTimeout(_timeoutId);
- reject(err);
- }
- });
- }).then(res => {
- response = res;
- headers = res.headers;
- status = res.status;
- statusText = res.statusText;
- this._checkForDeprecationHeader(headers);
- this._checkForBackoffHeader(status, headers);
- this._checkForRetryAfterHeader(status, headers);
- return res.text();
- })
- // Check if we have a body; if so parse it as JSON.
- .then(text => {
- if (text.length === 0) {
- return null;
- }
- // Note: we can't consume the response body twice.
- return JSON.parse(text);
- }).catch(err => {
- const error = new Error(`HTTP ${ status || 0 }; ${ err }`);
- error.response = response;
- error.stack = err.stack;
- throw error;
- }).then(json => {
- if (json && status >= 400) {
- let message = `HTTP ${ status } ${ json.error || "" }: `;
- if (json.errno && json.errno in _errors2.default) {
- const errnoMsg = _errors2.default[json.errno];
- message += errnoMsg;
- if (json.message && json.message !== errnoMsg) {
- message += ` (${ json.message })`;
- }
- } else {
- message += statusText || "";
- }
- const error = new Error(message.trim());
- error.response = response;
- error.data = json;
- throw error;
- }
- return { status, json, headers };
- });
- }
-
- _checkForDeprecationHeader(headers) {
- const alertHeader = headers.get("Alert");
- if (!alertHeader) {
- return;
- }
- let alert;
- try {
- alert = JSON.parse(alertHeader);
- } catch (err) {
- console.warn("Unable to parse Alert header message", alertHeader);
- return;
- }
- console.warn(alert.message, alert.url);
- this.events.emit("deprecated", alert);
- }
-
- _checkForBackoffHeader(status, headers) {
- let backoffMs;
- const backoffSeconds = parseInt(headers.get("Backoff"), 10);
- if (backoffSeconds > 0) {
- backoffMs = new Date().getTime() + backoffSeconds * 1000;
- } else {
- backoffMs = 0;
- }
- this.events.emit("backoff", backoffMs);
- }
-
- _checkForRetryAfterHeader(status, headers) {
- let retryAfter = headers.get("Retry-After");
- if (!retryAfter) {
- return;
- }
- retryAfter = new Date().getTime() + parseInt(retryAfter, 10) * 1000;
- this.events.emit("retry-after", retryAfter);
- }
-};
-exports.default = HTTP;
-
-},{"./errors":7}],9:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
-
-exports.createRequest = createRequest;
-exports.updateRequest = updateRequest;
-exports.deleteRequest = deleteRequest;
-
-var _utils = require("./utils");
-
-const requestDefaults = {
- safe: false,
- // check if we should set default content type here
- headers: {},
- permissions: undefined,
- data: undefined,
- patch: false
-};
-
-/**
- * @private
- */
-function safeHeader(safe, last_modified) {
- if (!safe) {
- return {};
- }
- if (last_modified) {
- return { "If-Match": `"${ last_modified }"` };
- }
- return { "If-None-Match": "*" };
-}
-
-/**
- * @private
- */
-function createRequest(path, { data, permissions }, options = {}) {
- const { headers, safe } = _extends({}, requestDefaults, options);
- return {
- method: data && data.id ? "PUT" : "POST",
- path,
- headers: _extends({}, headers, safeHeader(safe)),
- body: {
- data,
- permissions
- }
- };
-}
-
-/**
- * @private
- */
-function updateRequest(path, { data, permissions }, options = {}) {
- const {
- headers,
- safe,
- patch
- } = _extends({}, requestDefaults, options);
- const { last_modified } = _extends({}, data, options);
-
- if (Object.keys((0, _utils.omit)(data, "id", "last_modified")).length === 0) {
- data = undefined;
- }
-
- return {
- method: patch ? "PATCH" : "PUT",
- path,
- headers: _extends({}, headers, safeHeader(safe, last_modified)),
- body: {
- data,
- permissions
- }
- };
-}
-
-/**
- * @private
- */
-function deleteRequest(path, options = {}) {
- const { headers, safe, last_modified } = _extends({}, requestDefaults, options);
- if (safe && !last_modified) {
- throw new Error("Safe concurrency check requires a last_modified value.");
- }
- return {
- method: "DELETE",
- path,
- headers: _extends({}, headers, safeHeader(safe, last_modified))
- };
-}
-
-},{"./utils":10}],10:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.partition = partition;
-exports.pMap = pMap;
-exports.omit = omit;
-exports.toDataBody = toDataBody;
-exports.qsify = qsify;
-exports.checkVersion = checkVersion;
-exports.support = support;
-exports.capable = capable;
-exports.nobatch = nobatch;
-exports.isObject = isObject;
-/**
- * Chunks an array into n pieces.
- *
- * @private
- * @param {Array} array
- * @param {Number} n
- * @return {Array}
- */
-function partition(array, n) {
- if (n <= 0) {
- return array;
- }
- return array.reduce((acc, x, i) => {
- if (i === 0 || i % n === 0) {
- acc.push([x]);
- } else {
- acc[acc.length - 1].push(x);
- }
- return acc;
- }, []);
-}
-
-/**
- * Maps a list to promises using the provided mapping function, executes them
- * sequentially then returns a Promise resolving with ordered results obtained.
- * Think of this as a sequential Promise.all.
- *
- * @private
- * @param {Array} list The list to map.
- * @param {Function} fn The mapping function.
- * @return {Promise}
- */
-function pMap(list, fn) {
- let results = [];
- return list.reduce((promise, entry) => {
- return promise.then(() => {
- return Promise.resolve(fn(entry)).then(result => results = results.concat(result));
- });
- }, Promise.resolve()).then(() => results);
-}
-
-/**
- * Takes an object and returns a copy of it with the provided keys omitted.
- *
- * @private
- * @param {Object} obj The source object.
- * @param {...String} keys The keys to omit.
- * @return {Object}
- */
-function omit(obj, ...keys) {
- return Object.keys(obj).reduce((acc, key) => {
- if (keys.indexOf(key) === -1) {
- acc[key] = obj[key];
- }
- return acc;
- }, {});
-}
-
-/**
- * Always returns a resource data object from the provided argument.
- *
- * @private
- * @param {Object|String} resource
- * @return {Object}
- */
-function toDataBody(resource) {
- if (isObject(resource)) {
- return resource;
- }
- if (typeof resource === "string") {
- return { id: resource };
- }
- throw new Error("Invalid argument.");
-}
-
-/**
- * Transforms an object into an URL query string, stripping out any undefined
- * values.
- *
- * @param {Object} obj
- * @return {String}
- */
-function qsify(obj) {
- const sep = "&";
- const encode = v => encodeURIComponent(typeof v === "boolean" ? String(v) : v);
- const stripUndefined = o => JSON.parse(JSON.stringify(o));
- const stripped = stripUndefined(obj);
- return Object.keys(stripped).map(k => {
- const ks = encode(k) + "=";
- if (Array.isArray(stripped[k])) {
- return stripped[k].map(v => ks + encode(v)).join(sep);
- } else {
- return ks + encode(stripped[k]);
- }
- }).join(sep);
-}
-
-/**
- * Checks if a version is within the provided range.
- *
- * @param {String} version The version to check.
- * @param {String} minVersion The minimum supported version (inclusive).
- * @param {String} maxVersion The minimum supported version (exclusive).
- * @throws {Error} If the version is outside of the provided range.
- */
-function checkVersion(version, minVersion, maxVersion) {
- const extract = str => str.split(".").map(x => parseInt(x, 10));
- const [verMajor, verMinor] = extract(version);
- const [minMajor, minMinor] = extract(minVersion);
- const [maxMajor, maxMinor] = extract(maxVersion);
- const checks = [verMajor < minMajor, verMajor === minMajor && verMinor < minMinor, verMajor > maxMajor, verMajor === maxMajor && verMinor >= maxMinor];
- if (checks.some(x => x)) {
- throw new Error(`Version ${ version } doesn't satisfy ` + `${ minVersion } <= x < ${ maxVersion }`);
- }
-}
-
-/**
- * Generates a decorator function ensuring a version check is performed against
- * the provided requirements before executing it.
- *
- * @param {String} min The required min version (inclusive).
- * @param {String} max The required max version (inclusive).
- * @return {Function}
- */
-function support(min, max) {
- return function (target, key, descriptor) {
- const fn = descriptor.value;
- return {
- configurable: true,
- get() {
- const wrappedMethod = (...args) => {
- // "this" is the current instance which its method is decorated.
- const client = "client" in this ? this.client : this;
- return client.fetchHTTPApiVersion().then(version => checkVersion(version, min, max)).then(Promise.resolve(fn.apply(this, args)));
- };
- Object.defineProperty(this, key, {
- value: wrappedMethod,
- configurable: true,
- writable: true
- });
- return wrappedMethod;
- }
- };
- };
-}
-
-/**
- * Generates a decorator function ensuring that the specified capabilities are
- * available on the server before executing it.
- *
- * @param {Array<String>} capabilities The required capabilities.
- * @return {Function}
- */
-function capable(capabilities) {
- return function (target, key, descriptor) {
- const fn = descriptor.value;
- return {
- configurable: true,
- get() {
- const wrappedMethod = (...args) => {
- // "this" is the current instance which its method is decorated.
- const client = "client" in this ? this.client : this;
- return client.fetchServerCapabilities().then(available => {
- const missing = capabilities.filter(c => available.indexOf(c) < 0);
- if (missing.length > 0) {
- throw new Error(`Required capabilities ${ missing.join(", ") } ` + "not present on server");
- }
- }).then(Promise.resolve(fn.apply(this, args)));
- };
- Object.defineProperty(this, key, {
- value: wrappedMethod,
- configurable: true,
- writable: true
- });
- return wrappedMethod;
- }
- };
- };
-}
-
-/**
- * Generates a decorator function ensuring an operation is not performed from
- * within a batch request.
- *
- * @param {String} message The error message to throw.
- * @return {Function}
- */
-function nobatch(message) {
- return function (target, key, descriptor) {
- const fn = descriptor.value;
- return {
- configurable: true,
- get() {
- const wrappedMethod = (...args) => {
- // "this" is the current instance which its method is decorated.
- if (this._isBatch) {
- throw new Error(message);
- }
- return fn.apply(this, args);
- };
- Object.defineProperty(this, key, {
- value: wrappedMethod,
- configurable: true,
- writable: true
- });
- return wrappedMethod;
- }
- };
- };
-}
-
-/**
- * Returns true if the specified value is an object (i.e. not an array nor null).
- * @param {Object} thing The value to inspect.
- * @return {bool}
- */
-function isObject(thing) {
- return typeof thing === "object" && thing !== null && !Array.isArray(thing);
-}
-
-},{}]},{},[1])(1)
-}); \ No newline at end of file