@riddance/deploy
Version:
150 lines • 27 kB
JavaScript
import { missing } from '@riddance/fetch';
import { createPublicKey, generateKeyPairSync, randomBytes } from 'node:crypto';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
export async function getGlue(path, prefix, resolver, gluePath) {
const [packageJson, glueJson] = await Promise.all([
readFile(join(path, 'package.json'), 'utf-8'),
readFile(gluePath ?? join(path, '..', 'glue', 'glue.json'), 'utf-8'),
]);
const { name: service } = JSON.parse(packageJson);
const glue = JSON.parse(glueJson);
const { cors, env, secrets, ...provider } = glue.services[service] ?? {};
return {
service,
implementations: {
...glue.implementations,
},
corsSites: cors ? (glue.websites[cors] ?? []) : [],
env: resolveEnv(env ?? {}, secrets ?? {}, prefix, service, resolver),
...provider,
};
}
const own = Symbol();
const variables = [
{
pattern: /\$ENV/gu,
source: () => ({}),
value: prefix => prefix,
},
{
pattern: /\$SERVICE/gu,
source: () => ({}),
value: (_prefix, service) => service,
},
{
pattern: /\$PRIVATE_KEY\(([^)]+)\)/gu,
source: () => ({ environment: own }),
value: (_prefix, service, [_, curve], key, env) => env[service]?.[key] ??
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
generateKeyPairSync('ec', { namedCurve: curve })
.privateKey.export({ type: 'sec1', format: 'pem' })
.toString()
.split('\n')
.slice(1, -2)
.join(''),
},
{
pattern: /\$ASK\(([^)]*)\)/gu,
source: () => ({ environment: own }),
value: (_prefix, service, [_, hint], key, env, _url) => env[service]?.[key] ?? missing(`ASK implementation: ${hint}`),
},
{
pattern: /\$RANDOM\(([0-9]+)\)/gu,
source: () => ({ environment: own }),
value: (_prefix, service, [_, bits], key, env, _url) => env[service]?.[key] ?? randomBytes(Math.ceil(Number(bits) / 8)).toString('hex'),
},
{
pattern: /\$SAME_AS\(([^,]+),([^)]+)\)/gu,
source: match => ({ environment: match[1] }),
value: (_prefix, _service, [, service, key], _key, env, _url) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
env[service]?.[key] ??
variableError(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
`Variable ${key} for ${service} not found. Has it been deployed?`),
},
{
pattern: /\$PUBLIC_KEY\(([^,]+),([^)]+)\)/gu,
source: match => ({ environment: match[1] }),
value: (_prefix, _service, [, service, key], _key, env) => createPublicKey(`-----BEGIN EC PRIVATE KEY-----\n${
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
env[service]?.[key] ??
variableError(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
`Private key for ${service} not found. Has it been deployed?`)}\n-----END EC PRIVATE KEY-----\n`)
.export({ type: 'spki', format: 'pem' })
.toString()
.split('\n')
.slice(1, -2)
.join(''),
},
{
pattern: /\$BASE_URL\(([^)]+)\)/gu,
source: match => ({ baseUrl: match[1] }),
value: (_prefix, _service, [_, service], _key, _env, url) =>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
url[service] ??
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
variableError(`Base URL for ${service} not found. Has it been deployed?`),
},
];
function variableError(message) {
throw new Error(message);
}
async function resolveEnv(clear, secrets, prefix, service, resolver) {
const env = {
...clear,
...secrets,
};
const referencedEnvironments = [];
const referencedBaseUrls = [];
const selfReferencing = [];
for (const [key, value] of Object.entries(env)) {
for (const v of variables) {
for (const match of value.matchAll(v.pattern)) {
const source = v.source(match);
const sourceEnvName = source.environment === own ? service : source.environment;
if (sourceEnvName && !referencedEnvironments.includes(sourceEnvName)) {
if (source.environment === service) {
selfReferencing.push({ key, v, match });
}
else {
referencedEnvironments.push(sourceEnvName);
}
}
if (source.baseUrl && !referencedBaseUrls.includes(source.baseUrl)) {
referencedBaseUrls.push(source.baseUrl);
}
}
}
}
const [environments, baseUrls] = await Promise.all([
fetchEnvironments(prefix, referencedEnvironments, resolver),
fetchBaseUrls(prefix, referencedBaseUrls, resolver),
]);
for (const v of variables) {
for (const [key, value] of Object.entries(env)) {
env[key] = value.replaceAll(v.pattern, (substring, ...matches) => {
if (selfReferencing.some(r => r.key === key && r.v === v && r.match[0] === substring)) {
return substring;
}
return v.value(prefix, service, [substring, ...matches], key, environments, baseUrls);
});
}
}
for (const ref of selfReferencing) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
env[ref.key] = env[ref.key].replaceAll(ref.v.pattern, (substring, ...matches) => {
return ref.v.value(prefix, service, [substring, ...matches], ref.key, { [service]: env }, baseUrls);
});
}
return env;
}
async function fetchEnvironments(prefix, services, resolver) {
return Object.fromEntries(await Promise.all(services.map(async (s) => [s, await resolver.getEnvironment(prefix, s)])));
}
async function fetchBaseUrls(prefix, services, resolver) {
return Object.fromEntries(await Promise.all(services.map(async (s) => [s, await resolver.getBaseUrl(prefix, s)])));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2x1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdsdWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQy9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBT2hDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUFDLElBQVksRUFBRSxNQUFjLEVBQUUsUUFBa0IsRUFBRSxRQUFpQjtJQUM3RixNQUFNLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRSxPQUFPLENBQUM7UUFDN0MsUUFBUSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUUsT0FBTyxDQUFDO0tBQ3ZFLENBQUMsQ0FBQTtJQUNGLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQXFCLENBQUE7SUFDckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBa0IvQixDQUFBO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDeEUsT0FBTztRQUNILE9BQU87UUFDUCxlQUFlLEVBQUU7WUFDYixHQUFHLElBQUksQ0FBQyxlQUFlO1NBQzFCO1FB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QUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFVLENBQUMsQ0FDbEYsQ0FDSixDQUFBO0FBQ0wsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQUMsTUFBYyxFQUFFLFFBQWtCLEVBQUUsUUFBa0I7SUFDL0UsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUNyQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUMsQ0FBQyxFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFVLENBQUMsQ0FDOUUsQ0FDSixDQUFBO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1pc3NpbmcgfSBmcm9tICdAcmlkZGFuY2UvZmV0Y2gnXG5pbXBvcnQgeyBjcmVhdGVQdWJsaWNLZXksIGdlbmVyYXRlS2V5UGFpclN5bmMsIHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nXG5pbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnXG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJ1xuXG5leHBvcnQgdHlwZSBSZXNvbHZlciA9IHtcbiAgICBnZXRFbnZpcm9ubWVudChwcmVmaXg6IHN0cmluZywgc2VydmljZTogc3RyaW5nKTogUHJvbWlzZTx7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9PlxuICAgIGdldEJhc2VVcmwocHJlZml4OiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPlxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0R2x1ZShwYXRoOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nLCByZXNvbHZlcjogUmVzb2x2ZXIsIGdsdWVQYXRoPzogc3RyaW5nKSB7XG4gICAgY29uc3QgW3BhY2thZ2VKc29uLCBnbHVlSnNvbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHJlYWRGaWxlKGpvaW4ocGF0aCwgJ3BhY2thZ2UuanNvbicpLCAndXRmLTgnKSxcbiAgICAgICAgcmVhZEZpbGUoZ2x1ZVBhdGggPz8gam9pbihwYXRoLCAnLi4nLCAnZ2x1ZScsICdnbHVlLmpzb24nKSwgJ3V0Zi04JyksXG4gICAgXSlcbiAgICBjb25zdCB7IG5hbWU6IHNlcnZpY2UgfSA9IEpTT04ucGFyc2UocGFja2FnZUpzb24pIGFzIHsgbmFtZTogc3RyaW5nIH1cbiAgICBjb25zdCBnbHVlID0gSlNPTi5wYXJzZShnbHVlSnNvbikgYXMge1xuICAgICAgICBpbXBsZW1lbnRhdGlvbnM6IHtcbiAgICAgICAgICAgIFtpbnRlcmZhY2VQYWNrYWdlOiBzdHJpbmddOiB7XG4gICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb246IHN0cmluZ1xuICAgICAgICAgICAgICAgIHZlcnNpb246IHN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHdlYnNpdGVzOiB7XG4gICAgICAgICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXVxuICAgICAgICB9XG4gICAgICAgIHNlcnZpY2VzOiB7XG4gICAgICAgICAgICBba2V5OiBzdHJpbmddOiB7XG4gICAgICAgICAgICAgICAgY29ycz86IHN0cmluZ1xuICAgICAgICAgICAgICAgIGVudjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfVxuICAgICAgICAgICAgICAgIHNlY3JldHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbiAgICAgICAgICAgICAgICBbcHJvdmlkZXI6IHN0cmluZ106IHVua25vd25cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHsgY29ycywgZW52LCBzZWNyZXRzLCAuLi5wcm92aWRlciB9ID0gZ2x1ZS5zZXJ2aWNlc1tzZXJ2aWNlXSA/PyB7fVxuICAgIHJldHVybiB7XG4gICAgICAgIHNlcnZpY2UsXG4gICAgICAgIGltcGxlbWVudGF0aW9uczoge1xuICAgICAgICAgICAgLi4uZ2x1ZS5pbXBsZW1lbnRhdGlvbnMsXG4gICAgICAgIH0sXG4gICAgICAgIGNvcnNTaXRlczogY29ycyA/IChnbHVlLndlYnNpdGVzW2NvcnNdID8/IFtdKSA6IFtdLFxuICAgICAgICBlbnY6IHJlc29sdmVFbnYoZW52ID8/IHt9LCBzZWNyZXRzID8/IHt9LCBwcmVmaXgsIHNlcnZpY2UsIHJlc29sdmVyKSxcbiAgICAgICAgLi4ucHJvdmlkZXIsXG4gICAgfVxufVxuXG5jb25zdCBvd24gPSBTeW1ib2woKVxuXG50eXBlIFZhcmlhYmxlID0ge1xuICAgIHBhdHRlcm46IFJlZ0V4cFxuICAgIHNvdXJjZTogKG1hdGNoOiBSZWdFeHBNYXRjaEFycmF5KSA9PiB7XG4gICAgICAgIGVudmlyb25tZW50Pzogc3RyaW5nIHwgdHlwZW9mIG93blxuICAgICAgICBiYXNlVXJsPzogc3RyaW5nXG4gICAgfVxuICAgIHZhbHVlOiAoXG4gICAgICAgIHByZWZpeDogc3RyaW5nLFxuICAgICAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgICAgIG1hdGNoOiBSZWdFeHBNYXRjaEFycmF5LFxuICAgICAgICBrZXk6IHN0cmluZyxcbiAgICAgICAgZW52aXJvbm1lbnRzOiB7IFtzZXJ2aWNlOiBzdHJpbmddOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IH0sXG4gICAgICAgIGJhc2VVcmxzOiB7IFtzZXJ2aWNlOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQgfSxcbiAgICApID0+IHN0cmluZ1xufVxuXG5jb25zdCB2YXJpYWJsZXM6IFZhcmlhYmxlW10gPSBbXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkRU5WL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7fSksXG4gICAgICAgIHZhbHVlOiBwcmVmaXggPT4gcHJlZml4LFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkU0VSVklDRS9ndSxcbiAgICAgICAgc291cmNlOiAoKSA9PiAoe30pLFxuICAgICAgICB2YWx1ZTogKF9wcmVmaXgsIHNlcnZpY2UpID0+IHNlcnZpY2UsXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRQUklWQVRFX0tFWVxcKChbXildKylcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogKCkgPT4gKHsgZW52aXJvbm1lbnQ6IG93biB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBzZXJ2aWNlLCBbXywgY3VydmVdLCBrZXksIGVudikgPT5cbiAgICAgICAgICAgIGVudltzZXJ2aWNlXT8uW2tleV0gPz9cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICBnZW5lcmF0ZUtleVBhaXJTeW5jKCdlYycsIHsgbmFtZWRDdXJ2ZTogY3VydmUhIH0pXG4gICAgICAgICAgICAgICAgLnByaXZhdGVLZXkuZXhwb3J0KHsgdHlwZTogJ3NlYzEnLCBmb3JtYXQ6ICdwZW0nIH0pXG4gICAgICAgICAgICAgICAgLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgICAgICAgLnNsaWNlKDEsIC0yKVxuICAgICAgICAgICAgICAgIC5qb2luKCcnKSxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJEFTS1xcKChbXildKilcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogKCkgPT4gKHsgZW52aXJvbm1lbnQ6IG93biB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBzZXJ2aWNlLCBbXywgaGludF0sIGtleSwgZW52LCBfdXJsKSA9PlxuICAgICAgICAgICAgZW52W3NlcnZpY2VdPy5ba2V5XSA/PyBtaXNzaW5nKGBBU0sgaW1wbGVtZW50YXRpb246ICR7aGludH1gKSxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJFJBTkRPTVxcKChbMC05XSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7IGVudmlyb25tZW50OiBvd24gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgc2VydmljZSwgW18sIGJpdHNdLCBrZXksIGVudiwgX3VybCkgPT5cbiAgICAgICAgICAgIGVudltzZXJ2aWNlXT8uW2tleV0gPz8gcmFuZG9tQnl0ZXMoTWF0aC5jZWlsKE51bWJlcihiaXRzKSAvIDgpKS50b1N0cmluZygnaGV4JyksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRTQU1FX0FTXFwoKFteLF0rKSwoW14pXSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6IG1hdGNoID0+ICh7IGVudmlyb25tZW50OiBtYXRjaFsxXSB9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBfc2VydmljZSwgWywgc2VydmljZSwga2V5XSwgX2tleSwgZW52LCBfdXJsKSA9PlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIGVudltzZXJ2aWNlIV0/LltrZXkhXSA/P1xuICAgICAgICAgICAgdmFyaWFibGVFcnJvcihcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgIGBWYXJpYWJsZSAke2tleSF9IGZvciAke3NlcnZpY2UhfSBub3QgZm91bmQuIEhhcyBpdCBiZWVuIGRlcGxveWVkP2AsXG4gICAgICAgICAgICApLFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkUFVCTElDX0tFWVxcKChbXixdKyksKFteKV0rKVxcKS9ndSxcbiAgICAgICAgc291cmNlOiBtYXRjaCA9PiAoeyBlbnZpcm9ubWVudDogbWF0Y2hbMV0gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgX3NlcnZpY2UsIFssIHNlcnZpY2UsIGtleV0sIF9rZXksIGVudikgPT5cbiAgICAgICAgICAgIGNyZWF0ZVB1YmxpY0tleShcbiAgICAgICAgICAgICAgICBgLS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tXFxuJHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgICAgICAgICAgZW52W3NlcnZpY2UhXT8uW2tleSFdID8/XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgYFByaXZhdGUga2V5IGZvciAke3NlcnZpY2UhfSBub3QgZm91bmQuIEhhcyBpdCBiZWVuIGRlcGxveWVkP2AsXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XFxuLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLVxcbmAsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLmV4cG9ydCh7IHR5cGU6ICdzcGtpJywgZm9ybWF0OiAncGVtJyB9KVxuICAgICAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgICAgIC5zbGljZSgxLCAtMilcbiAgICAgICAgICAgICAgICAuam9pbignJyksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRCQVNFX1VSTFxcKChbXildKylcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogbWF0Y2ggPT4gKHsgYmFzZVVybDogbWF0Y2hbMV0gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgX3NlcnZpY2UsIFtfLCBzZXJ2aWNlXSwgX2tleSwgX2VudiwgdXJsKSA9PlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIHVybFtzZXJ2aWNlIV0gPz9cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB2YXJpYWJsZUVycm9yKGBCYXNlIFVSTCBmb3IgJHtzZXJ2aWNlIX0gbm90IGZvdW5kLiBIYXMgaXQgYmVlbiBkZXBsb3llZD9gKSxcbiAgICB9LFxuXVxuXG5mdW5jdGlvbiB2YXJpYWJsZUVycm9yKG1lc3NhZ2U6IHN0cmluZyk6IG5ldmVyIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSlcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUVudihcbiAgICBjbGVhcjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgICBzZWNyZXRzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICByZXNvbHZlcjogUmVzb2x2ZXIsXG4pIHtcbiAgICBjb25zdCBlbnYgPSB7XG4gICAgICAgIC4uLmNsZWFyLFxuICAgICAgICAuLi5zZWNyZXRzLFxuICAgIH1cbiAgICBjb25zdCByZWZlcmVuY2VkRW52aXJvbm1lbnRzOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3QgcmVmZXJlbmNlZEJhc2VVcmxzOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3Qgc2VsZlJlZmVyZW5jaW5nOiB7IGtleTogc3RyaW5nOyB2OiBWYXJpYWJsZTsgbWF0Y2g6IFJlZ0V4cE1hdGNoQXJyYXkgfVtdID0gW11cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICAgIGZvciAoY29uc3QgdiBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgdmFsdWUubWF0Y2hBbGwodi5wYXR0ZXJuKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHYuc291cmNlKG1hdGNoKVxuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVudk5hbWUgPSBzb3VyY2UuZW52aXJvbm1lbnQgPT09IG93biA/IHNlcnZpY2UgOiBzb3VyY2UuZW52aXJvbm1lbnRcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlRW52TmFtZSAmJiAhcmVmZXJlbmNlZEVudmlyb25tZW50cy5pbmNsdWRlcyhzb3VyY2VFbnZOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmVudmlyb25tZW50ID09PSBzZXJ2aWNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmUmVmZXJlbmNpbmcucHVzaCh7IGtleSwgdiwgbWF0Y2ggfSlcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZWRFbnZpcm9ubWVudHMucHVzaChzb3VyY2VFbnZOYW1lKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuYmFzZVVybCAmJiAhcmVmZXJlbmNlZEJhc2VVcmxzLmluY2x1ZGVzKHNvdXJjZS5iYXNlVXJsKSkge1xuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VkQmFzZVVybHMucHVzaChzb3VyY2UuYmFzZVVybClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgW2Vudmlyb25tZW50cywgYmFzZVVybHNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBmZXRjaEVudmlyb25tZW50cyhwcmVmaXgsIHJlZmVyZW5jZWRFbnZpcm9ubWVudHMsIHJlc29sdmVyKSxcbiAgICAgICAgZmV0Y2hCYXNlVXJscyhwcmVmaXgsIHJlZmVyZW5jZWRCYXNlVXJscywgcmVzb2x2ZXIpLFxuICAgIF0pXG4gICAgZm9yIChjb25zdCB2IG9mIHZhcmlhYmxlcykge1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICAgICAgICBlbnZba2V5XSA9IHZhbHVlLnJlcGxhY2VBbGwodi5wYXR0ZXJuLCAoc3Vic3RyaW5nLCAuLi5tYXRjaGVzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgc2VsZlJlZmVyZW5jaW5nLnNvbWUoXG4gICAgICAgICAgICAgICAgICAgICAgICByID0+IHIua2V5ID09PSBrZXkgJiYgci52ID09PSB2ICYmIHIubWF0Y2hbMF0gPT09IHN1YnN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3Vic3RyaW5nXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB2LnZhbHVlKFxuICAgICAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIHNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgIFtzdWJzdHJpbmcsIC4uLm1hdGNoZXNdLFxuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50cyxcbiAgICAgICAgICAgICAgICAgICAgYmFzZVVybHMsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgcmVmIG9mIHNlbGZSZWZlcmVuY2luZykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICBlbnZbcmVmLmtleV0gPSBlbnZbcmVmLmtleV0hLnJlcGxhY2VBbGwoXG4gICAgICAgICAgICByZWYudi5wYXR0ZXJuLFxuICAgICAgICAgICAgKHN1YnN0cmluZywgLi4ubWF0Y2hlczogc3RyaW5nW10pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVmLnYudmFsdWUoXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCxcbiAgICAgICAgICAgICAgICAgICAgc2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgW3N1YnN0cmluZywgLi4ubWF0Y2hlc10sXG4gICAgICAgICAgICAgICAgICAgIHJlZi5rZXksXG4gICAgICAgICAgICAgICAgICAgIHsgW3NlcnZpY2VdOiBlbnYgfSxcbiAgICAgICAgICAgICAgICAgICAgYmFzZVVybHMsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgKVxuICAgIH1cblxuICAgIHJldHVybiBlbnZcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hFbnZpcm9ubWVudHMocHJlZml4OiBzdHJpbmcsIHNlcnZpY2VzOiBzdHJpbmdbXSwgcmVzb2x2ZXI6IFJlc29sdmVyKSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBzZXJ2aWNlcy5tYXAoYXN5bmMgcyA9PiBbcywgYXdhaXQgcmVzb2x2ZXIuZ2V0RW52aXJvbm1lbnQocHJlZml4LCBzKV0gYXMgY29uc3QpLFxuICAgICAgICApLFxuICAgIClcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hCYXNlVXJscyhwcmVmaXg6IHN0cmluZywgc2VydmljZXM6IHN0cmluZ1tdLCByZXNvbHZlcjogUmVzb2x2ZXIpIHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIHNlcnZpY2VzLm1hcChhc3luYyBzID0+IFtzLCBhd2FpdCByZXNvbHZlci5nZXRCYXNlVXJsKHByZWZpeCwgcyldIGFzIGNvbnN0KSxcbiAgICAgICAgKSxcbiAgICApXG59XG4iXX0=