From 093165a46f4a2c3f03d3c12081baee437b681ac4 Mon Sep 17 00:00:00 2001
From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com>
Date: Sun, 24 Dec 2023 16:15:47 +0000
Subject: [PATCH] fix: cannot have multiple assets in the same scope (backport
#1017) (#1019)
This is an automatic backport of pull request #1017 done by [Mergify](https://mergify.com).
---
Mergify commands and options
More conditions and actions can be found in the [documentation](https://docs.mergify.com/).
You can also trigger Mergify actions by commenting on this pull request:
- `@Mergifyio refresh` will re-evaluate the rules
- `@Mergifyio rebase` will rebase this PR on its base branch
- `@Mergifyio update` will merge the base branch into this PR
- `@Mergifyio backport ` will backport this PR on `` branch
Additionally, on Mergify [dashboard](https://dashboard.mergify.com) you can:
- look at your merge queues
- generate the Mergify configuration with the config editor.
Finally, you can contact us on https://mergify.com
---
src/code.ts | 8 ++++----
src/private/utils.ts | 14 ++++++++++++++
src/source.ts | 4 +++-
test/code.test.ts | 18 ++++++++++++++++++
test/source.test.ts | 32 ++++++++++++++++++++++++++++++++
5 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/src/code.ts b/src/code.ts
index c56b5eb8..acae5863 100644
--- a/src/code.ts
+++ b/src/code.ts
@@ -10,7 +10,7 @@ import {
} from './asset';
import { EntryPoints } from './bundler';
import { BuildOptions } from './esbuild-types';
-import { defaultPlatformProps } from './private/utils';
+import { defaultPlatformProps, uniqueAssetId } from './private/utils';
export { CodeConfig } from 'aws-cdk-lib/aws-lambda';
export interface JavaScriptCodeProps extends AssetBaseProps {};
@@ -29,7 +29,7 @@ export class EsbuildCode<
protected getAsset(scope: Construct): EsbuildAsset {
return new EsbuildAsset(
scope,
- this.constructor.name,
+ uniqueAssetId(scope, this.constructor.name),
this.props,
);
}
@@ -137,7 +137,7 @@ export class JavaScriptCode extends EsbuildCode {
protected getAsset(scope: Construct): EsbuildAsset {
return new JSAsset(
scope,
- this.constructor.name,
+ uniqueAssetId(scope, this.constructor.name),
this.props,
);
}
@@ -186,7 +186,7 @@ export class TypeScriptCode extends EsbuildCode {
protected getAsset(scope: Construct): EsbuildAsset {
return new TSAsset(
scope,
- this.constructor.name,
+ uniqueAssetId(scope, this.constructor.name),
this.props,
);
}
diff --git a/src/private/utils.ts b/src/private/utils.ts
index 1d2d121c..2291fdb5 100644
--- a/src/private/utils.ts
+++ b/src/private/utils.ts
@@ -1,3 +1,4 @@
+import { IConstruct } from 'constructs';
import { BuildOptions, Platform, TransformOptions } from '../esbuild-types';
export function isEsbuildError(error: unknown): boolean {
@@ -22,3 +23,16 @@ export function defaultPlatformProps(options?: BuildOptions | TransformOptions):
return {};
}
+
+const assetIds = new WeakMap();
+export const uniqueAssetId = (scope: IConstruct, name: string) => {
+ const nextId = (assetIds.get(scope) ?? 0) + 1;
+ assetIds.set(scope, nextId);
+
+ // Only one asset per scope, skip the id
+ if (nextId === 1) {
+ return name;
+ }
+
+ return `${name}${nextId}`;
+};
diff --git a/src/source.ts b/src/source.ts
index 9389264f..757c44e5 100644
--- a/src/source.ts
+++ b/src/source.ts
@@ -8,6 +8,8 @@ import { Construct } from 'constructs';
import { AssetBaseProps, AssetProps, JavaScriptAsset, TypeScriptAsset } from './asset';
import { EntryPoints } from './bundler';
import { BuildOptions } from './esbuild-types';
+import { uniqueAssetId } from './private/utils';
+
export interface JavaScriptSourceProps extends AssetBaseProps{};
export interface TypeScriptSourceProps extends AssetBaseProps{};
@@ -75,7 +77,7 @@ abstract class Source<
if (!this.asset) {
this.asset = new this.assetClass(
scope,
- this.constructor.name,
+ uniqueAssetId(scope, this.constructor.name),
this.props,
);
} else if (Stack.of(this.asset) !== Stack.of(scope)) {
diff --git a/test/code.test.ts b/test/code.test.ts
index 1d52c4ef..2dd97847 100644
--- a/test/code.test.ts
+++ b/test/code.test.ts
@@ -202,3 +202,21 @@ describe('Amazon CloudWatch Synthetics', () => {
});
});
});
+
+
+describe('multiple Code in the same scope', () => {
+ it('does not throw', () => {
+ const stack = new Stack();
+
+ const codeOne = new TypeScriptCode('fixtures/handlers/ts-handler.ts', {
+ buildOptions: { absWorkingDir: resolve(__dirname) },
+ });
+
+ const codeTwo = new TypeScriptCode('fixtures/handlers/ts-handler.ts', {
+ buildOptions: { absWorkingDir: resolve(__dirname) },
+ });
+
+ codeOne.bind(stack);
+ codeTwo.bind(stack);
+ });
+});
diff --git a/test/source.test.ts b/test/source.test.ts
index 7b195aeb..4e38b341 100644
--- a/test/source.test.ts
+++ b/test/source.test.ts
@@ -176,4 +176,36 @@ describe('source', () => {
expect(source.props.buildOptions.platform).toBe('browser');
});
});
+
+ describe('with multiple sources in the same scope', () => {
+ it('does not throw', () => {
+ const stack = new Stack();
+
+ const sourceOne = new TypeScriptSource('fixtures/handlers/ts-handler.ts', {
+ buildOptions: {
+ absWorkingDir: resolve(__dirname),
+ },
+ });
+ const sourceTwo = new TypeScriptSource('fixtures/handlers/ts-handler.ts', {
+ buildOptions: {
+ absWorkingDir: resolve(__dirname),
+ },
+ });
+
+ const destinationBucket = new Bucket(stack, 'WebsiteBucket', {
+ autoDeleteObjects: true,
+ publicReadAccess: true,
+ removalPolicy: RemovalPolicy.DESTROY,
+ websiteIndexDocument: 'index.html',
+ });
+
+ new BucketDeployment(stack, 'MultipleAssets', {
+ destinationBucket,
+ sources: [
+ sourceOne,
+ sourceTwo,
+ ],
+ });
+ });
+ });
});