projen-sst
Version:
Helpers for Projen projects that use SST.
161 lines (157 loc) • 22.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SstSampleCode = exports.SstTypescriptApp = void 0;
const projen_1 = require("projen");
const SST_CONFIG_FILE_NAME = "sst.config.ts";
class SstTypescriptApp extends projen_1.awscdk.AwsCdkTypeScriptApp {
options;
branchNameToSstStageMap;
sstConfig;
sstVersion;
constructor(options) {
super({ ...options, sampleCode: false });
this.options = options;
this.branchNameToSstStageMap = options.branchNameToSstStageMap;
this.sstConfig = {
sstOut: options.sstOut ?? ".sst/dist/",
};
this.sstVersion = options.sstVersion ?? "2.39.2";
this.addDevDeps(`sst@${this.sstVersion}`);
this.addIgnores();
this.createPersonalTasks();
this.overrideTasks();
if (options.sampleCode) {
new SstSampleCode(this);
}
}
addIgnores() {
this.gitignore.exclude(".sst", ".build", ".open-next", ".DS_Store");
this.eslint?.allowDevDeps(SST_CONFIG_FILE_NAME);
this.tsconfig?.addExclude(SST_CONFIG_FILE_NAME);
this.tsconfigDev?.addInclude(SST_CONFIG_FILE_NAME);
}
createPersonalTasks() {
const devTask = this.tasks.tryFind("dev") ?? this.tasks.addTask("dev");
devTask.reset(`sst dev --stage $(whoami|head -c 7)`);
devTask.description = "Start SST Dev Server for personal stage";
const startTask = this.tasks.tryFind("start") ?? this.tasks.addTask("start");
startTask.reset();
startTask.spawn(devTask);
const destroyPersonalTask = this.tasks.tryFind("destroy:personal") ??
this.tasks.addTask("destroy:personal");
destroyPersonalTask.reset(`sst remove --stage $(whoami|head -c 7)`);
destroyPersonalTask.description = "Destroy personal SST stage";
}
overrideTasks() {
this.overrideTasksForDefaultStage();
const otherBranches = this.release?.branches?.filter((branch) => branch !== this.options.defaultReleaseBranch);
if (otherBranches && otherBranches.length > 0) {
for (const branch of otherBranches) {
this.createTasksForBranch(branch);
}
}
}
overrideTasksForDefaultStage() {
const defaultStageName = this.branchNameToSstStageMap?.[this.options.defaultReleaseBranch] ??
this.options.defaultReleaseBranch;
const synthTask = this.tasks.tryFind("synth");
if (synthTask) {
const { exec: _, ...restOfStep } = synthTask.steps[0];
synthTask.reset(`sst build --stage ${defaultStageName} --to ${this.sstConfig.sstOut}`, {
...restOfStep,
receiveArgs: true,
});
}
const synthSilentTask = this.tasks.tryFind("synth:silent");
if (synthSilentTask) {
const { exec: _, ...restOfStep } = synthSilentTask.steps[0];
synthSilentTask.reset(`sst build --stage ${defaultStageName} --to ${this.sstConfig.sstOut}`, {
...restOfStep,
receiveArgs: true,
});
}
const deployTask = this.tasks.tryFind("deploy");
if (deployTask) {
const { exec: _, ...restOfStep } = deployTask.steps[0];
deployTask.reset();
deployTask.exec(`sst deploy --stage ${defaultStageName} --from ${this.sstConfig.sstOut}`, { ...restOfStep, receiveArgs: true });
}
const destroyTask = this.tasks.tryFind("destroy");
if (destroyTask) {
const { exec: _, ...restOfStep } = destroyTask.steps[0];
destroyTask.reset(`sst remove sst build --stage ${defaultStageName}`, {
...restOfStep,
receiveArgs: true,
});
}
}
createTasksForBranch(branchName) {
const stageName = this.branchNameToSstStageMap?.[branchName] ?? branchName;
this.addTask(`synth:${stageName}`, {
description: `Synth ${stageName} stage`,
exec: `sst build --stage ${stageName} --to ${this.sstConfig.sstOut}`,
receiveArgs: true,
});
this.addTask(`synth:silent:${stageName}`, {
description: `Synth ${stageName} stage`,
exec: `sst build --stage ${stageName} --to ${this.sstConfig.sstOut}`,
receiveArgs: true,
});
const deployTask = this.addTask(`deploy:${stageName}`, {
description: `Deploy ${stageName} stage`,
});
deployTask.exec(`sst deploy --stage ${stageName} --from ${this.sstConfig.sstOut}`, {
receiveArgs: true,
});
this.addTask(`destroy:${stageName}`, {
description: `Destroy ${stageName} stage`,
exec: `sst remove sst build --stage ${stageName}`,
receiveArgs: true,
});
}
}
exports.SstTypescriptApp = SstTypescriptApp;
class SstSampleCode extends projen_1.Component {
constructor(project) {
super(project);
this.createSstConfigFile();
this.createStackFile();
}
createSstConfigFile() {
new projen_1.SampleFile(this.project, SST_CONFIG_FILE_NAME, {
contents: `import { SSTConfig } from "sst";
import { MyStack } from "./stacks/MyStack";
export default {
config(_input) {
return {
name: "test-create-sst",
region: "us-east-1",
};
},
stacks(app) {
new MyStack(app, "MyStack");
}
} satisfies SSTConfig;
`,
});
}
createStackFile() {
new projen_1.SampleDir(this.project, "src", {
files: {
"MyStack.ts": `import { Api, App, Stack, StackProps } from "sst/constructs";
export class MyStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
const api = new Api(this, "MyApi");
this.addOutputs({
ApiEndpoint: api.url,
});
}
}
`,
},
});
}
}
exports.SstSampleCode = SstSampleCode;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQWtFO0FBc0NsRSxNQUFNLG9CQUFvQixHQUFHLGVBQWUsQ0FBQztBQUU3QyxNQUFhLGdCQUFpQixTQUFRLGVBQU0sQ0FBQyxtQkFBbUI7SUFLL0I7SUFKYix1QkFBdUIsQ0FBMEI7SUFDakQsU0FBUyxDQUFtQjtJQUM1QixVQUFVLENBQVM7SUFFbkMsWUFBNkIsT0FBZ0M7UUFDekQsS0FBSyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFEaEIsWUFBTyxHQUFQLE9BQU8sQ0FBeUI7UUFHekQsSUFBSSxDQUFDLHVCQUF1QixHQUFHLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQztRQUMvRCxJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2IsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLElBQUksWUFBWTtTQUN6QyxDQUFDO1FBQ0YsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQztRQUVqRCxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFFMUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNyQixJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0wsQ0FBQztJQUVPLFVBQVU7UUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNwRSxJQUFJLENBQUMsTUFBTSxF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QUFFO1lBQy9DLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Q0FjckI7U0FDUSxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sZUFBZTtRQUNuQixJQUFJLGtCQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUU7WUFDL0IsS0FBSyxFQUFFO2dCQUNILFlBQVksRUFBRTs7Ozs7Ozs7Ozs7OztDQWE3QjthQUNZO1NBQ0osQ0FBQyxDQUFDO0lBQ1AsQ0FBQztDQUNKO0FBaERELHNDQWdEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgU2FtcGxlRGlyLCBTYW1wbGVGaWxlLCBhd3NjZGsgfSBmcm9tIFwicHJvamVuXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3N0Q29uZmlndXJhdGlvbk9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIE1hcHMgYnJhbmNoTmFtZXMgdG8gU1NUIFN0YWdlcy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IC0gVGhlIGJyYW5jaE5hbWUgd2lsbCBiZSB1c2VkIGFzIHRoZSBzdGFnZSBuYW1lLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGJyYW5jaE5hbWVUb1NzdFN0YWdlTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICAgIC8qKlxuICAgICAqIFdoZXJlIHRvIGJ1aWxkIC5zc3QgY29kZSB0by5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IFwiLnNzdC9kaXN0L1wiXG4gICAgICovXG4gICAgc3N0T3V0Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHZlcnNpb24gb2YgU1NUIHRvIHVzZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IFwiMi4zOS4yXCJcbiAgICAgKi9cbiAgICBzc3RWZXJzaW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNzdENvbmZpZ3VyYXRpb24ge1xuICAgIC8qKlxuICAgICAqIFdoZXJlIHRvIGJ1aWxkIC5zc3QgY29kZSB0by5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IFwiLnNzdC9kaXN0L1wiXG4gICAgICovXG4gICAgc3N0T3V0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3N0VHlwZXNjcmlwdEFwcE9wdGlvbnNcbiAgICBleHRlbmRzIGF3c2Nkay5Bd3NDZGtUeXBlU2NyaXB0QXBwT3B0aW9ucyxcbiAgICAgICAgU3N0Q29uZmlndXJhdGlvbk9wdGlvbnMge31cblxuY29uc3QgU1NUX0NPTkZJR19GSUxFX05BTUUgPSBcInNzdC5jb25maWcudHNcIjtcblxuZXhwb3J0IGNsYXNzIFNzdFR5cGVzY3JpcHRBcHAgZXh0ZW5kcyBhd3NjZGsuQXdzQ2RrVHlwZVNjcmlwdEFwcCB7XG4gICAgcHVibGljIHJlYWRvbmx5IGJyYW5jaE5hbWVUb1NzdFN0YWdlTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3N0Q29uZmlnOiBTc3RDb25maWd1cmF0aW9uO1xuICAgIHB1YmxpYyByZWFkb25seSBzc3RWZXJzaW9uOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IFNzdFR5cGVzY3JpcHRBcHBPcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKHsgLi4ub3B0aW9ucywgc2FtcGxlQ29kZTogZmFsc2UgfSk7XG5cbiAgICAgICAgdGhpcy5icmFuY2hOYW1lVG9Tc3RTdGFnZU1hcCA9IG9wdGlvbnMuYnJhbmNoTmFtZVRvU3N0U3RhZ2VNYXA7XG4gICAgICAgIHRoaXMuc3N0Q29uZmlnID0ge1xuICAgICAgICAgICAgc3N0T3V0OiBvcHRpb25zLnNzdE91dCA/PyBcIi5zc3QvZGlzdC9cIixcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zc3RWZXJzaW9uID0gb3B0aW9ucy5zc3RWZXJzaW9uID8/IFwiMi4zOS4yXCI7XG5cbiAgICAgICAgdGhpcy5hZGREZXZEZXBzKGBzc3RAJHt0aGlzLnNzdFZlcnNpb259YCk7XG5cbiAgICAgICAgdGhpcy5hZGRJZ25vcmVzKCk7XG4gICAgICAgIHRoaXMuY3JlYXRlUGVyc29uYWxUYXNrcygpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlVGFza3MoKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5zYW1wbGVDb2RlKSB7XG4gICAgICAgICAgICBuZXcgU3N0U2FtcGxlQ29kZSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYWRkSWdub3JlcygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5naXRpZ25vcmUuZXhjbHVkZShcIi5zc3RcIiwgXCIuYnVpbGRcIiwgXCIub3Blbi1uZXh0XCIsIFwiLkRTX1N0b3JlXCIpO1xuICAgICAgICB0aGlzLmVzbGludD8uYWxsb3dEZXZEZXBzKFNTVF9DT05GSUdfRklMRV9OQU1FKTtcbiAgICAgICAgdGhpcy50c2NvbmZpZz8uYWRkRXhjbHVkZShTU1RfQ09ORklHX0ZJTEVfTkFNRSk7XG4gICAgICAgIHRoaXMudHNjb25maWdEZXY/LmFkZEluY2x1ZGUoU1NUX0NPTkZJR19GSUxFX05BTUUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlUGVyc29uYWxUYXNrcygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGV2VGFzayA9IHRoaXMudGFza3MudHJ5RmluZChcImRldlwiKSA/PyB0aGlzLnRhc2tzLmFkZFRhc2soXCJkZXZcIik7XG4gICAgICAgIGRldlRhc2sucmVzZXQoYHNzdCBkZXYgLS1zdGFnZSAkKHdob2FtaXxoZWFkIC1jIDcpYCk7XG4gICAgICAgIGRldlRhc2suZGVzY3JpcHRpb24gPSBcIlN0YXJ0IFNTVCBEZXYgU2VydmVyIGZvciBwZXJzb25hbCBzdGFnZVwiO1xuXG4gICAgICAgIGNvbnN0IHN0YXJ0VGFzayA9XG4gICAgICAgICAgICB0aGlzLnRhc2tzLnRyeUZpbmQoXCJzdGFydFwiKSA/PyB0aGlzLnRhc2tzLmFkZFRhc2soXCJzdGFydFwiKTtcbiAgICAgICAgc3RhcnRUYXNrLnJlc2V0KCk7XG4gICAgICAgIHN0YXJ0VGFzay5zcGF3bihkZXZUYXNrKTtcblxuICAgICAgICBjb25zdCBkZXN0cm95UGVyc29uYWxUYXNrID1cbiAgICAgICAgICAgIHRoaXMudGFza3MudHJ5RmluZChcImRlc3Ryb3k6cGVyc29uYWxcIikgPz9cbiAgICAgICAgICAgIHRoaXMudGFza3MuYWRkVGFzayhcImRlc3Ryb3k6cGVyc29uYWxcIik7XG4gICAgICAgIGRlc3Ryb3lQZXJzb25hbFRhc2sucmVzZXQoYHNzdCByZW1vdmUgLS1zdGFnZSAkKHdob2FtaXxoZWFkIC1jIDcpYCk7XG4gICAgICAgIGRlc3Ryb3lQZXJzb25hbFRhc2suZGVzY3JpcHRpb24gPSBcIkRlc3Ryb3kgcGVyc29uYWwgU1NUIHN0YWdlXCI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVycmlkZVRhc2tzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLm92ZXJyaWRlVGFza3NGb3JEZWZhdWx0U3RhZ2UoKTtcblxuICAgICAgICBjb25zdCBvdGhlckJyYW5jaGVzID0gdGhpcy5yZWxlYXNlPy5icmFuY2hlcz8uZmlsdGVyKFxuICAgICAgICAgICAgKGJyYW5jaCkgPT4gYnJhbmNoICE9PSB0aGlzLm9wdGlvbnMuZGVmYXVsdFJlbGVhc2VCcmFuY2gsXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKG90aGVyQnJhbmNoZXMgJiYgb3RoZXJCcmFuY2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJyYW5jaCBvZiBvdGhlckJyYW5jaGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVUYXNrc0ZvckJyYW5jaChicmFuY2gpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVycmlkZVRhc2tzRm9yRGVmYXVsdFN0YWdlKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBkZWZhdWx0U3RhZ2VOYW1lID1cbiAgICAgICAgICAgIHRoaXMuYnJhbmNoTmFtZVRvU3N0U3RhZ2VNYXA/Llt0aGlzLm9wdGlvbnMuZGVmYXVsdFJlbGVhc2VCcmFuY2hdID8/XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuZGVmYXVsdFJlbGVhc2VCcmFuY2g7XG5cbiAgICAgICAgY29uc3Qgc3ludGhUYXNrID0gdGhpcy50YXNrcy50cnlGaW5kKFwic3ludGhcIik7XG4gICAgICAgIGlmIChzeW50aFRhc2spIHtcbiAgICAgICAgICAgIGNvbnN0IHsgZXhlYzogXywgLi4ucmVzdE9mU3RlcCB9ID0gc3ludGhUYXNrLnN0ZXBzWzBdO1xuICAgICAgICAgICAgc3ludGhUYXNrLnJlc2V0KFxuICAgICAgICAgICAgICAgIGBzc3QgYnVpbGQgLS1zdGFnZSAke2RlZmF1bHRTdGFnZU5hbWV9IC0tdG8gJHt0aGlzLnNzdENvbmZpZy5zc3RPdXR9YCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnJlc3RPZlN0ZXAsXG4gICAgICAgICAgICAgICAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3ludGhTaWxlbnRUYXNrID0gdGhpcy50YXNrcy50cnlGaW5kKFwic3ludGg6c2lsZW50XCIpO1xuICAgICAgICBpZiAoc3ludGhTaWxlbnRUYXNrKSB7XG4gICAgICAgICAgICBjb25zdCB7IGV4ZWM6IF8sIC4uLnJlc3RPZlN0ZXAgfSA9IHN5bnRoU2lsZW50VGFzay5zdGVwc1swXTtcbiAgICAgICAgICAgIHN5bnRoU2lsZW50VGFzay5yZXNldChcbiAgICAgICAgICAgICAgICBgc3N0IGJ1aWxkIC0tc3RhZ2UgJHtkZWZhdWx0U3RhZ2VOYW1lfSAtLXRvICR7dGhpcy5zc3RDb25maWcuc3N0T3V0fWAsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAuLi5yZXN0T2ZTdGVwLFxuICAgICAgICAgICAgICAgICAgICByZWNlaXZlQXJnczogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRlcGxveVRhc2sgPSB0aGlzLnRhc2tzLnRyeUZpbmQoXCJkZXBsb3lcIik7XG4gICAgICAgIGlmIChkZXBsb3lUYXNrKSB7XG4gICAgICAgICAgICBjb25zdCB7IGV4ZWM6IF8sIC4uLnJlc3RPZlN0ZXAgfSA9IGRlcGxveVRhc2suc3RlcHNbMF07XG4gICAgICAgICAgICBkZXBsb3lUYXNrLnJlc2V0KCk7XG4gICAgICAgICAgICBkZXBsb3lUYXNrLmV4ZWMoXG4gICAgICAgICAgICAgICAgYHNzdCBkZXBsb3kgLS1zdGFnZSAke2RlZmF1bHRTdGFnZU5hbWV9IC0tZnJvbSAke3RoaXMuc3N0Q29uZmlnLnNzdE91dH1gLFxuICAgICAgICAgICAgICAgIHsgLi4ucmVzdE9mU3RlcCwgcmVjZWl2ZUFyZ3M6IHRydWUgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXN0cm95VGFzayA9IHRoaXMudGFza3MudHJ5RmluZChcImRlc3Ryb3lcIik7XG4gICAgICAgIGlmIChkZXN0cm95VGFzaykge1xuICAgICAgICAgICAgY29uc3QgeyBleGVjOiBfLCAuLi5yZXN0T2ZTdGVwIH0gPSBkZXN0cm95VGFzay5zdGVwc1swXTtcbiAgICAgICAgICAgIGRlc3Ryb3lUYXNrLnJlc2V0KFxuICAgICAgICAgICAgICAgIGBzc3QgcmVtb3ZlIHNzdCBidWlsZCAtLXN0YWdlICR7ZGVmYXVsdFN0YWdlTmFtZX1gLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLi4ucmVzdE9mU3RlcCxcbiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVRhc2tzRm9yQnJhbmNoKGJyYW5jaE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBzdGFnZU5hbWUgPVxuICAgICAgICAgICAgdGhpcy5icmFuY2hOYW1lVG9Tc3RTdGFnZU1hcD8uW2JyYW5jaE5hbWVdID8/IGJyYW5jaE5hbWU7XG5cbiAgICAgICAgdGhpcy5hZGRUYXNrKGBzeW50aDoke3N0YWdlTmFtZX1gLCB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFN5bnRoICR7c3RhZ2VOYW1lfSBzdGFnZWAsXG4gICAgICAgICAgICBleGVjOiBgc3N0IGJ1aWxkIC0tc3RhZ2UgJHtzdGFnZU5hbWV9IC0tdG8gJHt0aGlzLnNzdENvbmZpZy5zc3RPdXR9YCxcbiAgICAgICAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmFkZFRhc2soYHN5bnRoOnNpbGVudDoke3N0YWdlTmFtZX1gLCB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFN5bnRoICR7c3RhZ2VOYW1lfSBzdGFnZWAsXG4gICAgICAgICAgICBleGVjOiBgc3N0IGJ1aWxkIC0tc3RhZ2UgJHtzdGFnZU5hbWV9IC0tdG8gJHt0aGlzLnNzdENvbmZpZy5zc3RPdXR9YCxcbiAgICAgICAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZXBsb3lUYXNrID0gdGhpcy5hZGRUYXNrKGBkZXBsb3k6JHtzdGFnZU5hbWV9YCwge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBEZXBsb3kgJHtzdGFnZU5hbWV9IHN0YWdlYCxcbiAgICAgICAgfSk7XG4gICAgICAgIGRlcGxveVRhc2suZXhlYyhcbiAgICAgICAgICAgIGBzc3QgZGVwbG95IC0tc3RhZ2UgJHtzdGFnZU5hbWV9IC0tZnJvbSAke3RoaXMuc3N0Q29uZmlnLnNzdE91dH1gLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZFRhc2soYGRlc3Ryb3k6JHtzdGFnZU5hbWV9YCwge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBEZXN0cm95ICR7c3RhZ2VOYW1lfSBzdGFnZWAsXG4gICAgICAgICAgICBleGVjOiBgc3N0IHJlbW92ZSBzc3QgYnVpbGQgLS1zdGFnZSAke3N0YWdlTmFtZX1gLFxuICAgICAgICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNzdFNhbXBsZUNvZGUgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKHByb2plY3Q6IFNzdFR5cGVzY3JpcHRBcHApIHtcbiAgICAgICAgc3VwZXIocHJvamVjdCk7XG5cbiAgICAgICAgdGhpcy5jcmVhdGVTc3RDb25maWdGaWxlKCk7XG4gICAgICAgIHRoaXMuY3JlYXRlU3RhY2tGaWxlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVTc3RDb25maWdGaWxlKCk6IHZvaWQge1xuICAgICAgICBuZXcgU2FtcGxlRmlsZSh0aGlzLnByb2plY3QsIFNTVF9DT05GSUdfRklMRV9OQU1FLCB7XG4gICAgICAgICAgICBjb250ZW50czogYGltcG9ydCB7IFNTVENvbmZpZyB9IGZyb20gXCJzc3RcIjtcbmltcG9ydCB7IE15U3RhY2sgfSBmcm9tIFwiLi9zdGFja3MvTXlTdGFja1wiO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGNvbmZpZyhfaW5wdXQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogXCJ0ZXN0LWNyZWF0ZS1zc3RcIixcbiAgICAgIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIixcbiAgICB9O1xuICB9LFxuICBzdGFja3MoYXBwKSB7XG4gICAgbmV3IE15U3RhY2soYXBwLCBcIk15U3RhY2tcIik7XG4gIH1cbn0gc2F0aXNmaWVzIFNTVENvbmZpZztcbmAsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlU3RhY2tGaWxlKCk6IHZvaWQge1xuICAgICAgICBuZXcgU2FtcGxlRGlyKHRoaXMucHJvamVjdCwgXCJzcmNcIiwge1xuICAgICAgICAgICAgZmlsZXM6IHtcbiAgICAgICAgICAgICAgICBcIk15U3RhY2sudHNcIjogYGltcG9ydCB7IEFwaSwgQXBwLCBTdGFjaywgU3RhY2tQcm9wcyB9IGZyb20gXCJzc3QvY29uc3RydWN0c1wiO1xuXG5leHBvcnQgY2xhc3MgTXlTdGFjayBleHRlbmRzIFN0YWNrIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZTogQXBwLCBpZDogc3RyaW5nLCBwcm9wcz86IFN0YWNrUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICAgICAgY29uc3QgYXBpID0gbmV3IEFwaSh0aGlzLCBcIk15QXBpXCIpO1xuXG4gICAgICAgIHRoaXMuYWRkT3V0cHV0cyh7XG4gICAgICAgICAgICBBcGlFbmRwb2ludDogYXBpLnVybCxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdfQ==