para-client-js 1.40.2 → 1.40.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["urlEncode"],"sources":["../lib/ParaObject.js","../lib/Pager.js","../lib/Constraint.js","../lib/index.js"],"sourcesContent":["/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n/* global encodeURIComponent */\n\n'use strict';\n\nexport default class ParaObject {\n constructor(id, type) {\n this.id = id || null;\n this.type = type || 'sysprop';\n this.name = 'ParaObject';\n this.stored = true;\n this.indexed = true;\n this.cached = true;\n this.version = 0;\n }\n /**\n * The id of an object. Usually an autogenerated unique string of numbers.\n *\n * @return the id\n */\n getId() {\n return this.id;\n }\n /**\n * Sets a new id. Must not be null or empty.\n *\n * @param {String} id the new id\n */\n setId(id) {\n this.id = id;\n }\n /**\n * The name of the object. Can be anything.\n *\n * @return {String} the name. default: [type id]\n */\n getName() {\n return this.name;\n }\n /**\n * Sets a new name. Must not be null or empty.\n *\n * @param {String} name the new name\n */\n setName(name) {\n this.name = name;\n }\n /**\n * The application name. Added to support multiple separate apps.\n * Every object must belong to an app.\n *\n * @return {String} the app id (name). default: para\n */\n getAppid() {\n return this.appid;\n }\n /**\n * Sets a new app name. Must not be null or empty.\n *\n * @param {String} appid the new app id (name)\n */\n setAppid(appid) {\n this.appid = appid;\n }\n /**\n * The id of the parent object.\n *\n * @return {String} the id of the parent or null\n */\n getParentid() {\n return this.parentid;\n }\n /**\n * Sets a new parent id. Must not be null or empty.\n *\n * @param {String} parentid a new id\n */\n setParentid(parentid) {\n this.parentid = parentid;\n }\n /**\n * The name of the object's class. This is equivalent to {@link Class#getSimpleName()}.toLowerCase().\n *\n * @return {String} the simple name of the class\n */\n getType() {\n return this.type;\n }\n /**\n * Sets a new object type. Must not be null or empty.\n *\n * @param {String} type a new type\n */\n setType(type) {\n this.type = type;\n }\n /**\n * The id of the user who created this. Should point to a {@link User} id.\n *\n * @return {String} the id or null\n */\n getCreatorid() {\n return this.creatorid;\n }\n /**\n * Sets a new creator id. Must not be null or empty.\n *\n * @param {String} creatorid a new id\n */\n setCreatorid(creatorid) {\n this.creatorid = creatorid;\n }\n /**\n * The URI of this object. For example: /user/123.\n *\n * @return {String} the URI\n */\n getObjectURI() {\n var def = '/' + urlEncode(this.getType());\n return this.id ? def + '/' + urlEncode(this.id) : def;\n }\n /**\n * The time when the object was created, in milliseconds.\n *\n * @return {Number} the timestamp of creation\n */\n getTimestamp() {\n return this.timestamp;\n }\n /**\n * Sets the timestamp.\n *\n * @param {Number} timestamp a new timestamp in milliseconds.\n */\n setTimestamp(timestamp) {\n this.timestamp = timestamp;\n }\n /**\n * The last time this object was updated. Timestamp in ms.\n *\n * @return {Number} timestamp in milliseconds\n */\n getUpdated() {\n return this.updated;\n }\n /**\n * Sets the last updated timestamp.\n *\n * @param {Number} updated a new timestamp\n */\n setUpdated(updated) {\n this.updated = updated;\n }\n /**\n * The tags associated with this object. Tags must not be null or empty.\n *\n * @return {Array} a set of tags, or an empty set\n */\n getTags() {\n return this.id;\n }\n /**\n * Merges the given tags with existing tags.\n *\n * @param {Array} tags the additional tags, or clears all tags if set to null\n */\n setTags(tags) {\n this.tags = tags;\n }\n /**\n * The votes associated with this object.\n *\n * @return {Number} votes or 0\n */\n getVotes() {\n return this.votes;\n }\n /**\n * Sets the votes.\n *\n * @param {Number} votes\n */\n setVotes(votes) {\n this.votes = votes;\n }\n /**\n * The version of this object.\n *\n * @return {Number} version\n */\n getVersion() {\n return this.version;\n }\n /**\n * Sets the version.\n *\n * @param {Number} version\n */\n setVersion(version) {\n this.version = version;\n }\n /**\n * Boolean flag which controls whether this object is stored\n * in the database or not. Default is true.\n *\n * @return {Boolean} true if this object is stored in DB.\n */\n getStored() {\n return this.stored;\n }\n /**\n * Sets the \"isStored\" flag.\n *\n * @param {Boolean} isStored when set to true, object is stored in DB.\n */\n setStored(isStored) {\n this.stored = isStored;\n }\n /**\n * Boolean flat which controls whether this object is indexed\n * by the search engine. Default is true.\n *\n * @return {Boolean} true if this object is indexed\n */\n getIndexed() {\n return this.indexed;\n }\n /**\n * Sets the \"isIndexed\" flag.\n *\n * @param {Boolean} isIndexed when set to true, object is indexed.\n */\n setIndexed(isIndexed) {\n this.indexed = isIndexed;\n }\n /**\n * Boolean flat which controls whether this object is cached.\n * Default is true.\n *\n * @return {Boolean} true if this object is cached on update() and create().\n */\n getCached() {\n return this.cached;\n }\n /**\n * Sets the \"isCached\" flag.\n *\n * @param {Boolean} isCached when set to true, object is cached.\n */\n setCached(isCached) {\n this.cached = isCached;\n }\n /**\n * Populates this object with data from a map.\n * @param {Object} map\n * @return {ParaObject} this\n */\n setFields(map) {\n if (map && map instanceof Object) {\n for (var key in map) {\n this[key] = map[key];\n }\n }\n return this;\n }\n}\n\nfunction urlEncode(path) {\n return encodeURIComponent(path).replace(/[!'()*]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n'use strict';\n\n/**\n * This class stores pagination data. It limits the results for queries in the DAO\n * and Search objects and also counts the total number of results that are returned.\n * @author Alex Bogdanovski <alex@erudika.com>\n * @param {Number} page page number to start from\n * @param {String} sortby sort by field\n * @param {Boolean} desc sort in descending or ascending order\n * @param {Number} limit limits the results\n *\n * @property {Number} count the total number of results\n * @property {String} lastKey reserved use\n * @property {Array} select selected fields filter for returning only part of an object\n * @returns {Pager} a pager\n */\nexport default class Pager {\n constructor(page, sortby, desc, limit) {\n this.page = page || 1;\n this.count = 0;\n this.sortby = sortby || null;\n this.desc = desc || true;\n this.limit = limit || 30;\n this.name = '';\n this.lastKey = null;\n this.select = null; // [field1,field2]\n }\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n'use strict';\n\n/**\n * Represents a validation constraint.\n * @author Alex Bogdanovski <alex@erudika.com>\n * @param {String} constraintName name\n * @param {Object} constraintPayload payload\n * @returns {Constraint}\n */\nexport default class Constraint {\n constructor(constraintName, constraintPayload) {\n var name = constraintName;\n var payload = constraintPayload;\n\n /**\n * The constraint name.\n * @returns {String} a name\n */\n this.getName = function () {\n return name;\n };\n\n /**\n * Sets the name of the constraint.\n * @param {String} n name\n */\n this.setName = function (n) {\n name = n;\n };\n\n /**\n * The payload (a map)\n * @returns {Object} an object\n */\n this.getPayload = function () {\n return payload;\n };\n\n /**\n * Sets the payload.\n * @param {Object} p the payload object\n */\n this.setPayload = function (p) {\n payload = p;\n };\n }\n /**\n * The 'required' constraint - marks a field as required.\n * @returns {Constraint}\n */\n static required() {\n return new Constraint('required', { message: 'messages.required' });\n }\n /**\n * The 'min' constraint - field must contain a number larger than or equal to min.\n * @param {Number} min the minimum value\n * @returns {Constraint}\n */\n static min(min) {\n return new Constraint('min', {\n value: min || 0,\n message: 'messages.min'\n });\n }\n /**\n * The 'max' constraint - field must contain a number smaller than or equal to max.\n * @param {Number} max the maximum value\n * @returns {Constraint}\n */\n static max(max) {\n return new Constraint('max', {\n value: max || 0,\n message: 'messages.max'\n });\n }\n /**\n * The 'size' constraint - field must be a String, Object or Array\n * with a given minimum and maximum length.\n * @param {Number} min the minimum length\n * @param {Number} max the maximum length\n * @returns {Constraint}\n */\n static size(min, max) {\n return new Constraint('size', {\n min: min || 0,\n max: max || 0,\n message: 'messages.size'\n });\n }\n /**\n * The 'digits' constraint - field must be a Number or String containing digits where the\n * number of digits in the integral part is limited by 'integer', and the\n * number of digits for the fractional part is limited\n * by 'fraction'.\n * @param {Number} i the max number of digits for the integral part\n * @param {Number} f the max number of digits for the fractional part\n * @returns {Constraint}\n */\n static digits(i, f) {\n return new Constraint('digits', {\n integer: i || 0,\n fraction: f || 0,\n message: 'messages.digits'\n });\n }\n /**\n * The 'pattern' constraint - field must contain a value matching a regular expression.\n * @param {String} regex a regular expression\n * @returns {Constraint}\n */\n static pattern(regex) {\n return new Constraint('pattern', {\n value: regex || '',\n message: 'messages.pattern'\n });\n }\n /**\n * The 'email' constraint - field must contain a valid email.\n * @returns {Constraint}\n */\n static email() {\n return new Constraint('email', { message: 'messages.email' });\n }\n /**\n * The 'falsy' constraint - field value must not be equal to 'true'.\n * @returns {Constraint}\n */\n static falsy() {\n return new Constraint('false', { message: 'messages.false' });\n }\n /**\n * The 'truthy' constraint - field value must be equal to 'true'.\n * @returns {Constraint}\n */\n static truthy() {\n return new Constraint('true', { message: 'messages.true' });\n }\n /**\n * The 'future' constraint - field value must be a Date or a timestamp in the future.\n * @returns {Constraint}\n */\n static future() {\n return new Constraint('future', { message: 'messages.future' });\n }\n /**\n * The 'past' constraint - field value must be a Date or a timestamp in the past.\n * @returns {Constraint}\n */\n static past() {\n return new Constraint('past', { message: 'messages.past' });\n }\n /**\n * The 'url' constraint - field value must be a valid URL.\n * @returns {Constraint}\n */\n static url() {\n return new Constraint('url', { message: 'messages.url' });\n }\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n/* global encodeURIComponent */\n\n'use strict';\n\nvar err = console.error;\nimport lodash from 'lodash';\nimport assert from 'assert';\nimport apiClient from 'superagent';\nimport aws4 from 'aws4';\nimport ParaObject from './ParaObject.js';\nimport Pager from './Pager.js';\nimport Constraint from './Constraint.js';\n\nconst DEFAULT_ENDPOINT = 'https://paraio.com';\nconst DEFAULT_PATH = '/v1/';\nconst JWT_PATH = '/jwt_auth';\nconst SEPARATOR = ':';\n\nconst {\n isEmpty,\n endsWith,\n startsWith,\n noop,\n isArray,\n isUndefined,\n isString,\n isFunction,\n merge,\n isInteger,\n isBoolean\n} = lodash;\nconst { sign } = aws4;\n\n/**\n * JavaScript client for communicating with a Para API server.\n * @param {String} accessKey Para access key\n * @param {String} secretKey Para access key\n * @param {Object} options\n * @property {String} endpoint the API endpoint (default: paraio.com)\n * @property {String} apiPath the request path (default: /v1/)\n * @author Alex Bogdanovski <alex@erudika.com>\n */\nexport default class ParaClient {\n constructor(accessKey, secretKey, options) {\n if (!secretKey || isEmpty(secretKey.trim())) {\n console.warn(\"Secret key not provided. Make sure you call 'signIn()' first.\");\n }\n options = options || {};\n this.accessKey = accessKey;\n this.endpoint = options.endpoint || DEFAULT_ENDPOINT;\n this.apiPath = options.apiPath || DEFAULT_PATH;\n this.apiRequestTimeout = options.apiRequestTimeout || 120 * 1000;\n this.tokenKey = null;\n this.tokenKeyExpires = null;\n this.tokenKeyNextRefresh = null;\n if (!endsWith(this.apiPath, '/')) {\n this.apiPath += '/';\n }\n\n var that = this;\n var secret = secretKey;\n\n this.getFullPath = function (resourcePath) {\n if (resourcePath && startsWith(resourcePath, JWT_PATH)) {\n if ((that.apiPath.match(/\\//g) || []).length > 2) {\n return that.apiPath.substring(0, that.apiPath.indexOf('/', 1)) + resourcePath;\n }\n return resourcePath;\n }\n if (!resourcePath) {\n resourcePath = '';\n } else if (resourcePath[0] === '/') {\n resourcePath = resourcePath.substring(1);\n }\n return that.apiPath + resourcePath;\n };\n\n this.setSecret = function (sec) {\n secret = sec;\n };\n\n /**\n * Clears the JWT token from memory, if such exists.\n */\n this.clearAccessToken = function () {\n that.tokenKey = null;\n that.tokenKeyExpires = null;\n that.tokenKeyNextRefresh = null;\n };\n\n /**\n * @returns the JWT access token, or null if not signed in\n */\n this.getAccessToken = function () {\n return that.tokenKey;\n };\n\n /**\n * Sets the JWT access token.\n * @param {String} token a valid token\n */\n this.setAccessToken = function (token) {\n if (token && token.length > 1) {\n try {\n var parts = token.split('.');\n var decoded = JSON.parse(decode(parts[1]));\n if (decoded && decoded['exp']) {\n that.tokenKeyExpires = decoded['exp'];\n that.tokenKeyNextRefresh = decoded['refresh'];\n }\n } catch (e) {\n that.tokenKeyExpires = null;\n that.tokenKeyNextRefresh = null;\n }\n }\n that.tokenKey = token;\n };\n\n /**\n * @param {Function} fn callback (optional)\n * @returns {Promise} the version of Para server\n */\n this.getServerVersion = async function (fn) {\n fn = fn || noop;\n return that.getEntity(that.invokeGet('')).then(function (result) {\n var ver = result.version || 'unknown';\n fn(ver);\n return ver;\n });\n };\n\n /**\n * Invoke a GET request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} params query parameters\n * @returns {Object} response\n */\n this.invokeGet = async function (resourcePath, params) {\n return that.invokeSignedRequest(\n 'GET',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n params\n );\n };\n\n /**\n * Invoke a POST request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePost = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'POST',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a PUT request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePut = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'PUT',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a PATCH request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePatch = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'PATCH',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a DELETE request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} params query parameters\n * @returns {Object} response\n */\n this.invokeDelete = async function (resourcePath, params) {\n return that.invokeSignedRequest(\n 'DELETE',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n params\n );\n };\n\n this.invokeSignedRequest = async function (\n httpMethod,\n endpointURL,\n reqPath,\n headers,\n params,\n jsonEntity\n ) {\n if (!accessKey || isEmpty(accessKey.trim())) {\n throw new Error('Blank access key: ' + httpMethod + ' ' + reqPath);\n }\n var doSign = true;\n if (!secret && !that.tokenKey && isEmpty(headers)) {\n headers = { Authorization: 'Anonymous ' + accessKey };\n doSign = false;\n }\n var host = endpointURL;\n if (startsWith(endpointURL, 'http://')) {\n host = endpointURL.substring(7);\n } else if (startsWith(endpointURL, 'https://')) {\n host = endpointURL.substring(8);\n }\n\n var opts = {\n service: 'para',\n method: httpMethod,\n host: host,\n path: uriEncodeAWSV4(reqPath),\n headers: headers || {}\n };\n\n // make sure that only the first parameter value is used for generating the signature\n // multi-valued parameters are reduced to single value\n // there's no spec for this case, so choose first param in array\n if (params && params instanceof Object && !isEmpty(params)) {\n opts.path += '?';\n var paramsObj = {};\n for (var key in params) {\n var value = params[key];\n if (isArray(value)) {\n if (!isEmpty(value)) {\n paramsObj[key] = value[0] !== null ? value[0] : '';\n }\n } else {\n paramsObj[key] = value !== null ? value : '';\n }\n }\n opts.path += new URLSearchParams(paramsObj).toString();\n }\n\n if (jsonEntity) {\n opts.body = JSON.stringify(jsonEntity);\n opts.headers['Content-Type'] = 'application/json; charset=UTF-8';\n }\n\n if (that.tokenKey !== null) {\n // make sure you don't create an infinite loop!\n if (!(httpMethod === 'GET' && reqPath === JWT_PATH)) {\n that.refreshToken();\n }\n opts.headers['Authorization'] = 'Bearer ' + that.tokenKey;\n } else if (doSign) {\n opts.doNotEncodePath = true;\n sign(opts, { accessKeyId: accessKey, secretAccessKey: secret });\n }\n\n if (typeof window !== 'undefined') {\n // don't set the 'Host' header, the browser does that.\n delete opts.headers['Host'];\n }\n opts.headers['User-Agent'] = 'Para client for JavaScript';\n try {\n return apiClient(opts.method, endpointURL + reqPath)\n .query(params)\n .set(opts.headers)\n .timeout({ response: that.apiRequestTimeout, deadline: that.apiRequestTimeout })\n .send(opts.body);\n } catch (e) {\n err('ParaClient request failed: ' + e);\n return Promise.reject(e);\n }\n };\n\n /**\n * Parses a search query response and extracts the objects from it.\n * @param {String} queryType type of search query\n * @param {Object} params query params\n * @param {Function} fn callback\n * @returns {Object} response\n */\n this.find = async function (queryType, params, fn) {\n if (params && params instanceof Object && !isEmpty(params)) {\n var qType = queryType ? '/' + queryType : '/default';\n if (!params['type']) {\n return that.getEntity(that.invokeGet('search' + qType, params), fn);\n } else {\n return that.getEntity(that.invokeGet(params['type'] + '/search' + qType, params), fn);\n }\n } else {\n var res = {\n items: [],\n totalHits: 0\n };\n fn(res);\n return resolve(res);\n }\n };\n\n /**\n * Deserializes a Response object to POJO of some type.\n * @param {Object} req request\n * @param {Function} callback callback\n * @param {Boolean} returnRawJSON true if raw JSON should be returned as string\n * @returns {Object} a ParaObject\n */\n this.getEntity = async function (req, callback, returnRawJSON) {\n callback = callback || noop;\n var rawJSON = isUndefined(returnRawJSON) ? true : returnRawJSON;\n return req.then(function (res) {\n //console.log(\"DEBUG \", req.method, req.url, res.status);\n var code = res.status;\n if (code === 200 || code === 201 || code === 304) {\n if (rawJSON) {\n var result;\n try {\n if (!isEmpty(res.body) || res.text === '{ }' || res.text === '{}') {\n result = res.body;\n } else {\n result = res.text;\n }\n } catch (exc) {\n result = res.text;\n }\n callback(result);\n return resolve(result);\n } else {\n var obj = new ParaObject();\n obj.setFields(res.body);\n callback(obj);\n return resolve(obj);\n }\n } else if (code !== 404 || code !== 304 || code !== 204) {\n var error = res.body || new Error('ParaClient request failed.');\n if (error && error['code']) {\n var msg = error['message'] ? error['message'] : 'error';\n err(msg + ' - ' + error['code']);\n } else {\n err(code + ' - ' + res.text);\n }\n callback(null, error);\n return Promise.reject(error);\n } else {\n var error1 = new Error('ParaClient request failed.');\n callback(null, error1);\n reject(error1);\n }\n });\n };\n\n /**\n * Deserializes ParaObjects from a JSON array (the \"items:[]\" field in search results).\n * @param {Array} items a list of deserialized maps\n * @returns {Array} a list of ParaObjects\n */\n this.getItemsFromList = function (items) {\n if (items && items instanceof Array && !isEmpty(items)) {\n var objects = [];\n for (var item of items) {\n if (item) {\n var p = new ParaObject();\n p.setFields(item);\n objects.push(p);\n }\n }\n return objects;\n }\n return [];\n };\n\n /**\n * Converts a list of Maps to a List of ParaObjects, at a given path within the JSON tree structure.\n * @param {Object} result the response body for an API request\n * @param {String} at the path (field) where the array of objects is located\n * @param {Pager} pager a pager\n * @returns {Array} a list of ParaObjects\n */\n this.getItemsAt = function (result, at, pager) {\n if (result && at && result[at]) {\n if (pager && result.totalHits) {\n pager.count = result.totalHits;\n }\n if (pager && result.lastKey) {\n pager.lastKey = result.lastKey;\n }\n return that.getItemsFromList(result[at]);\n }\n return [];\n };\n\n /**\n * Converts a list of Maps to a List of ParaObjects.\n * @param {Object} result the response body for an API request\n * @param {Pager} pager a pager\n * @returns {Array} a list of ParaObjects\n */\n this.getItems = function (result, pager) {\n return that.getItemsAt(result, 'items', pager);\n };\n\n /**\n * Converts a {Pager} object to query parameters.\n * @param {Pager} pager a pager\n * @returns {Object} parameters map\n */\n this.pagerToParams = function (pager) {\n var map = {};\n if (pager) {\n map['page'] = pager.page;\n map['desc'] = pager.desc;\n map['limit'] = pager.limit;\n if (pager.lastKey) {\n map['lastKey'] = pager.lastKey;\n }\n if (pager.sortby) {\n map['sort'] = pager.sortby;\n }\n if (pager.select && pager.select.length) {\n map['select'] = pager.select;\n }\n }\n return map;\n };\n }\n /**\n * Returns the App for the current access key (appid).\n * @param {Function} fn callback (optional)\n * @returns {Promise} a promise\n */\n async getApp(fn) {\n return this.me(fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t PERSISTENCE\n /////////////////////////////////////////////\n /**\n * Persists an object to the data store. If the object's type and id are given,\n * then the request will be a PUT request and any existing object will be\n * overwritten.\n * @param {ParaObject} obj the object to create\n * @param {Function} fn callback (optional)\n * @returns {Promise} the same object with assigned id or null if not created.\n */\n async create(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj) {\n fn(null);\n return resolve(null);\n }\n if (!obj.getId() || !obj.getType()) {\n return this.getEntity(this.invokePost(urlEncode(obj.getType()), obj), fn, false);\n } else {\n return this.getEntity(this.invokePut(obj.getObjectURI(), obj), fn, false);\n }\n }\n /**\n * Retrieves an object from the data store.\n * @param {String} type the type of the object\n * @param {String} id the id of the object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the retrieved object or null if not found\n */\n async read(type, id, fn) {\n fn = fn || noop;\n if (!id) {\n fn(null);\n return resolve(null);\n }\n if (!type) {\n return this.getEntity(this.invokeGet('_id/' + urlEncode(id)), fn, false);\n } else {\n return this.getEntity(this.invokeGet(urlEncode(type) + '/' + urlEncode(id)), fn, false);\n }\n }\n /**\n * Updates an object permanently. Supports partial updates.\n * @param {ParaObject} obj the object to update\n * @param {Function} fn callback (optional)\n * @returns {Promise} the updated object\n */\n async update(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj) {\n fn(null);\n return resolve(null);\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), obj), fn, false);\n }\n /**\n * Deletes an object permanently.\n * @param {ParaObject} obj object to delete\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async delete(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (obj) {\n return this.getEntity(this.invokeDelete(obj.getObjectURI()), fn);\n } else {\n fn(null);\n return resolve(null);\n }\n }\n /**\n * Saves multiple objects to the data store.\n * @param {Array} objects a list of ParaObjects to create\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async createAll(objects, fn) {\n fn = fn || noop;\n checkParaObjects(objects);\n if (!objects || !isArray(objects) || !objects[0]) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokePost('_batch', objects)).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Retrieves multiple objects from the data store.\n * @param {Array} keys a list of object ids\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async readAll(keys, fn) {\n fn = fn || noop;\n if (!keys || !isArray(keys) || isEmpty(keys)) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokeGet('_batch', { ids: keys })).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Updates multiple objects.\n * @param {Array} objects a list of ParaObjects to update\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async updateAll(objects, fn) {\n fn = fn || noop;\n checkParaObjects(objects);\n if (!objects || !isArray(objects) || isEmpty(objects)) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokePatch('_batch', objects)).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Deletes multiple objects.\n * @param {Function} fn callback (optional)\n * @param {Array} keys the ids of the objects to delete\n * @returns {Promise} promise\n */\n async deleteAll(keys, fn) {\n fn = fn || noop;\n if (keys && isArray(keys)) {\n return this.getEntity(this.invokeDelete('_batch', { ids: keys }), fn);\n } else {\n fn(null);\n return resolve(null);\n }\n }\n /**\n * Returns a list all objects found for the given type.\n * The result is paginated so only one page of items is returned, at a time.\n * @param {String} type the type of objects to search for\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async list(type, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n if (!type) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokeGet(urlEncode(type), this.pagerToParams(pager))).then(\n function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n }\n );\n }\n /////////////////////////////////////////////\n //\t\t\t\t SEARCH\n /////////////////////////////////////////////\n /**\n * Simple id search.\n * @param {String} id the id\n * @param {Function} fn callback (optional)\n * @returns {Promise} the object if found or null\n */\n async findById(id, fn) {\n fn = fn || noop;\n var that = this;\n return this.find('id', { id: id }).then(function (results) {\n var list = that.getItems(results);\n var res = isEmpty(list) ? null : list;\n fn(res);\n return res;\n });\n }\n /**\n * Simple multi id search.\n * @param {Array} ids a list of ids to search for\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects if found or []\n */\n async findByIds(ids, fn) {\n fn = fn || noop;\n var that = this;\n return this.find('ids', { ids: ids }).then(function (results) {\n var res = that.getItems(results);\n fn(res);\n return res;\n });\n }\n /**\n * Search for address objects in a radius of X km from a given point.\n * @param {String} type the type of object to search for\n * @param {String} query the query string\n * @param {Number} radius the radius of the search circle\n * @param {Number} lat latitude\n * @param {Number} lng longitude\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findNearby(type, query, radius, lat, lng, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n latlng: lat + ',' + lng,\n radius: radius,\n q: query,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('nearby', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have a property which value starts with a given prefix.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {String} prefix the prefix\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findPrefix(type, field, prefix, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n prefix: prefix,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('prefix', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Simple query string search. This is the basic search method.\n * @param {String} type the type of object to search for\n * @param {String} query the query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findQuery(type, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n q: query,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches within a nested field. The objects of the given type must contain a nested field \"nstd\".\n * @param {String} type the type of object to search for\n * @param {String} field the name of the field to target (within a nested field \"nstd\")\n * @param {String} query the query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findNestedQuery(type, field, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n q: query,\n field: field,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('nested', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have similar property values to a given text. A \"find like this\" query.\n * @param {String} type the type of object to search for\n * @param {String} filterKey exclude an object with this key from the results (optional)\n * @param {Array} fields a list of property names\n * @param {String} liketext text to compare to\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findSimilar(type, filterKey, fields, liketext, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n fields: fields || null,\n filterid: filterKey,\n like: liketext,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('similar', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects tagged with one or more tags.\n * @param {String} type the type of object to search for\n * @param {Array} tags the list of tags\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTagged(type, tags, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n tags: tags || null,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('tagged', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for Tag objects.\n * This method might be deprecated in the future.\n * @param {String} keyword the tag keyword to search for\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTags(keyword, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n keyword = keyword ? keyword + '*' : '*';\n return this.findWildcard('tag', 'tag', keyword, pager, fn);\n }\n /**\n * Searches for objects having a property value that is in list of possible values.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {Object} terms a map of terms (property values)\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTermInList(type, field, terms, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n terms: terms,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('in', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have properties matching some given values. A terms query.\n * @param {String} type the type of object to search for\n * @param {Object} terms a map of fields (property names) to terms (property values)\n * @param {Boolean} matchAll match all terms. If true - AND search, if false - OR search\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTerms(type, terms, matchAll, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n terms = terms || {};\n matchAll = matchAll || true;\n var params = {\n matchall: matchAll\n };\n var list = [];\n for (var key in terms) {\n if (terms[key]) {\n list.push(key + SEPARATOR + terms[key]);\n }\n }\n if (!isEmpty(terms)) {\n params['terms'] = list;\n }\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('terms', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have a property with a value matching a wildcard query.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {String} wildcard wildcard query string. For example \"cat*\".\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findWildcard(type, field, wildcard, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n q: wildcard,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('wildcard', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Counts indexed objects matching a set of terms/values.\n * @param {String} type the type of object to search for\n * @param {Object} terms a map of fields (property names) to terms (property values)\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of results found\n */\n async getCount(type, terms, fn) {\n fn = fn || noop;\n if (type === null && terms === null) {\n fn(0);\n return resolve(0);\n }\n terms = terms || {};\n var params = {};\n var pager = new Pager();\n var that = this;\n params['type'] = type;\n if (isEmpty(terms)) {\n return this.find('count', params).then(function (results) {\n that.getItems(results, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n } else {\n var list = [];\n for (var key in terms) {\n if (terms[key]) {\n list.push(key + SEPARATOR + terms[key]);\n }\n }\n if (!isEmpty(terms)) {\n params['terms'] = list;\n }\n params['count'] = 'true';\n return this.find('terms', params).then(function (results) {\n that.getItems(results, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n }\n /////////////////////////////////////////////\n //\t\t\t\t LINKS\n /////////////////////////////////////////////\n /**\n * Count the total number of links between this object and another type of object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of links for the given object\n */\n async countLinks(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(0);\n return resolve(0);\n }\n var params = {};\n params['count'] = 'true';\n var pager = new Pager();\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n that.getItems(result, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n /**\n * Returns all objects linked to the given one. Only applicable to many-to-many relationships.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of linked objects\n */\n async getLinkedObjects(obj, type2, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, this.pagerToParams(pager))).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches through all linked objects in many-to-many relationships.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} field the name of the field to target (within a nested field \"nstd\")\n * @param {String} query a query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of linked objects\n */\n async findLinkedObjects(obj, type2, field, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {\n field: field,\n q: query || '*'\n };\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Checks if this object is linked to another.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if the two are linked\n */\n async isLinked(obj, type2, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2 || !id2) {\n fn(false);\n return resolve(false);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2) + '/' + urlEncode(id2);\n return this.getEntity(this.invokeGet(url)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Checks if a given object is linked to this one.\n * @param {ParaObject} obj the object to execute this method on\n * @param {ParaObject} toObj the other object\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if linked\n */\n async isLinkedToObject(obj, toObj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n checkParaObject(toObj);\n if (!obj || !obj.getId() || !toObj || !toObj.getId()) {\n fn(false);\n return resolve(false);\n }\n return this.isLinked(obj, toObj.getType(), toObj.getId(), fn);\n }\n /**\n * Links an object to this one in a many-to-many relationship.\n * Only a link is created. Objects are left untouched.\n * The type of the second object is automatically determined on read.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} the id of the Linker object that is created\n */\n async link(obj, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !id2) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(id2);\n return this.getEntity(this.invokePost(url), fn);\n }\n /**\n * Unlinks an object from this one.\n * Only a link is deleted. Objects are left untouched.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async unlink(obj, type2, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2 || !id2) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2) + '/' + urlEncode(id2);\n return this.getEntity(this.invokeDelete(url), fn);\n }\n /**\n * Unlinks all objects that are linked to this one.\n * Deletes all Linker objects.\n * Only the links are deleted. Objects are left untouched.\n * @param {ParaObject} obj the object to execute this method on\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async unlinkAll(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId()) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links/';\n return this.getEntity(this.invokeDelete(url), fn);\n }\n /**\n * Count the total number of child objects for this object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of links\n */\n async countChildren(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(0);\n return resolve(0);\n }\n var params = {};\n params['count'] = 'true';\n params['childrenonly'] = 'true';\n var pager = new Pager();\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n that.getItems(result, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n /**\n * Returns all child objects linked to this object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} field the field name to use as filter\n * @param {String} term the field value to use as filter\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of ParaObject in a one-to-many relationship with this object\n */\n async getChildren(obj, type2, field, term, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {};\n params['childrenonly'] = 'true';\n if (field) {\n params['field'] = field;\n }\n if (term) {\n params['term'] = term;\n }\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Search through all child objects. Only searches child objects directly\n * connected to this parent via the `parentid` field.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} query a query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of ParaObject in a one-to-many relationship with this object\n */\n async findChildren(obj, type2, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {\n childrenonly: 'true',\n q: query || '*'\n };\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Deletes all child objects permanently.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async deleteChildren(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(null);\n return resolve(null);\n }\n var params = {};\n params['childrenonly'] = 'true';\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n return this.getEntity(this.invokeDelete(url, params), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t UTILS\n /////////////////////////////////////////////\n /**\n * Generates a new unique id.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a new id\n */\n async newId(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeGet('utils/newid')).then(function (result) {\n var res = result ? result : '';\n fn(res);\n return res;\n });\n }\n /**\n * Returns the current timestamp.\n * @param {Function} fn callback (optional)\n * @returns {Promise} timestamp in milliseconds\n */\n async getTimestamp(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeGet('utils/timestamp')).then(function (result) {\n var res = result ? result : 0;\n fn(res);\n return res;\n });\n }\n /**\n * Formats a date in a specific format.\n * @param {String} format the date format\n * @param {String} locale the locale instance\n * @param {Function} fn callback (optional)\n * @returns {Promise} a formatted date\n */\n async formatDate(format, locale, fn) {\n var params = { format: format || '', locale: locale || 'US' };\n return this.getEntity(this.invokeGet('utils/formatdate', params), fn);\n }\n /**\n * Converts spaces to dashes.\n * @param {String} str a string with spaces\n * @param {String} replaceWith a string to replace spaces with\n * @param {Function} fn callback (optional)\n * @returns {Promise} a string with no whitespace\n */\n async noSpaces(str, replaceWith, fn) {\n var params = { string: str || '', replacement: replaceWith || '' };\n return this.getEntity(this.invokeGet('utils/nospaces', params), fn);\n }\n /**\n * Strips all symbols, punctuation, whitespace and control chars from a string.\n * @param {String} str a dirty string\n * @param {Function} fn callback (optional)\n * @returns {Promise} a clean string\n */\n async stripAndTrim(str, fn) {\n var params = { string: str || '' };\n return this.getEntity(this.invokeGet('utils/nosymbols', params), fn);\n }\n /**\n * Converts Markdown to HTML\n * @param {String} markdownString some Markdown\n * @param {Function} fn callback (optional)\n * @returns {Promise} HTML\n */\n async markdownToHtml(markdownString, fn) {\n var params = { md: markdownString || '' };\n return this.getEntity(this.invokeGet('utils/md2html', params), fn);\n }\n /**\n * Returns the number of minutes, hours, months elapsed for a time delta (milliseconds).\n * @param {Number} delta the time delta between two events, in milliseconds\n * @param {Function} fn callback (optional)\n * @returns {Promise} a string like \"5m\", \"1h\"\n */\n async approximately(delta, fn) {\n var params = { delta: delta || 0 };\n return this.getEntity(this.invokeGet('utils/timeago', params), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t MISC\n /////////////////////////////////////////////\n /**\n * Generates a new set of access/secret keys.\n * Old keys are discarded and invalid after this.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of new credentials\n */\n async newKeys(fn) {\n fn = fn || noop;\n var that = this;\n return this.getEntity(this.invokePost('_newkeys')).then(function (result) {\n var res = result || {};\n if (res.secretKey && !isEmpty(res.secretKey.trim())) {\n that.setSecret(res.secretKey);\n }\n fn(res);\n return res;\n });\n }\n /**\n * Returns all registered types for this App.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of plural-singular form of all the registered types.\n */\n async types(fn) {\n return this.getEntity(this.invokeGet('_types'), fn);\n }\n /**\n * Returns the number of objects for each existing type in this App.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of singular object type to object count.\n */\n async typesCount(fn) {\n return this.getEntity(this.invokeGet('_types', { count: 'true' }), fn);\n }\n /**\n * Returns a User or an App that is currently authenticated.\n * @param {String} accessToken a valid JWT access token (optional)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a ParaObject\n */\n async me(accessToken, fn) {\n fn = isFunction(accessToken) ? accessToken : fn || noop;\n if (accessToken && isString(accessToken)) {\n var auth = startsWith(accessToken, 'Bearer') ? accessToken : 'Bearer ' + accessToken;\n var headers = { Authorization: auth };\n return this.getEntity(\n this.invokeSignedRequest('GET', this.endpoint, this.getFullPath('_me'), headers),\n fn,\n false\n );\n } else {\n return this.getEntity(this.invokeGet('_me'), fn, false);\n }\n }\n /**\n * Upvote an object and register the vote in DB.\n * @param {ParaObject} obj the object to receive +1 votes\n * @param {String} voterid the userid of the voter\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if vote was successful\n */\n async voteUp(obj, voterid, expiresAfter, lockedAfter, fn) {\n fn = isFunction(expiresAfter) ? expiresAfter : fn || noop;\n if (!obj || isEmpty(voterid)) {\n fn(false);\n return resolve(false);\n }\n var body = { _voteup: voterid };\n if (isInteger(expiresAfter) && isInteger(lockedAfter)) {\n body['_vote_expires_after'] = expiresAfter;\n body['_vote_locked_after'] = lockedAfter;\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), body)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Downvote an object and register the vote in DB.\n * @param {ParaObject} obj the object to receive +1 votes\n * @param {String} voterid the userid of the voter\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if vote was successful\n */\n async voteDown(obj, voterid, expiresAfter, lockedAfter, fn) {\n fn = isFunction(expiresAfter) ? expiresAfter : fn || noop;\n fn = fn || noop;\n if (!obj || isEmpty(voterid)) {\n fn(false);\n return resolve(false);\n }\n var body = { _votedown: voterid };\n if (isInteger(expiresAfter) && isInteger(lockedAfter)) {\n body['_vote_expires_after'] = expiresAfter;\n body['_vote_locked_after'] = lockedAfter;\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), body)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Rebuilds the entire search index.\n * @param {String} destinationIndex an existing index as destination\n * @param {Function} fn callback (optional)\n * @returns {Promise} a response object with properties \"tookMillis\" and \"reindexed\"\n */\n async rebuildIndex(destinationIndex, fn) {\n fn = fn || noop;\n if (!destinationIndex) {\n return this.getEntity(this.invokePost('_reindex'), fn);\n } else {\n return this.getEntity(\n this.invokeSignedRequest(\n 'POST',\n this.endpoint,\n this.getFullPath('_reindex'),\n {},\n { destinationIndex: destinationIndex }\n ),\n fn\n );\n }\n }\n /////////////////////////////////////////////\n //\t\t\tValidation Constraints\n /////////////////////////////////////////////\n /**\n * Returns the validation constraints map.\n * @param {String} type a type\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints.\n */\n async validationConstraints(type, fn) {\n return this.getEntity(this.invokeGet('_constraints/' + urlEncode(type || '')), fn);\n }\n /**\n * Add a new constraint for a given field.\n * @param {String} type a type\n * @param {String} field a field name\n * @param {Constraint} cons the constraint\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints for this type.\n */\n async addValidationConstraint(type, field, cons, fn) {\n fn = fn || noop;\n checkConstraint(cons);\n if (!type || !field || !cons) {\n fn({});\n return resolve({});\n }\n return this.getEntity(\n this.invokePut(\n '_constraints/' + urlEncode(type) + '/' + field + '/' + cons.getName(),\n cons.getPayload()\n ),\n fn\n );\n }\n /**\n * Removes a validation constraint for a given field.\n * @param {String} type a type\n * @param {String} field a field name\n * @param {String} constraintName the name of the constraint to remove\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints for this type.\n */\n async removeValidationConstraint(type, field, constraintName, fn) {\n fn = fn || noop;\n if (!type || !field || !constraintName) {\n fn({});\n return resolve({});\n }\n return this.getEntity(\n this.invokeDelete('_constraints/' + urlEncode(type) + '/' + field + '/' + constraintName),\n fn\n );\n }\n /////////////////////////////////////////////\n //\t\t\tResource Permissions\n /////////////////////////////////////////////\n /**\n * Returns only the permissions for a given subject (user) of the current app.\n * If subject is not given returns the permissions for all subjects and resources for current app.\n * @param {String} subjectid the subject id (user id)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of subject ids to resource names to a list of allowed methods\n */\n async resourcePermissions(subjectid, fn) {\n if (!subjectid) {\n return this.getEntity(this.invokeGet('_permissions'), fn);\n } else {\n return this.getEntity(this.invokeGet('_permissions/' + urlEncode(subjectid)), fn);\n }\n }\n /**\n * Grants a permission to a subject that allows them to call the specified HTTP methods on a given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Array} permission a set of HTTP methods\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async grantResourcePermission(subjectid, resourcePath, permission, fn) {\n return this.grantResourcePermissions(subjectid, resourcePath, permission, false, fn);\n }\n /**\n * Grants a permission to a subject that allows them to call the specified HTTP methods on a given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Array} permission a set of HTTP methods\n * @param {Boolean} allowGuestAccess if true - all unauthenticated requests will go through, 'false' by default.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async grantResourcePermissions(subjectid, resourcePath, permission, allowGuestAccess, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath || !permission || !isArray(permission)) {\n fn({});\n return resolve({});\n }\n if (allowGuestAccess && subjectid === '*') {\n permission.push('?');\n }\n resourcePath = base64Url(resourcePath);\n return this.getEntity(\n this.invokePut('_permissions/' + urlEncode(subjectid) + '/' + resourcePath, permission),\n fn\n );\n }\n /**\n * Revokes a permission for a subject, meaning they no longer will be able to access the given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async revokeResourcePermission(subjectid, resourcePath, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath) {\n fn({});\n return resolve({});\n }\n resourcePath = base64Url(resourcePath);\n return this.getEntity(\n this.invokeDelete('_permissions/' + urlEncode(subjectid) + '/' + resourcePath),\n fn\n );\n }\n /**\n * Revokes all permission for a subject.\n * @param {String} subjectid subject id (user id)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async revokeAllResourcePermissions(subjectid, fn) {\n fn = fn || noop;\n if (!subjectid) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokeDelete('_permissions/' + urlEncode(subjectid)), fn);\n }\n /**\n * Checks if a subject is allowed to call method X on resource Y.\n * @param {String} subjectid subject id\n * @param {String} resourcePath resource path or object type\n * @param {String} httpMethod HTTP method name\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if allowed\n */\n async isAllowedTo(subjectid, resourcePath, httpMethod, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath || !httpMethod) {\n fn(false);\n return resolve(false);\n }\n resourcePath = base64Url(resourcePath);\n var url = '_permissions/' + urlEncode(subjectid) + '/' + resourcePath + '/' + httpMethod;\n return this.getEntity(this.invokeGet(url))\n .then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n /////////////////////////////////////////////\n //\t\t\tResource Permissions\n /////////////////////////////////////////////\n /**\n * Returns the value of a specific app setting (property) or all settings if key is blank.\n * @param {String} key a key\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map\n */\n async appSettings(key, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key.trim())) {\n return this.getEntity(this.invokeGet('_settings'), fn);\n } else {\n return this.getEntity(this.invokeGet('_settings/' + key.trim()), fn);\n }\n }\n /**\n * Adds or overwrites an app-specific setting.\n * @param {String} key a key\n * @param {Object} value a value\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async addAppSetting(key, value, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key.trim()) || !value || isEmpty(value)) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokePut('_settings/' + key.trim(), { value: value }), fn);\n }\n /**\n * Overwrites all app-specific settings.\n * @param {Object} settings a key-value map of properties\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async setAppSettings(settings, fn) {\n fn = fn || noop;\n if (!settings) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokePut('_settings', settings), fn);\n }\n /**\n * Removes an app-specific setting.\n * @param {String} key a key\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async removeAppSetting(key, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key)) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokeDelete('_settings/' + key.trim()), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\tAccess Tokens\n /////////////////////////////////////////////\n /**\n * Takes an identity provider access token and fetches the user data from that provider.\n * A new User object is created if that user doesn't exist.\n * Access tokens are returned upon successful authentication using one of the SDKs from\n * Facebook, Google, Twitter, etc.\n * <b>Note:</b> Twitter uses OAuth 1 and gives you a token and a token secret.\n * <b>You must concatenate them like this: <code>{oauth_token}:{oauth_token_secret}</code> and\n * use that as the provider access token.</b>\n * @param {String} provider identity provider, e.g. 'facebook', 'google'...\n * @param {String} providerToken access token from a provider like Facebook, Google, Twitter\n * @param {Boolean} rememberJWT if true, the access token returned by Para will be saved and available via getAccessToken()\n * @param {Function} fn callback (optional)\n * @returns {Promise} a User object or null if something failed\n */\n async signIn(provider, providerToken, rememberJWT, fn) {\n var rememberToken = isBoolean(rememberJWT) ? rememberJWT : true;\n fn = isFunction(rememberJWT) ? rememberJWT : fn || noop;\n\n if (provider && providerToken) {\n var credentials = {};\n var that = this;\n credentials['appid'] = that.accessKey;\n credentials['provider'] = provider;\n credentials['token'] = providerToken;\n return this.getEntity(this.invokePost(JWT_PATH, credentials))\n .then(function (result) {\n if (result !== null && result['user'] && result['jwt']) {\n var jwtData = result['jwt'];\n if (jwtData && rememberToken) {\n that.tokenKey = jwtData['access_token'];\n that.tokenKeyExpires = jwtData['expires'];\n that.tokenKeyNextRefresh = jwtData['refresh'];\n }\n var user = new ParaObject();\n user.setFields(result['user']);\n fn(user);\n return user;\n } else {\n that.clearAccessToken();\n }\n fn(null);\n return null;\n })\n .catch(function () {\n fn(null);\n return null;\n });\n }\n fn(null);\n return Promise.reject(new Error('Provider and provider token are required.'));\n }\n /**\n * Clears the JWT access token but token is not revoked.\n * Tokens can be revoked globally per user with revokeAllTokens().\n */\n signOut() {\n this.clearAccessToken();\n }\n /**\n * Refreshes the JWT access token. This requires a valid existing token.\n * Call link signIn() first.\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if token was refreshed\n */\n async refreshToken(fn) {\n fn = fn || noop;\n var that = this;\n var now = new Date().getTime();\n var notExpired = that.tokenKeyExpires !== null && that.tokenKeyExpires > now;\n var canRefresh =\n that.tokenKeyNextRefresh !== null &&\n (that.tokenKeyNextRefresh < now || that.tokenKeyNextRefresh > that.tokenKeyExpires);\n // token present and NOT expired\n if (that.tokenKey !== null && notExpired && canRefresh) {\n return this.getEntity(this.invokeGet(JWT_PATH))\n .then(function (result) {\n if (result !== null && result['user'] && result['jwt']) {\n var jwtData = result['jwt'];\n that.tokenKey = jwtData['access_token'];\n that.tokenKeyExpires = jwtData['expires'];\n that.tokenKeyNextRefresh = jwtData['refresh'];\n fn(true);\n return true;\n } else {\n that.clearAccessToken();\n }\n fn(false);\n return false;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n fn(false);\n return Promise.reject(new Error('Invalid or expired token.'));\n }\n /**\n * Revokes all user tokens for a given user id.\n * This would be equivalent to \"logout everywhere\".\n * <b>Note:</b> Generating a new API secret on the server will also invalidate all client tokens.\n * Requires a valid existing token.\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if successful\n */\n async revokeAllTokens(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeDelete(JWT_PATH))\n .then(function (result) {\n var res = result !== null;\n fn(res);\n return res;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n}\n\nfunction urlEncode(path) {\n return encodeURIComponent(path).replace(/[!'()*]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n\nfunction uriEncodeAWSV4(path) {\n if (!path || !isString(path)) {\n return '';\n }\n return urlEncode(path).replace(/%2F/g, '/');\n}\n\nfunction unescape(str) {\n return (str + '==='.slice((str.length + 3) % 4)).replace(/-/g, '+').replace(/_/g, '/');\n}\n\nfunction decode(str, encoding) {\n return Buffer.from(unescape(str), 'base64').toString(encoding || 'utf8');\n}\n\nfunction base64Url(str) {\n return Buffer.from(str).toString('base64url');\n}\n\nfunction resolve(obj) {\n return Promise.resolve(obj);\n}\n\nfunction checkParaObject(obj) {\n if (obj) {\n assert(obj instanceof ParaObject, 'Parameter must be a ParaObject.');\n }\n}\n\nfunction checkParaObjects(obj) {\n if (obj && isArray(obj) && !isEmpty(obj)) {\n assert(obj[0] instanceof ParaObject, 'Parameter must be an array of ParaObjects.');\n }\n}\n\nfunction checkPager(obj, fn) {\n if (obj) {\n if (isFunction(obj)) {\n return obj;\n } else {\n assert(obj instanceof Pager, 'Parameter must be a Pager object.');\n return fn || noop;\n }\n }\n return noop;\n}\n\nfunction checkConstraint(obj) {\n if (obj) {\n assert(obj instanceof Constraint, 'Parameter must be a Constraint object.');\n }\n}\n\nexport { ParaClient, ParaObject, Pager, Constraint };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["urlEncode"],"sources":["../lib/ParaObject.js","../lib/Pager.js","../lib/Constraint.js","../lib/index.js"],"sourcesContent":["/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n/* global encodeURIComponent */\n\n'use strict';\n\nexport default class ParaObject {\n constructor(id, type) {\n this.id = id || null;\n this.type = type || 'sysprop';\n this.name = 'ParaObject';\n this.stored = true;\n this.indexed = true;\n this.cached = true;\n this.version = 0;\n }\n /**\n * The id of an object. Usually an autogenerated unique string of numbers.\n *\n * @return the id\n */\n getId() {\n return this.id;\n }\n /**\n * Sets a new id. Must not be null or empty.\n *\n * @param {String} id the new id\n */\n setId(id) {\n this.id = id;\n }\n /**\n * The name of the object. Can be anything.\n *\n * @return {String} the name. default: [type id]\n */\n getName() {\n return this.name;\n }\n /**\n * Sets a new name. Must not be null or empty.\n *\n * @param {String} name the new name\n */\n setName(name) {\n this.name = name;\n }\n /**\n * The application name. Added to support multiple separate apps.\n * Every object must belong to an app.\n *\n * @return {String} the app id (name). default: para\n */\n getAppid() {\n return this.appid;\n }\n /**\n * Sets a new app name. Must not be null or empty.\n *\n * @param {String} appid the new app id (name)\n */\n setAppid(appid) {\n this.appid = appid;\n }\n /**\n * The id of the parent object.\n *\n * @return {String} the id of the parent or null\n */\n getParentid() {\n return this.parentid;\n }\n /**\n * Sets a new parent id. Must not be null or empty.\n *\n * @param {String} parentid a new id\n */\n setParentid(parentid) {\n this.parentid = parentid;\n }\n /**\n * The name of the object's class. This is equivalent to {@link Class#getSimpleName()}.toLowerCase().\n *\n * @return {String} the simple name of the class\n */\n getType() {\n return this.type;\n }\n /**\n * Sets a new object type. Must not be null or empty.\n *\n * @param {String} type a new type\n */\n setType(type) {\n this.type = type;\n }\n /**\n * The id of the user who created this. Should point to a {@link User} id.\n *\n * @return {String} the id or null\n */\n getCreatorid() {\n return this.creatorid;\n }\n /**\n * Sets a new creator id. Must not be null or empty.\n *\n * @param {String} creatorid a new id\n */\n setCreatorid(creatorid) {\n this.creatorid = creatorid;\n }\n /**\n * The URI of this object. For example: /user/123.\n *\n * @return {String} the URI\n */\n getObjectURI() {\n var def = '/' + urlEncode(this.getType());\n return this.id ? def + '/' + urlEncode(this.id) : def;\n }\n /**\n * The time when the object was created, in milliseconds.\n *\n * @return {Number} the timestamp of creation\n */\n getTimestamp() {\n return this.timestamp;\n }\n /**\n * Sets the timestamp.\n *\n * @param {Number} timestamp a new timestamp in milliseconds.\n */\n setTimestamp(timestamp) {\n this.timestamp = timestamp;\n }\n /**\n * The last time this object was updated. Timestamp in ms.\n *\n * @return {Number} timestamp in milliseconds\n */\n getUpdated() {\n return this.updated;\n }\n /**\n * Sets the last updated timestamp.\n *\n * @param {Number} updated a new timestamp\n */\n setUpdated(updated) {\n this.updated = updated;\n }\n /**\n * The tags associated with this object. Tags must not be null or empty.\n *\n * @return {Array} a set of tags, or an empty set\n */\n getTags() {\n return this.id;\n }\n /**\n * Merges the given tags with existing tags.\n *\n * @param {Array} tags the additional tags, or clears all tags if set to null\n */\n setTags(tags) {\n this.tags = tags;\n }\n /**\n * The votes associated with this object.\n *\n * @return {Number} votes or 0\n */\n getVotes() {\n return this.votes;\n }\n /**\n * Sets the votes.\n *\n * @param {Number} votes\n */\n setVotes(votes) {\n this.votes = votes;\n }\n /**\n * The version of this object.\n *\n * @return {Number} version\n */\n getVersion() {\n return this.version;\n }\n /**\n * Sets the version.\n *\n * @param {Number} version\n */\n setVersion(version) {\n this.version = version;\n }\n /**\n * Boolean flag which controls whether this object is stored\n * in the database or not. Default is true.\n *\n * @return {Boolean} true if this object is stored in DB.\n */\n getStored() {\n return this.stored;\n }\n /**\n * Sets the \"isStored\" flag.\n *\n * @param {Boolean} isStored when set to true, object is stored in DB.\n */\n setStored(isStored) {\n this.stored = isStored;\n }\n /**\n * Boolean flat which controls whether this object is indexed\n * by the search engine. Default is true.\n *\n * @return {Boolean} true if this object is indexed\n */\n getIndexed() {\n return this.indexed;\n }\n /**\n * Sets the \"isIndexed\" flag.\n *\n * @param {Boolean} isIndexed when set to true, object is indexed.\n */\n setIndexed(isIndexed) {\n this.indexed = isIndexed;\n }\n /**\n * Boolean flat which controls whether this object is cached.\n * Default is true.\n *\n * @return {Boolean} true if this object is cached on update() and create().\n */\n getCached() {\n return this.cached;\n }\n /**\n * Sets the \"isCached\" flag.\n *\n * @param {Boolean} isCached when set to true, object is cached.\n */\n setCached(isCached) {\n this.cached = isCached;\n }\n /**\n * Populates this object with data from a map.\n * @param {Object} map\n * @return {ParaObject} this\n */\n setFields(map) {\n if (map && map instanceof Object) {\n for (var key in map) {\n this[key] = map[key];\n }\n }\n return this;\n }\n}\n\nfunction urlEncode(path) {\n return encodeURIComponent(path).replace(/[!'()*]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n'use strict';\n\n/**\n * This class stores pagination data. It limits the results for queries in the DAO\n * and Search objects and also counts the total number of results that are returned.\n * @author Alex Bogdanovski <alex@erudika.com>\n * @param {Number} page page number to start from\n * @param {String} sortby sort by field\n * @param {Boolean} desc sort in descending or ascending order\n * @param {Number} limit limits the results\n *\n * @property {Number} count the total number of results\n * @property {String} lastKey reserved use\n * @property {Array} select selected fields filter for returning only part of an object\n * @returns {Pager} a pager\n */\nexport default class Pager {\n constructor(page, sortby, desc, limit) {\n this.page = page || 1;\n this.count = 0;\n this.sortby = sortby || null;\n this.desc = desc || true;\n this.limit = limit || 30;\n this.name = '';\n this.lastKey = null;\n this.select = null; // [field1,field2]\n }\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n'use strict';\n\n/**\n * Represents a validation constraint.\n * @author Alex Bogdanovski <alex@erudika.com>\n * @param {String} constraintName name\n * @param {Object} constraintPayload payload\n * @returns {Constraint}\n */\nexport default class Constraint {\n constructor(constraintName, constraintPayload) {\n var name = constraintName;\n var payload = constraintPayload;\n\n /**\n * The constraint name.\n * @returns {String} a name\n */\n this.getName = function () {\n return name;\n };\n\n /**\n * Sets the name of the constraint.\n * @param {String} n name\n */\n this.setName = function (n) {\n name = n;\n };\n\n /**\n * The payload (a map)\n * @returns {Object} an object\n */\n this.getPayload = function () {\n return payload;\n };\n\n /**\n * Sets the payload.\n * @param {Object} p the payload object\n */\n this.setPayload = function (p) {\n payload = p;\n };\n }\n /**\n * The 'required' constraint - marks a field as required.\n * @returns {Constraint}\n */\n static required() {\n return new Constraint('required', { message: 'messages.required' });\n }\n /**\n * The 'min' constraint - field must contain a number larger than or equal to min.\n * @param {Number} min the minimum value\n * @returns {Constraint}\n */\n static min(min) {\n return new Constraint('min', {\n value: min || 0,\n message: 'messages.min'\n });\n }\n /**\n * The 'max' constraint - field must contain a number smaller than or equal to max.\n * @param {Number} max the maximum value\n * @returns {Constraint}\n */\n static max(max) {\n return new Constraint('max', {\n value: max || 0,\n message: 'messages.max'\n });\n }\n /**\n * The 'size' constraint - field must be a String, Object or Array\n * with a given minimum and maximum length.\n * @param {Number} min the minimum length\n * @param {Number} max the maximum length\n * @returns {Constraint}\n */\n static size(min, max) {\n return new Constraint('size', {\n min: min || 0,\n max: max || 0,\n message: 'messages.size'\n });\n }\n /**\n * The 'digits' constraint - field must be a Number or String containing digits where the\n * number of digits in the integral part is limited by 'integer', and the\n * number of digits for the fractional part is limited\n * by 'fraction'.\n * @param {Number} i the max number of digits for the integral part\n * @param {Number} f the max number of digits for the fractional part\n * @returns {Constraint}\n */\n static digits(i, f) {\n return new Constraint('digits', {\n integer: i || 0,\n fraction: f || 0,\n message: 'messages.digits'\n });\n }\n /**\n * The 'pattern' constraint - field must contain a value matching a regular expression.\n * @param {String} regex a regular expression\n * @returns {Constraint}\n */\n static pattern(regex) {\n return new Constraint('pattern', {\n value: regex || '',\n message: 'messages.pattern'\n });\n }\n /**\n * The 'email' constraint - field must contain a valid email.\n * @returns {Constraint}\n */\n static email() {\n return new Constraint('email', { message: 'messages.email' });\n }\n /**\n * The 'falsy' constraint - field value must not be equal to 'true'.\n * @returns {Constraint}\n */\n static falsy() {\n return new Constraint('false', { message: 'messages.false' });\n }\n /**\n * The 'truthy' constraint - field value must be equal to 'true'.\n * @returns {Constraint}\n */\n static truthy() {\n return new Constraint('true', { message: 'messages.true' });\n }\n /**\n * The 'future' constraint - field value must be a Date or a timestamp in the future.\n * @returns {Constraint}\n */\n static future() {\n return new Constraint('future', { message: 'messages.future' });\n }\n /**\n * The 'past' constraint - field value must be a Date or a timestamp in the past.\n * @returns {Constraint}\n */\n static past() {\n return new Constraint('past', { message: 'messages.past' });\n }\n /**\n * The 'url' constraint - field value must be a valid URL.\n * @returns {Constraint}\n */\n static url() {\n return new Constraint('url', { message: 'messages.url' });\n }\n}\n","/*\n * Copyright 2013-2026 Erudika. https://erudika.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * For issues and patches go to: https://github.com/erudika\n */\n/* global encodeURIComponent */\n\n'use strict';\n\nvar err = console.error;\nimport assert from 'assert';\nimport apiClient from 'superagent';\nimport aws4 from 'aws4';\nimport ParaObject from './ParaObject.js';\nimport Pager from './Pager.js';\nimport Constraint from './Constraint.js';\n\nconst DEFAULT_ENDPOINT = 'https://paraio.com';\nconst DEFAULT_PATH = '/v1/';\nconst JWT_PATH = '/jwt_auth';\nconst SEPARATOR = ':';\nconst { sign } = aws4;\n\n/**\n * JavaScript client for communicating with a Para API server.\n * @param {String} accessKey Para access key\n * @param {String} secretKey Para access key\n * @param {Object} options\n * @property {String} endpoint the API endpoint (default: paraio.com)\n * @property {String} apiPath the request path (default: /v1/)\n * @author Alex Bogdanovski <alex@erudika.com>\n */\nexport default class ParaClient {\n constructor(accessKey, secretKey, options) {\n if (!secretKey || isEmpty(secretKey.trim())) {\n console.warn(\"Secret key not provided. Make sure you call 'signIn()' first.\");\n }\n options = options || {};\n this.accessKey = accessKey;\n this.endpoint = options.endpoint || DEFAULT_ENDPOINT;\n this.apiPath = options.apiPath || DEFAULT_PATH;\n this.apiRequestTimeout = options.apiRequestTimeout || 120 * 1000;\n this.tokenKey = null;\n this.tokenKeyExpires = null;\n this.tokenKeyNextRefresh = null;\n if (!endsWith(this.apiPath, '/')) {\n this.apiPath += '/';\n }\n\n var that = this;\n var secret = secretKey;\n\n this.getFullPath = function (resourcePath) {\n if (resourcePath && startsWith(resourcePath, JWT_PATH)) {\n if ((that.apiPath.match(/\\//g) || []).length > 2) {\n return that.apiPath.substring(0, that.apiPath.indexOf('/', 1)) + resourcePath;\n }\n return resourcePath;\n }\n if (!resourcePath) {\n resourcePath = '';\n } else if (resourcePath[0] === '/') {\n resourcePath = resourcePath.substring(1);\n }\n return that.apiPath + resourcePath;\n };\n\n this.setSecret = function (sec) {\n secret = sec;\n };\n\n /**\n * Clears the JWT token from memory, if such exists.\n */\n this.clearAccessToken = function () {\n that.tokenKey = null;\n that.tokenKeyExpires = null;\n that.tokenKeyNextRefresh = null;\n };\n\n /**\n * @returns the JWT access token, or null if not signed in\n */\n this.getAccessToken = function () {\n return that.tokenKey;\n };\n\n /**\n * Sets the JWT access token.\n * @param {String} token a valid token\n */\n this.setAccessToken = function (token) {\n if (token && token.length > 1) {\n try {\n var parts = token.split('.');\n var decoded = JSON.parse(decode(parts[1]));\n if (decoded && decoded['exp']) {\n that.tokenKeyExpires = decoded['exp'];\n that.tokenKeyNextRefresh = decoded['refresh'];\n }\n } catch (e) {\n that.tokenKeyExpires = null;\n that.tokenKeyNextRefresh = null;\n }\n }\n that.tokenKey = token;\n };\n\n /**\n * @param {Function} fn callback (optional)\n * @returns {Promise} the version of Para server\n */\n this.getServerVersion = async function (fn) {\n fn = fn || noop;\n return that.getEntity(that.invokeGet('')).then(function (result) {\n var ver = result.version || 'unknown';\n fn(ver);\n return ver;\n });\n };\n\n /**\n * Invoke a GET request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} params query parameters\n * @returns {Object} response\n */\n this.invokeGet = async function (resourcePath, params) {\n return that.invokeSignedRequest(\n 'GET',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n params\n );\n };\n\n /**\n * Invoke a POST request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePost = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'POST',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a PUT request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePut = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'PUT',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a PATCH request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} entity request body\n * @returns {Object} response\n */\n this.invokePatch = async function (resourcePath, entity) {\n return that.invokeSignedRequest(\n 'PATCH',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n null,\n entity\n );\n };\n\n /**\n * Invoke a DELETE request to the Para API.\n * @param {String} resourcePath the subpath after '/v1/', should not start with '/'\n * @param {Object} params query parameters\n * @returns {Object} response\n */\n this.invokeDelete = async function (resourcePath, params) {\n return that.invokeSignedRequest(\n 'DELETE',\n that.endpoint,\n that.getFullPath(resourcePath),\n null,\n params\n );\n };\n\n this.invokeSignedRequest = async function (\n httpMethod,\n endpointURL,\n reqPath,\n headers,\n params,\n jsonEntity\n ) {\n if (!accessKey || isEmpty(accessKey.trim())) {\n throw new Error('Blank access key: ' + httpMethod + ' ' + reqPath);\n }\n var doSign = true;\n if (!secret && !that.tokenKey && isEmpty(headers)) {\n headers = { Authorization: 'Anonymous ' + accessKey };\n doSign = false;\n }\n var host = endpointURL;\n if (startsWith(endpointURL, 'http://')) {\n host = endpointURL.substring(7);\n } else if (startsWith(endpointURL, 'https://')) {\n host = endpointURL.substring(8);\n }\n\n var opts = {\n service: 'para',\n method: httpMethod,\n host: host,\n path: uriEncodeAWSV4(reqPath),\n headers: headers || {}\n };\n\n // make sure that only the first parameter value is used for generating the signature\n // multi-valued parameters are reduced to single value\n // there's no spec for this case, so choose first param in array\n if (params && params instanceof Object && !isEmpty(params)) {\n opts.path += '?';\n var paramsObj = {};\n for (var key in params) {\n var value = params[key];\n if (isArray(value)) {\n if (!isEmpty(value)) {\n paramsObj[key] = value[0] !== null ? value[0] : '';\n }\n } else {\n paramsObj[key] = value !== null ? value : '';\n }\n }\n opts.path += new URLSearchParams(paramsObj).toString();\n }\n\n if (jsonEntity) {\n opts.body = JSON.stringify(jsonEntity);\n opts.headers['Content-Type'] = 'application/json; charset=UTF-8';\n }\n\n if (that.tokenKey !== null) {\n // make sure you don't create an infinite loop!\n if (!(httpMethod === 'GET' && reqPath === JWT_PATH)) {\n await that.refreshToken();\n }\n opts.headers['Authorization'] = 'Bearer ' + that.tokenKey;\n } else if (doSign) {\n opts.doNotEncodePath = true;\n sign(opts, { accessKeyId: accessKey, secretAccessKey: secret });\n }\n\n if (typeof window !== 'undefined') {\n // don't set the 'Host' header, the browser does that.\n delete opts.headers['Host'];\n }\n opts.headers['User-Agent'] = 'Para client for JavaScript';\n try {\n return apiClient(opts.method, endpointURL + reqPath)\n .query(params)\n .set(opts.headers)\n .timeout({ response: that.apiRequestTimeout, deadline: that.apiRequestTimeout })\n .send(opts.body);\n } catch (e) {\n err('ParaClient request failed: ' + e);\n return Promise.reject(e);\n }\n };\n\n /**\n * Parses a search query response and extracts the objects from it.\n * @param {String} queryType type of search query\n * @param {Object} params query params\n * @param {Function} fn callback\n * @returns {Object} response\n */\n this.find = async function (queryType, params, fn) {\n if (params && params instanceof Object && !isEmpty(params)) {\n var qType = queryType ? '/' + queryType : '/default';\n if (!params['type']) {\n return that.getEntity(that.invokeGet('search' + qType, params), fn);\n } else {\n return that.getEntity(that.invokeGet(params['type'] + '/search' + qType, params), fn);\n }\n } else {\n var res = {\n items: [],\n totalHits: 0\n };\n fn(res);\n return resolve(res);\n }\n };\n\n /**\n * Deserializes a Response object to POJO of some type.\n * @param {Object} req request\n * @param {Function} callback callback\n * @param {Boolean} returnRawJSON true if raw JSON should be returned as string\n * @returns {Object} a ParaObject\n */\n this.getEntity = async function (req, callback, returnRawJSON) {\n callback = callback || noop;\n var rawJSON = isUndefined(returnRawJSON) ? true : returnRawJSON;\n return req.then(function (res) {\n //console.log(\"DEBUG \", req.method, req.url, res.status);\n var code = res.status;\n if (code === 200 || code === 201 || code === 304) {\n if (rawJSON) {\n var result;\n try {\n if (!isEmpty(res.body) || res.text === '{ }' || res.text === '{}') {\n result = res.body;\n } else {\n result = res.text;\n }\n } catch (exc) {\n result = res.text;\n }\n callback(result);\n return resolve(result);\n } else {\n var obj = new ParaObject();\n obj.setFields(res.body);\n callback(obj);\n return resolve(obj);\n }\n } else if (code !== 404 || code !== 304 || code !== 204) {\n var error = res.body || new Error('ParaClient request failed.');\n if (error && error['code']) {\n var msg = error['message'] ? error['message'] : 'error';\n err(msg + ' - ' + error['code']);\n } else {\n err(code + ' - ' + res.text);\n }\n callback(null, error);\n return Promise.reject(error);\n } else {\n var error1 = new Error('ParaClient request failed.');\n callback(null, error1);\n reject(error1);\n }\n });\n };\n\n /**\n * Deserializes ParaObjects from a JSON array (the \"items:[]\" field in search results).\n * @param {Array} items a list of deserialized maps\n * @returns {Array} a list of ParaObjects\n */\n this.getItemsFromList = function (items) {\n if (items && items instanceof Array && !isEmpty(items)) {\n var objects = [];\n for (var item of items) {\n if (item) {\n var p = new ParaObject();\n p.setFields(item);\n objects.push(p);\n }\n }\n return objects;\n }\n return [];\n };\n\n /**\n * Converts a list of Maps to a List of ParaObjects, at a given path within the JSON tree structure.\n * @param {Object} result the response body for an API request\n * @param {String} at the path (field) where the array of objects is located\n * @param {Pager} pager a pager\n * @returns {Array} a list of ParaObjects\n */\n this.getItemsAt = function (result, at, pager) {\n if (result && at && result[at]) {\n if (pager && result.totalHits) {\n pager.count = result.totalHits;\n }\n if (pager && result.lastKey) {\n pager.lastKey = result.lastKey;\n }\n return that.getItemsFromList(result[at]);\n }\n return [];\n };\n\n /**\n * Converts a list of Maps to a List of ParaObjects.\n * @param {Object} result the response body for an API request\n * @param {Pager} pager a pager\n * @returns {Array} a list of ParaObjects\n */\n this.getItems = function (result, pager) {\n return that.getItemsAt(result, 'items', pager);\n };\n\n /**\n * Converts a {Pager} object to query parameters.\n * @param {Pager} pager a pager\n * @returns {Object} parameters map\n */\n this.pagerToParams = function (pager) {\n var map = {};\n if (pager) {\n map['page'] = pager.page;\n map['desc'] = pager.desc;\n map['limit'] = pager.limit;\n if (pager.lastKey) {\n map['lastKey'] = pager.lastKey;\n }\n if (pager.sortby) {\n map['sort'] = pager.sortby;\n }\n if (pager.select && pager.select.length) {\n map['select'] = pager.select;\n }\n }\n return map;\n };\n }\n /**\n * Returns the App for the current access key (appid).\n * @param {Function} fn callback (optional)\n * @returns {Promise} a promise\n */\n async getApp(fn) {\n return this.me(fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t PERSISTENCE\n /////////////////////////////////////////////\n /**\n * Persists an object to the data store. If the object's type and id are given,\n * then the request will be a PUT request and any existing object will be\n * overwritten.\n * @param {ParaObject} obj the object to create\n * @param {Function} fn callback (optional)\n * @returns {Promise} the same object with assigned id or null if not created.\n */\n async create(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj) {\n fn(null);\n return resolve(null);\n }\n if (!obj.getId() || !obj.getType()) {\n return this.getEntity(this.invokePost(urlEncode(obj.getType()), obj), fn, false);\n } else {\n return this.getEntity(this.invokePut(obj.getObjectURI(), obj), fn, false);\n }\n }\n /**\n * Retrieves an object from the data store.\n * @param {String} type the type of the object\n * @param {String} id the id of the object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the retrieved object or null if not found\n */\n async read(type, id, fn) {\n fn = fn || noop;\n if (!id) {\n fn(null);\n return resolve(null);\n }\n if (!type) {\n return this.getEntity(this.invokeGet('_id/' + urlEncode(id)), fn, false);\n } else {\n return this.getEntity(this.invokeGet(urlEncode(type) + '/' + urlEncode(id)), fn, false);\n }\n }\n /**\n * Updates an object permanently. Supports partial updates.\n * @param {ParaObject} obj the object to update\n * @param {Function} fn callback (optional)\n * @returns {Promise} the updated object\n */\n async update(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj) {\n fn(null);\n return resolve(null);\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), obj), fn, false);\n }\n /**\n * Deletes an object permanently.\n * @param {ParaObject} obj object to delete\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async delete(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (obj) {\n return this.getEntity(this.invokeDelete(obj.getObjectURI()), fn);\n } else {\n fn(null);\n return resolve(null);\n }\n }\n /**\n * Saves multiple objects to the data store.\n * @param {Array} objects a list of ParaObjects to create\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async createAll(objects, fn) {\n fn = fn || noop;\n checkParaObjects(objects);\n if (!objects || !isArray(objects) || !objects[0]) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokePost('_batch', objects)).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Retrieves multiple objects from the data store.\n * @param {Array} keys a list of object ids\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async readAll(keys, fn) {\n fn = fn || noop;\n if (!keys || !isArray(keys) || isEmpty(keys)) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokeGet('_batch', { ids: keys })).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Updates multiple objects.\n * @param {Array} objects a list of ParaObjects to update\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async updateAll(objects, fn) {\n fn = fn || noop;\n checkParaObjects(objects);\n if (!objects || !isArray(objects) || isEmpty(objects)) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokePatch('_batch', objects)).then(function (result) {\n var res = that.getItemsFromList(result);\n fn(res);\n return res;\n });\n }\n /**\n * Deletes multiple objects.\n * @param {Function} fn callback (optional)\n * @param {Array} keys the ids of the objects to delete\n * @returns {Promise} promise\n */\n async deleteAll(keys, fn) {\n fn = fn || noop;\n if (keys && isArray(keys)) {\n return this.getEntity(this.invokeDelete('_batch', { ids: keys }), fn);\n } else {\n fn(null);\n return resolve(null);\n }\n }\n /**\n * Returns a list all objects found for the given type.\n * The result is paginated so only one page of items is returned, at a time.\n * @param {String} type the type of objects to search for\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects\n */\n async list(type, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n if (!type) {\n fn([]);\n return resolve([]);\n }\n var that = this;\n return this.getEntity(this.invokeGet(urlEncode(type), this.pagerToParams(pager))).then(\n function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n }\n );\n }\n /////////////////////////////////////////////\n //\t\t\t\t SEARCH\n /////////////////////////////////////////////\n /**\n * Simple id search.\n * @param {String} id the id\n * @param {Function} fn callback (optional)\n * @returns {Promise} the object if found or null\n */\n async findById(id, fn) {\n fn = fn || noop;\n var that = this;\n return this.find('id', { id: id }).then(function (results) {\n var list = that.getItems(results);\n var res = isEmpty(list) ? null : list;\n fn(res);\n return res;\n });\n }\n /**\n * Simple multi id search.\n * @param {Array} ids a list of ids to search for\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of objects if found or []\n */\n async findByIds(ids, fn) {\n fn = fn || noop;\n var that = this;\n return this.find('ids', { ids: ids }).then(function (results) {\n var res = that.getItems(results);\n fn(res);\n return res;\n });\n }\n /**\n * Search for address objects in a radius of X km from a given point.\n * @param {String} type the type of object to search for\n * @param {String} query the query string\n * @param {Number} radius the radius of the search circle\n * @param {Number} lat latitude\n * @param {Number} lng longitude\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findNearby(type, query, radius, lat, lng, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n latlng: lat + ',' + lng,\n radius: radius,\n q: query,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('nearby', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have a property which value starts with a given prefix.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {String} prefix the prefix\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findPrefix(type, field, prefix, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n prefix: prefix,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('prefix', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Simple query string search. This is the basic search method.\n * @param {String} type the type of object to search for\n * @param {String} query the query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findQuery(type, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n q: query,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches within a nested field. The objects of the given type must contain a nested field \"nstd\".\n * @param {String} type the type of object to search for\n * @param {String} field the name of the field to target (within a nested field \"nstd\")\n * @param {String} query the query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findNestedQuery(type, field, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n q: query,\n field: field,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('nested', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have similar property values to a given text. A \"find like this\" query.\n * @param {String} type the type of object to search for\n * @param {String} filterKey exclude an object with this key from the results (optional)\n * @param {Array} fields a list of property names\n * @param {String} liketext text to compare to\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findSimilar(type, filterKey, fields, liketext, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n fields: fields || null,\n filterid: filterKey,\n like: liketext,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('similar', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects tagged with one or more tags.\n * @param {String} type the type of object to search for\n * @param {Array} tags the list of tags\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTagged(type, tags, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n tags: tags || null,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('tagged', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for Tag objects.\n * This method might be deprecated in the future.\n * @param {String} keyword the tag keyword to search for\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTags(keyword, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n keyword = keyword ? keyword + '*' : '*';\n return this.findWildcard('tag', 'tag', keyword, pager, fn);\n }\n /**\n * Searches for objects having a property value that is in list of possible values.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {Object} terms a map of terms (property values)\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTermInList(type, field, terms, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n terms: terms,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('in', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have properties matching some given values. A terms query.\n * @param {String} type the type of object to search for\n * @param {Object} terms a map of fields (property names) to terms (property values)\n * @param {Boolean} matchAll match all terms. If true - AND search, if false - OR search\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findTerms(type, terms, matchAll, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n terms = terms || {};\n matchAll = matchAll || true;\n var params = {\n matchall: matchAll\n };\n var list = [];\n for (var key in terms) {\n if (terms[key]) {\n list.push(key + SEPARATOR + terms[key]);\n }\n }\n if (!isEmpty(terms)) {\n params['terms'] = list;\n }\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('terms', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches for objects that have a property with a value matching a wildcard query.\n * @param {String} type the type of object to search for\n * @param {String} field the property name of an object\n * @param {String} wildcard wildcard query string. For example \"cat*\".\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of object found\n */\n async findWildcard(type, field, wildcard, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n var params = {\n field: field,\n q: wildcard,\n type: type\n };\n params = merge(params, this.pagerToParams(pager));\n var that = this;\n return this.find('wildcard', params).then(function (results) {\n var res = that.getItems(results, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Counts indexed objects matching a set of terms/values.\n * @param {String} type the type of object to search for\n * @param {Object} terms a map of fields (property names) to terms (property values)\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of results found\n */\n async getCount(type, terms, fn) {\n fn = fn || noop;\n if (type === null && terms === null) {\n fn(0);\n return resolve(0);\n }\n terms = terms || {};\n var params = {};\n var pager = new Pager();\n var that = this;\n params['type'] = type;\n if (isEmpty(terms)) {\n return this.find('count', params).then(function (results) {\n that.getItems(results, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n } else {\n var list = [];\n for (var key in terms) {\n if (terms[key]) {\n list.push(key + SEPARATOR + terms[key]);\n }\n }\n if (!isEmpty(terms)) {\n params['terms'] = list;\n }\n params['count'] = 'true';\n return this.find('terms', params).then(function (results) {\n that.getItems(results, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n }\n /////////////////////////////////////////////\n //\t\t\t\t LINKS\n /////////////////////////////////////////////\n /**\n * Count the total number of links between this object and another type of object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of links for the given object\n */\n async countLinks(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(0);\n return resolve(0);\n }\n var params = {};\n params['count'] = 'true';\n var pager = new Pager();\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n that.getItems(result, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n /**\n * Returns all objects linked to the given one. Only applicable to many-to-many relationships.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of linked objects\n */\n async getLinkedObjects(obj, type2, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, this.pagerToParams(pager))).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Searches through all linked objects in many-to-many relationships.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} field the name of the field to target (within a nested field \"nstd\")\n * @param {String} query a query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of linked objects\n */\n async findLinkedObjects(obj, type2, field, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {\n field: field,\n q: query || '*'\n };\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Checks if this object is linked to another.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if the two are linked\n */\n async isLinked(obj, type2, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2 || !id2) {\n fn(false);\n return resolve(false);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2) + '/' + urlEncode(id2);\n return this.getEntity(this.invokeGet(url)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Checks if a given object is linked to this one.\n * @param {ParaObject} obj the object to execute this method on\n * @param {ParaObject} toObj the other object\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if linked\n */\n async isLinkedToObject(obj, toObj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n checkParaObject(toObj);\n if (!obj || !obj.getId() || !toObj || !toObj.getId()) {\n fn(false);\n return resolve(false);\n }\n return this.isLinked(obj, toObj.getType(), toObj.getId(), fn);\n }\n /**\n * Links an object to this one in a many-to-many relationship.\n * Only a link is created. Objects are left untouched.\n * The type of the second object is automatically determined on read.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} the id of the Linker object that is created\n */\n async link(obj, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !id2) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(id2);\n return this.getEntity(this.invokePost(url), fn);\n }\n /**\n * Unlinks an object from this one.\n * Only a link is deleted. Objects are left untouched.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} id2 the other id\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async unlink(obj, type2, id2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2 || !id2) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2) + '/' + urlEncode(id2);\n return this.getEntity(this.invokeDelete(url), fn);\n }\n /**\n * Unlinks all objects that are linked to this one.\n * Deletes all Linker objects.\n * Only the links are deleted. Objects are left untouched.\n * @param {ParaObject} obj the object to execute this method on\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async unlinkAll(obj, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId()) {\n fn(null);\n return resolve(null);\n }\n var url = obj.getObjectURI() + '/links';\n return this.getEntity(this.invokeDelete(url), fn);\n }\n /**\n * Count the total number of child objects for this object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} the number of links\n */\n async countChildren(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(0);\n return resolve(0);\n }\n var params = {};\n params['count'] = 'true';\n params['childrenonly'] = 'true';\n var pager = new Pager();\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n that.getItems(result, pager);\n var res = pager.count;\n fn(res);\n return res;\n });\n }\n /**\n * Returns all child objects linked to this object.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} field the field name to use as filter\n * @param {String} term the field value to use as filter\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of ParaObject in a one-to-many relationship with this object\n */\n async getChildren(obj, type2, field, term, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {};\n params['childrenonly'] = 'true';\n if (field) {\n params['field'] = field;\n }\n if (term) {\n params['term'] = term;\n }\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Search through all child objects. Only searches child objects directly\n * connected to this parent via the `parentid` field.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {String} query a query string\n * @param {Pager} pager a Pager object\n * @param {Function} fn callback (optional)\n * @returns {Promise} a list of ParaObject in a one-to-many relationship with this object\n */\n async findChildren(obj, type2, query, pager, fn) {\n fn = fn || noop;\n fn = checkPager(pager, fn);\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn([]);\n return resolve([]);\n }\n var params = {\n childrenonly: 'true',\n q: query || '*'\n };\n params = merge(params, this.pagerToParams(pager));\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n var that = this;\n return this.getEntity(this.invokeGet(url, params)).then(function (result) {\n var res = that.getItems(result, pager);\n fn(res);\n return res;\n });\n }\n /**\n * Deletes all child objects permanently.\n * @param {ParaObject} obj the object to execute this method on\n * @param {String} type2 the other type of object\n * @param {Function} fn callback (optional)\n * @returns {Promise} promise\n */\n async deleteChildren(obj, type2, fn) {\n fn = fn || noop;\n checkParaObject(obj);\n if (!obj || !obj.getId() || !type2) {\n fn(null);\n return resolve(null);\n }\n var params = {};\n params['childrenonly'] = 'true';\n var url = obj.getObjectURI() + '/links/' + urlEncode(type2);\n return this.getEntity(this.invokeDelete(url, params), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t UTILS\n /////////////////////////////////////////////\n /**\n * Generates a new unique id.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a new id\n */\n async newId(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeGet('utils/newid')).then(function (result) {\n var res = result ? result : '';\n fn(res);\n return res;\n });\n }\n /**\n * Returns the current timestamp.\n * @param {Function} fn callback (optional)\n * @returns {Promise} timestamp in milliseconds\n */\n async getTimestamp(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeGet('utils/timestamp')).then(function (result) {\n var res = result ? result : 0;\n fn(res);\n return res;\n });\n }\n /**\n * Formats a date in a specific format.\n * @param {String} format the date format\n * @param {String} locale the locale instance\n * @param {Function} fn callback (optional)\n * @returns {Promise} a formatted date\n */\n async formatDate(format, locale, fn) {\n var params = { format: format || '', locale: locale || 'US' };\n return this.getEntity(this.invokeGet('utils/formatdate', params), fn);\n }\n /**\n * Converts spaces to dashes.\n * @param {String} str a string with spaces\n * @param {String} replaceWith a string to replace spaces with\n * @param {Function} fn callback (optional)\n * @returns {Promise} a string with no whitespace\n */\n async noSpaces(str, replaceWith, fn) {\n var params = { string: str || '', replacement: replaceWith || '' };\n return this.getEntity(this.invokeGet('utils/nospaces', params), fn);\n }\n /**\n * Strips all symbols, punctuation, whitespace and control chars from a string.\n * @param {String} str a dirty string\n * @param {Function} fn callback (optional)\n * @returns {Promise} a clean string\n */\n async stripAndTrim(str, fn) {\n var params = { string: str || '' };\n return this.getEntity(this.invokeGet('utils/nosymbols', params), fn);\n }\n /**\n * Converts Markdown to HTML\n * @param {String} markdownString some Markdown\n * @param {Function} fn callback (optional)\n * @returns {Promise} HTML\n */\n async markdownToHtml(markdownString, fn) {\n var params = { md: markdownString || '' };\n return this.getEntity(this.invokeGet('utils/md2html', params), fn);\n }\n /**\n * Returns the number of minutes, hours, months elapsed for a time delta (milliseconds).\n * @param {Number} delta the time delta between two events, in milliseconds\n * @param {Function} fn callback (optional)\n * @returns {Promise} a string like \"5m\", \"1h\"\n */\n async approximately(delta, fn) {\n var params = { delta: delta || 0 };\n return this.getEntity(this.invokeGet('utils/timeago', params), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\t MISC\n /////////////////////////////////////////////\n /**\n * Generates a new set of access/secret keys.\n * Old keys are discarded and invalid after this.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of new credentials\n */\n async newKeys(fn) {\n fn = fn || noop;\n var that = this;\n return this.getEntity(this.invokePost('_newkeys')).then(function (result) {\n var res = result || {};\n if (res.secretKey && !isEmpty(res.secretKey.trim())) {\n that.setSecret(res.secretKey);\n }\n fn(res);\n return res;\n });\n }\n /**\n * Returns all registered types for this App.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of plural-singular form of all the registered types.\n */\n async types(fn) {\n return this.getEntity(this.invokeGet('_types'), fn);\n }\n /**\n * Returns the number of objects for each existing type in this App.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of singular object type to object count.\n */\n async typesCount(fn) {\n return this.getEntity(this.invokeGet('_types', { count: 'true' }), fn);\n }\n /**\n * Returns a User or an App that is currently authenticated.\n * @param {String} accessToken a valid JWT access token (optional)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a ParaObject\n */\n async me(accessToken, fn) {\n fn = isFunction(accessToken) ? accessToken : fn || noop;\n if (accessToken && isString(accessToken)) {\n var auth = startsWith(accessToken, 'Bearer') ? accessToken : 'Bearer ' + accessToken;\n var headers = { Authorization: auth };\n return this.getEntity(\n this.invokeSignedRequest('GET', this.endpoint, this.getFullPath('_me'), headers),\n fn,\n false\n );\n } else {\n return this.getEntity(this.invokeGet('_me'), fn, false);\n }\n }\n /**\n * Upvote an object and register the vote in DB.\n * @param {ParaObject} obj the object to receive +1 votes\n * @param {String} voterid the userid of the voter\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if vote was successful\n */\n async voteUp(obj, voterid, expiresAfter, lockedAfter, fn) {\n fn = isFunction(expiresAfter) ? expiresAfter : fn || noop;\n if (!obj || isEmpty(voterid)) {\n fn(false);\n return resolve(false);\n }\n var body = { _voteup: voterid };\n if (isInteger(expiresAfter) && isInteger(lockedAfter)) {\n body['_vote_expires_after'] = expiresAfter;\n body['_vote_locked_after'] = lockedAfter;\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), body)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Downvote an object and register the vote in DB.\n * @param {ParaObject} obj the object to receive +1 votes\n * @param {String} voterid the userid of the voter\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if vote was successful\n */\n async voteDown(obj, voterid, expiresAfter, lockedAfter, fn) {\n fn = isFunction(expiresAfter) ? expiresAfter : fn || noop;\n fn = fn || noop;\n if (!obj || isEmpty(voterid)) {\n fn(false);\n return resolve(false);\n }\n var body = { _votedown: voterid };\n if (isInteger(expiresAfter) && isInteger(lockedAfter)) {\n body['_vote_expires_after'] = expiresAfter;\n body['_vote_locked_after'] = lockedAfter;\n }\n return this.getEntity(this.invokePatch(obj.getObjectURI(), body)).then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n });\n }\n /**\n * Rebuilds the entire search index.\n * @param {String} destinationIndex an existing index as destination\n * @param {Function} fn callback (optional)\n * @returns {Promise} a response object with properties \"tookMillis\" and \"reindexed\"\n */\n async rebuildIndex(destinationIndex, fn) {\n fn = fn || noop;\n if (!destinationIndex) {\n return this.getEntity(this.invokePost('_reindex'), fn);\n } else {\n return this.getEntity(\n this.invokeSignedRequest(\n 'POST',\n this.endpoint,\n this.getFullPath('_reindex'),\n {},\n { destinationIndex: destinationIndex }\n ),\n fn\n );\n }\n }\n /////////////////////////////////////////////\n //\t\t\tValidation Constraints\n /////////////////////////////////////////////\n /**\n * Returns the validation constraints map.\n * @param {String} type a type\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints.\n */\n async validationConstraints(type, fn) {\n return this.getEntity(this.invokeGet('_constraints' + (type ? '/' + urlEncode(type) : '')), fn);\n }\n /**\n * Add a new constraint for a given field.\n * @param {String} type a type\n * @param {String} field a field name\n * @param {Constraint} cons the constraint\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints for this type.\n */\n async addValidationConstraint(type, field, cons, fn) {\n fn = fn || noop;\n checkConstraint(cons);\n if (!type || !field || !cons) {\n fn({});\n return resolve({});\n }\n return this.getEntity(\n this.invokePut(\n '_constraints/' + urlEncode(type) + '/' + field + '/' + cons.getName(),\n cons.getPayload()\n ),\n fn\n );\n }\n /**\n * Removes a validation constraint for a given field.\n * @param {String} type a type\n * @param {String} field a field name\n * @param {String} constraintName the name of the constraint to remove\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map containing all validation constraints for this type.\n */\n async removeValidationConstraint(type, field, constraintName, fn) {\n fn = fn || noop;\n if (!type || !field || !constraintName) {\n fn({});\n return resolve({});\n }\n return this.getEntity(\n this.invokeDelete('_constraints/' + urlEncode(type) + '/' + field + '/' + constraintName),\n fn\n );\n }\n /////////////////////////////////////////////\n //\t\t\tResource Permissions\n /////////////////////////////////////////////\n /**\n * Returns only the permissions for a given subject (user) of the current app.\n * If subject is not given returns the permissions for all subjects and resources for current app.\n * @param {String} subjectid the subject id (user id)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of subject ids to resource names to a list of allowed methods\n */\n async resourcePermissions(subjectid, fn) {\n if (!subjectid) {\n return this.getEntity(this.invokeGet('_permissions'), fn);\n } else {\n return this.getEntity(this.invokeGet('_permissions/' + urlEncode(subjectid)), fn);\n }\n }\n /**\n * Grants a permission to a subject that allows them to call the specified HTTP methods on a given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Array} permission a set of HTTP methods\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async grantResourcePermission(subjectid, resourcePath, permission, fn) {\n return this.grantResourcePermissions(subjectid, resourcePath, permission, false, fn);\n }\n /**\n * Grants a permission to a subject that allows them to call the specified HTTP methods on a given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Array} permission a set of HTTP methods\n * @param {Boolean} allowGuestAccess if true - all unauthenticated requests will go through, 'false' by default.\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async grantResourcePermissions(subjectid, resourcePath, permission, allowGuestAccess, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath || !permission || !isArray(permission)) {\n fn({});\n return resolve({});\n }\n if (allowGuestAccess && subjectid === '*') {\n permission.push('?');\n }\n resourcePath = base64Url(resourcePath);\n return this.getEntity(\n this.invokePut('_permissions/' + urlEncode(subjectid) + '/' + resourcePath, permission),\n fn\n );\n }\n /**\n * Revokes a permission for a subject, meaning they no longer will be able to access the given resource.\n * @param {String} subjectid subject id (user id)\n * @param {String} resourcePath resource path or object type\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async revokeResourcePermission(subjectid, resourcePath, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath) {\n fn({});\n return resolve({});\n }\n resourcePath = base64Url(resourcePath);\n return this.getEntity(\n this.invokeDelete('_permissions/' + urlEncode(subjectid) + '/' + resourcePath),\n fn\n );\n }\n /**\n * Revokes all permission for a subject.\n * @param {String} subjectid subject id (user id)\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map of the permissions for this subject id\n */\n async revokeAllResourcePermissions(subjectid, fn) {\n fn = fn || noop;\n if (!subjectid) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokeDelete('_permissions/' + urlEncode(subjectid)), fn);\n }\n /**\n * Checks if a subject is allowed to call method X on resource Y.\n * @param {String} subjectid subject id\n * @param {String} resourcePath resource path or object type\n * @param {String} httpMethod HTTP method name\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if allowed\n */\n async isAllowedTo(subjectid, resourcePath, httpMethod, fn) {\n fn = fn || noop;\n if (!subjectid || !resourcePath || !httpMethod) {\n fn(false);\n return resolve(false);\n }\n resourcePath = base64Url(resourcePath);\n var url = '_permissions/' + urlEncode(subjectid) + '/' + resourcePath + '/' + httpMethod;\n return this.getEntity(this.invokeGet(url))\n .then(function (result) {\n var res = result === 'true';\n fn(res);\n return res;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n /////////////////////////////////////////////\n //\t\t\tResource Permissions\n /////////////////////////////////////////////\n /**\n * Returns the value of a specific app setting (property) or all settings if key is blank.\n * @param {String} key a key\n * @param {Function} fn callback (optional)\n * @returns {Promise} a map\n */\n async appSettings(key, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key.trim())) {\n return this.getEntity(this.invokeGet('_settings'), fn);\n } else {\n return this.getEntity(this.invokeGet('_settings/' + key.trim()), fn);\n }\n }\n /**\n * Adds or overwrites an app-specific setting.\n * @param {String} key a key\n * @param {Object} value a value\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async addAppSetting(key, value, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key.trim()) || !value || isEmpty(value)) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokePut('_settings/' + key.trim(), { value: value }), fn);\n }\n /**\n * Overwrites all app-specific settings.\n * @param {Object} settings a key-value map of properties\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async setAppSettings(settings, fn) {\n fn = fn || noop;\n if (!settings) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokePut('_settings', settings), fn);\n }\n /**\n * Removes an app-specific setting.\n * @param {String} key a key\n * @param {Function} fn callback (optional)\n * @returns {Promise} void\n */\n async removeAppSetting(key, fn) {\n fn = fn || noop;\n if (!key || isEmpty(key)) {\n fn({});\n return resolve({});\n }\n return this.getEntity(this.invokeDelete('_settings/' + key.trim()), fn);\n }\n /////////////////////////////////////////////\n //\t\t\t\tAccess Tokens\n /////////////////////////////////////////////\n /**\n * Takes an identity provider access token and fetches the user data from that provider.\n * A new User object is created if that user doesn't exist.\n * Access tokens are returned upon successful authentication using one of the SDKs from\n * Facebook, Google, Twitter, etc.\n * <b>Note:</b> Twitter uses OAuth 1 and gives you a token and a token secret.\n * <b>You must concatenate them like this: <code>{oauth_token}:{oauth_token_secret}</code> and\n * use that as the provider access token.</b>\n * @param {String} provider identity provider, e.g. 'facebook', 'google'...\n * @param {String} providerToken access token from a provider like Facebook, Google, Twitter\n * @param {Boolean} rememberJWT if true, the access token returned by Para will be saved and available via getAccessToken()\n * @param {Function} fn callback (optional)\n * @returns {Promise} a User object or null if something failed\n */\n async signIn(provider, providerToken, rememberJWT, fn) {\n var rememberToken = isBoolean(rememberJWT) ? rememberJWT : true;\n fn = isFunction(rememberJWT) ? rememberJWT : fn || noop;\n\n if (provider && providerToken) {\n var credentials = {};\n var that = this;\n credentials['appid'] = that.accessKey;\n credentials['provider'] = provider;\n credentials['token'] = providerToken;\n return this.getEntity(this.invokePost(JWT_PATH, credentials))\n .then(function (result) {\n if (result !== null && result['user'] && result['jwt']) {\n var jwtData = result['jwt'];\n if (jwtData && rememberToken) {\n that.tokenKey = jwtData['access_token'];\n that.tokenKeyExpires = jwtData['expires'];\n that.tokenKeyNextRefresh = jwtData['refresh'];\n }\n var user = new ParaObject();\n user.setFields(result['user']);\n fn(user);\n return user;\n } else {\n that.clearAccessToken();\n }\n fn(null);\n return null;\n })\n .catch(function () {\n fn(null);\n return null;\n });\n }\n fn(null);\n return Promise.reject(new Error('Provider and provider token are required.'));\n }\n /**\n * Clears the JWT access token but token is not revoked.\n * Tokens can be revoked globally per user with revokeAllTokens().\n */\n signOut() {\n this.clearAccessToken();\n }\n /**\n * Refreshes the JWT access token. This requires a valid existing token.\n * Call link signIn() first.\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if token was refreshed\n */\n async refreshToken(fn) {\n fn = fn || noop;\n var that = this;\n var now = new Date().getTime();\n var notExpired = that.tokenKeyExpires !== null && that.tokenKeyExpires > now;\n var canRefresh =\n that.tokenKeyNextRefresh !== null &&\n (that.tokenKeyNextRefresh < now || that.tokenKeyNextRefresh > that.tokenKeyExpires);\n // token present and NOT expired\n if (that.tokenKey !== null && notExpired && canRefresh) {\n return this.getEntity(this.invokeGet(JWT_PATH))\n .then(function (result) {\n if (result !== null && result['user'] && result['jwt']) {\n var jwtData = result['jwt'];\n that.tokenKey = jwtData['access_token'];\n that.tokenKeyExpires = jwtData['expires'];\n that.tokenKeyNextRefresh = jwtData['refresh'];\n fn(true);\n return true;\n } else {\n that.clearAccessToken();\n }\n fn(false);\n return false;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n fn(false);\n return Promise.resolve(false);\n }\n /**\n * Revokes all user tokens for a given user id.\n * This would be equivalent to \"logout everywhere\".\n * <b>Note:</b> Generating a new API secret on the server will also invalidate all client tokens.\n * Requires a valid existing token.\n * @param {Function} fn callback (optional)\n * @returns {Promise} true if successful\n */\n async revokeAllTokens(fn) {\n fn = fn || noop;\n return this.getEntity(this.invokeDelete(JWT_PATH))\n .then(function (result) {\n var res = result !== null;\n fn(res);\n return res;\n })\n .catch(function () {\n fn(false);\n return false;\n });\n }\n}\n\n/////////////////////////////////////////////\n//\t\t\t\tUtilities\n/////////////////////////////////////////////\n\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nfunction isArray(value) {\n return Array.isArray(value);\n}\n\nfunction isString(value) {\n return typeof value === 'string' || value instanceof String;\n}\n\nfunction isFunction(value) {\n return typeof value === 'function';\n}\n\nfunction isBoolean(value) {\n return typeof value === 'boolean' || value instanceof Boolean;\n}\n\nfunction isInteger(value) {\n return typeof value == 'number';\n}\n\nfunction startsWith(value, prefix) {\n if (value == null) {\n return false;\n }\n return String(value).startsWith(prefix);\n}\n\nfunction endsWith(value, suffix) {\n if (value == null) {\n return false;\n }\n return String(value).endsWith(suffix);\n}\n\nfunction isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArray(value) || isString(value)) {\n return value.length === 0;\n }\n if (value instanceof Map || value instanceof Set) {\n return value.size === 0;\n }\n if (typeof value === 'object') {\n for (var key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n }\n return true;\n}\n\nfunction noop() { }\n\nfunction merge(target) {\n var output = target;\n if (output == null || typeof output !== 'object') {\n output = {};\n }\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n if (source == null) {\n continue;\n }\n for (var key in source) {\n if (!Object.prototype.hasOwnProperty.call(source, key)) {\n continue;\n }\n var sourceValue = source[key];\n var targetValue = output[key];\n if (\n sourceValue &&\n typeof sourceValue === 'object' &&\n !isArray(sourceValue) &&\n !(sourceValue instanceof Date)\n ) {\n if (!targetValue || typeof targetValue !== 'object' || isArray(targetValue)) {\n targetValue = {};\n }\n output[key] = merge(targetValue, sourceValue);\n } else {\n output[key] = sourceValue;\n }\n }\n }\n return output;\n}\n\nfunction urlEncode(path) {\n return encodeURIComponent(path).replace(/[!'()*]/g, function (c) {\n return '%' + c.charCodeAt(0).toString(16).toUpperCase();\n });\n}\n\nfunction uriEncodeAWSV4(path) {\n if (!path || !isString(path)) {\n return '';\n }\n return urlEncode(path).replace(/%2F/g, '/');\n}\n\nfunction unescape(str) {\n return (str + '==='.slice((str.length + 3) % 4)).replace(/-/g, '+').replace(/_/g, '/');\n}\n\nfunction decode(str, encoding) {\n return Buffer.from(unescape(str), 'base64').toString(encoding || 'utf8');\n}\n\nfunction base64Url(str) {\n return Buffer.from(str).toString('base64url');\n}\n\nfunction resolve(obj) {\n return Promise.resolve(obj);\n}\n\nfunction checkParaObject(obj) {\n if (obj) {\n assert(obj instanceof ParaObject, 'Parameter must be a ParaObject.');\n }\n}\n\nfunction checkParaObjects(obj) {\n if (obj && isArray(obj) && !isEmpty(obj)) {\n assert(obj[0] instanceof ParaObject, 'Parameter must be an array of ParaObjects.');\n }\n}\n\nfunction checkPager(obj, fn) {\n if (obj) {\n if (isFunction(obj)) {\n return obj;\n } else {\n assert(obj instanceof Pager, 'Parameter must be a Pager object.');\n return fn || noop;\n }\n }\n return noop;\n}\n\nfunction checkConstraint(obj) {\n if (obj) {\n assert(obj instanceof Constraint, 'Parameter must be a Constraint object.');\n }\n}\n\nexport { ParaClient, ParaObject, Pager, Constraint };\n"],"mappings":"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"}
|