token-injectable-docker-builder 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +26 -7
- package/API.md +17 -0
- package/README.md +3 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +22 -10
- package/package.json +1 -1
package/.jsii
CHANGED
|
@@ -8536,7 +8536,7 @@
|
|
|
8536
8536
|
},
|
|
8537
8537
|
"name": "token-injectable-docker-builder",
|
|
8538
8538
|
"readme": {
|
|
8539
|
-
"markdown": "# TokenInjectableDockerBuilder\n\nThe `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables the usage of AWS CDK tokens in the building, pushing, and deployment of Docker images to Amazon Elastic Container Registry (ECR). It leverages AWS CodeBuild and Lambda custom resources.\n\n---\n\n## Why?\n\nAWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these constructs are limited because they cannot accept CDK tokens as build-args. The `TokenInjectableDockerBuilder` allows injecting CDK tokens as build-time arguments into Docker-based assets, enabling more dynamic dependency relationships.\n\nFor example, a Next.js frontend Docker image may require an API Gateway URL as an argument to create a reference from the UI to the associated API in a given deployment. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image. As a result, your Next.js frontend can dynamically fetch data from the API Gateway without hardcoding the URL or needing multiple separate stacks.\n\n---\n\n## Features\n\n- **Build and Push Docker Images**: Automatically builds and pushes Docker images to ECR.\n- **Token Support**: Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.\n- **Custom Install and Pre-Build Commands**: Allows specifying custom commands to run during the `install` and `pre_build` phases of the CodeBuild build process.\n- **VPC Configuration**: Supports deploying the CodeBuild project within a VPC, with customizable security groups and subnet selection.\n- **Docker Login**: Supports Docker login using credentials stored in AWS Secrets Manager.\n- **ECR Repository Management**: Creates an ECR repository with lifecycle rules and encryption.\n- **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.\n- **Custom Build Query Interval**: Configure how frequently the custom resource polls for build completion using the `completenessQueryInterval` property (defaults to 30 seconds).\n- **Custom Dockerfile**: Specify a custom Dockerfile name via the `file` property (e.g. `Dockerfile.production`), allowing multiple Docker images from the same source directory.\n\n---\n\n## Installation\n\n### For NPM\n\nInstall the construct using NPM:\n\n```bash\nnpm install token-injectable-docker-builder\n```\n\n### For Python\n\nInstall the construct using pip:\n\n```bash\npip install token-injectable-docker-builder\n```\n\n---\n\n## Constructor\n\n### `TokenInjectableDockerBuilder`\n\n#### Parameters\n\n- **`scope`**: The construct's parent scope.\n- **`id`**: The construct ID.\n- **`props`**: Configuration properties.\n\n#### Properties in `TokenInjectableDockerBuilderProps`\n\n| Property | Type | Required | Description |\n|----------------------------|-----------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |\n| `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. These are transformed into `--build-arg` flags. To use in Dockerfile, leverage the `ARG` keyword. For more details, please see the [official Docker docs](https://docs.docker.com/build/building/variables/). |\n| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |\n| `vpc` | `IVpc` | No | The VPC in which the CodeBuild project will be deployed. If provided, the CodeBuild project will be launched within the specified VPC. |\n| `securityGroups` | `ISecurityGroup[]` | No | The security groups to attach to the CodeBuild project. These should define the network access rules for the CodeBuild project. |\n| `subnetSelection` | `SubnetSelection` | No | The subnet selection to specify which subnets to use within the VPC. Allows the user to select private, public, or isolated subnets. |\n| `installCommands` | `string[]` | No | Custom commands to run during the `install` phase of the CodeBuild build process. Will be executed before the Docker image is built. Useful for installing necessary dependencies for running pre-build scripts. |\n| `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. Will be executed before the Docker image is built. Useful for running pre-build scripts, such as fetching configs. |\n| `kmsEncryption` | `boolean` | No | Whether to enable KMS encryption for the ECR repository. If `true`, a KMS key will be created for encrypting ECR images; otherwise, AES-256 encryption is used. Defaults to `false`. |\n| `completenessQueryInterval`| `Duration` | No | The query interval for checking if the CodeBuild project has completed. This determines how frequently the custom resource polls for build completion. Defaults to `Duration.seconds(30)`. |\n| `exclude` | `string[]` | No | A list of file paths in the Docker directory to exclude from the S3 asset bundle. If a `.dockerignore` file is present in the source directory, its contents will be used if this prop is not set. Defaults to an empty list or `.dockerignore` contents. |\n| `file` | `string` | No | The name of the Dockerfile to use for the build. Passed as `--file` to `docker build`. Useful when a project has multiple Dockerfiles (e.g. `Dockerfile.production`, `Dockerfile.admin`). Defaults to `Dockerfile`. |\n\n---\n\n## Usage Examples\n\n### Simple Usage Example\n\nThis example demonstrates the basic usage of the `TokenInjectableDockerBuilder`, where a Next.js frontend Docker image requires an API Gateway URL as a build argument to create a reference from the UI to the associated API in a given deployment.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\n\nexport class SimpleStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Create your API Gateway\n const api = new apigateway.RestApi(this, 'MyApiGateway', {\n restApiName: 'MyService',\n });\n\n // Create the Docker builder\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {\n path: './nextjs-app', // Path to your Next.js app Docker context\n buildArgs: {\n API_URL: api.url, // Pass the API Gateway URL as a build argument\n },\n // Optionally override the default completeness query interval:\n // completenessQueryInterval: cdk.Duration.seconds(45),\n });\n\n // Use in ECS\n const cluster = new ecs.Cluster(this, 'EcsCluster', {\n vpc: new ec2.Vpc(this, 'Vpc'),\n });\n\n const service = new ecs.FargateService(this, 'FargateService', {\n cluster,\n taskDefinition: new ecs.FargateTaskDefinition(this, 'TaskDef', {\n cpu: 512,\n memoryLimitMiB: 1024,\n }).addContainer('Container', {\n image: dockerBuilder.containerImage,\n logging: ecs.LogDriver.awsLogs({ streamPrefix: 'MyApp' }),\n }),\n });\n\n service.node.addDependency(dockerBuilder);\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_ec2 as ec2,\n aws_apigateway as apigateway,\n Duration,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass SimpleStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Create your API Gateway\n api = apigateway.RestApi(self, \"MyApiGateway\",\n rest_api_name=\"MyService\",\n )\n\n # Create the Docker builder\n docker_builder = TokenInjectableDockerBuilder(self, \"SimpleDockerBuilder\",\n path=\"./nextjs-app\", # Path to your Next.js app Docker context\n build_args={\n \"API_URL\": api.url, # Pass the API Gateway URL as a build argument\n },\n # Optionally override the default completeness query interval:\n # completeness_query_interval=Duration.seconds(45)\n )\n\n # Use in ECS\n vpc = ec2.Vpc(self, \"Vpc\")\n cluster = ecs.Cluster(self, \"EcsCluster\", vpc=vpc)\n\n task_definition = ecs.FargateTaskDefinition(self, \"TaskDef\",\n cpu=512,\n memory_limit_mib=1024,\n )\n\n task_definition.node.add_dependency(docker_builder)\n\n task_definition.add_container(\"Container\",\n image=docker_builder.container_image,\n logging=ecs.LogDriver.aws_logs(stream_prefix=\"MyApp\"),\n )\n\n ecs.FargateService(self, \"FargateService\",\n cluster=cluster,\n task_definition=task_definition,\n )\n```\n\n---\n\n### Advanced Usage Example\n\nBuilding on the previous example, this advanced usage demonstrates how to include additional configurations, such as fetching private API endpoints and configuration files during the build process.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\n\nexport class AdvancedStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Create your API Gateway\n const api = new apigateway.RestApi(this, 'MyApiGateway', {\n restApiName: 'MyService',\n });\n\n // VPC and Security Group for CodeBuild\n const vpc = new ec2.Vpc(this, 'MyVpc');\n const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {\n vpc,\n });\n\n // Create the Docker builder with additional pre-build commands\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'AdvancedDockerBuilder', {\n path: './nextjs-app',\n buildArgs: {\n API_URL: api.url,\n },\n vpc,\n securityGroups: [securityGroup],\n subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },\n installCommands: [\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing necessary packages...\"',\n 'apt-get install -y curl',\n ],\n preBuildCommands: [\n 'echo \"Fetching private API configuration...\"',\n // Replace with your actual command to fetch configs\n 'curl -o config.json https://internal-api.example.com/config',\n ],\n // Optionally override the default completeness query interval:\n // completenessQueryInterval: cdk.Duration.seconds(45),\n });\n\n // Use in ECS\n const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc });\n\n const service = new ecs.FargateService(this, 'FargateService', {\n cluster,\n taskDefinition: new ecs.FargateTaskDefinition(this, 'TaskDef', {\n cpu: 512,\n memoryLimitMiB: 1024,\n }).addContainer('Container', {\n image: dockerBuilder.containerImage,\n logging: ecs.LogDriver.awsLogs({ streamPrefix: 'MyApp' }),\n }),\n });\n\n service.node.addDependency(dockerBuilder);\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_ec2 as ec2,\n aws_apigateway as apigateway,\n Duration,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass AdvancedStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Create your API Gateway\n api = apigateway.RestApi(self, \"MyApiGateway\",\n rest_api_name=\"MyService\",\n )\n\n # VPC and Security Group for CodeBuild\n vpc = ec2.Vpc(self, \"MyVpc\")\n security_group = ec2.SecurityGroup(self, \"MySecurityGroup\", vpc=vpc)\n\n # Create the Docker builder with additional pre-build commands\n docker_builder = TokenInjectableDockerBuilder(self, \"AdvancedDockerBuilder\",\n path=\"./nextjs-app\",\n build_args={\n \"API_URL\": api.url,\n },\n vpc=vpc,\n security_groups=[security_group],\n subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),\n install_commands=[\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing necessary packages...\"',\n 'apt-get install -y curl',\n ],\n pre_build_commands=[\n 'echo \"Fetching private API configuration...\"',\n # Replace with your actual command to fetch configs\n 'curl -o config.json https://internal-api.example.com/config',\n ],\n # Optionally override the default completeness query interval:\n # completeness_query_interval=Duration.seconds(45)\n )\n\n # Use in ECS\n cluster = ecs.Cluster(self, \"EcsCluster\", vpc=vpc)\n\n task_definition = ecs.FargateTaskDefinition(self, \"TaskDef\",\n cpu=512,\n memory_limit_mib=1024,\n )\n\n task_definition.node.add_dependency(docker_builder)\n\n task_definition.add_container(\"Container\",\n image=docker_builder.container_image,\n logging=ecs.LogDriver.aws_logs(stream_prefix=\"MyApp\"),\n )\n\n ecs.FargateService(self, \"FargateService\",\n cluster=cluster,\n task_definition=task_definition,\n )\n```\n\nIn this advanced example:\n\n- **VPC Configuration**: The CodeBuild project is configured to run inside a VPC with specified security groups and subnet selection, allowing it to access internal resources such as a private API endpoint.\n- **Custom Install and Pre-Build Commands**: The `installCommands` and `preBuildCommands` properties are used to install necessary packages and fetch configuration files from a private API before building the Docker image.\n- **Access to Internal APIs**: By running inside a VPC and configuring the security groups appropriately, the CodeBuild project can access private endpoints not accessible over the public internet.\n\n---\n\n## How It Works\n\n1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.\n2. **CodeBuild Project**:\n - Uses the packaged asset and `buildArgs` to build the Docker image.\n - Executes any custom `installCommands` and `preBuildCommands` during the build process.\n - Pushes the image to an ECR repository.\n3. **Custom Resource**:\n - Triggers the build process using a Lambda function (`onEvent`).\n - Monitors the build status using another Lambda function (`isComplete`) which polls at the interval specified by `completenessQueryInterval` (defaulting to 30 seconds if not provided).\n4. **Outputs**:\n - `.containerImage`: Returns the Docker image for ECS.\n - `.dockerImageCode`: Returns the Docker image code for Lambda.\n\n---\n\n## IAM Permissions\n\nThe construct automatically grants permissions for:\n\n- **CodeBuild**:\n - Pull and push images to ECR.\n - Access to AWS Secrets Manager if `dockerLoginSecretArn` is provided.\n - Access to the KMS key for encryption.\n- **Lambda Functions**:\n - Start and monitor CodeBuild builds.\n - Access CloudWatch Logs.\n - Access to the KMS key for encryption.\n - Pull and push images to ECR.\n\n---\n\n## Notes\n\n- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags. CDK tokens can be used to inject dynamic values resolved at deployment time.\n- **Custom Commands**: Use `installCommands` and `preBuildCommands` to run custom shell commands during the build process. This can be useful for installing dependencies or fetching configuration files.\n- **VPC Configuration**: If your build process requires access to resources within a VPC, you can specify the VPC, security groups, and subnet selection.\n- **Docker Login**: If you need to log in to a private Docker registry before building the image, provide the ARN of a secret in AWS Secrets Manager containing the Docker credentials.\n- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.\n- **Build Query Interval**: The polling frequency for checking build completion can be customized via the `completenessQueryInterval` property.\n- **Custom Dockerfile**: Use the `file` property to specify a Dockerfile other than the default `Dockerfile`. This is passed as the `--file` flag to `docker build`.\n\n---\n\n## Troubleshooting\n\n1. **Build Errors**: Check the CodeBuild logs in CloudWatch Logs for detailed error messages.\n2. **Lambda Errors**: Check the `onEvent` and `isComplete` Lambda function logs in CloudWatch Logs.\n3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, Secrets Manager, and KMS if applicable.\n4. **Network Access**: If the build requires network access (e.g., to download dependencies or access internal APIs), ensure that the VPC configuration allows necessary network connectivity, and adjust security group rules accordingly.\n\n---\n\n## Support\n\nFor issues or feature requests, please open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).\n\n---\n\n## Reference Links\n\n[](https://constructs.dev/packages/token-injectable-docker-builder)\n\n---\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n\n---\n\n## Acknowledgements\n\n- Inspired by the need for more dynamic Docker asset management in AWS CDK.\n- Thanks to the AWS CDK community for their continuous support and contributions.\n\n---\n\nFeel free to reach out if you have any questions or need further assistance!\n"
|
|
8539
|
+
"markdown": "# TokenInjectableDockerBuilder\n\nThe `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables the usage of AWS CDK tokens in the building, pushing, and deployment of Docker images to Amazon Elastic Container Registry (ECR). It leverages AWS CodeBuild and Lambda custom resources.\n\n---\n\n## Why?\n\nAWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these constructs are limited because they cannot accept CDK tokens as build-args. The `TokenInjectableDockerBuilder` allows injecting CDK tokens as build-time arguments into Docker-based assets, enabling more dynamic dependency relationships.\n\nFor example, a Next.js frontend Docker image may require an API Gateway URL as an argument to create a reference from the UI to the associated API in a given deployment. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image. As a result, your Next.js frontend can dynamically fetch data from the API Gateway without hardcoding the URL or needing multiple separate stacks.\n\n---\n\n## Features\n\n- **Build and Push Docker Images**: Automatically builds and pushes Docker images to ECR.\n- **Token Support**: Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.\n- **Custom Install and Pre-Build Commands**: Allows specifying custom commands to run during the `install` and `pre_build` phases of the CodeBuild build process.\n- **VPC Configuration**: Supports deploying the CodeBuild project within a VPC, with customizable security groups and subnet selection.\n- **Docker Login**: Supports Docker login using credentials stored in AWS Secrets Manager.\n- **ECR Repository Management**: Creates an ECR repository with lifecycle rules and encryption.\n- **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.\n- **Custom Build Query Interval**: Configure how frequently the custom resource polls for build completion using the `completenessQueryInterval` property (defaults to 30 seconds).\n- **Custom Dockerfile**: Specify a custom Dockerfile name via the `file` property (e.g. `Dockerfile.production`), allowing multiple Docker images from the same source directory.\n- **ECR Docker Layer Caching**: By default, builds use `docker buildx` with ECR as a remote cache backend, reducing build times by reusing layers across deploys. Set `cacheDisabled: true` to force a clean build from scratch.\n\n---\n\n## Installation\n\n### For NPM\n\nInstall the construct using NPM:\n\n```bash\nnpm install token-injectable-docker-builder\n```\n\n### For Python\n\nInstall the construct using pip:\n\n```bash\npip install token-injectable-docker-builder\n```\n\n---\n\n## Constructor\n\n### `TokenInjectableDockerBuilder`\n\n#### Parameters\n\n- **`scope`**: The construct's parent scope.\n- **`id`**: The construct ID.\n- **`props`**: Configuration properties.\n\n#### Properties in `TokenInjectableDockerBuilderProps`\n\n| Property | Type | Required | Description |\n|----------------------------|-----------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |\n| `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. These are transformed into `--build-arg` flags. To use in Dockerfile, leverage the `ARG` keyword. For more details, please see the [official Docker docs](https://docs.docker.com/build/building/variables/). |\n| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |\n| `vpc` | `IVpc` | No | The VPC in which the CodeBuild project will be deployed. If provided, the CodeBuild project will be launched within the specified VPC. |\n| `securityGroups` | `ISecurityGroup[]` | No | The security groups to attach to the CodeBuild project. These should define the network access rules for the CodeBuild project. |\n| `subnetSelection` | `SubnetSelection` | No | The subnet selection to specify which subnets to use within the VPC. Allows the user to select private, public, or isolated subnets. |\n| `installCommands` | `string[]` | No | Custom commands to run during the `install` phase of the CodeBuild build process. Will be executed before the Docker image is built. Useful for installing necessary dependencies for running pre-build scripts. |\n| `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. Will be executed before the Docker image is built. Useful for running pre-build scripts, such as fetching configs. |\n| `kmsEncryption` | `boolean` | No | Whether to enable KMS encryption for the ECR repository. If `true`, a KMS key will be created for encrypting ECR images; otherwise, AES-256 encryption is used. Defaults to `false`. |\n| `completenessQueryInterval`| `Duration` | No | The query interval for checking if the CodeBuild project has completed. This determines how frequently the custom resource polls for build completion. Defaults to `Duration.seconds(30)`. |\n| `exclude` | `string[]` | No | A list of file paths in the Docker directory to exclude from the S3 asset bundle. If a `.dockerignore` file is present in the source directory, its contents will be used if this prop is not set. Defaults to an empty list or `.dockerignore` contents. |\n| `file` | `string` | No | The name of the Dockerfile to use for the build. Passed as `--file` to `docker build`. Useful when a project has multiple Dockerfiles (e.g. `Dockerfile.production`, `Dockerfile.admin`). Defaults to `Dockerfile`. |\n| `cacheDisabled` | `boolean` | No | When `true`, disables Docker layer caching. Every build runs from scratch. Use for debugging, corrupted cache, or major dependency changes. Defaults to `false`. |\n\n---\n\n## Usage Examples\n\n### Simple Usage Example\n\nThis example demonstrates the basic usage of the `TokenInjectableDockerBuilder`, where a Next.js frontend Docker image requires an API Gateway URL as a build argument to create a reference from the UI to the associated API in a given deployment.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\n\nexport class SimpleStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Create your API Gateway\n const api = new apigateway.RestApi(this, 'MyApiGateway', {\n restApiName: 'MyService',\n });\n\n // Create the Docker builder\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {\n path: './nextjs-app', // Path to your Next.js app Docker context\n buildArgs: {\n API_URL: api.url, // Pass the API Gateway URL as a build argument\n },\n // Optionally override the default completeness query interval:\n // completenessQueryInterval: cdk.Duration.seconds(45),\n });\n\n // Use in ECS\n const cluster = new ecs.Cluster(this, 'EcsCluster', {\n vpc: new ec2.Vpc(this, 'Vpc'),\n });\n\n const service = new ecs.FargateService(this, 'FargateService', {\n cluster,\n taskDefinition: new ecs.FargateTaskDefinition(this, 'TaskDef', {\n cpu: 512,\n memoryLimitMiB: 1024,\n }).addContainer('Container', {\n image: dockerBuilder.containerImage,\n logging: ecs.LogDriver.awsLogs({ streamPrefix: 'MyApp' }),\n }),\n });\n\n service.node.addDependency(dockerBuilder);\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_ec2 as ec2,\n aws_apigateway as apigateway,\n Duration,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass SimpleStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Create your API Gateway\n api = apigateway.RestApi(self, \"MyApiGateway\",\n rest_api_name=\"MyService\",\n )\n\n # Create the Docker builder\n docker_builder = TokenInjectableDockerBuilder(self, \"SimpleDockerBuilder\",\n path=\"./nextjs-app\", # Path to your Next.js app Docker context\n build_args={\n \"API_URL\": api.url, # Pass the API Gateway URL as a build argument\n },\n # Optionally override the default completeness query interval:\n # completeness_query_interval=Duration.seconds(45)\n )\n\n # Use in ECS\n vpc = ec2.Vpc(self, \"Vpc\")\n cluster = ecs.Cluster(self, \"EcsCluster\", vpc=vpc)\n\n task_definition = ecs.FargateTaskDefinition(self, \"TaskDef\",\n cpu=512,\n memory_limit_mib=1024,\n )\n\n task_definition.node.add_dependency(docker_builder)\n\n task_definition.add_container(\"Container\",\n image=docker_builder.container_image,\n logging=ecs.LogDriver.aws_logs(stream_prefix=\"MyApp\"),\n )\n\n ecs.FargateService(self, \"FargateService\",\n cluster=cluster,\n task_definition=task_definition,\n )\n```\n\n---\n\n### Advanced Usage Example\n\nBuilding on the previous example, this advanced usage demonstrates how to include additional configurations, such as fetching private API endpoints and configuration files during the build process.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\n\nexport class AdvancedStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Create your API Gateway\n const api = new apigateway.RestApi(this, 'MyApiGateway', {\n restApiName: 'MyService',\n });\n\n // VPC and Security Group for CodeBuild\n const vpc = new ec2.Vpc(this, 'MyVpc');\n const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {\n vpc,\n });\n\n // Create the Docker builder with additional pre-build commands\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'AdvancedDockerBuilder', {\n path: './nextjs-app',\n buildArgs: {\n API_URL: api.url,\n },\n vpc,\n securityGroups: [securityGroup],\n subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },\n installCommands: [\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing necessary packages...\"',\n 'apt-get install -y curl',\n ],\n preBuildCommands: [\n 'echo \"Fetching private API configuration...\"',\n // Replace with your actual command to fetch configs\n 'curl -o config.json https://internal-api.example.com/config',\n ],\n // Optionally override the default completeness query interval:\n // completenessQueryInterval: cdk.Duration.seconds(45),\n });\n\n // Use in ECS\n const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc });\n\n const service = new ecs.FargateService(this, 'FargateService', {\n cluster,\n taskDefinition: new ecs.FargateTaskDefinition(this, 'TaskDef', {\n cpu: 512,\n memoryLimitMiB: 1024,\n }).addContainer('Container', {\n image: dockerBuilder.containerImage,\n logging: ecs.LogDriver.awsLogs({ streamPrefix: 'MyApp' }),\n }),\n });\n\n service.node.addDependency(dockerBuilder);\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_ec2 as ec2,\n aws_apigateway as apigateway,\n Duration,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass AdvancedStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Create your API Gateway\n api = apigateway.RestApi(self, \"MyApiGateway\",\n rest_api_name=\"MyService\",\n )\n\n # VPC and Security Group for CodeBuild\n vpc = ec2.Vpc(self, \"MyVpc\")\n security_group = ec2.SecurityGroup(self, \"MySecurityGroup\", vpc=vpc)\n\n # Create the Docker builder with additional pre-build commands\n docker_builder = TokenInjectableDockerBuilder(self, \"AdvancedDockerBuilder\",\n path=\"./nextjs-app\",\n build_args={\n \"API_URL\": api.url,\n },\n vpc=vpc,\n security_groups=[security_group],\n subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),\n install_commands=[\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing necessary packages...\"',\n 'apt-get install -y curl',\n ],\n pre_build_commands=[\n 'echo \"Fetching private API configuration...\"',\n # Replace with your actual command to fetch configs\n 'curl -o config.json https://internal-api.example.com/config',\n ],\n # Optionally override the default completeness query interval:\n # completeness_query_interval=Duration.seconds(45)\n )\n\n # Use in ECS\n cluster = ecs.Cluster(self, \"EcsCluster\", vpc=vpc)\n\n task_definition = ecs.FargateTaskDefinition(self, \"TaskDef\",\n cpu=512,\n memory_limit_mib=1024,\n )\n\n task_definition.node.add_dependency(docker_builder)\n\n task_definition.add_container(\"Container\",\n image=docker_builder.container_image,\n logging=ecs.LogDriver.aws_logs(stream_prefix=\"MyApp\"),\n )\n\n ecs.FargateService(self, \"FargateService\",\n cluster=cluster,\n task_definition=task_definition,\n )\n```\n\nIn this advanced example:\n\n- **VPC Configuration**: The CodeBuild project is configured to run inside a VPC with specified security groups and subnet selection, allowing it to access internal resources such as a private API endpoint.\n- **Custom Install and Pre-Build Commands**: The `installCommands` and `preBuildCommands` properties are used to install necessary packages and fetch configuration files from a private API before building the Docker image.\n- **Access to Internal APIs**: By running inside a VPC and configuring the security groups appropriately, the CodeBuild project can access private endpoints not accessible over the public internet.\n\n---\n\n## How It Works\n\n1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.\n2. **CodeBuild Project**:\n - Uses the packaged asset and `buildArgs` to build the Docker image.\n - Executes any custom `installCommands` and `preBuildCommands` during the build process.\n - Pushes the image to an ECR repository.\n3. **Custom Resource**:\n - Triggers the build process using a Lambda function (`onEvent`).\n - Monitors the build status using another Lambda function (`isComplete`) which polls at the interval specified by `completenessQueryInterval` (defaulting to 30 seconds if not provided).\n4. **Outputs**:\n - `.containerImage`: Returns the Docker image for ECS.\n - `.dockerImageCode`: Returns the Docker image code for Lambda.\n\n---\n\n## IAM Permissions\n\nThe construct automatically grants permissions for:\n\n- **CodeBuild**:\n - Pull and push images to ECR.\n - Access to AWS Secrets Manager if `dockerLoginSecretArn` is provided.\n - Access to the KMS key for encryption.\n- **Lambda Functions**:\n - Start and monitor CodeBuild builds.\n - Access CloudWatch Logs.\n - Access to the KMS key for encryption.\n - Pull and push images to ECR.\n\n---\n\n## Notes\n\n- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags. CDK tokens can be used to inject dynamic values resolved at deployment time.\n- **Custom Commands**: Use `installCommands` and `preBuildCommands` to run custom shell commands during the build process. This can be useful for installing dependencies or fetching configuration files.\n- **VPC Configuration**: If your build process requires access to resources within a VPC, you can specify the VPC, security groups, and subnet selection.\n- **Docker Login**: If you need to log in to a private Docker registry before building the image, provide the ARN of a secret in AWS Secrets Manager containing the Docker credentials.\n- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.\n- **Build Query Interval**: The polling frequency for checking build completion can be customized via the `completenessQueryInterval` property.\n- **Custom Dockerfile**: Use the `file` property to specify a Dockerfile other than the default `Dockerfile`. This is passed as the `--file` flag to `docker build`.\n- **Docker Layer Caching**: By default, builds use ECR as a remote cache backend (via `docker buildx`), which can reduce build times by up to 25%. Set `cacheDisabled: true` when you need a clean build—for example, when debugging, the cache is corrupted, or after major dependency upgrades.\n\n---\n\n## Troubleshooting\n\n1. **Build Errors**: Check the CodeBuild logs in CloudWatch Logs for detailed error messages.\n2. **Lambda Errors**: Check the `onEvent` and `isComplete` Lambda function logs in CloudWatch Logs.\n3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, Secrets Manager, and KMS if applicable.\n4. **Network Access**: If the build requires network access (e.g., to download dependencies or access internal APIs), ensure that the VPC configuration allows necessary network connectivity, and adjust security group rules accordingly.\n\n---\n\n## Support\n\nFor issues or feature requests, please open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).\n\n---\n\n## Reference Links\n\n[](https://constructs.dev/packages/token-injectable-docker-builder)\n\n---\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n\n---\n\n## Acknowledgements\n\n- Inspired by the need for more dynamic Docker asset management in AWS CDK.\n- Thanks to the AWS CDK community for their continuous support and contributions.\n\n---\n\nFeel free to reach out if you have any questions or need further assistance!\n"
|
|
8540
8540
|
},
|
|
8541
8541
|
"repository": {
|
|
8542
8542
|
"type": "git",
|
|
@@ -8568,7 +8568,7 @@
|
|
|
8568
8568
|
},
|
|
8569
8569
|
"locationInModule": {
|
|
8570
8570
|
"filename": "src/index.ts",
|
|
8571
|
-
"line":
|
|
8571
|
+
"line": 181
|
|
8572
8572
|
},
|
|
8573
8573
|
"parameters": [
|
|
8574
8574
|
{
|
|
@@ -8603,7 +8603,7 @@
|
|
|
8603
8603
|
"kind": "class",
|
|
8604
8604
|
"locationInModule": {
|
|
8605
8605
|
"filename": "src/index.ts",
|
|
8606
|
-
"line":
|
|
8606
|
+
"line": 156
|
|
8607
8607
|
},
|
|
8608
8608
|
"name": "TokenInjectableDockerBuilder",
|
|
8609
8609
|
"properties": [
|
|
@@ -8615,7 +8615,7 @@
|
|
|
8615
8615
|
"immutable": true,
|
|
8616
8616
|
"locationInModule": {
|
|
8617
8617
|
"filename": "src/index.ts",
|
|
8618
|
-
"line":
|
|
8618
|
+
"line": 166
|
|
8619
8619
|
},
|
|
8620
8620
|
"name": "containerImage",
|
|
8621
8621
|
"type": {
|
|
@@ -8630,7 +8630,7 @@
|
|
|
8630
8630
|
"immutable": true,
|
|
8631
8631
|
"locationInModule": {
|
|
8632
8632
|
"filename": "src/index.ts",
|
|
8633
|
-
"line":
|
|
8633
|
+
"line": 172
|
|
8634
8634
|
},
|
|
8635
8635
|
"name": "dockerImageCode",
|
|
8636
8636
|
"type": {
|
|
@@ -8695,6 +8695,25 @@
|
|
|
8695
8695
|
}
|
|
8696
8696
|
}
|
|
8697
8697
|
},
|
|
8698
|
+
{
|
|
8699
|
+
"abstract": true,
|
|
8700
|
+
"docs": {
|
|
8701
|
+
"default": "false",
|
|
8702
|
+
"remarks": "Every build runs from scratch.\nUse for debugging, corrupted cache, or major dependency changes.",
|
|
8703
|
+
"stability": "stable",
|
|
8704
|
+
"summary": "When `true`, disables Docker layer caching."
|
|
8705
|
+
},
|
|
8706
|
+
"immutable": true,
|
|
8707
|
+
"locationInModule": {
|
|
8708
|
+
"filename": "src/index.ts",
|
|
8709
|
+
"line": 148
|
|
8710
|
+
},
|
|
8711
|
+
"name": "cacheDisabled",
|
|
8712
|
+
"optional": true,
|
|
8713
|
+
"type": {
|
|
8714
|
+
"primitive": "boolean"
|
|
8715
|
+
}
|
|
8716
|
+
},
|
|
8698
8717
|
{
|
|
8699
8718
|
"abstract": true,
|
|
8700
8719
|
"docs": {
|
|
@@ -8910,6 +8929,6 @@
|
|
|
8910
8929
|
"symbolId": "src/index:TokenInjectableDockerBuilderProps"
|
|
8911
8930
|
}
|
|
8912
8931
|
},
|
|
8913
|
-
"version": "1.
|
|
8914
|
-
"fingerprint": "
|
|
8932
|
+
"version": "1.7.0",
|
|
8933
|
+
"fingerprint": "vr37Zm1lHQnZYkFEo0ctdMq7hlp3LsLBksuoVKzit6A="
|
|
8915
8934
|
}
|
package/API.md
CHANGED
|
@@ -155,6 +155,7 @@ const tokenInjectableDockerBuilderProps: TokenInjectableDockerBuilderProps = { .
|
|
|
155
155
|
| --- | --- | --- |
|
|
156
156
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.path">path</a></code> | <code>string</code> | The path to the directory containing the Dockerfile or source code. |
|
|
157
157
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.buildArgs">buildArgs</a></code> | <code>{[ key: string ]: string}</code> | Build arguments to pass to the Docker build process. |
|
|
158
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.cacheDisabled">cacheDisabled</a></code> | <code>boolean</code> | When `true`, disables Docker layer caching. |
|
|
158
159
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.completenessQueryInterval">completenessQueryInterval</a></code> | <code>aws-cdk-lib.Duration</code> | The query interval for checking if the CodeBuild project has completed. |
|
|
159
160
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.dockerLoginSecretArn">dockerLoginSecretArn</a></code> | <code>string</code> | The ARN of the AWS Secrets Manager secret containing Docker login credentials. |
|
|
160
161
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.exclude">exclude</a></code> | <code>string[]</code> | A list of file paths in the Docker directory to exclude from build. |
|
|
@@ -204,6 +205,22 @@ These are transformed into `--build-arg KEY=VALUE` flags.
|
|
|
204
205
|
```
|
|
205
206
|
|
|
206
207
|
|
|
208
|
+
##### `cacheDisabled`<sup>Optional</sup> <a name="cacheDisabled" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.cacheDisabled"></a>
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
public readonly cacheDisabled: boolean;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
- *Type:* boolean
|
|
215
|
+
- *Default:* false
|
|
216
|
+
|
|
217
|
+
When `true`, disables Docker layer caching.
|
|
218
|
+
|
|
219
|
+
Every build runs from scratch.
|
|
220
|
+
Use for debugging, corrupted cache, or major dependency changes.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
207
224
|
##### `completenessQueryInterval`<sup>Optional</sup> <a name="completenessQueryInterval" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.completenessQueryInterval"></a>
|
|
208
225
|
|
|
209
226
|
```typescript
|
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ For example, a Next.js frontend Docker image may require an API Gateway URL as a
|
|
|
23
23
|
- **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.
|
|
24
24
|
- **Custom Build Query Interval**: Configure how frequently the custom resource polls for build completion using the `completenessQueryInterval` property (defaults to 30 seconds).
|
|
25
25
|
- **Custom Dockerfile**: Specify a custom Dockerfile name via the `file` property (e.g. `Dockerfile.production`), allowing multiple Docker images from the same source directory.
|
|
26
|
+
- **ECR Docker Layer Caching**: By default, builds use `docker buildx` with ECR as a remote cache backend, reducing build times by reusing layers across deploys. Set `cacheDisabled: true` to force a clean build from scratch.
|
|
26
27
|
|
|
27
28
|
---
|
|
28
29
|
|
|
@@ -72,6 +73,7 @@ pip install token-injectable-docker-builder
|
|
|
72
73
|
| `completenessQueryInterval`| `Duration` | No | The query interval for checking if the CodeBuild project has completed. This determines how frequently the custom resource polls for build completion. Defaults to `Duration.seconds(30)`. |
|
|
73
74
|
| `exclude` | `string[]` | No | A list of file paths in the Docker directory to exclude from the S3 asset bundle. If a `.dockerignore` file is present in the source directory, its contents will be used if this prop is not set. Defaults to an empty list or `.dockerignore` contents. |
|
|
74
75
|
| `file` | `string` | No | The name of the Dockerfile to use for the build. Passed as `--file` to `docker build`. Useful when a project has multiple Dockerfiles (e.g. `Dockerfile.production`, `Dockerfile.admin`). Defaults to `Dockerfile`. |
|
|
76
|
+
| `cacheDisabled` | `boolean` | No | When `true`, disables Docker layer caching. Every build runs from scratch. Use for debugging, corrupted cache, or major dependency changes. Defaults to `false`. |
|
|
75
77
|
|
|
76
78
|
---
|
|
77
79
|
|
|
@@ -377,6 +379,7 @@ The construct automatically grants permissions for:
|
|
|
377
379
|
- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.
|
|
378
380
|
- **Build Query Interval**: The polling frequency for checking build completion can be customized via the `completenessQueryInterval` property.
|
|
379
381
|
- **Custom Dockerfile**: Use the `file` property to specify a Dockerfile other than the default `Dockerfile`. This is passed as the `--file` flag to `docker build`.
|
|
382
|
+
- **Docker Layer Caching**: By default, builds use ECR as a remote cache backend (via `docker buildx`), which can reduce build times by up to 25%. Set `cacheDisabled: true` when you need a clean build—for example, when debugging, the cache is corrupted, or after major dependency upgrades.
|
|
380
383
|
|
|
381
384
|
---
|
|
382
385
|
|
package/lib/index.d.ts
CHANGED
|
@@ -118,6 +118,13 @@ export interface TokenInjectableDockerBuilderProps {
|
|
|
118
118
|
* @default 'Dockerfile'
|
|
119
119
|
*/
|
|
120
120
|
readonly file?: string;
|
|
121
|
+
/**
|
|
122
|
+
* When `true`, disables Docker layer caching. Every build runs from scratch.
|
|
123
|
+
* Use for debugging, corrupted cache, or major dependency changes.
|
|
124
|
+
*
|
|
125
|
+
* @default false
|
|
126
|
+
*/
|
|
127
|
+
readonly cacheDisabled?: boolean;
|
|
121
128
|
}
|
|
122
129
|
/**
|
|
123
130
|
* A CDK construct to build and push Docker images to an ECR repository using
|
package/lib/index.js
CHANGED
|
@@ -31,7 +31,7 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
31
31
|
*/
|
|
32
32
|
constructor(scope, id, props) {
|
|
33
33
|
super(scope, id);
|
|
34
|
-
const { path: sourcePath, buildArgs, dockerLoginSecretArn, vpc, securityGroups, subnetSelection, installCommands, preBuildCommands, kmsEncryption = false, completenessQueryInterval, exclude, file: dockerFile, } = props;
|
|
34
|
+
const { path: sourcePath, buildArgs, dockerLoginSecretArn, vpc, securityGroups, subnetSelection, installCommands, preBuildCommands, kmsEncryption = false, completenessQueryInterval, exclude, file: dockerFile, cacheDisabled = false, } = props;
|
|
35
35
|
// Generate an ephemeral tag for CodeBuild
|
|
36
36
|
const imageTag = crypto.randomUUID();
|
|
37
37
|
// Optionally define a KMS key for ECR encryption if requested
|
|
@@ -94,6 +94,15 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
94
94
|
'echo $DOCKER_PASSWORD | docker login --username $DOCKER_USERNAME --password-stdin',
|
|
95
95
|
]
|
|
96
96
|
: ['echo "No Docker credentials. Skipping Docker Hub login."'];
|
|
97
|
+
const buildxInstallCommands = cacheDisabled
|
|
98
|
+
? []
|
|
99
|
+
: [
|
|
100
|
+
'echo "Setting up Docker buildx for ECR layer cache..."',
|
|
101
|
+
'docker buildx create --driver docker-container --name ecr-cache-builder --use 2>/dev/null || docker buildx use ecr-cache-builder',
|
|
102
|
+
];
|
|
103
|
+
const buildCommand = cacheDisabled
|
|
104
|
+
? `docker build ${dockerFileFlag} ${buildArgsString} -t $ECR_REPO_URI:${imageTag} $CODEBUILD_SRC_DIR`
|
|
105
|
+
: `docker buildx build --push --cache-from type=registry,ref=$ECR_REPO_URI:cache --cache-to type=registry,ref=$ECR_REPO_URI:cache,mode=max,image-manifest=true ${dockerFileFlag} ${buildArgsString} -t $ECR_REPO_URI:${imageTag} $CODEBUILD_SRC_DIR`;
|
|
97
106
|
const buildSpecObj = {
|
|
98
107
|
version: '0.2',
|
|
99
108
|
phases: {
|
|
@@ -101,6 +110,7 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
101
110
|
commands: [
|
|
102
111
|
'echo "Beginning install phase..."',
|
|
103
112
|
...(installCommands ?? []),
|
|
113
|
+
...buildxInstallCommands,
|
|
104
114
|
],
|
|
105
115
|
},
|
|
106
116
|
pre_build: {
|
|
@@ -116,15 +126,17 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
116
126
|
build: {
|
|
117
127
|
commands: [
|
|
118
128
|
`echo "Building Docker image with tag ${imageTag}..."`,
|
|
119
|
-
|
|
120
|
-
],
|
|
121
|
-
},
|
|
122
|
-
post_build: {
|
|
123
|
-
commands: [
|
|
124
|
-
`echo "Pushing Docker image with tag ${imageTag}..."`,
|
|
125
|
-
`docker push $ECR_REPO_URI:${imageTag}`,
|
|
129
|
+
buildCommand,
|
|
126
130
|
],
|
|
127
131
|
},
|
|
132
|
+
...(cacheDisabled && {
|
|
133
|
+
post_build: {
|
|
134
|
+
commands: [
|
|
135
|
+
`echo "Pushing Docker image with tag ${imageTag}..."`,
|
|
136
|
+
`docker push $ECR_REPO_URI:${imageTag}`,
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
128
140
|
},
|
|
129
141
|
};
|
|
130
142
|
// Create the CodeBuild project
|
|
@@ -228,5 +240,5 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
228
240
|
}
|
|
229
241
|
exports.TokenInjectableDockerBuilder = TokenInjectableDockerBuilder;
|
|
230
242
|
_a = JSII_RTTI_SYMBOL_1;
|
|
231
|
-
TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.
|
|
232
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUU3Qiw2Q0FBdUQ7QUFDdkQsNkRBQXdGO0FBRXhGLGlEQUFrRjtBQUNsRixpREFBcUQ7QUFDckQsaURBQXNEO0FBQ3RELGlEQUEwQztBQUMxQyx1REFBa0Y7QUFDbEYsNkRBQWtEO0FBQ2xELG1FQUF3RDtBQUN4RCwyQ0FBdUM7QUFnSXZDOzs7O0dBSUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBa0J6RDs7Ozs7O09BTUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXdDO1FBQ2hGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxFQUNKLElBQUksRUFBRSxVQUFVLEVBQ2hCLFNBQVMsRUFDVCxvQkFBb0IsRUFDcEIsR0FBRyxFQUNILGNBQWMsRUFDZCxlQUFlLEVBQ2YsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixhQUFhLEdBQUcsS0FBSyxFQUNyQix5QkFBeUIsRUFDekIsT0FBTyxFQUNQLElBQUksRUFBRSxVQUFVLEdBQ2pCLEdBQUcsS0FBSyxDQUFDO1FBRVYsMENBQTBDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVyQyw4REFBOEQ7UUFDOUQsSUFBSSxhQUE4QixDQUFDO1FBQ25DLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtnQkFDaEQsaUJBQWlCLEVBQUUsSUFBSTthQUN4QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsNERBQTREO1FBQzVELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxvQkFBVSxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7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LEVBQUUsQ0FBQztTQUNqRSxDQUFDLENBQUM7UUFFSCx1RUFBdUU7UUFDdkUsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLDRCQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQzVFLFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtZQUNuQyxVQUFVLEVBQUU7Z0JBQ1YsV0FBVyxFQUFFLGdCQUFnQixDQUFDLFdBQVc7Z0JBQ3pDLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixPQUFPLEVBQUUsV0FBVyxDQUFDLFNBQVM7YUFDL0I7U0FDRixDQUFDLENBQUM7UUFDSCxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFMUQseURBQXlEO1FBQ3pELE1BQU0sV0FBVyxHQUFHLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsY0FBYyxHQUFHLHdCQUFjLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsZUFBZSxHQUFHLDRCQUFlLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDakUsV0FBVyxFQUFFLFdBQVc7U0FDekIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUF4UUgsb0VBeVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG5pbXBvcnQgeyBDdXN0b21SZXNvdXJjZSwgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBQcm9qZWN0LCBTb3VyY2UsIExpbnV4QnVpbGRJbWFnZSwgQnVpbGRTcGVjIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZCc7XG5pbXBvcnQgeyBJVnBjLCBJU2VjdXJpdHlHcm91cCwgU3VibmV0U2VsZWN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgeyBSZXBvc2l0b3J5LCBSZXBvc2l0b3J5RW5jcnlwdGlvbiwgVGFnU3RhdHVzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjcic7XG5pbXBvcnQgeyBDb250YWluZXJJbWFnZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3MnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBLZXkgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mta21zJztcbmltcG9ydCB7IFJ1bnRpbWUsIENvZGUsIERvY2tlckltYWdlQ29kZSwgRnVuY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IEFzc2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWFzc2V0cyc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgdGhlIGBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyYCBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgRG9ja2VyZmlsZSBvciBzb3VyY2UgY29kZS5cbiAgICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQnVpbGQgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIERvY2tlciBidWlsZCBwcm9jZXNzLlxuICAgKiBUaGVzZSBhcmUgdHJhbnNmb3JtZWQgaW50byBgLS1idWlsZC1hcmcgS0VZPVZBTFVFYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhpcyBzZWNyZXQgc2hvdWxkIHN0b3JlIGEgSlNPTiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJ1c2VybmFtZVwiOiBcIm15LWRvY2tlci11c2VybmFtZVwiLFxuICAgKiAgIFwicGFzc3dvcmRcIjogXCJteS1kb2NrZXItcGFzc3dvcmRcIlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBJZiBub3QgcHJvdmlkZWQgKG9yIG5vdCBuZWVkZWQpLCB0aGUgY29uc3RydWN0IHdpbGwgc2tpcCBEb2NrZXIgSHViIGxvZ2luLlxuICAgKlxuICAgKiAqKk5vdGUqKjogVGhlIHNlY3JldCBtdXN0IGJlIGluIHRoZSBzYW1lIHJlZ2lvbiBhcyB0aGUgc3RhY2suXG4gICAqXG4gICAqIEBleGFtcGxlICdhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6c2VjcmV0OkRvY2tlckxvZ2luU2VjcmV0J1xuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyTG9naW5TZWNyZXRBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBWUEMgaW4gd2hpY2ggdGhlIENvZGVCdWlsZCBwcm9qZWN0IHdpbGwgYmUgZGVwbG95ZWQuXG4gICAqIElmIHByb3ZpZGVkLCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCBiZSBsYXVuY2hlZCB3aXRoaW4gdGhlIHNwZWNpZmllZCBWUEMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gVlBDIGlzIGF0dGFjaGVkLCBhbmQgdGhlIENvZGVCdWlsZCBwcm9qZWN0IHdpbGwgdXNlIHB1YmxpYyBpbnRlcm5ldC5cbiAgICovXG4gIHJlYWRvbmx5IHZwYz86IElWcGM7XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBncm91cHMgdG8gYXR0YWNoIHRvIHRoZSBDb2RlQnVpbGQgcHJvamVjdC5cbiAgICogVGhlc2UgZGVmaW5lIHRoZSBuZXR3b3JrIGFjY2VzcyBydWxlcyBmb3IgdGhlIENvZGVCdWlsZCBwcm9qZWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHNlY3VyaXR5IGdyb3VwcyBhcmUgYXR0YWNoZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IElTZWN1cml0eUdyb3VwW107XG5cbiAgLyoqXG4gICAqIFRoZSBzdWJuZXQgc2VsZWN0aW9uIHRvIHNwZWNpZnkgd2hpY2ggc3VibmV0cyB0byB1c2Ugd2l0aGluIHRoZSBWUEMuXG4gICAqIEFsbG93cyB0aGUgdXNlciB0byBzZWxlY3QgcHJpdmF0ZSwgcHVibGljLCBvciBpc29sYXRlZCBzdWJuZXRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEFsbCBzdWJuZXRzIGluIHRoZSBWUEMgYXJlIHVzZWQuXG4gICAqL1xuICByZWFkb25seSBzdWJuZXRTZWxlY3Rpb24/OiBTdWJuZXRTZWxlY3Rpb247XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb21tYW5kcyB0byBydW4gZHVyaW5nIHRoZSBpbnN0YWxsIHBoYXNlIG9mIENvZGVCdWlsZC5cbiAgICpcbiAgICogKipFeGFtcGxlKio6XG4gICAqIGBgYHRzXG4gICAqIGluc3RhbGxDb21tYW5kczogW1xuICAgKiAgICdlY2hvIFwiVXBkYXRpbmcgcGFja2FnZSBsaXN0cy4uLlwiJyxcbiAgICogICAnYXB0LWdldCB1cGRhdGUgLXknLFxuICAgKiAgICdlY2hvIFwiSW5zdGFsbGluZyByZXF1aXJlZCBwYWNrYWdlcy4uLlwiJyxcbiAgICogICAnYXB0LWdldCBpbnN0YWxsIC15IGN1cmwgZG5zdXRpbHMnLFxuICAgKiBdLFxuICAgKiBgYGBcbiAgICogQGRlZmF1bHQgLSBObyBhZGRpdGlvbmFsIGluc3RhbGwgY29tbWFuZHMuXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsQ29tbWFuZHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogQ3VzdG9tIGNvbW1hbmRzIHRvIHJ1biBkdXJpbmcgdGhlIHByZV9idWlsZCBwaGFzZSBvZiBDb2RlQnVpbGQuXG4gICAqXG4gICAqICoqRXhhbXBsZSoqOlxuICAgKiBgYGB0c1xuICAgKiBwcmVCdWlsZENvbW1hbmRzOiBbXG4gICAqICAgJ2VjaG8gXCJGZXRjaGluZyBjb25maWd1cmF0aW9uIGZyb20gcHJpdmF0ZSBBUEkuLi5cIicsXG4gICAqICAgJ2N1cmwgLW8gY29uZmlnLmpzb24gaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20vY29uZmlnJyxcbiAgICogXSxcbiAgICogYGBgXG4gICAqIEBkZWZhdWx0IC0gTm8gYWRkaXRpb25hbCBwcmUtYnVpbGQgY29tbWFuZHMuXG4gICAqL1xuICByZWFkb25seSBwcmVCdWlsZENvbW1hbmRzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZW5hYmxlIEtNUyBlbmNyeXB0aW9uIGZvciB0aGUgRUNSIHJlcG9zaXRvcnkuXG4gICAqIElmIGB0cnVlYCwgYSBLTVMga2V5IHdpbGwgYmUgY3JlYXRlZCBmb3IgZW5jcnlwdGluZyBFQ1IgaW1hZ2VzLlxuICAgKiBJZiBgZmFsc2VgLCB0aGUgcmVwb3NpdG9yeSB3aWxsIHVzZSBBRVMtMjU2IGVuY3J5cHRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGttc0VuY3J5cHRpb24/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgcXVlcnkgaW50ZXJ2YWwgZm9yIGNoZWNraW5nIGlmIHRoZSBDb2RlQnVpbGQgcHJvamVjdCBoYXMgY29tcGxldGVkLlxuICAgKiBUaGlzIGRldGVybWluZXMgaG93IGZyZXF1ZW50bHkgdGhlIGN1c3RvbSByZXNvdXJjZSBwb2xscyBmb3IgYnVpbGQgY29tcGxldGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBEdXJhdGlvbi5zZWNvbmRzKDMwKVxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGxldGVuZXNzUXVlcnlJbnRlcnZhbD86IER1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgZmlsZSBwYXRocyBpbiB0aGUgRG9ja2VyIGRpcmVjdG9yeSB0byBleGNsdWRlIGZyb20gYnVpbGQuXG4gICAqIFdpbGwgdXNlIHBhdGhzIGluIC5kb2NrZXJpZ25vcmUgZmlsZSBpZiBwcmVzZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGZpbGUgcGF0aCBleGNsdXNpb25zXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBEb2NrZXJmaWxlIHRvIHVzZSBmb3IgdGhlIGJ1aWxkLlxuICAgKiBQYXNzZWQgYXMgYC0tZmlsZWAgdG8gYGRvY2tlciBidWlsZGAuXG4gICAqXG4gICAqIEBleGFtcGxlICdEb2NrZXJmaWxlLnByb2R1Y3Rpb24nXG4gICAqIEBkZWZhdWx0ICdEb2NrZXJmaWxlJ1xuICAgKi9cbiAgcmVhZG9ubHkgZmlsZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIENESyBjb25zdHJ1Y3QgdG8gYnVpbGQgYW5kIHB1c2ggRG9ja2VyIGltYWdlcyB0byBhbiBFQ1IgcmVwb3NpdG9yeSB1c2luZ1xuICogQ29kZUJ1aWxkIGFuZCBMYW1iZGEgY3VzdG9tIHJlc291cmNlcywgKip0aGVuKiogcmV0cmlldmUgdGhlIGZpbmFsIGltYWdlIHRhZ1xuICogc28gdGhhdCBFQ1MvTGFtYmRhIHJlZmVyZW5jZXMgdXNlIHRoZSBleGFjdCBkaWdlc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBFQ1IgcmVwb3NpdG9yeSB0aGF0IHN0b3JlcyB0aGUgcmVzdWx0aW5nIERvY2tlciBpbWFnZS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZWNyUmVwb3NpdG9yeTogUmVwb3NpdG9yeTtcblxuICAvKipcbiAgICogQW4gRUNTLWNvbXBhdGlibGUgY29udGFpbmVyIGltYWdlIHJlZmVyZW5jaW5nIHRoZSB0YWdcbiAgICogb2YgdGhlIGJ1aWx0IERvY2tlciBpbWFnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb250YWluZXJJbWFnZTogQ29udGFpbmVySW1hZ2U7XG5cbiAgLyoqXG4gICAqIEEgTGFtYmRhLWNvbXBhdGlibGUgRG9ja2VySW1hZ2VDb2RlIHJlZmVyZW5jaW5nIHRoZSB0YWdcbiAgICogb2YgdGhlIGJ1aWx0IERvY2tlciBpbWFnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkb2NrZXJJbWFnZUNvZGU6IERvY2tlckltYWdlQ29kZTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgc2NvcGUgaW4gd2hpY2ggdG8gZGVmaW5lIHRoaXMgY29uc3RydWN0LlxuICAgKiBAcGFyYW0gaWQgVGhlIHNjb3BlZCBjb25zdHJ1Y3QgSUQuXG4gICAqIEBwYXJhbSBwcm9wcyBDb25maWd1cmF0aW9uIGZvciBidWlsZGluZyBhbmQgcHVzaGluZyB0aGUgRG9ja2VyIGltYWdlLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgICAgYnVpbGRBcmdzLFxuICAgICAgZG9ja2VyTG9naW5TZWNyZXRBcm4sXG4gICAgICB2cGMsXG4gICAgICBzZWN1cml0eUdyb3VwcyxcbiAgICAgIHN1Ym5ldFNlbGVjdGlvbixcbiAgICAgIGluc3RhbGxDb21tYW5kcyxcbiAgICAgIHByZUJ1aWxkQ29tbWFuZHMsXG4gICAgICBrbXNFbmNyeXB0aW9uID0gZmFsc2UsXG4gICAgICBjb21wbGV0ZW5lc3NRdWVyeUludGVydmFsLFxuICAgICAgZXhjbHVkZSxcbiAgICAgIGZpbGU6IGRvY2tlckZpbGUsXG4gICAgfSA9IHByb3BzO1xuXG4gICAgLy8gR2VuZXJhdGUgYW4gZXBoZW1lcmFsIHRhZyBmb3IgQ29kZUJ1aWxkXG4gICAgY29uc3QgaW1hZ2VUYWcgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuXG4gICAgLy8gT3B0aW9uYWxseSBkZWZpbmUgYSBLTVMga2V5IGZvciBFQ1IgZW5jcnlwdGlvbiBpZiByZXF1ZXN0ZWRcbiAgICBsZXQgZW5jcnlwdGlvbktleTogS2V5IHwgdW5kZWZpbmVkO1xuICAgIGlmIChrbXNFbmNyeXB0aW9uKSB7XG4gICAgICBlbmNyeXB0aW9uS2V5ID0gbmV3IEtleSh0aGlzLCAnRWNyRW5jcnlwdGlvbktleScsIHtcbiAgICAgICAgZW5hYmxlS2V5Um90YXRpb246IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYW4gRUNSIHJlcG9zaXRvcnkgKG9wdGlvbmFsbHkgd2l0aCBLTVMgZW5jcnlwdGlvbilcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkgPSBuZXcgUmVwb3NpdG9yeSh0aGlzLCAnRUNSUmVwb3NpdG9yeScsIHtcbiAgICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBydWxlUHJpb3JpdHk6IDEsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgdW50YWdnZWQgaW1hZ2VzIGFmdGVyIDEgZGF5JyxcbiAgICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgICBtYXhJbWFnZUFnZTogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBlbmNyeXB0aW9uOiBrbXNFbmNyeXB0aW9uID8gUmVwb3NpdG9yeUVuY3J5cHRpb24uS01TIDogUmVwb3NpdG9yeUVuY3J5cHRpb24uQUVTXzI1NixcbiAgICAgIGVuY3J5cHRpb25LZXk6IGttc0VuY3J5cHRpb24gPyBlbmNyeXB0aW9uS2V5IDogdW5kZWZpbmVkLFxuICAgICAgaW1hZ2VTY2FuT25QdXNoOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgbGV0IGVmZmVjdGl2ZUV4Y2x1ZGUgPSBleGNsdWRlO1xuICAgIGlmICghZWZmZWN0aXZlRXhjbHVkZSkge1xuICAgICAgY29uc3QgZG9ja2VyaWdub3JlUGF0aCA9IHBhdGguam9pbihzb3VyY2VQYXRoLCAnLmRvY2tlcmlnbm9yZScpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZG9ja2VyaWdub3JlUGF0aCkpIHtcbiAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZG9ja2VyaWdub3JlUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgZWZmZWN0aXZlRXhjbHVkZSA9IGZpbGVDb250ZW50XG4gICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgIC5tYXAoKGxpbmU6IHN0cmluZykgPT4gbGluZS50cmltKCkpXG4gICAgICAgICAgLmZpbHRlcigobGluZTogc3RyaW5nKSA9PiBsaW5lLmxlbmd0aCA+IDAgJiYgIWxpbmUuc3RhcnRzV2l0aCgnIycpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgdGhlIHRhcmdldCBEb2NrZXJmaWxlIGlzIG5ldmVyIGV4Y2x1ZGVkXG4gICAgY29uc3QgZG9ja2VyRmlsZU5hbWUgPSBkb2NrZXJGaWxlID8/ICdEb2NrZXJmaWxlJztcbiAgICBpZiAoZWZmZWN0aXZlRXhjbHVkZSkge1xuICAgICAgZWZmZWN0aXZlRXhjbHVkZSA9IGVmZmVjdGl2ZUV4Y2x1ZGUuZmlsdGVyKFxuICAgICAgICAocGF0dGVybjogc3RyaW5nKSA9PiBwYXR0ZXJuLnRvTG93ZXJDYXNlKCkgIT09IGRvY2tlckZpbGVOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFdyYXAgdGhlIHNvdXJjZSBmb2xkZXIgYXMgYW4gUzMgYXNzZXQgZm9yIENvZGVCdWlsZCB0byB1c2VcbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgICAgZXhjbHVkZTogZWZmZWN0aXZlRXhjbHVkZSxcblxuICAgIH0pO1xuXG4gICAgLy8gQ29udmVydCBidWlsZEFyZ3MgdG8gYSBDTEktZnJpZW5kbHkgc3RyaW5nXG4gICAgY29uc3QgYnVpbGRBcmdzU3RyaW5nID0gYnVpbGRBcmdzXG4gICAgICA/IE9iamVjdC5lbnRyaWVzKGJ1aWxkQXJncylcbiAgICAgICAgLm1hcCgoW2ssIHZdKSA9PiBgLS1idWlsZC1hcmcgJHtrfT0ke3Z9YClcbiAgICAgICAgLmpvaW4oJyAnKVxuICAgICAgOiAnJztcblxuICAgIGNvbnN0IGRvY2tlckZpbGVGbGFnID0gZG9ja2VyRmlsZSA/IGAtZiAkQ09ERUJVSUxEX1NSQ19ESVIvJHtkb2NrZXJGaWxlfWAgOiAnJztcblxuICAgIC8vIE9wdGlvbmFsIERvY2tlckh1YiBsb2dpbiwgaWYgYSBzZWNyZXQgQVJOIGlzIHByb3ZpZGVkXG4gICAgY29uc3QgZG9ja2VyTG9naW5Db21tYW5kcyA9IGRvY2tlckxvZ2luU2VjcmV0QXJuXG4gICAgICA/IFtcbiAgICAgICAgJ2VjaG8gXCJSZXRyaWV2aW5nIERvY2tlciBjcmVkZW50aWFscy4uLlwiJyxcbiAgICAgICAgJ2FwdC1nZXQgdXBkYXRlIC15ICYmIGFwdC1nZXQgaW5zdGFsbCAteSBqcScsXG4gICAgICAgIGBET0NLRVJfVVNFUk5BTUU9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnVzZXJuYW1lKWAsXG4gICAgICAgIGBET0NLRVJfUEFTU1dPUkQ9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnBhc3N3b3JkKWAsXG4gICAgICAgICdlY2hvIFwiTG9nZ2luZyBpbiB0byBEb2NrZXIgSHViLi4uXCInLFxuICAgICAgICAnZWNobyAkRE9DS0VSX1BBU1NXT1JEIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgJERPQ0tFUl9VU0VSTkFNRSAtLXBhc3N3b3JkLXN0ZGluJyxcbiAgICAgIF1cbiAgICAgIDogWydlY2hvIFwiTm8gRG9ja2VyIGNyZWRlbnRpYWxzLiBTa2lwcGluZyBEb2NrZXIgSHViIGxvZ2luLlwiJ107XG5cbiAgICBjb25zdCBidWlsZFNwZWNPYmogPSB7XG4gICAgICB2ZXJzaW9uOiAnMC4yJyxcbiAgICAgIHBoYXNlczoge1xuICAgICAgICBpbnN0YWxsOiB7XG4gICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICdlY2hvIFwiQmVnaW5uaW5nIGluc3RhbGwgcGhhc2UuLi5cIicsXG4gICAgICAgICAgICAuLi4oaW5zdGFsbENvbW1hbmRzID8/IFtdKSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBwcmVfYnVpbGQ6IHtcbiAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgLi4uKHByZUJ1aWxkQ29tbWFuZHMgPz8gW10pLFxuICAgICAgICAgICAgLi4uZG9ja2VyTG9naW5Db21tYW5kcyxcbiAgICAgICAgICAgICdlY2hvIFwiUmV0cmlldmluZyBBV1MgQWNjb3VudCBJRC4uLlwiJyxcbiAgICAgICAgICAgICdleHBvcnQgQUNDT1VOVF9JRD0kKGF3cyBzdHMgZ2V0LWNhbGxlci1pZGVudGl0eSAtLXF1ZXJ5IEFjY291bnQgLS1vdXRwdXQgdGV4dCknLFxuICAgICAgICAgICAgJ2VjaG8gXCJMb2dnaW5nIGludG8gQW1hem9uIEVDUi4uLlwiJyxcbiAgICAgICAgICAgICdhd3MgZWNyIGdldC1sb2dpbi1wYXNzd29yZCAtLXJlZ2lvbiAkQVdTX0RFRkFVTFRfUkVHSU9OIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgQVdTIC0tcGFzc3dvcmQtc3RkaW4gJEFDQ09VTlRfSUQuZGtyLmVjci4kQVdTX0RFRkFVTFRfUkVHSU9OLmFtYXpvbmF3cy5jb20nLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIGJ1aWxkOiB7XG4gICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgIGBlY2hvIFwiQnVpbGRpbmcgRG9ja2VyIGltYWdlIHdpdGggdGFnICR7aW1hZ2VUYWd9Li4uXCJgLFxuICAgICAgICAgICAgYGRvY2tlciBidWlsZCAke2RvY2tlckZpbGVGbGFnfSAke2J1aWxkQXJnc1N0cmluZ30gLXQgJEVDUl9SRVBPX1VSSToke2ltYWdlVGFnfSAkQ09ERUJVSUxEX1NSQ19ESVJgLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgYGVjaG8gXCJQdXNoaW5nIERvY2tlciBpbWFnZSB3aXRoIHRhZyAke2ltYWdlVGFnfS4uLlwiYCxcbiAgICAgICAgICAgIGBkb2NrZXIgcHVzaCAkRUNSX1JFUE9fVVJJOiR7aW1hZ2VUYWd9YCxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBDb2RlQnVpbGQgcHJvamVjdFxuICAgIGNvbnN0IGNvZGVCdWlsZFByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCAnQ29kZUJ1aWxkUHJvamVjdCcsIHtcbiAgICAgIHNvdXJjZTogU291cmNlLnMzKHtcbiAgICAgICAgYnVja2V0OiBzb3VyY2VBc3NldC5idWNrZXQsXG4gICAgICAgIHBhdGg6IHNvdXJjZUFzc2V0LnMzT2JqZWN0S2V5LFxuICAgICAgfSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBidWlsZEltYWdlOiBMaW51eEJ1aWxkSW1hZ2UuU1RBTkRBUkRfN18wLFxuICAgICAgICBwcml2aWxlZ2VkOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVzOiB7XG4gICAgICAgIEVDUl9SRVBPX1VSSTogeyB2YWx1ZTogdGhpcy5lY3JSZXBvc2l0b3J5LnJlcG9zaXRvcnlVcmkgfSxcbiAgICAgIH0sXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KGJ1aWxkU3BlY09iaiksXG4gICAgICB2cGMsXG4gICAgICBzZWN1cml0eUdyb3VwcyxcbiAgICAgIHN1Ym5ldFNlbGVjdGlvbixcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IENvZGVCdWlsZCB0aGUgYWJpbGl0eSB0byBpbnRlcmFjdCB3aXRoIEVDUlxuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGNvZGVCdWlsZFByb2plY3QpO1xuICAgIGNvZGVCdWlsZFByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnZWNyOkdldEF1dGhvcml6YXRpb25Ub2tlbicsXG4gICAgICAgICAgJ2VjcjpHZXREb3dubG9hZFVybEZvckxheWVyJyxcbiAgICAgICAgICAnZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eScsXG4gICAgICAgIF0sXG4gICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICB9KSxcbiAgICApO1xuICAgIGlmIChkb2NrZXJMb2dpblNlY3JldEFybikge1xuICAgICAgY29kZUJ1aWxkUHJvamVjdC5hZGRUb1JvbGVQb2xpY3koXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFsnc2VjcmV0c21hbmFnZXI6R2V0U2VjcmV0VmFsdWUnXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtkb2NrZXJMb2dpblNlY3JldEFybl0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDb25kaXRpb25hbGx5IGdyYW50IEtNUyBlbmNyeXB0L2RlY3J5cHQgaWYgYSBrZXkgaXMgdXNlZFxuICAgIGlmIChlbmNyeXB0aW9uS2V5KSB7XG4gICAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQoY29kZUJ1aWxkUHJvamVjdC5yb2xlISk7XG4gICAgfVxuXG4gICAgLy8gRGVmaW5lIExhbWJkYSBmdW5jdGlvbnMgZm9yIGN1c3RvbSByZXNvdXJjZSBldmVudCBhbmQgY29tcGxldGlvbiBoYW5kbGluZ1xuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24gPSBuZXcgRnVuY3Rpb24odGhpcywgJ09uRXZlbnRIYW5kbGVyRnVuY3Rpb24nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL29uRXZlbnQnKSksXG4gICAgICBoYW5kbGVyOiAnb25FdmVudC5oYW5kbGVyJyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMTUpLFxuICAgIH0pO1xuICAgIG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnY29kZWJ1aWxkOlN0YXJ0QnVpbGQnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbY29kZUJ1aWxkUHJvamVjdC5wcm9qZWN0QXJuXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdJc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9pc0NvbXBsZXRlJykpLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgSU1BR0VfVEFHOiBpbWFnZVRhZyxcbiAgICAgIH0sXG4gICAgICBoYW5kbGVyOiAnaXNDb21wbGV0ZS5oYW5kbGVyJyxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMTUpLFxuICAgIH0pO1xuICAgIGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnY29kZWJ1aWxkOkJhdGNoR2V0QnVpbGRzJyxcbiAgICAgICAgICAnY29kZWJ1aWxkOkxpc3RCdWlsZHNGb3JQcm9qZWN0JyxcbiAgICAgICAgICAnbG9nczpHZXRMb2dFdmVudHMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nU3RyZWFtcycsXG4gICAgICAgICAgJ2xvZ3M6RGVzY3JpYmVMb2dHcm91cHMnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIENvbmRpdGlvbmFsbHkgYWxsb3cgZW5jcnlwdGlvbiBpZiBhIGtleSBpcyB1c2VkXG4gICAgaWYgKGVuY3J5cHRpb25LZXkpIHtcbiAgICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChvbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uKTtcbiAgICB9XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gob25FdmVudEhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG5cbiAgICAvLyBDcmVhdGUgYSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXIgdGhhdCB1c2VzIHRoZSBhYm92ZSBMYW1iZGFzXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgJ0N1c3RvbVJlc291cmNlUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogb25FdmVudEhhbmRsZXJGdW5jdGlvbixcbiAgICAgIGlzQ29tcGxldGVIYW5kbGVyOiBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLFxuICAgICAgcXVlcnlJbnRlcnZhbDogY29tcGxldGVuZXNzUXVlcnlJbnRlcnZhbCA/PyBEdXJhdGlvbi5zZWNvbmRzKDMwKSxcbiAgICB9KTtcblxuICAgIC8vIEN1c3RvbSBSZXNvdXJjZSB0aGF0IHRyaWdnZXJzIHRoZSBDb2RlQnVpbGQgYW5kIHdhaXRzIGZvciBjb21wbGV0aW9uXG4gICAgY29uc3QgYnVpbGRUcmlnZ2VyUmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0J1aWxkVHJpZ2dlclJlc291cmNlJywge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFByb2plY3ROYW1lOiBjb2RlQnVpbGRQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICBJbWFnZVRhZzogaW1hZ2VUYWcsXG4gICAgICAgIFRyaWdnZXI6IHNvdXJjZUFzc2V0LmFzc2V0SGFzaCxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgYnVpbGRUcmlnZ2VyUmVzb3VyY2Uubm9kZS5hZGREZXBlbmRlbmN5KGNvZGVCdWlsZFByb2plY3QpO1xuXG4gICAgLy8gUmV0cmlldmUgdGhlIGZpbmFsIERvY2tlciBpbWFnZSB0YWcgZnJvbSBEYXRhLkltYWdlVGFnXG4gICAgY29uc3QgaW1hZ2VUYWdSZWYgPSBidWlsZFRyaWdnZXJSZXNvdXJjZS5nZXRBdHRTdHJpbmcoJ0ltYWdlVGFnJyk7XG4gICAgdGhpcy5jb250YWluZXJJbWFnZSA9IENvbnRhaW5lckltYWdlLmZyb21FY3JSZXBvc2l0b3J5KHRoaXMuZWNyUmVwb3NpdG9yeSwgaW1hZ2VUYWdSZWYpO1xuICAgIHRoaXMuZG9ja2VySW1hZ2VDb2RlID0gRG9ja2VySW1hZ2VDb2RlLmZyb21FY3IodGhpcy5lY3JSZXBvc2l0b3J5LCB7XG4gICAgICB0YWdPckRpZ2VzdDogaW1hZ2VUYWdSZWYsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|
|
243
|
+
TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.7.0" };
|
|
244
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUU3Qiw2Q0FBdUQ7QUFDdkQsNkRBQXdGO0FBRXhGLGlEQUFrRjtBQUNsRixpREFBcUQ7QUFDckQsaURBQXNEO0FBQ3RELGlEQUEwQztBQUMxQyx1REFBa0Y7QUFDbEYsNkRBQWtEO0FBQ2xELG1FQUF3RDtBQUN4RCwyQ0FBdUM7QUF3SXZDOzs7O0dBSUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBa0J6RDs7Ozs7O09BTUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXdDO1FBQ2hGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxFQUNKLElBQUksRUFBRSxVQUFVLEVBQ2hCLFNBQVMsRUFDVCxvQkFBb0IsRUFDcEIsR0FBRyxFQUNILGNBQWMsRUFDZCxlQUFlLEVBQ2YsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixhQUFhLEdBQUcsS0FBSyxFQUNyQix5QkFBeUIsRUFDekIsT0FBTyxFQUNQLElBQUksRUFBRSxVQUFVLEVBQ2hCLGFBQWEsR0FBRyxLQUFLLEdBQ3RCLEdBQUcsS0FBSyxDQUFDO1FBRVYsMENBQTBDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUVyQyw4REFBOEQ7UUFDOUQsSUFBSSxhQUE4QixDQUFDO1FBQ25DLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtnQkFDaEQsaUJBQWlCLEVBQUUsSUFBSTthQUN4QixDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsNERBQTREO1FBQzVELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxvQkFBVSxDQUFD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bXBvcnQgKiBhcyBjcnlwdG8gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IEN1c3RvbVJlc291cmNlLCBEdXJhdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IFByb2plY3QsIFNvdXJjZSwgTGludXhCdWlsZEltYWdlLCBCdWlsZFNwZWMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY29kZWJ1aWxkJztcbmltcG9ydCB7IElWcGMsIElTZWN1cml0eUdyb3VwLCBTdWJuZXRTZWxlY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCB7IFJlcG9zaXRvcnksIFJlcG9zaXRvcnlFbmNyeXB0aW9uLCBUYWdTdGF0dXMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNyJztcbmltcG9ydCB7IENvbnRhaW5lckltYWdlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjcyc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEtleSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1rbXMnO1xuaW1wb3J0IHsgUnVudGltZSwgQ29kZSwgRG9ja2VySW1hZ2VDb2RlLCBGdW5jdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQXNzZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMtYXNzZXRzJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB0aGUgYFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJgIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvcHMge1xuICAvKipcbiAgICogVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBEb2NrZXJmaWxlIG9yIHNvdXJjZSBjb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBCdWlsZCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgRG9ja2VyIGJ1aWxkIHByb2Nlc3MuXG4gICAqIFRoZXNlIGFyZSB0cmFuc2Zvcm1lZCBpbnRvIGAtLWJ1aWxkLWFyZyBLRVk9VkFMVUVgIGZsYWdzLlxuICAgKiBAZXhhbXBsZVxuICAgKiB7XG4gICAqICAgVE9LRU46ICdteS1zZWNyZXQtdG9rZW4nLFxuICAgKiAgIEVOVjogJ3Byb2R1Y3Rpb24nXG4gICAqIH1cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkQXJncz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIEFXUyBTZWNyZXRzIE1hbmFnZXIgc2VjcmV0IGNvbnRhaW5pbmcgRG9ja2VyIGxvZ2luIGNyZWRlbnRpYWxzLlxuICAgKiBUaGlzIHNlY3JldCBzaG91bGQgc3RvcmUgYSBKU09OIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICAgKiBgYGBqc29uXG4gICAqIHtcbiAgICogICBcInVzZXJuYW1lXCI6IFwibXktZG9ja2VyLXVzZXJuYW1lXCIsXG4gICAqICAgXCJwYXNzd29yZFwiOiBcIm15LWRvY2tlci1wYXNzd29yZFwiXG4gICAqIH1cbiAgICogYGBgXG4gICAqIElmIG5vdCBwcm92aWRlZCAob3Igbm90IG5lZWRlZCksIHRoZSBjb25zdHJ1Y3Qgd2lsbCBza2lwIERvY2tlciBIdWIgbG9naW4uXG4gICAqXG4gICAqICoqTm90ZSoqOiBUaGUgc2VjcmV0IG11c3QgYmUgaW4gdGhlIHNhbWUgcmVnaW9uIGFzIHRoZSBzdGFjay5cbiAgICpcbiAgICogQGV4YW1wbGUgJ2Fybjphd3M6c2VjcmV0c21hbmFnZXI6dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpzZWNyZXQ6RG9ja2VyTG9naW5TZWNyZXQnXG4gICAqL1xuICByZWFkb25seSBkb2NrZXJMb2dpblNlY3JldEFybj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFZQQyBpbiB3aGljaCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCBiZSBkZXBsb3llZC5cbiAgICogSWYgcHJvdmlkZWQsIHRoZSBDb2RlQnVpbGQgcHJvamVjdCB3aWxsIGJlIGxhdW5jaGVkIHdpdGhpbiB0aGUgc3BlY2lmaWVkIFZQQy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBWUEMgaXMgYXR0YWNoZWQsIGFuZCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCB1c2UgcHVibGljIGludGVybmV0LlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjPzogSVZwYztcblxuICAvKipcbiAgICogVGhlIHNlY3VyaXR5IGdyb3VwcyB0byBhdHRhY2ggdG8gdGhlIENvZGVCdWlsZCBwcm9qZWN0LlxuICAgKiBUaGVzZSBkZWZpbmUgdGhlIG5ldHdvcmsgYWNjZXNzIHJ1bGVzIGZvciB0aGUgQ29kZUJ1aWxkIHByb2plY3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gc2VjdXJpdHkgZ3JvdXBzIGFyZSBhdHRhY2hlZC5cbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzPzogSVNlY3VyaXR5R3JvdXBbXTtcblxuICAvKipcbiAgICogVGhlIHN1Ym5ldCBzZWxlY3Rpb24gdG8gc3BlY2lmeSB3aGljaCBzdWJuZXRzIHRvIHVzZSB3aXRoaW4gdGhlIFZQQy5cbiAgICogQWxsb3dzIHRoZSB1c2VyIHRvIHNlbGVjdCBwcml2YXRlLCBwdWJsaWMsIG9yIGlzb2xhdGVkIHN1Ym5ldHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQWxsIHN1Ym5ldHMgaW4gdGhlIFZQQyBhcmUgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHN1Ym5ldFNlbGVjdGlvbj86IFN1Ym5ldFNlbGVjdGlvbjtcblxuICAvKipcbiAgICogQ3VzdG9tIGNvbW1hbmRzIHRvIHJ1biBkdXJpbmcgdGhlIGluc3RhbGwgcGhhc2Ugb2YgQ29kZUJ1aWxkLlxuICAgKlxuICAgKiAqKkV4YW1wbGUqKjpcbiAgICogYGBgdHNcbiAgICogaW5zdGFsbENvbW1hbmRzOiBbXG4gICAqICAgJ2VjaG8gXCJVcGRhdGluZyBwYWNrYWdlIGxpc3RzLi4uXCInLFxuICAgKiAgICdhcHQtZ2V0IHVwZGF0ZSAteScsXG4gICAqICAgJ2VjaG8gXCJJbnN0YWxsaW5nIHJlcXVpcmVkIHBhY2thZ2VzLi4uXCInLFxuICAgKiAgICdhcHQtZ2V0IGluc3RhbGwgLXkgY3VybCBkbnN1dGlscycsXG4gICAqIF0sXG4gICAqIGBgYFxuICAgKiBAZGVmYXVsdCAtIE5vIGFkZGl0aW9uYWwgaW5zdGFsbCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxDb21tYW5kcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gY29tbWFuZHMgdG8gcnVuIGR1cmluZyB0aGUgcHJlX2J1aWxkIHBoYXNlIG9mIENvZGVCdWlsZC5cbiAgICpcbiAgICogKipFeGFtcGxlKio6XG4gICAqIGBgYHRzXG4gICAqIHByZUJ1aWxkQ29tbWFuZHM6IFtcbiAgICogICAnZWNobyBcIkZldGNoaW5nIGNvbmZpZ3VyYXRpb24gZnJvbSBwcml2YXRlIEFQSS4uLlwiJyxcbiAgICogICAnY3VybCAtbyBjb25maWcuanNvbiBodHRwczovL2FwaS5leGFtcGxlLmNvbS9jb25maWcnLFxuICAgKiBdLFxuICAgKiBgYGBcbiAgICogQGRlZmF1bHQgLSBObyBhZGRpdGlvbmFsIHByZS1idWlsZCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IHByZUJ1aWxkQ29tbWFuZHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogV2hldGhlciB0byBlbmFibGUgS01TIGVuY3J5cHRpb24gZm9yIHRoZSBFQ1IgcmVwb3NpdG9yeS5cbiAgICogSWYgYHRydWVgLCBhIEtNUyBrZXkgd2lsbCBiZSBjcmVhdGVkIGZvciBlbmNyeXB0aW5nIEVDUiBpbWFnZXMuXG4gICAqIElmIGBmYWxzZWAsIHRoZSByZXBvc2l0b3J5IHdpbGwgdXNlIEFFUy0yNTYgZW5jcnlwdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkga21zRW5jcnlwdGlvbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBxdWVyeSBpbnRlcnZhbCBmb3IgY2hlY2tpbmcgaWYgdGhlIENvZGVCdWlsZCBwcm9qZWN0IGhhcyBjb21wbGV0ZWQuXG4gICAqIFRoaXMgZGV0ZXJtaW5lcyBob3cgZnJlcXVlbnRseSB0aGUgY3VzdG9tIHJlc291cmNlIHBvbGxzIGZvciBidWlsZCBjb21wbGV0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIER1cmF0aW9uLnNlY29uZHMoMzApXG4gICAqL1xuICByZWFkb25seSBjb21wbGV0ZW5lc3NRdWVyeUludGVydmFsPzogRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBmaWxlIHBhdGhzIGluIHRoZSBEb2NrZXIgZGlyZWN0b3J5IHRvIGV4Y2x1ZGUgZnJvbSBidWlsZC5cbiAgICogV2lsbCB1c2UgcGF0aHMgaW4gLmRvY2tlcmlnbm9yZSBmaWxlIGlmIHByZXNlbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZmlsZSBwYXRoIGV4Y2x1c2lvbnNcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIERvY2tlcmZpbGUgdG8gdXNlIGZvciB0aGUgYnVpbGQuXG4gICAqIFBhc3NlZCBhcyBgLS1maWxlYCB0byBgZG9ja2VyIGJ1aWxkYC5cbiAgICpcbiAgICogQGV4YW1wbGUgJ0RvY2tlcmZpbGUucHJvZHVjdGlvbidcbiAgICogQGRlZmF1bHQgJ0RvY2tlcmZpbGUnXG4gICAqL1xuICByZWFkb25seSBmaWxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGVuIGB0cnVlYCwgZGlzYWJsZXMgRG9ja2VyIGxheWVyIGNhY2hpbmcuIEV2ZXJ5IGJ1aWxkIHJ1bnMgZnJvbSBzY3JhdGNoLlxuICAgKiBVc2UgZm9yIGRlYnVnZ2luZywgY29ycnVwdGVkIGNhY2hlLCBvciBtYWpvciBkZXBlbmRlbmN5IGNoYW5nZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjYWNoZURpc2FibGVkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIENESyBjb25zdHJ1Y3QgdG8gYnVpbGQgYW5kIHB1c2ggRG9ja2VyIGltYWdlcyB0byBhbiBFQ1IgcmVwb3NpdG9yeSB1c2luZ1xuICogQ29kZUJ1aWxkIGFuZCBMYW1iZGEgY3VzdG9tIHJlc291cmNlcywgKip0aGVuKiogcmV0cmlldmUgdGhlIGZpbmFsIGltYWdlIHRhZ1xuICogc28gdGhhdCBFQ1MvTGFtYmRhIHJlZmVyZW5jZXMgdXNlIHRoZSBleGFjdCBkaWdlc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBFQ1IgcmVwb3NpdG9yeSB0aGF0IHN0b3JlcyB0aGUgcmVzdWx0aW5nIERvY2tlciBpbWFnZS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZWNyUmVwb3NpdG9yeTogUmVwb3NpdG9yeTtcblxuICAvKipcbiAgICogQW4gRUNTLWNvbXBhdGlibGUgY29udGFpbmVyIGltYWdlIHJlZmVyZW5jaW5nIHRoZSB0YWdcbiAgICogb2YgdGhlIGJ1aWx0IERvY2tlciBpbWFnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb250YWluZXJJbWFnZTogQ29udGFpbmVySW1hZ2U7XG5cbiAgLyoqXG4gICAqIEEgTGFtYmRhLWNvbXBhdGlibGUgRG9ja2VySW1hZ2VDb2RlIHJlZmVyZW5jaW5nIHRoZSB0YWdcbiAgICogb2YgdGhlIGJ1aWx0IERvY2tlciBpbWFnZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkb2NrZXJJbWFnZUNvZGU6IERvY2tlckltYWdlQ29kZTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgc2NvcGUgaW4gd2hpY2ggdG8gZGVmaW5lIHRoaXMgY29uc3RydWN0LlxuICAgKiBAcGFyYW0gaWQgVGhlIHNjb3BlZCBjb25zdHJ1Y3QgSUQuXG4gICAqIEBwYXJhbSBwcm9wcyBDb25maWd1cmF0aW9uIGZvciBidWlsZGluZyBhbmQgcHVzaGluZyB0aGUgRG9ja2VyIGltYWdlLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgICAgYnVpbGRBcmdzLFxuICAgICAgZG9ja2VyTG9naW5TZWNyZXRBcm4sXG4gICAgICB2cGMsXG4gICAgICBzZWN1cml0eUdyb3VwcyxcbiAgICAgIHN1Ym5ldFNlbGVjdGlvbixcbiAgICAgIGluc3RhbGxDb21tYW5kcyxcbiAgICAgIHByZUJ1aWxkQ29tbWFuZHMsXG4gICAgICBrbXNFbmNyeXB0aW9uID0gZmFsc2UsXG4gICAgICBjb21wbGV0ZW5lc3NRdWVyeUludGVydmFsLFxuICAgICAgZXhjbHVkZSxcbiAgICAgIGZpbGU6IGRvY2tlckZpbGUsXG4gICAgICBjYWNoZURpc2FibGVkID0gZmFsc2UsXG4gICAgfSA9IHByb3BzO1xuXG4gICAgLy8gR2VuZXJhdGUgYW4gZXBoZW1lcmFsIHRhZyBmb3IgQ29kZUJ1aWxkXG4gICAgY29uc3QgaW1hZ2VUYWcgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuXG4gICAgLy8gT3B0aW9uYWxseSBkZWZpbmUgYSBLTVMga2V5IGZvciBFQ1IgZW5jcnlwdGlvbiBpZiByZXF1ZXN0ZWRcbiAgICBsZXQgZW5jcnlwdGlvbktleTogS2V5IHwgdW5kZWZpbmVkO1xuICAgIGlmIChrbXNFbmNyeXB0aW9uKSB7XG4gICAgICBlbmNyeXB0aW9uS2V5ID0gbmV3IEtleSh0aGlzLCAnRWNyRW5jcnlwdGlvbktleScsIHtcbiAgICAgICAgZW5hYmxlS2V5Um90YXRpb246IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYW4gRUNSIHJlcG9zaXRvcnkgKG9wdGlvbmFsbHkgd2l0aCBLTVMgZW5jcnlwdGlvbilcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkgPSBuZXcgUmVwb3NpdG9yeSh0aGlzLCAnRUNSUmVwb3NpdG9yeScsIHtcbiAgICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBydWxlUHJpb3JpdHk6IDEsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgdW50YWdnZWQgaW1hZ2VzIGFmdGVyIDEgZGF5JyxcbiAgICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgICBtYXhJbWFnZUFnZTogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBlbmNyeXB0aW9uOiBrbXNFbmNyeXB0aW9uID8gUmVwb3NpdG9yeUVuY3J5cHRpb24uS01TIDogUmVwb3NpdG9yeUVuY3J5cHRpb24uQUVTXzI1NixcbiAgICAgIGVuY3J5cHRpb25LZXk6IGttc0VuY3J5cHRpb24gPyBlbmNyeXB0aW9uS2V5IDogdW5kZWZpbmVkLFxuICAgICAgaW1hZ2VTY2FuT25QdXNoOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgbGV0IGVmZmVjdGl2ZUV4Y2x1ZGUgPSBleGNsdWRlO1xuICAgIGlmICghZWZmZWN0aXZlRXhjbHVkZSkge1xuICAgICAgY29uc3QgZG9ja2VyaWdub3JlUGF0aCA9IHBhdGguam9pbihzb3VyY2VQYXRoLCAnLmRvY2tlcmlnbm9yZScpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZG9ja2VyaWdub3JlUGF0aCkpIHtcbiAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZG9ja2VyaWdub3JlUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgZWZmZWN0aXZlRXhjbHVkZSA9IGZpbGVDb250ZW50XG4gICAgICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgICAgIC5tYXAoKGxpbmU6IHN0cmluZykgPT4gbGluZS50cmltKCkpXG4gICAgICAgICAgLmZpbHRlcigobGluZTogc3RyaW5nKSA9PiBsaW5lLmxlbmd0aCA+IDAgJiYgIWxpbmUuc3RhcnRzV2l0aCgnIycpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgdGhlIHRhcmdldCBEb2NrZXJmaWxlIGlzIG5ldmVyIGV4Y2x1ZGVkXG4gICAgY29uc3QgZG9ja2VyRmlsZU5hbWUgPSBkb2NrZXJGaWxlID8/ICdEb2NrZXJmaWxlJztcbiAgICBpZiAoZWZmZWN0aXZlRXhjbHVkZSkge1xuICAgICAgZWZmZWN0aXZlRXhjbHVkZSA9IGVmZmVjdGl2ZUV4Y2x1ZGUuZmlsdGVyKFxuICAgICAgICAocGF0dGVybjogc3RyaW5nKSA9PiBwYXR0ZXJuLnRvTG93ZXJDYXNlKCkgIT09IGRvY2tlckZpbGVOYW1lLnRvTG93ZXJDYXNlKCksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFdyYXAgdGhlIHNvdXJjZSBmb2xkZXIgYXMgYW4gUzMgYXNzZXQgZm9yIENvZGVCdWlsZCB0byB1c2VcbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgICAgZXhjbHVkZTogZWZmZWN0aXZlRXhjbHVkZSxcblxuICAgIH0pO1xuXG4gICAgLy8gQ29udmVydCBidWlsZEFyZ3MgdG8gYSBDTEktZnJpZW5kbHkgc3RyaW5nXG4gICAgY29uc3QgYnVpbGRBcmdzU3RyaW5nID0gYnVpbGRBcmdzXG4gICAgICA/IE9iamVjdC5lbnRyaWVzKGJ1aWxkQXJncylcbiAgICAgICAgLm1hcCgoW2ssIHZdKSA9PiBgLS1idWlsZC1hcmcgJHtrfT0ke3Z9YClcbiAgICAgICAgLmpvaW4oJyAnKVxuICAgICAgOiAnJztcblxuICAgIGNvbnN0IGRvY2tlckZpbGVGbGFnID0gZG9ja2VyRmlsZSA/IGAtZiAkQ09ERUJVSUxEX1NSQ19ESVIvJHtkb2NrZXJGaWxlfWAgOiAnJztcblxuICAgIC8vIE9wdGlvbmFsIERvY2tlckh1YiBsb2dpbiwgaWYgYSBzZWNyZXQgQVJOIGlzIHByb3ZpZGVkXG4gICAgY29uc3QgZG9ja2VyTG9naW5Db21tYW5kcyA9IGRvY2tlckxvZ2luU2VjcmV0QXJuXG4gICAgICA/IFtcbiAgICAgICAgJ2VjaG8gXCJSZXRyaWV2aW5nIERvY2tlciBjcmVkZW50aWFscy4uLlwiJyxcbiAgICAgICAgJ2FwdC1nZXQgdXBkYXRlIC15ICYmIGFwdC1nZXQgaW5zdGFsbCAteSBqcScsXG4gICAgICAgIGBET0NLRVJfVVNFUk5BTUU9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnVzZXJuYW1lKWAsXG4gICAgICAgIGBET0NLRVJfUEFTU1dPUkQ9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnBhc3N3b3JkKWAsXG4gICAgICAgICdlY2hvIFwiTG9nZ2luZyBpbiB0byBEb2NrZXIgSHViLi4uXCInLFxuICAgICAgICAnZWNobyAkRE9DS0VSX1BBU1NXT1JEIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgJERPQ0tFUl9VU0VSTkFNRSAtLXBhc3N3b3JkLXN0ZGluJyxcbiAgICAgIF1cbiAgICAgIDogWydlY2hvIFwiTm8gRG9ja2VyIGNyZWRlbnRpYWxzLiBTa2lwcGluZyBEb2NrZXIgSHViIGxvZ2luLlwiJ107XG5cbiAgICBjb25zdCBidWlsZHhJbnN0YWxsQ29tbWFuZHMgPSBjYWNoZURpc2FibGVkXG4gICAgICA/IFtdXG4gICAgICA6IFtcbiAgICAgICAgJ2VjaG8gXCJTZXR0aW5nIHVwIERvY2tlciBidWlsZHggZm9yIEVDUiBsYXllciBjYWNoZS4uLlwiJyxcbiAgICAgICAgJ2RvY2tlciBidWlsZHggY3JlYXRlIC0tZHJpdmVyIGRvY2tlci1jb250YWluZXIgLS1uYW1lIGVjci1jYWNoZS1idWlsZGVyIC0tdXNlIDI+L2Rldi9udWxsIHx8IGRvY2tlciBidWlsZHggdXNlIGVjci1jYWNoZS1idWlsZGVyJyxcbiAgICAgIF07XG5cbiAgICBjb25zdCBidWlsZENvbW1hbmQgPSBjYWNoZURpc2FibGVkXG4gICAgICA/IGBkb2NrZXIgYnVpbGQgJHtkb2NrZXJGaWxlRmxhZ30gJHtidWlsZEFyZ3NTdHJpbmd9IC10ICRFQ1JfUkVQT19VUkk6JHtpbWFnZVRhZ30gJENPREVCVUlMRF9TUkNfRElSYFxuICAgICAgOiBgZG9ja2VyIGJ1aWxkeCBidWlsZCAtLXB1c2ggLS1jYWNoZS1mcm9tIHR5cGU9cmVnaXN0cnkscmVmPSRFQ1JfUkVQT19VUkk6Y2FjaGUgLS1jYWNoZS10byB0eXBlPXJlZ2lzdHJ5LHJlZj0kRUNSX1JFUE9fVVJJOmNhY2hlLG1vZGU9bWF4LGltYWdlLW1hbmlmZXN0PXRydWUgJHtkb2NrZXJGaWxlRmxhZ30gJHtidWlsZEFyZ3NTdHJpbmd9IC10ICRFQ1JfUkVQT19VUkk6JHtpbWFnZVRhZ30gJENPREVCVUlMRF9TUkNfRElSYDtcblxuICAgIGNvbnN0IGJ1aWxkU3BlY09iaiA9IHtcbiAgICAgIHZlcnNpb246ICcwLjInLFxuICAgICAgcGhhc2VzOiB7XG4gICAgICAgIGluc3RhbGw6IHtcbiAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgJ2VjaG8gXCJCZWdpbm5pbmcgaW5zdGFsbCBwaGFzZS4uLlwiJyxcbiAgICAgICAgICAgIC4uLihpbnN0YWxsQ29tbWFuZHMgPz8gW10pLFxuICAgICAgICAgICAgLi4uYnVpbGR4SW5zdGFsbENvbW1hbmRzLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIHByZV9idWlsZDoge1xuICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAuLi4ocHJlQnVpbGRDb21tYW5kcyA/PyBbXSksXG4gICAgICAgICAgICAuLi5kb2NrZXJMb2dpbkNvbW1hbmRzLFxuICAgICAgICAgICAgJ2VjaG8gXCJSZXRyaWV2aW5nIEFXUyBBY2NvdW50IElELi4uXCInLFxuICAgICAgICAgICAgJ2V4cG9ydCBBQ0NPVU5UX0lEPSQoYXdzIHN0cyBnZXQtY2FsbGVyLWlkZW50aXR5IC0tcXVlcnkgQWNjb3VudCAtLW91dHB1dCB0ZXh0KScsXG4gICAgICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW50byBBbWF6b24gRUNSLi4uXCInLFxuICAgICAgICAgICAgJ2F3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uICRBV1NfREVGQVVMVF9SRUdJT04gfCBkb2NrZXIgbG9naW4gLS11c2VybmFtZSBBV1MgLS1wYXNzd29yZC1zdGRpbiAkQUNDT1VOVF9JRC5ka3IuZWNyLiRBV1NfREVGQVVMVF9SRUdJT04uYW1hem9uYXdzLmNvbScsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgYGVjaG8gXCJCdWlsZGluZyBEb2NrZXIgaW1hZ2Ugd2l0aCB0YWcgJHtpbWFnZVRhZ30uLi5cImAsXG4gICAgICAgICAgICBidWlsZENvbW1hbmQsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4uKGNhY2hlRGlzYWJsZWQgJiYge1xuICAgICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgIGBlY2hvIFwiUHVzaGluZyBEb2NrZXIgaW1hZ2Ugd2l0aCB0YWcgJHtpbWFnZVRhZ30uLi5cImAsXG4gICAgICAgICAgICAgIGBkb2NrZXIgcHVzaCAkRUNSX1JFUE9fVVJJOiR7aW1hZ2VUYWd9YCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH07XG5cbiAgICAvLyBDcmVhdGUgdGhlIENvZGVCdWlsZCBwcm9qZWN0XG4gICAgY29uc3QgY29kZUJ1aWxkUHJvamVjdCA9IG5ldyBQcm9qZWN0KHRoaXMsICdDb2RlQnVpbGRQcm9qZWN0Jywge1xuICAgICAgc291cmNlOiBTb3VyY2UuczMoe1xuICAgICAgICBidWNrZXQ6IHNvdXJjZUFzc2V0LmJ1Y2tldCxcbiAgICAgICAgcGF0aDogc291cmNlQXNzZXQuczNPYmplY3RLZXksXG4gICAgICB9KSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGJ1aWxkSW1hZ2U6IExpbnV4QnVpbGRJbWFnZS5TVEFOREFSRF83XzAsXG4gICAgICAgIHByaXZpbGVnZWQ6IHRydWUsXG4gICAgICB9LFxuICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IHtcbiAgICAgICAgRUNSX1JFUE9fVVJJOiB7IHZhbHVlOiB0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeVVyaSB9LFxuICAgICAgfSxcbiAgICAgIGJ1aWxkU3BlYzogQnVpbGRTcGVjLmZyb21PYmplY3QoYnVpbGRTcGVjT2JqKSxcbiAgICAgIHZwYyxcbiAgICAgIHNlY3VyaXR5R3JvdXBzLFxuICAgICAgc3VibmV0U2VsZWN0aW9uLFxuICAgIH0pO1xuXG4gICAgLy8gR3JhbnQgQ29kZUJ1aWxkIHRoZSBhYmlsaXR5IHRvIGludGVyYWN0IHdpdGggRUNSXG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goY29kZUJ1aWxkUHJvamVjdCk7XG4gICAgY29kZUJ1aWxkUHJvamVjdC5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICdlY3I6R2V0QXV0aG9yaXphdGlvblRva2VuJyxcbiAgICAgICAgICAnZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXInLFxuICAgICAgICAgICdlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgaWYgKGRvY2tlckxvZ2luU2VjcmV0QXJuKSB7XG4gICAgICBjb2RlQnVpbGRQcm9qZWN0LmFkZFRvUm9sZVBvbGljeShcbiAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogWydzZWNyZXRzbWFuYWdlcjpHZXRTZWNyZXRWYWx1ZSddLFxuICAgICAgICAgIHJlc291cmNlczogW2RvY2tlckxvZ2luU2VjcmV0QXJuXSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIENvbmRpdGlvbmFsbHkgZ3JhbnQgS01TIGVuY3J5cHQvZGVjcnlwdCBpZiBhIGtleSBpcyB1c2VkXG4gICAgaWYgKGVuY3J5cHRpb25LZXkpIHtcbiAgICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChjb2RlQnVpbGRQcm9qZWN0LnJvbGUhKTtcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgTGFtYmRhIGZ1bmN0aW9ucyBmb3IgY3VzdG9tIHJlc291cmNlIGV2ZW50IGFuZCBjb21wbGV0aW9uIGhhbmRsaW5nXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnT25FdmVudEhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vb25FdmVudCcpKSxcbiAgICAgIGhhbmRsZXI6ICdvbkV2ZW50LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG4gICAgb25FdmVudEhhbmRsZXJGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydjb2RlYnVpbGQ6U3RhcnRCdWlsZCddLFxuICAgICAgICByZXNvdXJjZXM6IFtjb2RlQnVpbGRQcm9qZWN0LnByb2plY3RBcm5dLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24gPSBuZXcgRnVuY3Rpb24odGhpcywgJ0lzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2lzQ29tcGxldGUnKSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBJTUFHRV9UQUc6IGltYWdlVGFnLFxuICAgICAgfSxcbiAgICAgIGhhbmRsZXI6ICdpc0NvbXBsZXRlLmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG4gICAgaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICdjb2RlYnVpbGQ6QmF0Y2hHZXRCdWlsZHMnLFxuICAgICAgICAgICdjb2RlYnVpbGQ6TGlzdEJ1aWxkc0ZvclByb2plY3QnLFxuICAgICAgICAgICdsb2dzOkdldExvZ0V2ZW50cycsXG4gICAgICAgICAgJ2xvZ3M6RGVzY3JpYmVMb2dTdHJlYW1zJyxcbiAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ0dyb3VwcycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gQ29uZGl0aW9uYWxseSBhbGxvdyBlbmNyeXB0aW9uIGlmIGEga2V5IGlzIHVzZWRcbiAgICBpZiAoZW5jcnlwdGlvbktleSkge1xuICAgICAgZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHREZWNyeXB0KG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24pO1xuICAgICAgZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHREZWNyeXB0KGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24pO1xuICAgIH1cbiAgICB0aGlzLmVjclJlcG9zaXRvcnkuZ3JhbnRQdWxsUHVzaChvbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkuZ3JhbnRQdWxsUHVzaChpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uKTtcblxuICAgIC8vIENyZWF0ZSBhIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlciB0aGF0IHVzZXMgdGhlIGFib3ZlIExhbWJkYXNcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnQ3VzdG9tUmVzb3VyY2VQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLFxuICAgICAgaXNDb21wbGV0ZUhhbmRsZXI6IGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24sXG4gICAgICBxdWVyeUludGVydmFsOiBjb21wbGV0ZW5lc3NRdWVyeUludGVydmFsID8/IER1cmF0aW9uLnNlY29uZHMoMzApLFxuICAgIH0pO1xuXG4gICAgLy8gQ3VzdG9tIFJlc291cmNlIHRoYXQgdHJpZ2dlcnMgdGhlIENvZGVCdWlsZCBhbmQgd2FpdHMgZm9yIGNvbXBsZXRpb25cbiAgICBjb25zdCBidWlsZFRyaWdnZXJSZXNvdXJjZSA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCAnQnVpbGRUcmlnZ2VyUmVzb3VyY2UnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgUHJvamVjdE5hbWU6IGNvZGVCdWlsZFByb2plY3QucHJvamVjdE5hbWUsXG4gICAgICAgIEltYWdlVGFnOiBpbWFnZVRhZyxcbiAgICAgICAgVHJpZ2dlcjogc291cmNlQXNzZXQuYXNzZXRIYXNoLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBidWlsZFRyaWdnZXJSZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY29kZUJ1aWxkUHJvamVjdCk7XG5cbiAgICAvLyBSZXRyaWV2ZSB0aGUgZmluYWwgRG9ja2VyIGltYWdlIHRhZyBmcm9tIERhdGEuSW1hZ2VUYWdcbiAgICBjb25zdCBpbWFnZVRhZ1JlZiA9IGJ1aWxkVHJpZ2dlclJlc291cmNlLmdldEF0dFN0cmluZygnSW1hZ2VUYWcnKTtcbiAgICB0aGlzLmNvbnRhaW5lckltYWdlID0gQ29udGFpbmVySW1hZ2UuZnJvbUVjclJlcG9zaXRvcnkodGhpcy5lY3JSZXBvc2l0b3J5LCBpbWFnZVRhZ1JlZik7XG4gICAgdGhpcy5kb2NrZXJJbWFnZUNvZGUgPSBEb2NrZXJJbWFnZUNvZGUuZnJvbUVjcih0aGlzLmVjclJlcG9zaXRvcnksIHtcbiAgICAgIHRhZ09yRGlnZXN0OiBpbWFnZVRhZ1JlZixcbiAgICB9KTtcbiAgfVxufVxuIl19
|