projen
Version:
CDK for software projects
260 lines • 29.2 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyType = exports.Dependencies = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = require("path");
const semver = require("semver");
const common_1 = require("./common");
const component_1 = require("./component");
const json_1 = require("./json");
/**
* The `Dependencies` component is responsible to track the list of dependencies
* a project has, and then used by project types as the model for rendering
* project-specific dependency manifests such as the dependencies section
* `package.json` files.
*
* To add a dependency you can use a project-type specific API such as
* `nodeProject.addDeps()` or use the generic API of `project.deps`:
*/
class Dependencies extends component_1.Component {
/**
* Returns the coordinates of a dependency spec.
*
* Given `foo@^3.4.0` returns `{ name: "foo", version: "^3.4.0" }`.
* Given `bar@npm:@bar/legacy` returns `{ name: "bar", version: "npm:@bar/legacy" }`.
*/
static parseDependency(spec) {
const scope = spec.startsWith("@");
if (scope) {
spec = spec.substr(1);
}
const [module, ...version] = spec.split("@");
const name = scope ? `@${module}` : module;
if (version.length == 0) {
return { name };
}
else {
return { name, version: version?.join("@") };
}
}
/**
* Adds a dependencies component to the project.
* @param project The parent project
*/
constructor(project) {
super(project);
this._deps = new Array();
// this is not really required at the moment, but actually quite useful as a
// checked-in source of truth for dependencies and will potentially be
// valuable in the future for CLI tools.
if (!project.ejected) {
new json_1.JsonFile(project, Dependencies.MANIFEST_FILE, {
omitEmpty: true,
obj: () => this.toJson(),
});
}
}
/**
* A copy of all dependencies recorded for this project.
*
* The list is sorted by type->name->version
*/
get all() {
return [...this._deps].sort(compareDeps).map(normalizeDep);
}
/**
* Returns a dependency by name.
*
* Fails if there is no dependency defined by that name or if `type` is not
* provided and there is more then one dependency type for this dependency.
*
* @param name The name of the dependency
* @param type The dependency type. If this dependency is defined only for a
* single type, this argument can be omitted.
*
* @returns a copy (cannot be modified)
*/
getDependency(name, type) {
const dep = this.tryGetDependency(name, type);
if (!dep) {
const msg = type
? `there is no ${type} dependency defined on "${name}"`
: `there is no dependency defined on "${name}"`;
throw new Error(msg);
}
return dep;
}
/**
* Returns a dependency by name.
*
* Returns `undefined` if there is no dependency defined by that name or if
* `type` is not provided and there is more then one dependency type for this
* dependency.
*
* @param name The name of the dependency
* @param type The dependency type. If this dependency is defined only for a
* single type, this argument can be omitted.
*
* @returns a copy (cannot be modified) or undefined if there is no match
*/
tryGetDependency(name, type) {
const idx = this.tryGetDependencyIndex(name, type);
if (idx === -1) {
return undefined;
}
return {
...normalizeDep(this._deps[idx]),
};
}
/**
* Adds a dependency to this project.
* @param spec The dependency spec in the format `MODULE[@VERSION]` where
* `MODULE` is the package-manager-specific module name and `VERSION` is an
* optional semantic version requirement (e.g. `^3.4.0`).
* @param type The type of the dependency.
*/
addDependency(spec, type, metadata = {}) {
this.project.logger.debug(`${type}-dep ${spec}`);
const dep = {
...Dependencies.parseDependency(spec),
type,
metadata,
};
const existingDepIndex = this.tryGetDependencyIndex(dep.name, type);
if (existingDepIndex !== -1) {
this.project.logger.debug(`updating existing ${dep.type}-dep ${dep.name} with more specific version/metadata`);
this._deps[existingDepIndex] = dep;
}
else {
this._deps.push(dep);
}
return dep;
}
/**
* Removes a dependency.
* @param name The name of the module to remove (without the version)
* @param type The dependency type. This is only required if there the
* dependency is defined for multiple types.
*/
removeDependency(name, type) {
const removeIndex = this.tryGetDependencyIndex(name, type);
if (removeIndex === -1) {
return;
}
this._deps.splice(removeIndex, 1);
}
/**
* Checks if an existing dependency satisfies a dependency requirement.
* @param name The name of the dependency to check (without the version).
* @param type The dependency type.
* @param expectedRange The version constraint to check (e.g. `^3.4.0`).
* The constraint of the dependency must be a subset of the expected range to satisfy the requirements.
* @returns `true` if the dependency exists and its version satisfies the provided constraint. `false` otherwise.
* Notably returns `false` if a dependency exists, but has no version.
*/
isDependencySatisfied(name, type, expectedRange) {
const dep = this.tryGetDependency(name, type);
return dep?.version != null && semver.subset(dep.version, expectedRange);
}
tryGetDependencyIndex(name, type) {
const deps = this._deps.filter((d) => d.name === name);
if (deps.length === 0) {
return -1; // not found
}
if (!type) {
if (deps.length > 1) {
throw new Error(`"${name}" is defined for multiple dependency types: ${deps
.map((d) => d.type)
.join(",")}. Please specify dependency type`);
}
type = deps[0].type;
}
return this._deps.findIndex((dep) => dep.name === name && dep.type === type);
}
toJson() {
if (this._deps.length === 0) {
return undefined;
}
return {
dependencies: this._deps.sort(compareDeps).map(normalizeDep),
};
}
}
exports.Dependencies = Dependencies;
_a = JSII_RTTI_SYMBOL_1;
Dependencies[_a] = { fqn: "projen.Dependencies", version: "0.99.17" };
/**
* The project-relative path of the deps manifest file.
*/
Dependencies.MANIFEST_FILE = path.posix.join(common_1.PROJEN_DIR, "deps.json");
function normalizeDep(d) {
const obj = {};
for (const [k, v] of Object.entries(d)) {
if (v == undefined) {
continue;
}
if (typeof v === "object" && Object.keys(v).length === 0) {
continue;
}
if (Array.isArray(v) && v.length === 0) {
continue;
}
obj[k] = v;
}
return obj;
}
function compareDeps(d1, d2) {
return specOf(d1).localeCompare(specOf(d2));
function specOf(dep) {
let spec = dep.type + ":" + dep.name;
if (dep.version) {
spec += "@" + dep.version;
}
return spec;
}
}
/**
* Type of dependency.
*/
var DependencyType;
(function (DependencyType) {
/**
* The dependency is required for the program/library during runtime.
*/
DependencyType["RUNTIME"] = "runtime";
/**
* The dependency is required at runtime but expected to be installed by the
* consumer.
*/
DependencyType["PEER"] = "peer";
/**
* The dependency is bundled and shipped with the module, so consumers are not
* required to install it.
*/
DependencyType["BUNDLED"] = "bundled";
/**
* The dependency is required to run the `build` task.
*/
DependencyType["BUILD"] = "build";
/**
* The dependency is required to run the `test` task.
*/
DependencyType["TEST"] = "test";
/**
* The dependency is required for development (e.g. IDE plugins).
*/
DependencyType["DEVENV"] = "devenv";
/**
* Transient dependency that needs to be overwritten.
*
* Available for Node packages
*/
DependencyType["OVERRIDE"] = "override";
/**
* An optional dependency that may be used at runtime if available, but is not required.
* It is expected to be installed by the consumer.
*/
DependencyType["OPTIONAL"] = "optional";
})(DependencyType || (exports.DependencyType = DependencyType = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwZW5kZW5jaWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RlcGVuZGVuY2llcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZCQUE2QjtBQUM3QixpQ0FBaUM7QUFDakMscUNBQXNDO0FBQ3RDLDJDQUF3QztBQUN4QyxpQ0FBa0M7QUFHbEM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLFlBQWEsU0FBUSxxQkFBUztJQVN6Qzs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxlQUFlLENBQUMsSUFBWTtRQUN4QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QixDQUFDO1FBRUQsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0MsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDM0MsSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUNsQixDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUlEOzs7T0FHRztJQUNILFlBQVksT0FBZ0I7UUFDMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBUEEsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFjLENBQUM7UUFTL0MsNEVBQTRFO1FBQzVFLHNFQUFzRTtRQUN0RSx3Q0FB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RUFBYztJQUNqRCxPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFNUMsU0FBUyxNQUFNLENBQUMsR0FBZTtRQUM3QixJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ3JDLElBQUksR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hCLElBQUksSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztRQUM1QixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQThDRDs7R0FFRztBQUNILElBQVksY0E2Q1g7QUE3Q0QsV0FBWSxjQUFjO0lBQ3hCOztPQUVHO0lBQ0gscUNBQW1CLENBQUE7SUFFbkI7OztPQUdHO0lBQ0gsK0JBQWEsQ0FBQTtJQUViOzs7T0FHRztJQUNILHFDQUFtQixDQUFBO0lBRW5COztPQUVHO0lBQ0gsaUNBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gsK0JBQWEsQ0FBQTtJQUViOztPQUVHO0lBQ0gsbUNBQWlCLENBQUE7SUFFakI7Ozs7T0FJRztJQUNILHVDQUFxQixDQUFBO0lBRXJCOzs7T0FHRztJQUNILHVDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUE3Q1csY0FBYyw4QkFBZCxjQUFjLFFBNkN6QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCAqIGFzIHNlbXZlciBmcm9tIFwic2VtdmVyXCI7XG5pbXBvcnQgeyBQUk9KRU5fRElSIH0gZnJvbSBcIi4vY29tbW9uXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IEpzb25GaWxlIH0gZnJvbSBcIi4vanNvblwiO1xuaW1wb3J0IHsgUHJvamVjdCB9IGZyb20gXCIuL3Byb2plY3RcIjtcblxuLyoqXG4gKiBUaGUgYERlcGVuZGVuY2llc2AgY29tcG9uZW50IGlzIHJlc3BvbnNpYmxlIHRvIHRyYWNrIHRoZSBsaXN0IG9mIGRlcGVuZGVuY2llc1xuICogYSBwcm9qZWN0IGhhcywgYW5kIHRoZW4gdXNlZCBieSBwcm9qZWN0IHR5cGVzIGFzIHRoZSBtb2RlbCBmb3IgcmVuZGVyaW5nXG4gKiBwcm9qZWN0LXNwZWNpZmljIGRlcGVuZGVuY3kgbWFuaWZlc3RzIHN1Y2ggYXMgdGhlIGRlcGVuZGVuY2llcyBzZWN0aW9uXG4gKiBgcGFja2FnZS5qc29uYCBmaWxlcy5cbiAqXG4gKiBUbyBhZGQgYSBkZXBlbmRlbmN5IHlvdSBjYW4gdXNlIGEgcHJvamVjdC10eXBlIHNwZWNpZmljIEFQSSBzdWNoIGFzXG4gKiBgbm9kZVByb2plY3QuYWRkRGVwcygpYCBvciB1c2UgdGhlIGdlbmVyaWMgQVBJIG9mIGBwcm9qZWN0LmRlcHNgOlxuICovXG5leHBvcnQgY2xhc3MgRGVwZW5kZW5jaWVzIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIFRoZSBwcm9qZWN0LXJlbGF0aXZlIHBhdGggb2YgdGhlIGRlcHMgbWFuaWZlc3QgZmlsZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTUFOSUZFU1RfRklMRSA9IHBhdGgucG9zaXguam9pbihcbiAgICBQUk9KRU5fRElSLFxuICAgIFwiZGVwcy5qc29uXCIsXG4gICk7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNvb3JkaW5hdGVzIG9mIGEgZGVwZW5kZW5jeSBzcGVjLlxuICAgKlxuICAgKiBHaXZlbiBgZm9vQF4zLjQuMGAgcmV0dXJucyBgeyBuYW1lOiBcImZvb1wiLCB2ZXJzaW9uOiBcIl4zLjQuMFwiIH1gLlxuICAgKiBHaXZlbiBgYmFyQG5wbTpAYmFyL2xlZ2FjeWAgcmV0dXJucyBgeyBuYW1lOiBcImJhclwiLCB2ZXJzaW9uOiBcIm5wbTpAYmFyL2xlZ2FjeVwiIH1gLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwYXJzZURlcGVuZGVuY3koc3BlYzogc3RyaW5nKTogRGVwZW5kZW5jeUNvb3JkaW5hdGVzIHtcbiAgICBjb25zdCBzY29wZSA9IHNwZWMuc3RhcnRzV2l0aChcIkBcIik7XG4gICAgaWYgKHNjb3BlKSB7XG4gICAgICBzcGVjID0gc3BlYy5zdWJzdHIoMSk7XG4gICAgfVxuXG4gICAgY29uc3QgW21vZHVsZSwgLi4udmVyc2lvbl0gPSBzcGVjLnNwbGl0KFwiQFwiKTtcbiAgICBjb25zdCBuYW1lID0gc2NvcGUgPyBgQCR7bW9kdWxlfWAgOiBtb2R1bGU7XG4gICAgaWYgKHZlcnNpb24ubGVuZ3RoID09IDApIHtcbiAgICAgIHJldHVybiB7IG5hbWUgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbjogdmVyc2lvbj8uam9pbihcIkBcIikgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IF9kZXBzID0gbmV3IEFycmF5PERlcGVuZGVuY3k+KCk7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBkZXBlbmRlbmNpZXMgY29tcG9uZW50IHRvIHRoZSBwcm9qZWN0LlxuICAgKiBAcGFyYW0gcHJvamVjdCBUaGUgcGFyZW50IHByb2plY3RcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IFByb2plY3QpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgIC8vIHRoaXMgaXMgbm90IHJlYWxseSByZXF1aXJlZCBhdCB0aGUgbW9tZW50LCBidXQgYWN0dWFsbHkgcXVpdGUgdXNlZnVsIGFzIGFcbiAgICAvLyBjaGVja2VkLWluIHNvdXJjZSBvZiB0cnV0aCBmb3IgZGVwZW5kZW5jaWVzIGFuZCB3aWxsIHBvdGVudGlhbGx5IGJlXG4gICAgLy8gdmFsdWFibGUgaW4gdGhlIGZ1dHVyZSBmb3IgQ0xJIHRvb2xzLlxuICAgIGlmICghcHJvamVjdC5lamVjdGVkKSB7XG4gICAgICBuZXcgSnNvbkZpbGUocHJvamVjdCwgRGVwZW5kZW5jaWVzLk1BTklGRVNUX0ZJTEUsIHtcbiAgICAgICAgb21pdEVtcHR5OiB0cnVlLFxuICAgICAgICBvYmo6ICgpID0+IHRoaXMudG9Kc29uKCksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQSBjb3B5IG9mIGFsbCBkZXBlbmRlbmNpZXMgcmVjb3JkZWQgZm9yIHRoaXMgcHJvamVjdC5cbiAgICpcbiAgICogVGhlIGxpc3QgaXMgc29ydGVkIGJ5IHR5cGUtPm5hbWUtPnZlcnNpb25cbiAgICovXG4gIHB1YmxpYyBnZXQgYWxsKCk6IERlcGVuZGVuY3lbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLl9kZXBzXS5zb3J0KGNvbXBhcmVEZXBzKS5tYXAobm9ybWFsaXplRGVwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgZGVwZW5kZW5jeSBieSBuYW1lLlxuICAgKlxuICAgKiBGYWlscyBpZiB0aGVyZSBpcyBubyBkZXBlbmRlbmN5IGRlZmluZWQgYnkgdGhhdCBuYW1lIG9yIGlmIGB0eXBlYCBpcyBub3RcbiAgICogcHJvdmlkZWQgYW5kIHRoZXJlIGlzIG1vcmUgdGhlbiBvbmUgZGVwZW5kZW5jeSB0eXBlIGZvciB0aGlzIGRlcGVuZGVuY3kuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZXBlbmRlbmN5XG4gICAqIEBwYXJhbSB0eXBlIFRoZSBkZXBlbmRlbmN5IHR5cGUuIElmIHRoaXMgZGVwZW5kZW5jeSBpcyBkZWZpbmVkIG9ubHkgZm9yIGFcbiAgICogc2luZ2xlIHR5cGUsIHRoaXMgYXJndW1lbnQgY2FuIGJlIG9taXR0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgY29weSAoY2Fubm90IGJlIG1vZGlmaWVkKVxuICAgKi9cbiAgcHVibGljIGdldERlcGVuZGVuY3kobmFtZTogc3RyaW5nLCB0eXBlPzogRGVwZW5kZW5jeVR5cGUpOiBEZXBlbmRlbmN5IHtcbiAgICBjb25zdCBkZXAgPSB0aGlzLnRyeUdldERlcGVuZGVuY3kobmFtZSwgdHlwZSk7XG4gICAgaWYgKCFkZXApIHtcbiAgICAgIGNvbnN0IG1zZyA9IHR5cGVcbiAgICAgICAgPyBgdGhlcmUgaXMgbm8gJHt0eXBlfSBkZXBlbmRlbmN5IGRlZmluZWQgb24gXCIke25hbWV9XCJgXG4gICAgICAgIDogYHRoZXJlIGlzIG5vIGRlcGVuZGVuY3kgZGVmaW5lZCBvbiBcIiR7bmFtZX1cImA7XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH1cblxuICAgIHJldHVybiBkZXA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGRlcGVuZGVuY3kgYnkgbmFtZS5cbiAgICpcbiAgICogUmV0dXJucyBgdW5kZWZpbmVkYCBpZiB0aGVyZSBpcyBubyBkZXBlbmRlbmN5IGRlZmluZWQgYnkgdGhhdCBuYW1lIG9yIGlmXG4gICAqIGB0eXBlYCBpcyBub3QgcHJvdmlkZWQgYW5kIHRoZXJlIGlzIG1vcmUgdGhlbiBvbmUgZGVwZW5kZW5jeSB0eXBlIGZvciB0aGlzXG4gICAqIGRlcGVuZGVuY3kuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBkZXBlbmRlbmN5XG4gICAqIEBwYXJhbSB0eXBlIFRoZSBkZXBlbmRlbmN5IHR5cGUuIElmIHRoaXMgZGVwZW5kZW5jeSBpcyBkZWZpbmVkIG9ubHkgZm9yIGFcbiAgICogc2luZ2xlIHR5cGUsIHRoaXMgYXJndW1lbnQgY2FuIGJlIG9taXR0ZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgY29weSAoY2Fubm90IGJlIG1vZGlmaWVkKSBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXMgbm8gbWF0Y2hcbiAgICovXG4gIHB1YmxpYyB0cnlHZXREZXBlbmRlbmN5KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB0eXBlPzogRGVwZW5kZW5jeVR5cGUsXG4gICk6IERlcGVuZGVuY3kgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGlkeCA9IHRoaXMudHJ5R2V0RGVwZW5kZW5jeUluZGV4KG5hbWUsIHR5cGUpO1xuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi5ub3JtYWxpemVEZXAodGhpcy5fZGVwc1tpZHhdKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBkZXBlbmRlbmN5IHRvIHRoaXMgcHJvamVjdC5cbiAgICogQHBhcmFtIHNwZWMgVGhlIGRlcGVuZGVuY3kgc3BlYyBpbiB0aGUgZm9ybWF0IGBNT0RVTEVbQFZFUlNJT05dYCB3aGVyZVxuICAgKiBgTU9EVUxFYCBpcyB0aGUgcGFja2FnZS1tYW5hZ2VyLXNwZWNpZmljIG1vZHVsZSBuYW1lIGFuZCBgVkVSU0lPTmAgaXMgYW5cbiAgICogb3B0aW9uYWwgc2VtYW50aWMgdmVyc2lvbiByZXF1aXJlbWVudCAoZS5nLiBgXjMuNC4wYCkuXG4gICAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIHRoZSBkZXBlbmRlbmN5LlxuICAgKi9cbiAgcHVibGljIGFkZERlcGVuZGVuY3koXG4gICAgc3BlYzogc3RyaW5nLFxuICAgIHR5cGU6IERlcGVuZGVuY3lUeXBlLFxuICAgIG1ldGFkYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge30sXG4gICk6IERlcGVuZGVuY3kge1xuICAgIHRoaXMucHJvamVjdC5sb2dnZXIuZGVidWcoYCR7dHlwZX0tZGVwICR7c3BlY31gKTtcblxuICAgIGNvbnN0IGRlcDogRGVwZW5kZW5jeSA9IHtcbiAgICAgIC4uLkRlcGVuZGVuY2llcy5wYXJzZURlcGVuZGVuY3koc3BlYyksXG4gICAgICB0eXBlLFxuICAgICAgbWV0YWRhdGEsXG4gICAgfTtcblxuICAgIGNvbnN0IGV4aXN0aW5nRGVwSW5kZXggPSB0aGlzLnRyeUdldERlcGVuZGVuY3lJbmRleChkZXAubmFtZSwgdHlwZSk7XG5cbiAgICBpZiAoZXhpc3RpbmdEZXBJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMucHJvamVjdC5sb2dnZXIuZGVidWcoXG4gICAgICAgIGB1cGRhdGluZyBleGlzdGluZyAke2RlcC50eXBlfS1kZXAgJHtkZXAubmFtZX0gd2l0aCBtb3JlIHNwZWNpZmljIHZlcnNpb24vbWV0YWRhdGFgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuX2RlcHNbZXhpc3RpbmdEZXBJbmRleF0gPSBkZXA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2RlcHMucHVzaChkZXApO1xuICAgIH1cblxuICAgIHJldHVybiBkZXA7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGRlcGVuZGVuY3kuXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGUgdG8gcmVtb3ZlICh3aXRob3V0IHRoZSB2ZXJzaW9uKVxuICAgKiBAcGFyYW0gdHlwZSBUaGUgZGVwZW5kZW5jeSB0eXBlLiBUaGlzIGlzIG9ubHkgcmVxdWlyZWQgaWYgdGhlcmUgdGhlXG4gICAqIGRlcGVuZGVuY3kgaXMgZGVmaW5lZCBmb3IgbXVsdGlwbGUgdHlwZXMuXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlRGVwZW5kZW5jeShuYW1lOiBzdHJpbmcsIHR5cGU/OiBEZXBlbmRlbmN5VHlwZSkge1xuICAgIGNvbnN0IHJlbW92ZUluZGV4ID0gdGhpcy50cnlHZXREZXBlbmRlbmN5SW5kZXgobmFtZSwgdHlwZSk7XG4gICAgaWYgKHJlbW92ZUluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RlcHMuc3BsaWNlKHJlbW92ZUluZGV4LCAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYW4gZXhpc3RpbmcgZGVwZW5kZW5jeSBzYXRpc2ZpZXMgYSBkZXBlbmRlbmN5IHJlcXVpcmVtZW50LlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZGVwZW5kZW5jeSB0byBjaGVjayAod2l0aG91dCB0aGUgdmVyc2lvbikuXG4gICAqIEBwYXJhbSB0eXBlIFRoZSBkZXBlbmRlbmN5IHR5cGUuXG4gICAqIEBwYXJhbSBleHBlY3RlZFJhbmdlIFRoZSB2ZXJzaW9uIGNvbnN0cmFpbnQgdG8gY2hlY2sgKGUuZy4gYF4zLjQuMGApLlxuICAgKiBUaGUgY29uc3RyYWludCBvZiB0aGUgZGVwZW5kZW5jeSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSBleHBlY3RlZCByYW5nZSB0byBzYXRpc2Z5IHRoZSByZXF1aXJlbWVudHMuXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgZGVwZW5kZW5jeSBleGlzdHMgYW5kIGl0cyB2ZXJzaW9uIHNhdGlzZmllcyB0aGUgcHJvdmlkZWQgY29uc3RyYWludC4gYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqIE5vdGFibHkgcmV0dXJucyBgZmFsc2VgIGlmIGEgZGVwZW5kZW5jeSBleGlzdHMsIGJ1dCBoYXMgbm8gdmVyc2lvbi5cbiAgICovXG4gIHB1YmxpYyBpc0RlcGVuZGVuY3lTYXRpc2ZpZWQoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHR5cGU6IERlcGVuZGVuY3lUeXBlLFxuICAgIGV4cGVjdGVkUmFuZ2U6IHN0cmluZyxcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGVwID0gdGhpcy50cnlHZXREZXBlbmRlbmN5KG5hbWUsIHR5cGUpO1xuICAgIHJldHVybiBkZXA/LnZlcnNpb24gIT0gbnVsbCAmJiBzZW12ZXIuc3Vic2V0KGRlcC52ZXJzaW9uLCBleHBlY3RlZFJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJ5R2V0RGVwZW5kZW5jeUluZGV4KG5hbWU6IHN0cmluZywgdHlwZT86IERlcGVuZGVuY3lUeXBlKTogbnVtYmVyIHtcbiAgICBjb25zdCBkZXBzID0gdGhpcy5fZGVwcy5maWx0ZXIoKGQpID0+IGQubmFtZSA9PT0gbmFtZSk7XG4gICAgaWYgKGRlcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTE7IC8vIG5vdCBmb3VuZFxuICAgIH1cblxuICAgIGlmICghdHlwZSkge1xuICAgICAgaWYgKGRlcHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFwiJHtuYW1lfVwiIGlzIGRlZmluZWQgZm9yIG11bHRpcGxlIGRlcGVuZGVuY3kgdHlwZXM6ICR7ZGVwc1xuICAgICAgICAgICAgLm1hcCgoZCkgPT4gZC50eXBlKVxuICAgICAgICAgICAgLmpvaW4oXCIsXCIpfS4gUGxlYXNlIHNwZWNpZnkgZGVwZW5kZW5jeSB0eXBlYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdHlwZSA9IGRlcHNbMF0udHlwZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGVwcy5maW5kSW5kZXgoXG4gICAgICAoZGVwKSA9PiBkZXAubmFtZSA9PT0gbmFtZSAmJiBkZXAudHlwZSA9PT0gdHlwZSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB0b0pzb24oKTogRGVwc01hbmlmZXN0IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5fZGVwcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBkZXBlbmRlbmNpZXM6IHRoaXMuX2RlcHMuc29ydChjb21wYXJlRGVwcykubWFwKG5vcm1hbGl6ZURlcCksXG4gICAgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVEZXAoZDogRGVwZW5kZW5jeSkge1xuICBjb25zdCBvYmo6IGFueSA9IHt9O1xuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhkKSkge1xuICAgIGlmICh2ID09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiBPYmplY3Qua2V5cyh2KS5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2KSAmJiB2Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG9ialtrXSA9IHY7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlRGVwcyhkMTogRGVwZW5kZW5jeSwgZDI6IERlcGVuZGVuY3kpIHtcbiAgcmV0dXJuIHNwZWNPZihkMSkubG9jYWxlQ29tcGFyZShzcGVjT2YoZDIpKTtcblxuICBmdW5jdGlvbiBzcGVjT2YoZGVwOiBEZXBlbmRlbmN5KSB7XG4gICAgbGV0IHNwZWMgPSBkZXAudHlwZSArIFwiOlwiICsgZGVwLm5hbWU7XG4gICAgaWYgKGRlcC52ZXJzaW9uKSB7XG4gICAgICBzcGVjICs9IFwiQFwiICsgZGVwLnZlcnNpb247XG4gICAgfVxuICAgIHJldHVybiBzcGVjO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwc01hbmlmZXN0IHtcbiAgLyoqXG4gICAqIEFsbCBkZXBlbmRlbmNpZXMgb2YgdGhpcyBtb2R1bGUuXG4gICAqL1xuICByZWFkb25seSBkZXBlbmRlbmNpZXM6IERlcGVuZGVuY3lbXTtcbn1cblxuLyoqXG4gKiBDb29yZGluYXRlcyBvZiB0aGUgZGVwZW5kZW5jeSAobmFtZSBhbmQgdmVyc2lvbikuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVwZW5kZW5jeUNvb3JkaW5hdGVzIHtcbiAgLyoqXG4gICAqIFRoZSBwYWNrYWdlIG1hbmFnZXIgbmFtZSBvZiB0aGUgZGVwZW5kZW5jeSAoZS5nLiBgbGVmdHBhZGAgZm9yIG5wbSkuXG4gICAqXG4gICAqIE5PVEU6IEZvciBwYWNrYWdlIG1hbmFnZXJzIHRoYXQgdXNlIGNvbXBsZXggY29vcmRpbmF0ZXMgKGxpa2UgTWF2ZW4pLCB3ZVxuICAgKiB3aWxsIGNvZGlmeSBpdCBpbnRvIGEgc3RyaW5nIHNvbWVob3cuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNlbWFudGljIHZlcnNpb24gdmVyc2lvbiByZXF1aXJlbWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSByZXF1aXJlbWVudCBpcyBtYW5hZ2VkIGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXIgKGUuZy4gbnBtL3lhcm4pLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcHJvamVjdCBkZXBlbmRlbmN5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlcGVuZGVuY3kgZXh0ZW5kcyBEZXBlbmRlbmN5Q29vcmRpbmF0ZXMge1xuICAvKipcbiAgICogV2hpY2ggdHlwZSBvZiBkZXBlbmRlbmN5IHRoaXMgaXMgKHJ1bnRpbWUsIGJ1aWxkLXRpbWUsIGV0YykuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBEZXBlbmRlbmN5VHlwZTtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBKU09OIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGVwZW5kZW5jeSAocGFja2FnZSBtYW5hZ2VyXG4gICAqIHNwZWNpZmljKS5cbiAgICogQGRlZmF1bHQge31cbiAgICovXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuLyoqXG4gKiBUeXBlIG9mIGRlcGVuZGVuY3kuXG4gKi9cbmV4cG9ydCBlbnVtIERlcGVuZGVuY3lUeXBlIHtcbiAgLyoqXG4gICAqIFRoZSBkZXBlbmRlbmN5IGlzIHJlcXVpcmVkIGZvciB0aGUgcHJvZ3JhbS9saWJyYXJ5IGR1cmluZyBydW50aW1lLlxuICAgKi9cbiAgUlVOVElNRSA9IFwicnVudGltZVwiLFxuXG4gIC8qKlxuICAgKiBUaGUgZGVwZW5kZW5jeSBpcyByZXF1aXJlZCBhdCBydW50aW1lIGJ1dCBleHBlY3RlZCB0byBiZSBpbnN0YWxsZWQgYnkgdGhlXG4gICAqIGNvbnN1bWVyLlxuICAgKi9cbiAgUEVFUiA9IFwicGVlclwiLFxuXG4gIC8qKlxuICAgKiBUaGUgZGVwZW5kZW5jeSBpcyBidW5kbGVkIGFuZCBzaGlwcGVkIHdpdGggdGhlIG1vZHVsZSwgc28gY29uc3VtZXJzIGFyZSBub3RcbiAgICogcmVxdWlyZWQgdG8gaW5zdGFsbCBpdC5cbiAgICovXG4gIEJVTkRMRUQgPSBcImJ1bmRsZWRcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgdG8gcnVuIHRoZSBgYnVpbGRgIHRhc2suXG4gICAqL1xuICBCVUlMRCA9IFwiYnVpbGRcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgdG8gcnVuIHRoZSBgdGVzdGAgdGFzay5cbiAgICovXG4gIFRFU1QgPSBcInRlc3RcIixcblxuICAvKipcbiAgICogVGhlIGRlcGVuZGVuY3kgaXMgcmVxdWlyZWQgZm9yIGRldmVsb3BtZW50IChlLmcuIElERSBwbHVnaW5zKS5cbiAgICovXG4gIERFVkVOViA9IFwiZGV2ZW52XCIsXG5cbiAgLyoqXG4gICAqIFRyYW5zaWVudCBkZXBlbmRlbmN5IHRoYXQgbmVlZHMgdG8gYmUgb3ZlcndyaXR0ZW4uXG4gICAqXG4gICAqIEF2YWlsYWJsZSBmb3IgTm9kZSBwYWNrYWdlc1xuICAgKi9cbiAgT1ZFUlJJREUgPSBcIm92ZXJyaWRlXCIsXG5cbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIGRlcGVuZGVuY3kgdGhhdCBtYXkgYmUgdXNlZCBhdCBydW50aW1lIGlmIGF2YWlsYWJsZSwgYnV0IGlzIG5vdCByZXF1aXJlZC5cbiAgICogSXQgaXMgZXhwZWN0ZWQgdG8gYmUgaW5zdGFsbGVkIGJ5IHRoZSBjb25zdW1lci5cbiAgICovXG4gIE9QVElPTkFMID0gXCJvcHRpb25hbFwiLFxufVxuIl19