@adpt/cloud
Version:
AdaptJS cloud component library
155 lines • 5.55 kB
JavaScript
;
/*
* 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