UNPKG

projen

Version:

CDK for software projects

224 lines • 32.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModuleImports = void 0; exports.renderProjenInitOptions = renderProjenInitOptions; exports.resolveInitProject = resolveInitProject; exports.renderJavaScriptOptions = renderJavaScriptOptions; const inventory = require("../inventory"); const option_hints_1 = require("../option-hints"); const PROJEN_NEW = "__new__"; const TAB = makePadding(2); /** * Renders options as if the project was created via `projen new` (embeds the __new__ field). */ function renderProjenInitOptions(fqn, args, comments = option_hints_1.InitProjectOptionHints.NONE) { return { ...args, [PROJEN_NEW]: { fqn, args, comments }, }; } function resolveInitProject(opts) { const f = opts[PROJEN_NEW]; if (!f) { return undefined; } const type = inventory.resolveProjectType(f.fqn); if (!type) { throw new Error(`unable to resolve project type for ${f.fqn}`); } return { args: f.args, fqn: f.fqn, type: type, comments: f.comments, }; } class ModuleImports { constructor() { this.imports = new Map(); } /** * Add a named import from a module */ add(moduleName, importName) { const moduleImports = this.imports.get(moduleName) ?? new Set(); moduleImports.add(importName); this.imports.set(moduleName, moduleImports); } /** * Get all named imports for a module */ get(moduleName) { const moduleImports = this.imports.get(moduleName) ?? new Set(); return Array.from(moduleImports); } /** * Get a list of all used modules */ get modules() { return Array.from(this.imports.keys()); } /** * Return all imports as ESM import statements */ asEsmImports() { return this.all().map(([moduleName, namedImports]) => `import { ${[...namedImports].join(", ")} } from "${moduleName}";`); } /** * Return all imports as CJS require statements */ asCjsRequire() { return this.all().map(([moduleName, namedImports]) => `const { ${[...namedImports].join(", ")} } = require("${moduleName}");`); } all() { const allImports = Object.fromEntries(this.imports); return Object.entries(allImports).map(([key, value]) => [ key, Array.from(value).sort(), ]); } } exports.ModuleImports = ModuleImports; /** * Prints all parameters that can be used in a project type, alongside their descriptions. * * Parameters in `params` that aren't undefined are rendered as defaults, * while all other parameters are rendered as commented out. * * Returns the printed output and a set of required imports as an object * in the form { options, imports }. */ function renderJavaScriptOptions(opts) { const renders = {}; const optionsWithDefaults = []; const allImports = new ModuleImports(); for (const option of opts.type.options) { if (option.deprecated) { continue; } const optionName = option.name; if (opts.args[optionName] !== undefined) { const arg = opts.args[optionName]; const { js, moduleName, importName } = renderArgAsJavaScript(arg, option); renders[optionName] = `${optionName}: ${js},`; optionsWithDefaults.push(optionName); if (moduleName && importName) { allImports.add(moduleName, importName); if (opts.prefixImports) { const prefix = `${opts.prefixImports}["${moduleName}"].`; renders[optionName] = `${optionName}: ${prefix}${js},`; } } } else { const defaultValue = option.default?.startsWith("-") ? undefined : (option.default ?? undefined); renders[optionName] = `// ${optionName}: ${defaultValue},`; } } const bootstrap = opts.bootstrap ?? false; if (bootstrap) { for (const arg of opts.omitFromBootstrap ?? []) { delete opts.args[arg]; } renders[PROJEN_NEW] = `${PROJEN_NEW}: ${JSON.stringify({ args: opts.args, fqn: opts.type.fqn, comments: opts.comments, })},`; optionsWithDefaults.push(PROJEN_NEW); } // generate rendering const result = []; result.push("{"); // render options with defaults optionsWithDefaults.sort(); for (const optionName of optionsWithDefaults) { result.push(`${TAB}${renders[optionName]}`); } if (result.length > 1) { result.push(""); } // render options without defaults as comments if (opts.comments === option_hints_1.InitProjectOptionHints.ALL) { const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined); result.push(...renderCommentedOptionsByModule(renders, options)); } else if (opts.comments === option_hints_1.InitProjectOptionHints.FEATURED) { const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined && opt.featured); result.push(...renderCommentedOptionsInOrder(renders, options)); } else if (opts.comments === option_hints_1.InitProjectOptionHints.NONE) { // don't render any extra options } if (result[result.length - 1] === "") { result.pop(); } result.push("}"); return { renderedOptions: result.join("\n"), imports: allImports }; } function renderCommentedOptionsByModule(renders, options) { const optionsByModule = {}; for (const option of options) { const parentModule = option.parent; optionsByModule[parentModule] = optionsByModule[parentModule] ?? []; optionsByModule[parentModule].push(option); } for (const parentModule in optionsByModule) { optionsByModule[parentModule].sort((o1, o2) => o1.name.localeCompare(o2.name)); } const result = []; const marginSize = Math.max(...options.map((opt) => renders[opt.name].length)); for (const [moduleName, optionGroup] of Object.entries(optionsByModule).sort()) { result.push(`${TAB}/* ${moduleName} */`); for (const option of optionGroup) { const paramRender = renders[option.name]; const docstring = option.docs || "No documentation found."; result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`); } result.push(""); } return result; } function renderCommentedOptionsInOrder(renders, options) { const result = []; const marginSize = Math.max(...options.map((opt) => renders[opt.name].length)); for (const option of options) { const paramRender = renders[option.name]; const docstring = option.docs || "No documentation found."; result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`); } return result; } /** * Renders a value as a JavaScript value, converting strings to enums where * appropriate. The type must be JSON-like (string, number, boolean, array, * enum, or JSON object). * * Returns a JavaScript expression as a string, and the names of any * necessary imports. */ function renderArgAsJavaScript(arg, option) { if (option.kind === "enum") { if (!option.fqn) { throw new Error(`fqn field is missing from enum option ${option.name}`); } const parts = option.fqn.split("."); // -> ['projen', 'web', 'MyEnum'] const enumChoice = String(arg).toUpperCase().replace(/-/g, "_"); // custom-value -> CUSTOM_VALUE const js = `${parts.slice(1).join(".")}.${enumChoice}`; // -> web.MyEnum.CUSTOM_VALUE const moduleName = parts[0]; // -> projen const importName = parts[1]; // -> web return { js, moduleName, importName }; } else if (option.jsonLike) { return { js: JSON.stringify(arg) }; } else { throw new Error(`Unexpected option ${option.name} - cannot render a value for this option because it does not have a JSON-like type.`); } } function makePadding(paddingLength) { return " ".repeat(paddingLength); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLW9wdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvamF2YXNjcmlwdC9yZW5kZXItb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEyRUEsMERBU0M7QUFFRCxnREFnQkM7QUFtRUQsMERBb0ZDO0FBN1BELDBDQUEwQztBQUMxQyxrREFBeUQ7QUFFekQsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO0FBQzdCLE1BQU0sR0FBRyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQW9FM0I7O0dBRUc7QUFDSCxTQUFnQix1QkFBdUIsQ0FDckMsR0FBVyxFQUNYLElBQXlCLEVBQ3pCLFdBQW1DLHFDQUFzQixDQUFDLElBQUk7SUFFOUQsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBZ0I7S0FDcEQsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUFTO0lBQzFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQWUsQ0FBQztJQUN6QyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBQ0QsT0FBTztRQUNMLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSTtRQUNaLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRztRQUNWLElBQUksRUFBRSxJQUFJO1FBQ1YsUUFBUSxFQUFFLENBQUMsQ0FBQyxRQUFRO0tBQ3JCLENB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LElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtRQUNoRyxNQUFNLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDLENBQUMsNkJBQTZCO1FBQ3JGLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVk7UUFDekMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUN0QyxPQUFPLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUN4QyxDQUFDO1NBQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0IsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDckMsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLElBQUksS0FBSyxDQUNiLHFCQUFxQixNQUFNLENBQUMsSUFBSSxxRkFBcUYsQ0FDdEgsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsYUFBcUI7SUFDeEMsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBpbnZlbnRvcnkgZnJvbSBcIi4uL2ludmVudG9yeVwiO1xuaW1wb3J0IHsgSW5pdFByb2plY3RPcHRpb25IaW50cyB9IGZyb20gXCIuLi9vcHRpb24taGludHNcIjtcblxuY29uc3QgUFJPSkVOX05FVyA9IFwiX19uZXdfX1wiO1xuY29uc3QgVEFCID0gbWFrZVBhZGRpbmcoMik7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYHJlbmRlclByb2plY3RPcHRpb25zYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJQcm9qZWN0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgcHJvamVjdCB0eXBlIHRvIHJlbmRlci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IGludmVudG9yeS5Qcm9qZWN0VHlwZTtcblxuICAvKipcbiAgICogUHJvamVjdCBhcmd1bWVudHMgYXMgcGFzc2VkIHRvIGBwcm9qZW4gbmV3YC5cbiAgICovXG4gIHJlYWRvbmx5IGFyZ3M6IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgLyoqXG4gICAqIEluY2x1ZGUgY29tbWVudGVkIG91dCBvcHRpb25zLlxuICAgKiBAZGVmYXVsdCBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkZFQVRVUkVEXG4gICAqL1xuICByZWFkb25seSBjb21tZW50cz86IEluaXRQcm9qZWN0T3B0aW9uSGludHM7XG5cbiAgLyoqXG4gICAqIEluamVjdCBhIGBfX25ld19fYCBhdHRyaWJ1dGUgdG8gdGhlIHByb2plY3QgY29uc3RydWN0b3Igd2l0aCBhIHN0cmluZ2lmaWVkXG4gICAqIHZlcnNpb24gb2YgdGhlIHByb2plY3QgcGFyYW1ldGVycyBhbmQgYSBganNpaUZxbmAgYXR0cmlidXRlIHRoYXQgaW5jbHVkZXNcbiAgICogdGhlIEZRTiBvZiB0aGUgcHJvamVjdCB0eXBlLiBUaGlzIGlzIG5lZWRlZCBpbiBvcmRlciB0byBnZW5lcmF0ZSBpbml0aWFsXG4gICAqIHByb2plbnJjIGZpbGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgYm9vdHN0cmFwPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIGZpZWxkcyB0byBvbWl0IGZyb20gdGhlIGluaXRpYWwgcHJvamVucmMgZmlsZS5cbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBvbWl0RnJvbUJvb3RzdHJhcD86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBQcmVmaXggYWxsIGltcG9ydHMgd2l0aCB0aGlzIHN0cmluZyBhbmQgdGhlIGZ1bGwgbW9kdWxlIG5hbWVcbiAgICogVGhpcyBpcyByZXF1aXJlZCB3aGVuIGV4ZWN1dGluZyBvcHRpb25zIGNvZGUgaW4gYSB2bVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG9ubHkgdXNlIHN1Ym1vZHVsZSBhcyBwcmVmaXhcbiAgICovXG4gIHJlYWRvbmx5IHByZWZpeEltcG9ydHM/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSW5mb3JtYXRpb24gcGFzc2VkIGZyb20gYHByb2plbiBuZXdgIHRvIHRoZSBwcm9qZWN0IG9iamVjdCB3aGVuIHRoZSBwcm9qZWN0XG4gKiBpcyBmaXJzdCBjcmVhdGVkLiBJdCBpcyB1c2VkIHRvIGdlbmVyYXRlIHByb2plbnJjIGZpbGVzIGluIHZhcmlvdXMgbGFuZ3VhZ2VzLlxuICovXG5pbnRlcmZhY2UgUHJvamVuSW5pdCB7XG4gIC8qKlxuICAgKiBUaGUgSlNJSSBGUU4gb2YgdGhlIHByb2plY3QgdHlwZS5cbiAgICovXG4gIHJlYWRvbmx5IGZxbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbml0aWFsIGFyZ3VtZW50cyBwYXNzZWQgdG8gYHByb2plbiBuZXdgLlxuICAgKi9cbiAgcmVhZG9ubHkgYXJnczogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAvKipcbiAgICogSW5jbHVkZSBjb21tZW50ZWQgb3V0IG9wdGlvbnMuIERvZXMgbm90IGFwcGx5IHRvIHByb2plbnJjLmpzb24gZmlsZXMuXG4gICAqL1xuICByZWFkb25seSBjb21tZW50czogSW5pdFByb2plY3RPcHRpb25IaW50cztcbn1cblxuLyoqXG4gKiBSZW5kZXJzIG9wdGlvbnMgYXMgaWYgdGhlIHByb2plY3Qgd2FzIGNyZWF0ZWQgdmlhIGBwcm9qZW4gbmV3YCAoZW1iZWRzIHRoZSBfX25ld19fIGZpZWxkKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlclByb2plbkluaXRPcHRpb25zKFxuICBmcW46IHN0cmluZyxcbiAgYXJnczogUmVjb3JkPHN0cmluZywgYW55PixcbiAgY29tbWVudHM6IEluaXRQcm9qZWN0T3B0aW9uSGludHMgPSBJbml0UHJvamVjdE9wdGlvbkhpbnRzLk5PTkUsXG4pOiBhbnkge1xuICByZXR1cm4ge1xuICAgIC4uLmFyZ3MsXG4gICAgW1BST0pFTl9ORVddOiB7IGZxbiwgYXJncywgY29tbWVudHMgfSBhcyBQcm9qZW5Jbml0LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUluaXRQcm9qZWN0KG9wdHM6IGFueSkge1xuICBjb25zdCBmID0gb3B0c1tQUk9KRU5fTkVXXSBhcyBQcm9qZW5Jbml0O1xuICBpZiAoIWYpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdHlwZSA9IGludmVudG9yeS5yZXNvbHZlUHJvamVjdFR5cGUoZi5mcW4pO1xuICBpZiAoIXR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVuYWJsZSB0byByZXNvbHZlIHByb2plY3QgdHlwZSBmb3IgJHtmLmZxbn1gKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGFyZ3M6IGYuYXJncyxcbiAgICBmcW46IGYuZnFuLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgY29tbWVudHM6IGYuY29tbWVudHMsXG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBNb2R1bGVJbXBvcnRzIHtcbiAgcHJpdmF0ZSBpbXBvcnRzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj4gPSBuZXcgTWFwKCk7XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5hbWVkIGltcG9ydCBmcm9tIGEgbW9kdWxlXG4gICAqL1xuICBwdWJsaWMgYWRkKG1vZHVsZU5hbWU6IHN0cmluZywgaW1wb3J0TmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgbW9kdWxlSW1wb3J0cyA9IHRoaXMuaW1wb3J0cy5nZXQobW9kdWxlTmFtZSkgPz8gbmV3IFNldCgpO1xuICAgIG1vZHVsZUltcG9ydHMuYWRkKGltcG9ydE5hbWUpO1xuICAgIHRoaXMuaW1wb3J0cy5zZXQobW9kdWxlTmFtZSwgbW9kdWxlSW1wb3J0cyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBuYW1lZCBpbXBvcnRzIGZvciBhIG1vZHVsZVxuICAgKi9cbiAgcHVibGljIGdldChtb2R1bGVOYW1lOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgbW9kdWxlSW1wb3J0cyA9IHRoaXMuaW1wb3J0cy5nZXQobW9kdWxlTmFtZSkgPz8gbmV3IFNldCgpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKG1vZHVsZUltcG9ydHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIGxpc3Qgb2YgYWxsIHVzZWQgbW9kdWxlc1xuICAgKi9cbiAgcHVibGljIGdldCBtb2R1bGVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmltcG9ydHMua2V5cygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYWxsIGltcG9ydHMgYXMgRVNNIGltcG9ydCBzdGF0ZW1lbnRzXG4gICAqL1xuICBwdWJsaWMgYXNFc21JbXBvcnRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5hbGwoKS5tYXAoXG4gICAgICAoW21vZHVsZU5hbWUsIG5hbWVkSW1wb3J0c10pID0+XG4gICAgICAgIGBpbXBvcnQgeyAke1suLi5uYW1lZEltcG9ydHNdLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHttb2R1bGVOYW1lfVwiO2AsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYWxsIGltcG9ydHMgYXMgQ0pTIHJlcXVpcmUgc3RhdGVtZW50c1xuICAgKi9cbiAgcHVibGljIGFzQ2pzUmVxdWlyZSgpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkubWFwKFxuICAgICAgKFttb2R1bGVOYW1lLCBuYW1lZEltcG9ydHNdKSA9PlxuICAgICAgICBgY29uc3QgeyAke1suLi5uYW1lZEltcG9ydHNdLmpvaW4oXCIsIFwiKX0gfSA9IHJlcXVpcmUoXCIke21vZHVsZU5hbWV9XCIpO2AsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWxsKCk6IEFycmF5PFtzdHJpbmcsIHN0cmluZ1tdXT4ge1xuICAgIGNvbnN0IGFsbEltcG9ydHMgPSBPYmplY3QuZnJvbUVudHJpZXModGhpcy5pbXBvcnRzKTtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoYWxsSW1wb3J0cykubWFwKChba2V5LCB2YWx1ZV0pID0+IFtcbiAgICAgIGtleSxcbiAgICAgIEFycmF5LmZyb20odmFsdWUpLnNvcnQoKSxcbiAgICBdKTtcbiAgfVxufVxuXG4vKipcbiAqIFByaW50cyBhbGwgcGFyYW1ldGVycyB0aGF0IGNhbiBiZSB1c2VkIGluIGEgcHJvamVjdCB0eXBlLCBhbG9uZ3NpZGUgdGhlaXIgZGVzY3JpcHRpb25zLlxuICpcbiAqIFBhcmFtZXRlcnMgaW4gYHBhcmFtc2AgdGhhdCBhcmVuJ3QgdW5kZWZpbmVkIGFyZSByZW5kZXJlZCBhcyBkZWZhdWx0cyxcbiAqIHdoaWxlIGFsbCBvdGhlciBwYXJhbWV0ZXJzIGFyZSByZW5kZXJlZCBhcyBjb21tZW50ZWQgb3V0LlxuICpcbiAqIFJldHVybnMgdGhlIHByaW50ZWQgb3V0cHV0IGFuZCBhIHNldCBvZiByZXF1aXJlZCBpbXBvcnRzIGFzIGFuIG9iamVjdFxuICogaW4gdGhlIGZvcm0geyBvcHRpb25zLCBpbXBvcnRzIH0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJKYXZhU2NyaXB0T3B0aW9ucyhvcHRzOiBSZW5kZXJQcm9qZWN0T3B0aW9ucyk6IHtcbiAgcmVuZGVyZWRPcHRpb25zOiBzdHJpbmc7XG4gIGltcG9ydHM6IE1vZHVsZUltcG9ydHM7XG59IHtcbiAgY29uc3QgcmVuZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBjb25zdCBvcHRpb25zV2l0aERlZmF1bHRzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBhbGxJbXBvcnRzID0gbmV3IE1vZHVsZUltcG9ydHMoKTtcblxuICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRzLnR5cGUub3B0aW9ucykge1xuICAgIGlmIChvcHRpb24uZGVwcmVjYXRlZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW9uTmFtZSA9IG9wdGlvbi5uYW1lO1xuXG4gICAgaWYgKG9wdHMuYXJnc1tvcHRpb25OYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBhcmcgPSBvcHRzLmFyZ3Nbb3B0aW9uTmFtZV07XG4gICAgICBjb25zdCB7IGpzLCBtb2R1bGVOYW1lLCBpbXBvcnROYW1lIH0gPSByZW5kZXJBcmdBc0phdmFTY3JpcHQoYXJnLCBvcHRpb24pO1xuXG4gICAgICByZW5kZXJzW29wdGlvbk5hbWVdID0gYCR7b3B0aW9uTmFtZX06ICR7anN9LGA7XG4gICAgICBvcHRpb25zV2l0aERlZmF1bHRzLnB1c2gob3B0aW9uTmFtZSk7XG5cbiAgICAgIGlmIChtb2R1bGVOYW1lICYmIGltcG9ydE5hbWUpIHtcbiAgICAgICAgYWxsSW1wb3J0cy5hZGQobW9kdWxlTmFtZSwgaW1wb3J0TmFtZSk7XG4gICAgICAgIGlmIChvcHRzLnByZWZpeEltcG9ydHMpIHtcbiAgICAgICAgICBjb25zdCBwcmVmaXggPSBgJHtvcHRzLnByZWZpeEltcG9ydHN9W1wiJHttb2R1bGVOYW1lfVwiXS5gO1xuICAgICAgICAgIHJlbmRlcnNbb3B0aW9uTmFtZV0gPSBgJHtvcHRpb25OYW1lfTogJHtwcmVmaXh9JHtqc30sYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBvcHRpb24uZGVmYXVsdD8uc3RhcnRzV2l0aChcIi1cIilcbiAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgOiAob3B0aW9uLmRlZmF1bHQgPz8gdW5kZWZpbmVkKTtcbiAgICAgIHJlbmRlcnNbb3B0aW9uTmFtZV0gPSBgLy8gJHtvcHRpb25OYW1lfTogJHtkZWZhdWx0VmFsdWV9LGA7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYm9vdHN0cmFwID0gb3B0cy5ib290c3RyYXAgPz8gZmFsc2U7XG4gIGlmIChib290c3RyYXApIHtcbiAgICBmb3IgKGNvbnN0IGFyZyBvZiBvcHRzLm9taXRGcm9tQm9vdHN0cmFwID8/IFtdKSB7XG4gICAgICBkZWxldGUgb3B0cy5hcmdzW2FyZ107XG4gICAgfVxuICAgIHJlbmRlcnNbUFJPSkVOX05FV10gPSBgJHtQUk9KRU5fTkVXfTogJHtKU09OLnN0cmluZ2lmeSh7XG4gICAgICBhcmdzOiBvcHRzLmFyZ3MsXG4gICAgICBmcW46IG9wdHMudHlwZS5mcW4sXG4gICAgICBjb21tZW50czogb3B0cy5jb21tZW50cyxcbiAgICB9IGFzIFByb2plbkluaXQpfSxgO1xuICAgIG9wdGlvbnNXaXRoRGVmYXVsdHMucHVzaChQUk9KRU5fTkVXKTtcbiAgfVxuXG4gIC8vIGdlbmVyYXRlIHJlbmRlcmluZ1xuICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gIHJlc3VsdC5wdXNoKFwie1wiKTtcblxuICAvLyByZW5kZXIgb3B0aW9ucyB3aXRoIGRlZmF1bHRzXG4gIG9wdGlvbnNXaXRoRGVmYXVsdHMuc29ydCgpO1xuICBmb3IgKGNvbnN0IG9wdGlvbk5hbWUgb2Ygb3B0aW9uc1dpdGhEZWZhdWx0cykge1xuICAgIHJlc3VsdC5wdXNoKGAke1RBQn0ke3JlbmRlcnNbb3B0aW9uTmFtZV19YCk7XG4gIH1cbiAgaWYgKHJlc3VsdC5sZW5ndGggPiAxKSB7XG4gICAgcmVzdWx0LnB1c2goXCJcIik7XG4gIH1cblxuICAvLyByZW5kZXIgb3B0aW9ucyB3aXRob3V0IGRlZmF1bHRzIGFzIGNvbW1lbnRzXG4gIGlmIChvcHRzLmNvbW1lbnRzID09PSBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkFMTCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRzLnR5cGUub3B0aW9ucy5maWx0ZXIoXG4gICAgICAob3B0KSA9PiAhb3B0LmRlcHJlY2F0ZWQgJiYgb3B0cy5hcmdzW29wdC5uYW1lXSA9PT0gdW5kZWZpbmVkLFxuICAgICk7XG4gICAgcmVzdWx0LnB1c2goLi4ucmVuZGVyQ29tbWVudGVkT3B0aW9uc0J5TW9kdWxlKHJlbmRlcnMsIG9wdGlvbnMpKTtcbiAgfSBlbHNlIGlmIChvcHRzLmNvbW1lbnRzID09PSBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkZFQVRVUkVEKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IG9wdHMudHlwZS5vcHRpb25zLmZpbHRlcihcbiAgICAgIChvcHQpID0+XG4gICAgICAgICFvcHQuZGVwcmVjYXRlZCAmJiBvcHRzLmFyZ3Nbb3B0Lm5hbWVdID09PSB1bmRlZmluZWQgJiYgb3B0LmZlYXR1cmVkLFxuICAgICk7XG4gICAgcmVzdWx0LnB1c2goLi4ucmVuZGVyQ29tbWVudGVkT3B0aW9uc0luT3JkZXIocmVuZGVycywgb3B0aW9ucykpO1xuICB9IGVsc2UgaWYgKG9wdHMuY29tbWVudHMgPT09IEluaXRQcm9qZWN0T3B0aW9uSGludHMuTk9ORSkge1xuICAgIC8vIGRvbid0IHJlbmRlciBhbnkgZXh0cmEgb3B0aW9uc1xuICB9XG5cbiAgaWYgKHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPT09IFwiXCIpIHtcbiAgICByZXN1bHQucG9wKCk7XG4gIH1cbiAgcmVzdWx0LnB1c2goXCJ9XCIpO1xuICByZXR1cm4geyByZW5kZXJlZE9wdGlvbnM6IHJlc3VsdC5qb2luKFwiXFxuXCIpLCBpbXBvcnRzOiBhbGxJbXBvcnRzIH07XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNvbW1lbnRlZE9wdGlvbnNCeU1vZHVsZShcbiAgcmVuZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgb3B0aW9uczogaW52ZW50b3J5LlByb2plY3RPcHRpb25bXSxcbikge1xuICBjb25zdCBvcHRpb25zQnlNb2R1bGU6IFJlY29yZDxzdHJpbmcsIGludmVudG9yeS5Qcm9qZWN0T3B0aW9uW10+ID0ge307XG5cbiAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykge1xuICAgIGNvbnN0IHBhcmVudE1vZHVsZSA9IG9wdGlvbi5wYXJlbnQ7XG4gICAgb3B0aW9uc0J5TW9kdWxlW3BhcmVudE1vZHVsZV0gPSBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXSA/PyBbXTtcbiAgICBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXS5wdXNoKG9wdGlvbik7XG4gIH1cblxuICBmb3IgKGNvbnN0IHBhcmVudE1vZHVsZSBpbiBvcHRpb25zQnlNb2R1bGUpIHtcbiAgICBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXS5zb3J0KChvMSwgbzIpID0+XG4gICAgICBvMS5uYW1lLmxvY2FsZUNvbXBhcmUobzIubmFtZSksXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBtYXJnaW5TaXplID0gTWF0aC5tYXgoXG4gICAgLi4ub3B0aW9ucy5tYXAoKG9wdCkgPT4gcmVuZGVyc1tvcHQubmFtZV0ubGVuZ3RoKSxcbiAgKTtcbiAgZm9yIChjb25zdCBbbW9kdWxlTmFtZSwgb3B0aW9uR3JvdXBdIG9mIE9iamVjdC5lbnRyaWVzKFxuICAgIG9wdGlvbnNCeU1vZHVsZSxcbiAgKS5zb3J0KCkpIHtcbiAgICByZXN1bHQucHVzaChgJHtUQUJ9LyogJHttb2R1bGVOYW1lfSAqL2ApO1xuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbkdyb3VwKSB7XG4gICAgICBjb25zdCBwYXJhbVJlbmRlciA9IHJlbmRlcnNbb3B0aW9uLm5hbWVdO1xuICAgICAgY29uc3QgZG9jc3RyaW5nID0gb3B0aW9uLmRvY3MgfHwgXCJObyBkb2N1bWVudGF0aW9uIGZvdW5kLlwiO1xuICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgIGAke1RBQn0ke3BhcmFtUmVuZGVyfSR7bWFrZVBhZGRpbmcoXG4gICAgICAgICAgbWFyZ2luU2l6ZSAtIHBhcmFtUmVuZGVyLmxlbmd0aCArIDIsXG4gICAgICAgICl9LyogJHtkb2NzdHJpbmd9ICovYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKFwiXCIpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNvbW1lbnRlZE9wdGlvbnNJbk9yZGVyKFxuICByZW5kZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICBvcHRpb25zOiBpbnZlbnRvcnkuUHJvamVjdE9wdGlvbltdLFxuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBtYXJnaW5TaXplID0gTWF0aC5tYXgoXG4gICAgLi4ub3B0aW9ucy5tYXAoKG9wdCkgPT4gcmVuZGVyc1tvcHQubmFtZV0ubGVuZ3RoKSxcbiAgKTtcbiAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykge1xuICAgIGNvbnN0IHBhcmFtUmVuZGVyID0gcmVuZGVyc1tvcHRpb24ubmFtZV07XG4gICAgY29uc3QgZG9jc3RyaW5nID0gb3B0aW9uLmRvY3MgfHwgXCJObyBkb2N1bWVudGF0aW9uIGZvdW5kLlwiO1xuICAgIHJlc3VsdC5wdXNoKFxuICAgICAgYCR7VEFCfSR7cGFyYW1SZW5kZXJ9JHttYWtlUGFkZGluZyhcbiAgICAgICAgbWFyZ2luU2l6ZSAtIHBhcmFtUmVuZGVyLmxlbmd0aCArIDIsXG4gICAgICApfS8qICR7ZG9jc3RyaW5nfSAqL2AsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJlbmRlcnMgYSB2YWx1ZSBhcyBhIEphdmFTY3JpcHQgdmFsdWUsIGNvbnZlcnRpbmcgc3RyaW5ncyB0byBlbnVtcyB3aGVyZVxuICogYXBwcm9wcmlhdGUuIFRoZSB0eXBlIG11c3QgYmUgSlNPTi1saWtlIChzdHJpbmcsIG51bWJlciwgYm9vbGVhbiwgYXJyYXksXG4gKiBlbnVtLCBvciBKU09OIG9iamVjdCkuXG4gKlxuICogUmV0dXJucyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBhcyBhIHN0cmluZywgYW5kIHRoZSBuYW1lcyBvZiBhbnlcbiAqIG5lY2Vzc2FyeSBpbXBvcnRzLlxuICovXG5mdW5jdGlvbiByZW5kZXJBcmdBc0phdmFTY3JpcHQoYXJnOiBhbnksIG9wdGlvbjogaW52ZW50b3J5LlByb2plY3RPcHRpb24pIHtcbiAgaWYgKG9wdGlvbi5raW5kID09PSBcImVudW1cIikge1xuICAgIGlmICghb3B0aW9uLmZxbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBmcW4gZmllbGQgaXMgbWlzc2luZyBmcm9tIGVudW0gb3B0aW9uICR7b3B0aW9uLm5hbWV9YCk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gb3B0aW9uLmZxbi5zcGxpdChcIi5cIik7IC8vIC0+IFsncHJvamVuJywgJ3dlYicsICdNeUVudW0nXVxuICAgIGNvbnN0IGVudW1DaG9pY2UgPSBTdHJpbmcoYXJnKS50b1VwcGVyQ2FzZSgpLnJlcGxhY2UoLy0vZywgXCJfXCIpOyAvLyBjdXN0b20tdmFsdWUgLT4gQ1VTVE9NX1ZBTFVFXG4gICAgY29uc3QganMgPSBgJHtwYXJ0cy5zbGljZSgxKS5qb2luKFwiLlwiKX0uJHtlbnVtQ2hvaWNlfWA7IC8vIC0+IHdlYi5NeUVudW0uQ1VTVE9NX1ZBTFVFXG4gICAgY29uc3QgbW9kdWxlTmFtZSA9IHBhcnRzWzBdOyAvLyAtPiBwcm9qZW5cbiAgICBjb25zdCBpbXBvcnROYW1lID0gcGFydHNbMV07IC8vIC0+IHdlYlxuICAgIHJldHVybiB7IGpzLCBtb2R1bGVOYW1lLCBpbXBvcnROYW1lIH07XG4gIH0gZWxzZSBpZiAob3B0aW9uLmpzb25MaWtlKSB7XG4gICAgcmV0dXJuIHsganM6IEpTT04uc3RyaW5naWZ5KGFyZykgfTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVW5leHBlY3RlZCBvcHRpb24gJHtvcHRpb24ubmFtZX0gLSBjYW5ub3QgcmVuZGVyIGEgdmFsdWUgZm9yIHRoaXMgb3B0aW9uIGJlY2F1c2UgaXQgZG9lcyBub3QgaGF2ZSBhIEpTT04tbGlrZSB0eXBlLmAsXG4gICAgKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYWtlUGFkZGluZyhwYWRkaW5nTGVuZ3RoOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gXCIgXCIucmVwZWF0KHBhZGRpbmdMZW5ndGgpO1xufVxuIl19