kinto
Version:
An Offline-First JavaScript client for Kinto.
637 lines (636 loc) • 25.7 kB
JavaScript
"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);