Skip to content

Commit 20c49d2

Browse files
authored
Merge branch 'gen2-migration' into sai/stateful-resources-for-gen2-migration
2 parents 4ff8d8c + 67f3e7a commit 20c49d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+5958
-674
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ packages/amplify-opensearch-simulator/emulator
4242
packages/graphql*/lib
4343
packages/amplify-graphql-transformer-*/lib
4444
packages/amplify-cli/lib
45+
packages/amplify-cli/src/commands/gen2-migration/amplify-gen2-migration-codegen-dg/lib
4546
packages/amplify-cli-npm/lib
4647
packages/amplify-cli-core/lib
4748
packages/amplify-cli-core-vNext/lib

packages/amplify-cli/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@
108108
},
109109
"devDependencies": {
110110
"@aws-amplify/amplify-function-plugin-interface": "1.12.1",
111+
"@aws-sdk/client-cognito-identity-provider": "^3.624.0",
112+
"@aws-sdk/client-lambda": "^3.624.0",
113+
"@aws-sdk/client-s3": "^3.624.0",
111114
"@types/archiver": "^5.3.1",
112115
"@types/columnify": "^1.5.1",
113116
"@types/folder-hash": "^4.0.1",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { PatternDetector } from '../../../../../commands/gen2-migration/codegen-custom-resources/parser/pattern-detector';
2+
3+
describe('PatternDetector', () => {
4+
let detector: PatternDetector;
5+
6+
beforeEach(() => {
7+
detector = new PatternDetector();
8+
});
9+
10+
describe('detectPatterns', () => {
11+
it('should detect CfnParameter for env', () => {
12+
const code = `new cdk.CfnParameter(this, 'env', { type: 'String' });`;
13+
const patterns = detector.detectPatterns(code);
14+
expect(patterns.hasCfnParameter).toBe(true);
15+
});
16+
17+
it('should detect cdk.Fn.ref', () => {
18+
const code = `const name = \`resource-\${cdk.Fn.ref('env')}\`;`;
19+
const patterns = detector.detectPatterns(code);
20+
expect(patterns.hasCdkFnRef).toBe(true);
21+
});
22+
23+
it('should detect AmplifyHelpers.getProjectInfo', () => {
24+
const code = `const info = AmplifyHelpers.getProjectInfo();`;
25+
const patterns = detector.detectPatterns(code);
26+
expect(patterns.hasGetProjectInfo).toBe(true);
27+
});
28+
29+
it('should detect AmplifyHelpers.addResourceDependency', () => {
30+
const code = `AmplifyHelpers.addResourceDependency(this, 'auth', 'userPool', []);`;
31+
const patterns = detector.detectPatterns(code);
32+
expect(patterns.hasAddResourceDependency).toBe(true);
33+
});
34+
35+
it('should detect CfnOutput', () => {
36+
const code = `new cdk.CfnOutput(this, 'topicArn', { value: topic.topicArn });`;
37+
const patterns = detector.detectPatterns(code);
38+
expect(patterns.hasCfnOutput).toBe(true);
39+
});
40+
});
41+
42+
describe('extractCfnOutputs', () => {
43+
it('should extract CfnOutput with value and description', () => {
44+
const code = `new cdk.CfnOutput(this, 'snsTopicArn', {
45+
value: topic.topicArn,
46+
description: 'The arn of the SNS topic',
47+
});`;
48+
49+
const outputs = detector.extractCfnOutputs(code);
50+
51+
expect(outputs).toHaveLength(1);
52+
expect(outputs[0].id).toBe('snsTopicArn');
53+
expect(outputs[0].value).toBe('topic.topicArn');
54+
expect(outputs[0].description).toBe('The arn of the SNS topic');
55+
});
56+
57+
it('should extract multiple CfnOutputs', () => {
58+
const code = `
59+
new cdk.CfnOutput(this, 'topicArn', { value: topic.topicArn });
60+
new cdk.CfnOutput(this, 'queueUrl', { value: queue.queueUrl });
61+
`;
62+
63+
const outputs = detector.extractCfnOutputs(code);
64+
65+
expect(outputs).toHaveLength(2);
66+
expect(outputs[0].id).toBe('topicArn');
67+
expect(outputs[1].id).toBe('queueUrl');
68+
});
69+
});
70+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { CustomResourceScanner } from '../../../../../commands/gen2-migration/codegen-custom-resources/scanner/custom-resource-scanner';
2+
import * as fs from 'fs-extra';
3+
import { promises as fsPromises } from 'fs';
4+
import * as path from 'path';
5+
import * as os from 'os';
6+
7+
describe('CustomResourceScanner', () => {
8+
let scanner: CustomResourceScanner;
9+
10+
beforeAll(() => {
11+
scanner = new CustomResourceScanner();
12+
});
13+
14+
it('should return empty array when custom directory does not exist', async () => {
15+
const tempDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'amplify-test-'));
16+
try {
17+
const resources = await scanner.scanCustomResources(tempDir);
18+
expect(resources).toEqual([]);
19+
} finally {
20+
await fs.remove(tempDir);
21+
}
22+
});
23+
24+
it('should find custom resources with cdk-stack.ts', async () => {
25+
const tempDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'amplify-test-'));
26+
try {
27+
const customDir = path.join(tempDir, 'amplify', 'backend', 'custom');
28+
const notificationsDir = path.join(customDir, 'notifications');
29+
30+
await fsPromises.mkdir(customDir, { recursive: true });
31+
await fsPromises.mkdir(notificationsDir, { recursive: true });
32+
await fsPromises.writeFile(path.join(notificationsDir, 'cdk-stack.ts'), '// CDK stack');
33+
34+
const resources = await scanner.scanCustomResources(tempDir);
35+
36+
expect(resources).toHaveLength(1);
37+
expect(resources[0].name).toBe('notifications');
38+
expect(resources[0].cdkStackPath).toContain('cdk-stack.ts');
39+
} finally {
40+
await fs.remove(tempDir);
41+
}
42+
});
43+
44+
it('should find multiple custom resources', async () => {
45+
const tempDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'amplify-test-'));
46+
try {
47+
const customDir = path.join(tempDir, 'amplify', 'backend', 'custom');
48+
49+
await fsPromises.mkdir(customDir, { recursive: true });
50+
await fsPromises.mkdir(path.join(customDir, 'notifications'), { recursive: true });
51+
await fsPromises.mkdir(path.join(customDir, 'analytics'), { recursive: true });
52+
await fsPromises.writeFile(path.join(customDir, 'notifications', 'cdk-stack.ts'), '// CDK stack');
53+
await fsPromises.writeFile(path.join(customDir, 'analytics', 'cdk-stack.ts'), '// CDK stack');
54+
55+
const resources = await scanner.scanCustomResources(tempDir);
56+
57+
expect(resources).toHaveLength(2);
58+
expect(resources.map((r) => r.name).sort()).toEqual(['analytics', 'notifications']);
59+
} finally {
60+
await fs.remove(tempDir);
61+
}
62+
});
63+
64+
it('should ignore directories without cdk-stack.ts', async () => {
65+
const tempDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), 'amplify-test-'));
66+
try {
67+
const customDir = path.join(tempDir, 'amplify', 'backend', 'custom');
68+
69+
await fsPromises.mkdir(customDir, { recursive: true });
70+
await fsPromises.mkdir(path.join(customDir, 'notifications'), { recursive: true });
71+
await fsPromises.mkdir(path.join(customDir, 'other'), { recursive: true });
72+
await fsPromises.writeFile(path.join(customDir, 'notifications', 'cdk-stack.ts'), '// CDK stack');
73+
74+
const resources = await scanner.scanCustomResources(tempDir);
75+
76+
expect(resources).toHaveLength(1);
77+
expect(resources[0].name).toBe('notifications');
78+
} finally {
79+
await fs.remove(tempDir);
80+
}
81+
});
82+
});

0 commit comments

Comments
 (0)