From d55ee5cd4e35a8f17ee334d1792bd69c0d22e37c Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:16:16 -0700 Subject: [PATCH] Revert "feat: Multi bucket support" (#1837) * Revert "feat: Multi bucket support (#1742)" This reverts commit d8b43d252c7d5553bf719dd889571807098adf13. * add changeset --- .changeset/eleven-crews-remain.md | 2 + .changeset/sharp-penguins-impress.md | 11 -- package-lock.json | 17 -- packages/backend-output-schemas/API.md | 12 -- .../backend-output-schemas/src/storage/v1.ts | 7 - packages/backend-output-storage/API.md | 3 +- ...k_metadata_output_storage_strategy.test.ts | 81 ++------ .../stack_metadata_output_storage_strategy.ts | 94 +++------ packages/backend-storage/API.md | 1 - .../backend-storage/src/construct.test.ts | 61 +++++- packages/backend-storage/src/construct.ts | 39 ++-- packages/backend-storage/src/factory.test.ts | 98 +++------- packages/backend-storage/src/factory.ts | 22 +-- packages/backend-storage/src/index.ts | 2 +- .../src/storage_access_policy_factory.ts | 13 +- .../src/storage_outputs_aspect.test.ts | 181 ------------------ .../src/storage_outputs_aspect.ts | 111 ----------- packages/client-config/API.md | 14 +- .../client_config_contributor_v1.test.ts | 19 +- .../client_config_contributor_v1.ts | 23 +-- ...ent_config_v1.1.ts => client_config_v1.ts} | 6 - .../{schema_v1.1.json => schema_v1.json} | 22 --- .../src/client-config-types/client_config.ts | 2 +- .../src/backend_output_client.ts | 2 - .../src/deployed_backend_client.ts | 7 +- packages/integration-tests/package.json | 2 - .../test-project-setup/test_project_base.ts | 3 +- packages/plugin-types/API.md | 7 +- packages/plugin-types/src/deep_partial.ts | 10 - .../src/output_storage_strategy.ts | 6 +- 30 files changed, 183 insertions(+), 695 deletions(-) create mode 100644 .changeset/eleven-crews-remain.md delete mode 100644 .changeset/sharp-penguins-impress.md delete mode 100644 packages/backend-storage/src/storage_outputs_aspect.test.ts delete mode 100644 packages/backend-storage/src/storage_outputs_aspect.ts rename packages/client-config/src/client-config-schema/{client_config_v1.1.ts => client_config_v1.ts} (97%) rename packages/client-config/src/client-config-schema/{schema_v1.1.json => schema_v1.json} (95%) diff --git a/.changeset/eleven-crews-remain.md b/.changeset/eleven-crews-remain.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/eleven-crews-remain.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/sharp-penguins-impress.md b/.changeset/sharp-penguins-impress.md deleted file mode 100644 index f2cc27815f..0000000000 --- a/.changeset/sharp-penguins-impress.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@aws-amplify/deployed-backend-client': minor -'@aws-amplify/backend-output-schemas': minor -'@aws-amplify/backend-output-storage': minor -'@aws-amplify/backend-storage': minor -'@aws-amplify/client-config': minor -'@aws-amplify/plugin-types': minor -'@aws-amplify/backend': minor ---- - -support adding more than one bucket diff --git a/package-lock.json b/package-lock.json index 69e84f9bff..37f1c01f32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19576,15 +19576,6 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==" }, - "node_modules/@types/lodash.ismatch": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/@types/lodash.ismatch/-/lodash.ismatch-4.4.9.tgz", - "integrity": "sha512-qWihnStOPKH8urljLGm6ZOEdN/5Bt4vxKR81tL3L4ArUNLvcf9RW3QSnPs21eix5BiqioSWq4aAXD4Iep+d0fw==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/lodash.mergewith": { "version": "4.6.9", "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.9.tgz", @@ -27466,12 +27457,6 @@ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", "dev": true }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", @@ -33053,7 +33038,6 @@ "@aws-sdk/client-sts": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@smithy/shared-ini-file-loader": "^2.2.5", - "@types/lodash.ismatch": "^4.4.9", "aws-amplify": "^6.0.16", "aws-appsync-auth-link": "^3.0.7", "aws-cdk-lib": "^2.132.0", @@ -33062,7 +33046,6 @@ "fs-extra": "^11.1.1", "glob": "^10.2.7", "graphql-tag": "^2.12.6", - "lodash.ismatch": "^4.4.0", "node-fetch": "^3.3.2", "semver": "^7.5.4", "ssh2": "^1.15.0", diff --git a/packages/backend-output-schemas/API.md b/packages/backend-output-schemas/API.md index 41fbd8abed..6c2692bc54 100644 --- a/packages/backend-output-schemas/API.md +++ b/packages/backend-output-schemas/API.md @@ -275,29 +275,24 @@ export const unifiedBackendOutputSchema: z.ZodObject<{ payload: z.ZodObject<{ bucketName: z.ZodString; storageRegion: z.ZodString; - buckets: z.ZodOptional; }, "strip", z.ZodTypeAny, { bucketName: string; storageRegion: string; - buckets?: string | undefined; }, { bucketName: string; storageRegion: string; - buckets?: string | undefined; }>; }, "strip", z.ZodTypeAny, { version: "1"; payload: { bucketName: string; storageRegion: string; - buckets?: string | undefined; }; }, { version: "1"; payload: { bucketName: string; storageRegion: string; - buckets?: string | undefined; }; }>]>>; "AWS::Amplify::Custom": z.ZodOptional; }, "strip", z.ZodTypeAny, { bucketName: string; storageRegion: string; - buckets?: string | undefined; }, { bucketName: string; storageRegion: string; - buckets?: string | undefined; }>; }, "strip", z.ZodTypeAny, { version: "1"; payload: { bucketName: string; storageRegion: string; - buckets?: string | undefined; }; }, { version: "1"; payload: { bucketName: string; storageRegion: string; - buckets?: string | undefined; }; }>]>; diff --git a/packages/backend-output-schemas/src/storage/v1.ts b/packages/backend-output-schemas/src/storage/v1.ts index 5095714a81..31407cd478 100644 --- a/packages/backend-output-schemas/src/storage/v1.ts +++ b/packages/backend-output-schemas/src/storage/v1.ts @@ -1,16 +1,9 @@ import { z } from 'zod'; -const bucketSchema = z.object({ - name: z.string(), - bucketName: z.string(), - storageRegion: z.string(), -}); - export const storageOutputSchema = z.object({ version: z.literal('1'), payload: z.object({ bucketName: z.string(), storageRegion: z.string(), - buckets: z.string(z.array(bucketSchema)).optional(), // JSON serialized array of bucketSchema }), }); diff --git a/packages/backend-output-storage/API.md b/packages/backend-output-storage/API.md index b4924f8d62..c79ecc0472 100644 --- a/packages/backend-output-storage/API.md +++ b/packages/backend-output-storage/API.md @@ -8,7 +8,6 @@ import { BackendOutputEntry } from '@aws-amplify/plugin-types'; import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types'; -import { DeepPartial } from '@aws-amplify/plugin-types'; import * as _os from 'os'; import { PackageJsonReader } from '@aws-amplify/platform-core'; import { Stack } from 'aws-cdk-lib'; @@ -38,7 +37,7 @@ export type Platform = 'Mac' | 'Windows' | 'Linux' | 'Other'; export class StackMetadataBackendOutputStorageStrategy implements BackendOutputStorageStrategy { constructor(stack: Stack); addBackendOutputEntry: (keyName: string, backendOutputEntry: BackendOutputEntry) => void; - appendToBackendOutputList: (keyName: string, backendOutputEntry: DeepPartial) => void; + appendToBackendOutputList: (keyName: string, backendOutputEntry: BackendOutputEntry) => void; } // (No @packageDocumentation comment for this package) diff --git a/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.test.ts b/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.test.ts index 9b299be238..7cfce6b0c2 100644 --- a/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.test.ts +++ b/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.test.ts @@ -16,18 +16,17 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.addBackendOutputEntry('TestStorageOutput', { version: '1', payload: { - bucketName: 'test-bucket', - storageRegion: 'us-west-2', + something: 'special', }, }); const template = Template.fromStack(stack); - template.hasOutput('bucketName', { Value: 'test-bucket' }); + template.hasOutput('something', { Value: 'special' }); template.templateMatches({ Metadata: { TestStorageOutput: { version: '1', - stackOutputs: ['bucketName', 'storageRegion'], + stackOutputs: ['something'], }, }, }); @@ -42,8 +41,7 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.addBackendOutputEntry('TestStorageOutput', { version: '44', payload: { - bucketName: 'test-bucket', - storageRegion: 'us-west-2', + something: 'special', }, }); @@ -63,19 +61,17 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: 'test-bucket', + something: 'special', }, }); const template = Template.fromStack(stack); - template.hasOutput('buckets', { - Value: JSON.stringify(['test-bucket']), - }); + template.hasOutput('something', { Value: JSON.stringify(['special']) }); template.templateMatches({ Metadata: { TestStorageOutput: { version: '1', - stackOutputs: ['buckets'], + stackOutputs: ['something'], }, }, }); @@ -90,93 +86,57 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: JSON.stringify({ - name: 'test-bucket', - bucketName: 'test-bucket', - storageRegion: 'us-west-2', - }), - }, - }); - outputStorage.addBackendOutputEntry('TestStorageOutput', { - version: '1', - payload: { - bucketName: 'test-bucket-two', - storageRegion: 'us-west-2', + something: 'special', }, }); outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: JSON.stringify({ - name: 'test-bucket-two', - bucketName: 'test-bucket-two', - storageRegion: 'us-west-2', - }), + something: 'otherSpecial', }, }); const template = Template.fromStack(stack); - template.hasOutput('buckets', { - Value: JSON.stringify([ - '{"name":"test-bucket","bucketName":"test-bucket","storageRegion":"us-west-2"}', - '{"name":"test-bucket-two","bucketName":"test-bucket-two","storageRegion":"us-west-2"}', - ]), + template.hasOutput('something', { + Value: JSON.stringify(['special', 'otherSpecial']), }); template.templateMatches({ Metadata: { TestStorageOutput: { version: '1', - stackOutputs: ['buckets', 'bucketName', 'storageRegion'], + stackOutputs: ['something'], }, }, }); }); - void it('appends a cdk token to an existing list in stack output with two buckets', () => { + void it('appends a cdk token to an existing list in stack output', () => { const testToken = Token.asString('testToken'); const app = new App(); const stack = new Stack(app); const outputStorage = new StackMetadataBackendOutputStorageStrategy( stack ); - outputStorage.addBackendOutputEntry('TestStorageOutput', { - version: '1', - payload: { - bucketName: testToken, - storageRegion: 'us-west-2', - }, - }); outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: JSON.stringify({ - name: testToken, - bucketName: testToken, - storageRegion: 'us-west-2', - }), + something: 'special', }, }); outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: JSON.stringify({ - name: 'test-bucket-two', - bucketName: 'test-bucket-two', - storageRegion: 'us-west-2', - }), + something: testToken, }, }); const template = Template.fromStack(stack); - template.hasOutput('buckets', { - Value: JSON.stringify([ - '{"name":"testToken","bucketName":"testToken","storageRegion":"us-west-2"}', - '{"name":"test-bucket-two","bucketName":"test-bucket-two","storageRegion":"us-west-2"}', - ]), + template.hasOutput('something', { + Value: JSON.stringify(['special', 'testToken']), }); template.templateMatches({ Metadata: { TestStorageOutput: { version: '1', - stackOutputs: ['buckets', 'bucketName', 'storageRegion'], + stackOutputs: ['something'], }, }, }); @@ -191,7 +151,7 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '1', payload: { - buckets: 'test-bucket', + something: 'special', }, }); @@ -200,8 +160,7 @@ void describe('StackMetadataBackendOutputStorageStrategy', () => { outputStorage.appendToBackendOutputList('TestStorageOutput', { version: '2', payload: { - bucketName: 'test-bucket', - storageRegion: 'us-west-2', + something: 'otherSpecial', }, }), { diff --git a/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.ts b/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.ts index e5bc26e3bc..494504bc59 100644 --- a/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.ts +++ b/packages/backend-output-storage/src/stack_metadata_output_storage_strategy.ts @@ -1,7 +1,6 @@ import { BackendOutputEntry, BackendOutputStorageStrategy, - DeepPartial, } from '@aws-amplify/plugin-types'; import { CfnOutput, Lazy, Stack } from 'aws-cdk-lib'; @@ -37,14 +36,10 @@ export class StackMetadataBackendOutputStorageStrategy new CfnOutput(this.stack, key, { value }); }); - const metadata = this.stack.templateOptions.metadata || {}; - const existingMetadataEntry = metadata[keyName]; - - this.addOrUpdateMetadata( - existingMetadataEntry, - keyName, - backendOutputEntry - ); + this.stack.addMetadata(keyName, { + version: backendOutputEntry.version, + stackOutputs: Object.keys(backendOutputEntry.payload), + }); }; /** @@ -52,7 +47,7 @@ export class StackMetadataBackendOutputStorageStrategy */ appendToBackendOutputList = ( keyName: string, - backendOutputEntry: DeepPartial + backendOutputEntry: BackendOutputEntry ): void => { const version = backendOutputEntry.version; let listsMap = this.lazyListValueMap.get(keyName); @@ -66,67 +61,32 @@ export class StackMetadataBackendOutputStorageStrategy `Metadata entry for ${keyName} at version ${existingMetadataEntry.version} already exists. Cannot add another entry for the same key at version ${version}.` ); } + } else { + this.stack.addMetadata(keyName, { + version, + stackOutputs: Lazy.list({ + produce: () => Array.from(listsMap ? listsMap.keys() : []), + }), + }); } - this.addOrUpdateMetadata( - existingMetadataEntry, - keyName, - backendOutputEntry as BackendOutputEntry - ); - - Object.entries(backendOutputEntry.payload ?? []).forEach( - ([listName, value]) => { - if (!value) { - return; - } - if (!listsMap) { - listsMap = new Map(); - this.lazyListValueMap.set(keyName, listsMap); - } - let outputList = listsMap.get(listName); + Object.entries(backendOutputEntry.payload).forEach(([listName, value]) => { + if (!listsMap) { + listsMap = new Map(); + this.lazyListValueMap.set(keyName, listsMap); + } + let outputList = listsMap.get(listName); - if (outputList) { - outputList.push(value); - } else { - outputList = [value]; - listsMap.set(listName, outputList); + if (outputList) { + outputList.push(value); + } else { + outputList = [value]; + listsMap.set(listName, outputList); - new CfnOutput(this.stack, listName, { - value: Lazy.string({ produce: () => JSON.stringify(outputList) }), - }); - } + new CfnOutput(this.stack, listName, { + value: Lazy.string({ produce: () => JSON.stringify(outputList) }), + }); } - ); + }); }; - - /** - * Add or update metadata entry. - * @param existingMetadataEntry - The existing metadata entry. - * @param keyName - The key name. - * @param backendOutputEntry - The backend output entry. - */ - private addOrUpdateMetadata( - existingMetadataEntry: - | { version: string; stackOutputs: string[] } - | undefined, - keyName: string, - backendOutputEntry: BackendOutputEntry - ) { - if (existingMetadataEntry) { - this.stack.addMetadata(keyName, { - version: backendOutputEntry.version, - stackOutputs: [ - ...new Set([ - ...Object.keys(backendOutputEntry.payload), - ...existingMetadataEntry.stackOutputs, - ]), - ], - }); - } else { - this.stack.addMetadata(keyName, { - version: backendOutputEntry.version, - stackOutputs: Object.keys(backendOutputEntry.payload), - }); - } - } } diff --git a/packages/backend-storage/API.md b/packages/backend-storage/API.md index e7472b5770..5baf581857 100644 --- a/packages/backend-storage/API.md +++ b/packages/backend-storage/API.md @@ -23,7 +23,6 @@ export type AmplifyStorageFactoryProps = Omit; diff --git a/packages/backend-storage/src/construct.test.ts b/packages/backend-storage/src/construct.test.ts index 9621ea8e4f..158c1e2af0 100644 --- a/packages/backend-storage/src/construct.test.ts +++ b/packages/backend-storage/src/construct.test.ts @@ -1,8 +1,14 @@ -import { describe, it } from 'node:test'; +import { describe, it, mock } from 'node:test'; import { AmplifyStorage } from './construct.js'; import { App, Stack } from 'aws-cdk-lib'; import { Capture, Template } from 'aws-cdk-lib/assertions'; +import { + BackendOutputEntry, + BackendOutputStorageStrategy, +} from '@aws-amplify/plugin-types'; import assert from 'node:assert'; +import { Bucket } from 'aws-cdk-lib/aws-s3'; +import { storageOutputKey } from '@aws-amplify/backend-output-schemas'; void describe('AmplifyStorage', () => { void it('creates a bucket', () => { @@ -101,6 +107,59 @@ void describe('AmplifyStorage', () => { ); }); + void describe('storeOutput', () => { + void it('stores output using the provided strategy', () => { + const app = new App(); + const stack = new Stack(app); + + const storeOutputMock = mock.fn(); + const storageStrategy: BackendOutputStorageStrategy = + { + addBackendOutputEntry: storeOutputMock, + appendToBackendOutputList: storeOutputMock, + }; + + const storageConstruct = new AmplifyStorage(stack, 'test', { + name: 'testName', + outputStorageStrategy: storageStrategy, + }); + + const expectedBucketName = ( + storageConstruct.node.findChild('Bucket') as Bucket + ).bucketName; + const expectedRegion = Stack.of(storageConstruct).region; + + const storeOutputArgs = storeOutputMock.mock.calls[0].arguments; + assert.strictEqual(storeOutputArgs.length, 2); + + assert.deepStrictEqual(storeOutputArgs, [ + storageOutputKey, + { + version: '1', + payload: { + bucketName: expectedBucketName, + storageRegion: expectedRegion, + }, + }, + ]); + }); + void it('stores output when no storage strategy is injected', () => { + const app = new App(); + const stack = new Stack(app); + + new AmplifyStorage(stack, 'test', { name: 'testName' }); + const template = Template.fromStack(stack); + template.templateMatches({ + Metadata: { + [storageOutputKey]: { + version: '1', + stackOutputs: ['storageRegion', 'bucketName'], + }, + }, + }); + }); + }); + void describe('storage overrides', () => { void it('can override bucket properties', () => { const app = new App(); diff --git a/packages/backend-storage/src/construct.ts b/packages/backend-storage/src/construct.ts index 1cbdb71670..ad96b56a30 100644 --- a/packages/backend-storage/src/construct.ts +++ b/packages/backend-storage/src/construct.ts @@ -13,9 +13,15 @@ import { FunctionResources, ResourceProvider, } from '@aws-amplify/plugin-types'; -import { StorageOutput } from '@aws-amplify/backend-output-schemas'; +import { + StorageOutput, + storageOutputKey, +} from '@aws-amplify/backend-output-schemas'; import { RemovalPolicy, Stack } from 'aws-cdk-lib'; -import { AttributionMetadataStorage } from '@aws-amplify/backend-output-storage'; +import { + AttributionMetadataStorage, + StackMetadataBackendOutputStorageStrategy, +} from '@aws-amplify/backend-output-storage'; import { fileURLToPath } from 'node:url'; import { IFunction } from 'aws-cdk-lib/aws-lambda'; import { S3EventSourceV2 } from 'aws-cdk-lib/aws-lambda-event-sources'; @@ -26,12 +32,6 @@ const storageStackType = 'storage-S3'; export type AmplifyStorageTriggerEvent = 'onDelete' | 'onUpload'; export type AmplifyStorageProps = { - /** - * Whether this storage resource is the default storage resource for the backend. - * required and relevant only if there are multiple storage resources defined. - * @default false. - */ - isDefault?: boolean; /** * Friendly name that will be used to derive the S3 Bucket name */ @@ -80,15 +80,11 @@ export class AmplifyStorage implements ResourceProvider { readonly resources: StorageResources; - readonly isDefault: boolean; - readonly name: string; /** * Create a new AmplifyStorage instance */ constructor(scope: Construct, id: string, props: AmplifyStorageProps) { super(scope, id); - this.isDefault = props.isDefault || false; - this.name = props.name; const bucketProps: BucketProps = { versioned: props.versioned || false, @@ -126,6 +122,8 @@ export class AmplifyStorage }, }; + this.storeOutput(props.outputStorageStrategy); + new AttributionMetadataStorage().storeAttributionMetadata( Stack.of(this), storageStackType, @@ -143,4 +141,21 @@ export class AmplifyStorage new S3EventSourceV2(this.resources.bucket, { events }) ); }; + + /** + * Store storage outputs using provided strategy + */ + private storeOutput = ( + outputStorageStrategy: BackendOutputStorageStrategy = new StackMetadataBackendOutputStorageStrategy( + Stack.of(this) + ) + ): void => { + outputStorageStrategy.addBackendOutputEntry(storageOutputKey, { + version: '1', + payload: { + storageRegion: Stack.of(this).region, + bucketName: this.resources.bucket.bucketName, + }, + }); + }; } diff --git a/packages/backend-storage/src/factory.test.ts b/packages/backend-storage/src/factory.test.ts index d3f425a6d2..2feff4e5a2 100644 --- a/packages/backend-storage/src/factory.test.ts +++ b/packages/backend-storage/src/factory.test.ts @@ -21,7 +21,6 @@ import { StackResolverStub, } from '@aws-amplify/backend-platform-test-stubs'; import { StorageResources } from './construct.js'; -import { AmplifyUserError } from '@aws-amplify/platform-core'; const createStackAndSetContext = (): Stack => { const app = new App(); @@ -32,16 +31,15 @@ const createStackAndSetContext = (): Stack => { return stack; }; -let storageFactory: ConstructFactory>; -let storageFactory2: ConstructFactory>; -let constructContainer: ConstructContainer; -let outputStorageStrategy: BackendOutputStorageStrategy; -let importPathVerifier: ImportPathVerifier; -let resourceNameValidator: ResourceNameValidator; +void describe('AmplifyStorageFactory', () => { + let storageFactory: ConstructFactory>; + let constructContainer: ConstructContainer; + let outputStorageStrategy: BackendOutputStorageStrategy; + let importPathVerifier: ImportPathVerifier; + let resourceNameValidator: ResourceNameValidator; -let getInstanceProps: ConstructFactoryGetInstanceProps; + let getInstanceProps: ConstructFactoryGetInstanceProps; -void describe('AmplifyStorageFactory', () => { beforeEach(() => { storageFactory = defineStorage({ name: 'testName' }); const stack = createStackAndSetContext(); @@ -82,6 +80,23 @@ void describe('AmplifyStorageFactory', () => { template.resourceCountIs('AWS::S3::Bucket', 1); }); + void it('sets output in storage strategy', () => { + const storeOutputMock = mock.fn(); + + const outputStorageStrategy: BackendOutputStorageStrategy = + { + addBackendOutputEntry: storeOutputMock, + appendToBackendOutputList: storeOutputMock, + }; + + storageFactory.getInstance({ + ...getInstanceProps, + outputStorageStrategy, + }); + + assert.strictEqual(storeOutputMock.mock.callCount(), 1); + }); + void it('verifies constructor import path', () => { const importPathVerifier = { verify: mock.fn(), @@ -123,68 +138,3 @@ void describe('AmplifyStorageFactory', () => { ); }); }); - -void describe('AmplifyStorageFactory', () => { - let stack: Stack; - beforeEach(() => { - stack = createStackAndSetContext(); - - constructContainer = new ConstructContainerStub( - new StackResolverStub(stack) - ); - - outputStorageStrategy = new StackMetadataBackendOutputStorageStrategy( - stack - ); - - importPathVerifier = new ImportPathVerifierStub(); - - resourceNameValidator = new ResourceNameValidatorStub(); - - getInstanceProps = { - constructContainer, - outputStorageStrategy, - importPathVerifier, - resourceNameValidator, - }; - }); - - void it('if more than one default bucket, throw', () => { - storageFactory = defineStorage({ name: 'testName', isDefault: true }); - storageFactory2 = defineStorage({ name: 'testName2', isDefault: true }); - storageFactory.getInstance(getInstanceProps); - storageFactory2.getInstance(getInstanceProps); - - assert.throws( - () => Template.fromStack(stack), - new AmplifyUserError('MultipleDefaultStorageError', { - message: 'More than one default storage set in the Amplify project.', - resolution: - 'Remove `isDefault: true` from all `defineStorage` calls except for one in your Amplify project.', - }) - ); - }); - - void it('if there is no default storage among storage, throw', () => { - storageFactory = defineStorage({ name: 'testName' }); - storageFactory2 = defineStorage({ name: 'testName2' }); - storageFactory.getInstance(getInstanceProps); - storageFactory2.getInstance(getInstanceProps); - - assert.throws( - () => Template.fromStack(stack), - new AmplifyUserError('NoDefaultStorageError', { - message: 'No default storage set in the Amplify project.', - resolution: - 'Add `isDefault: true` to one of the `defineStorage` calls in your Amplify project.', - }) - ); - }); - - void it('if there is no default storage for one storage, ok', () => { - storageFactory = defineStorage({ name: 'testName' }); - storageFactory.getInstance(getInstanceProps); - - assert.ok(Template.fromStack(stack)); - }); -}); diff --git a/packages/backend-storage/src/factory.ts b/packages/backend-storage/src/factory.ts index 49eff9ba1e..743f6efb39 100644 --- a/packages/backend-storage/src/factory.ts +++ b/packages/backend-storage/src/factory.ts @@ -8,13 +8,11 @@ import * as path from 'path'; import { AmplifyStorage, StorageResources } from './construct.js'; import { AmplifyStorageFactoryProps } from './types.js'; import { StorageContainerEntryGenerator } from './storage_container_entry_generator.js'; -import { Aspects, Stack } from 'aws-cdk-lib'; -import { StorageOutputsAspect } from './storage_outputs_aspect.js'; /** * Singleton factory for a Storage bucket that can be used in `resource.ts` files */ -export class AmplifyStorageFactory +class AmplifyStorageFactory implements ConstructFactory> { private generator: ConstructContainerEntryGenerator; @@ -48,23 +46,7 @@ export class AmplifyStorageFactory getInstanceProps ); } - const amplifyStorage = constructContainer.getOrCompute( - this.generator - ) as AmplifyStorage; - - /* - * only call Aspects once, - * otherwise there will be the an error - - * "there is already a construct with name 'storageRegion'" - */ - const aspects = Aspects.of(Stack.of(amplifyStorage)); - if (!aspects.all.length) { - aspects.add( - new StorageOutputsAspect(getInstanceProps.outputStorageStrategy) - ); - } - - return amplifyStorage; + return constructContainer.getOrCompute(this.generator) as AmplifyStorage; }; } diff --git a/packages/backend-storage/src/index.ts b/packages/backend-storage/src/index.ts index ad1007e9ec..9fdcd83804 100644 --- a/packages/backend-storage/src/index.ts +++ b/packages/backend-storage/src/index.ts @@ -1,4 +1,4 @@ -export { defineStorage } from './factory.js'; +export * from './factory.js'; export { StorageResources, AmplifyStorageProps, diff --git a/packages/backend-storage/src/storage_access_policy_factory.ts b/packages/backend-storage/src/storage_access_policy_factory.ts index c7408a5df7..ca3c803123 100644 --- a/packages/backend-storage/src/storage_access_policy_factory.ts +++ b/packages/backend-storage/src/storage_access_policy_factory.ts @@ -17,8 +17,11 @@ export type Permission = { * Generates IAM policies scoped to a single bucket */ export class StorageAccessPolicyFactory { + private readonly namePrefix = 'storageAccess'; private readonly stack: Stack; + private policyCount = 1; + /** * Instantiate with the bucket to generate policies for */ @@ -60,13 +63,9 @@ export class StorageAccessPolicyFactory { }); } - return new Policy( - this.stack, - `storageAccess${this.stack.node.children.length}`, - { - statements, - } - ); + return new Policy(this.stack, `${this.namePrefix}${this.policyCount++}`, { + statements, + }); }; private getStatement = ( diff --git a/packages/backend-storage/src/storage_outputs_aspect.test.ts b/packages/backend-storage/src/storage_outputs_aspect.test.ts deleted file mode 100644 index 7487f0864d..0000000000 --- a/packages/backend-storage/src/storage_outputs_aspect.test.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { afterEach, beforeEach, describe, it, mock } from 'node:test'; -import assert from 'node:assert'; -import { StorageOutputsAspect } from './storage_outputs_aspect.js'; -import { AmplifyStorage } from './construct.js'; -import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types'; -import { StorageOutput } from '@aws-amplify/backend-output-schemas'; -import { App, Stack } from 'aws-cdk-lib'; -import { IConstruct } from 'constructs'; -import { AmplifyUserError } from '@aws-amplify/platform-core'; - -void describe('StorageOutputsAspect', () => { - let app: App; - let stack: Stack; - let outputStorageStrategy: BackendOutputStorageStrategy; - let aspect: StorageOutputsAspect; - const addBackendOutputEntryMock = mock.fn(); - const appendToBackendOutputListMock = mock.fn(); - - beforeEach(() => { - app = new App(); - stack = new Stack(app); - outputStorageStrategy = { - addBackendOutputEntry: addBackendOutputEntryMock, - appendToBackendOutputList: appendToBackendOutputListMock, - }; - }); - - afterEach(() => { - addBackendOutputEntryMock.mock.resetCalls(); - appendToBackendOutputListMock.mock.resetCalls(); - }); - - void describe('visit', () => { - void it('should store the storage outputs if the node is an AmplifyStorage construct', () => { - const node = new AmplifyStorage(stack, 'test', { name: 'testName' }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - aspect.visit(node); - - assert.equal(addBackendOutputEntryMock.mock.callCount(), 1); - assert.equal(appendToBackendOutputListMock.mock.callCount(), 1); - }); - - void it('should not store the storage outputs if the node is not an AmplifyStorage construct', () => { - const node: IConstruct = {} as IConstruct; - - aspect.visit(node); - - assert.equal(addBackendOutputEntryMock.mock.callCount(), 0); - assert.equal(appendToBackendOutputListMock.mock.callCount(), 0); - }); - - void it('should only traverse the siblings once to store the outputs', () => { - const node = new AmplifyStorage(stack, 'test', { name: 'testName' }); - new AmplifyStorage(stack, 'test2', { - name: 'testName2', - isDefault: true, - }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - - aspect.visit(node); - - assert.equal(addBackendOutputEntryMock.mock.callCount(), 1); - assert.equal(appendToBackendOutputListMock.mock.callCount(), 2); - }); - }); - - void describe('storeOutput', () => { - void it('should store the output if the storage is default', () => { - const node = new AmplifyStorage(stack, 'test', { - name: 'testName', - isDefault: true, - }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - aspect.visit(node); - - assert.equal( - addBackendOutputEntryMock.mock.calls[0].arguments[0], - 'AWS::Amplify::Storage' - ); - assert.equal( - addBackendOutputEntryMock.mock.calls[0].arguments[1].payload - .storageRegion, - Stack.of(node).region - ); - assert.equal( - appendToBackendOutputListMock.mock.calls[0].arguments[0], - 'AWS::Amplify::Storage' - ); - assert.equal( - appendToBackendOutputListMock.mock.calls[0].arguments[1].payload - .buckets, - JSON.stringify({ - name: node.name, - bucketName: node.resources.bucket.bucketName, - storageRegion: Stack.of(node).region, - }) - ); - }); - - void it('should store the output if the storage is non-default and it is the only bucket', () => { - const node = new AmplifyStorage(stack, 'test', { name: 'testName' }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - aspect.visit(node); - - assert.equal( - addBackendOutputEntryMock.mock.calls[0].arguments[0], - 'AWS::Amplify::Storage' - ); - assert.equal( - addBackendOutputEntryMock.mock.calls[0].arguments[1].payload - .storageRegion, - Stack.of(node).region - ); - assert.equal( - addBackendOutputEntryMock.mock.calls[0].arguments[1].payload.bucketName, - node.resources.bucket.bucketName - ); - assert.equal( - appendToBackendOutputListMock.mock.calls[0].arguments[0], - 'AWS::Amplify::Storage' - ); - assert.equal( - appendToBackendOutputListMock.mock.calls[0].arguments[1].payload - .buckets, - JSON.stringify({ - name: node.name, - bucketName: node.resources.bucket.bucketName, - storageRegion: Stack.of(node).region, - }) - ); - }); - }); - - void describe('Validate', () => { - void it('should throw if there is no default bucket', () => { - const node = new AmplifyStorage(stack, 'test', { name: 'testName' }); - new AmplifyStorage(stack, 'test2', { name: 'testName2' }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - - assert.throws( - () => { - aspect.visit(node); - }, - (err: AmplifyUserError) => { - assert.equal(err.name, 'NoDefaultStorageError'); - assert.equal( - err.message, - 'No default storage set in the Amplify project.' - ); - return true; - } - ); - }); - - void it('should throw if there is more than one default bucket', () => { - const node = new AmplifyStorage(stack, 'test', { - name: 'testName', - isDefault: true, - }); - new AmplifyStorage(stack, 'test2', { - name: 'testName2', - isDefault: true, - }); - aspect = new StorageOutputsAspect(outputStorageStrategy); - - assert.throws( - () => { - aspect.visit(node); - }, - (err: AmplifyUserError) => { - assert.equal(err.name, 'MultipleDefaultStorageError'); - assert.equal( - err.message, - 'More than one default storage set in the Amplify project.' - ); - return true; - } - ); - }); - }); -}); diff --git a/packages/backend-storage/src/storage_outputs_aspect.ts b/packages/backend-storage/src/storage_outputs_aspect.ts deleted file mode 100644 index 9e9a9fcfa0..0000000000 --- a/packages/backend-storage/src/storage_outputs_aspect.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { - StorageOutput, - storageOutputKey, -} from '@aws-amplify/backend-output-schemas'; -import { AmplifyUserError } from '@aws-amplify/platform-core'; -import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types'; -import { IAspect, Stack } from 'aws-cdk-lib'; -import { IConstruct } from 'constructs'; -import { AmplifyStorage } from './construct.js'; - -/** - * Aspect to store the storage outputs in the backend - */ -export class StorageOutputsAspect implements IAspect { - isStorageProcessed = false; - outputStorageStrategy; - /** - * Constructs a new instance of the StorageValidator class. - */ - constructor( - outputStorageStrategy: BackendOutputStorageStrategy - ) { - this.outputStorageStrategy = outputStorageStrategy; - } - - /** - * Visit the given node. - * If the node is an AmplifyStorage construct, we will traverse its siblings in the same stack - * @param node The node to visit. - */ - public visit(node: IConstruct): void { - if (!(node instanceof AmplifyStorage) || this.isStorageProcessed) { - return; - } - /** - * only traverse the siblings once to store the outputs, - * storing the same outputs multiple times result in error - */ - this.isStorageProcessed = true; - - const storageInstances = Stack.of(node).node.children.filter( - (el) => el instanceof AmplifyStorage - ); - const storageCount = storageInstances.length; - - let defaultStorageFound = false; - - Stack.of(node).node.children.forEach((child) => { - if (!(child instanceof AmplifyStorage)) { - return; - } - if (child.isDefault && !defaultStorageFound) { - defaultStorageFound = true; - } else if (child.isDefault && defaultStorageFound) { - throw new AmplifyUserError('MultipleDefaultStorageError', { - message: `More than one default storage set in the Amplify project.`, - resolution: - 'Remove `isDefault: true` from all `defineStorage` calls except for one in your Amplify project.', - }); - } - }); - /* - * If there is no default bucket set and there is only one bucket, - * we need to set the bucket as default. - */ - if (!defaultStorageFound && storageCount === 1) { - this.storeOutput(this.outputStorageStrategy, true, node); - } else if (!defaultStorageFound && storageCount > 1) { - throw new AmplifyUserError('NoDefaultStorageError', { - message: 'No default storage set in the Amplify project.', - resolution: - 'Add `isDefault: true` to one of the `defineStorage` calls in your Amplify project.', - }); - } else { - Stack.of(node).node.children.forEach((child) => { - if (!(child instanceof AmplifyStorage)) { - return; - } - this.storeOutput(this.outputStorageStrategy, child.isDefault, child); - }); - } - } - - private storeOutput = ( - outputStorageStrategy: BackendOutputStorageStrategy, - isDefault: boolean = false, - node: AmplifyStorage - ): void => { - if (isDefault) { - outputStorageStrategy.addBackendOutputEntry(storageOutputKey, { - version: '1', - payload: { - storageRegion: Stack.of(node).region, - bucketName: node.resources.bucket.bucketName, - }, - }); - } - - // both default and non-default buckets should have the name, bucket name, and storage region stored in `buckets` field - outputStorageStrategy.appendToBackendOutputList(storageOutputKey, { - version: '1', - payload: { - buckets: JSON.stringify({ - name: node.name, - bucketName: node.resources.bucket.bucketName, - storageRegion: Stack.of(node).region, - }), - }, - }); - }; -} diff --git a/packages/client-config/API.md b/packages/client-config/API.md index 67eefb0f69..aa690ed2fd 100644 --- a/packages/client-config/API.md +++ b/packages/client-config/API.md @@ -22,16 +22,6 @@ interface AmazonLocationServiceConfig { // @public type AmazonPinpointChannels = 'IN_APP_MESSAGING' | 'FCM' | 'APNS' | 'EMAIL' | 'SMS'; -// @public (undocumented) -interface AmplifyStorageBucket { - // (undocumented) - aws_region: string; - // (undocumented) - bucket_name: string; - // (undocumented) - name: string; -} - // @public (undocumented) export type AnalyticsClientConfig = { aws_mobile_analytics_app_id?: string; @@ -145,7 +135,6 @@ interface AWSAmplifyBackendOutputs { storage?: { aws_region: AwsRegion; bucket_name: string; - buckets?: AmplifyStorageBucket[]; }; version: '1'; } @@ -191,8 +180,7 @@ declare namespace clientConfigTypesV1 { AwsAppsyncAuthorizationType, AmazonPinpointChannels, AWSAmplifyBackendOutputs, - AmazonLocationServiceConfig, - AmplifyStorageBucket + AmazonLocationServiceConfig } } export { clientConfigTypesV1 } diff --git a/packages/client-config/src/client-config-contributor/client_config_contributor_v1.test.ts b/packages/client-config/src/client-config-contributor/client_config_contributor_v1.test.ts index 2029621fb8..7ea2d6fe6c 100644 --- a/packages/client-config/src/client-config-contributor/client_config_contributor_v1.test.ts +++ b/packages/client-config/src/client-config-contributor/client_config_contributor_v1.test.ts @@ -533,15 +533,8 @@ void describe('storage client config contributor v1', () => { ); }); - void it('returns translated config when output has storage', () => { + void it('returns translated config when output has auth', () => { const contributor = new StorageClientConfigContributor(); - const buckets = JSON.stringify([ - JSON.stringify({ - name: 'testName', - bucketName: 'testBucketName', - storageRegion: 'testRegion', - }), - ]); assert.deepStrictEqual( contributor.contribute({ [storageOutputKey]: { @@ -549,7 +542,6 @@ void describe('storage client config contributor v1', () => { payload: { bucketName: 'testBucketName', storageRegion: 'testRegion', - buckets, }, }, }), @@ -557,15 +549,8 @@ void describe('storage client config contributor v1', () => { storage: { aws_region: 'testRegion', bucket_name: 'testBucketName', - buckets: [ - { - name: 'testName', - bucket_name: 'testBucketName', - aws_region: 'testRegion', - }, - ], }, - } + } as Partial ); }); }); diff --git a/packages/client-config/src/client-config-contributor/client_config_contributor_v1.ts b/packages/client-config/src/client-config-contributor/client_config_contributor_v1.ts index 4f4c2e8eec..6336bb9d79 100644 --- a/packages/client-config/src/client-config-contributor/client_config_contributor_v1.ts +++ b/packages/client-config/src/client-config-contributor/client_config_contributor_v1.ts @@ -12,7 +12,7 @@ import { clientConfigTypesV1, } from '../client-config-types/client_config.js'; import { ModelIntrospectionSchemaAdapter } from '../model_introspection_schema_adapter.js'; -import { AwsAppsyncAuthorizationType } from '../client-config-schema/client_config_v1.1.js'; +import { AwsAppsyncAuthorizationType } from '../client-config-schema/client_config_v1.js'; // All categories client config contributors are included here to mildly enforce them using // the same schema (version and other types) @@ -258,29 +258,10 @@ export class StorageClientConfigContributor implements ClientConfigContributor { return {}; } const config: Partial = {}; - const bucketsStringArray = JSON.parse( - storageOutput.payload.buckets ?? '[]' - ); + config.storage = { aws_region: storageOutput.payload.storageRegion, bucket_name: storageOutput.payload.bucketName, - buckets: bucketsStringArray - .map((b: string) => JSON.parse(b)) - .map( - ({ - name, - bucketName, - storageRegion, - }: { - name: string; - bucketName: string; - storageRegion: string; - }) => ({ - name, - bucket_name: bucketName, - aws_region: storageRegion, - }) - ), }; return config; diff --git a/packages/client-config/src/client-config-schema/client_config_v1.1.ts b/packages/client-config/src/client-config-schema/client_config_v1.ts similarity index 97% rename from packages/client-config/src/client-config-schema/client_config_v1.1.ts rename to packages/client-config/src/client-config-schema/client_config_v1.ts index d17e72c54e..eff8e48836 100644 --- a/packages/client-config/src/client-config-schema/client_config_v1.1.ts +++ b/packages/client-config/src/client-config-schema/client_config_v1.ts @@ -216,7 +216,6 @@ export interface AWSAmplifyBackendOutputs { storage?: { aws_region: AwsRegion; bucket_name: string; - buckets?: AmplifyStorageBucket[]; }; /** * Outputs generated from backend.addOutput({ custom: }) @@ -239,8 +238,3 @@ export interface AmazonLocationServiceConfig { */ style?: string; } -export interface AmplifyStorageBucket { - name: string; - bucket_name: string; - aws_region: string; -} diff --git a/packages/client-config/src/client-config-schema/schema_v1.1.json b/packages/client-config/src/client-config-schema/schema_v1.json similarity index 95% rename from packages/client-config/src/client-config-schema/schema_v1.1.json rename to packages/client-config/src/client-config-schema/schema_v1.json index fdea35c4fa..80d6508b83 100644 --- a/packages/client-config/src/client-config-schema/schema_v1.1.json +++ b/packages/client-config/src/client-config-schema/schema_v1.json @@ -337,12 +337,6 @@ }, "bucket_name": { "type": "string" - }, - "buckets": { - "type": "array", - "items": { - "$ref": "#/$defs/amplify_storage_bucket" - } } }, "required": ["aws_region", "bucket_name"] @@ -354,22 +348,6 @@ }, "required": ["version"], "$defs": { - "amplify_storage_bucket": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string" - }, - "bucket_name": { - "type": "string" - }, - "aws_region": { - "type": "string" - } - }, - "required": ["bucket_name", "aws_region", "name"] - }, "aws_region": { "type": "string" }, diff --git a/packages/client-config/src/client-config-types/client_config.ts b/packages/client-config/src/client-config-types/client_config.ts index 006230ba98..996de528ed 100644 --- a/packages/client-config/src/client-config-types/client_config.ts +++ b/packages/client-config/src/client-config-types/client_config.ts @@ -8,7 +8,7 @@ import { AnalyticsClientConfig } from './analytics_client_config.js'; import { NotificationsClientConfig } from './notifications_client_config.js'; // Versions of new unified config schemas -import * as clientConfigTypesV1 from '../client-config-schema/client_config_v1.1.js'; +import * as clientConfigTypesV1 from '../client-config-schema/client_config_v1.js'; /** * Merged type of all category client config legacy types diff --git a/packages/deployed-backend-client/src/backend_output_client.ts b/packages/deployed-backend-client/src/backend_output_client.ts index 3d5c9b72de..a856303cc6 100644 --- a/packages/deployed-backend-client/src/backend_output_client.ts +++ b/packages/deployed-backend-client/src/backend_output_client.ts @@ -21,9 +21,7 @@ export class DefaultBackendOutputClient implements BackendOutputClient { this.cloudFormationClient, this.amplifyClient ).getStrategy(backendIdentifier); - const output = await outputFetcher.fetchBackendOutput(); - return unifiedBackendOutputSchema.parse(output); }; } diff --git a/packages/deployed-backend-client/src/deployed_backend_client.ts b/packages/deployed-backend-client/src/deployed_backend_client.ts index 94b18def4c..c188b82761 100644 --- a/packages/deployed-backend-client/src/deployed_backend_client.ts +++ b/packages/deployed-backend-client/src/deployed_backend_client.ts @@ -307,8 +307,9 @@ export class DefaultDeployedBackendClient implements DeployedBackendClient { } if (apiStack) { - const additionalAuthTypesString = backendOutput[graphqlOutputKey]?.payload - .awsAppsyncAdditionalAuthenticationTypes as string; + const additionalAuthTypesString = + backendOutput[graphqlOutputKey]?.payload + .awsAppsyncAdditionalAuthenticationTypes; const additionalAuthTypes = additionalAuthTypesString ? (additionalAuthTypesString.split(',') as ApiAuthType[]) : []; @@ -339,7 +340,7 @@ export class DefaultDeployedBackendClient implements DeployedBackendClient { const definedFunctionsString = backendOutput[functionOutputKey]?.payload.definedFunctions; const customerFunctionNames = definedFunctionsString - ? (JSON.parse(definedFunctionsString as string) as string[]) + ? (JSON.parse(definedFunctionsString) as string[]) : []; customerFunctionNames.forEach((functionName) => { diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 07032f46bf..770740398d 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -25,7 +25,6 @@ "@aws-sdk/client-sts": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@smithy/shared-ini-file-loader": "^2.2.5", - "@types/lodash.ismatch": "^4.4.9", "aws-amplify": "^6.0.16", "aws-appsync-auth-link": "^3.0.7", "aws-cdk-lib": "^2.132.0", @@ -34,7 +33,6 @@ "fs-extra": "^11.1.1", "glob": "^10.2.7", "graphql-tag": "^2.12.6", - "lodash.ismatch": "^4.4.0", "node-fetch": "^3.3.2", "semver": "^7.5.4", "ssh2": "^1.15.0", diff --git a/packages/integration-tests/src/test-project-setup/test_project_base.ts b/packages/integration-tests/src/test-project-setup/test_project_base.ts index c6ab0284fe..a37a7cddc5 100644 --- a/packages/integration-tests/src/test-project-setup/test_project_base.ts +++ b/packages/integration-tests/src/test-project-setup/test_project_base.ts @@ -24,7 +24,6 @@ import { BackendOutputClientFactory as CurrentCodebaseBackendOutputClientFactory import path from 'path'; import { AmplifyClient } from '@aws-sdk/client-amplify'; import { pathToFileURL } from 'url'; -import isMatch from 'lodash.ismatch'; export type PlatformDeploymentThresholds = { onWindows: number; @@ -184,6 +183,6 @@ export abstract class TestProjectBase { await currentCodebaseBackendOutputClient.getOutput(backendId); const npmOutputs = await npmBackendOutputClient.getOutput(backendId); - assert.ok(isMatch(currentCodebaseOutputs, npmOutputs)); + assert.deepStrictEqual(currentCodebaseOutputs, npmOutputs); } } diff --git a/packages/plugin-types/API.md b/packages/plugin-types/API.md index 58b1302c88..cac0b4ad81 100644 --- a/packages/plugin-types/API.md +++ b/packages/plugin-types/API.md @@ -90,7 +90,7 @@ export type BackendOutputRetrievalStrategy = { // @public export type BackendOutputStorageStrategy = { addBackendOutputEntry: (keyName: string, backendOutputEntry: T) => void; - appendToBackendOutputList: (keyName: string, backendOutputEntry: DeepPartial) => void; + appendToBackendOutputList: (keyName: string, backendOutputEntry: T) => void; }; // @public (undocumented) @@ -135,11 +135,6 @@ export type ConstructFactoryGetInstanceProps = { resourceNameValidator?: ResourceNameValidator; }; -// @public -export type DeepPartial = { - [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; -}; - // @public export type DeepPartialAmplifyGeneratedConfigs = { [P in keyof T]?: P extends 'auth' | 'data' | 'storage' ? T[P] extends object ? DeepPartialAmplifyGeneratedConfigs : Partial : T[P]; diff --git a/packages/plugin-types/src/deep_partial.ts b/packages/plugin-types/src/deep_partial.ts index d1caee668c..bead10f809 100644 --- a/packages/plugin-types/src/deep_partial.ts +++ b/packages/plugin-types/src/deep_partial.ts @@ -1,13 +1,3 @@ -/** - * Represents a type that allows partial deep cloning of an object. - * The `DeepPartial` type recursively makes all properties of `T` optional. - * If a property is an object, it will also be made partially optional. - * @template T - The type of the object to make partially optional. - */ -export type DeepPartial = { - [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; -}; - /** * Makes all the properties of the entire nested object partial for Amplify generated configs * instead of just the top level properties. Other properties are not changed. diff --git a/packages/plugin-types/src/output_storage_strategy.ts b/packages/plugin-types/src/output_storage_strategy.ts index 90ddfd3d84..560662bdae 100644 --- a/packages/plugin-types/src/output_storage_strategy.ts +++ b/packages/plugin-types/src/output_storage_strategy.ts @@ -1,13 +1,9 @@ import { BackendOutputEntry } from './backend_output.js'; -import { DeepPartial } from './deep_partial.js'; /** * Type for an object that collects output data from constructs */ export type BackendOutputStorageStrategy = { addBackendOutputEntry: (keyName: string, backendOutputEntry: T) => void; - appendToBackendOutputList: ( - keyName: string, - backendOutputEntry: DeepPartial - ) => void; + appendToBackendOutputList: (keyName: string, backendOutputEntry: T) => void; };