projen
Version:
CDK for software projects
198 lines (193 loc) • 23.5 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CdktnTypeScriptApp = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const cdktn_config_1 = require("./cdktn-config");
const cdktn_deps_1 = require("./cdktn-deps");
const cdktn_tasks_1 = require("./cdktn-tasks");
const component_1 = require("../component");
const dependencies_1 = require("../dependencies");
const typescript_1 = require("../typescript");
const typescript_runner_1 = require("../typescript/typescript-runner");
const fs_1 = require("../util/fs");
/**
* CDKTN app in TypeScript.
*
* CDKTN (CDK Terrain) is a community-driven fork of CDK for Terraform (CDKTF).
* Learn more at https://cdktn.io/
*
* @pjid cdktn-app-ts
*/
class CdktnTypeScriptApp extends typescript_1.TypeScriptAppProject {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.cdktn.CdktnTypeScriptApp", version: "0.103.12" };
/**
* The CDKTN app entrypoint.
*/
appEntrypoint;
/**
* Common CDKTN tasks.
*/
cdktnTasks;
/**
* cdktf.json configuration.
*/
cdktnConfig;
cdktnDeps;
constructor(options) {
super({
...options,
// Default to native Node.js TypeScript runner with type transformation via amaro
runner: options.runner ?? typescript_runner_1.TypeScriptRunner.nodejs({ transformTypes: true }),
sampleCode: false,
});
this.cdktnDeps = new cdktn_deps_1.CdktnDeps(this, {
dependencyType: dependencies_1.DependencyType.RUNTIME,
...options,
});
this.appEntrypoint = options.appEntrypoint ?? "main.ts";
// no compile step because we do all of it in typescript directly
this.compileTask.reset();
this.cdktnTasks = new cdktn_tasks_1.CdktnTasks(this);
// call get command before build
this.preCompileTask.spawn(this.cdktnTasks.get);
// add synth to the build
this.postCompileTask.spawn(this.cdktnTasks.synthSilent);
this.cdktnConfig = new cdktn_config_1.CdktnConfig(this, {
terraformProviders: options.terraformProviders,
terraformModules: options.terraformModules,
context: options.context,
cdktnOut: options.cdktnOut,
projectId: options.projectId,
sendCrashReports: options.sendCrashReports,
app: this.getCdktnApp(options),
});
this.tsconfig?.addExclude(this.cdktnConfig.cdktnOut);
this.gitignore.exclude(".terraform/");
this.gitignore.exclude(".terraform.lock.hcl");
this.gitignore.exclude("*.tfstate*");
this.gitignore.exclude("*.tfvars*");
this.npmignore?.exclude(`${this.cdktnConfig.cdktnOut}/`);
this.npmignore?.exclude(".gen/");
if (options.sampleCode ?? true) {
new SampleCode(this);
}
}
getCdktnApp(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);
// Use the project's runner to produce the app command
const { dependencies, steps } = this.runner.configFor(appEntrypoint);
// Register any runner dependencies
for (const dep of dependencies) {
this.deps.requestDependency(dep);
}
// Convert the last step's execArgs into a shell command string for cdktf.json
const runStep = steps[steps.length - 1];
if (runStep.execArgs) {
return runStep.execArgs.join(" ");
}
// Fallback: direct node invocation
return `node ${appEntrypoint}`;
}
}
exports.CdktnTypeScriptApp = CdktnTypeScriptApp;
class SampleCode extends component_1.Component {
appProject;
constructor(project) {
super(project);
this.appProject = project;
}
synthesize() {
const outdir = this.project.outdir;
const srcdir = path.join(outdir, this.appProject.srcdir);
// Don't generate the sample app if the user already has TypeScript source
// files in the source directory - we don't want to pollute something they
// have worked on. We check recursively so that an existing entrypoint
// located in a subdirectory (e.g. an `appEntrypoint` of "bin/main.ts") is
// also detected. As an extra safeguard, never overwrite an existing
// entrypoint file.
const entrypointPath = path.join(srcdir, this.appProject.appEntrypoint);
if (!(0, fs_1.dirContainsFile)(srcdir, ".ts") && !fs.existsSync(entrypointPath)) {
const srcCode = `import { Construct } from 'constructs';
import { App, TerraformStack } from 'cdktn';
export class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
// define resources here...
}
}
const app = new App();
new MyStack(app, '${this.project.name}');
app.synth();`;
// create the entrypoint's directory (which may be a subdirectory of `srcdir`) before writing the file.
fs.mkdirSync(path.dirname(entrypointPath), { recursive: true });
fs.writeFileSync(entrypointPath, srcCode);
}
const testdir = path.join(outdir, this.appProject.testdir);
const appEntrypointName = path.basename(this.appProject.appEntrypoint, ".ts");
const testPath = path.join(testdir, `${appEntrypointName}.test.ts`);
// import path to the stack, preserving any subdirectory in the entrypoint
// (e.g. "bin/main.ts" -> "../src/bin/main") and using posix separators.
const entrypointImport = this.appProject.appEntrypoint
.replace(/\.ts$/, "")
.split(path.sep)
.join(path.posix.sep);
// Likewise, don't generate the sample test if the user already has
// TypeScript files in the test directory, and never overwrite an existing
// test file.
if (!(0, fs_1.dirContainsFile)(testdir, ".ts") && !fs.existsSync(testPath)) {
const testCode = `import "cdktn/lib/testing/adapters/jest";
import { Testing } from 'cdktn';
import { MyStack } from '../${this.appProject.srcdir}/${entrypointImport}';
test('Snapshot', () => {
const app = Testing.app();
const stack = new MyStack(app, 'test');
expect(Testing.synth(stack)).toMatchSnapshot();
});`;
fs.mkdirSync(path.dirname(testPath), { recursive: true });
fs.writeFileSync(testPath, testCode);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrdG4tYXBwLXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nka3RuL2Nka3RuLWFwcC10cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQThCO0FBQzlCLGdEQUFrQztBQUNsQyxpREFBNkM7QUFFN0MsNkNBQXlDO0FBRXpDLCtDQUEyQztBQUMzQyw0Q0FBeUM7QUFDekMsa0RBQWlEO0FBRWpELDhDQUFxRDtBQUNyRCx1RUFBbUU7QUFDbkUsbUNBQTZDO0FBc0I3Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxrQkFBbUIsU0FBUSxpQ0FBb0I7O0lBQzFEOztPQUVHO0lBQ2EsYUFBYSxDQUFTO0lBRXRDOztPQUVHO0lBQ2EsVUFBVSxDQUFhO0lBRXZDOztPQUVHO0lBQ2EsV0FBVyxDQUFjO0lBRXpCLFNBQVMsQ0FBWTtJQUVyQyxZQUFZLE9BQWtDO1FBQzVDLEtBQUssQ0FBQztZQUNKLEdBQUcsT0FBTztZQUNWLGlGQUFpRjtZQUNqRixNQUFNLEVBQ0osT0FBTyxDQUFDLE1BQU0sSUFBSSxvQ0FBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDckUsVUFBVSxFQUFFLEtBQUs7U0FDbEIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLHNCQUFTLENBQUMsSUFBSSxFQUFFO1lBQ25DLGNBQWMsRUFBRSw2QkFBYyxDQUFDLE9BQU87WUFDdEMsR0FBRyxPQUFPO1NBQ1gsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLFNBQVMsQ0FBQztRQUV4RCxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUV6QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksd0JBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztR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QUMsVUFBVSxDQUFDLGFBQWEsRUFDN0IsS0FBSyxDQUNOLENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLGlCQUFpQixVQUFVLENBQUMsQ0FBQztRQUVwRSwwRUFBMEU7UUFDMUUsd0VBQXdFO1FBQ3hFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhO2FBQ25ELE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO2FBQ3BCLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO2FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFeEIsbUVBQW1FO1FBQ25FLDBFQUEwRTtRQUMxRSxhQUFhO1FBQ2IsSUFBSSxDQUFDLElBQUEsb0JBQWUsRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDakUsTUFBTSxRQUFRLEdBQUc7OzhCQUVPLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLGdCQUFnQjs7Ozs7OztJQU9wRSxDQUFDO1lBRUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDMUQsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IENka3RuQ29uZmlnIH0gZnJvbSBcIi4vY2RrdG4tY29uZmlnXCI7XG5pbXBvcnQgdHlwZSB7IENka3RuQ29uZmlnQ29tbW9uT3B0aW9ucyB9IGZyb20gXCIuL2Nka3RuLWNvbmZpZ1wiO1xuaW1wb3J0IHsgQ2RrdG5EZXBzIH0gZnJvbSBcIi4vY2RrdG4tZGVwc1wiO1xuaW1wb3J0IHR5cGUgeyBDZGt0bkRlcHNDb21tb25PcHRpb25zIH0gZnJvbSBcIi4vY2RrdG4tZGVwc1wiO1xuaW1wb3J0IHsgQ2RrdG5UYXNrcyB9IGZyb20gXCIuL2Nka3RuLXRhc2tzXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgeyBEZXBlbmRlbmN5VHlwZSB9IGZyb20gXCIuLi9kZXBlbmRlbmNpZXNcIjtcbmltcG9ydCB0eXBlIHsgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IFR5cGVTY3JpcHRBcHBQcm9qZWN0IH0gZnJvbSBcIi4uL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IFR5cGVTY3JpcHRSdW5uZXIgfSBmcm9tIFwiLi4vdHlwZXNjcmlwdC90eXBlc2NyaXB0LXJ1bm5lclwiO1xuaW1wb3J0IHsgZGlyQ29udGFpbnNGaWxlIH0gZnJvbSBcIi4uL3V0aWwvZnNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBDZGt0blR5cGVTY3JpcHRBcHBPcHRpb25zXG4gIGV4dGVuZHNcbiAgICBUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMsXG4gICAgQ2RrdG5EZXBzQ29tbW9uT3B0aW9ucyxcbiAgICBDZGt0bkNvbmZpZ0NvbW1vbk9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIENES1ROIGFwcCdzIGVudHJ5cG9pbnQgKHJlbGF0aXZlIHRvIHRoZSBzb3VyY2UgZGlyZWN0b3J5LCB3aGljaCBpc1xuICAgKiBcInNyY1wiIGJ5IGRlZmF1bHQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIm1haW4udHNcIlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwRW50cnlwb2ludD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNvbW1hbmQgbGluZSB0byBleGVjdXRlIGluIG9yZGVyIHRvIHN5bnRoZXNpemUgdGhlIENES1ROIGFwcGxpY2F0aW9uXG4gICAqIChsYW5ndWFnZSBzcGVjaWZpYykuXG4gICAqL1xuICByZWFkb25seSBhcHA/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ0RLVE4gYXBwIGluIFR5cGVTY3JpcHQuXG4gKlxuICogQ0RLVE4gKENESyBUZXJyYWluKSBpcyBhIGNvbW11bml0eS1kcml2ZW4gZm9yayBvZiBDREsgZm9yIFRlcnJhZm9ybSAoQ0RLVEYpLlxuICogTGVhcm4gbW9yZSBhdCBodHRwczovL2Nka3RuLmlvL1xuICpcbiAqIEBwamlkIGNka3RuLWFwcC10c1xuICovXG5leHBvcnQgY2xhc3MgQ2RrdG5UeXBlU2NyaXB0QXBwIGV4dGVuZHMgVHlwZVNjcmlwdEFwcFByb2plY3Qge1xuICAvKipcbiAgICogVGhlIENES1ROIGFwcCBlbnRyeXBvaW50LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwcEVudHJ5cG9pbnQ6IHN0cmluZztcblxuICAvKipcbiAgICogQ29tbW9uIENES1ROIHRhc2tzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNka3RuVGFza3M6IENka3RuVGFza3M7XG5cbiAgLyoqXG4gICAqIGNka3RmLmpzb24gY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjZGt0bkNvbmZpZzogQ2RrdG5Db25maWc7XG5cbiAgcHVibGljIHJlYWRvbmx5IGNka3RuRGVwczogQ2RrdG5EZXBzO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IENka3RuVHlwZVNjcmlwdEFwcE9wdGlvbnMpIHtcbiAgICBzdXBlcih7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgLy8gRGVmYXVsdCB0byBuYXRpdmUgTm9kZS5qcyBUeXBlU2NyaXB0IHJ1bm5lciB3aXRoIHR5cGUgdHJhbnNmb3JtYXRpb24gdmlhIGFtYXJvXG4gICAgICBydW5uZXI6XG4gICAgICAgIG9wdGlvbnMucnVubmVyID8/IFR5cGVTY3JpcHRSdW5uZXIubm9kZWpzKHsgdHJhbnNmb3JtVHlwZXM6IHRydWUgfSksXG4gICAgICBzYW1wbGVDb2RlOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuY2RrdG5EZXBzID0gbmV3IENka3RuRGVwcyh0aGlzLCB7XG4gICAgICBkZXBlbmRlbmN5VHlwZTogRGVwZW5kZW5jeVR5cGUuUlVOVElNRSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gICAgdGhpcy5hcHBFbnRyeXBvaW50ID0gb3B0aW9ucy5hcHBFbnRyeXBvaW50ID8/IFwibWFpbi50c1wiO1xuXG4gICAgLy8gbm8gY29tcGlsZSBzdGVwIGJlY2F1c2Ugd2UgZG8gYWxsIG9mIGl0IGluIHR5cGVzY3JpcHQgZGlyZWN0bHlcbiAgICB0aGlzLmNvbXBpbGVUYXNrLnJlc2V0KCk7XG5cbiAgICB0aGlzLmNka3RuVGFza3MgPSBuZXcgQ2RrdG5UYXNrcyh0aGlzKTtcblxuICAgIC8vIGNhbGwgZ2V0IGNvbW1hbmQgYmVmb3JlIGJ1aWxkXG4gICAgdGhpcy5wcmVDb21waWxlVGFzay5zcGF3bih0aGlzLmNka3RuVGFza3MuZ2V0KTtcblxuICAgIC8vIGFkZCBzeW50aCB0byB0aGUgYnVpbGRcbiAgICB0aGlzLnBvc3RDb21waWxlVGFzay5zcGF3bih0aGlzLmNka3RuVGFza3Muc3ludGhTaWxlbnQpO1xuXG4gICAgdGhpcy5jZGt0bkNvbmZpZyA9IG5ldyBDZGt0bkNvbmZpZyh0aGlzLCB7XG4gICAgICB0ZXJyYWZvcm1Qcm92aWRlcnM6IG9wdGlvbnMudGVycmFmb3JtUHJvdmlkZXJzLFxuICAgICAgdGVycmFmb3JtTW9kdWxlczogb3B0aW9ucy50ZXJyYWZvcm1Nb2R1bGVzLFxuICAgICAgY29udGV4dDogb3B0aW9ucy5jb250ZXh0LFxuICAgICAgY2RrdG5PdXQ6IG9wdGlvbnMuY2RrdG5PdXQsXG4gICAgICBwcm9qZWN0SWQ6IG9wdGlvbnMucHJvamVjdElkLFxuICAgICAgc2VuZENyYXNoUmVwb3J0czogb3B0aW9ucy5zZW5kQ3Jhc2hSZXBvcnRzLFxuICAgICAgYXBwOiB0aGlzLmdldENka3RuQXBwKG9wdGlvbnMpLFxuICAgIH0pO1xuXG4gICAgdGhpcy50c2NvbmZpZz8uYWRkRXhjbHVkZSh0aGlzLmNka3RuQ29uZmlnLmNka3RuT3V0KTtcblxuICAgIHRoaXMuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIudGVycmFmb3JtL1wiKTtcbiAgICB0aGlzLmdpdGlnbm9yZS5leGNsdWRlKFwiLnRlcnJhZm9ybS5sb2NrLmhjbFwiKTtcbiAgICB0aGlzLmdpdGlnbm9yZS5leGNsdWRlKFwiKi50ZnN0YXRlKlwiKTtcbiAgICB0aGlzLmdpdGlnbm9yZS5leGNsdWRlKFwiKi50ZnZhcnMqXCIpO1xuXG4gICAgdGhpcy5ucG1pZ25vcmU/LmV4Y2x1ZGUoYCR7dGhpcy5jZGt0bkNvbmZpZy5jZGt0bk91dH0vYCk7XG4gICAgdGhpcy5ucG1pZ25vcmU/LmV4Y2x1ZGUoXCIuZ2VuL1wiKTtcblxuICAgIGlmIChvcHRpb25zLnNhbXBsZUNvZGUgPz8gdHJ1ZSkge1xuICAgICAgbmV3IFNhbXBsZUNvZGUodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDZGt0bkFwcChvcHRpb25zOiBDZGt0blR5cGVTY3JpcHRBcHBPcHRpb25zKTogc3RyaW5nIHtcbiAgICBpZiAob3B0aW9ucy5hcHAgJiYgb3B0aW9ucy5hcHBFbnRyeXBvaW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPbmx5IG9uZSBvZiAnYXBwJyBvciAnYXBwRW50cnlwb2ludCcgY2FuIGJlIHNwZWNpZmllZFwiKTtcbiAgICB9XG5cbiAgICAvLyBwcmVmZXIgYW4gZXhwbGljaXRseSBwcm92aWRlZCBhcHAgY29tbWFuZFxuICAgIGlmIChvcHRpb25zLmFwcCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuYXBwO1xuICAgIH1cblxuICAgIGNvbnN0IGFwcEVudHJ5cG9pbnQgPSBwYXRoLnBvc2l4LmpvaW4odGhpcy5zcmNkaXIsIHRoaXMuYXBwRW50cnlwb2ludCk7XG5cbiAgICAvLyBVc2UgdGhlIHByb2plY3QncyBydW5uZXIgdG8gcHJvZHVjZSB0aGUgYXBwIGNvbW1hbmRcbiAgICBjb25zdCB7IGRlcGVuZGVuY2llcywgc3RlcHMgfSA9IHRoaXMucnVubmVyLmNvbmZpZ0ZvcihhcHBFbnRyeXBvaW50KTtcblxuICAgIC8vIFJlZ2lzdGVyIGFueSBydW5uZXIgZGVwZW5kZW5jaWVzXG4gICAgZm9yIChjb25zdCBkZXAgb2YgZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aGlzLmRlcHMucmVxdWVzdERlcGVuZGVuY3koZGVwKTtcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IHRoZSBsYXN0IHN0ZXAncyBleGVjQXJncyBpbnRvIGEgc2hlbGwgY29tbWFuZCBzdHJpbmcgZm9yIGNka3RmLmpzb25cbiAgICBjb25zdCBydW5TdGVwID0gc3RlcHNbc3RlcHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKHJ1blN0ZXAuZXhlY0FyZ3MpIHtcbiAgICAgIHJldHVybiBydW5TdGVwLmV4ZWNBcmdzLmpvaW4oXCIgXCIpO1xuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrOiBkaXJlY3Qgbm9kZSBpbnZvY2F0aW9uXG4gICAgcmV0dXJuIGBub2RlICR7YXBwRW50cnlwb2ludH1gO1xuICB9XG59XG5cbmNsYXNzIFNhbXBsZUNvZGUgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcFByb2plY3Q6IENka3RuVHlwZVNjcmlwdEFwcDtcblxuICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBDZGt0blR5cGVTY3JpcHRBcHApIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcbiAgICB0aGlzLmFwcFByb2plY3QgPSBwcm9qZWN0O1xuICB9XG5cbiAgcHVibGljIHN5bnRoZXNpemUoKSB7XG4gICAgY29uc3Qgb3V0ZGlyID0gdGhpcy5wcm9qZWN0Lm91dGRpcjtcbiAgICBjb25zdCBzcmNkaXIgPSBwYXRoLmpvaW4ob3V0ZGlyLCB0aGlzLmFwcFByb2plY3Quc3JjZGlyKTtcblxuICAgIC8vIERvbid0IGdlbmVyYXRlIHRoZSBzYW1wbGUgYXBwIGlmIHRoZSB1c2VyIGFscmVhZHkgaGFzIFR5cGVTY3JpcHQgc291cmNlXG4gICAgLy8gZmlsZXMgaW4gdGhlIHNvdXJjZSBkaXJlY3RvcnkgLSB3ZSBkb24ndCB3YW50IHRvIHBvbGx1dGUgc29tZXRoaW5nIHRoZXlcbiAgICAvLyBoYXZlIHdvcmtlZCBvbi4gV2UgY2hlY2sgcmVjdXJzaXZlbHkgc28gdGhhdCBhbiBleGlzdGluZyBlbnRyeXBvaW50XG4gICAgLy8gbG9jYXRlZCBpbiBhIHN1YmRpcmVjdG9yeSAoZS5nLiBhbiBgYXBwRW50cnlwb2ludGAgb2YgXCJiaW4vbWFpbi50c1wiKSBpc1xuICAgIC8vIGFsc28gZGV0ZWN0ZWQuIEFzIGFuIGV4dHJhIHNhZmVndWFyZCwgbmV2ZXIgb3ZlcndyaXRlIGFuIGV4aXN0aW5nXG4gICAgLy8gZW50cnlwb2ludCBmaWxlLlxuICAgIGNvbnN0IGVudHJ5cG9pbnRQYXRoID0gcGF0aC5qb2luKHNyY2RpciwgdGhpcy5hcHBQcm9qZWN0LmFwcEVudHJ5cG9pbnQpO1xuICAgIGlmICghZGlyQ29udGFpbnNGaWxlKHNyY2RpciwgXCIudHNcIikgJiYgIWZzLmV4aXN0c1N5bmMoZW50cnlwb2ludFBhdGgpKSB7XG4gICAgICBjb25zdCBzcmNDb2RlID0gYGltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXBwLCBUZXJyYWZvcm1TdGFjayB9IGZyb20gJ2Nka3RuJztcblxuZXhwb3J0IGNsYXNzIE15U3RhY2sgZXh0ZW5kcyBUZXJyYWZvcm1TdGFjayB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gZGVmaW5lIHJlc291cmNlcyBoZXJlLi4uXG4gIH1cbn1cblxuY29uc3QgYXBwID0gbmV3IEFwcCgpO1xubmV3IE15U3RhY2soYXBwLCAnJHt0aGlzLnByb2plY3QubmFtZX0nKTtcbmFwcC5zeW50aCgpO2A7XG5cbiAgICAgIC8vIGNyZWF0ZSB0aGUgZW50cnlwb2ludCdzIGRpcmVjdG9yeSAod2hpY2ggbWF5IGJlIGEgc3ViZGlyZWN0b3J5IG9mIGBzcmNkaXJgKSBiZWZvcmUgd3JpdGluZyB0aGUgZmlsZS5cbiAgICAgIGZzLm1rZGlyU3luYyhwYXRoLmRpcm5hbWUoZW50cnlwb2ludFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZW50cnlwb2ludFBhdGgsIHNyY0NvZGUpO1xuICAgIH1cblxuICAgIGNvbnN0IHRlc3RkaXIgPSBwYXRoLmpvaW4ob3V0ZGlyLCB0aGlzLmFwcFByb2plY3QudGVzdGRpcik7XG4gICAgY29uc3QgYXBwRW50cnlwb2ludE5hbWUgPSBwYXRoLmJhc2VuYW1lKFxuICAgICAgdGhpcy5hcHBQcm9qZWN0LmFwcEVudHJ5cG9pbnQsXG4gICAgICBcIi50c1wiLFxuICAgICk7XG4gICAgY29uc3QgdGVzdFBhdGggPSBwYXRoLmpvaW4odGVzdGRpciwgYCR7YXBwRW50cnlwb2ludE5hbWV9LnRlc3QudHNgKTtcblxuICAgIC8vIGltcG9ydCBwYXRoIHRvIHRoZSBzdGFjaywgcHJlc2VydmluZyBhbnkgc3ViZGlyZWN0b3J5IGluIHRoZSBlbnRyeXBvaW50XG4gICAgLy8gKGUuZy4gXCJiaW4vbWFpbi50c1wiIC0+IFwiLi4vc3JjL2Jpbi9tYWluXCIpIGFuZCB1c2luZyBwb3NpeCBzZXBhcmF0b3JzLlxuICAgIGNvbnN0IGVudHJ5cG9pbnRJbXBvcnQgPSB0aGlzLmFwcFByb2plY3QuYXBwRW50cnlwb2ludFxuICAgICAgLnJlcGxhY2UoL1xcLnRzJC8sIFwiXCIpXG4gICAgICAuc3BsaXQocGF0aC5zZXApXG4gICAgICAuam9pbihwYXRoLnBvc2l4LnNlcCk7XG5cbiAgICAvLyBMaWtld2lzZSwgZG9uJ3QgZ2VuZXJhdGUgdGhlIHNhbXBsZSB0ZXN0IGlmIHRoZSB1c2VyIGFscmVhZHkgaGFzXG4gICAgLy8gVHlwZVNjcmlwdCBmaWxlcyBpbiB0aGUgdGVzdCBkaXJlY3RvcnksIGFuZCBuZXZlciBvdmVyd3JpdGUgYW4gZXhpc3RpbmdcbiAgICAvLyB0ZXN0IGZpbGUuXG4gICAgaWYgKCFkaXJDb250YWluc0ZpbGUodGVzdGRpciwgXCIudHNcIikgJiYgIWZzLmV4aXN0c1N5bmModGVzdFBhdGgpKSB7XG4gICAgICBjb25zdCB0ZXN0Q29kZSA9IGBpbXBvcnQgXCJjZGt0bi9saWIvdGVzdGluZy9hZGFwdGVycy9qZXN0XCI7XG5pbXBvcnQgeyBUZXN0aW5nIH0gZnJvbSAnY2RrdG4nO1xuaW1wb3J0IHsgTXlTdGFjayB9IGZyb20gJy4uLyR7dGhpcy5hcHBQcm9qZWN0LnNyY2Rpcn0vJHtlbnRyeXBvaW50SW1wb3J0fSc7XG5cbnRlc3QoJ1NuYXBzaG90JywgKCkgPT4ge1xuICBjb25zdCBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICBjb25zdCBzdGFjayA9IG5ldyBNeVN0YWNrKGFwcCwgJ3Rlc3QnKTtcblxuICBleHBlY3QoVGVzdGluZy5zeW50aChzdGFjaykpLnRvTWF0Y2hTbmFwc2hvdCgpO1xufSk7YDtcblxuICAgICAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZSh0ZXN0UGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyh0ZXN0UGF0aCwgdGVzdENvZGUpO1xuICAgIH1cbiAgfVxufVxuIl19