UNPKG

@riddance/deploy

Version:

152 lines 27.5 kB
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 { publish, cors, env, secrets, implementations, ...provider } = glue.services[service] ?? {}; return { service, implementations: { ...glue.implementations, ...implementations, }, publishTopics: publish ?? [], 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2x1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdsdWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQy9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBT2hDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUFDLElBQVksRUFBRSxNQUFjLEVBQUUsUUFBa0IsRUFBRSxRQUFpQjtJQUM3RixNQUFNLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRSxPQUFPLENBQUM7UUFDN0MsUUFBUSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUUsT0FBTyxDQUFDO0tBQ3ZFLENBQUMsQ0FBQTtJQUNGLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQXFCLENBQUE7SUFDckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBZS9CLENBQUE7SUFFRCxNQUFNLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxHQUFHLFFBQVEsRUFBRSxHQUMvRCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUNoQyxPQUFPO1FBQ0gsT0FBTztRQUNQLGVBQWUsRUFBRTtZQUNiLEdBQUcsSUFB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TUFBTSxPQUFPLENBQUMsR0FBRyxDQUNiLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBVSxDQUFDLENBQ2xGLENBQ0osQ0FBQTtBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsYUFBYSxDQUFDLE1BQWMsRUFBRSxRQUFrQixFQUFFLFFBQWtCO0lBQy9FLE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FDckIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNiLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBVSxDQUFDLENBQzlFLENBQ0osQ0FBQTtBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBtaXNzaW5nIH0gZnJvbSAnQHJpZGRhbmNlL2ZldGNoJ1xuaW1wb3J0IHsgY3JlYXRlUHVibGljS2V5LCBnZW5lcmF0ZUtleVBhaXJTeW5jLCByYW5kb21CeXRlcyB9IGZyb20gJ25vZGU6Y3J5cHRvJ1xuaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJ1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCdcblxuZXhwb3J0IHR5cGUgUmVzb2x2ZXIgPSB7XG4gICAgZ2V0RW52aXJvbm1lbnQocHJlZml4OiBzdHJpbmcsIHNlcnZpY2U6IHN0cmluZyk6IFByb21pc2U8eyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfT5cbiAgICBnZXRCYXNlVXJsKHByZWZpeDogc3RyaW5nLCBzZXJ2aWNlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD5cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEdsdWUocGF0aDogc3RyaW5nLCBwcmVmaXg6IHN0cmluZywgcmVzb2x2ZXI6IFJlc29sdmVyLCBnbHVlUGF0aD86IHN0cmluZykge1xuICAgIGNvbnN0IFtwYWNrYWdlSnNvbiwgZ2x1ZUpzb25dID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICByZWFkRmlsZShqb2luKHBhdGgsICdwYWNrYWdlLmpzb24nKSwgJ3V0Zi04JyksXG4gICAgICAgIHJlYWRGaWxlKGdsdWVQYXRoID8/IGpvaW4ocGF0aCwgJy4uJywgJ2dsdWUnLCAnZ2x1ZS5qc29uJyksICd1dGYtOCcpLFxuICAgIF0pXG4gICAgY29uc3QgeyBuYW1lOiBzZXJ2aWNlIH0gPSBKU09OLnBhcnNlKHBhY2thZ2VKc29uKSBhcyB7IG5hbWU6IHN0cmluZyB9XG4gICAgY29uc3QgZ2x1ZSA9IEpTT04ucGFyc2UoZ2x1ZUpzb24pIGFzIHtcbiAgICAgICAgaW1wbGVtZW50YXRpb25zOiBJbXBsZW1lbnRhdGlvbnNcbiAgICAgICAgd2Vic2l0ZXM6IHtcbiAgICAgICAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1tdXG4gICAgICAgIH1cbiAgICAgICAgc2VydmljZXM6IHtcbiAgICAgICAgICAgIFtrZXk6IHN0cmluZ106IHtcbiAgICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbnM6IEltcGxlbWVudGF0aW9uc1xuICAgICAgICAgICAgICAgIHB1Ymxpc2g/OiBzdHJpbmdbXVxuICAgICAgICAgICAgICAgIGNvcnM/OiBzdHJpbmdcbiAgICAgICAgICAgICAgICBlbnY6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbiAgICAgICAgICAgICAgICBzZWNyZXRzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9XG4gICAgICAgICAgICAgICAgW3Byb3ZpZGVyOiBzdHJpbmddOiB1bmtub3duXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB7IHB1Ymxpc2gsIGNvcnMsIGVudiwgc2VjcmV0cywgaW1wbGVtZW50YXRpb25zLCAuLi5wcm92aWRlciB9ID1cbiAgICAgICAgZ2x1ZS5zZXJ2aWNlc1tzZXJ2aWNlXSA/PyB7fVxuICAgIHJldHVybiB7XG4gICAgICAgIHNlcnZpY2UsXG4gICAgICAgIGltcGxlbWVudGF0aW9uczoge1xuICAgICAgICAgICAgLi4uZ2x1ZS5pbXBsZW1lbnRhdGlvbnMsXG4gICAgICAgICAgICAuLi5pbXBsZW1lbnRhdGlvbnMsXG4gICAgICAgIH0sXG4gICAgICAgIHB1Ymxpc2hUb3BpY3M6IHB1Ymxpc2ggPz8gW10sXG4gICAgICAgIGNvcnNTaXRlczogY29ycyA/IChnbHVlLndlYnNpdGVzW2NvcnNdID8/IFtdKSA6IFtdLFxuICAgICAgICBlbnY6IHJlc29sdmVFbnYoZW52ID8/IHt9LCBzZWNyZXRzID8/IHt9LCBwcmVmaXgsIHNlcnZpY2UsIHJlc29sdmVyKSxcbiAgICAgICAgLi4ucHJvdmlkZXIsXG4gICAgfVxufVxuXG50eXBlIEltcGxlbWVudGF0aW9ucyA9IHtcbiAgICBbaW50ZXJmYWNlUGFja2FnZTogc3RyaW5nXToge1xuICAgICAgICBpbXBsZW1lbnRhdGlvbjogc3RyaW5nXG4gICAgICAgIHZlcnNpb246IHN0cmluZ1xuICAgIH1cbn1cblxuY29uc3Qgb3duID0gU3ltYm9sKClcblxudHlwZSBWYXJpYWJsZSA9IHtcbiAgICBwYXR0ZXJuOiBSZWdFeHBcbiAgICBzb3VyY2U6IChtYXRjaDogUmVnRXhwTWF0Y2hBcnJheSkgPT4ge1xuICAgICAgICBlbnZpcm9ubWVudD86IHN0cmluZyB8IHR5cGVvZiBvd25cbiAgICAgICAgYmFzZVVybD86IHN0cmluZ1xuICAgIH1cbiAgICB2YWx1ZTogKFxuICAgICAgICBwcmVmaXg6IHN0cmluZyxcbiAgICAgICAgc2VydmljZTogc3RyaW5nLFxuICAgICAgICBtYXRjaDogUmVnRXhwTWF0Y2hBcnJheSxcbiAgICAgICAga2V5OiBzdHJpbmcsXG4gICAgICAgIGVudmlyb25tZW50czogeyBbc2VydmljZTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB9LFxuICAgICAgICBiYXNlVXJsczogeyBbc2VydmljZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkIH0sXG4gICAgKSA9PiBzdHJpbmdcbn1cblxuY29uc3QgdmFyaWFibGVzOiBWYXJpYWJsZVtdID0gW1xuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJEVOVi9ndSxcbiAgICAgICAgc291cmNlOiAoKSA9PiAoe30pLFxuICAgICAgICB2YWx1ZTogcHJlZml4ID0+IHByZWZpeCxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJFNFUlZJQ0UvZ3UsXG4gICAgICAgIHNvdXJjZTogKCkgPT4gKHt9KSxcbiAgICAgICAgdmFsdWU6IChfcHJlZml4LCBzZXJ2aWNlKSA9PiBzZXJ2aWNlLFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkUFJJVkFURV9LRVlcXCgoW14pXSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7IGVudmlyb25tZW50OiBvd24gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgc2VydmljZSwgW18sIGN1cnZlXSwga2V5LCBlbnYpID0+XG4gICAgICAgICAgICBlbnZbc2VydmljZV0/LltrZXldID8/XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgZ2VuZXJhdGVLZXlQYWlyU3luYygnZWMnLCB7IG5hbWVkQ3VydmU6IGN1cnZlISB9KVxuICAgICAgICAgICAgICAgIC5wcml2YXRlS2V5LmV4cG9ydCh7IHR5cGU6ICdzZWMxJywgZm9ybWF0OiAncGVtJyB9KVxuICAgICAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgICAgICAgIC5zbGljZSgxLCAtMilcbiAgICAgICAgICAgICAgICAuam9pbignJyksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRBU0tcXCgoW14pXSopXFwpL2d1LFxuICAgICAgICBzb3VyY2U6ICgpID0+ICh7IGVudmlyb25tZW50OiBvd24gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgc2VydmljZSwgW18sIGhpbnRdLCBrZXksIGVudiwgX3VybCkgPT5cbiAgICAgICAgICAgIGVudltzZXJ2aWNlXT8uW2tleV0gPz8gbWlzc2luZyhgQVNLIGltcGxlbWVudGF0aW9uOiAke2hpbnR9YCksXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdHRlcm46IC9cXCRSQU5ET01cXCgoWzAtOV0rKVxcKS9ndSxcbiAgICAgICAgc291cmNlOiAoKSA9PiAoeyBlbnZpcm9ubWVudDogb3duIH0pLFxuICAgICAgICB2YWx1ZTogKF9wcmVmaXgsIHNlcnZpY2UsIFtfLCBiaXRzXSwga2V5LCBlbnYsIF91cmwpID0+XG4gICAgICAgICAgICBlbnZbc2VydmljZV0/LltrZXldID8/IHJhbmRvbUJ5dGVzKE1hdGguY2VpbChOdW1iZXIoYml0cykgLyA4KSkudG9TdHJpbmcoJ2hleCcpLFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkU0FNRV9BU1xcKChbXixdKyksKFteKV0rKVxcKS9ndSxcbiAgICAgICAgc291cmNlOiBtYXRjaCA9PiAoeyBlbnZpcm9ubWVudDogbWF0Y2hbMV0gfSksXG4gICAgICAgIHZhbHVlOiAoX3ByZWZpeCwgX3NlcnZpY2UsIFssIHNlcnZpY2UsIGtleV0sIF9rZXksIGVudiwgX3VybCkgPT5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICBlbnZbc2VydmljZSFdPy5ba2V5IV0gPz9cbiAgICAgICAgICAgIHZhcmlhYmxlRXJyb3IoXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgICAgICBgVmFyaWFibGUgJHtrZXkhfSBmb3IgJHtzZXJ2aWNlIX0gbm90IGZvdW5kLiBIYXMgaXQgYmVlbiBkZXBsb3llZD9gLFxuICAgICAgICAgICAgKSxcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0dGVybjogL1xcJFBVQkxJQ19LRVlcXCgoW14sXSspLChbXildKylcXCkvZ3UsXG4gICAgICAgIHNvdXJjZTogbWF0Y2ggPT4gKHsgZW52aXJvbm1lbnQ6IG1hdGNoWzFdIH0pLFxuICAgICAgICB2YWx1ZTogKF9wcmVmaXgsIF9zZXJ2aWNlLCBbLCBzZXJ2aWNlLCBrZXldLCBfa2V5LCBlbnYpID0+XG4gICAgICAgICAgICBjcmVhdGVQdWJsaWNLZXkoXG4gICAgICAgICAgICAgICAgYC0tLS0tQkVHSU4gRUMgUFJJVkFURSBLRVktLS0tLVxcbiR7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICAgICAgICAgIGVudltzZXJ2aWNlIV0/LltrZXkhXSA/P1xuICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGBQcml2YXRlIGtleSBmb3IgJHtzZXJ2aWNlIX0gbm90IGZvdW5kLiBIYXMgaXQgYmVlbiBkZXBsb3llZD9gLFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgfVxcbi0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS1cXG5gLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5leHBvcnQoeyB0eXBlOiAnc3BraScsIGZvcm1hdDogJ3BlbScgfSlcbiAgICAgICAgICAgICAgICAudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnXFxuJylcbiAgICAgICAgICAgICAgICAuc2xpY2UoMSwgLTIpXG4gICAgICAgICAgICAgICAgLmpvaW4oJycpLFxuICAgIH0sXG4gICAge1xuICAgICAgICBwYXR0ZXJuOiAvXFwkQkFTRV9VUkxcXCgoW14pXSspXFwpL2d1LFxuICAgICAgICBzb3VyY2U6IG1hdGNoID0+ICh7IGJhc2VVcmw6IG1hdGNoWzFdIH0pLFxuICAgICAgICB2YWx1ZTogKF9wcmVmaXgsIF9zZXJ2aWNlLCBbXywgc2VydmljZV0sIF9rZXksIF9lbnYsIHVybCkgPT5cbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB1cmxbc2VydmljZSFdID8/XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgdmFyaWFibGVFcnJvcihgQmFzZSBVUkwgZm9yICR7c2VydmljZSF9IG5vdCBmb3VuZC4gSGFzIGl0IGJlZW4gZGVwbG95ZWQ/YCksXG4gICAgfSxcbl1cblxuZnVuY3Rpb24gdmFyaWFibGVFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBuZXZlciB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVFbnYoXG4gICAgY2xlYXI6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICAgc2VjcmV0czogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgcmVzb2x2ZXI6IFJlc29sdmVyLFxuKSB7XG4gICAgY29uc3QgZW52ID0ge1xuICAgICAgICAuLi5jbGVhcixcbiAgICAgICAgLi4uc2VjcmV0cyxcbiAgICB9XG4gICAgY29uc3QgcmVmZXJlbmNlZEVudmlyb25tZW50czogc3RyaW5nW10gPSBbXVxuICAgIGNvbnN0IHJlZmVyZW5jZWRCYXNlVXJsczogc3RyaW5nW10gPSBbXVxuICAgIGNvbnN0IHNlbGZSZWZlcmVuY2luZzogeyBrZXk6IHN0cmluZzsgdjogVmFyaWFibGU7IG1hdGNoOiBSZWdFeHBNYXRjaEFycmF5IH1bXSA9IFtdXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZW52KSkge1xuICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIHZhbHVlLm1hdGNoQWxsKHYucGF0dGVybikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSB2LnNvdXJjZShtYXRjaClcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbnZOYW1lID0gc291cmNlLmVudmlyb25tZW50ID09PSBvd24gPyBzZXJ2aWNlIDogc291cmNlLmVudmlyb25tZW50XG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZUVudk5hbWUgJiYgIXJlZmVyZW5jZWRFbnZpcm9ubWVudHMuaW5jbHVkZXMoc291cmNlRW52TmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5lbnZpcm9ubWVudCA9PT0gc2VydmljZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZlJlZmVyZW5jaW5nLnB1c2goeyBrZXksIHYsIG1hdGNoIH0pXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VkRW52aXJvbm1lbnRzLnB1c2goc291cmNlRW52TmFtZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmJhc2VVcmwgJiYgIXJlZmVyZW5jZWRCYXNlVXJscy5pbmNsdWRlcyhzb3VyY2UuYmFzZVVybCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlZEJhc2VVcmxzLnB1c2goc291cmNlLmJhc2VVcmwpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IFtlbnZpcm9ubWVudHMsIGJhc2VVcmxzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZmV0Y2hFbnZpcm9ubWVudHMocHJlZml4LCByZWZlcmVuY2VkRW52aXJvbm1lbnRzLCByZXNvbHZlciksXG4gICAgICAgIGZldGNoQmFzZVVybHMocHJlZml4LCByZWZlcmVuY2VkQmFzZVVybHMsIHJlc29sdmVyKSxcbiAgICBdKVxuICAgIGZvciAoY29uc3QgdiBvZiB2YXJpYWJsZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZW52KSkge1xuICAgICAgICAgICAgZW52W2tleV0gPSB2YWx1ZS5yZXBsYWNlQWxsKHYucGF0dGVybiwgKHN1YnN0cmluZywgLi4ubWF0Y2hlczogc3RyaW5nW10pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHNlbGZSZWZlcmVuY2luZy5zb21lKFxuICAgICAgICAgICAgICAgICAgICAgICAgciA9PiByLmtleSA9PT0ga2V5ICYmIHIudiA9PT0gdiAmJiByLm1hdGNoWzBdID09PSBzdWJzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnN0cmluZ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdi52YWx1ZShcbiAgICAgICAgICAgICAgICAgICAgcHJlZml4LFxuICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICBbc3Vic3RyaW5nLCAuLi5tYXRjaGVzXSxcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudHMsXG4gICAgICAgICAgICAgICAgICAgIGJhc2VVcmxzLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlZiBvZiBzZWxmUmVmZXJlbmNpbmcpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgZW52W3JlZi5rZXldID0gZW52W3JlZi5rZXldIS5yZXBsYWNlQWxsKFxuICAgICAgICAgICAgcmVmLnYucGF0dGVybixcbiAgICAgICAgICAgIChzdWJzdHJpbmcsIC4uLm1hdGNoZXM6IHN0cmluZ1tdKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlZi52LnZhbHVlKFxuICAgICAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIHNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgIFtzdWJzdHJpbmcsIC4uLm1hdGNoZXNdLFxuICAgICAgICAgICAgICAgICAgICByZWYua2V5LFxuICAgICAgICAgICAgICAgICAgICB7IFtzZXJ2aWNlXTogZW52IH0sXG4gICAgICAgICAgICAgICAgICAgIGJhc2VVcmxzLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0sXG4gICAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gZW52XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoRW52aXJvbm1lbnRzKHByZWZpeDogc3RyaW5nLCBzZXJ2aWNlczogc3RyaW5nW10sIHJlc29sdmVyOiBSZXNvbHZlcikge1xuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgc2VydmljZXMubWFwKGFzeW5jIHMgPT4gW3MsIGF3YWl0IHJlc29sdmVyLmdldEVudmlyb25tZW50KHByZWZpeCwgcyldIGFzIGNvbnN0KSxcbiAgICAgICAgKSxcbiAgICApXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoQmFzZVVybHMocHJlZml4OiBzdHJpbmcsIHNlcnZpY2VzOiBzdHJpbmdbXSwgcmVzb2x2ZXI6IFJlc29sdmVyKSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBzZXJ2aWNlcy5tYXAoYXN5bmMgcyA9PiBbcywgYXdhaXQgcmVzb2x2ZXIuZ2V0QmFzZVVybChwcmVmaXgsIHMpXSBhcyBjb25zdCksXG4gICAgICAgICksXG4gICAgKVxufVxuIl19