UNPKG

@riddance/deploy

Version:

133 lines 27.2 kB
import { jsonResponse, okResponse } from '@riddance/fetch'; import { randomUUID } from 'node:crypto'; import { isDeepStrictEqual } from 'node:util'; import { awsRequest, isNotFound } from '../lite.js'; export async function syncTriggers(context, prefix, service, functions, reflection, region, account, apiGatewayId) { const currentTriggers = await getTriggers(context, prefix, service, functions); await Promise.all([ ...reflection.http.map(async (fn) => { const trigger = currentTriggers.find(t => t.name === fn.name); if (!apiGatewayId) { throw new Error('Need API Gateway for http triggers.'); } if (!trigger) { const statement = makeApiGatewayStatementData(region, account, apiGatewayId, functions.find(f => f.name === fn.name)?.id ?? '', fn); await addTrigger(context, prefix, service, fn.name, randomUUID(), statement); return; } const statement = makeApiGatewayStatementData(region, account, apiGatewayId, trigger.id, fn); await syncTrigger(trigger, statement, context, prefix, service, fn.name); }), ...reflection.timers.map(async (fn) => { const trigger = currentTriggers.find(t => t.name === fn.name); if (!trigger) { const statement = makeEventBridgeStatementData(region, account, functions.find(f => f.name === fn.name)?.id ?? '', prefix, service, fn.name); await addTrigger(context, prefix, service, fn.name, randomUUID(), statement); return; } const statement = makeEventBridgeStatementData(region, account, trigger.id, prefix, service, fn.name); await syncTrigger(trigger, statement, context, prefix, service, fn.name); }), ...reflection.events.map(async (fn) => { const trigger = currentTriggers.find(t => t.name === fn.name); if (!trigger) { const statement = makeSnsStatementData(region, account, functions.find(f => f.name === fn.name)?.id ?? '', prefix, fn.topic, fn.type); await addTrigger(context, prefix, service, fn.name, randomUUID(), statement); return; } const statement = makeSnsStatementData(region, account, trigger.id, prefix, fn.topic, fn.type); await syncTrigger(trigger, statement, context, prefix, service, fn.name); }), ]); } async function syncTrigger(trigger, statement, context, prefix, service, name) { let exists = false; if (trigger.statements) { for (const { Sid, ...data } of trigger.statements) { if (isDeepStrictEqual(data, statement)) { if (exists) { await deleteTrigger(context, prefix, service, name, Sid); } else { exists = true; } } else { await deleteTrigger(context, prefix, service, name, Sid); } } } if (!exists) { await addTrigger(context, prefix, service, name, randomUUID(), statement); } } export async function getTriggers(context, prefix, service, functions) { return await Promise.all(functions.map(async (fn) => { try { return { id: fn.id, name: fn.name, statements: JSON.parse((await jsonResponse(awsRequest(context, 'GET', 'lambda', `/2015-03-31/functions/${prefix}-${service}-${fn.name}/policy/`), 'Error getting triggers.')).Policy).Statement, }; } catch (e) { if (isNotFound(e)) { return { id: fn.id, name: fn.name, }; } throw e; } })); } async function addTrigger(context, prefix, service, name, id, statement) { const arn = statement.Condition.ArnLike['AWS:SourceArn']; context.log.trace(`adding trigger ${id} to lambda ${name}`); context.log.trace(` from ${arn}`); await okResponse(awsRequest(context, 'POST', 'lambda', `/2015-03-31/functions/${prefix}-${service}-${name}/policy/`, { StatementId: id, Action: statement.Action, Principal: statement.Principal.Service, SourceArn: arn, }), 'Error adding triggers.'); } async function deleteTrigger(context, prefix, service, name, id) { context.log.trace(`deleting trigger ${id} from ${name}`); await okResponse(awsRequest(context, 'DELETE', 'lambda', `/2015-03-31/functions/${prefix}-${service}-${name}/policy/${id}`), 'Error deleting triggers.'); } function makeApiGatewayStatementData(region, account, apiGatewayId, functionId, fn) { let p = 0; return makeStatementData(region, account, functionId, 'apigateway.amazonaws.com', `arn:aws:execute-api:${region}:${account}:${apiGatewayId}/*/*/${trimTrailingSlash(fn.pathPattern.replaceAll('*', () => `{p${++p}}`))}`); } function makeEventBridgeStatementData(region, account, functionId, prefix, service, name) { return makeStatementData(region, account, functionId, 'events.amazonaws.com', `arn:aws:events:${region}:${account}:rule/${prefix}-${service}-${name}`); } function makeSnsStatementData(region, account, functionId, prefix, topic, type) { return makeStatementData(region, account, functionId, 'sns.amazonaws.com', `arn:aws:sns:${region}:${account}:${prefix}-${topic}-${type}`); } function makeStatementData(region, account, functionId, service, source) { if (!region || !account) { throw new Error('Weird'); } return { Action: 'lambda:InvokeFunction', Effect: 'Allow', Principal: { Service: service, }, Resource: functionId, Condition: { ArnLike: { 'AWS:SourceArn': source, }, }, }; } function trimTrailingSlash(pathPattern) { if (pathPattern.endsWith('/')) { return pathPattern.slice(0, -1); } return pathPattern; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJpZ2dlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cmlnZ2Vycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBRTFELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQzdDLE9BQU8sRUFBZ0IsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVqRSxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FDOUIsT0FBZ0IsRUFDaEIsTUFBYyxFQUNkLE9BQWUsRUFDZixTQUF5QyxFQUN6QyxVQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBZSxFQUNmLFlBQWdDO0lBRWhDLE1BQU0sZUFBZSxHQUFHLE1BQU0sV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQzlFLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUNkLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLEVBQUUsRUFBQyxFQUFFO1lBQzlCLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUM3RCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQTtZQUMxRCxDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNYLE1BQU0sU0FBUyxHQUFHLDJCQUEyQixDQUN6QyxNQUFNLEVBQ04sT0FBTyxFQUNQLFlBQVksRUFDWixTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxF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LElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVCLE9BQU8sV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNuQyxDQUFDO0lBQ0QsT0FBTyxXQUFXLENBQUE7QUFDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGpzb25SZXNwb25zZSwgb2tSZXNwb25zZSB9IGZyb20gJ0ByaWRkYW5jZS9mZXRjaCdcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tICdAcmlkZGFuY2UvaG9zdC9yZWZsZWN0J1xuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ25vZGU6Y3J5cHRvJ1xuaW1wb3J0IHsgaXNEZWVwU3RyaWN0RXF1YWwgfSBmcm9tICdub2RlOnV0aWwnXG5pbXBvcnQgeyB0eXBlIENvbnRleHQsIGF3c1JlcXVlc3QsIGlzTm90Rm91bmQgfSBmcm9tICcuLi9saXRlLmpzJ1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3luY1RyaWdnZXJzKFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICAgc2VydmljZTogc3RyaW5nLFxuICAgIGZ1bmN0aW9uczogeyBpZDogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfVtdLFxuICAgIHJlZmxlY3Rpb246IFJlZmxlY3Rpb24sXG4gICAgcmVnaW9uOiBzdHJpbmcsXG4gICAgYWNjb3VudDogc3RyaW5nLFxuICAgIGFwaUdhdGV3YXlJZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuKSB7XG4gICAgY29uc3QgY3VycmVudFRyaWdnZXJzID0gYXdhaXQgZ2V0VHJpZ2dlcnMoY29udGV4dCwgcHJlZml4LCBzZXJ2aWNlLCBmdW5jdGlvbnMpXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAuLi5yZWZsZWN0aW9uLmh0dHAubWFwKGFzeW5jIGZuID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSBjdXJyZW50VHJpZ2dlcnMuZmluZCh0ID0+IHQubmFtZSA9PT0gZm4ubmFtZSlcbiAgICAgICAgICAgIGlmICghYXBpR2F0ZXdheUlkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZWVkIEFQSSBHYXRld2F5IGZvciBodHRwIHRyaWdnZXJzLicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRyaWdnZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGF0ZW1lbnQgPSBtYWtlQXBpR2F0ZXdheVN0YXRlbWVudERhdGEoXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICAgICAgICAgICAgYWNjb3VudCxcbiAgICAgICAgICAgICAgICAgICAgYXBpR2F0ZXdheUlkLFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMuZmluZChmID0+IGYubmFtZSA9PT0gZm4ubmFtZSk/LmlkID8/ICcnLFxuICAgICAgICAgICAgICAgICAgICBmbixcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgYXdhaXQgYWRkVHJpZ2dlcihjb250ZXh0LCBwcmVmaXgsIHNlcnZpY2UsIGZuLm5hbWUsIHJhbmRvbVVVSUQoKSwgc3RhdGVtZW50KVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc3RhdGVtZW50ID0gbWFrZUFwaUdhdGV3YXlTdGF0ZW1lbnREYXRhKFxuICAgICAgICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICAgICAgICBhY2NvdW50LFxuICAgICAgICAgICAgICAgIGFwaUdhdGV3YXlJZCxcbiAgICAgICAgICAgICAgICB0cmlnZ2VyLmlkLFxuICAgICAgICAgICAgICAgIGZuLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgYXdhaXQgc3luY1RyaWdnZXIodHJpZ2dlciwgc3RhdGVtZW50LCBjb250ZXh0LCBwcmVmaXgsIHNlcnZpY2UsIGZuLm5hbWUpXG4gICAgICAgIH0pLFxuICAgICAgICAuLi5yZWZsZWN0aW9uLnRpbWVycy5tYXAoYXN5bmMgZm4gPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJpZ2dlciA9IGN1cnJlbnRUcmlnZ2Vycy5maW5kKHQgPT4gdC5uYW1lID09PSBmbi5uYW1lKVxuICAgICAgICAgICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVtZW50ID0gbWFrZUV2ZW50QnJpZGdlU3RhdGVtZW50RGF0YShcbiAgICAgICAgICAgICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgICAgICAgICAgICBhY2NvdW50LFxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMuZmluZChmID0+IGYubmFtZSA9PT0gZm4ubmFtZSk/LmlkID8/ICcnLFxuICAgICAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIHNlcnZpY2UsXG4gICAgICAgICAgICAgICAgICAgIGZuLm5hbWUsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGF3YWl0IGFkZFRyaWdnZXIoY29udGV4dCwgcHJlZml4LCBzZXJ2aWNlLCBmbi5uYW1lLCByYW5kb21VVUlEKCksIHN0YXRlbWVudClcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHN0YXRlbWVudCA9IG1ha2VFdmVudEJyaWRnZVN0YXRlbWVudERhdGEoXG4gICAgICAgICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgICAgICAgIGFjY291bnQsXG4gICAgICAgICAgICAgICAgdHJpZ2dlci5pZCxcbiAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgc2VydmljZSxcbiAgICAgICAgICAgICAgICBmbi5uYW1lLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgYXdhaXQgc3luY1RyaWdnZXIodHJpZ2dlciwgc3RhdGVtZW50LCBjb250ZXh0LCBwcmVmaXgsIHNlcnZpY2UsIGZuLm5hbWUpXG4gICAgICAgIH0pLFxuICAgICAgICAuLi5yZWZsZWN0aW9uLmV2ZW50cy5tYXAoYXN5bmMgZm4gPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJpZ2dlciA9IGN1cnJlbnRUcmlnZ2Vycy5maW5kKHQgPT4gdC5uYW1lID09PSBmbi5uYW1lKVxuICAgICAgICAgICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVtZW50ID0gbWFrZVNuc1N0YXRlbWVudERhdGEoXG4gICAgICAgICAgICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICAgICAgICAgICAgYWNjb3VudCxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zLmZpbmQoZiA9PiBmLm5hbWUgPT09IGZuLm5hbWUpPy5pZCA/PyAnJyxcbiAgICAgICAgICAgICAgICAgICAgcHJlZml4LFxuICAgICAgICAgICAgICAgICAgICBmbi50b3BpYyxcbiAgICAgICAgICAgICAgICAgICAgZm4udHlwZSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgYXdhaXQgYWRkVHJpZ2dlcihjb250ZXh0LCBwcmVmaXgsIHNlcnZpY2UsIGZuLm5hbWUsIHJhbmRvbVVVSUQoKSwgc3RhdGVtZW50KVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc3RhdGVtZW50ID0gbWFrZVNuc1N0YXRlbWVudERhdGEoXG4gICAgICAgICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgICAgICAgIGFjY291bnQsXG4gICAgICAgICAgICAgICAgdHJpZ2dlci5pZCxcbiAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgZm4udG9waWMsXG4gICAgICAgICAgICAgICAgZm4udHlwZSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGF3YWl0IHN5bmNUcmlnZ2VyKHRyaWdnZXIsIHN0YXRlbWVudCwgY29udGV4dCwgcHJlZml4LCBzZXJ2aWNlLCBmbi5uYW1lKVxuICAgICAgICB9KSxcbiAgICBdKVxufVxuXG5leHBvcnQgdHlwZSBBd3NUcmlnZ2VyID0ge1xuICAgIGlkOiBzdHJpbmdcbiAgICBuYW1lOiBzdHJpbmdcbiAgICBjb25maWc/OiB7XG4gICAgICAgIG1ldGhvZDogc3RyaW5nXG4gICAgICAgIHBhdGhQYXR0ZXJuOiBzdHJpbmdcbiAgICB9XG4gICAgc3RhdGVtZW50cz86IEF3c1N0YXRlbWVudFtdXG59XG5cbnR5cGUgQXdzU3RhdGVtZW50ID0ge1xuICAgIFNpZDogc3RyaW5nXG4gICAgRWZmZWN0OiBzdHJpbmdcbiAgICBQcmluY2lwYWw6IHsgU2VydmljZTogc3RyaW5nIH1cbiAgICBBY3Rpb246IHN0cmluZ1xuICAgIFJlc291cmNlOiBzdHJpbmdcbiAgICBDb25kaXRpb246IHVua25vd25cbn1cblxuYXN5bmMgZnVuY3Rpb24gc3luY1RyaWdnZXIoXG4gICAgdHJpZ2dlcjogQXdzVHJpZ2dlcixcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudERhdGEsXG4gICAgY29udGV4dDogQ29udGV4dCxcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBzZXJ2aWNlOiBzdHJpbmcsXG4gICAgbmFtZTogc3RyaW5nLFxuKSB7XG4gICAgbGV0IGV4aXN0cyA9IGZhbHNlXG4gICAgaWYgKHRyaWdnZXIuc3RhdGVtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IHsgU2lkLCAuLi5kYXRhIH0gb2YgdHJpZ2dlci5zdGF0ZW1lbnRzKSB7XG4gICAgICAgICAgICBpZiAoaXNEZWVwU3RyaWN0RXF1YWwoZGF0YSwgc3RhdGVtZW50KSkge1xuICAgICAgICAgICAgICAgIGlmIChleGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGVsZXRlVHJpZ2dlcihjb250ZXh0LCBwcmVmaXgsIHNlcnZpY2UsIG5hbWUsIFNpZClcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleGlzdHMgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkZWxldGVUcmlnZ2VyKGNvbnRleHQsIHByZWZpeCwgc2VydmljZSwgbmFtZSwgU2lkKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghZXhpc3RzKSB7XG4gICAgICAgIGF3YWl0IGFkZFRyaWdnZXIoY29udGV4dCwgcHJlZml4LCBzZXJ2aWNlLCBuYW1lLCByYW5kb21VVUlEKCksIHN0YXRlbWVudClcbiAgICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRUcmlnZ2VycyhcbiAgICBjb250ZXh0OiBDb250ZXh0LFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICBmdW5jdGlvbnM6IHsgaWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nIH1bXSxcbik6IFByb21pc2U8QXdzVHJpZ2dlcltdPiB7XG4gICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBmdW5jdGlvbnMubWFwKGFzeW5jIGZuID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGZuLmlkLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBmbi5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBzdGF0ZW1lbnRzOiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBKU09OLnBhcnNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQganNvblJlc3BvbnNlPHsgUG9saWN5OiBzdHJpbmcgfT4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd3NSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dFVCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2xhbWJkYScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYC8yMDE1LTAzLTMxL2Z1bmN0aW9ucy8ke3ByZWZpeH0tJHtzZXJ2aWNlfS0ke2ZuLm5hbWV9L3BvbGljeS9gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciBnZXR0aW5nIHRyaWdnZXJzLicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLlBvbGljeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICkgYXMgeyBTdGF0ZW1lbnQ6IEF3c1N0YXRlbWVudFtdIH1cbiAgICAgICAgICAgICAgICAgICAgKS5TdGF0ZW1lbnQsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc05vdEZvdW5kKGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogZm4uaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBmbi5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgKVxufVxuXG5hc3luYyBmdW5jdGlvbiBhZGRUcmlnZ2VyKFxuICAgIGNvbnRleHQ6IENvbnRleHQsXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICAgc2VydmljZTogc3RyaW5nLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nLFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50RGF0YSxcbikge1xuICAgIGNvbnN0IGFybiA9IHN0YXRlbWVudC5Db25kaXRpb24uQXJuTGlrZVsnQVdTOlNvdXJjZUFybiddXG4gICAgY29udGV4dC5sb2cudHJhY2UoYGFkZGluZyB0cmlnZ2VyICR7aWR9IHRvIGxhbWJkYSAke25hbWV9YClcbiAgICBjb250ZXh0LmxvZy50cmFjZShgICBmcm9tICR7YXJufWApXG4gICAgYXdhaXQgb2tSZXNwb25zZShcbiAgICAgICAgYXdzUmVxdWVzdChcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAnUE9TVCcsXG4gICAgICAgICAgICAnbGFtYmRhJyxcbiAgICAgICAgICAgIGAvMjAxNS0wMy0zMS9mdW5jdGlvbnMvJHtwcmVmaXh9LSR7c2VydmljZX0tJHtuYW1lfS9wb2xpY3kvYCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBTdGF0ZW1lbnRJZDogaWQsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBzdGF0ZW1lbnQuQWN0aW9uLFxuICAgICAgICAgICAgICAgIFByaW5jaXBhbDogc3RhdGVtZW50LlByaW5jaXBhbC5TZXJ2aWNlLFxuICAgICAgICAgICAgICAgIFNvdXJjZUFybjogYXJuLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgKSxcbiAgICAgICAgJ0Vycm9yIGFkZGluZyB0cmlnZ2Vycy4nLFxuICAgIClcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVsZXRlVHJpZ2dlcihcbiAgICBjb250ZXh0OiBDb250ZXh0LFxuICAgIHByZWZpeDogc3RyaW5nLFxuICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyxcbikge1xuICAgIGNvbnRleHQubG9nLnRyYWNlKGBkZWxldGluZyB0cmlnZ2VyICR7aWR9IGZyb20gJHtuYW1lfWApXG4gICAgYXdhaXQgb2tSZXNwb25zZShcbiAgICAgICAgYXdzUmVxdWVzdChcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAnREVMRVRFJyxcbiAgICAgICAgICAgICdsYW1iZGEnLFxuICAgICAgICAgICAgYC8yMDE1LTAzLTMxL2Z1bmN0aW9ucy8ke3ByZWZpeH0tJHtzZXJ2aWNlfS0ke25hbWV9L3BvbGljeS8ke2lkfWAsXG4gICAgICAgICksXG4gICAgICAgICdFcnJvciBkZWxldGluZyB0cmlnZ2Vycy4nLFxuICAgIClcbn1cblxuZnVuY3Rpb24gbWFrZUFwaUdhdGV3YXlTdGF0ZW1lbnREYXRhKFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIGFjY291bnQ6IHN0cmluZyxcbiAgICBhcGlHYXRld2F5SWQ6IHN0cmluZyxcbiAgICBmdW5jdGlvbklkOiBzdHJpbmcsXG4gICAgZm46IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG1ldGhvZDogc3RyaW5nXG4gICAgICAgIHBhdGhQYXR0ZXJuOiBzdHJpbmdcbiAgICB9LFxuKSB7XG4gICAgbGV0IHAgPSAwXG4gICAgcmV0dXJuIG1ha2VTdGF0ZW1lbnREYXRhKFxuICAgICAgICByZWdpb24sXG4gICAgICAgIGFjY291bnQsXG4gICAgICAgIGZ1bmN0aW9uSWQsXG4gICAgICAgICdhcGlnYXRld2F5LmFtYXpvbmF3cy5jb20nLFxuICAgICAgICBgYXJuOmF3czpleGVjdXRlLWFwaToke3JlZ2lvbn06JHthY2NvdW50fToke2FwaUdhdGV3YXlJZH0vKi8qLyR7dHJpbVRyYWlsaW5nU2xhc2goXG4gICAgICAgICAgICBmbi5wYXRoUGF0dGVybi5yZXBsYWNlQWxsKCcqJywgKCkgPT4gYHtwJHsrK3B9fWApLFxuICAgICAgICApfWAsXG4gICAgKVxufVxuXG5mdW5jdGlvbiBtYWtlRXZlbnRCcmlkZ2VTdGF0ZW1lbnREYXRhKFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIGFjY291bnQ6IHN0cmluZyxcbiAgICBmdW5jdGlvbklkOiBzdHJpbmcsXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICAgc2VydmljZTogc3RyaW5nLFxuICAgIG5hbWU6IHN0cmluZyxcbikge1xuICAgIHJldHVybiBtYWtlU3RhdGVtZW50RGF0YShcbiAgICAgICAgcmVnaW9uLFxuICAgICAgICBhY2NvdW50LFxuICAgICAgICBmdW5jdGlvbklkLFxuICAgICAgICAnZXZlbnRzLmFtYXpvbmF3cy5jb20nLFxuICAgICAgICBgYXJuOmF3czpldmVudHM6JHtyZWdpb259OiR7YWNjb3VudH06cnVsZS8ke3ByZWZpeH0tJHtzZXJ2aWNlfS0ke25hbWV9YCxcbiAgICApXG59XG5cbmZ1bmN0aW9uIG1ha2VTbnNTdGF0ZW1lbnREYXRhKFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIGFjY291bnQ6IHN0cmluZyxcbiAgICBmdW5jdGlvbklkOiBzdHJpbmcsXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICAgdG9waWM6IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4pIHtcbiAgICByZXR1cm4gbWFrZVN0YXRlbWVudERhdGEoXG4gICAgICAgIHJlZ2lvbixcbiAgICAgICAgYWNjb3VudCxcbiAgICAgICAgZnVuY3Rpb25JZCxcbiAgICAgICAgJ3Nucy5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgYGFybjphd3M6c25zOiR7cmVnaW9ufToke2FjY291bnR9OiR7cHJlZml4fS0ke3RvcGljfS0ke3R5cGV9YCxcbiAgICApXG59XG5cbnR5cGUgU3RhdGVtZW50RGF0YSA9IFJldHVyblR5cGU8dHlwZW9mIG1ha2VTdGF0ZW1lbnREYXRhPlxuXG5mdW5jdGlvbiBtYWtlU3RhdGVtZW50RGF0YShcbiAgICByZWdpb246IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBhY2NvdW50OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgZnVuY3Rpb25JZDogc3RyaW5nLFxuICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICBzb3VyY2U6IHN0cmluZyxcbikge1xuICAgIGlmICghcmVnaW9uIHx8ICFhY2NvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignV2VpcmQnKVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBBY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgIFByaW5jaXBhbDoge1xuICAgICAgICAgICAgU2VydmljZTogc2VydmljZSxcbiAgICAgICAgfSxcbiAgICAgICAgUmVzb3VyY2U6IGZ1bmN0aW9uSWQsXG4gICAgICAgIENvbmRpdGlvbjoge1xuICAgICAgICAgICAgQXJuTGlrZToge1xuICAgICAgICAgICAgICAgICdBV1M6U291cmNlQXJuJzogc291cmNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyaW1UcmFpbGluZ1NsYXNoKHBhdGhQYXR0ZXJuOiBzdHJpbmcpIHtcbiAgICBpZiAocGF0aFBhdHRlcm4uZW5kc1dpdGgoJy8nKSkge1xuICAgICAgICByZXR1cm4gcGF0aFBhdHRlcm4uc2xpY2UoMCwgLTEpXG4gICAgfVxuICAgIHJldHVybiBwYXRoUGF0dGVyblxufVxuIl19