token-injectable-docker-builder 1.1.3 → 1.2.1

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 CHANGED
@@ -3898,7 +3898,7 @@
3898
3898
  },
3899
3899
  "name": "token-injectable-docker-builder",
3900
3900
  "readme": {
3901
- "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. 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.\n\n---\n\n## Features\n\n- Automatically builds and pushes Docker images to ECR.\n- Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.\n- Retrieves Docker images for use in ECS or Lambda.\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. |\n| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |\n\n---\n\n## Usage Examples\n\n### TypeScript/NPM Example\n\nHere is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with TypeScript:\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 lambda from 'aws-cdk-lib/aws-lambda';\n\nexport class MyStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: './docker',\n buildArgs: {\n TOKEN: 'my-secret-token',\n ENV: 'production',\n },\n dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',\n });\n\n // Use in ECS\n new ecs.FargateTaskDefinition(this, 'TaskDefinition', {\n containerImage: dockerBuilder.containerImage,\n });\n\n // Use in Lambda\n new lambda.Function(this, 'DockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n---\n\n### Python Example\n\nHere is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with Python:\n\n```python\nfrom aws_cdk import core as cdk\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\nfrom aws_cdk import aws_ecs as ecs\nfrom aws_cdk import aws_lambda as lambda_\n\nclass MyStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n docker_builder = TokenInjectableDockerBuilder(self, \"MyDockerBuilder\",\n path=\"./docker\",\n build_args={\n \"TOKEN\": \"my-secret-token\",\n \"ENV\": \"production\"\n },\n docker_login_secret_arn=\"arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret\"\n )\n\n # Use in ECS\n ecs.FargateTaskDefinition(self, \"TaskDefinition\",\n container_image=docker_builder.container_image\n )\n\n # Use in Lambda\n lambda_.Function(self, \"DockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\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 - 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`).\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- CodeBuild to pull and push images to ECR.\n- Lambda to monitor build status and retrieve logs.\n- Encryption via a custom KMS key.\n\n---\n\n## Notes\n\n- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags.\n- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules.\n- **Custom Resources**: Manages lifecycle events for builds using custom Lambda handlers.\n\n---\n\n## Troubleshooting\n\n1. **Build Errors**: Check CodeBuild logs in CloudWatch.\n2. **Lambda Errors**: Check `onEvent` and `isComplete` Lambda logs in CloudWatch.\n3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, and Secrets Manager.\n\n---\n\n## Support\n\nOpen an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).\n\n---\n\n## Reference Links\n[![View on Construct Hub](https://constructs.dev/badge?package=token-injectable-docker-builder)](https://constructs.dev/packages/token-injectable-docker-builder)\n"
3901
+ "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. 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 mutliple sepereate 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\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. |\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. |\n| `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. |\n\n---\n\n## Usage Examples\n\n### Simple Usage Example\n\nThis example demonstrates the most basic usage of the `TokenInjectableDockerBuilder`, where you specify the path to your Docker context and provide simple build arguments.\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 lambda from 'aws-cdk-lib/aws-lambda';\n\nexport class SimpleStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {\n path: './docker', // Path to your Dockerfile or Docker context\n buildArgs: {\n ENV: 'production', // Simple build argument\n },\n });\n\n // Use in ECS\n new ecs.ContainerDefinition(this, 'SimpleContainer', {\n image: dockerBuilder.containerImage,\n // ... other container properties ...\n });\n\n // Use in Lambda\n new lambda.Function(this, 'SimpleDockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_lambda as lambda_,\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 docker_builder = TokenInjectableDockerBuilder(self, \"SimpleDockerBuilder\",\n path=\"./docker\", # Path to your Dockerfile or Docker context\n build_args={\n \"ENV\": \"production\", # Simple build argument\n },\n )\n\n # Use in ECS\n ecs.ContainerDefinition(self, \"SimpleContainer\",\n image=docker_builder.container_image,\n # ... other container properties ...\n )\n\n # Use in Lambda\n lambda_.Function(self, \"SimpleDockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\n\n---\n\n### Advanced Usage Example\n\nThis example demonstrates more advanced usage, including using CDK tokens as build arguments, specifying custom install and pre-build commands, and configuring VPC settings.\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 lambda from 'aws-cdk-lib/aws-lambda';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\n\nexport class MyStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Example VPC and security group (optional)\n const vpc = new ec2.Vpc(this, 'MyVpc');\n const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {\n vpc,\n });\n\n // Example of using CDK tokens as build arguments\n const myApiGateway = /* ... create or import your API Gateway ... */;\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: './docker',\n buildArgs: {\n API_URL: myApiGateway.url, // Using CDK token\n ENV: 'production',\n },\n dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',\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 required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n preBuildCommands: [\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n });\n\n // Use in ECS\n new ecs.ContainerDefinition(this, 'MyContainer', {\n image: dockerBuilder.containerImage,\n // ... other container properties ...\n });\n\n // Use in Lambda\n new lambda.Function(this, 'DockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ec2 as ec2,\n aws_ecs as ecs,\n aws_lambda as lambda_,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass MyStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Example VPC and security group (optional)\n vpc = ec2.Vpc(self, \"MyVpc\")\n security_group = ec2.SecurityGroup(self, \"MySecurityGroup\", vpc=vpc)\n\n # Example of using CDK tokens as build arguments\n my_api_gateway = # ... create or import your API Gateway ...\n\n docker_builder = TokenInjectableDockerBuilder(self, \"MyDockerBuilder\",\n path=\"./docker\",\n build_args={\n \"API_URL\": my_api_gateway.url, # Using CDK token\n \"ENV\": \"production\"\n },\n docker_login_secret_arn=\"arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret\",\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 required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n pre_build_commands=[\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n )\n\n # Use in ECS\n ecs.ContainerDefinition(self, \"MyContainer\",\n image=docker_builder.container_image,\n # ... other container properties ...\n )\n\n # Use in Lambda\n lambda_.Function(self, \"DockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\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`).\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\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), ensure that the VPC configuration allows outbound internet access, or use a NAT gateway if in private subnets.\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[![View on Construct Hub](https://constructs.dev/badge?package=token-injectable-docker-builder)](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!"
3902
3902
  },
3903
3903
  "repository": {
3904
3904
  "type": "git",
@@ -3929,7 +3929,7 @@
3929
3929
  },
3930
3930
  "locationInModule": {
3931
3931
  "filename": "src/index.ts",
3932
- "line": 58
3932
+ "line": 123
3933
3933
  },
