UNPKG

deploy-time-build

Version:
206 lines (201 loc) 28.3 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodejsBuild = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const path_1 = require("path"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets"); const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment"); const constructs_1 = require("constructs"); /** * Build Node.js app and optionally publish the artifact to an S3 bucket. */ class NodejsBuild extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const handler = new aws_lambda_1.SingletonFunction(this, 'CustomResourceHandler', { // Use raw string to avoid from tightening CDK version requirement runtime: new aws_lambda_1.Runtime('nodejs20.x', aws_lambda_1.RuntimeFamily.NODEJS), code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, '../lambda/trigger-codebuild/dist')), handler: 'index.handler', uuid: '25648b21-2c40-4f09-aa65-b6bbb0c44659', // generated for this construct lambdaPurpose: 'NodejsBuildCustomResourceHandler', timeout: aws_cdk_lib_1.Duration.minutes(5), }); const nodejsVersion = props.nodejsVersion ?? 18; let buildImage = 'aws/codebuild/standard:7.0'; // See: https://docs.aws.amazon.com/codebuild/latest/userguide/available-runtimes.html#linux-runtimes switch (nodejsVersion) { case 12: case 14: buildImage = 'aws/codebuild/standard:5.0'; break; case 16: buildImage = 'aws/codebuild/standard:6.0'; break; case 18: case 20: buildImage = 'aws/codebuild/standard:7.0'; break; default: aws_cdk_lib_1.Annotations.of(this).addWarning(`Possibly unsupported Node.js version: ${nodejsVersion}. Currently 12, 14, 16, 18, and 20 are supported.`); } const destinationObjectKeyOutputKey = 'destinationObjectKey'; const envFileKeyOutputKey = 'envFileKey'; const project = new aws_codebuild_1.Project(this, 'Project', { environment: { buildImage: aws_codebuild_1.LinuxBuildImage.fromCodeBuildImageId(buildImage) }, buildSpec: aws_codebuild_1.BuildSpec.fromObject({ version: '0.2', env: { shell: 'bash', }, phases: { install: { 'runtime-versions': { nodejs: nodejsVersion, }, }, build: { commands: [ 'current_dir=$(pwd)', // Iterate a json array using jq // https://www.starkandwayne.com/blog/bash-for-loop-over-json-array-using-jq/index.html ` echo "$input" for obj in $(echo "$input" | jq -r '.[] | @base64'); do decoded=$(echo "$obj" | base64 --decode) assetUrl=$(echo "$decoded" | jq -r '.assetUrl') extractPath=$(echo "$decoded" | jq -r '.extractPath') commands=$(echo "$decoded" | jq -r '.commands') # Download the zip file aws s3 cp "$assetUrl" temp.zip # Extract the zip file to the extractPath directory mkdir -p "$extractPath" unzip temp.zip -d "$extractPath" # Remove the zip file rm temp.zip # Run the specified commands in the extractPath directory cd "$extractPath" ls -la eval "$commands" cd "$current_dir" ls -la done `, 'ls -la', 'cd "$workingDirectory"', 'eval "$buildCommands"', 'ls -la', 'cd "$current_dir"', 'cd "$outputSourceDirectory"', 'zip -r output.zip ./', 'aws s3 cp output.zip "s3://$destinationBucketName/$destinationObjectKey"', // Upload .env if required ` if [[ $outputEnvFile == "true" ]] then # Split the comma-separated string into an array for var_name in \${envNames//,/ } do echo "Element: $var_name" var_value="\${!var_name}" echo "$var_name=$var_value" >> tmp.env done aws s3 cp tmp.env "s3://$destinationBucketName/$envFileKey" fi `, ], }, post_build: { commands: [ 'echo Build completed on `date`', ` STATUS='SUCCESS' if [ $CODEBUILD_BUILD_SUCCEEDING -ne 1 ] # Test if the build is failing then STATUS='FAILED' REASON="NodejsBuild failed. See CloudWatch Log stream for the detailed reason: https://$AWS_REGION.console.aws.amazon.com/cloudwatch/home?region=$AWS_REGION#logsV2:log-groups/log-group/\\$252Faws\\$252Fcodebuild\\$252F$projectName/log-events/$CODEBUILD_LOG_PATH" fi cat <<EOF > payload.json { "StackId": "$stackId", "RequestId": "$requestId", "LogicalResourceId":"$logicalResourceId", "PhysicalResourceId": "$logicalResourceId", "Status": "$STATUS", "Reason": "$REASON", "Data": { "${destinationObjectKeyOutputKey}": "$destinationObjectKey", "${envFileKeyOutputKey}": "$envFileKey" } } EOF curl -v -i -X PUT -H 'Content-Type:' -d "@payload.json" "$responseURL" `, ], }, }, }), }); handler.addToRolePolicy(new aws_iam_1.PolicyStatement({ actions: ['codebuild:StartBuild'], resources: [project.projectArn], })); this.grantPrincipal = project.grantPrincipal; const commonExclude = ['.DS_Store', '.git', 'node_modules']; const assets = props.assets.map((assetProps) => { const asset = new aws_s3_assets_1.Asset(this, `Source-${assetProps.path.replace('/', '')}`, { ...assetProps, ...(props.excludeCommonFiles ?? true ? { exclude: [...commonExclude, ...(assetProps.exclude ?? [])] } : {}), }); asset.grantRead(project); return asset; }); // use the asset bucket that are created by CDK bootstrap to store intermediate artifacts const bucket = assets[0].bucket; bucket.grantWrite(project); const sources = props.assets.map((s, i) => ({ sourceBucketName: assets[i].s3BucketName, sourceObjectKey: assets[i].s3ObjectKey, extractPath: s.extractPath ?? (0, path_1.basename)(s.path), commands: s.commands, })); const properties = { type: 'NodejsBuild', sources, destinationBucketName: bucket.bucketName, workingDirectory: sources[0].extractPath, // join paths for CodeBuild (Linux) platform outputSourceDirectory: path_1.posix.join(sources[0].extractPath, props.outputSourceDirectory), environment: props.buildEnvironment, buildCommands: props.buildCommands ?? ['npm run build'], codeBuildProjectName: project.projectName, outputEnvFile: props.outputEnvFile ?? false, }; const custom = new aws_cdk_lib_1.CustomResource(this, 'Resource', { serviceToken: handler.functionArn, resourceType: 'Custom::CDKNodejsBuild', properties, }); const deploy = new aws_s3_deployment_1.BucketDeployment(this, 'Deploy', { sources: [aws_s3_deployment_1.Source.bucket(bucket, custom.getAttString(destinationObjectKeyOutputKey))], destinationBucket: props.destinationBucket, destinationKeyPrefix: props.destinationKeyPrefix, distribution: props.distribution, memoryLimit: 512, // sometimes timeout on default (128MB) memory }); deploy.node.addDependency(custom); if (props.outputEnvFile) { new aws_cdk_lib_1.CfnOutput(this, 'DownloadEnvFile', { value: `aws s3 cp ${bucket.s3UrlForObject(custom.getAttString(envFileKeyOutputKey))} .env.local` }); } } } exports.NodejsBuild = NodejsBuild; _a = JSII_RTTI_SYMBOL_1; NodejsBuild[_a] = { fqn: "deploy-time-build.NodejsBuild", version: "0.3.37" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWJ1aWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25vZGVqcy1idWlsZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtCQUE2QztBQUM3Qyw2Q0FBK0U7QUFFL0UsNkRBQWdGO0FBQ2hGLGlEQUE4RTtBQUM5RSx1REFBeUY7QUFFekYsNkRBQThEO0FBQzlELHFFQUF5RTtBQUN6RSwyQ0FBdUM7QUE0RXZDOztHQUVHO0FBQ0gsTUFBYSxXQUFZLFNBQVEsc0JBQVM7SUFHeEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF1QjtRQUMvRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sT0FBTyxHQUFHLElBQUksOEJBQWlCLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ25FLGtFQUFrRTtZQUNsRSxPQUFPLEVBQUUsSUFBSSxvQkFBTyxDQUFDLFlBQVksRUFBRSwwQkFBYSxDQUFDLE1BQU0sQ0FBQztZQUN4RCxJQUFJLEVBQUUsaUJBQUksQ0FBQyxTQUFTLENBQUMsSUFBQSxXQUFJLEVBQUMsU0FBUyxFQUFFLGtDQUFrQyxDQUFDLENBQUM7WUFDekUsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLHNDQUFzQyxFQUFFLCtCQUErQjtZQUM3RSxhQUFhLEVBQUUsa0NBQWtDO1lBQ2pELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDN0IsQ0FBQyxDQUFDO1FBRUgsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDaEQsSUFBSSxVQUFVLEdBQUcsNEJBQTRCLENBQUM7UUFDOUMscUdBQXFHO1FBQ3JHLFFBQVEsYUFBYSxFQUFFLENBQUM7WUFDdEIsS0FBSyxFQUFFLENBQUM7WUFDUixLQUFLLEVBQUU7Z0JBQ0wsVUFBVSxHQUFHLDRCQUE0QixDQUFDO2dCQUMxQyxNQUFNO1lBQ1Is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R0FBRyxJQUFJLG9DQUFnQixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDbEQsT0FBTyxFQUFFLENBQUMsMEJBQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxDQUFDO1lBQ3BGLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUI7WUFDMUMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLG9CQUFvQjtZQUNoRCxZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVk7WUFDaEMsV0FBVyxFQUFFLEdBQUcsRUFBRSw4Q0FBOEM7U0FDakUsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbEMsSUFBSSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxpQkFBaUIsRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDL0ksQ0FBQztJQUNILENBQUM7O0FBMU1ILGtDQTJNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHBvc2l4LCBqb2luLCBiYXNlbmFtZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQW5ub3RhdGlvbnMsIENmbk91dHB1dCwgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSURpc3RyaWJ1dGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZGZyb250JztcbmltcG9ydCB7IEJ1aWxkU3BlYywgTGludXhCdWlsZEltYWdlLCBQcm9qZWN0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZCc7XG5pbXBvcnQgeyBJR3JhbnRhYmxlLCBJUHJpbmNpcGFsLCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IENvZGUsIFJ1bnRpbWUsIFJ1bnRpbWVGYW1pbHksIFNpbmdsZXRvbkZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBJQnVja2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzJztcbmltcG9ydCB7IEFzc2V0LCBBc3NldFByb3BzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWFzc2V0cyc7XG5pbXBvcnQgeyBCdWNrZXREZXBsb3ltZW50LCBTb3VyY2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudCc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IE5vZGVqc0J1aWxkUmVzb3VyY2VQcm9wcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2V0Q29uZmlnIGV4dGVuZHMgQXNzZXRQcm9wcyB7XG4gIC8qKlxuICAgKiBTaGVsbCBjb21tYW5kcyBleGVjdXRlZCByaWdodCBhZnRlciB0aGUgYXNzZXQgemlwIGlzIGV4dHJhY3RlZCB0byB0aGUgYnVpbGQgZW52aXJvbm1lbnQuXG4gICAqIEBkZWZhdWx0IE5vIGNvbW1hbmQgaXMgZXhlY3V0ZWQuXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBSZWxhdGl2ZSBwYXRoIGZyb20gYSBidWlsZCBkaXJlY3RvcnkgdG8gdGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgYXNzZXQgaXMgZXh0cmFjdGVkLlxuICAgKiBAZGVmYXVsdCBiYXNlbmFtZSBvZiB0aGUgYXNzZXQgcGF0aC5cbiAgICovXG4gIHJlYWRvbmx5IGV4dHJhY3RQYXRoPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5vZGVqc0J1aWxkUHJvcHMge1xuICAvKipcbiAgICogVGhlIEFzc2V0UHJvcHMgZnJvbSB3aGljaCBzMy1hc3NldHMgYXJlIGNyZWF0ZWQgYW5kIGNvcGllZCB0byB0aGUgYnVpbGQgZW52aXJvbm1lbnQuXG4gICAqL1xuICByZWFkb25seSBhc3NldHM6IEFzc2V0Q29uZmlnW107XG4gIC8qKlxuICAgKiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgaW5qZWN0ZWQgdG8gdGhlIGJ1aWxkIGVudmlyb25tZW50LlxuICAgKiBZb3UgY2FuIHVzZSBDREsgZGVwbG95LXRpbWUgdmFsdWVzIGFzIHdlbGwgYXMgbGl0ZXJhbHMuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqL1xuICByZWFkb25seSBidWlsZEVudmlyb25tZW50PzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgLyoqXG4gICAqIFMzIEJ1Y2tldCB0byB3aGljaCB5b3VyIGJ1aWxkIGFydGlmYWN0cyBhcmUgZmluYWxseSBkZXBsb3llZC5cbiAgICovXG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uQnVja2V0OiBJQnVja2V0O1xuICAvKipcbiAgICogS2V5IHByZWZpeCB0byBkZXBsb3kgeW91ciBidWlsZCBhcnRpZmFjdC5cbiAgICogQGRlZmF1bHQgJy8nXG4gICAqL1xuICByZWFkb25seSBkZXN0aW5hdGlvbktleVByZWZpeD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkaXN0cmlidXRpb24geW91IGFyZSB1c2luZyB0byBwdWJsaXNoIHlvdSBidWlsZCBhcnRpZmFjdC5cbiAgICogSWYgYW55IHNwZWNpZmllZCwgdGhlIGNhY2hlcyBhcmUgaW52YWxpZGF0ZWQgb24gbmV3IGFydGlmYWN0IGRlcGxveW1lbnRzLlxuICAgKiBAZGVmYXVsdCBObyBkaXN0cmlidXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbj86IElEaXN0cmlidXRpb247XG4gIC8qKlxuICAgKiBTaGVsbCBjb21tYW5kcyB0byBidWlsZCB5b3VyIHByb2plY3QuIFRoZXkgYXJlIGV4ZWN1dGVkIG9uIHRoZSB3b3JraW5nIGRpcmVjdG9yeSB5b3Ugc3BlY2lmaWVkLlxuICAgKiBAZGVmYXVsdCBbJ25wbSBydW4gYnVpbGQnXVxuICAgKi9cbiAgcmVhZG9ubHkgYnVpbGRDb21tYW5kcz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogUmVsYXRpdmUgcGF0aCBmcm9tIHRoZSBidWlsZCBkaXJlY3RvcnkgdG8gdGhlIGRpcmVjdG9yeSB3aGVyZSBidWlsZCBjb21tYW5kcyBydW4uXG4gICAqIEBkZWZhdWx0IGFzc2V0UHJvcHNbMF0uZXh0cmFjdFBhdGhcbiAgICovXG4gIHJlYWRvbmx5IHdvcmtpbmdEaXJlY3Rvcnk/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBSZWxhdGl2ZSBwYXRoIGZyb20gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IHRvIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGJ1aWxkIGFydGlmYWN0cyBhcmUgb3V0cHV0LlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0U291cmNlRGlyZWN0b3J5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBvZiBOb2RlLmpzIHRvIHVzZSBpbiBhIGJ1aWxkIGVudmlyb25tZW50LiBBdmFpbGFibGUgdmVyc2lvbnM6IDEyLCAxNCwgMTYsIDE4LCAyMC5cbiAgICogQGRlZmF1bHQgMThcbiAgICovXG4gIHJlYWRvbmx5IG5vZGVqc1ZlcnNpb24/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBJZiB0cnVlLCBhIC5lbnYgZmlsZSBpcyB1cGxvYWRlZCB0byBhbiBTMyBidWNrZXQgd2l0aCB2YWx1ZXMgb2YgYGJ1aWxkRW52aXJvbm1lbnRgIHByb3BlcnR5LlxuICAgKiBZb3UgY2FuIGNvcHkgaXQgdG8geW91ciBsb2NhbCBtYWNoaW5lIGJ5IHJ1bm5pbmcgdGhlIGNvbW1hbmQgaW4gdGhlIHN0YWNrIG91dHB1dC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dEVudkZpbGU/OiBib29sZWFuO1xuICAvKipcbiAgICogSWYgdHJ1ZSwgY29tbW9uIHVubmVjZXNzYXJ5IGZpbGVzL2RpcmVjdG9yaWVzIHN1Y2ggYXMgLkRTX1N0b3JlLCAuZ2l0LCBub2RlX21vZHVsZXMsIGV0YyBhcmUgZXhjbHVkZWRcbiAgICogZnJvbSB0aGUgYXNzZXRzIGJ5IGRlZmF1bHQuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVDb21tb25GaWxlcz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQnVpbGQgTm9kZS5qcyBhcHAgYW5kIG9wdGlvbmFsbHkgcHVibGlzaCB0aGUgYXJ0aWZhY3QgdG8gYW4gUzMgYnVja2V0LlxuICovXG5leHBvcnQgY2xhc3MgTm9kZWpzQnVpbGQgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJR3JhbnRhYmxlIHtcbiAgcHVibGljIHJlYWRvbmx5IGdyYW50UHJpbmNpcGFsOiBJUHJpbmNpcGFsO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOb2RlanNCdWlsZFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgU2luZ2xldG9uRnVuY3Rpb24odGhpcywgJ0N1c3RvbVJlc291cmNlSGFuZGxlcicsIHtcbiAgICAgIC8vIFVzZSByYXcgc3RyaW5nIHRvIGF2b2lkIGZyb20gdGlnaHRlbmluZyBDREsgdmVyc2lvbiByZXF1aXJlbWVudFxuICAgICAgcnVudGltZTogbmV3IFJ1bnRpbWUoJ25vZGVqczIwLngnLCBSdW50aW1lRmFtaWx5Lk5PREVKUyksXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChqb2luKF9fZGlybmFtZSwgJy4uL2xhbWJkYS90cmlnZ2VyLWNvZGVidWlsZC9kaXN0JykpLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgdXVpZDogJzI1NjQ4YjIxLTJjNDAtNGYwOS1hYTY1LWI2YmJiMGM0NDY1OScsIC8vIGdlbmVyYXRlZCBmb3IgdGhpcyBjb25zdHJ1Y3RcbiAgICAgIGxhbWJkYVB1cnBvc2U6ICdOb2RlanNCdWlsZEN1c3RvbVJlc291cmNlSGFuZGxlcicsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDUpLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgbm9kZWpzVmVyc2lvbiA9IHByb3BzLm5vZGVqc1ZlcnNpb24gPz8gMTg7XG4gICAgbGV0IGJ1aWxkSW1hZ2UgPSAnYXdzL2NvZGVidWlsZC9zdGFuZGFyZDo3LjAnO1xuICAgIC8vIFNlZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NvZGVidWlsZC9sYXRlc3QvdXNlcmd1aWRlL2F2YWlsYWJsZS1ydW50aW1lcy5odG1sI2xpbnV4LXJ1bnRpbWVzXG4gICAgc3dpdGNoIChub2RlanNWZXJzaW9uKSB7XG4gICAgICBjYXNlIDEyOlxuICAgICAgY2FzZSAxNDpcbiAgICAgICAgYnVpbGRJbWFnZSA9ICdhd3MvY29kZWJ1aWxkL3N0YW5kYXJkOjUuMCc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxNjpcbiAgICAgICAgYnVpbGRJbWFnZSA9ICdhd3MvY29kZWJ1aWxkL3N0YW5kYXJkOjYuMCc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxODpcbiAgICAgIGNhc2UgMjA6XG4gICAgICAgIGJ1aWxkSW1hZ2UgPSAnYXdzL2NvZGVidWlsZC9zdGFuZGFyZDo3LjAnO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcoYFBvc3NpYmx5IHVuc3VwcG9ydGVkIE5vZGUuanMgdmVyc2lvbjogJHtub2RlanNWZXJzaW9ufS4gQ3VycmVudGx5IDEyLCAxNCwgMTYsIDE4LCBhbmQgMjAgYXJlIHN1cHBvcnRlZC5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXN0aW5hdGlvbk9iamVjdEtleU91dHB1dEtleSA9ICdkZXN0aW5hdGlvbk9iamVjdEtleSc7XG4gICAgY29uc3QgZW52RmlsZUtleU91dHB1dEtleSA9ICdlbnZGaWxlS2V5JztcblxuICAgIGNvbnN0IHByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCAnUHJvamVjdCcsIHtcbiAgICAgIGVudmlyb25tZW50OiB7IGJ1aWxkSW1hZ2U6IExpbnV4QnVpbGRJbWFnZS5mcm9tQ29kZUJ1aWxkSW1hZ2VJZChidWlsZEltYWdlKSB9LFxuICAgICAgYnVpbGRTcGVjOiBCdWlsZFNwZWMuZnJvbU9iamVjdCh7XG4gICAgICAgIHZlcnNpb246ICcwLjInLFxuICAgICAgICBlbnY6IHtcbiAgICAgICAgICBzaGVsbDogJ2Jhc2gnLFxuICAgICAgICB9LFxuICAgICAgICBwaGFzZXM6IHtcbiAgICAgICAgICBpbnN0YWxsOiB7XG4gICAgICAgICAgICAncnVudGltZS12ZXJzaW9ucyc6IHtcbiAgICAgICAgICAgICAgbm9kZWpzOiBub2RlanNWZXJzaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJ1aWxkOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgICAnY3VycmVudF9kaXI9JChwd2QpJyxcbiAgICAgICAgICAgICAgLy8gSXRlcmF0ZSBhIGpzb24gYXJyYXkgdXNpbmcganFcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cuc3RhcmthbmR3YXluZS5jb20vYmxvZy9iYXNoLWZvci1sb29wLW92ZXItanNvbi1hcnJheS11c2luZy1qcS9pbmRleC5odG1sXG4gICAgICAgICAgICAgIGBcbmVjaG8gXCIkaW5wdXRcIlxuZm9yIG9iaiBpbiAkKGVjaG8gXCIkaW5wdXRcIiB8IGpxIC1yICcuW10gfCBAYmFzZTY0Jyk7IGRvXG4gIGRlY29kZWQ9JChlY2hvIFwiJG9ialwiIHwgYmFzZTY0IC0tZGVjb2RlKVxuICBhc3NldFVybD0kKGVjaG8gXCIkZGVjb2RlZFwiIHwganEgLXIgJy5hc3NldFVybCcpXG4gIGV4dHJhY3RQYXRoPSQoZWNobyBcIiRkZWNvZGVkXCIgfCBqcSAtciAnLmV4dHJhY3RQYXRoJylcbiAgY29tbWFuZHM9JChlY2hvIFwiJGRlY29kZWRcIiB8IGpxIC1yICcuY29tbWFuZHMnKVxuXG4gICMgRG93bmxvYWQgdGhlIHppcCBmaWxlXG4gIGF3cyBzMyBjcCBcIiRhc3NldFVybFwiIHRlbXAuemlwXG5cbiAgIyBFeHRyYWN0IHRoZSB6aXAgZmlsZSB0byB0aGUgZXh0cmFjdFBhdGggZGlyZWN0b3J5XG4gIG1rZGlyIC1wIFwiJGV4dHJhY3RQYXRoXCJcbiAgdW56aXAgdGVtcC56aXAgLWQgXCIkZXh0cmFjdFBhdGhcIlxuXG4gICMgUmVtb3ZlIHRoZSB6aXAgZmlsZVxuICBybSB0ZW1wLnppcFxuXG4gICMgUnVuIHRoZSBzcGVjaWZpZWQgY29tbWFuZHMgaW4gdGhlIGV4dHJhY3RQYXRoIGRpcmVjdG9yeVxuICBjZCBcIiRleHRyYWN0UGF0aFwiXG4gIGxzIC1sYVxuICBldmFsIFwiJGNvbW1hbmRzXCJcbiAgY2QgXCIkY3VycmVudF9kaXJcIlxuICBscyAtbGFcbmRvbmVcbiAgICAgICAgICAgICAgYCxcbiAgICAgICAgICAgICAgJ2xzIC1sYScsXG4gICAgICAgICAgICAgICdjZCBcIiR3b3JraW5nRGlyZWN0b3J5XCInLFxuICAgICAgICAgICAgICAnZXZhbCBcIiRidWlsZENvbW1hbmRzXCInLFxuICAgICAgICAgICAgICAnbHMgLWxhJyxcbiAgICAgICAgICAgICAgJ2NkIFwiJGN1cnJlbnRfZGlyXCInLFxuICAgICAgICAgICAgICAnY2QgXCIkb3V0cHV0U291cmNlRGlyZWN0b3J5XCInLFxuICAgICAgICAgICAgICAnemlwIC1yIG91dHB1dC56aXAgLi8nLFxuICAgICAgICAgICAgICAnYXdzIHMzIGNwIG91dHB1dC56aXAgXCJzMzovLyRkZXN0aW5hdGlvbkJ1Y2tldE5hbWUvJGRlc3RpbmF0aW9uT2JqZWN0S2V5XCInLFxuICAgICAgICAgICAgICAvLyBVcGxvYWQgLmVudiBpZiByZXF1aXJlZFxuICAgICAgICAgICAgICBgXG5pZiBbWyAkb3V0cHV0RW52RmlsZSA9PSBcInRydWVcIiBdXVxudGhlblxuICAjIFNwbGl0IHRoZSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nIGludG8gYW4gYXJyYXlcbiAgZm9yIHZhcl9uYW1lIGluIFxcJHtlbnZOYW1lcy8vLC8gfVxuICBkb1xuICAgICAgZWNobyBcIkVsZW1lbnQ6ICR2YXJfbmFtZVwiXG4gICAgICB2YXJfdmFsdWU9XCJcXCR7IXZhcl9uYW1lfVwiXG4gICAgICBlY2hvIFwiJHZhcl9uYW1lPSR2YXJfdmFsdWVcIiA+PiB0bXAuZW52XG4gIGRvbmVcblxuICBhd3MgczMgY3AgdG1wLmVudiBcInMzOi8vJGRlc3RpbmF0aW9uQnVja2V0TmFtZS8kZW52RmlsZUtleVwiXG5maVxuICAgICAgICAgICAgICBgLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIEJ1aWxkIGNvbXBsZXRlZCBvbiBgZGF0ZWAnLFxuICAgICAgICAgICAgICBgXG5TVEFUVVM9J1NVQ0NFU1MnXG5pZiBbICRDT0RFQlVJTERfQlVJTERfU1VDQ0VFRElORyAtbmUgMSBdICMgVGVzdCBpZiB0aGUgYnVpbGQgaXMgZmFpbGluZ1xudGhlblxuU1RBVFVTPSdGQUlMRUQnXG5SRUFTT049XCJOb2RlanNCdWlsZCBmYWlsZWQuIFNlZSBDbG91ZFdhdGNoIExvZyBzdHJlYW0gZm9yIHRoZSBkZXRhaWxlZCByZWFzb246IFxuaHR0cHM6Ly8kQVdTX1JFR0lPTi5jb25zb2xlLmF3cy5hbWF6b24uY29tL2Nsb3Vkd2F0Y2gvaG9tZT9yZWdpb249JEFXU19SRUdJT04jbG9nc1YyOmxvZy1ncm91cHMvbG9nLWdyb3VwL1xcXFwkMjUyRmF3c1xcXFwkMjUyRmNvZGVidWlsZFxcXFwkMjUyRiRwcm9qZWN0TmFtZS9sb2ctZXZlbnRzLyRDT0RFQlVJTERfTE9HX1BBVEhcIlxuZmlcbmNhdCA8PEVPRiA+IHBheWxvYWQuanNvblxue1xuICBcIlN0YWNrSWRcIjogXCIkc3RhY2tJZFwiLFxuICBcIlJlcXVlc3RJZFwiOiBcIiRyZXF1ZXN0SWRcIixcbiAgXCJMb2dpY2FsUmVzb3VyY2VJZFwiOlwiJGxvZ2ljYWxSZXNvdXJjZUlkXCIsXG4gIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCI6IFwiJGxvZ2ljYWxSZXNvdXJjZUlkXCIsXG4gIFwiU3RhdHVzXCI6IFwiJFNUQVRVU1wiLFxuICBcIlJlYXNvblwiOiBcIiRSRUFTT05cIixcbiAgXCJEYXRhXCI6IHtcbiAgICBcIiR7ZGVzdGluYXRpb25PYmplY3RLZXlPdXRwdXRLZXl9XCI6IFwiJGRlc3RpbmF0aW9uT2JqZWN0S2V5XCIsXG4gICAgXCIke2VudkZpbGVLZXlPdXRwdXRLZXl9XCI6IFwiJGVudkZpbGVLZXlcIlxuICB9XG59XG5FT0ZcbmN1cmwgLXYgLWkgLVggUFVUIC1IICdDb250ZW50LVR5cGU6JyAtZCBcIkBwYXlsb2FkLmpzb25cIiBcIiRyZXNwb25zZVVSTFwiXG4gICAgICAgICAgICAgIGAsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGhhbmRsZXIuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnY29kZWJ1aWxkOlN0YXJ0QnVpbGQnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbcHJvamVjdC5wcm9qZWN0QXJuXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gcHJvamVjdC5ncmFudFByaW5jaXBhbDtcblxuICAgIGNvbnN0IGNvbW1vbkV4Y2x1ZGUgPSBbJy5EU19TdG9yZScsICcuZ2l0JywgJ25vZGVfbW9kdWxlcyddO1xuICAgIGNvbnN0IGFzc2V0cyA9IHByb3BzLmFzc2V0cy5tYXAoKGFzc2V0UHJvcHMpID0+IHtcbiAgICAgIGNvbnN0IGFzc2V0ID0gbmV3IEFzc2V0KHRoaXMsIGBTb3VyY2UtJHthc3NldFByb3BzLnBhdGgucmVwbGFjZSgnLycsICcnKX1gLCB7XG4gICAgICAgIC4uLmFzc2V0UHJvcHMsXG4gICAgICAgIC4uLihwcm9wcy5leGNsdWRlQ29tbW9uRmlsZXMgPz8gdHJ1ZSA/IHsgZXhjbHVkZTogWy4uLmNvbW1vbkV4Y2x1ZGUsIC4uLihhc3NldFByb3BzLmV4Y2x1ZGUgPz8gW10pXSB9IDoge30pLFxuICAgICAgfSk7XG4gICAgICBhc3NldC5ncmFudFJlYWQocHJvamVjdCk7XG4gICAgICByZXR1cm4gYXNzZXQ7XG4gICAgfSk7XG5cbiAgICAvLyB1c2UgdGhlIGFzc2V0IGJ1Y2tldCB0aGF0IGFyZSBjcmVhdGVkIGJ5IENESyBib290c3RyYXAgdG8gc3RvcmUgaW50ZXJtZWRpYXRlIGFydGlmYWN0c1xuICAgIGNvbnN0IGJ1Y2tldCA9IGFzc2V0c1swXS5idWNrZXQ7XG4gICAgYnVja2V0LmdyYW50V3JpdGUocHJvamVjdCk7XG5cbiAgICBjb25zdCBzb3VyY2VzOiBOb2RlanNCdWlsZFJlc291cmNlUHJvcHNbJ3NvdXJjZXMnXSA9IHByb3BzLmFzc2V0cy5tYXAoKHMsIGkpID0+ICh7XG4gICAgICBzb3VyY2VCdWNrZXROYW1lOiBhc3NldHNbaV0uczNCdWNrZXROYW1lLFxuICAgICAgc291cmNlT2JqZWN0S2V5OiBhc3NldHNbaV0uczNPYmplY3RLZXksXG4gICAgICBleHRyYWN0UGF0aDogcy5leHRyYWN0UGF0aCA/PyBiYXNlbmFtZShzLnBhdGgpLFxuICAgICAgY29tbWFuZHM6IHMuY29tbWFuZHMsXG4gICAgfSkpO1xuXG4gICAgY29uc3QgcHJvcGVydGllczogTm9kZWpzQnVpbGRSZXNvdXJjZVByb3BzID0ge1xuICAgICAgdHlwZTogJ05vZGVqc0J1aWxkJyxcbiAgICAgIHNvdXJjZXMsXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldE5hbWU6IGJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgd29ya2luZ0RpcmVjdG9yeTogc291cmNlc1swXS5leHRyYWN0UGF0aCxcbiAgICAgIC8vIGpvaW4gcGF0aHMgZm9yIENvZGVCdWlsZCAoTGludXgpIHBsYXRmb3JtXG4gICAgICBvdXRwdXRTb3VyY2VEaXJlY3Rvcnk6IHBvc2l4LmpvaW4oc291cmNlc1swXS5leHRyYWN0UGF0aCwgcHJvcHMub3V0cHV0U291cmNlRGlyZWN0b3J5KSxcbiAgICAgIGVudmlyb25tZW50OiBwcm9wcy5idWlsZEVudmlyb25tZW50LFxuICAgICAgYnVpbGRDb21tYW5kczogcHJvcHMuYnVpbGRDb21tYW5kcyA/PyBbJ25wbSBydW4gYnVpbGQnXSxcbiAgICAgIGNvZGVCdWlsZFByb2plY3ROYW1lOiBwcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgb3V0cHV0RW52RmlsZTogcHJvcHMub3V0cHV0RW52RmlsZSA/PyBmYWxzZSxcbiAgICB9O1xuXG4gICAgY29uc3QgY3VzdG9tID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogaGFuZGxlci5mdW5jdGlvbkFybixcbiAgICAgIHJlc291cmNlVHlwZTogJ0N1c3RvbTo6Q0RLTm9kZWpzQnVpbGQnLFxuICAgICAgcHJvcGVydGllcyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlcGxveSA9IG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsICdEZXBsb3knLCB7XG4gICAgICBzb3VyY2VzOiBbU291cmNlLmJ1Y2tldChidWNrZXQsIGN1c3RvbS5nZXRBdHRTdHJpbmcoZGVzdGluYXRpb25PYmplY3RLZXlPdXRwdXRLZXkpKV0sXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogcHJvcHMuZGVzdGluYXRpb25CdWNrZXQsXG4gICAgICBkZXN0aW5hdGlvbktleVByZWZpeDogcHJvcHMuZGVzdGluYXRpb25LZXlQcmVmaXgsXG4gICAgICBkaXN0cmlidXRpb246IHByb3BzLmRpc3RyaWJ1dGlvbixcbiAgICAgIG1lbW9yeUxpbWl0OiA1MTIsIC8vIHNvbWV0aW1lcyB0aW1lb3V0IG9uIGRlZmF1bHQgKDEyOE1CKSBtZW1vcnlcbiAgICB9KTtcblxuICAgIGRlcGxveS5ub2RlLmFkZERlcGVuZGVuY3koY3VzdG9tKTtcblxuICAgIGlmIChwcm9wcy5vdXRwdXRFbnZGaWxlKSB7XG4gICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdEb3dubG9hZEVudkZpbGUnLCB7IHZhbHVlOiBgYXdzIHMzIGNwICR7YnVja2V0LnMzVXJsRm9yT2JqZWN0KGN1c3RvbS5nZXRBdHRTdHJpbmcoZW52RmlsZUtleU91dHB1dEtleSkpfSAuZW52LmxvY2FsYCB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==