aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
244 lines • 38.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const os = require("os");
const path = require("path");
const cxapi = require("@aws-cdk/cx-api");
const fs = require("fs-extra");
const init_1 = require("../lib/init");
describe('constructs version', () => {
cliTest('create a TypeScript library project', async (workDir) => {
await (0, init_1.cliInit)({
type: 'lib',
language: 'typescript',
workDir,
});
// Check that package.json and lib/ got created in the current directory
expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, 'lib'))).toBeTruthy();
});
cliTest('create a TypeScript app project', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'typescript',
workDir,
});
// Check that package.json and bin/ got created in the current directory
expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
});
cliTest('create a JavaScript app project', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'javascript',
workDir,
});
// Check that package.json and bin/ got created in the current directory
expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, '.git'))).toBeTruthy();
});
cliTest('create a Java app project', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'java',
canUseNetwork: false,
generateOnly: true,
workDir,
});
expect(await fs.pathExists(path.join(workDir, 'pom.xml'))).toBeTruthy();
const pom = (await fs.readFile(path.join(workDir, 'pom.xml'), 'utf8')).split(/\r?\n/);
const matches = pom.map(line => line.match(/\<constructs\.version\>(.*)\<\/constructs\.version\>/))
.filter(l => l);
expect(matches.length).toEqual(1);
matches.forEach(m => {
const version = m && m[1];
expect(version).toMatch(/\[10\.[\d]+\.[\d]+,11\.0\.0\)/);
});
});
cliTest('create a .NET app project in csharp', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'csharp',
canUseNetwork: false,
generateOnly: true,
workDir,
});
const csprojFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.csproj'))[0];
const slnFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.sln'))[0];
expect(csprojFile).toBeDefined();
expect(slnFile).toBeDefined();
const csproj = (await fs.readFile(csprojFile, 'utf8')).split(/\r?\n/);
const sln = (await fs.readFile(slnFile, 'utf8')).split(/\r?\n/);
expect(csproj).toContainEqual(expect.stringMatching(/\<PackageReference Include="Constructs" Version="\[10\..*,11\..*\)"/));
expect(csproj).toContainEqual(expect.stringMatching(/\<TargetFramework>net6.0<\/TargetFramework>/));
expect(sln).toContainEqual(expect.stringMatching(/\"AwsCdkTest[a-zA-Z0-9]{6}\\AwsCdkTest[a-zA-Z0-9]{6}.csproj\"/));
});
cliTest('create a .NET app project in fsharp', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'fsharp',
canUseNetwork: false,
generateOnly: true,
workDir,
});
const fsprojFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.fsproj'))[0];
const slnFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.sln'))[0];
expect(fsprojFile).toBeDefined();
expect(slnFile).toBeDefined();
const fsproj = (await fs.readFile(fsprojFile, 'utf8')).split(/\r?\n/);
const sln = (await fs.readFile(slnFile, 'utf8')).split(/\r?\n/);
expect(fsproj).toContainEqual(expect.stringMatching(/\<PackageReference Include="Constructs" Version="\[10\..*,11\..*\)"/));
expect(fsproj).toContainEqual(expect.stringMatching(/\<TargetFramework>net6.0<\/TargetFramework>/));
expect(sln).toContainEqual(expect.stringMatching(/\"AwsCdkTest[a-zA-Z0-9]{6}\\AwsCdkTest[a-zA-Z0-9]{6}.fsproj\"/));
});
cliTestWithDirSpaces('csharp app with spaces', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'csharp',
canUseNetwork: false,
generateOnly: true,
workDir,
});
const csprojFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.csproj'))[0];
expect(csprojFile).toBeDefined();
const csproj = (await fs.readFile(csprojFile, 'utf8')).split(/\r?\n/);
expect(csproj).toContainEqual(expect.stringMatching(/\<PackageReference Include="Constructs" Version="\[10\..*,11\..*\)"/));
expect(csproj).toContainEqual(expect.stringMatching(/\<TargetFramework>net6.0<\/TargetFramework>/));
});
cliTestWithDirSpaces('fsharp app with spaces', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'fsharp',
canUseNetwork: false,
generateOnly: true,
workDir,
});
const fsprojFile = (await recursiveListFiles(workDir)).filter(f => f.endsWith('.fsproj'))[0];
expect(fsprojFile).toBeDefined();
const fsproj = (await fs.readFile(fsprojFile, 'utf8')).split(/\r?\n/);
expect(fsproj).toContainEqual(expect.stringMatching(/\<PackageReference Include="Constructs" Version="\[10\..*,11\..*\)"/));
expect(fsproj).toContainEqual(expect.stringMatching(/\<TargetFramework>net6.0<\/TargetFramework>/));
});
cliTest('create a Python app project', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'python',
canUseNetwork: false,
generateOnly: true,
workDir,
});
expect(await fs.pathExists(path.join(workDir, 'requirements.txt'))).toBeTruthy();
const setupPy = (await fs.readFile(path.join(workDir, 'requirements.txt'), 'utf8')).split(/\r?\n/);
// return RegExpMatchArray (result of line.match()) for every lines that match re.
const matches = setupPy.map(line => line.match(/^constructs(.*)/))
.filter(l => l);
expect(matches.length).toEqual(1);
matches.forEach(m => {
const version = m && m[1];
expect(version).toMatch(/>=10\.\d+\.\d,<11\.0\.0/);
});
});
cliTest('--generate-only should skip git init', async (workDir) => {
await (0, init_1.cliInit)({
type: 'app',
language: 'javascript',
canUseNetwork: false,
generateOnly: true,
workDir,
});
// Check that package.json and bin/ got created in the current directory
expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, '.git'))).toBeFalsy();
});
cliTest('git directory does not throw off the initer!', async (workDir) => {
fs.mkdirSync(path.join(workDir, '.git'));
await (0, init_1.cliInit)({
type: 'app',
language: 'typescript',
canUseNetwork: false,
workDir,
});
// Check that package.json and bin/ got created in the current directory
expect(await fs.pathExists(path.join(workDir, 'package.json'))).toBeTruthy();
expect(await fs.pathExists(path.join(workDir, 'bin'))).toBeTruthy();
});
test('verify "future flags" are added to cdk.json', async () => {
for (const templ of await (0, init_1.availableInitTemplates)()) {
for (const lang of templ.languages) {
await withTempDir(async (tmpDir) => {
await (0, init_1.cliInit)({
type: templ.name,
language: lang,
canUseNetwork: false,
generateOnly: true,
workDir: tmpDir,
});
// ok if template doesn't have a cdk.json file (e.g. the "lib" template)
if (!await fs.pathExists(path.join(tmpDir, 'cdk.json'))) {
return;
}
const config = await fs.readJson(path.join(tmpDir, 'cdk.json'));
const context = config.context || {};
for (const [key, actual] of Object.entries(context)) {
expect(key in cxapi.NEW_PROJECT_CONTEXT).toBeTruthy();
expect(cxapi.NEW_PROJECT_CONTEXT[key]).toEqual(actual);
}
// assert that expired future flags are not part of the cdk.json
Object.keys(context).forEach(k => {
expect(cxapi.CURRENT_VERSION_EXPIRED_FLAGS.includes(k)).toEqual(false);
});
});
}
}
},
// This is a lot to test, and it can be slow-ish, especially when ran with other tests.
30000);
});
test('when no version number is present (e.g., local development), the v2 templates are chosen by default', async () => {
expect((await (0, init_1.availableInitTemplates)()).length).toBeGreaterThan(0);
});
function cliTest(name, handler) {
test(name, () => withTempDir(handler));
}
async function withTempDir(cb) {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'aws-cdk-test'));
try {
await cb(tmpDir);
}
finally {
await fs.remove(tmpDir);
}
}
function cliTestWithDirSpaces(name, handler) {
test(name, () => withTempDirWithSpaces(handler));
}
async function withTempDirWithSpaces(cb) {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'aws-cdk-test with-space'));
try {
await cb(tmpDir);
}
finally {
await fs.remove(tmpDir);
}
}
/**
* List all files underneath dir
*/
async function recursiveListFiles(rdir) {
const ret = new Array();
await recurse(rdir);
return ret;
async function recurse(dir) {
for (const name of await fs.readdir(dir)) {
const fullPath = path.join(dir, name);
if ((await fs.stat(fullPath)).isDirectory()) {
await recurse(fullPath);
}
else {
ret.push(fullPath);
}
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW5pdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix5Q0FBeUM7QUFDekMsK0JBQStCO0FBQy9CLHNDQUE4RDtBQUU5RCxRQUFRLENBQUMsb0JBQW9CLEVBQUUsR0FBRyxFQUFFO0lBQ2xDLE9BQU8sQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDL0QsTUFBTSxJQUFBLGNBQU8sRUFBQztZQUNaLElBQUksRUFBRSxLQUFLO1lBQ1gsUUFBUSxFQUFFLFlBQVk7WUFDdEIsT0FBTztTQUNSLENBQUMsQ0FBQztRQUVILHdFQUF3RTtRQUN4RSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM3RSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN0RSxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDM0QsTUFBTSxJQUFBLGNBQU8sRUFBQztZQUNaLElBQUksRUFBRSxLQUFLO1lBQ1gsUUFBUSxFQUFFLFlBQVk7WUFDdEIsT0FBTztTQUNSLENBQUMsQ0FBQztRQUVILHdFQUF3RTtRQUN4RSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM3RSxNQUFNLENBQUMsTUFBTSxFQUFFLENB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LE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQixPQUFPLEdBQUcsQ0FBQztJQUVYLEtBQUssVUFBVSxPQUFPLENBQUMsR0FBVztRQUNoQyxLQUFLLE1BQU0sSUFBSSxJQUFJLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN4QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUU7Z0JBQzNDLE1BQU0sT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3pCO2lCQUFNO2dCQUNMLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDcEI7U0FDRjtJQUNILENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyBhdmFpbGFibGVJbml0VGVtcGxhdGVzLCBjbGlJbml0IH0gZnJvbSAnLi4vbGliL2luaXQnO1xuXG5kZXNjcmliZSgnY29uc3RydWN0cyB2ZXJzaW9uJywgKCkgPT4ge1xuICBjbGlUZXN0KCdjcmVhdGUgYSBUeXBlU2NyaXB0IGxpYnJhcnkgcHJvamVjdCcsIGFzeW5jICh3b3JrRGlyKSA9PiB7XG4gICAgYXdhaXQgY2xpSW5pdCh7XG4gICAgICB0eXBlOiAnbGliJyxcbiAgICAgIGxhbmd1YWdlOiAndHlwZXNjcmlwdCcsXG4gICAgICB3b3JrRGlyLFxuICAgIH0pO1xuXG4gICAgLy8gQ2hlY2sgdGhhdCBwYWNrYWdlLmpzb24gYW5kIGxpYi8gZ290IGNyZWF0ZWQgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICdwYWNrYWdlLmpzb24nKSkpLnRvQmVUcnV0aHkoKTtcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ2xpYicpKSkudG9CZVRydXRoeSgpO1xuICB9KTtcblxuICBjbGlUZXN0KCdjcmVhdGUgYSBUeXBlU2NyaXB0IGFwcCBwcm9qZWN0JywgYXN5bmMgKHdvcmtEaXIpID0+IHtcbiAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgIHR5cGU6ICdhcHAnLFxuICAgICAgbGFuZ3VhZ2U6ICd0eXBlc2NyaXB0JyxcbiAgICAgIHdvcmtEaXIsXG4gICAgfSk7XG5cbiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2UuanNvbiBhbmQgYmluLyBnb3QgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BhY2thZ2UuanNvbicpKSkudG9CZVRydXRoeSgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAnYmluJykpKS50b0JlVHJ1dGh5KCk7XG4gIH0pO1xuXG4gIGNsaVRlc3QoJ2NyZWF0ZSBhIEphdmFTY3JpcHQgYXBwIHByb2plY3QnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGF3YWl0IGNsaUluaXQoe1xuICAgICAgdHlwZTogJ2FwcCcsXG4gICAgICBsYW5ndWFnZTogJ2phdmFzY3JpcHQnLFxuICAgICAgd29ya0RpcixcbiAgICB9KTtcblxuICAgIC8vIENoZWNrIHRoYXQgcGFja2FnZS5qc29uIGFuZCBiaW4vIGdvdCBjcmVhdGVkIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeVxuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAncGFja2FnZS5qc29uJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICdiaW4nKSkpLnRvQmVUcnV0aHkoKTtcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJy5naXQnKSkpLnRvQmVUcnV0aHkoKTtcbiAgfSk7XG5cbiAgY2xpVGVzdCgnY3JlYXRlIGEgSmF2YSBhcHAgcHJvamVjdCcsIGFzeW5jICh3b3JrRGlyKSA9PiB7XG4gICAgYXdhaXQgY2xpSW5pdCh7XG4gICAgICB0eXBlOiAnYXBwJyxcbiAgICAgIGxhbmd1YWdlOiAnamF2YScsXG4gICAgICBjYW5Vc2VOZXR3b3JrOiBmYWxzZSxcbiAgICAgIGdlbmVyYXRlT25seTogdHJ1ZSxcbiAgICAgIHdvcmtEaXIsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BvbS54bWwnKSkpLnRvQmVUcnV0aHkoKTtcblxuICAgIGNvbnN0IHBvbSA9IChhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4od29ya0RpciwgJ3BvbS54bWwnKSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcbiAgICBjb25zdCBtYXRjaGVzID0gcG9tLm1hcChsaW5lID0+IGxpbmUubWF0Y2goL1xcPGNvbnN0cnVjdHNcXC52ZXJzaW9uXFw+KC4qKVxcPFxcL2NvbnN0cnVjdHNcXC52ZXJzaW9uXFw+LykpXG4gICAgICAuZmlsdGVyKGwgPT4gbCk7XG5cbiAgICBleHBlY3QobWF0Y2hlcy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgbWF0Y2hlcy5mb3JFYWNoKG0gPT4ge1xuICAgICAgY29uc3QgdmVyc2lvbiA9IG0gJiYgbVsxXTtcbiAgICAgIGV4cGVjdCh2ZXJzaW9uKS50b01hdGNoKC9cXFsxMFxcLltcXGRdK1xcLltcXGRdKywxMVxcLjBcXC4wXFwpLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNsaVRlc3QoJ2NyZWF0ZSBhIC5ORVQgYXBwIHByb2plY3QgaW4gY3NoYXJwJywgYXN5bmMgKHdvcmtEaXIpID0+IHtcbiAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgIHR5cGU6ICdhcHAnLFxuICAgICAgbGFuZ3VhZ2U6ICdjc2hhcnAnLFxuICAgICAgY2FuVXNlTmV0d29yazogZmFsc2UsXG4gICAgICBnZW5lcmF0ZU9ubHk6IHRydWUsXG4gICAgICB3b3JrRGlyLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY3Nwcm9qRmlsZSA9IChhd2FpdCByZWN1cnNpdmVMaXN0RmlsZXMod29ya0RpcikpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5jc3Byb2onKSlbMF07XG4gICAgY29uc3Qgc2xuRmlsZSA9IChhd2FpdCByZWN1cnNpdmVMaXN0RmlsZXMod29ya0RpcikpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5zbG4nKSlbMF07XG4gICAgZXhwZWN0KGNzcHJvakZpbGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgZXhwZWN0KHNsbkZpbGUpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICBjb25zdCBjc3Byb2ogPSAoYXdhaXQgZnMucmVhZEZpbGUoY3Nwcm9qRmlsZSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcbiAgICBjb25zdCBzbG4gPSAoYXdhaXQgZnMucmVhZEZpbGUoc2xuRmlsZSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcblxuICAgIGV4cGVjdChjc3Byb2opLnRvQ29udGFpbkVxdWFsKGV4cGVjdC5zdHJpbmdNYXRjaGluZygvXFw8UGFja2FnZVJlZmVyZW5jZSBJbmNsdWRlPVwiQ29uc3RydWN0c1wiIFZlcnNpb249XCJcXFsxMFxcLi4qLDExXFwuLipcXClcIi8pKTtcbiAgICBleHBlY3QoY3Nwcm9qKS50b0NvbnRhaW5FcXVhbChleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL1xcPFRhcmdldEZyYW1ld29yaz5uZXQ2LjA8XFwvVGFyZ2V0RnJhbWV3b3JrPi8pKTtcbiAgICBleHBlY3Qoc2xuKS50b0NvbnRhaW5FcXVhbChleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL1xcXCJBd3NDZGtUZXN0W2EtekEtWjAtOV17Nn1cXFxcQXdzQ2RrVGVzdFthLXpBLVowLTldezZ9LmNzcHJvalxcXCIvKSk7XG4gIH0pO1xuXG4gIGNsaVRlc3QoJ2NyZWF0ZSBhIC5ORVQgYXBwIHByb2plY3QgaW4gZnNoYXJwJywgYXN5bmMgKHdvcmtEaXIpID0+IHtcbiAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgIHR5cGU6ICdhcHAnLFxuICAgICAgbGFuZ3VhZ2U6ICdmc2hhcnAnLFxuICAgICAgY2FuVXNlTmV0d29yazogZmFsc2UsXG4gICAgICBnZW5lcmF0ZU9ubHk6IHRydWUsXG4gICAgICB3b3JrRGlyLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZnNwcm9qRmlsZSA9IChhd2FpdCByZWN1cnNpdmVMaXN0RmlsZXMod29ya0RpcikpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5mc3Byb2onKSlbMF07XG4gICAgY29uc3Qgc2xuRmlsZSA9IChhd2FpdCByZWN1cnNpdmVMaXN0RmlsZXMod29ya0RpcikpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5zbG4nKSlbMF07XG4gICAgZXhwZWN0KGZzcHJvakZpbGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgZXhwZWN0KHNsbkZpbGUpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICBjb25zdCBmc3Byb2ogPSAoYXdhaXQgZnMucmVhZEZpbGUoZnNwcm9qRmlsZSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcbiAgICBjb25zdCBzbG4gPSAoYXdhaXQgZnMucmVhZEZpbGUoc2xuRmlsZSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcblxuICAgIGV4cGVjdChmc3Byb2opLnRvQ29udGFpbkVxdWFsKGV4cGVjdC5zdHJpbmdNYXRjaGluZygvXFw8UGFja2FnZVJlZmVyZW5jZSBJbmNsdWRlPVwiQ29uc3RydWN0c1wiIFZlcnNpb249XCJcXFsxMFxcLi4qLDExXFwuLipcXClcIi8pKTtcbiAgICBleHBlY3QoZnNwcm9qKS50b0NvbnRhaW5FcXVhbChleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL1xcPFRhcmdldEZyYW1ld29yaz5uZXQ2LjA8XFwvVGFyZ2V0RnJhbWV3b3JrPi8pKTtcbiAgICBleHBlY3Qoc2xuKS50b0NvbnRhaW5FcXVhbChleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL1xcXCJBd3NDZGtUZXN0W2EtekEtWjAtOV17Nn1cXFxcQXdzQ2RrVGVzdFthLXpBLVowLTldezZ9LmZzcHJvalxcXCIvKSk7XG4gIH0pO1xuXG4gIGNsaVRlc3RXaXRoRGlyU3BhY2VzKCdjc2hhcnAgYXBwIHdpdGggc3BhY2VzJywgYXN5bmMgKHdvcmtEaXIpID0+IHtcbiAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgIHR5cGU6ICdhcHAnLFxuICAgICAgbGFuZ3VhZ2U6ICdjc2hhcnAnLFxuICAgICAgY2FuVXNlTmV0d29yazogZmFsc2UsXG4gICAgICBnZW5lcmF0ZU9ubHk6IHRydWUsXG4gICAgICB3b3JrRGlyLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY3Nwcm9qRmlsZSA9IChhd2FpdCByZWN1cnNpdmVMaXN0RmlsZXMod29ya0RpcikpLmZpbHRlcihmID0+IGYuZW5kc1dpdGgoJy5jc3Byb2onKSlbMF07XG4gICAgZXhwZWN0KGNzcHJvakZpbGUpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICBjb25zdCBjc3Byb2ogPSAoYXdhaXQgZnMucmVhZEZpbGUoY3Nwcm9qRmlsZSwgJ3V0ZjgnKSkuc3BsaXQoL1xccj9cXG4vKTtcblxuICAgIGV4cGVjdChjc3Byb2opLnRvQ29udGFpbkVxdWFsKGV4cGVjdC5zdHJpbmdNYXRjaGluZygvXFw8UGFja2FnZVJlZmVyZW5jZSBJbmNsdWRlPVwiQ29uc3RydWN0c1wiIFZlcnNpb249XCJcXFsxMFxcLi4qLDExXFwuLipcXClcIi8pKTtcbiAgICBleHBlY3QoY3Nwcm9qKS50b0NvbnRhaW5FcXVhbChleHBlY3Quc3RyaW5nTWF0Y2hpbmcoL1xcPFRhcmdldEZyYW1ld29yaz5uZXQ2LjA8XFwvVGFyZ2V0RnJhbWV3b3JrPi8pKTtcbiAgfSk7XG5cbiAgY2xpVGVzdFdpdGhEaXJTcGFjZXMoJ2ZzaGFycCBhcHAgd2l0aCBzcGFjZXMnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGF3YWl0IGNsaUluaXQoe1xuICAgICAgdHlwZTogJ2FwcCcsXG4gICAgICBsYW5ndWFnZTogJ2ZzaGFycCcsXG4gICAgICBjYW5Vc2VOZXR3b3JrOiBmYWxzZSxcbiAgICAgIGdlbmVyYXRlT25seTogdHJ1ZSxcbiAgICAgIHdvcmtEaXIsXG4gICAgfSk7XG5cbiAgICBjb25zdCBmc3Byb2pGaWxlID0gKGF3YWl0IHJlY3Vyc2l2ZUxpc3RGaWxlcyh3b3JrRGlyKSkuZmlsdGVyKGYgPT4gZi5lbmRzV2l0aCgnLmZzcHJvaicpKVswXTtcbiAgICBleHBlY3QoZnNwcm9qRmlsZSkudG9CZURlZmluZWQoKTtcblxuICAgIGNvbnN0IGZzcHJvaiA9IChhd2FpdCBmcy5yZWFkRmlsZShmc3Byb2pGaWxlLCAndXRmOCcpKS5zcGxpdCgvXFxyP1xcbi8pO1xuXG4gICAgZXhwZWN0KGZzcHJvaikudG9Db250YWluRXF1YWwoZXhwZWN0LnN0cmluZ01hdGNoaW5nKC9cXDxQYWNrYWdlUmVmZXJlbmNlIEluY2x1ZGU9XCJDb25zdHJ1Y3RzXCIgVmVyc2lvbj1cIlxcWzEwXFwuLiosMTFcXC4uKlxcKVwiLykpO1xuICAgIGV4cGVjdChmc3Byb2opLnRvQ29udGFpbkVxdWFsKGV4cGVjdC5zdHJpbmdNYXRjaGluZygvXFw8VGFyZ2V0RnJhbWV3b3JrPm5ldDYuMDxcXC9UYXJnZXRGcmFtZXdvcms+LykpO1xuICB9KTtcblxuICBjbGlUZXN0KCdjcmVhdGUgYSBQeXRob24gYXBwIHByb2plY3QnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGF3YWl0IGNsaUluaXQoe1xuICAgICAgdHlwZTogJ2FwcCcsXG4gICAgICBsYW5ndWFnZTogJ3B5dGhvbicsXG4gICAgICBjYW5Vc2VOZXR3b3JrOiBmYWxzZSxcbiAgICAgIGdlbmVyYXRlT25seTogdHJ1ZSxcbiAgICAgIHdvcmtEaXIsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3JlcXVpcmVtZW50cy50eHQnKSkpLnRvQmVUcnV0aHkoKTtcbiAgICBjb25zdCBzZXR1cFB5ID0gKGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbih3b3JrRGlyLCAncmVxdWlyZW1lbnRzLnR4dCcpLCAndXRmOCcpKS5zcGxpdCgvXFxyP1xcbi8pO1xuICAgIC8vIHJldHVybiBSZWdFeHBNYXRjaEFycmF5IChyZXN1bHQgb2YgbGluZS5tYXRjaCgpKSBmb3IgZXZlcnkgbGluZXMgdGhhdCBtYXRjaCByZS5cbiAgICBjb25zdCBtYXRjaGVzID0gc2V0dXBQeS5tYXAobGluZSA9PiBsaW5lLm1hdGNoKC9eY29uc3RydWN0cyguKikvKSlcbiAgICAgIC5maWx0ZXIobCA9PiBsKTtcblxuICAgIGV4cGVjdChtYXRjaGVzLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICBtYXRjaGVzLmZvckVhY2gobSA9PiB7XG4gICAgICBjb25zdCB2ZXJzaW9uID0gbSAmJiBtWzFdO1xuICAgICAgZXhwZWN0KHZlcnNpb24pLnRvTWF0Y2goLz49MTBcXC5cXGQrXFwuXFxkLDwxMVxcLjBcXC4wLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNsaVRlc3QoJy0tZ2VuZXJhdGUtb25seSBzaG91bGQgc2tpcCBnaXQgaW5pdCcsIGFzeW5jICh3b3JrRGlyKSA9PiB7XG4gICAgYXdhaXQgY2xpSW5pdCh7XG4gICAgICB0eXBlOiAnYXBwJyxcbiAgICAgIGxhbmd1YWdlOiAnamF2YXNjcmlwdCcsXG4gICAgICBjYW5Vc2VOZXR3b3JrOiBmYWxzZSxcbiAgICAgIGdlbmVyYXRlT25seTogdHJ1ZSxcbiAgICAgIHdvcmtEaXIsXG4gICAgfSk7XG5cbiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2UuanNvbiBhbmQgYmluLyBnb3QgY3JlYXRlZCBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnlcbiAgICBleHBlY3QoYXdhaXQgZnMucGF0aEV4aXN0cyhwYXRoLmpvaW4od29ya0RpciwgJ3BhY2thZ2UuanNvbicpKSkudG9CZVRydXRoeSgpO1xuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAnYmluJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICcuZ2l0JykpKS50b0JlRmFsc3koKTtcbiAgfSk7XG5cbiAgY2xpVGVzdCgnZ2l0IGRpcmVjdG9yeSBkb2VzIG5vdCB0aHJvdyBvZmYgdGhlIGluaXRlciEnLCBhc3luYyAod29ya0RpcikgPT4ge1xuICAgIGZzLm1rZGlyU3luYyhwYXRoLmpvaW4od29ya0RpciwgJy5naXQnKSk7XG5cbiAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgIHR5cGU6ICdhcHAnLFxuICAgICAgbGFuZ3VhZ2U6ICd0eXBlc2NyaXB0JyxcbiAgICAgIGNhblVzZU5ldHdvcms6IGZhbHNlLFxuICAgICAgd29ya0RpcixcbiAgICB9KTtcblxuICAgIC8vIENoZWNrIHRoYXQgcGFja2FnZS5qc29uIGFuZCBiaW4vIGdvdCBjcmVhdGVkIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeVxuICAgIGV4cGVjdChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih3b3JrRGlyLCAncGFja2FnZS5qc29uJykpKS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHdvcmtEaXIsICdiaW4nKSkpLnRvQmVUcnV0aHkoKTtcbiAgfSk7XG5cbiAgdGVzdCgndmVyaWZ5IFwiZnV0dXJlIGZsYWdzXCIgYXJlIGFkZGVkIHRvIGNkay5qc29uJywgYXN5bmMgKCkgPT4ge1xuXG4gICAgZm9yIChjb25zdCB0ZW1wbCBvZiBhd2FpdCBhdmFpbGFibGVJbml0VGVtcGxhdGVzKCkpIHtcbiAgICAgIGZvciAoY29uc3QgbGFuZyBvZiB0ZW1wbC5sYW5ndWFnZXMpIHtcbiAgICAgICAgYXdhaXQgd2l0aFRlbXBEaXIoYXN5bmMgdG1wRGlyID0+IHtcbiAgICAgICAgICBhd2FpdCBjbGlJbml0KHtcbiAgICAgICAgICAgIHR5cGU6IHRlbXBsLm5hbWUsXG4gICAgICAgICAgICBsYW5ndWFnZTogbGFuZyxcbiAgICAgICAgICAgIGNhblVzZU5ldHdvcms6IGZhbHNlLFxuICAgICAgICAgICAgZ2VuZXJhdGVPbmx5OiB0cnVlLFxuICAgICAgICAgICAgd29ya0RpcjogdG1wRGlyLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gb2sgaWYgdGVtcGxhdGUgZG9lc24ndCBoYXZlIGEgY2RrLmpzb24gZmlsZSAoZS5nLiB0aGUgXCJsaWJcIiB0ZW1wbGF0ZSlcbiAgICAgICAgICBpZiAoIWF3YWl0IGZzLnBhdGhFeGlzdHMocGF0aC5qb2luKHRtcERpciwgJ2Nkay5qc29uJykpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY29uZmlnID0gYXdhaXQgZnMucmVhZEpzb24ocGF0aC5qb2luKHRtcERpciwgJ2Nkay5qc29uJykpO1xuICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBjb25maWcuY29udGV4dCB8fCB7fTtcbiAgICAgICAgICBmb3IgKGNvbnN0IFtrZXksIGFjdHVhbF0gb2YgT2JqZWN0LmVudHJpZXMoY29udGV4dCkpIHtcbiAgICAgICAgICAgIGV4cGVjdChrZXkgaW4gY3hhcGkuTkVXX1BST0pFQ1RfQ09OVEVYVCkudG9CZVRydXRoeSgpO1xuICAgICAgICAgICAgZXhwZWN0KGN4YXBpLk5FV19QUk9KRUNUX0NPTlRFWFRba2V5XSkudG9FcXVhbChhY3R1YWwpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGFzc2VydCB0aGF0IGV4cGlyZWQgZnV0dXJlIGZsYWdzIGFyZSBub3QgcGFydCBvZiB0aGUgY2RrLmpzb25cbiAgICAgICAgICBPYmplY3Qua2V5cyhjb250ZXh0KS5mb3JFYWNoKGsgPT4ge1xuICAgICAgICAgICAgZXhwZWN0KGN4YXBpLkNVUlJFTlRfVkVSU0lPTl9FWFBJUkVEX0ZMQUdTLmluY2x1ZGVzKGspKS50b0VxdWFsKGZhbHNlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICAvLyBUaGlzIGlzIGEgbG90IHRvIHRlc3QsIGFuZCBpdCBjYW4gYmUgc2xvdy1pc2gsIGVzcGVjaWFsbHkgd2hlbiByYW4gd2l0aCBvdGhlciB0ZXN0cy5cbiAgMzBfMDAwKTtcbn0pO1xuXG50ZXN0KCd3aGVuIG5vIHZlcnNpb24gbnVtYmVyIGlzIHByZXNlbnQgKGUuZy4sIGxvY2FsIGRldmVsb3BtZW50KSwgdGhlIHYyIHRlbXBsYXRlcyBhcmUgY2hvc2VuIGJ5IGRlZmF1bHQnLCBhc3luYyAoKSA9PiB7XG4gIGV4cGVjdCgoYXdhaXQgYXZhaWxhYmxlSW5pdFRlbXBsYXRlcygpKS5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKTtcbn0pO1xuXG5mdW5jdGlvbiBjbGlUZXN0KG5hbWU6IHN0cmluZywgaGFuZGxlcjogKGRpcjogc3RyaW5nKSA9PiB2b2lkIHwgUHJvbWlzZTxhbnk+KTogdm9pZCB7XG4gIHRlc3QobmFtZSwgKCkgPT4gd2l0aFRlbXBEaXIoaGFuZGxlcikpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3aXRoVGVtcERpcihjYjogKGRpcjogc3RyaW5nKSA9PiB2b2lkIHwgUHJvbWlzZTxhbnk+KSB7XG4gIGNvbnN0IHRtcERpciA9IGF3YWl0IGZzLm1rZHRlbXAocGF0aC5qb2luKG9zLnRtcGRpcigpLCAnYXdzLWNkay10ZXN0JykpO1xuICB0cnkge1xuICAgIGF3YWl0IGNiKHRtcERpcik7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgZnMucmVtb3ZlKHRtcERpcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xpVGVzdFdpdGhEaXJTcGFjZXMobmFtZTogc3RyaW5nLCBoYW5kbGVyOiAoZGlyOiBzdHJpbmcpID0+IHZvaWQgfCBQcm9taXNlPGFueT4pOiB2b2lkIHtcbiAgdGVzdChuYW1lLCAoKSA9PiB3aXRoVGVtcERpcldpdGhTcGFjZXMoaGFuZGxlcikpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3aXRoVGVtcERpcldpdGhTcGFjZXMoY2I6IChkaXI6IHN0cmluZykgPT4gdm9pZCB8IFByb21pc2U8YW55Pikge1xuICBjb25zdCB0bXBEaXIgPSBhd2FpdCBmcy5ta2R0ZW1wKHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2F3cy1jZGstdGVzdCB3aXRoLXNwYWNlJykpO1xuICB0cnkge1xuICAgIGF3YWl0IGNiKHRtcERpcik7XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgZnMucmVtb3ZlKHRtcERpcik7XG4gIH1cbn1cblxuLyoqXG4gKiBMaXN0IGFsbCBmaWxlcyB1bmRlcm5lYXRoIGRpclxuICovXG5hc3luYyBmdW5jdGlvbiByZWN1cnNpdmVMaXN0RmlsZXMocmRpcjogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBjb25zdCByZXQgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuICBhd2FpdCByZWN1cnNlKHJkaXIpO1xuICByZXR1cm4gcmV0O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlY3Vyc2UoZGlyOiBzdHJpbmcpIHtcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgYXdhaXQgZnMucmVhZGRpcihkaXIpKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihkaXIsIG5hbWUpO1xuICAgICAgaWYgKChhd2FpdCBmcy5zdGF0KGZ1bGxQYXRoKSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBhd2FpdCByZWN1cnNlKGZ1bGxQYXRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldC5wdXNoKGZ1bGxQYXRoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==