3934
3934
  "parameters": [
3935
3935
  {
@@ -3955,7 +3955,7 @@
3955
3955
  "kind": "class",
3956
3956
  "locationInModule": {
3957
3957
  "filename": "src/index.ts",
3958
- "line": 53
3958
+ "line": 118
3959
3959
  },
3960
3960
  "name": "TokenInjectableDockerBuilder",
3961
3961
  "properties": [
@@ -3966,7 +3966,7 @@
3966
3966
  "immutable": true,
3967
3967
  "locationInModule": {
3968
3968
  "filename": "src/index.ts",
3969
- "line": 55
3969
+ "line": 120
3970
3970
  },
3971
3971
  "name": "containerImage",
3972
3972
  "type": {
@@ -3980,7 +3980,7 @@
3980
3980
  "immutable": true,
3981
3981
  "locationInModule": {
3982
3982
  "filename": "src/index.ts",
3983
- "line": 56
3983
+ "line": 121
3984
3984
  },
3985
3985
  "name": "dockerImageCode",
3986
3986
  "type": {
@@ -4001,7 +4001,7 @@
4001
4001
  "kind": "interface",
4002
4002
  "locationInModule": {
4003
4003
  "filename": "src/index.ts",
4004
- "line": 17
4004
+ "line": 18
4005
4005
  },
4006
4006
  "name": "TokenInjectableDockerBuilderProps",
4007
4007
  "properties": [
@@ -4014,7 +4014,7 @@
4014
4014
  "immutable": true,
4015
4015
  "locationInModule": {
4016
4016
  "filename": "src/index.ts",
4017
- "line": 21
4017
+ "line": 22
4018
4018
  },
4019
4019
  "name": "path",
4020
4020
  "type": {
@@ -4032,7 +4032,7 @@
4032
4032
  "immutable": true,
4033
4033
  "locationInModule": {
4034
4034
  "filename": "src/index.ts",
4035
- "line": 32
4035
+ "line": 33
4036
4036
  },
4037
4037
  "name": "buildArgs",
4038
4038
  "optional": true,
@@ -4056,18 +4056,128 @@
4056
4056
  "immutable": true,
4057
4057
  "locationInModule": {
4058
4058
  "filename": "src/index.ts",
4059
- "line": 47
4059
+ "line": 48
4060
4060
  },
4061
4061
  "name": "dockerLoginSecretArn",
4062
4062
  "optional": true,
4063
4063
  "type": {
4064
4064
  "primitive": "string"
4065
4065
  }
4066
+ },
4067
+ {
4068
+ "abstract": true,
4069
+ "docs": {
4070
+ "default": "- No additional install commands.",
4071
+ "remarks": "**Example Usage:**\n```typescript\nnew TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: path.resolve(__dirname, '../app'),\n installCommands: [\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n // ... other properties ...\n});\n```\n*This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*",
4072
+ "stability": "stable",
4073
+ "summary": "Custom commands to run during the install phase."
4074
+ },
4075
+ "immutable": true,
4076
+ "locationInModule": {
4077
+ "filename": "src/index.ts",
4078
+ "line": 91
4079
+ },
4080
+ "name": "installCommands",
4081
+ "optional": true,
4082
+ "type": {
4083
+ "collection": {
4084
+ "elementtype": {
4085
+ "primitive": "string"
4086
+ },
4087
+ "kind": "array"
4088
+ }
4089
+ }
4090
+ },
4091
+ {
4092
+ "abstract": true,
4093
+ "docs": {
4094
+ "default": "- No additional pre-build commands.",
4095
+ "remarks": "**Example Usage:**\n```typescript\nnew TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: path.resolve(__dirname, '../app'),\n preBuildCommands: [\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n // ... other properties ...\n});\n```\n*In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*",
4096
+ "stability": "stable",
4097
+ "summary": "Custom commands to run during the pre_build phase."
4098
+ },
4099
+ "immutable": true,
4100
+ "locationInModule": {
4101
+ "filename": "src/index.ts",
4102
+ "line": 112
4103
+ },
4104
+ "name": "preBuildCommands",
4105
+ "optional": true,
4106
+ "type": {
4107
+ "collection": {
4108
+ "elementtype": {
4109
+ "primitive": "string"
4110
+ },
4111
+ "kind": "array"
4112
+ }
4113
+ }
4114
+ },
4115
+ {
4116
+ "abstract": true,
4117
+ "docs": {
4118
+ "default": "No security groups are attached.",
4119
+ "remarks": "These should define the network access rules for the CodeBuild project.",
4120
+ "stability": "stable",
4121
+ "summary": "The security groups to attach to the CodeBuild project."
4122
+ },
4123
+ "immutable": true,
4124
+ "locationInModule": {
4125
+ "filename": "src/index.ts",
4126
+ "line": 62
4127
+ },
4128
+ "name": "securityGroups",
4129
+ "optional": true,
4130
+ "type": {
4131
+ "collection": {
4132
+ "elementtype": {
4133
+ "fqn": "aws-cdk-lib.aws_ec2.ISecurityGroup"
4134
+ },
4135
+ "kind": "array"
4136
+ }
4137
+ }
4138
+ },
4139
+ {
4140
+ "abstract": true,
4141
+ "docs": {
4142
+ "default": "All subnets in the VPC are used.",
4143
+ "remarks": "Allows the user to select private, public, or isolated subnets.",
4144
+ "stability": "stable",
4145
+ "summary": "The subnet selection to specify which subnets to use within the VPC."
4146
+ },
4147
+ "immutable": true,
4148
+ "locationInModule": {
4149
+ "filename": "src/index.ts",
4150
+ "line": 69
4151
+ },
4152
+ "name": "subnetSelection",
4153
+ "optional": true,
4154
+ "type": {
4155
+ "fqn": "aws-cdk-lib.aws_ec2.SubnetSelection"
4156
+ }
4157
+ },
4158
+ {
4159
+ "abstract": true,
4160
+ "docs": {
4161
+ "default": "No VPC is attached, and the CodeBuild project will use public internet.",
4162
+ "remarks": "If provided, the CodeBuild project will be launched within the specified VPC.",
4163
+ "stability": "stable",
4164
+ "summary": "The VPC in which the CodeBuild project will be deployed."
4165
+ },
4166
+ "immutable": true,
4167
+ "locationInModule": {
4168
+ "filename": "src/index.ts",
4169
+ "line": 55
4170
+ },
4171
+ "name": "vpc",
4172
+ "optional": true,
4173
+ "type": {
4174
+ "fqn": "aws-cdk-lib.aws_ec2.IVpc"
4175
+ }
4066
4176
  }
4067
4177
  ],
4068
4178
  "symbolId": "src/index:TokenInjectableDockerBuilderProps"
4069
4179
  }
4070
4180
  },
4071
- "version": "1.1.3",
4072
- "fingerprint": "v6DFW98Thu9mQ4Bzmw2vWg3rPPZ0KabZFpqSivvcgbU="
4181
+ "version": "1.2.1",
4182
+ "fingerprint": "a7GeyojH1ylq8LpbucfYVuQAxmidU1TWKcf9PIFYzjw="
4073
4183
  }
package/API.md CHANGED
@@ -146,6 +146,11 @@ const tokenInjectableDockerBuilderProps: TokenInjectableDockerBuilderProps = { .
146
146
  | <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. |
147
147
  | <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. |
148
148
  | <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. |
149
+ | <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.installCommands">installCommands</a></code> | <code>string[]</code> | Custom commands to run during the install phase. |
150
+ | <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.preBuildCommands">preBuildCommands</a></code> | <code>string[]</code> | Custom commands to run during the pre_build phase. |
151
+ | <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.securityGroups">securityGroups</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup[]</code> | The security groups to attach to the CodeBuild project. |
152
+ | <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.subnetSelection">subnetSelection</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | The subnet selection to specify which subnets to use within the VPC. |
153
+ | <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | The VPC in which the CodeBuild project will be deployed. |
149
154
 
150
155
  ---
151
156
 
@@ -213,5 +218,104 @@ If not provided, the construct will skip Docker login during the build process.
213
218
  ```
214
219
 
215
220
 
221
+ ##### `installCommands`<sup>Optional</sup> <a name="installCommands" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.installCommands"></a>
222
+
223
+ ```typescript
224
+ public readonly installCommands: string[];
225
+ ```
226
+
227
+ - *Type:* string[]
228
+ - *Default:* No additional install commands.
229
+
230
+ Custom commands to run during the install phase.
231
+
232
+ **Example Usage:**
233
+ ```typescript
234
+ new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
235
+ path: path.resolve(__dirname, '../app'),
236
+ installCommands: [
237
+ 'echo "Updating package lists..."',
238
+ 'apt-get update -y',
239
+ 'echo "Installing required packages..."',
240
+ 'apt-get install -y curl dnsutils',
241
+ ],
242
+ // ... other properties ...
243
+ });
244
+ ```
245
+ *This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*
246
+
247
+ ---
248
+
249
+ ##### `preBuildCommands`<sup>Optional</sup> <a name="preBuildCommands" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.preBuildCommands"></a>
250
+
251
+ ```typescript
252
+ public readonly preBuildCommands: string[];
253
+ ```
254
+
255
+ - *Type:* string[]
256
+ - *Default:* No additional pre-build commands.
257
+
258
+ Custom commands to run during the pre_build phase.
259
+
260
+ **Example Usage:**
261
+ ```typescript
262
+ new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
263
+ path: path.resolve(__dirname, '../app'),
264
+ preBuildCommands: [
265
+ 'echo "Fetching configuration from private API..."',
266
+ 'curl -o config.json https://api.example.com/config',
267
+ ],
268
+ // ... other properties ...
269
+ });
270
+ ```
271
+ *In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*
272
+
273
+ ---
274
+
275
+ ##### `securityGroups`<sup>Optional</sup> <a name="securityGroups" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.securityGroups"></a>
276
+
277
+ ```typescript
278
+ public readonly securityGroups: ISecurityGroup[];
279
+ ```
280
+
281
+ - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[]
282
+ - *Default:* No security groups are attached.
283
+
284
+ The security groups to attach to the CodeBuild project.
285
+
286
+ These should define the network access rules for the CodeBuild project.
287
+
288
+ ---
289
+
290
+ ##### `subnetSelection`<sup>Optional</sup> <a name="subnetSelection" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.subnetSelection"></a>
291
+
292
+ ```typescript
293
+ public readonly subnetSelection: SubnetSelection;
294
+ ```
295
+
296
+ - *Type:* aws-cdk-lib.aws_ec2.SubnetSelection
297
+ - *Default:* All subnets in the VPC are used.
298
+
299
+ The subnet selection to specify which subnets to use within the VPC.
300
+
301
+ Allows the user to select private, public, or isolated subnets.
302
+
303
+ ---
304
+
305
+ ##### `vpc`<sup>Optional</sup> <a name="vpc" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.vpc"></a>
306
+
307
+ ```typescript
308
+ public readonly vpc: IVpc;
309
+ ```
310
+
311
+ - *Type:* aws-cdk-lib.aws_ec2.IVpc
312
+ - *Default:* No VPC is attached, and the CodeBuild project will use public internet.
313
+
314
+ The VPC in which the CodeBuild project will be deployed.
315
+
316
+ If provided, the CodeBuild project will be launched within the specified VPC.
317
+
318
+ ---
319
+
216
320
 
217
321
 
package/README.md CHANGED
@@ -6,17 +6,21 @@ The `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables
6
6
 
7
7
  ## Why?
8
8
 
9
- AWS 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.
9
+ AWS 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.
10
10
 
11
- For example, a Next.js frontend Docker image may require an API Gateway URL. 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.
11
+ For example, a Next.js frontend Docker image may require an API Gateway URL as an argument. 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 mutliple sepereate Stacks.
12
12
 
13
13
  ---
14
14
 
15
15
  ## Features
16
16
 
17
- - Automatically builds and pushes Docker images to ECR.
18
- - Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.
19
- - Retrieves Docker images for use in ECS or Lambda.
17
+ - **Build and Push Docker Images**: Automatically builds and pushes Docker images to ECR.
18
+ - **Token Support**: Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.
19
+ - **Custom Install and Pre-Build Commands**: Allows specifying custom commands to run during the `install` and `pre_build` phases of the CodeBuild build process.
20
+ - **VPC Configuration**: Supports deploying the CodeBuild project within a VPC, with customizable security groups and subnet selection.
21
+ - **Docker Login**: Supports Docker login using credentials stored in AWS Secrets Manager.
22
+ - **ECR Repository Management**: Creates an ECR repository with lifecycle rules and encryption.
23
+ - **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.
20
24
 
21
25
  ---
22
26
 
@@ -52,42 +56,150 @@ pip install token-injectable-docker-builder
52
56
 
