UNPKG

projen

Version:

CDK for software projects

236 lines (228 loc) • 32.1 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.AwsCdkTypeScriptApp = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const fs = require("fs"); const path = require("path"); const auto_discover_1 = require("./auto-discover"); const awscdk_deps_js_1 = require("./awscdk-deps-js"); const cdk_config_1 = require("./cdk-config"); const cdk_tasks_1 = require("./cdk-tasks"); const integ_runner_1 = require("./integ-runner"); const component_1 = require("../component"); const dependencies_1 = require("../dependencies"); const javascript_1 = require("../javascript"); const typescript_1 = require("../typescript"); /** * AWS CDK app in TypeScript * * @pjid awscdk-app-ts */ class AwsCdkTypeScriptApp extends typescript_1.TypeScriptAppProject { /** * The CDK version this app is using. */ get cdkVersion() { return this.cdkDeps.cdkVersion; } constructor(options) { super({ ...options, sampleCode: false, bundlerOptions: { ...options.bundlerOptions, // we invoke the "bundle" task as part of the build step in cdk.json so // we don't want it to be added to the pre-compile phase. runBundleTask: javascript_1.RunBundleTask.MANUAL, }, }); this.cdkDeps = new awscdk_deps_js_1.AwsCdkDepsJs(this, { dependencyType: dependencies_1.DependencyType.RUNTIME, ...options, }); this.appEntrypoint = options.appEntrypoint ?? "main.ts"; // CLI this.addDevDeps(`aws-cdk@${this.cdkDeps.cdkCliVersion}`); // no compile step because we do all of it in typescript directly this.compileTask.reset(); this.cdkTasks = new cdk_tasks_1.CdkTasks(this); // add synth to the build this.postCompileTask.spawn(this.cdkTasks.synthSilent); const tsConfigFile = this.tsconfig?.fileName; if (!tsConfigFile) { throw new Error("Expecting tsconfig.json"); } this.cdkConfig = new cdk_config_1.CdkConfig(this, { featureFlags: this.cdkDeps.cdkMajorVersion < 2, buildCommand: this.runTaskCommand(this.bundler.bundleTask), watchIncludes: [`${this.srcdir}/**/*.ts`, `${this.testdir}/**/*.ts`], watchExcludes: [ "README.md", "cdk*.json", "**/*.d.ts", "**/*.js", "tsconfig.json", "package*.json", "yarn.lock", "node_modules", ], ...options, app: this.getCdkApp(options), }); this.gitignore.exclude(".parcel-cache/"); this.npmignore?.exclude(`${this.cdkConfig.cdkout}/`); this.npmignore?.exclude(".cdk.staging/"); if (this.tsconfig) { this.tsconfig.exclude.push(this.cdkConfig.cdkout); } this.addDevDeps("ts-node"); if (options.sampleCode ?? true) { new SampleCode(this, this.cdkDeps.cdkMajorVersion); } new auto_discover_1.AutoDiscover(this, { srcdir: this.srcdir, testdir: this.testdir, lambdaOptions: options.lambdaOptions, tsconfigPath: this.tsconfigDev.fileName, cdkDeps: this.cdkDeps, lambdaAutoDiscover: options.lambdaAutoDiscover ?? true, edgeLambdaAutoDiscover: options.edgeLambdaAutoDiscover ?? true, lambdaExtensionAutoDiscover: options.lambdaExtensionAutoDiscover ?? true, integrationTestAutoDiscover: options.integrationTestAutoDiscover ?? true, }); if (options.experimentalIntegRunner) { new integ_runner_1.IntegRunner(this); } } /** * Adds an AWS CDK module dependencies * @param modules The list of modules to depend on */ addCdkDependency(...modules) { return this.cdkDeps.addV1Dependencies(...modules); } getCdkApp(options) { if (options.app && options.appEntrypoint) { throw new Error("Only one of 'app' or 'appEntrypoint' can be specified"); } // prefer an explicitly provided app command if (options.app) { return options.app; } const appEntrypoint = path.posix.join(this.srcdir, this.appEntrypoint); const tsNodeConfig = this.tsconfig?.fileName ? ` -P ${this.tsconfig?.fileName}` : ""; const tsNodeApp = `ts-node${tsNodeConfig} --prefer-ts-exts ${appEntrypoint}`; switch (this.package.packageManager) { case javascript_1.NodePackageManager.BUN: const bunTsConfig = this.tsconfig?.fileName ? ` --tsconfig-override=${this.tsconfig?.fileName}` : ""; const bunEntrypoint = ensureRelativePathPrefix(appEntrypoint); // https://bun.sh/docs/cli/run // bun can run ts files directly return `bun run${bunTsConfig} ${bunEntrypoint}`; case javascript_1.NodePackageManager.PNPM: // https://pnpm.io/cli/exec return `pnpm exec ${tsNodeApp}`; case javascript_1.NodePackageManager.YARN_CLASSIC: case javascript_1.NodePackageManager.YARN: case javascript_1.NodePackageManager.YARN_BERRY: case javascript_1.NodePackageManager.YARN2: // use npx with yarn due to reported issues // @see https://github.com/projen/projen/issues/4180 return `npx ${tsNodeApp}`; default: return `npx ${tsNodeApp}`; } } } exports.AwsCdkTypeScriptApp = AwsCdkTypeScriptApp; _a = JSII_RTTI_SYMBOL_1; AwsCdkTypeScriptApp[_a] = { fqn: "projen.awscdk.AwsCdkTypeScriptApp", version: "0.91.26" }; /** * Ensures a path is properly prefixed with './' if it's a relative path * @param {string} filePath - The path to normalize * @returns {string} - The normalized path */ function ensureRelativePathPrefix(filePath) { // If it's already an absolute path, return as is if (path.isAbsolute(filePath)) { return filePath; } // If it already starts with ./ or ../, return as is if (filePath.startsWith("./") || filePath.startsWith("../")) { return filePath; } // Otherwise, add ./ prefix return `./${filePath}`; } class SampleCode extends component_1.Component { constructor(project, cdkMajorVersion) { super(project); this.cdkMajorVersion = cdkMajorVersion; this.appProject = project; } synthesize() { const outdir = this.project.outdir; const srcdir = path.join(outdir, this.appProject.srcdir); if (fs.existsSync(srcdir) && fs.readdirSync(srcdir).filter((x) => x.endsWith(".ts"))) { return; } const srcImports = new Array(); if (this.cdkMajorVersion < 2) { srcImports.push("import { App, Construct, Stack, StackProps } from '@aws-cdk/core';"); } else { srcImports.push("import { App, Stack, StackProps } from 'aws-cdk-lib';"); srcImports.push("import { Construct } from 'constructs';"); } const srcCode = `${srcImports.join("\n")} export class MyStack extends Stack { constructor(scope: Construct, id: string, props: StackProps = {}) { super(scope, id, props); // define resources here... } } // for development, use account/region from cdk cli const devEnv = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION, }; const app = new App(); new MyStack(app, '${this.project.name}-dev', { env: devEnv }); // new MyStack(app, '${this.project.name}-prod', { env: prodEnv }); app.synth();`; fs.mkdirSync(srcdir, { recursive: true }); fs.writeFileSync(path.join(srcdir, this.appProject.appEntrypoint), srcCode); const testdir = path.join(outdir, this.appProject.testdir); if (fs.existsSync(testdir) && fs.readdirSync(testdir).filter((x) => x.endsWith(".ts"))) { return; } const testImports = new Array(); if (this.cdkMajorVersion < 2) { testImports.push("import { App } from '@aws-cdk/core';"); testImports.push("import { Template } from '@aws-cdk/assertions';"); } else { testImports.push("import { App } from 'aws-cdk-lib';"); testImports.push("import { Template } from 'aws-cdk-lib/assertions';"); } const appEntrypointName = path.basename(this.appProject.appEntrypoint, ".ts"); const testCode = `${testImports.join("\n")} import { MyStack } from '../${this.appProject.srcdir}/${appEntrypointName}'; test('Snapshot', () => { const app = new App(); const stack = new MyStack(app, 'test'); const template = Template.fromStack(stack); expect(template.toJSON()).toMatchSnapshot(); });`; fs.mkdirSync(testdir, { recursive: true }); fs.writeFileSync(path.join(testdir, `${appEntrypointName}.test.ts`), testCode); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzY2RrLWFwcC10cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hd3NjZGsvYXdzY2RrLWFwcC10cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsbURBQStDO0FBRS9DLHFEQUFnRDtBQUNoRCw2Q0FBaUU7QUFDakUsMkNBQXVDO0FBQ3ZDLGlEQUE2QztBQUU3Qyw0Q0FBeUM7QUFDekMsa0RBQWlEO0FBQ2pELDhDQUFrRTtBQUNsRSw4Q0FBK0U7QUFxRS9FOzs7O0dBSUc7QUFDSCxNQUFhLG1CQUFvQixTQUFRLGlDQUFvQjtJQUMzRDs7T0FFRztJQUNILElBQVcsVUFBVTtRQUNuQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQ2pDLENBQUM7SUFtQkQsWUFBWSxPQUFtQztRQUM3QyxLQUFLLENBQUM7WUFDSixHQUFHLE9BQU87WUFDVixVQUFVLEVBQUUsS0FBSztZQUNqQixjQUFjLEVBQUU7Z0JBQ2QsR0FBRyxPQUFPLENBQUMsY0FBYztnQkFFekIsdUVBQXVFO2dCQUN2RSx5REFBeUQ7Z0JBQ3pELGFBQWEsRUFBRSwwQkFBYSxDQUFDLE1BQU07YUFDcEM7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksNkJBQVksQ0FBQyxJQUFJLEVBQUU7WUFDcEMsY0FBYyxFQUFFLDZCQUFjLENBQUMsT0FBTztZQUN0QyxHQUFHLE9BQU87U0FDWCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksU0FBUyxDQUFDO1FBRXhELE1BQU07UUFDTixJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBRXpELGlFQUFpRTtRQUNqRSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRXpCLElB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LENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUN4RCxDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO1FBQ3hDLElBQUksSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixXQUFXLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7WUFDekQsV0FBVyxDQUFDLElBQUksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7YUFBTSxDQUFDO1lBQ04sV0FBVyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1lBQ3ZELFdBQVcsQ0FBQyxJQUFJLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUNyQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFDN0IsS0FBSyxDQUNOLENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDOzhCQUNoQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxpQkFBaUI7Ozs7Ozs7O0lBUXJFLENBQUM7UUFFRCxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzNDLEVBQUUsQ0FBQyxhQUFhLENBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxpQkFBaUIsVUFBVSxDQUFDLEVBQ2xELFFBQVEsQ0FDVCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBBdXRvRGlzY292ZXIgfSBmcm9tIFwiLi9hdXRvLWRpc2NvdmVyXCI7XG5pbXBvcnQgeyBBd3NDZGtEZXBzLCBBd3NDZGtEZXBzQ29tbW9uT3B0aW9ucyB9IGZyb20gXCIuL2F3c2Nkay1kZXBzXCI7XG5pbXBvcnQgeyBBd3NDZGtEZXBzSnMgfSBmcm9tIFwiLi9hd3NjZGstZGVwcy1qc1wiO1xuaW1wb3J0IHsgQ2RrQ29uZmlnLCBDZGtDb25maWdDb21tb25PcHRpb25zIH0gZnJvbSBcIi4vY2RrLWNvbmZpZ1wiO1xuaW1wb3J0IHsgQ2RrVGFza3MgfSBmcm9tIFwiLi9jZGstdGFza3NcIjtcbmltcG9ydCB7IEludGVnUnVubmVyIH0gZnJvbSBcIi4vaW50ZWctcnVubmVyXCI7XG5pbXBvcnQgeyBMYW1iZGFGdW5jdGlvbkNvbW1vbk9wdGlvbnMgfSBmcm9tIFwiLi9sYW1iZGEtZnVuY3Rpb25cIjtcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCIuLi9jb21wb25lbnRcIjtcbmltcG9ydCB7IERlcGVuZGVuY3lUeXBlIH0gZnJvbSBcIi4uL2RlcGVuZGVuY2llc1wiO1xuaW1wb3J0IHsgTm9kZVBhY2thZ2VNYW5hZ2VyLCBSdW5CdW5kbGVUYXNrIH0gZnJvbSBcIi4uL2phdmFzY3JpcHRcIjtcbmltcG9ydCB7IFR5cGVTY3JpcHRBcHBQcm9qZWN0LCBUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNjcmlwdFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF3c0Nka1R5cGVTY3JpcHRBcHBPcHRpb25zXG4gIGV4dGVuZHMgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zLFxuICAgIENka0NvbmZpZ0NvbW1vbk9wdGlvbnMsXG4gICAgQXdzQ2RrRGVwc0NvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIENESyBhcHAncyBlbnRyeXBvaW50IChyZWxhdGl2ZSB0byB0aGUgc291cmNlIGRpcmVjdG9yeSwgd2hpY2ggaXNcbiAgICogXCJzcmNcIiBieSBkZWZhdWx0KS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJtYWluLnRzXCJcbiAgICovXG4gIHJlYWRvbmx5IGFwcEVudHJ5cG9pbnQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgY29tbWFuZCBsaW5lIHRvIGV4ZWN1dGUgaW4gb3JkZXIgdG8gc3ludGhlc2l6ZSB0aGUgQ0RLIGFwcGxpY2F0aW9uXG4gICAqIChsYW5ndWFnZSBzcGVjaWZpYykuXG4gICAqL1xuICByZWFkb25seSBhcHA/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBdXRvbWF0aWNhbGx5IGFkZHMgYW4gYGF3c2Nkay5MYW1iZGFGdW5jdGlvbmAgZm9yIGVhY2ggYC5sYW1iZGEudHNgIGhhbmRsZXJcbiAgICogaW4geW91ciBzb3VyY2UgdHJlZS4gSWYgdGhpcyBpcyBkaXNhYmxlZCwgeW91IGNhbiBtYW51YWxseSBhZGQgYW5cbiAgICogYGF3c2Nkay5BdXRvRGlzY292ZXJgIGNvbXBvbmVudCB0byB5b3VyIHByb2plY3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGxhbWJkYUF1dG9EaXNjb3Zlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEF1dG9tYXRpY2FsbHkgYWRkcyBhbiBgY2xvdWRmcm9udC5leHBlcmltZW50YWwuRWRnZUZ1bmN0aW9uYCBmb3IgZWFjaFxuICAgKiBgLmVkZ2UtbGFtYmRhLnRzYCBoYW5kbGVyIGluIHlvdXIgc291cmNlIHRyZWUuIElmIHRoaXMgaXMgZGlzYWJsZWQsIHlvdSBjYW5cbiAgICogbWFudWFsbHkgYWRkIGFuIGBhd3NjZGsuQXV0b0Rpc2NvdmVyYCBjb21wb25lbnQgdG8geW91ciBwcm9qZWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBlZGdlTGFtYmRhQXV0b0Rpc2NvdmVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQXV0b21hdGljYWxseSBhZGRzIGFuIGBhd3NjZGsuTGFtYmRhRXh0ZW5zaW9uYCBmb3IgZWFjaCBgLmxhbWJkYS1leHRlbnNpb24udHNgXG4gICAqIGVudHJ5cG9pbnQgaW4geW91ciBzb3VyY2UgdHJlZS4gSWYgdGhpcyBpcyBkaXNhYmxlZCwgeW91IGNhbiBtYW51YWxseSBhZGQgYW5cbiAgICogYGF3c2Nkay5BdXRvRGlzY292ZXJgIGNvbXBvbmVudCB0byB5b3VyIHByb2plY3RcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgbGFtYmRhRXh0ZW5zaW9uQXV0b0Rpc2NvdmVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQXV0b21hdGljYWxseSBkaXNjb3ZlcnMgYW5kIGNyZWF0ZXMgaW50ZWdyYXRpb24gdGVzdHMgZm9yIGVhY2ggYC5pbnRlZy50c2BcbiAgICogZmlsZSBpbiB1bmRlciB5b3VyIHRlc3QgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBpbnRlZ3JhdGlvblRlc3RBdXRvRGlzY292ZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBFbmFibGUgZXhwZXJpbWVudGFsIHN1cHBvcnQgZm9yIHRoZSBBV1MgQ0RLIGludGVnLXJ1bm5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKi9cbiAgcmVhZG9ubHkgZXhwZXJpbWVudGFsSW50ZWdSdW5uZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb21tb24gb3B0aW9ucyBmb3IgYWxsIEFXUyBMYW1iZGEgZnVuY3Rpb25zLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgbGFtYmRhT3B0aW9ucz86IExhbWJkYUZ1bmN0aW9uQ29tbW9uT3B0aW9ucztcbn1cblxuLyoqXG4gKiBBV1MgQ0RLIGFwcCBpbiBUeXBlU2NyaXB0XG4gKlxuICogQHBqaWQgYXdzY2RrLWFwcC10c1xuICovXG5leHBvcnQgY2xhc3MgQXdzQ2RrVHlwZVNjcmlwdEFwcCBleHRlbmRzIFR5cGVTY3JpcHRBcHBQcm9qZWN0IHtcbiAgLyoqXG4gICAqIFRoZSBDREsgdmVyc2lvbiB0aGlzIGFwcCBpcyB1c2luZy5cbiAgICovXG4gIHB1YmxpYyBnZXQgY2RrVmVyc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5jZGtEZXBzLmNka1ZlcnNpb247XG4gIH1cblxuICAvKipcbiAgICogVGhlIENESyBhcHAgZW50cnlwb2ludFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwcEVudHJ5cG9pbnQ6IHN0cmluZztcblxuICAvKipcbiAgICogQ29tbW9uIENESyB0YXNrcy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjZGtUYXNrczogQ2RrVGFza3M7XG5cbiAgLyoqXG4gICAqIGNkay5qc29uIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2RrQ29uZmlnOiBDZGtDb25maWc7XG5cbiAgcHVibGljIHJlYWRvbmx5IGNka0RlcHM6IEF3c0Nka0RlcHM7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogQXdzQ2RrVHlwZVNjcmlwdEFwcE9wdGlvbnMpIHtcbiAgICBzdXBlcih7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgc2FtcGxlQ29kZTogZmFsc2UsXG4gICAgICBidW5kbGVyT3B0aW9uczoge1xuICAgICAgICAuLi5vcHRpb25zLmJ1bmRsZXJPcHRpb25zLFxuXG4gICAgICAgIC8vIHdlIGludm9rZSB0aGUgXCJidW5kbGVcIiB0YXNrIGFzIHBhcnQgb2YgdGhlIGJ1aWxkIHN0ZXAgaW4gY2RrLmpzb24gc29cbiAgICAgICAgLy8gd2UgZG9uJ3Qgd2FudCBpdCB0byBiZSBhZGRlZCB0byB0aGUgcHJlLWNvbXBpbGUgcGhhc2UuXG4gICAgICAgIHJ1bkJ1bmRsZVRhc2s6IFJ1bkJ1bmRsZVRhc2suTUFOVUFMLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmNka0RlcHMgPSBuZXcgQXdzQ2RrRGVwc0pzKHRoaXMsIHtcbiAgICAgIGRlcGVuZGVuY3lUeXBlOiBEZXBlbmRlbmN5VHlwZS5SVU5USU1FLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLmFwcEVudHJ5cG9pbnQgPSBvcHRpb25zLmFwcEVudHJ5cG9pbnQgPz8gXCJtYWluLnRzXCI7XG5cbiAgICAvLyBDTElcbiAgICB0aGlzLmFkZERldkRlcHMoYGF3cy1jZGtAJHt0aGlzLmNka0RlcHMuY2RrQ2xpVmVyc2lvbn1gKTtcblxuICAgIC8vIG5vIGNvbXBpbGUgc3RlcCBiZWNhdXNlIHdlIGRvIGFsbCBvZiBpdCBpbiB0eXBlc2NyaXB0IGRpcmVjdGx5XG4gICAgdGhpcy5jb21waWxlVGFzay5yZXNldCgpO1xuXG4gICAgdGhpcy5jZGtUYXNrcyA9IG5ldyBDZGtUYXNrcyh0aGlzKTtcblxuICAgIC8vIGFkZCBzeW50aCB0byB0aGUgYnVpbGRcbiAgICB0aGlzLnBvc3RDb21waWxlVGFzay5zcGF3bih0aGlzLmNka1Rhc2tzLnN5bnRoU2lsZW50KTtcblxuICAgIGNvbnN0IHRzQ29uZmlnRmlsZSA9IHRoaXMudHNjb25maWc/LmZpbGVOYW1lO1xuICAgIGlmICghdHNDb25maWdGaWxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RpbmcgdHNjb25maWcuanNvblwiKTtcbiAgICB9XG5cbiAgICB0aGlzLmNka0NvbmZpZyA9IG5ldyBDZGtDb25maWcodGhpcywge1xuICAgICAgZmVhdHVyZUZsYWdzOiB0aGlzLmNka0RlcHMuY2RrTWFqb3JWZXJzaW9uIDwgMixcbiAgICAgIGJ1aWxkQ29tbWFuZDogdGhpcy5ydW5UYXNrQ29tbWFuZCh0aGlzLmJ1bmRsZXIuYnVuZGxlVGFzayksXG4gICAgICB3YXRjaEluY2x1ZGVzOiBbYCR7dGhpcy5zcmNkaXJ9LyoqLyoudHNgLCBgJHt0aGlzLnRlc3RkaXJ9LyoqLyoudHNgXSxcbiAgICAgIHdhdGNoRXhjbHVkZXM6IFtcbiAgICAgICAgXCJSRUFETUUubWRcIixcbiAgICAgICAgXCJjZGsqLmpzb25cIixcbiAgICAgICAgXCIqKi8qLmQudHNcIixcbiAgICAgICAgXCIqKi8qLmpzXCIsXG4gICAgICAgIFwidHNjb25maWcuanNvblwiLFxuICAgICAgICBcInBhY2thZ2UqLmpzb25cIixcbiAgICAgICAgXCJ5YXJuLmxvY2tcIixcbiAgICAgICAgXCJub2RlX21vZHVsZXNcIixcbiAgICAgIF0sXG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgYXBwOiB0aGlzLmdldENka0FwcChvcHRpb25zKSxcbiAgICB9KTtcblxuICAgIHRoaXMuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIucGFyY2VsLWNhY2hlL1wiKTtcblxuICAgIHRoaXMubnBtaWdub3JlPy5leGNsdWRlKGAke3RoaXMuY2RrQ29uZmlnLmNka291dH0vYCk7XG4gICAgdGhpcy5ucG1pZ25vcmU/LmV4Y2x1ZGUoXCIuY2RrLnN0YWdpbmcvXCIpO1xuXG4gICAgaWYgKHRoaXMudHNjb25maWcpIHtcbiAgICAgIHRoaXMudHNjb25maWcuZXhjbHVkZS5wdXNoKHRoaXMuY2RrQ29uZmlnLmNka291dCk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGREZXZEZXBzKFwidHMtbm9kZVwiKTtcbiAgICBpZiAob3B0aW9ucy5zYW1wbGVDb2RlID8/IHRydWUpIHtcbiAgICAgIG5ldyBTYW1wbGVDb2RlKHRoaXMsIHRoaXMuY2RrRGVwcy5jZGtNYWpvclZlcnNpb24pO1xuICAgIH1cblxuICAgIG5ldyBBdXRvRGlzY292ZXIodGhpcywge1xuICAgICAgc3JjZGlyOiB0aGlzLnNyY2RpcixcbiAgICAgIHRlc3RkaXI6IHRoaXMudGVzdGRpcixcbiAgICAgIGxhbWJkYU9wdGlvbnM6IG9wdGlvbnMubGFtYmRhT3B0aW9ucyxcbiAgICAgIHRzY29uZmlnUGF0aDogdGhpcy50c2NvbmZpZ0Rldi5maWxlTmFtZSxcbiAgICAgIGNka0RlcHM6IHRoaXMuY2RrRGVwcyxcbiAgICAgIGxhbWJkYUF1dG9EaXNjb3Zlcjogb3B0aW9ucy5sYW1iZGFBdXRvRGlzY292ZXIgPz8gdHJ1ZSxcbiAgICAgIGVkZ2VMYW1iZGFBdXRvRGlzY292ZXI6IG9wdGlvbnMuZWRnZUxhbWJkYUF1dG9EaXNjb3ZlciA/PyB0cnVlLFxuICAgICAgbGFtYmRhRXh0ZW5zaW9uQXV0b0Rpc2NvdmVyOiBvcHRpb25zLmxhbWJkYUV4dGVuc2lvbkF1dG9EaXNjb3ZlciA/PyB0cnVlLFxuICAgICAgaW50ZWdyYXRpb25UZXN0QXV0b0Rpc2NvdmVyOiBvcHRpb25zLmludGVncmF0aW9uVGVzdEF1dG9EaXNjb3ZlciA/PyB0cnVlLFxuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMuZXhwZXJpbWVudGFsSW50ZWdSdW5uZXIpIHtcbiAgICAgIG5ldyBJbnRlZ1J1bm5lcih0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBBV1MgQ0RLIG1vZHVsZSBkZXBlbmRlbmNpZXNcbiAgICogQHBhcmFtIG1vZHVsZXMgVGhlIGxpc3Qgb2YgbW9kdWxlcyB0byBkZXBlbmQgb25cbiAgICovXG4gIHB1YmxpYyBhZGRDZGtEZXBlbmRlbmN5KC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuY2RrRGVwcy5hZGRWMURlcGVuZGVuY2llcyguLi5tb2R1bGVzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2RrQXBwKG9wdGlvbnM6IEF3c0Nka1R5cGVTY3JpcHRBcHBPcHRpb25zKTogc3RyaW5nIHtcbiAgICBpZiAob3B0aW9ucy5hcHAgJiYgb3B0aW9ucy5hcHBFbnRyeXBvaW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmx5IG9uZSBvZiAnYXBwJyBvciAnYXBwRW50cnlwb2ludCcgY2FuIGJlIHNwZWNpZmllZFwiKTtcbiAgICB9XG5cbiAgICAvLyBwcmVmZXIgYW4gZXhwbGljaXRseSBwcm92aWRlZCBhcHAgY29tbWFuZFxuICAgIGlmIChvcHRpb25zLmFwcCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuYXBwO1xuICAgIH1cblxuICAgIGNvbnN0IGFwcEVudHJ5cG9pbnQgPSBwYXRoLnBvc2l4LmpvaW4odGhpcy5zcmNkaXIsIHRoaXMuYXBwRW50cnlwb2ludCk7XG5cbiAgICBjb25zdCB0c05vZGVDb25maWcgPSB0aGlzLnRzY29uZmlnPy5maWxlTmFtZVxuICAgICAgPyBgIC1QICR7dGhpcy50c2NvbmZpZz8uZmlsZU5hbWV9YFxuICAgICAgOiBcIlwiO1xuICAgIGNvbnN0IHRzTm9kZUFwcCA9IGB0cy1ub2RlJHt0c05vZGVDb25maWd9IC0tcHJlZmVyLXRzLWV4dHMgJHthcHBFbnRyeXBvaW50fWA7XG5cbiAgICBzd2l0Y2ggKHRoaXMucGFja2FnZS5wYWNrYWdlTWFuYWdlcikge1xuICAgICAgY2FzZSBOb2RlUGFja2FnZU1hbmFnZXIuQlVOOlxuICAgICAgICBjb25zdCBidW5Uc0NvbmZpZyA9IHRoaXMudHNjb25maWc/LmZpbGVOYW1lXG4gICAgICAgICAgPyBgIC0tdHNjb25maWctb3ZlcnJpZGU9JHt0aGlzLnRzY29uZmlnPy5maWxlTmFtZX1gXG4gICAgICAgICAgOiBcIlwiO1xuICAgICAgICBjb25zdCBidW5FbnRyeXBvaW50ID0gZW5zdXJlUmVsYXRpdmVQYXRoUHJlZml4KGFwcEVudHJ5cG9pbnQpO1xuXG4gICAgICAgIC8vIGh0dHBzOi8vYnVuLnNoL2RvY3MvY2xpL3J1blxuICAgICAgICAvLyBidW4gY2FuIHJ1biB0cyBmaWxlcyBkaXJlY3RseVxuICAgICAgICByZXR1cm4gYGJ1biBydW4ke2J1blRzQ29uZmlnfSAke2J1bkVudHJ5cG9pbnR9YDtcbiAgICAgIGNhc2UgTm9kZVBhY2thZ2VNYW5hZ2VyLlBOUE06XG4gICAgICAgIC8vIGh0dHBzOi8vcG5wbS5pby9jbGkvZXhlY1xuICAgICAgICByZXR1cm4gYHBucG0gZXhlYyAke3RzTm9kZUFwcH1gO1xuICAgICAgY2FzZSBOb2RlUGFja2FnZU1hbmFnZXIuWUFSTl9DTEFTU0lDOlxuICAgICAgY2FzZSBOb2RlUGFja2FnZU1hbmFnZXIuWUFSTjpcbiAgICAgIGNhc2UgTm9kZVBhY2thZ2VNYW5hZ2VyLllBUk5fQkVSUlk6XG4gICAgICBjYXNlIE5vZGVQYWNrYWdlTWFuYWdlci5ZQVJOMjpcbiAgICAgICAgLy8gdXNlIG5weCB3aXRoIHlhcm4gZHVlIHRvIHJlcG9ydGVkIGlzc3Vlc1xuICAgICAgICAvLyBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9qZW4vcHJvamVuL2lzc3Vlcy80MTgwXG4gICAgICAgIHJldHVybiBgbnB4ICR7dHNOb2RlQXBwfWA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gYG5weCAke3RzTm9kZUFwcH1gO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEVuc3VyZXMgYSBwYXRoIGlzIHByb3Blcmx5IHByZWZpeGVkIHdpdGggJy4vJyBpZiBpdCdzIGEgcmVsYXRpdmUgcGF0aFxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoIC0gVGhlIHBhdGggdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBub3JtYWxpemVkIHBhdGhcbiAqL1xuZnVuY3Rpb24gZW5zdXJlUmVsYXRpdmVQYXRoUHJlZml4KGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgLy8gSWYgaXQncyBhbHJlYWR5IGFuIGFic29sdXRlIHBhdGgsIHJldHVybiBhcyBpc1xuICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGVQYXRoKSkge1xuICAgIHJldHVybiBmaWxlUGF0aDtcbiAgfVxuXG4gIC8vIElmIGl0IGFscmVhZHkgc3RhcnRzIHdpdGggLi8gb3IgLi4vLCByZXR1cm4gYXMgaXNcbiAgaWYgKGZpbGVQYXRoLnN0YXJ0c1dpdGgoXCIuL1wiKSB8fCBmaWxlUGF0aC5zdGFydHNXaXRoKFwiLi4vXCIpKSB7XG4gICAgcmV0dXJuIGZpbGVQYXRoO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBhZGQgLi8gcHJlZml4XG4gIHJldHVybiBgLi8ke2ZpbGVQYXRofWA7XG59XG5cbmNsYXNzIFNhbXBsZUNvZGUgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcFByb2plY3Q6IEF3c0Nka1R5cGVTY3JpcHRBcHA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvamVjdDogQXdzQ2RrVHlwZVNjcmlwdEFwcCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNka01ham9yVmVyc2lvbjogbnVtYmVyXG4gICkge1xuICAgIHN1cGVyKHByb2plY3QpO1xuICAgIHRoaXMuYXBwUHJvamVjdCA9IHByb2plY3Q7XG4gIH1cblxuICBwdWJsaWMgc3ludGhlc2l6ZSgpIHtcbiAgICBjb25zdCBvdXRkaXIgPSB0aGlzLnByb2plY3Qub3V0ZGlyO1xuICAgIGNvbnN0IHNyY2RpciA9IHBhdGguam9pbihvdXRkaXIsIHRoaXMuYXBwUHJvamVjdC5zcmNkaXIpO1xuICAgIGlmIChcbiAgICAgIGZzLmV4aXN0c1N5bmMoc3JjZGlyKSAmJlxuICAgICAgZnMucmVhZGRpclN5bmMoc3JjZGlyKS5maWx0ZXIoKHgpID0+IHguZW5kc1dpdGgoXCIudHNcIikpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3JjSW1wb3J0cyA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gICAgaWYgKHRoaXMuY2RrTWFqb3JWZXJzaW9uIDwgMikge1xuICAgICAgc3JjSW1wb3J0cy5wdXNoKFxuICAgICAgICBcImltcG9ydCB7IEFwcCwgQ29uc3RydWN0LCBTdGFjaywgU3RhY2tQcm9wcyB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1wiXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzcmNJbXBvcnRzLnB1c2goXCJpbXBvcnQgeyBBcHAsIFN0YWNrLCBTdGFja1Byb3BzIH0gZnJvbSAnYXdzLWNkay1saWInO1wiKTtcbiAgICAgIHNyY0ltcG9ydHMucHVzaChcImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBzcmNDb2RlID0gYCR7c3JjSW1wb3J0cy5qb2luKFwiXFxuXCIpfVxuXG5leHBvcnQgY2xhc3MgTXlTdGFjayBleHRlbmRzIFN0YWNrIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0YWNrUHJvcHMgPSB7fSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgLy8gZGVmaW5lIHJlc291cmNlcyBoZXJlLi4uXG4gIH1cbn1cblxuLy8gZm9yIGRldmVsb3BtZW50LCB1c2UgYWNjb3VudC9yZWdpb24gZnJvbSBjZGsgY2xpXG5jb25zdCBkZXZFbnYgPSB7XG4gIGFjY291bnQ6IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX0FDQ09VTlQsXG4gIHJlZ2lvbjogcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfUkVHSU9OLFxufTtcblxuY29uc3QgYXBwID0gbmV3IEFwcCgpO1xuXG5uZXcgTXlTdGFjayhhcHAsICcke3RoaXMucHJvamVjdC5uYW1lfS1kZXYnLCB7IGVudjogZGV2RW52IH0pO1xuLy8gbmV3IE15U3RhY2soYXBwLCAnJHt0aGlzLnByb2plY3QubmFtZX0tcHJvZCcsIHsgZW52OiBwcm9kRW52IH0pO1xuXG5hcHAuc3ludGgoKTtgO1xuXG4gICAgZnMubWtkaXJTeW5jKHNyY2RpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4oc3JjZGlyLCB0aGlzLmFwcFByb2plY3QuYXBwRW50cnlwb2ludCksIHNyY0NvZGUpO1xuXG4gICAgY29uc3QgdGVzdGRpciA9IHBhdGguam9pbihvdXRkaXIsIHRoaXMuYXBwUHJvamVjdC50ZXN0ZGlyKTtcbiAgICBpZiAoXG4gICAgICBmcy5leGlzdHNTeW5jKHRlc3RkaXIpICYmXG4gICAgICBmcy5yZWFkZGlyU3luYyh0ZXN0ZGlyKS5maWx0ZXIoKHgpID0+IHguZW5kc1dpdGgoXCIudHNcIikpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGVzdEltcG9ydHMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuICAgIGlmICh0aGlzLmNka01ham9yVmVyc2lvbiA8IDIpIHtcbiAgICAgIHRlc3RJbXBvcnRzLnB1c2goXCJpbXBvcnQgeyBBcHAgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcIik7XG4gICAgICB0ZXN0SW1wb3J0cy5wdXNoKFwiaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdAYXdzLWNkay9hc3NlcnRpb25zJztcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRlc3RJbXBvcnRzLnB1c2goXCJpbXBvcnQgeyBBcHAgfSBmcm9tICdhd3MtY2RrLWxpYic7XCIpO1xuICAgICAgdGVzdEltcG9ydHMucHVzaChcImltcG9ydCB7IFRlbXBsYXRlIH0gZnJvbSAnYXdzLWNkay1saWIvYXNzZXJ0aW9ucyc7XCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGFwcEVudHJ5cG9pbnROYW1lID0gcGF0aC5iYXNlbmFtZShcbiAgICAgIHRoaXMuYXBwUHJvamVjdC5hcHBFbnRyeXBvaW50LFxuICAgICAgXCIudHNcIlxuICAgICk7XG4gICAgY29uc3QgdGVzdENvZGUgPSBgJHt0ZXN0SW1wb3J0cy5qb2luKFwiXFxuXCIpfVxuaW1wb3J0IHsgTXlTdGFjayB9IGZyb20gJy4uLyR7dGhpcy5hcHBQcm9qZWN0LnNyY2Rpcn0vJHthcHBFbnRyeXBvaW50TmFtZX0nO1xuXG50ZXN0KCdTbmFwc2hvdCcsICgpID0+IHtcbiAgY29uc3QgYXBwID0gbmV3IEFwcCgpO1xuICBjb25zdCBzdGFjayA9IG5ldyBNeVN0YWNrKGFwcCwgJ3Rlc3QnKTtcblxuICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gIGV4cGVjdCh0ZW1wbGF0ZS50b0pTT04oKSkudG9NYXRjaFNuYXBzaG90KCk7XG59KTtgO1xuXG4gICAgZnMubWtkaXJTeW5jKHRlc3RkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICBwYXRoLmpvaW4odGVzdGRpciwgYCR7YXBwRW50cnlwb2ludE5hbWV9LnRlc3QudHNgKSxcbiAgICAgIHRlc3RDb2RlXG4gICAgKTtcbiAgfVxufVxuIl19