UNPKG

open-next-cdk

Version:

Deploy a NextJS app using OpenNext packaging to serverless AWS using CDK

123 lines 17.4 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.getS3ReplaceValues = exports.NextjsS3EnvRewriter = exports.replaceTokenGlobs = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const fs = require("fs"); const os = require("os"); const path = require("path"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const iam = require("aws-cdk-lib/aws-iam"); const lambda = require("aws-cdk-lib/aws-lambda"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const aws_s3_1 = require("aws-cdk-lib/aws-s3"); const cr = require("aws-cdk-lib/custom-resources"); const constructs_1 = require("constructs"); const BundleFunction_1 = require("./BundleFunction"); const NextjsBuild_1 = require("./NextjsBuild"); // files to rewrite CloudFormation tokens in environment variables exports.replaceTokenGlobs = ['**/*.html', '**/*.js', '**/*.cjs', '**/*.mjs', '**/*.json']; /** * Rewrites variables in S3 objects after a deployment happens to * replace CloudFormation tokens with their values. * These values are not resolved at build time because they are * only known at deploy time. */ class NextjsS3EnvRewriter extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const { s3Bucket, s3keys, replacementConfig, debug, cloudfrontDistributionId } = props; if (s3keys.length === 0) return; const app = aws_cdk_lib_1.App.of(this); const tmpDir = props.tempBuildDir ? path.resolve(path.join(props.tempBuildDir, 'static')) : fs.mkdtempSync(path.join(os.tmpdir(), 'static-')); // create a custom resource to find and replace tokenized strings in static files // must happen after deployment when tokens can be resolved // compile function const inputPath = path.resolve(__dirname, '../assets/lambda/S3EnvRewriter.ts'); const outputPath = path.join(tmpDir, 'deployment-scripts', 'S3EnvRewriter.cjs'); const handlerDir = BundleFunction_1.bundleFunction({ inputPath, outputPath, bundleOptions: { bundle: true, sourcemap: true, external: ['aws-sdk'], target: 'node16', platform: 'node', format: 'cjs', }, }); // rewriter lambda function const rewriteFn = new lambda.Function(this, 'RewriteOnEventHandler', { runtime: aws_lambda_1.Runtime.NODEJS_16_X, memorySize: 1024, timeout: aws_cdk_lib_1.Duration.minutes(5), handler: 'S3EnvRewriter.handler', code: lambda.Code.fromAsset(handlerDir), initialPolicy: [ new iam.PolicyStatement({ actions: ['s3:GetObject', 's3:PutObject'], resources: [s3Bucket.arnForObjects('*')], }), ...(cloudfrontDistributionId ? [ new iam.PolicyStatement({ actions: ['cloudfront:CreateInvalidation'], resources: [`arn:aws:cloudfront::${app.account}:distribution/${cloudfrontDistributionId}`], }), ] : []), ], }); // grant permission to read env var config if provided if (replacementConfig.jsonS3Bucket && replacementConfig.jsonS3Key) { const bucket = typeof replacementConfig.jsonS3Bucket === 'string' ? aws_s3_1.Bucket.fromBucketName(this, 'EnvConfigBucket', replacementConfig.jsonS3Bucket) : replacementConfig.jsonS3Bucket; rewriteFn.addToRolePolicy(new iam.PolicyStatement({ actions: ['s3:GetObject'], resources: [bucket.arnForObjects(replacementConfig.jsonS3Key)], })); } // custom resource to run the rewriter after files are copied and we can resolve token values const provider = new cr.Provider(this, 'RewriteStaticProvider', { onEventHandler: rewriteFn, }); // params for the rewriter function const properties = { bucket: s3Bucket.bucketName, s3keys, replacementConfig: { ...replacementConfig, jsonS3Bucket: replacementConfig.jsonS3Bucket?.bucketName, }, debug, cloudfrontDistributionId, }; this.rewriteNode = new aws_cdk_lib_1.CustomResource(this, 'RewriteStatic', { serviceToken: provider.serviceToken, properties, }); } } exports.NextjsS3EnvRewriter = NextjsS3EnvRewriter; _a = JSII_RTTI_SYMBOL_1; NextjsS3EnvRewriter[_a] = { fqn: "open-next-cdk.NextjsS3EnvRewriter", version: "0.0.10" }; // inline env vars for client and server code // these are values to replace in built code after it's deployed to S3/lambda function getS3ReplaceValues(environment, publicOnly) { const replacements = {}; Object.entries(environment || {}) .filter(([, value]) => aws_cdk_lib_1.Token.isUnresolved(value)) .filter(([key]) => !publicOnly || key.startsWith('NEXT_PUBLIC_')) // don't replace server-only env vars .forEach(([key, value]) => { const token = NextjsBuild_1.makeTokenPlaceholder(key); replacements[token] = value.toString(); }); return replacements; } exports.getS3ReplaceValues = getS3ReplaceValues; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTmV4dGpzUzNFbnZSZXdyaXRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9OZXh0anNTM0VudlJld3JpdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEseUJBQXlCO0FBQ3pCLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsNkNBQW1FO0FBQ25FLDJDQUEyQztBQUMzQyxpREFBaUQ7QUFDakQsdURBQWlEO0FBQ2pELCtDQUFxRDtBQUNyRCxtREFBbUQ7QUFDbkQsMkNBQXVDO0FBQ3ZDLHFEQUFrRDtBQUVsRCwrQ0FBcUQ7QUFFckQsa0VBQWtFO0FBQ3JELFFBQUEsaUJBQWlCLEdBQUcsQ0FBQyxXQUFXLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFpQi9GOzs7OztHQUtHO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSxzQkFBUztJQUdoRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQStCO1FBQ3ZFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLHdCQUF3QixFQUFFLEdBQUcsS0FBSyxDQUFDO1FBRXZGLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUVoQyxNQUFNLEdBQUcsR0FBRyxpQkFBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQVEsQ0FBQztRQUVoQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsWUFBWTtZQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDdkQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVB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Q0wsd0JBQXdCO1NBQ3pCLENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksNEJBQWMsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQzNELFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtZQUNuQyxVQUFVO1NBQ1gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUF6Rkgsa0RBMEZDOzs7QUFFRCw2Q0FBNkM7QUFDN0MsNkVBQTZFO0FBQzdFLFNBQWdCLGtCQUFrQixDQUFDLFdBQW1DLEVBQUUsVUFBbUI7SUFDekYsTUFBTSxZQUFZLEdBQTJCLEVBQUUsQ0FBQztJQUVoRCxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7U0FDOUIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxtQkFBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNoRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMscUNBQXFDO1NBQ3RHLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7UUFDeEIsTUFBTSxLQUFLLEdBQUcsa0NBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVMLE9BQU8sWUFBWSxDQUFDO0FBQ3RCLENBQUM7QUFaRCxnREFZQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBBcHAsIEN1c3RvbVJlc291cmNlLCBEdXJhdGlvbiwgVG9rZW4gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBSdW50aW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBCdWNrZXQsIElCdWNrZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0ICogYXMgY3IgZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IGJ1bmRsZUZ1bmN0aW9uIH0gZnJvbSAnLi9CdW5kbGVGdW5jdGlvbic7XG5pbXBvcnQgeyBOZXh0anNCYXNlUHJvcHMgfSBmcm9tICcuL05leHRqc0Jhc2UnO1xuaW1wb3J0IHsgbWFrZVRva2VuUGxhY2Vob2xkZXIgfSBmcm9tICcuL05leHRqc0J1aWxkJztcblxuLy8gZmlsZXMgdG8gcmV3cml0ZSBDbG91ZEZvcm1hdGlvbiB0b2tlbnMgaW4gZW52aXJvbm1lbnQgdmFyaWFibGVzXG5leHBvcnQgY29uc3QgcmVwbGFjZVRva2VuR2xvYnMgPSBbJyoqLyouaHRtbCcsICcqKi8qLmpzJywgJyoqLyouY2pzJywgJyoqLyoubWpzJywgJyoqLyouanNvbiddO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJld3JpdGVSZXBsYWNlbWVudHNDb25maWcge1xuICByZWFkb25seSBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+OyAvLyByZXBsYWNlIGtleXMgd2l0aCB2YWx1ZXMgaW4gZmlsZXNcbiAgcmVhZG9ubHkganNvblMzQnVja2V0PzogSUJ1Y2tldDtcbiAgcmVhZG9ubHkganNvblMzS2V5Pzogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBSZXdyaXRlclBhcmFtcyB7XG4gIHJlYWRvbmx5IHMzQnVja2V0OiBJQnVja2V0O1xuICByZWFkb25seSBzM2tleXM6IHN0cmluZ1tdOyAvLyBmaWxlcyB0byByZXdyaXRlXG4gIHJlYWRvbmx5IHJlcGxhY2VtZW50Q29uZmlnOiBSZXdyaXRlUmVwbGFjZW1lbnRzQ29uZmlnO1xuICByZWFkb25seSBkZWJ1Zz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNsb3VkZnJvbnREaXN0cmlidXRpb25JZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNTM0VudlJld3JpdGVyUHJvcHMgZXh0ZW5kcyBOZXh0anNCYXNlUHJvcHMsIFJld3JpdGVyUGFyYW1zIHt9XG5cbi8qKlxuICogUmV3cml0ZXMgdmFyaWFibGVzIGluIFMzIG9iamVjdHMgYWZ0ZXIgYSBkZXBsb3ltZW50IGhhcHBlbnMgdG9cbiAqIHJlcGxhY2UgQ2xvdWRGb3JtYXRpb24gdG9rZW5zIHdpdGggdGhlaXIgdmFsdWVzLlxuICogVGhlc2UgdmFsdWVzIGFyZSBub3QgcmVzb2x2ZWQgYXQgYnVpbGQgdGltZSBiZWNhdXNlIHRoZXkgYXJlXG4gKiBvbmx5IGtub3duIGF0IGRlcGxveSB0aW1lLlxuICovXG5leHBvcnQgY2xhc3MgTmV4dGpzUzNFbnZSZXdyaXRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZXdyaXRlTm9kZT86IENvbnN0cnVjdDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzUzNFbnZSZXdyaXRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHsgczNCdWNrZXQsIHMza2V5cywgcmVwbGFjZW1lbnRDb25maWcsIGRlYnVnLCBjbG91ZGZyb250RGlzdHJpYnV0aW9uSWQgfSA9IHByb3BzO1xuXG4gICAgaWYgKHMza2V5cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgIGNvbnN0IGFwcCA9IEFwcC5vZih0aGlzKSBhcyBBcHA7XG5cbiAgICBjb25zdCB0bXBEaXIgPSBwcm9wcy50ZW1wQnVpbGREaXJcbiAgICAgID8gcGF0aC5yZXNvbHZlKHBhdGguam9pbihwcm9wcy50ZW1wQnVpbGREaXIsICdzdGF0aWMnKSlcbiAgICAgIDogZnMubWtkdGVtcFN5bmMocGF0aC5qb2luKG9zLnRtcGRpcigpLCAnc3RhdGljLScpKTtcblxuICAgIC8vIGNyZWF0ZSBhIGN1c3RvbSByZXNvdXJjZSB0byBmaW5kIGFuZCByZXBsYWNlIHRva2VuaXplZCBzdHJpbmdzIGluIHN0YXRpYyBmaWxlc1xuICAgIC8vIG11c3QgaGFwcGVuIGFmdGVyIGRlcGxveW1lbnQgd2hlbiB0b2tlbnMgY2FuIGJlIHJlc29sdmVkXG4gICAgLy8gY29tcGlsZSBmdW5jdGlvblxuICAgIGNvbnN0IGlucHV0UGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9hc3NldHMvbGFtYmRhL1MzRW52UmV3cml0ZXIudHMnKTtcbiAgICBjb25zdCBvdXRwdXRQYXRoID0gcGF0aC5qb2luKHRtcERpciwgJ2RlcGxveW1lbnQtc2NyaXB0cycsICdTM0VudlJld3JpdGVyLmNqcycpO1xuICAgIGNvbnN0IGhhbmRsZXJEaXIgPSBidW5kbGVGdW5jdGlvbih7XG4gICAgICBpbnB1dFBhdGgsXG4gICAgICBvdXRwdXRQYXRoLFxuICAgICAgYnVuZGxlT3B0aW9uczoge1xuICAgICAgICBidW5kbGU6IHRydWUsXG4gICAgICAgIHNvdXJjZW1hcDogdHJ1ZSxcbiAgICAgICAgZXh0ZXJuYWw6IFsnYXdzLXNkayddLFxuICAgICAgICB0YXJnZXQ6ICdub2RlMTYnLFxuICAgICAgICBwbGF0Zm9ybTogJ25vZGUnLFxuICAgICAgICBmb3JtYXQ6ICdjanMnLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIHJld3JpdGVyIGxhbWJkYSBmdW5jdGlvblxuICAgIGNvbnN0IHJld3JpdGVGbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgJ1Jld3JpdGVPbkV2ZW50SGFuZGxlcicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE2X1gsXG4gICAgICBtZW1vcnlTaXplOiAxMDI0LFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgIGhhbmRsZXI6ICdTM0VudlJld3JpdGVyLmhhbmRsZXInLFxuICAgICAgY29kZTogbGFtYmRhLkNvZGUuZnJvbUFzc2V0KGhhbmRsZXJEaXIpLFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogWydzMzpHZXRPYmplY3QnLCAnczM6UHV0T2JqZWN0J10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbczNCdWNrZXQuYXJuRm9yT2JqZWN0cygnKicpXSxcbiAgICAgICAgfSksXG4gICAgICAgIC4uLihjbG91ZGZyb250RGlzdHJpYnV0aW9uSWRcbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICAgIGFjdGlvbnM6IFsnY2xvdWRmcm9udDpDcmVhdGVJbnZhbGlkYXRpb24nXSxcbiAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFtgYXJuOmF3czpjbG91ZGZyb250Ojoke2FwcC5hY2NvdW50fTpkaXN0cmlidXRpb24vJHtjbG91ZGZyb250RGlzdHJpYnV0aW9uSWR9YF0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgXVxuICAgICAgICAgIDogW10pLFxuICAgICAgXSxcbiAgICB9KTtcbiAgICAvLyBncmFudCBwZXJtaXNzaW9uIHRvIHJlYWQgZW52IHZhciBjb25maWcgaWYgcHJvdmlkZWRcbiAgICBpZiAocmVwbGFjZW1lbnRDb25maWcuanNvblMzQnVja2V0ICYmIHJlcGxhY2VtZW50Q29uZmlnLmpzb25TM0tleSkge1xuICAgICAgY29uc3QgYnVja2V0OiBJQnVja2V0ID1cbiAgICAgICAgdHlwZW9mIHJlcGxhY2VtZW50Q29uZmlnLmpzb25TM0J1Y2tldCA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IEJ1Y2tldC5mcm9tQnVja2V0TmFtZSh0aGlzLCAnRW52Q29uZmlnQnVja2V0JywgcmVwbGFjZW1lbnRDb25maWcuanNvblMzQnVja2V0KVxuICAgICAgICAgIDogcmVwbGFjZW1lbnRDb25maWcuanNvblMzQnVja2V0O1xuICAgICAgcmV3cml0ZUZuLmFkZFRvUm9sZVBvbGljeShcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFsnczM6R2V0T2JqZWN0J10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbYnVja2V0LmFybkZvck9iamVjdHMocmVwbGFjZW1lbnRDb25maWcuanNvblMzS2V5KV0sXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIGN1c3RvbSByZXNvdXJjZSB0byBydW4gdGhlIHJld3JpdGVyIGFmdGVyIGZpbGVzIGFyZSBjb3BpZWQgYW5kIHdlIGNhbiByZXNvbHZlIHRva2VuIHZhbHVlc1xuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IGNyLlByb3ZpZGVyKHRoaXMsICdSZXdyaXRlU3RhdGljUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogcmV3cml0ZUZuLFxuICAgIH0pO1xuICAgIC8vIHBhcmFtcyBmb3IgdGhlIHJld3JpdGVyIGZ1bmN0aW9uXG4gICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgIGJ1Y2tldDogczNCdWNrZXQuYnVja2V0TmFtZSxcbiAgICAgIHMza2V5cyxcbiAgICAgIHJlcGxhY2VtZW50Q29uZmlnOiB7XG4gICAgICAgIC4uLnJlcGxhY2VtZW50Q29uZmlnLFxuICAgICAgICBqc29uUzNCdWNrZXQ6IHJlcGxhY2VtZW50Q29uZmlnLmpzb25TM0J1Y2tldD8uYnVja2V0TmFtZSxcbiAgICAgIH0sXG4gICAgICBkZWJ1ZyxcbiAgICAgIGNsb3VkZnJvbnREaXN0cmlidXRpb25JZCxcbiAgICB9O1xuICAgIHRoaXMucmV3cml0ZU5vZGUgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ1Jld3JpdGVTdGF0aWMnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXMsXG4gICAgfSk7XG4gIH1cbn1cblxuLy8gaW5saW5lIGVudiB2YXJzIGZvciBjbGllbnQgYW5kIHNlcnZlciBjb2RlXG4vLyB0aGVzZSBhcmUgdmFsdWVzIHRvIHJlcGxhY2UgaW4gYnVpbHQgY29kZSBhZnRlciBpdCdzIGRlcGxveWVkIHRvIFMzL2xhbWJkYVxuZXhwb3J0IGZ1bmN0aW9uIGdldFMzUmVwbGFjZVZhbHVlcyhlbnZpcm9ubWVudDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiwgcHVibGljT25seTogYm9vbGVhbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCByZXBsYWNlbWVudHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBPYmplY3QuZW50cmllcyhlbnZpcm9ubWVudCB8fCB7fSlcbiAgICAuZmlsdGVyKChbLCB2YWx1ZV0pID0+IFRva2VuLmlzVW5yZXNvbHZlZCh2YWx1ZSkpXG4gICAgLmZpbHRlcigoW2tleV0pID0+ICFwdWJsaWNPbmx5IHx8IGtleS5zdGFydHNXaXRoKCdORVhUX1BVQkxJQ18nKSkgLy8gZG9uJ3QgcmVwbGFjZSBzZXJ2ZXItb25seSBlbnYgdmFyc1xuICAgIC5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGNvbnN0IHRva2VuID0gbWFrZVRva2VuUGxhY2Vob2xkZXIoa2V5KTtcbiAgICAgIHJlcGxhY2VtZW50c1t0b2tlbl0gPSB2YWx1ZS50b1N0cmluZygpO1xuICAgIH0pO1xuXG4gIHJldHVybiByZXBsYWNlbWVudHM7XG59XG4iXX0=