53
57
  #### Properties in `TokenInjectableDockerBuilderProps`
54
58
 
55
- | Property | Type | Required | Description |
56
- |------------------------|--------------------|----------|-------------------------------------------------------------------------------------------------------|
57
- | `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |
58
- | `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. |
59
- | `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |
59
+ | Property | Type | Required | Description |
60
+ |--------------------------|-----------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
61
+ | `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |
62
+ | `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. These are transformed into `--build-arg` flags. |
63
+ | `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |
64
+ | `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. |
65
+ | `securityGroups` | `ISecurityGroup[]` | No | The security groups to attach to the CodeBuild project. These should define the network access rules for the CodeBuild project. |
66
+ | `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. |
67
+ | `installCommands` | `string[]` | No | Custom commands to run during the `install` phase of the CodeBuild build process. |
68
+ | `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. |
60
69
 
61
70
  ---
62
71
 
63
72
  ## Usage Examples
64
73
 
65
- ### TypeScript/NPM Example
74
+ ### Simple Usage Example
66
75
 
67
- Here is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with TypeScript:
76
+ This example demonstrates the most basic usage of the `TokenInjectableDockerBuilder`, where you specify the path to your Docker context and provide simple build arguments.
77
+
78
+ #### TypeScript/NPM Example
79
+
80
+ ```typescript
81
+ import * as cdk from 'aws-cdk-lib';
82
+ import { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';
83
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
84
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
85
+
86
+ export class SimpleStack extends cdk.Stack {
87
+ constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
88
+ super(scope, id, props);
89
+
90
+ const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {
91
+ path: './docker', // Path to your Dockerfile or Docker context
92
+ buildArgs: {
93
+ ENV: 'production', // Simple build argument
94
+ },
95
+ });
96
+
97
+ // Use in ECS
98
+ new ecs.ContainerDefinition(this, 'SimpleContainer', {
99
+ image: dockerBuilder.containerImage,
100
+ // ... other container properties ...
101
+ });
102
+
103
+ // Use in Lambda
104
+ new lambda.Function(this, 'SimpleDockerLambdaFunction', {
105
+ runtime: lambda.Runtime.FROM_IMAGE,
106
+ code: dockerBuilder.dockerImageCode,
107
+ handler: lambda.Handler.FROM_IMAGE,
108
+ });
109
+ }
110
+ }
111
+ ```
112
+
113
+ #### Python Example
114
+
115
+ ```python
116
+ from aws_cdk import (
117
+ aws_ecs as ecs,
118
+ aws_lambda as lambda_,
119
+ core as cdk,
120
+ )
121
+ from token_injectable_docker_builder import TokenInjectableDockerBuilder
122
+
123
+ class SimpleStack(cdk.Stack):
124
+
125
+ def __init__(self, scope: cdk.App, id: str, **kwargs):
126
+ super().__init__(scope, id, **kwargs)
127
+
128
+ docker_builder = TokenInjectableDockerBuilder(self, "SimpleDockerBuilder",
129
+ path="./docker", # Path to your Dockerfile or Docker context
130
+ build_args={
131
+ "ENV": "production", # Simple build argument
132
+ },
133
+ )
134
+
135
+ # Use in ECS
136
+ ecs.ContainerDefinition(self, "SimpleContainer",
137
+ image=docker_builder.container_image,
138
+ # ... other container properties ...
139
+ )
140
+
141
+ # Use in Lambda
142
+ lambda_.Function(self, "SimpleDockerLambdaFunction",
143
+ runtime=lambda_.Runtime.FROM_IMAGE,
144
+ code=docker_builder.docker_image_code,
145
+ handler=lambda_.Handler.FROM_IMAGE
146
+ )
147
+ ```
148
+
149
+ ---
150
+
151
+ ### Advanced Usage Example
152
+
153
+ This example demonstrates more advanced usage, including using CDK tokens as build arguments, specifying custom install and pre-build commands, and configuring VPC settings.
154
+
155
+ #### TypeScript/NPM Example
68
156
 
69
157
  ```typescript
70
158
  import * as cdk from 'aws-cdk-lib';
71
159
  import { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';
72
160
  import * as ecs from 'aws-cdk-lib/aws-ecs';
73
161
  import * as lambda from 'aws-cdk-lib/aws-lambda';
162
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
74
163
 
75
164
  export class MyStack extends cdk.Stack {
76
165
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
77
166
  super(scope, id, props);
78
167
 
168
+ // Example VPC and security group (optional)
169
+ const vpc = new ec2.Vpc(this, 'MyVpc');
170
+ const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {
171
+ vpc,
172
+ });
173
+
174
+ // Example of using CDK tokens as build arguments
175
+ const myApiGateway = /* ... create or import your API Gateway ... */;
176
+
79
177
  const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
80
178
  path: './docker',
81
179
  buildArgs: {
82
- TOKEN: 'my-secret-token',
180
+ API_URL: myApiGateway.url, // Using CDK token
83
181
  ENV: 'production',
84
182
  },
85
183
  dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',
184
+ vpc,
185
+ securityGroups: [securityGroup],
186
+ subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
187
+ installCommands: [
188
+ 'echo "Updating package lists..."',
189
+ 'apt-get update -y',
190
+ 'echo "Installing required packages..."',
191
+ 'apt-get install -y curl dnsutils',
192
+ ],
193
+ preBuildCommands: [
194
+ 'echo "Fetching configuration from private API..."',
195
+ 'curl -o config.json https://api.example.com/config',
196
+ ],
86
197
  });
87
198
 
88
199
  // Use in ECS
89
- new ecs.FargateTaskDefinition(this, 'TaskDefinition', {
90
- containerImage: dockerBuilder.containerImage,
200
+ new ecs.ContainerDefinition(this, 'MyContainer', {
201
+ image: dockerBuilder.containerImage,
202
+ // ... other container properties ...
91
203
  });
92
204
 
93
205
  // Use in Lambda
@@ -100,35 +212,55 @@ export class MyStack extends cdk.Stack {
100
212
  }
101
213
  ```
102
214
 
103
- ---
104
-
105
- ### Python Example
106
-
107
- Here is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with Python:
215
+ #### Python Example
108
216
 
109
217
  ```python
110
- from aws_cdk import core as cdk
218
+ from aws_cdk import (
219
+ aws_ec2 as ec2,
220
+ aws_ecs as ecs,
221
+ aws_lambda as lambda_,
222
+ core as cdk,
223
+ )
111
224
  from token_injectable_docker_builder import TokenInjectableDockerBuilder
112
- from aws_cdk import aws_ecs as ecs
113
- from aws_cdk import aws_lambda as lambda_
114
225
 
115
226
  class MyStack(cdk.Stack):
116
227
 
117
228
  def __init__(self, scope: cdk.App, id: str, **kwargs):
118
229
  super().__init__(scope, id, **kwargs)
119
230
 
231
+ # Example VPC and security group (optional)
232
+ vpc = ec2.Vpc(self, "MyVpc")
233
+ security_group = ec2.SecurityGroup(self, "MySecurityGroup", vpc=vpc)
234
+
235
+ # Example of using CDK tokens as build arguments
236
+ my_api_gateway = # ... create or import your API Gateway ...
237
+
120
238
  docker_builder = TokenInjectableDockerBuilder(self, "MyDockerBuilder",
121
239
  path="./docker",
122
240
  build_args={
123
- "TOKEN": "my-secret-token",
241
+ "API_URL": my_api_gateway.url, # Using CDK token
124
242
  "ENV": "production"
125
243
  },
126
- docker_login_secret_arn="arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret"
244
+ docker_login_secret_arn="arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret",
245
+ vpc=vpc,
246
+ security_groups=[security_group],
247
+ subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),
248
+ install_commands=[
249
+ 'echo "Updating package lists..."',
250
+ 'apt-get update -y',
251
+ 'echo "Installing required packages..."',
252
+ 'apt-get install -y curl dnsutils',
253
+ ],
254
+ pre_build_commands=[
255
+ 'echo "Fetching configuration from private API..."',
256
+ 'curl -o config.json https://api.example.com/config',
257
+ ],
127
258
  )
128
259
 
129
260
  # Use in ECS
130
- ecs.FargateTaskDefinition(self, "TaskDefinition",
131
- container_image=docker_builder.container_image
261
+ ecs.ContainerDefinition(self, "MyContainer",
262
+ image=docker_builder.container_image,
263
+ # ... other container properties ...
132
264
  )
133
265
 
134
266
  # Use in Lambda
@@ -146,6 +278,7 @@ class MyStack(cdk.Stack):
146
278
  1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.
147
279
  2. **CodeBuild Project**:
148
280
  - Uses the packaged asset and `buildArgs` to build the Docker image.
281
+ - Executes any custom `installCommands` and `preBuildCommands` during the build process.
149
282
  - Pushes the image to an ECR repository.
150
283
  3. **Custom Resource**:
151
284
  - Triggers the build process using a Lambda function (`onEvent`).
@@ -159,33 +292,61 @@ class MyStack(cdk.Stack):
159
292
  ## IAM Permissions
160
293
 
161
294
  The construct automatically grants permissions for:
162
- - CodeBuild to pull and push images to ECR.
163
- - Lambda to monitor build status and retrieve logs.
164
- - Encryption via a custom KMS key.
295
+
296
+ - **CodeBuild**:
297
+ - Pull and push images to ECR.
298
+ - Access to AWS Secrets Manager if `dockerLoginSecretArn` is provided.
299
+ - Access to the KMS key for encryption.
300
+ - **Lambda Functions**:
301
+ - Start and monitor CodeBuild builds.
302
+ - Access CloudWatch Logs.
303
+ - Access to the KMS key for encryption.
304
+ - Pull and push images to ECR.
165
305
 
166
306
  ---
167
307
 
168
308
  ## Notes
169
309
 
170
- - **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags.
171
- - **ECR Repository**: Automatically creates an ECR repository with lifecycle rules.
172
- - **Custom Resources**: Manages lifecycle events for builds using custom Lambda handlers.
310
+ - **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags. CDK tokens can be used to inject dynamic values resolved at deployment time.
311
+ - **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.
312
+ - **VPC Configuration**: If your build process requires access to resources within a VPC, you can specify the VPC, security groups, and subnet selection.
313
+ - **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.
314
+ - **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.
173
315
 
174
316
  ---
175
317
 
176
318
  ## Troubleshooting
177
319
 
178
- 1. **Build Errors**: Check CodeBuild logs in CloudWatch.
179
- 2. **Lambda Errors**: Check `onEvent` and `isComplete` Lambda logs in CloudWatch.
180
- 3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, and Secrets Manager.
320
+ 1. **Build Errors**: Check the CodeBuild logs in CloudWatch Logs for detailed error messages.
321
+ 2. **Lambda Errors**: Check the `onEvent` and `isComplete` Lambda function logs in CloudWatch Logs.
322
+ 3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, Secrets Manager, and KMS if applicable.
323
+ 4. **Network Access**: If the build requires network access (e.g., to download dependencies), ensure that the VPC configuration allows outbound internet access, or use a NAT gateway if in private subnets.
181
324
 
182
325
  ---
183
326
 
184
327
  ## Support
185
328
 
186
- Open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).
329
+ For issues or feature requests, please open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).
187
330
 
