Skip to content

Commit 7bc0b56

Browse files
authored
fix: remove vm2 (#12989)
* fix: remove vm2 * ci: fix missing await * ci: refactor * chore: refactor initializer override, lint * chore: cleanup, make async * chore: update api docs
1 parent 4ce0329 commit 7bc0b56

File tree

18 files changed

+83
-177
lines changed

18 files changed

+83
-177
lines changed

packages/amplify-category-auth/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@
4949
"mime-types": "^2.1.26",
5050
"ora": "^4.0.3",
5151
"promise-sequential": "^1.1.1",
52-
"uuid": "^8.3.2",
53-
"vm2": "^3.9.19"
52+
"uuid": "^8.3.2"
5453
},
5554
"devDependencies": {
5655
"@aws-sdk/client-cognito-identity-provider": "^3.303.0",

packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/auth-stack-transform.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
FeatureFlags,
1212
JSONUtilities,
1313
pathManager,
14+
runOverride,
1415
stateManager,
1516
Template,
1617
writeCFNTemplate,
@@ -20,7 +21,6 @@ import * as cdk from 'aws-cdk-lib';
2021
import * as fs from 'fs-extra';
2122
import _ from 'lodash';
2223
import * as path from 'path';
23-
import * as vm from 'vm2';
2424
import { AuthInputState } from '../auth-inputs-manager/auth-input-state';
2525
import { CognitoCLIInputs } from '../service-walkthrough-types/awsCognito-user-input-types';
2626
import { AuthTriggerConnection, AuthTriggerPermissions, CognitoStackOptions } from '../service-walkthrough-types/cognito-user-input-types';
@@ -109,26 +109,9 @@ export class AmplifyAuthTransform extends AmplifyCategoryTransform {
109109
const overrideDir = path.join(backendDir, this._category, this.resourceName);
110110
const isBuild = await buildOverrideDir(backendDir, overrideDir);
111111
if (isBuild) {
112-
const overrideCode: string = await fs.readFile(path.join(overrideDir, 'build', 'override.js'), 'utf-8').catch(() => {
113-
formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth`]);
114-
return '';
115-
});
116-
117-
const sandboxNode = new vm.NodeVM({
118-
console: 'inherit',
119-
timeout: 5000,
120-
sandbox: {},
121-
require: {
122-
context: 'sandbox',
123-
builtin: ['path'],
124-
external: true,
125-
},
126-
});
127112
const projectInfo = getProjectInfo();
128113
try {
129-
await sandboxNode
130-
.run(overrideCode, path.join(overrideDir, 'build', 'override.js'))
131-
.override(this._authTemplateObj as AmplifyAuthCognitoStack & AmplifyStackTemplate, projectInfo);
114+
await runOverride(overrideDir, this._authTemplateObj, projectInfo);
132115
} catch (err) {
133116
throw new AmplifyError(
134117
'InvalidOverrideError',

packages/amplify-category-auth/src/provider-utils/awscloudformation/auth-stack-builder/user-pool-group-stack-transform.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import {
1010
CFNTemplateFormat,
1111
JSONUtilities,
1212
pathManager,
13+
runOverride,
1314
Template,
1415
writeCFNTemplate,
1516
} from '@aws-amplify/amplify-cli-core';
1617
import { formatter } from '@aws-amplify/amplify-prompts';
1718
import * as cdk from 'aws-cdk-lib';
1819
import * as fs from 'fs-extra';
1920
import * as path from 'path';
20-
import * as vm from 'vm2';
2121
import { AuthInputState } from '../auth-inputs-manager/auth-input-state';
2222
import { CognitoCLIInputs } from '../service-walkthrough-types/awsCognito-user-input-types';
2323
import { AmplifyUserPoolGroupStack, AmplifyUserPoolGroupStackOutputs } from './index';
@@ -186,20 +186,9 @@ export class AmplifyUserPoolGroupTransform extends AmplifyCategoryTransform {
186186
const overrideDir = path.join(backendDir, this._category, this._resourceName);
187187
const isBuild = await buildOverrideDir(backendDir, overrideDir);
188188
if (isBuild) {
189-
const overrideCode: string = await fs.readFile(path.join(overrideDir, 'build', 'override.js'), 'utf-8').catch(() => {
190-
formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth`]);
191-
return '';
192-
});
193-
const sandboxNode = new vm.NodeVM({
194-
console: 'inherit',
195-
timeout: 5000,
196-
sandbox: {},
197-
});
198189
const projectInfo = getProjectInfo();
199190
try {
200-
await sandboxNode
201-
.run(overrideCode)
202-
.override(this._userPoolGroupTemplateObj as AmplifyUserPoolGroupStack & AmplifyStackTemplate, projectInfo);
191+
await runOverride(overrideDir, this._userPoolGroupTemplateObj, projectInfo);
203192
} catch (err: $TSAny) {
204193
throw new AmplifyError(
205194
'InvalidOverrideError',

packages/amplify-category-storage/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
"fs-extra": "^8.1.0",
4343
"lodash": "^4.17.21",
4444
"promise-sequential": "^1.1.1",
45-
"uuid": "^8.3.2",
46-
"vm2": "^3.9.19"
45+
"uuid": "^8.3.2"
4746
},
4847
"devDependencies": {
4948
"cloudform-types": "^4.2.0",

packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/ddb-stack-transform.ts

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { AmplifyDDBResourceTemplate, getProjectInfo } from '@aws-amplify/cli-extensibility-helper';
2-
import { $TSContext, AmplifyError, buildOverrideDir, JSONUtilities, pathManager } from '@aws-amplify/amplify-cli-core';
2+
import { $TSContext, AmplifyError, buildOverrideDir, JSONUtilities, pathManager, runOverride } from '@aws-amplify/amplify-cli-core';
33
import { formatter } from '@aws-amplify/amplify-prompts';
44
import * as cdk from 'aws-cdk-lib';
55
import * as fs from 'fs-extra';
66
import * as path from 'path';
7-
import * as vm from 'vm2';
87
import { getDdbAttrType } from '../cfn-template-utils';
98
import { DynamoDBCLIInputs } from '../service-walkthrough-types/dynamoDB-user-input-types';
109
import { DynamoDBInputState } from '../service-walkthroughs/dynamoDB-input-state';
@@ -188,48 +187,22 @@ export class DDBStackTransform {
188187
async applyOverrides(): Promise<void> {
189188
const backendDir = pathManager.getBackendDirPath();
190189
const resourceDirPath = pathManager.getResourceDirectoryPath(undefined, 'storage', this._resourceName);
191-
const overrideJSFilePath = path.resolve(path.join(resourceDirPath, 'build', 'override.js'));
192-
193190
const isBuild = await buildOverrideDir(backendDir, resourceDirPath);
194191
// skip if packageManager or override.ts not found
195192
if (isBuild) {
196-
const { override } = await import(overrideJSFilePath).catch(() => {
197-
formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth ${this._resourceName} `]);
198-
return undefined;
199-
});
200-
201-
if (typeof override === 'function' && override) {
202-
const overrideCode: string = await fs.readFile(overrideJSFilePath, 'utf-8').catch(() => {
203-
formatter.list(['No override File Found', `To override ${this._resourceName} run amplify override auth`]);
204-
return '';
205-
});
206-
207-
const sandboxNode = new vm.NodeVM({
208-
console: 'inherit',
209-
timeout: 5000,
210-
sandbox: {},
211-
require: {
212-
context: 'sandbox',
213-
builtin: ['path'],
214-
external: true,
193+
const projectInfo = getProjectInfo();
194+
try {
195+
await runOverride(resourceDirPath, this._resourceTemplateObj, projectInfo);
196+
} catch (err) {
197+
throw new AmplifyError(
198+
'InvalidOverrideError',
199+
{
200+
message: `Executing overrides failed.`,
201+
details: err.message,
202+
resolution: 'There may be runtime errors in your overrides file. If so, fix the errors and try again.',
215203
},
216-
});
217-
const projectInfo = getProjectInfo();
218-
try {
219-
await sandboxNode
220-
.run(overrideCode, overrideJSFilePath)
221-
.override(this._resourceTemplateObj as AmplifyDDBResourceTemplate, projectInfo);
222-
} catch (err) {
223-
throw new AmplifyError(
224-
'InvalidOverrideError',
225-
{
226-
message: `Executing overrides failed.`,
227-
details: err.message,
228-
resolution: 'There may be runtime errors in your overrides file. If so, fix the errors and try again.',
229-
},
230-
err,
231-
);
232-
}
204+
err,
205+
);
233206
}
234207
}
235208
}

packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import {
1010
IAmplifyResource,
1111
JSONUtilities,
1212
pathManager,
13+
runOverride,
1314
} from '@aws-amplify/amplify-cli-core';
1415
import { formatter } from '@aws-amplify/amplify-prompts';
1516
import * as fs from 'fs-extra';
1617
import * as path from 'path';
17-
import * as vm from 'vm2';
1818
import { S3PermissionType, S3UserInputs } from '../service-walkthrough-types/s3-user-input-types';
1919
// eslint-disable-next-line import/no-cycle
2020
import { canResourceBeTransformed, S3CFNDependsOn, S3CFNPermissionType, S3InputState } from '../service-walkthroughs/s3-user-input-state';
@@ -195,49 +195,23 @@ export class AmplifyS3ResourceStackTransform {
195195
*/
196196
applyOverrides = async (): Promise<void> => {
197197
const backendDir = pathManager.getBackendDirPath();
198-
const resourceDirPath = pathManager.getResourceDirectoryPath(undefined, AmplifyCategories.STORAGE, this.resourceName);
199-
const overrideJSFilePath = path.resolve(path.join(resourceDirPath, 'build', 'override.js'));
200-
201-
const isBuild = await buildOverrideDir(backendDir, resourceDirPath);
198+
const overrideDir = pathManager.getResourceDirectoryPath(undefined, AmplifyCategories.STORAGE, this.resourceName);
199+
const isBuild = await buildOverrideDir(backendDir, overrideDir);
202200
// Skip if packageManager or override.ts not found
203201
if (isBuild) {
204-
const { override } = await import(overrideJSFilePath).catch(() => {
205-
formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth ${this.resourceName} `]);
206-
return undefined;
207-
});
208-
// Pass stack object
209-
if (override && typeof override === 'function') {
210-
const overrideCode: string = await fs.readFile(overrideJSFilePath, 'utf-8').catch(() => {
211-
formatter.list(['No override File Found', `To override ${this.resourceName} run amplify override auth`]);
212-
return '';
213-
});
214-
215-
const sandboxNode = new vm.NodeVM({
216-
console: 'inherit',
217-
timeout: 5000,
218-
sandbox: {},
219-
require: {
220-
context: 'sandbox',
221-
builtin: ['path'],
222-
external: true,
202+
const projectInfo = getProjectInfo();
203+
try {
204+
await runOverride(overrideDir, this.resourceTemplateObj, projectInfo);
205+
} catch (err: $TSAny) {
206+
throw new AmplifyError(
207+
'InvalidOverrideError',
208+
{
209+
message: `Executing overrides failed.`,
210+
details: err.message,
211+
resolution: 'There may be runtime errors in your overrides file. If so, fix the errors and try again.',
223212
},
224-
});
225-
try {
226-
const projectInfo = getProjectInfo();
227-
await sandboxNode
228-
.run(overrideCode, overrideJSFilePath)
229-
.override(this.resourceTemplateObj as AmplifyS3ResourceTemplate, projectInfo);
230-
} catch (err: $TSAny) {
231-
throw new AmplifyError(
232-
'InvalidOverrideError',
233-
{
234-
message: `Executing overrides failed.`,
235-
details: err.message,
236-
resolution: 'There may be runtime errors in your overrides file. If so, fix the errors and try again.',
237-
},
238-
err,
239-
);
240-
}
213+
err,
214+
);
241215
}
242216
}
243217
};

packages/amplify-cli-core/API.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,9 @@ export interface ResourceTuple {
19191919
// @public (undocumented)
19201920
export function runHelp(context: $TSContext, commandsInfo: Array<CommandInfo>): void;
19211921

1922+
// @public (undocumented)
1923+
export const runOverride: (overrideDir: string, templateObject: $TSAny, projectInfo: $TSAny) => Promise<void>;
1924+
19221925
// @public (undocumented)
19231926
export type Runtime = {
19241927
plugins: Plugin_2[];
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './migration-message';
22
export * from './override-skeleton-generator';
3+
export * from './override-runner';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { $TSAny } from '../index';
2+
import * as path from 'path';
3+
4+
export const runOverride = async (overrideDir: string, templateObject: $TSAny, projectInfo: $TSAny): Promise<void> => {
5+
const overrideJSFilePath = path.join(overrideDir, 'build', 'override.js');
6+
// before importing the override file, we should clear the require cache to avoid
7+
// importing an outdated version of the override file
8+
// see: https://github.com/nodejs/modules/issues/307
9+
// and https://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate
10+
delete require.cache[require.resolve(overrideJSFilePath)];
11+
const overrideImport = require(overrideJSFilePath);
12+
if (overrideImport && overrideImport?.override && typeof overrideImport?.override === 'function') {
13+
await overrideImport.override(templateObject, projectInfo);
14+
}
15+
};

packages/amplify-e2e-tests/src/__tests__/delete.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ async function testDeletion(projRoot: string, settings: { ios?: boolean; android
123123
if (meta.AmplifyAppId) expect(await appExists(meta.AmplifyAppId, meta.Region)).toBe(false);
124124
expect(await bucketNotExists(deploymentBucketName1)).toBe(true);
125125
expect(await bucketNotExists(deploymentBucketName2)).toBe(true);
126-
expect(AuthRoleName).not.toBeIAMRoleWithArn(AuthRoleName);
127-
expect(UnauthRoleName).not.toBeIAMRoleWithArn(UnauthRoleName);
126+
await expect(AuthRoleName).not.toBeIAMRoleWithArn(AuthRoleName);
127+
await expect(UnauthRoleName).not.toBeIAMRoleWithArn(UnauthRoleName);
128128
// check that config/exports file was deleted
129129
if (settings.ios) {
130130
expect(fs.existsSync(getAWSConfigIOSPath(projRoot))).toBe(false);

packages/amplify-e2e-tests/src/__tests__/init-special-case.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ describe('amplify init', () => {
3333
const meta = getBackendAmplifyMeta(projectRoot).providers.awscloudformation;
3434
expect(meta.Region).toBeDefined();
3535
const { AuthRoleName, UnauthRoleName, UnauthRoleArn, AuthRoleArn, DeploymentBucketName } = meta;
36-
expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
37-
expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
38-
expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
36+
await expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
37+
await expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
38+
await expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
3939
});
4040

4141
it('test init on a git pulled project', async () => {

packages/amplify-e2e-tests/src/__tests__/init_b.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ describe('amplify init b', () => {
2727
expect(meta.Region).toBeDefined();
2828
const { AuthRoleName, UnauthRoleName, UnauthRoleArn, AuthRoleArn, DeploymentBucketName } = meta;
2929

30-
expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
31-
expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
32-
expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
30+
await expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
31+
await expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
32+
await expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
3333

3434
// init new env
3535
await initNewEnvWithProfile(projRoot, { envName: 'foo' });
@@ -49,8 +49,8 @@ describe('amplify init b', () => {
4949
expect(AuthRoleArn).not.toEqual(newEnvAuthRoleArn);
5050
expect(DeploymentBucketName).not.toEqual(newEnvDeploymentBucketName);
5151

52-
expect(newEnvUnAuthRoleName).toBeIAMRoleWithArn(newEnvUnauthRoleArn);
53-
expect(newEnvAuthRoleName).toBeIAMRoleWithArn(newEnvAuthRoleArn);
54-
expect(newEnvDeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
52+
await expect(newEnvUnAuthRoleName).toBeIAMRoleWithArn(newEnvUnauthRoleArn);
53+
await expect(newEnvAuthRoleName).toBeIAMRoleWithArn(newEnvAuthRoleArn);
54+
await expect(newEnvDeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
5555
});
5656
});

packages/amplify-e2e-tests/src/__tests__/init_c.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ describe('amplify init c', () => {
3636
expect(meta.Region).toBeDefined();
3737
const { AuthRoleName, UnauthRoleName, UnauthRoleArn, AuthRoleArn, DeploymentBucketName } = meta;
3838

39-
expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
40-
expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
41-
expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
39+
await expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
40+
await expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
41+
await expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
4242

4343
// init new env
4444
await initNewEnvWithAccessKey(projRoot, {
@@ -62,8 +62,8 @@ describe('amplify init c', () => {
6262
expect(AuthRoleArn).not.toEqual(newEnvAuthRoleArn);
6363
expect(DeploymentBucketName).not.toEqual(newEnvDeploymentBucketName);
6464

65-
expect(newEnvUnAuthRoleName).toBeIAMRoleWithArn(newEnvUnauthRoleArn);
66-
expect(newEnvAuthRoleName).toBeIAMRoleWithArn(newEnvAuthRoleArn);
67-
expect(newEnvDeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
65+
await expect(newEnvUnAuthRoleName).toBeIAMRoleWithArn(newEnvUnauthRoleArn);
66+
await expect(newEnvAuthRoleName).toBeIAMRoleWithArn(newEnvAuthRoleArn);
67+
await expect(newEnvDeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
6868
});
6969
});

packages/amplify-e2e-tests/src/__tests__/init_e.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ describe('amplify init e', () => {
4040
expect(meta.Region).toBeDefined();
4141
const { AuthRoleName, UnauthRoleName, UnauthRoleArn, AuthRoleArn, DeploymentBucketName } = meta;
4242

43-
expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
44-
expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
45-
expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
43+
await expect(UnauthRoleName).toBeIAMRoleWithArn(UnauthRoleArn);
44+
await expect(AuthRoleName).toBeIAMRoleWithArn(AuthRoleArn);
45+
await expect(DeploymentBucketName).toBeAS3Bucket(DeploymentBucketName);
4646

4747
// override new env
4848
await amplifyOverrideRoot(projRoot, { testingWithLatestCodebase: false });

packages/amplify-provider-awscloudformation/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
"promise-sequential": "^1.1.1",
6969
"proxy-agent": "^5.0.0",
7070
"rimraf": "^3.0.0",
71-
"vm2": "^3.9.19",
7271
"xstate": "^4.14.0"
7372
},
7473
"devDependencies": {

0 commit comments

Comments
 (0)