UNPKG

kinto

Version:

An Offline-First JavaScript client for Kinto.

637 lines (636 loc) 25.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const utils_1 = require("../utils"); const collection_1 = __importDefault(require("./collection")); const requests = __importStar(require("./requests")); /** * Abstract representation of a selected 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. * @param {Number} [options.retry] The retry option. */ constructor(client, name, options = {}) { /** * @ignore */ this.client = client; /** * The bucket name. * @type {String} */ this.name = name; this._endpoints = client.endpoints; /** * @ignore */ this._headers = options.headers || {}; this._retry = options.retry || 0; this._safe = !!options.safe; } get execute() { return this.client.execute.bind(this.client); } get headers() { return this._headers; } /** * Get the value of "headers" for a given request, merging the * per-request headers with our own "default" headers. * * @private */ _getHeaders(options) { return { ...this._headers, ...options.headers, }; } /** * Get the value of "safe" for a given request, using the * per-request option if present or falling back to our default * otherwise. * * @private * @param {Object} options The options for a request. * @returns {Boolean} */ _getSafe(options) { return { safe: this._safe, ...options }.safe; } /** * As _getSafe, but for "retry". * * @private */ _getRetry(options) { return { retry: this._retry, ...options }.retry; } /** * 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 collection_1.default(this.client, this, name, { headers: this._getHeaders(options), retry: this._getRetry(options), safe: this._getSafe(options), }); } /** * Retrieves the ETag of the collection list, for use with the `since` filtering option. * * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<String, Error>} */ async getCollectionsTimestamp(options = {}) { const path = this._endpoints.collection(this.name); const request = { headers: this._getHeaders(options), path, method: "HEAD", }; const { headers } = (await this.client.execute(request, { raw: true, retry: this._getRetry(options), })); return headers.get("ETag"); } /** * Retrieves the ETag of the group list, for use with the `since` filtering option. * * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<String, Error>} */ async getGroupsTimestamp(options = {}) { const path = this._endpoints.group(this.name); const request = { headers: this._getHeaders(options), path, method: "HEAD", }; const { headers } = (await this.client.execute(request, { raw: true, retry: this._getRetry(options), })); return headers.get("ETag"); } /** * Retrieves bucket data. * * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Object} [options.query] Query parameters to pass in * the request. This might be useful for features that aren't * yet supported by this library. * @param {Array} [options.fields] Limit response to * just some fields. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<Object, Error>} */ async getData(options = {}) { const path = this._endpoints.bucket(this.name); const request = { headers: this._getHeaders(options), path, }; const { data } = (await this.client.execute(request, { retry: this._getRetry(options), query: options.query, fields: options.fields, })); return 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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Boolean} [options.patch] The patch option. * @param {Number} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async setData(data, options = {}) { if (!(0, utils_1.isObject)(data)) { throw new Error("A bucket object is required."); } const bucket = { ...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 = this._endpoints.bucket(bucketId); const { patch, permissions } = options; const { last_modified } = { ...data, ...options }; const request = requests.updateRequest(path, { data: bucket, permissions }, { last_modified, patch, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * Retrieves the list of history entries in the current bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<Array<Object>, Error>} */ async listHistory(options = {}) { const path = this._endpoints.history(this.name); return this.client.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), }); } /** * Retrieves the list of collections in the current bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.filters={}] The filters object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Array} [options.fields] Limit response to * just some fields. * @return {Promise<Array<Object>, Error>} */ async listCollections(options = {}) { const path = this._endpoints.collection(this.name); return this.client.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), }); } /** * 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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Object} [options.permissions] The permissions object. * @param {Object} [options.data] The data object. * @return {Promise<Object, Error>} */ async createCollection(id, options = {}) { const { permissions, data = {} } = options; data.id = id; const path = this._endpoints.collection(this.name, id); const request = requests.createRequest(path, { data, permissions }, { headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * 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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Boolean} [options.safe] The safe option. * @param {Number} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async deleteCollection(collection, options = {}) { const collectionObj = (0, utils_1.toDataBody)(collection); if (!collectionObj.id) { throw new Error("A collection id is required."); } const { id } = collectionObj; const { last_modified } = { ...collectionObj, ...options }; const path = this._endpoints.collection(this.name, id); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * Deletes collections from the current bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.filters={}] The filters object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Array} [options.fields] Limit response to * just some fields. * @return {Promise<Array<Object>, Error>} */ async deleteCollections(options = {}) { const path = this._endpoints.collection(this.name); return this.client.paginatedDelete(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), }); } /** * Retrieves the list of groups in the current bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.filters={}] The filters object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Array} [options.fields] Limit response to * just some fields. * @return {Promise<Array<Object>, Error>} */ async listGroups(options = {}) { const path = this._endpoints.group(this.name); return this.client.paginatedList(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), }); } /** * Fetches a group in current bucket. * * @param {String} id The group id. * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Object} [options.query] Query parameters to pass in * the request. This might be useful for features that aren't * yet supported by this library. * @param {Array} [options.fields] Limit response to * just some fields. * @return {Promise<Object, Error>} */ async getGroup(id, options = {}) { const path = this._endpoints.group(this.name, id); const request = { headers: this._getHeaders(options), path, }; return this.client.execute(request, { retry: this._getRetry(options), query: options.query, fields: options.fields, }); } /** * 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. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<Object, Error>} */ async createGroup(id, members = [], options = {}) { const data = { ...options.data, id, members, }; const path = this._endpoints.group(this.name, id); const { permissions } = options; const request = requests.createRequest(path, { data, permissions }, { headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * 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.retry=0] Number of retries to make * when faced with transient errors. * @param {Number} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async updateGroup(group, options = {}) { if (!(0, utils_1.isObject)(group)) { throw new Error("A group object is required."); } if (!group.id) { throw new Error("A group id is required."); } const data = { ...options.data, ...group, }; const path = this._endpoints.group(this.name, group.id); const { patch, permissions } = options; const { last_modified } = { ...data, ...options }; const request = requests.updateRequest(path, { data, permissions }, { last_modified, patch, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * 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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Boolean} [options.safe] The safe option. * @param {Number} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async deleteGroup(group, options = {}) { const groupObj = (0, utils_1.toDataBody)(group); const { id } = groupObj; const { last_modified } = { ...groupObj, ...options }; const path = this._endpoints.group(this.name, id); const request = requests.deleteRequest(path, { last_modified, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * Deletes groups from the current bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.filters={}] The filters object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Array} [options.fields] Limit response to * just some fields. * @return {Promise<Array<Object>, Error>} */ async deleteGroups(options = {}) { const path = this._endpoints.group(this.name); return this.client.paginatedDelete(path, options, { headers: this._getHeaders(options), retry: this._getRetry(options), }); } /** * Retrieves the list of permissions for this bucket. * * @param {Object} [options={}] The options object. * @param {Object} [options.headers] The headers object option. * @param {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @return {Promise<Object, Error>} */ async getPermissions(options = {}) { const request = { headers: this._getHeaders(options), path: this._endpoints.bucket(this.name), }; const { permissions } = (await this.client.execute(request, { retry: this._getRetry(options), })); return 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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Object} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async setPermissions(permissions, options = {}) { if (!(0, utils_1.isObject)(permissions)) { throw new Error("A permissions object is required."); } const path = this._endpoints.bucket(this.name); const { last_modified } = options; const data = { last_modified }; const request = requests.updateRequest(path, { data, permissions }, { headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * Append principals to the bucket permissions. * * @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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Object} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async addPermissions(permissions, options = {}) { if (!(0, utils_1.isObject)(permissions)) { throw new Error("A permissions object is required."); } const path = this._endpoints.bucket(this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest(path, permissions, "add", { last_modified, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * Remove principals from the bucket permissions. * * @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 {Number} [options.retry=0] Number of retries to make * when faced with transient errors. * @param {Object} [options.last_modified] The last_modified option. * @return {Promise<Object, Error>} */ async removePermissions(permissions, options = {}) { if (!(0, utils_1.isObject)(permissions)) { throw new Error("A permissions object is required."); } const path = this._endpoints.bucket(this.name); const { last_modified } = options; const request = requests.jsonPatchPermissionsRequest(path, permissions, "remove", { last_modified, headers: this._getHeaders(options), safe: this._getSafe(options), }); return this.client.execute(request, { retry: this._getRetry(options), }); } /** * 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 {Number} [options.retry=0] The retry option. * @param {Boolean} [options.aggregate] Produces a grouped result object. * @return {Promise<Object, Error>} */ async batch(fn, options = {}) { return this.client.batch(fn, { bucket: this.name, headers: this._getHeaders(options), retry: this._getRetry(options), safe: this._getSafe(options), aggregate: !!options.aggregate, }); } } exports.default = Bucket; __decorate([ (0, utils_1.capable)(["history"]) ], Bucket.prototype, "listHistory", null);