188
331
  ---
189
332
 
190
333
  ## Reference Links
334
+
191
335
  [![View on Construct Hub](https://constructs.dev/badge?package=token-injectable-docker-builder)](https://constructs.dev/packages/token-injectable-docker-builder)
336
+
337
+ ---
338
+
339
+ # License
340
+
341
+ This project is licensed under the terms of the MIT license.
342
+
343
+ ---
344
+
345
+ # Acknowledgements
346
+
347
+ - Inspired by the need for more dynamic Docker asset management in AWS CDK.
348
+ - Thanks to the AWS CDK community for their continuous support and contributions.
349
+
350
+ ---
351
+
352
+ Feel free to reach out if you have any questions or need further assistance!
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { IVpc, ISecurityGroup, SubnetSelection } from 'aws-cdk-lib/aws-ec2';
1
2
  import { ContainerImage } from 'aws-cdk-lib/aws-ecs';
2
3
  import { DockerImageCode } from 'aws-cdk-lib/aws-lambda';
3
4
  import { Construct } from 'constructs';
@@ -35,6 +36,64 @@ export interface TokenInjectableDockerBuilderProps {
35
36
  * @example 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret'
36
37
  */
37
38
  readonly dockerLoginSecretArn?: string;
39
+ /**
40
+ * The VPC in which the CodeBuild project will be deployed.
41
+ * If provided, the CodeBuild project will be launched within the specified VPC.
42
+ * @default No VPC is attached, and the CodeBuild project will use public internet.
43
+ */
44
+ readonly vpc?: IVpc;
45
+ /**
46
+ * The security groups to attach to the CodeBuild project.
47
+ * These should define the network access rules for the CodeBuild project.
48
+ * @default No security groups are attached.
49
+ */
50
+ readonly securityGroups?: ISecurityGroup[];
51
+ /**
52
+ * The subnet selection to specify which subnets to use within the VPC.
53
+ * Allows the user to select private, public, or isolated subnets.
54
+ * @default All subnets in the VPC are used.
55
+ */
56
+ readonly subnetSelection?: SubnetSelection;
57
+ /**
58
+ * Custom commands to run during the install phase.
59
+ *
60
+ * **Example Usage:**
61
+ * ```typescript
62
+ * new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
63
+ * path: path.resolve(__dirname, '../app'),
64
+ * installCommands: [
65
+ * 'echo "Updating package lists..."',
66
+ * 'apt-get update -y',
67
+ * 'echo "Installing required packages..."',
68
+ * 'apt-get install -y curl dnsutils',
69
+ * ],
70
+ * // ... other properties ...
71
+ * });
72
+ * ```
73
+ * *This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*
74
+ *
75
+ * @default - No additional install commands.
76
+ */
77
+ readonly installCommands?: string[];
78
+ /**
79
+ * Custom commands to run during the pre_build phase.
80
+ *
81
+ * **Example Usage:**
82
+ * ```typescript
83
+ * new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
84
+ * path: path.resolve(__dirname, '../app'),
85
+ * preBuildCommands: [
86
+ * 'echo "Fetching configuration from private API..."',
87
+ * 'curl -o config.json https://api.example.com/config',
88
+ * ],
89
+ * // ... other properties ...
90
+ * });
91
+ * ```
92
+ * *In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*
93
+ *
94
+ * @default - No additional pre-build commands.
95
+ */
96
+ readonly preBuildCommands?: string[];
38
97
  }
39
98
  /**
40
99
  * A CDK construct to build and push Docker images to an ECR repository using CodeBuild and Lambda custom resources.
package/lib/index.js CHANGED
@@ -21,7 +21,7 @@ const constructs_1 = require("constructs");
21
21
  class TokenInjectableDockerBuilder extends constructs_1.Construct {
22
22
  constructor(scope, id, props) {
23
23
  super(scope, id);
24
- const { path: sourcePath, buildArgs, dockerLoginSecretArn } = props;
24
+ const { path: sourcePath, buildArgs, dockerLoginSecretArn, vpc, securityGroups, subnetSelection, installCommands, preBuildCommands, } = props;
25
25
  // Define a KMS key for ECR encryption
26
26
  const encryptionKey = new aws_kms_1.Key(this, 'EcrEncryptionKey', {
27
27
  enableKeyRotation: true,
@@ -73,12 +73,25 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
73
73
  environmentVariables: {
74
74
  ECR_REPO_URI: { value: this.ecrRepository.repositoryUri },
75
75
  BUILD_ARGS: { value: buildArgsString },
76
+ // Include build arguments as environment variables if needed
77
+ ...(buildArgs &&
78
+ Object.fromEntries(Object.entries(buildArgs).map(([key, value]) => [key, { value }]))),
76
79
  },
80
+ vpc,
81
+ securityGroups,
82
+ subnetSelection,
77
83
  buildSpec: aws_codebuild_1.BuildSpec.fromObject({
78
84
  version: '0.2',
79
85
  phases: {
86
+ install: {
87
+ commands: [
88
+ 'echo "Beginning install phase..."',
89
+ ...(installCommands || []),
90
+ ],
91
+ },
80
92
  pre_build: {
81
93
  commands: [
94
+ ...(preBuildCommands || []),
82
95
  ...dockerLoginCommands,
83
96
  'echo "Retrieving AWS Account ID..."',
84
97
  'export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)',
@@ -104,7 +117,11 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
104
117
  // Grant permissions to CodeBuild
105
118
  this.ecrRepository.grantPullPush(codeBuildProject);
106
119
  codeBuildProject.role.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
107
- actions: ['ecr:GetAuthorizationToken', 'ecr:GetDownloadUrlForLayer', 'ecr:BatchCheckLayerAvailability'],
120
+ actions: [
121
+ 'ecr:GetAuthorizationToken',
122
+ 'ecr:GetDownloadUrlForLayer',
123
+ 'ecr:BatchCheckLayerAvailability',
124
+ ],
108
125
  resources: [this.ecrRepository.repositoryArn],
109
126
  }));
110
127
  if (dockerLoginSecretArn) {
@@ -168,5 +185,5 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
168
185
  }
169
186
  exports.TokenInjectableDockerBuilder = TokenInjectableDockerBuilder;
170
187
  _a = JSII_RTTI_SYMBOL_1;
171
- TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.1.3" };
172
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBQzdCLDZDQUF1RDtBQUN2RCw2REFBd0Y7QUFDeEYsaURBQWtGO0FBQ2xGLGlEQUFxRDtBQUNyRCxpREFBc0Q7QUFDdEQsaURBQTBDO0FBQzFDLHVEQUFrRjtBQUNsRiw2REFBa0Q7QUFDbEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQXNDdkM7O0dBRUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBS3pELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFcEUsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUN0RCxpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztRQUVILHdGQUF3RjtRQUN4RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksb0JBQVUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQ3pELGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxZQUFZLEVBQUUsQ0FBQztvQkFDZixXQUFXLEVBQUUsb0NBQW9DO29CQUNqRCxTQUFTLEVBQUUsbUJBQVMsQ0FBQyxRQUFRO29CQUM3QixXQUFXLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUM5QjthQUNGO1lBQ0QsVUFBVSxFQUFFLDhCQUFvQixDQUFDLEdBQUc7WUFDcEMsYUFBYSxFQUFFLGFBQWE7WUFDNUIsZUFBZSxFQUFFLElBQUk7U0FDdEIsQ0FBQyxDQUFDO1FBRUgsc0NBQXNDO1FB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Q0FBQztRQUMxRCxhQUFhLENBQUMsbUJBQW1CLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFNUQsb0NBQW9DO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLElBQUksMkJBQVEsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUU7WUFDNUQsY0FBYyxFQUFFLHNCQUFzQjtZQUN0QyxpQkFBaUIsRUFBRSx5QkFBeUI7WUFDNUMsYUFBYSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztTQUNwQyxDQUFDLENBQUM7UUFFSCw2QkFBNkI7UUFDN0IsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLDRCQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQzVFLFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtZQUNuQyxVQUFVLEVBQUU7Z0JBQ1YsV0FBVyxFQUFFLGdCQUFnQixDQUFDLFdBQVc7Z0JBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFO2FBQzdCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsd0JBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLGVBQWUsR0FBRyw0QkFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckUsQ0FBQzs7QUFoTEgsb0VBaUxDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUHJvamVjdCwgU291cmNlLCBMaW51eEJ1aWxkSW1hZ2UsIEJ1aWxkU3BlYyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSwgUmVwb3NpdG9yeUVuY3J5cHRpb24sIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgQ29udGFpbmVySW1hZ2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBSdW50aW1lLCBDb2RlLCBEb2NrZXJJbWFnZUNvZGUsIEZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBc3NldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMy1hc3NldHMnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIERvY2tlcmZpbGUgb3Igc291cmNlIGNvZGUuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBEb2NrZXIgYnVpbGQgcHJvY2Vzcy5cbiAgICogVGhlc2UgYXJlIHRyYW5zZm9ybWVkIGludG8gYC0tYnVpbGQtYXJnYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhpcyBzZWNyZXQgc2hvdWxkIHN0b3JlIGEgSlNPTiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJ1c2VybmFtZVwiOiBcIm15LWRvY2tlci11c2VybmFtZVwiLFxuICAgKiAgIFwicGFzc3dvcmRcIjogXCJteS1kb2NrZXItcGFzc3dvcmRcIlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBjb25zdHJ1Y3Qgd2lsbCBza2lwIERvY2tlciBsb2dpbiBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gICAqXG4gICAqIEBleGFtcGxlICdhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6c2VjcmV0OkRvY2tlckxvZ2luU2VjcmV0J1xuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyTG9naW5TZWNyZXRBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBDREsgY29uc3RydWN0IHRvIGJ1aWxkIGFuZCBwdXNoIERvY2tlciBpbWFnZXMgdG8gYW4gRUNSIHJlcG9zaXRvcnkgdXNpbmcgQ29kZUJ1aWxkIGFuZCBMYW1iZGEgY3VzdG9tIHJlc291cmNlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGVjclJlcG9zaXRvcnk6IFJlcG9zaXRvcnk7XG4gIHB1YmxpYyByZWFkb25seSBjb250YWluZXJJbWFnZTogQ29udGFpbmVySW1hZ2U7XG4gIHB1YmxpYyByZWFkb25seSBkb2NrZXJJbWFnZUNvZGU6IERvY2tlckltYWdlQ29kZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHsgcGF0aDogc291cmNlUGF0aCwgYnVpbGRBcmdzLCBkb2NrZXJMb2dpblNlY3JldEFybiB9ID0gcHJvcHM7XG5cbiAgICAvLyBEZWZpbmUgYSBLTVMga2V5IGZvciBFQ1IgZW5jcnlwdGlvblxuICAgIGNvbnN0IGVuY3J5cHRpb25LZXkgPSBuZXcgS2V5KHRoaXMsICdFY3JFbmNyeXB0aW9uS2V5Jywge1xuICAgICAgZW5hYmxlS2V5Um90YXRpb246IHRydWUsXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgYW4gRUNSIHJlcG9zaXRvcnkgd2l0aCBsaWZlY3ljbGUgcnVsZXMsIGVuY3J5cHRpb24sIGFuZCBpbWFnZSBzY2FubmluZyBlbmFibGVkXG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5ID0gbmV3IFJlcG9zaXRvcnkodGhpcywgJ0VDUlJlcG9zaXRvcnknLCB7XG4gICAgICBsaWZlY3ljbGVSdWxlczogW1xuICAgICAgICB7XG4gICAgICAgICAgcnVsZVByaW9yaXR5OiAxLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVtb3ZlIHVudGFnZ2VkIGltYWdlcyBhZnRlciAxIGRheScsXG4gICAgICAgICAgdGFnU3RhdHVzOiBUYWdTdGF0dXMuVU5UQUdHRUQsXG4gICAgICAgICAgbWF4SW1hZ2VBZ2U6IER1cmF0aW9uLmRheXMoMSksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZW5jcnlwdGlvbjogUmVwb3NpdG9yeUVuY3J5cHRpb24uS01TLFxuICAgICAgZW5jcnlwdGlvbktleTogZW5jcnlwdGlvbktleSxcbiAgICAgIGltYWdlU2Nhbk9uUHVzaDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIFBhY2thZ2UgdGhlIHNvdXJjZSBjb2RlIGFzIGFuIGFzc2V0XG4gICAgY29uc3Qgc291cmNlQXNzZXQgPSBuZXcgQXNzZXQodGhpcywgJ1NvdXJjZUFzc2V0Jywge1xuICAgICAgcGF0aDogc291cmNlUGF0aCxcbiAgICB9KTtcblxuICAgIC8vIFRyYW5zZm9ybSBidWlsZEFyZ3MgaW50byBhIHN0cmluZyBvZiAtLWJ1aWxkLWFyZyBLRVk9VkFMVUVcbiAgICBjb25zdCBidWlsZEFyZ3NTdHJpbmcgPSBidWlsZEFyZ3NcbiAgICAgID8gT2JqZWN0LmVudHJpZXMoYnVpbGRBcmdzKVxuICAgICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAtLWJ1aWxkLWFyZyAke2tleX09JHt2YWx1ZX1gKVxuICAgICAgICAuam9pbignICcpXG4gICAgICA6ICcnO1xuXG4gICAgLy8gQ29uZGl0aW9uYWwgRG9ja2VyaHViIGxvZ2luIGNvbW1hbmRzXG4gICAgY29uc3QgZG9ja2VyTG9naW5Db21tYW5kcyA9IGRvY2tlckxvZ2luU2VjcmV0QXJuXG4gICAgICA/IFtcbiAgICAgICAgJ2VjaG8gXCJSZXRyaWV2aW5nIERvY2tlciBjcmVkZW50aWFscyBmcm9tIFNlY3JldHMgTWFuYWdlci4uLlwiJyxcbiAgICAgICAgYERPQ0tFUl9VU0VSTkFNRT0kKGF3cyBzZWNyZXRzbWFuYWdlciBnZXQtc2VjcmV0LXZhbHVlIC0tc2VjcmV0LWlkICR7ZG9ja2VyTG9naW5TZWNyZXRBcm59IC0tcXVlcnkgU2VjcmV0U3RyaW5nIC0tb3V0cHV0IHRleHQgfCBqcSAtciAudXNlcm5hbWUpYCxcbiAgICAgICAgYERPQ0tFUl9QQVNTV09SRD0kKGF3cyBzZWNyZXRzbWFuYWdlciBnZXQtc2VjcmV0LXZhbHVlIC0tc2VjcmV0LWlkICR7ZG9ja2VyTG9naW5TZWNyZXRBcm59IC0tcXVlcnkgU2VjcmV0U3RyaW5nIC0tb3V0cHV0IHRleHQgfCBqcSAtciAucGFzc3dvcmQpYCxcbiAgICAgICAgJ2VjaG8gXCJMb2dnaW5nIGluIHRvIERvY2tlci4uLlwiJyxcbiAgICAgICAgJ2VjaG8gJERPQ0tFUl9QQVNTV09SRCB8IGRvY2tlciBsb2dpbiAtLXVzZXJuYW1lICRET0NLRVJfVVNFUk5BTUUgLS1wYXNzd29yZC1zdGRpbicsXG4gICAgICBdXG4gICAgICA6IFsnZWNobyBcIk5vIERvY2tlciBjcmVkZW50aWFscyBwcm92aWRlZC4gU2tpcHBpbmcgbG9naW4gc3RlcC5cIiddO1xuXG4gICAgLy8gQ3JlYXRlIGEgQ29kZUJ1aWxkIHByb2plY3RcbiAgICBjb25zdCBjb2RlQnVpbGRQcm9qZWN0ID0gbmV3IFByb2plY3QodGhpcywgJ1VJQ29kZUJ1aWxkUHJvamVjdCcsIHtcbiAgICAgIHNvdXJjZTogU291cmNlLnMzKHtcbiAgICAgICAgYnVja2V0OiBzb3VyY2VBc3NldC5idWNrZXQsXG4gICAgICAgIHBhdGg6IHNvdXJjZUFzc2V0LnMzT2JqZWN0S2V5LFxuICAgICAgfSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBidWlsZEltYWdlOiBMaW51eEJ1aWxkSW1hZ2UuU1RBTkRBUkRfN18wLFxuICAgICAgICBwcml2aWxlZ2VkOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVzOiB7XG4gICAgICAgIEVDUl9SRVBPX1VSSTogeyB2YWx1ZTogdGhpcy5lY3JSZXBvc2l0b3J5LnJlcG9zaXRvcnlVcmkgfSxcbiAgICAgICAgQlVJTERfQVJHUzogeyB2YWx1ZTogYnVpbGRBcmdzU3RyaW5nIH0sXG4gICAgICB9LFxuICAgICAgYnVpbGRTcGVjOiBCdWlsZFNwZWMuZnJvbU9iamVjdCh7XG4gICAgICAgIHZlcnNpb246ICcwLjInLFxuICAgICAgICBwaGFzZXM6IHtcbiAgICAgICAgICBwcmVfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgIC4uLmRvY2tlckxvZ2luQ29tbWFuZHMsXG4gICAgICAgICAgICAgICdlY2hvIFwiUmV0cmlldmluZyBBV1MgQWNjb3VudCBJRC4uLlwiJyxcbiAgICAgICAgICAgICAgJ2V4cG9ydCBBQ0NPVU5UX0lEPSQoYXdzIHN0cyBnZXQtY2FsbGVyLWlkZW50aXR5IC0tcXVlcnkgQWNjb3VudCAtLW91dHB1dCB0ZXh0KScsXG4gICAgICAgICAgICAgICdlY2hvIFwiTG9nZ2luZyBpbiB0byBBbWF6b24gRUNSLi4uXCInLFxuICAgICAgICAgICAgICAnYXdzIGVjciBnZXQtbG9naW4tcGFzc3dvcmQgLS1yZWdpb24gJEFXU19ERUZBVUxUX1JFR0lPTiB8IGRvY2tlciBsb2dpbiAtLXVzZXJuYW1lIEFXUyAtLXBhc3N3b3JkLXN0ZGluICRBQ0NPVU5UX0lELmRrci5lY3IuJEFXU19ERUZBVUxUX1JFR0lPTi5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBidWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgJ2VjaG8gQnVpbGQgcGhhc2U6IEJ1aWxkaW5nIHRoZSBEb2NrZXIgaW1hZ2UuLi4nLFxuICAgICAgICAgICAgICAnZG9ja2VyIGJ1aWxkICRCVUlMRF9BUkdTIC10ICRFQ1JfUkVQT19VUkk6bGF0ZXN0ICRDT0RFQlVJTERfU1JDX0RJUicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcG9zdF9idWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgJ2VjaG8gUG9zdC1idWlsZCBwaGFzZTogUHVzaGluZyB0aGUgRG9ja2VyIGltYWdlLi4uJyxcbiAgICAgICAgICAgICAgJ2RvY2tlciBwdXNoICRFQ1JfUkVQT19VUkk6bGF0ZXN0JyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgLy8gR3JhbnQgcGVybWlzc2lvbnMgdG8gQ29kZUJ1aWxkXG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goY29kZUJ1aWxkUHJvamVjdCk7XG5cbiAgICBjb2RlQnVpbGRQcm9qZWN0LnJvbGUhLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnZWNyOkdldEF1dGhvcml6YXRpb25Ub2tlbicsICdlY3I6R2V0RG93bmxvYWRVcmxGb3JMYXllcicsICdlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5J10sXG4gICAgICAgIHJlc291cmNlczogW3RoaXMuZWNyUmVwb3NpdG9yeS5yZXBvc2l0b3J5QXJuXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBpZiAoZG9ja2VyTG9naW5TZWNyZXRBcm4pIHtcbiAgICAgIGNvZGVCdWlsZFByb2plY3Qucm9sZSEuYWRkVG9QcmluY2lwYWxQb2xpY3koXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFsnc2VjcmV0c21hbmFnZXI6R2V0U2VjcmV0VmFsdWUnXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtkb2NrZXJMb2dpblNlY3JldEFybl0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBHcmFudCBDb2RlQnVpbGQgYWNjZXNzIHRvIHRoZSBLTVMga2V5XG4gICAgZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHREZWNyeXB0KGNvZGVCdWlsZFByb2plY3Qucm9sZSEpO1xuXG4gICAgLy8gQ3JlYXRlIExhbWJkYSBmdW5jdGlvbnMgZm9yIG9uRXZlbnQgYW5kIGlzQ29tcGxldGUgaGFuZGxlcnNcbiAgICBjb25zdCBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdPbkV2ZW50SGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9vbkV2ZW50JykpLFxuICAgICAgaGFuZGxlcjogJ29uRXZlbnQuaGFuZGxlcicsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICB9KTtcblxuICAgIG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnY29kZWJ1aWxkOlN0YXJ0QnVpbGQnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbY29kZUJ1aWxkUHJvamVjdC5wcm9qZWN0QXJuXSwgLy8gUmVzdHJpY3QgdG8gc3BlY2lmaWMgcHJvamVjdFxuICAgICAgfSksXG4gICAgKTtcbiAgICBjb25zdCBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdJc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9pc0NvbXBsZXRlJykpLFxuICAgICAgaGFuZGxlcjogJ2lzQ29tcGxldGUuaGFuZGxlcicsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICB9KTtcblxuICAgIGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnY29kZWJ1aWxkOkJhdGNoR2V0QnVpbGRzJyxcbiAgICAgICAgICAnY29kZWJ1aWxkOkxpc3RCdWlsZHNGb3JQcm9qZWN0JyxcbiAgICAgICAgICAnbG9nczpHZXRMb2dFdmVudHMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nU3RyZWFtcycsXG4gICAgICAgICAgJ2xvZ3M6RGVzY3JpYmVMb2dHcm91cHMnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIEdyYW50IExhbWJkYSBmdW5jdGlvbnMgYWNjZXNzIHRvIEtNUyBrZXkgYW5kIEVDUlxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChvbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQoaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gob25FdmVudEhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG5cbiAgICAvLyBDcmVhdGUgYSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXJcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnQ3VzdG9tUmVzb3VyY2VQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLFxuICAgICAgaXNDb21wbGV0ZUhhbmRsZXI6IGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24sXG4gICAgICBxdWVyeUludGVydmFsOiBEdXJhdGlvbi5zZWNvbmRzKDMwKSxcbiAgICB9KTtcblxuICAgIC8vIERlZmluZSB0aGUgY3VzdG9tIHJlc291cmNlXG4gICAgY29uc3QgYnVpbGRUcmlnZ2VyUmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0J1aWxkVHJpZ2dlclJlc291cmNlJywge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFByb2plY3ROYW1lOiBjb2RlQnVpbGRQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICBUcmlnZ2VyOiBjcnlwdG8ucmFuZG9tVVVJRCgpLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGJ1aWxkVHJpZ2dlclJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShjb2RlQnVpbGRQcm9qZWN0KTtcbiAgICB0aGlzLmNvbnRhaW5lckltYWdlID0gQ29udGFpbmVySW1hZ2UuZnJvbUVjclJlcG9zaXRvcnkodGhpcy5lY3JSZXBvc2l0b3J5KTtcbiAgICB0aGlzLmRvY2tlckltYWdlQ29kZSA9IERvY2tlckltYWdlQ29kZS5mcm9tRWNyKHRoaXMuZWNyUmVwb3NpdG9yeSk7XG4gIH1cbn1cbiJdfQ==
188
+ TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.2.1" };
189
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBQzdCLDZDQUF1RDtBQUN2RCw2REFBd0Y7QUFFeEYsaURBQWtGO0FBQ2xGLGlEQUFxRDtBQUNyRCxpREFBc0Q7QUFDdEQsaURBQTBDO0FBQzFDLHVEQUFrRjtBQUNsRiw2REFBa0Q7QUFDbEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQXNHdkM7O0dBRUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBS3pELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQ0osSUFBSSxFQUFFLFVBQVUsRUFDaEIsU0FBUyxFQUNULG9CQUFvQixFQUNwQixHQUFHLEVBQ0gsY0FBYyxFQUNkLGVBQWUsRUFDZixlQUFlLEVBQ2YsZ0JBQWdCLEdBQ2pCLEdBQUcsS0FBSyxDQUFDO1FBRVYsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUN0RCxpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztRQUVILHdGQUF3RjtRQUN4RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksb0JBQVUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQ3pELGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxZQUFZLEVBQUUsQ0FBQztvQkFDZixXQUFXLEVBQUUsb0NBQW9DO29CQUNqRCxTQUFTLEVBQUUsbUJBQVMsQ0FBQyxRQUFRO29CQUM3QixXQUFXLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUM5QjthQUNGO1lBQ0QsVUFBVSxFQUFFLDhCQUFvQixDQUFDLEdBQUc7WUFDcEMsYUFBYSxFQUFFLGFB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LGdCQUFnQixDQUFDLFdBQVc7Z0JBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFO2FBQzdCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsd0JBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLGVBQWUsR0FBRyw0QkFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckUsQ0FBQzs7QUE3TUgsb0VBOE1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUHJvamVjdCwgU291cmNlLCBMaW51eEJ1aWxkSW1hZ2UsIEJ1aWxkU3BlYyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgSVZwYywgSVNlY3VyaXR5R3JvdXAsIFN1Ym5ldFNlbGVjdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSwgUmVwb3NpdG9yeUVuY3J5cHRpb24sIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgQ29udGFpbmVySW1hZ2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBSdW50aW1lLCBDb2RlLCBEb2NrZXJJbWFnZUNvZGUsIEZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBc3NldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMy1hc3NldHMnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIERvY2tlcmZpbGUgb3Igc291cmNlIGNvZGUuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBEb2NrZXIgYnVpbGQgcHJvY2Vzcy5cbiAgICogVGhlc2UgYXJlIHRyYW5zZm9ybWVkIGludG8gYC0tYnVpbGQtYXJnYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhpcyBzZWNyZXQgc2hvdWxkIHN0b3JlIGEgSlNPTiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJ1c2VybmFtZVwiOiBcIm15LWRvY2tlci11c2VybmFtZVwiLFxuICAgKiAgIFwicGFzc3dvcmRcIjogXCJteS1kb2NrZXItcGFzc3dvcmRcIlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBjb25zdHJ1Y3Qgd2lsbCBza2lwIERvY2tlciBsb2dpbiBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gICAqXG4gICAqIEBleGFtcGxlICdhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6c2VjcmV0OkRvY2tlckxvZ2luU2VjcmV0J1xuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyTG9naW5TZWNyZXRBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBWUEMgaW4gd2hpY2ggdGhlIENvZGVCdWlsZCBwcm9qZWN0IHdpbGwgYmUgZGVwbG95ZWQuXG4gICAqIElmIHByb3ZpZGVkLCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCBiZSBsYXVuY2hlZCB3aXRoaW4gdGhlIHNwZWNpZmllZCBWUEMuXG4gICAqIEBkZWZhdWx0IE5vIFZQQyBpcyBhdHRhY2hlZCwgYW5kIHRoZSBDb2RlQnVpbGQgcHJvamVjdCB3aWxsIHVzZSBwdWJsaWMgaW50ZXJuZXQuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIHRvIGF0dGFjaCB0byB0aGUgQ29kZUJ1aWxkIHByb2plY3QuXG4gICAqIFRoZXNlIHNob3VsZCBkZWZpbmUgdGhlIG5ldHdvcmsgYWNjZXNzIHJ1bGVzIGZvciB0aGUgQ29kZUJ1aWxkIHByb2plY3QuXG4gICAqIEBkZWZhdWx0IE5vIHNlY3VyaXR5IGdyb3VwcyBhcmUgYXR0YWNoZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IElTZWN1cml0eUdyb3VwW107XG5cbiAgLyoqXG4gICAqIFRoZSBzdWJuZXQgc2VsZWN0aW9uIHRvIHNwZWNpZnkgd2hpY2ggc3VibmV0cyB0byB1c2Ugd2l0aGluIHRoZSBWUEMuXG4gICAqIEFsbG93cyB0aGUgdXNlciB0byBzZWxlY3QgcHJpdmF0ZSwgcHVibGljLCBvciBpc29sYXRlZCBzdWJuZXRzLlxuICAgKiBAZGVmYXVsdCBBbGwgc3VibmV0cyBpbiB0aGUgVlBDIGFyZSB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0U2VsZWN0aW9uPzogU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gY29tbWFuZHMgdG8gcnVuIGR1cmluZyB0aGUgaW5zdGFsbCBwaGFzZS5cbiAgICpcbiAgICogKipFeGFtcGxlIFVzYWdlOioqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIodGhpcywgJ015RG9ja2VyQnVpbGRlcicsIHtcbiAgICogICBwYXRoOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vYXBwJyksXG4gICAqICAgaW5zdGFsbENvbW1hbmRzOiBbXG4gICAqICAgICAnZWNobyBcIlVwZGF0aW5nIHBhY2thZ2UgbGlzdHMuLi5cIicsXG4gICAqICAgICAnYXB0LWdldCB1cGRhdGUgLXknLFxuICAgKiAgICAgJ2VjaG8gXCJJbnN0YWxsaW5nIHJlcXVpcmVkIHBhY2thZ2VzLi4uXCInLFxuICAgKiAgICAgJ2FwdC1nZXQgaW5zdGFsbCAteSBjdXJsIGRuc3V0aWxzJyxcbiAgICogICBdLFxuICAgKiAgIC8vIC4uLiBvdGhlciBwcm9wZXJ0aWVzIC4uLlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqICpUaGlzIGV4YW1wbGUgZGVtb25zdHJhdGVzIGhvdyB0byBpbnN0YWxsIHRoZSBgY3VybGAgYW5kIGBkbnN1dGlsc2AgcGFja2FnZXMgZHVyaW5nIHRoZSBpbnN0YWxsIHBoYXNlIHVzaW5nIGBhcHQtZ2V0YCwgdGhlIHBhY2thZ2UgbWFuYWdlciBmb3IgVWJ1bnR1LWJhc2VkIENvZGVCdWlsZCBlbnZpcm9ubWVudHMuKlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGFkZGl0aW9uYWwgaW5zdGFsbCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxDb21tYW5kcz86IHN0cmluZ1tdO1xuXG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb21tYW5kcyB0byBydW4gZHVyaW5nIHRoZSBwcmVfYnVpbGQgcGhhc2UuXG4gICAqXG4gICAqICoqRXhhbXBsZSBVc2FnZToqKlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIG5ldyBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyKHRoaXMsICdNeURvY2tlckJ1aWxkZXInLCB7XG4gICAqICAgcGF0aDogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2FwcCcpLFxuICAgKiAgIHByZUJ1aWxkQ29tbWFuZHM6IFtcbiAgICogICAgICdlY2hvIFwiRmV0Y2hpbmcgY29uZmlndXJhdGlvbiBmcm9tIHByaXZhdGUgQVBJLi4uXCInLFxuICAgKiAgICAgJ2N1cmwgLW8gY29uZmlnLmpzb24gaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20vY29uZmlnJyxcbiAgICogICBdLFxuICAgKiAgIC8vIC4uLiBvdGhlciBwcm9wZXJ0aWVzIC4uLlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqICpJbiB0aGlzIGV4YW1wbGUsIHRoZSBidWlsZGVyIGZldGNoZXMgYSBjb25maWd1cmF0aW9uIGZpbGUgZnJvbSBhIHByaXZhdGUgQVBJIGJlZm9yZSBzdGFydGluZyB0aGUgRG9ja2VyIGJ1aWxkLiBUaGlzIGNvbmZpZyBmaWxlIHdpbGwgYmUgYXZhaWxhYmxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeSBhcyB5b3VyIERvY2tlcmZpbGUgZHVyaW5nIENESyBkZXBsb3ltZW50LipcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBhZGRpdGlvbmFsIHByZS1idWlsZCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IHByZUJ1aWxkQ29tbWFuZHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIENESyBjb25zdHJ1Y3QgdG8gYnVpbGQgYW5kIHB1c2ggRG9ja2VyIGltYWdlcyB0byBhbiBFQ1IgcmVwb3NpdG9yeSB1c2luZyBDb2RlQnVpbGQgYW5kIExhbWJkYSBjdXN0b20gcmVzb3VyY2VzLlxuICovXG5leHBvcnQgY2xhc3MgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWNyUmVwb3NpdG9yeTogUmVwb3NpdG9yeTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRhaW5lckltYWdlOiBDb250YWluZXJJbWFnZTtcbiAgcHVibGljIHJlYWRvbmx5IGRvY2tlckltYWdlQ29kZTogRG9ja2VySW1hZ2VDb2RlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qge1xuICAgICAgcGF0aDogc291cmNlUGF0aCxcbiAgICAgIGJ1aWxkQXJncyxcbiAgICAgIGRvY2tlckxvZ2luU2VjcmV0QXJuLFxuICAgICAgdnBjLFxuICAgICAgc2VjdXJpdHlHcm91cHMsXG4gICAgICBzdWJuZXRTZWxlY3Rpb24sXG4gICAgICBpbnN0YWxsQ29tbWFuZHMsXG4gICAgICBwcmVCdWlsZENvbW1hbmRzLFxuICAgIH0gPSBwcm9wcztcblxuICAgIC8vIERlZmluZSBhIEtNUyBrZXkgZm9yIEVDUiBlbmNyeXB0aW9uXG4gICAgY29uc3QgZW5jcnlwdGlvbktleSA9IG5ldyBLZXkodGhpcywgJ0VjckVuY3J5cHRpb25LZXknLCB7XG4gICAgICBlbmFibGVLZXlSb3RhdGlvbjogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhbiBFQ1IgcmVwb3NpdG9yeSB3aXRoIGxpZmVjeWNsZSBydWxlcywgZW5jcnlwdGlvbiwgYW5kIGltYWdlIHNjYW5uaW5nIGVuYWJsZWRcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkgPSBuZXcgUmVwb3NpdG9yeSh0aGlzLCAnRUNSUmVwb3NpdG9yeScsIHtcbiAgICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBydWxlUHJpb3JpdHk6IDEsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgdW50YWdnZWQgaW1hZ2VzIGFmdGVyIDEgZGF5JyxcbiAgICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgICBtYXhJbWFnZUFnZTogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBlbmNyeXB0aW9uOiBSZXBvc2l0b3J5RW5jcnlwdGlvbi5LTVMsXG4gICAgICBlbmNyeXB0aW9uS2V5OiBlbmNyeXB0aW9uS2V5LFxuICAgICAgaW1hZ2VTY2FuT25QdXNoOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgLy8gUGFja2FnZSB0aGUgc291cmNlIGNvZGUgYXMgYW4gYXNzZXRcbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgIH0pO1xuXG4gICAgLy8gVHJhbnNmb3JtIGJ1aWxkQXJncyBpbnRvIGEgc3RyaW5nIG9mIC0tYnVpbGQtYXJnIEtFWT1WQUxVRVxuICAgIGNvbnN0IGJ1aWxkQXJnc1N0cmluZyA9IGJ1aWxkQXJnc1xuICAgICAgPyBPYmplY3QuZW50cmllcyhidWlsZEFyZ3MpXG4gICAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYC0tYnVpbGQtYXJnICR7a2V5fT0ke3ZhbHVlfWApXG4gICAgICAgIC5qb2luKCcgJylcbiAgICAgIDogJyc7XG5cbiAgICAvLyBDb25kaXRpb25hbCBEb2NrZXJodWIgbG9naW4gY29tbWFuZHNcbiAgICBjb25zdCBkb2NrZXJMb2dpbkNvbW1hbmRzID0gZG9ja2VyTG9naW5TZWNyZXRBcm5cbiAgICAgID8gW1xuICAgICAgICAnZWNobyBcIlJldHJpZXZpbmcgRG9ja2VyIGNyZWRlbnRpYWxzIGZyb20gU2VjcmV0cyBNYW5hZ2VyLi4uXCInLFxuICAgICAgICBgRE9DS0VSX1VTRVJOQU1FPSQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1zZWNyZXQtaWQgJHtkb2NrZXJMb2dpblNlY3JldEFybn0gLS1xdWVyeSBTZWNyZXRTdHJpbmcgLS1vdXRwdXQgdGV4dCB8IGpxIC1yIC51c2VybmFtZSlgLFxuICAgICAgICBgRE9DS0VSX1BBU1NXT1JEPSQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1zZWNyZXQtaWQgJHtkb2NrZXJMb2dpblNlY3JldEFybn0gLS1xdWVyeSBTZWNyZXRTdHJpbmcgLS1vdXRwdXQgdGV4dCB8IGpxIC1yIC5wYXNzd29yZClgLFxuICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW4gdG8gRG9ja2VyLi4uXCInLFxuICAgICAgICAnZWNobyAkRE9DS0VSX1BBU1NXT1JEIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgJERPQ0tFUl9VU0VSTkFNRSAtLXBhc3N3b3JkLXN0ZGluJyxcbiAgICAgIF1cbiAgICAgIDogWydlY2hvIFwiTm8gRG9ja2VyIGNyZWRlbnRpYWxzIHByb3ZpZGVkLiBTa2lwcGluZyBsb2dpbiBzdGVwLlwiJ107XG5cbiAgICAvLyBDcmVhdGUgYSBDb2RlQnVpbGQgcHJvamVjdFxuICAgIGNvbnN0IGNvZGVCdWlsZFByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCAnVUlDb2RlQnVpbGRQcm9qZWN0Jywge1xuICAgICAgc291cmNlOiBTb3VyY2UuczMoe1xuICAgICAgICBidWNrZXQ6IHNvdXJjZUFzc2V0LmJ1Y2tldCxcbiAgICAgICAgcGF0aDogc291cmNlQXNzZXQuczNPYmplY3RLZXksXG4gICAgICB9KSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGJ1aWxkSW1hZ2U6IExpbnV4QnVpbGRJbWFnZS5TVEFOREFSRF83XzAsXG4gICAgICAgIHByaXZpbGVnZWQ6IHRydWUsXG4gICAgICB9LFxuICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IHtcbiAgICAgICAgRUNSX1JFUE9fVVJJOiB7IHZhbHVlOiB0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeVVyaSB9LFxuICAgICAgICBCVUlMRF9BUkdTOiB7IHZhbHVlOiBidWlsZEFyZ3NTdHJpbmcgfSxcbiAgICAgICAgLy8gSW5jbHVkZSBidWlsZCBhcmd1bWVudHMgYXMgZW52aXJvbm1lbnQgdmFyaWFibGVzIGlmIG5lZWRlZFxuICAgICAgICAuLi4oYnVpbGRBcmdzICYmXG4gICAgICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXMoYnVpbGRBcmdzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleSwgeyB2YWx1ZSB9XSksXG4gICAgICAgICAgKSksXG4gICAgICB9LFxuICAgICAgdnBjLFxuICAgICAgc2VjdXJpdHlHcm91cHMsXG4gICAgICBzdWJuZXRTZWxlY3Rpb24sXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KHtcbiAgICAgICAgdmVyc2lvbjogJzAuMicsXG4gICAgICAgIHBoYXNlczoge1xuICAgICAgICAgIGluc3RhbGw6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIFwiQmVnaW5uaW5nIGluc3RhbGwgcGhhc2UuLi5cIicsXG4gICAgICAgICAgICAgIC4uLihpbnN0YWxsQ29tbWFuZHMgfHwgW10pLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHByZV9idWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgLi4uKHByZUJ1aWxkQ29tbWFuZHMgfHwgW10pLFxuICAgICAgICAgICAgICAuLi5kb2NrZXJMb2dpbkNvbW1hbmRzLFxuICAgICAgICAgICAgICAnZWNobyBcIlJldHJpZXZpbmcgQVdTIEFjY291bnQgSUQuLi5cIicsXG4gICAgICAgICAgICAgICdleHBvcnQgQUNDT1VOVF9JRD0kKGF3cyBzdHMgZ2V0LWNhbGxlci1pZGVudGl0eSAtLXF1ZXJ5IEFjY291bnQgLS1vdXRwdXQgdGV4dCknLFxuICAgICAgICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW4gdG8gQW1hem9uIEVDUi4uLlwiJyxcbiAgICAgICAgICAgICAgJ2F3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uICRBV1NfREVGQVVMVF9SRUdJT04gfCBkb2NrZXIgbG9naW4gLS11c2VybmFtZSBBV1MgLS1wYXNzd29yZC1zdGRpbiAkQUNDT1VOVF9JRC5ka3IuZWNyLiRBV1NfREVGQVVMVF9SRUdJT04uYW1hem9uYXdzLmNvbScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIEJ1aWxkIHBoYXNlOiBCdWlsZGluZyB0aGUgRG9ja2VyIGltYWdlLi4uJyxcbiAgICAgICAgICAgICAgJ2RvY2tlciBidWlsZCAkQlVJTERfQVJHUyAtdCAkRUNSX1JFUE9fVVJJOmxhdGVzdCAkQ09ERUJVSUxEX1NSQ19ESVInLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIFBvc3QtYnVpbGQgcGhhc2U6IFB1c2hpbmcgdGhlIERvY2tlciBpbWFnZS4uLicsXG4gICAgICAgICAgICAgICdkb2NrZXIgcHVzaCAkRUNSX1JFUE9fVVJJOmxhdGVzdCcsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IHBlcm1pc3Npb25zIHRvIENvZGVCdWlsZFxuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGNvZGVCdWlsZFByb2plY3QpO1xuXG4gICAgY29kZUJ1aWxkUHJvamVjdC5yb2xlIS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nLFxuICAgICAgICAgICdlY3I6R2V0RG93bmxvYWRVcmxGb3JMYXllcicsXG4gICAgICAgICAgJ2VjcjpCYXRjaENoZWNrTGF5ZXJBdmFpbGFiaWxpdHknLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeUFybl0sXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgaWYgKGRvY2tlckxvZ2luU2VjcmV0QXJuKSB7XG4gICAgICBjb2RlQnVpbGRQcm9qZWN0LnJvbGUhLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbZG9ja2VyTG9naW5TZWNyZXRBcm5dLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR3JhbnQgQ29kZUJ1aWxkIGFjY2VzcyB0byB0aGUgS01TIGtleVxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChjb2RlQnVpbGRQcm9qZWN0LnJvbGUhKTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb25zIGZvciBvbkV2ZW50IGFuZCBpc0NvbXBsZXRlIGhhbmRsZXJzXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnT25FdmVudEhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vb25FdmVudCcpKSxcbiAgICAgIGhhbmRsZXI6ICdvbkV2ZW50LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG5cbiAgICBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2NvZGVidWlsZDpTdGFydEJ1aWxkJ10sXG4gICAgICAgIHJlc291cmNlczogW2NvZGVCdWlsZFByb2plY3QucHJvamVjdEFybl0sIC8vIFJlc3RyaWN0IHRvIHNwZWNpZmljIHByb2plY3RcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdJc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9pc0NvbXBsZXRlJykpLFxuICAgICAgaGFuZGxlcjogJ2lzQ29tcGxldGUuaGFuZGxlcicsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICB9KTtcblxuICAgIGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnY29kZWJ1aWxkOkJhdGNoR2V0QnVpbGRzJyxcbiAgICAgICAgICAnY29kZWJ1aWxkOkxpc3RCdWlsZHNGb3JQcm9qZWN0JyxcbiAgICAgICAgICAnbG9nczpHZXRMb2dFdmVudHMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nU3RyZWFtcycsXG4gICAgICAgICAgJ2xvZ3M6RGVzY3JpYmVMb2dHcm91cHMnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIEdyYW50IExhbWJkYSBmdW5jdGlvbnMgYWNjZXNzIHRvIEtNUyBrZXkgYW5kIEVDUlxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChvbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQoaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gob25FdmVudEhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG5cbiAgICAvLyBDcmVhdGUgYSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXJcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnQ3VzdG9tUmVzb3VyY2VQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLFxuICAgICAgaXNDb21wbGV0ZUhhbmRsZXI6IGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24sXG4gICAgICBxdWVyeUludGVydmFsOiBEdXJhdGlvbi5zZWNvbmRzKDMwKSxcbiAgICB9KTtcblxuICAgIC8vIERlZmluZSB0aGUgY3VzdG9tIHJlc291cmNlXG4gICAgY29uc3QgYnVpbGRUcmlnZ2VyUmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0J1aWxkVHJpZ2dlclJlc291cmNlJywge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFByb2plY3ROYW1lOiBjb2RlQnVpbGRQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICBUcmlnZ2VyOiBjcnlwdG8ucmFuZG9tVVVJRCgpLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGJ1aWxkVHJpZ2dlclJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShjb2RlQnVpbGRQcm9qZWN0KTtcbiAgICB0aGlzLmNvbnRhaW5lckltYWdlID0gQ29udGFpbmVySW1hZ2UuZnJvbUVjclJlcG9zaXRvcnkodGhpcy5lY3JSZXBvc2l0b3J5KTtcbiAgICB0aGlzLmRvY2tlckltYWdlQ29kZSA9IERvY2tlckltYWdlQ29kZS5mcm9tRWNyKHRoaXMuZWNyUmVwb3NpdG9yeSk7XG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@stylistic/eslint-plugin": "^2",
42
42
  "@types/jest": "^29.5.14",
43
- "@types/node": "^22.9.4",
43
+ "@types/node": "^22.10.1",
44
44
  "@typescript-eslint/eslint-plugin": "^8",
45
45
  "@typescript-eslint/parser": "^8",
46
46
  "aws-cdk-lib": "2.166.0",
@@ -96,7 +96,7 @@
96
96
  "publishConfig": {
97
97
  "access": "public"
98
98
  },
99
- "version": "1.1.3",
99
+ "version": "1.2.1",
100
100
  "jest": {
101
101
  "coverageProvider": "v8",
102
102
  "testMatch": [