UNPKG

@adpt/cloud

Version:
155 lines 5.55 kB
"use strict"; /* * Copyright 2018-2019 Unbounded Systems, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const utils_1 = require("@adpt/utils"); const lodash_1 = require("lodash"); const randomstring = tslib_1.__importStar(require("randomstring")); var ResourceIdPolicy; (function (ResourceIdPolicy) { ResourceIdPolicy["local"] = "local"; ResourceIdPolicy["default"] = "local"; ResourceIdPolicy["globalCreateOnly"] = "globalCreateOnly"; ResourceIdPolicy["globalUseOnly"] = "globalUseOnly"; ResourceIdPolicy["globalCreateOrUse"] = "globalCreateOrUse"; })(ResourceIdPolicy = exports.ResourceIdPolicy || (exports.ResourceIdPolicy = {})); function isResourceId(val) { if (val == null || typeof val !== "object") return false; if (val.baseId !== null && typeof val.baseId !== "string") return false; if ("policy" in val && typeof val.policy !== "string") return false; if ("options" in val && typeof val.options !== "object") return false; for (const k of Object.keys(val)) { switch (k) { case "baseId": case "policy": case "options": continue; default: return false; } } return true; } /** * Creates a tuple of the names of a set of properties. This can then be used * subsequently for both static type operations and runtime manipulation. * * @param idPropNames The string literal names of object properties that * should be ResourceIds. */ function resourceIdList(...idPropNames) { return utils_1.tuple(...idPropNames); } exports.resourceIdList = resourceIdList; function idToString(config) { const { baseId, options, policy } = config; let base = baseId; let rand = ""; let sep = ""; if (base == null) base = options.defaultBaseId; if (base == null) { throw new Error(`ResourceId: one of baseId or defaultBaseId must be set`); } if (policy === ResourceIdPolicy.local) { rand = randomstring.generate({ length: options.randLength, charset: "alphabetic", readable: true, capitalization: "lowercase", }); sep = options.separator; } if (options.maxIdLength) { base = base.substring(0, options.maxIdLength - sep.length - rand.length); } return base + sep + rand; } exports.idToString = idToString; const defaultIdOptions = Object.freeze({ defaultBaseId: null, maxIdLength: null, // randomstring uses 8 bits of entropy from crypto.randomBytes (which // uses the system's strong PRNG e.g. /dev/random) to select each character, // so entropy is actually constrained by the character set used. // With randLength=8, and lower case alphabetic, the probability of // collision of names is 1 in 26^8 or about 208 trillion. randLength: 8, separator: "", }); function resourceIdConfig(id, policy, options) { if (isResourceId(id)) { return { baseId: id.baseId, options: Object.assign({}, defaultIdOptions, options, id.options), policy: id.policy || policy, }; } if (lodash_1.isNull(id) || typeof id === "string") { return { baseId: id, options: Object.assign({}, defaultIdOptions, options), policy }; } return undefined; } exports.resourceIdConfig = resourceIdConfig; function updateResourceIdState(idList, props, state, policy = ResourceIdPolicy.default, options = {}) { // tslint:disable-next-line:no-object-literal-type-assertion const currentIds = (state.adaptResourceIds || {}); // tslint:disable-next-line:no-object-literal-type-assertion const updated = {}; for (const k of idList) { const current = currentIds[k]; const newConfig = resourceIdConfig(props[k], policy, options); if (newConfig === undefined) continue; // If the configuration hasn't changed and we already have an ID, // then no change for this ID if (current != null && (typeof current.currentId === "string") && lodash_1.isEqual(current.configured, newConfig)) { updated[k] = current; } else { updated[k] = { configured: newConfig, currentId: idToString(newConfig), }; } } return { adaptResourceIds: updated }; } exports.updateResourceIdState = updateResourceIdState; function getResourceIds(idList, state) { const currentIds = state.adaptResourceIds; if (currentIds == null) return undefined; // tslint:disable-next-line:no-object-literal-type-assertion const ret = {}; for (const key of idList) { ret[key] = currentIds[key].currentId; } return ret; } exports.getResourceIds = getResourceIds; //# sourceMappingURL=resource_id.js.map