diff --git a/.circleci/config.base.yml b/.circleci/config.base.yml index 79b36d2caf1..4e29ce7f868 100644 --- a/.circleci/config.base.yml +++ b/.circleci/config.base.yml @@ -1040,10 +1040,11 @@ commands: steps: - run: name: Run E2e Tests - shell: powershell.exe + shell: bash.exe command: | + source .circleci/local_publish_helpers.sh cd packages/amplify-e2e-tests - yarn run e2e --detectOpenHandles --maxWorkers=3 $env:TEST_SUITE + retry yarn run e2e --detectOpenHandles --maxWorkers=3 $TEST_SUITE no_output_timeout: 90m - when: condition: diff --git a/.circleci/config.yml b/.circleci/config.yml index 14e236d7218..67911846932 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14612,6 +14612,7 @@ workflows: parameters: os: - linux + - windows - layer-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14702,6 +14703,7 @@ workflows: parameters: os: - linux + - windows - schema-key-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14756,6 +14758,7 @@ workflows: parameters: os: - linux + - windows - schema-iterative-rollback-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14828,6 +14831,7 @@ workflows: parameters: os: - linux + - windows - frontend_config_drift-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14846,6 +14850,7 @@ workflows: parameters: os: - linux + - windows - iam-permissions-boundary-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14864,6 +14869,7 @@ workflows: parameters: os: - linux + - windows - layer-3-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14918,6 +14924,7 @@ workflows: parameters: os: - linux + - windows - amplify-configure-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14955,6 +14962,7 @@ workflows: parameters: os: - linux + - windows - schema-predictions-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14973,6 +14981,7 @@ workflows: parameters: os: - linux + - windows - predictions-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -14991,6 +15000,7 @@ workflows: parameters: os: - linux + - windows - auth_1-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15009,6 +15019,7 @@ workflows: parameters: os: - linux + - windows - auth_3-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15081,6 +15092,7 @@ workflows: parameters: os: - linux + - windows - schema-auth-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15099,6 +15111,7 @@ workflows: parameters: os: - linux + - windows - auth_7-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15117,6 +15130,7 @@ workflows: parameters: os: - linux + - windows - function_5-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15189,6 +15203,7 @@ workflows: parameters: os: - linux + - windows - storage-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15207,6 +15222,7 @@ workflows: parameters: os: - linux + - windows - init-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15225,6 +15241,7 @@ workflows: parameters: os: - linux + - windows - amplify-app-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15261,6 +15278,7 @@ workflows: parameters: os: - linux + - windows - auth_5-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15279,6 +15297,7 @@ workflows: parameters: os: - linux + - windows - migration-api-key-migration1-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15333,6 +15352,7 @@ workflows: parameters: os: - linux + - windows - function_4-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15387,6 +15407,7 @@ workflows: parameters: os: - linux + - windows - function_6-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15459,6 +15480,7 @@ workflows: parameters: os: - linux + - windows - storage-3-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15477,6 +15499,7 @@ workflows: parameters: os: - linux + - windows - tags-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15495,6 +15518,7 @@ workflows: parameters: os: - linux + - windows - hosting-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15513,6 +15537,7 @@ workflows: parameters: os: - linux + - windows - geo-add-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15603,6 +15628,7 @@ workflows: parameters: os: - linux + - windows - schema-model-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15621,6 +15647,7 @@ workflows: parameters: os: - linux + - windows - schema-auth-5-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15639,6 +15666,7 @@ workflows: parameters: os: - linux + - windows - configure-project-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15730,6 +15758,7 @@ workflows: parameters: os: - linux + - windows - storage-4-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15748,7 +15777,6 @@ workflows: parameters: os: - linux - - windows - notifications-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15767,6 +15795,7 @@ workflows: parameters: os: - linux + - windows - analytics-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15785,6 +15814,7 @@ workflows: parameters: os: - linux + - windows - geo-update-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15839,6 +15869,7 @@ workflows: parameters: os: - linux + - windows - import_s3_1-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15875,6 +15906,7 @@ workflows: parameters: os: - linux + - windows - migration-api-connection-migration-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -15966,7 +15998,6 @@ workflows: parameters: os: - linux - - windows - migration-api-key-migration5-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16003,6 +16034,7 @@ workflows: parameters: os: - linux + - windows - plugin-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16040,6 +16072,7 @@ workflows: parameters: os: - linux + - windows - feature-flags-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16094,6 +16127,7 @@ workflows: parameters: os: - linux + - windows - schema-auth-8-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16112,6 +16146,7 @@ workflows: parameters: os: - linux + - windows - import_dynamodb_1-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16130,6 +16165,7 @@ workflows: parameters: os: - linux + - windows - migration-api-key-migration2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16166,6 +16202,7 @@ workflows: parameters: os: - linux + - windows - api_5-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16184,6 +16221,7 @@ workflows: parameters: os: - linux + - windows - custom_policies_container-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16256,6 +16294,7 @@ workflows: parameters: os: - linux + - windows - schema-function-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16274,6 +16313,7 @@ workflows: parameters: os: - linux + - windows - init-special-case-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16311,6 +16351,7 @@ workflows: parameters: os: - linux + - windows - schema-iterative-update-2-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16347,6 +16388,7 @@ workflows: parameters: os: - linux + - windows - delete-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16383,6 +16425,7 @@ workflows: parameters: os: - linux + - windows - schema-iterative-rollback-1-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -16437,6 +16480,7 @@ workflows: parameters: os: - linux + - windows - schema-iterative-update-4-amplify_e2e_tests_pkg: context: - amplify-ecr-image-pull @@ -17524,12 +17568,14 @@ commands: steps: - run: name: Run E2e Tests - shell: powershell.exe + shell: bash.exe command: > + source .circleci/local_publish_helpers.sh + cd packages/amplify-e2e-tests - yarn run e2e --detectOpenHandles --maxWorkers=3 - $env:TEST_SUITE + retry yarn run e2e --detectOpenHandles --maxWorkers=3 + $TEST_SUITE no_output_timeout: 90m - when: condition: diff --git a/package.json b/package.json index 3023ff6b531..134447a6bb5 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "production-build": "yarn --frozen-lockfile --cache-folder ~/.cache/yarn && lerna run build --concurrency 3 --stream", "dev-build": "yarn --cache-folder ~/.cache/yarn && lerna run build", "link-aa-dev": "cd packages/amplify-app && ln -s \"$(pwd)/bin/amplify-app\" \"$(yarn global bin)/amplify-app-dev\" && cd -", - "rm-aa-dev-link": "rm -f \"$(yarn global bin)/amplify-app-dev\"", + "rm-aa-dev-link": "rimraf -f \"$(yarn global bin)/amplify-app-dev\"", "link-dev": "cd packages/amplify-cli && ln -s \"$(pwd)/bin/amplify\" \"$(yarn global bin)/amplify-dev\" && cd -", - "rm-dev-link": "rm -f \"$(yarn global bin)/amplify-dev\"", + "rm-dev-link": "rimraf -f \"$(yarn global bin)/amplify-dev\"", "setup-dev": "yarn dev-build && yarn rm-dev-link && yarn link-dev && yarn rm-aa-dev-link && yarn link-aa-dev", "link-win": "node ./scripts/link-bin.js packages/amplify-cli/bin/amplify amplify-dev", "link-aa-win": "node ./scripts/link-bin.js packages/amplify-app/bin/amplify-app amplify-app-dev", diff --git a/packages/amplify-category-api/resources/awscloudformation/graphql-schemas/single-object-auth-schema-v2.graphql b/packages/amplify-category-api/resources/awscloudformation/graphql-schemas/single-object-auth-schema-v2.graphql index 0faf0997d4a..d1706a3bab9 100644 --- a/packages/amplify-category-api/resources/awscloudformation/graphql-schemas/single-object-auth-schema-v2.graphql +++ b/packages/amplify-category-api/resources/awscloudformation/graphql-schemas/single-object-auth-schema-v2.graphql @@ -1,8 +1,11 @@ type Task @model - @auth(rules: [ + @auth( + rules: [ { allow: groups, groups: ["Managers"], operations: [create, update, read, delete] } - { allow: groups, groups: ["Employees"], operations: [read] } ]) { + { allow: groups, groups: ["Employees"], operations: [read] } + ] + ) { id: ID! title: String! description: String diff --git a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts index 1d7ed55cdfd..6e6a75c8d8c 100644 --- a/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts +++ b/packages/amplify-category-api/src/__tests__/provider-utils/awscloudformation/service-walkthroughs/appSync-walkthrough.test.ts @@ -25,16 +25,15 @@ const context_stub = (prompt: jest.Mock) => ({ }); type IAMArtifact = { - attributes: string[], - policy: any, + attributes: string[]; + policy: any; }; - describe('get IAM policies', () => { beforeEach(() => { jest.resetModules(); }); -it('does not include API key if none exists', async () => { + it('does not include API key if none exists', async () => { mockGetBoolean.mockImplementationOnce(() => true); authConfigHasApiKey_mock.mockImplementationOnce(() => false); const iamArtifact: IAMArtifact = getIAMPolicies('testResourceName', ['Query'], context_stub(confirmPromptFalse_mock)); @@ -47,7 +46,7 @@ it('does not include API key if none exists', async () => { expect(iamArtifact.policy.Resource[0]['Fn::Join'][1][6]).toMatch('/types/Query/*'); }); -it('includes API key if it exists', async () => { + it('includes API key if it exists', async () => { mockGetBoolean.mockImplementationOnce(() => true); authConfigHasApiKey_mock.mockImplementationOnce(() => true); const iamArtifact: IAMArtifact = getIAMPolicies('testResourceName', ['Query'], context_stub(confirmPromptFalse_mock)); @@ -61,7 +60,7 @@ it('includes API key if it exists', async () => { expect(iamArtifact.policy.Resource[0]['Fn::Join'][1][6]).toMatch('/types/Query/*'); }); -it('policy path includes the new format for graphql operations', async () => { + it('policy path includes the new format for graphql operations', async () => { mockGetBoolean.mockImplementationOnce(() => true); authConfigHasApiKey_mock.mockImplementationOnce(() => false); const iamArtifact: IAMArtifact = getIAMPolicies('testResourceName', ['Query', 'Mutate'], context_stub(confirmPromptFalse_mock)); @@ -85,7 +84,7 @@ it('policy path includes the new format for graphql operations', async () => { ] `); expect(iamArtifact.policy.Action).toHaveLength(4); - expect(iamArtifact.policy.Action).toEqual(["appsync:Create*", "appsync:StartSchemaCreation", "appsync:GraphQL", "appsync:Update*"]); + expect(iamArtifact.policy.Action).toEqual(['appsync:Create*', 'appsync:StartSchemaCreation', 'appsync:GraphQL', 'appsync:Update*']); expect(iamArtifact.policy.Resource).toHaveLength(2); expect(iamArtifact.policy.Resource[0]['Fn::Join'][1][6]).toMatch('/*'); }); diff --git a/packages/amplify-category-api/src/index.ts b/packages/amplify-category-api/src/index.ts index 3593ba6b977..4ada1ab74d5 100644 --- a/packages/amplify-category-api/src/index.ts +++ b/packages/amplify-category-api/src/index.ts @@ -249,4 +249,4 @@ export async function addGraphQLAuthorizationMode(context, args) { ); return addAuthConfig; -} \ No newline at end of file +} diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/handlers/resource-handlers.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/handlers/resource-handlers.ts index f40a03833c0..8ea2f603f2b 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/handlers/resource-handlers.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/handlers/resource-handlers.ts @@ -11,34 +11,36 @@ import { doesConfigurationIncludeSMS } from '../utils/auth-sms-workflow-helper'; * The consumer returns the resourceName of the generated resource. * @param context The amplify context */ -export const getAddAuthHandler = (context: any, skipNextSteps: boolean = false) => async (request: ServiceQuestionsResult) => { - const serviceMetadata = getSupportedServices()[request.serviceName]; - const { cfnFilename, defaultValuesFilename, provider } = serviceMetadata; +export const getAddAuthHandler = + (context: any, skipNextSteps: boolean = false) => + async (request: ServiceQuestionsResult) => { + const serviceMetadata = getSupportedServices()[request.serviceName]; + const { cfnFilename, defaultValuesFilename, provider } = serviceMetadata; - let projectName = context.amplify.getProjectConfig().projectName.toLowerCase(); - const disallowedChars = /[^A-Za-z0-9]+/g; - projectName = projectName.replace(disallowedChars, ''); + let projectName = context.amplify.getProjectConfig().projectName.toLowerCase(); + const disallowedChars = /[^A-Za-z0-9]+/g; + projectName = projectName.replace(disallowedChars, ''); - const requestWithDefaults = await getAddAuthDefaultsApplier(context, defaultValuesFilename, projectName)(request); + const requestWithDefaults = await getAddAuthDefaultsApplier(context, defaultValuesFilename, projectName)(request); - try { - await getResourceSynthesizer(context, cfnFilename, provider)(requestWithDefaults); - await getPostAddAuthMetaUpdater(context, { service: requestWithDefaults.serviceName, providerName: provider })( - requestWithDefaults.resourceName!, - ); - await getPostAddAuthMessagePrinter(context.print)(requestWithDefaults.resourceName!, skipNextSteps); + try { + await getResourceSynthesizer(context, cfnFilename, provider)(requestWithDefaults); + await getPostAddAuthMetaUpdater(context, { service: requestWithDefaults.serviceName, providerName: provider })( + requestWithDefaults.resourceName!, + ); + await getPostAddAuthMessagePrinter(context.print)(requestWithDefaults.resourceName!, skipNextSteps); - if (doesConfigurationIncludeSMS(request)) { - await printSMSSandboxWarning(context.print); + if (doesConfigurationIncludeSMS(request)) { + await printSMSSandboxWarning(context.print); + } + } catch (err) { + context.print.info(err.stack); + context.print.error('There was an error adding the auth resource'); + context.usageData.emitError(err); + process.exitCode = 1; } - } catch (err) { - context.print.info(err.stack); - context.print.error('There was an error adding the auth resource'); - context.usageData.emitError(err); - process.exitCode = 1; - } - return requestWithDefaults.resourceName!; -}; + return requestWithDefaults.resourceName!; + }; export const getUpdateAuthHandler = (context: any) => async (request: ServiceQuestionsResult) => { const { cfnFilename, defaultValuesFilename, provider } = getSupportedServices()[request.serviceName]; diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js b/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js index 3a8a5691e93..48101bfa4f5 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js @@ -17,9 +17,10 @@ function serviceQuestions(context, defaultValuesFilename, stringMapsFilename, se async function addResource(context, service, skipNextSteps = false) { const serviceMetadata = getSupportedServices()[service]; const { defaultValuesFilename, stringMapsFilename, serviceWalkthroughFilename } = serviceMetadata; - return getAddAuthHandler(context, skipNextSteps)( - await serviceQuestions(context, defaultValuesFilename, stringMapsFilename, serviceWalkthroughFilename, serviceMetadata), - ); + return getAddAuthHandler( + context, + skipNextSteps, + )(await serviceQuestions(context, defaultValuesFilename, stringMapsFilename, serviceWalkthroughFilename, serviceMetadata)); } async function updateResource(context, { service }) { diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/message-printer.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/message-printer.ts index 9b3f9a71bae..58d841f0660 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/message-printer.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/message-printer.ts @@ -5,13 +5,15 @@ import { BannerMessage } from 'amplify-cli-core'; * A factory function that returns a function that prints the "success message" after adding auth * @param print The amplify print object */ -export const getPostAddAuthMessagePrinter = (print: any) => (resourceName: string, skipNextSteps: boolean = false) => { - print.success(`Successfully added auth resource ${resourceName} locally`); +export const getPostAddAuthMessagePrinter = + (print: any) => + (resourceName: string, skipNextSteps: boolean = false) => { + print.success(`Successfully added auth resource ${resourceName} locally`); - if (!skipNextSteps) { - printCommonText(print); - } -}; + if (!skipNextSteps) { + printCommonText(print); + } + }; /** * A factory function that returns a function that prints the "success message" after updating auth diff --git a/packages/amplify-category-geo/amplify-plugin.json b/packages/amplify-category-geo/amplify-plugin.json index c0e36ecff65..e34ea906e1a 100644 --- a/packages/amplify-category-geo/amplify-plugin.json +++ b/packages/amplify-category-geo/amplify-plugin.json @@ -1,16 +1,9 @@ { - "name": "geo", - "type": "category", - "commands": [ - "add", - "push", - "remove", - "update", - "help", - "console" - ], - "commandAliases":{ - "configure": "update" - }, - "eventHandlers": [] -} \ No newline at end of file + "name": "geo", + "type": "category", + "commands": ["add", "push", "remove", "update", "help", "console"], + "commandAliases": { + "configure": "update" + }, + "eventHandlers": [] +} diff --git a/packages/amplify-category-geo/resources/custom-map-resource-handler.js b/packages/amplify-category-geo/resources/custom-map-resource-handler.js index db8903b3f39..f5a005fd2a7 100644 --- a/packages/amplify-category-geo/resources/custom-map-resource-handler.js +++ b/packages/amplify-category-geo/resources/custom-map-resource-handler.js @@ -1,61 +1,61 @@ const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - let params = { - MapName: event.ResourceProperties.mapName, - Configuration: { - Style: event.ResourceProperties.mapStyle - }, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createMap(params).promise(); - console.log("create resource response data" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + let params = { + MapName: event.ResourceProperties.mapName, + Configuration: { + Style: event.ResourceProperties.mapStyle, + }, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createMap(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } - } - if (event.RequestType == 'Update') { - let params = { - MapName: event.ResourceProperties.mapName, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updateMap(params).promise(); - console.log("update resource response data" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + if (event.RequestType == 'Update') { + let params = { + MapName: event.ResourceProperties.mapName, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updateMap(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + let params = { + MapName: event.ResourceProperties.mapName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deleteMap(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.mapName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - let params = { - MapName: event.ResourceProperties.mapName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deleteMap(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.mapName; - console.log("delete resource response data" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } diff --git a/packages/amplify-category-geo/resources/custom-place-index-resource-handler.js b/packages/amplify-category-geo/resources/custom-place-index-resource-handler.js index a180d0a04a1..0299a2d8f4e 100644 --- a/packages/amplify-category-geo/resources/custom-place-index-resource-handler.js +++ b/packages/amplify-category-geo/resources/custom-place-index-resource-handler.js @@ -1,65 +1,65 @@ const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - const params = { - IndexName: event.ResourceProperties.indexName, - DataSource: event.ResourceProperties.dataSource, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse - } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createPlaceIndex(params).promise(); - console.log("create resource response data" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + const params = { + IndexName: event.ResourceProperties.indexName, + DataSource: event.ResourceProperties.dataSource, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createPlaceIndex(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); - } - } - if (event.RequestType == 'Update') { - const params = { - IndexName: event.ResourceProperties.indexName, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updatePlaceIndex(params).promise(); - console.log("update resource response data" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + } + if (event.RequestType == 'Update') { + const params = { + IndexName: event.ResourceProperties.indexName, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updatePlaceIndex(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + const params = { + IndexName: event.ResourceProperties.indexName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deletePlaceIndex(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.indexName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - const params = { - IndexName: event.ResourceProperties.indexName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deletePlaceIndex(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.indexName; - console.log("delete resource response data" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } diff --git a/packages/amplify-category-geo/src/__tests__/commands/geo/add.test.ts b/packages/amplify-category-geo/src/__tests__/commands/geo/add.test.ts index e04a5ded891..127efe1b99b 100644 --- a/packages/amplify-category-geo/src/__tests__/commands/geo/add.test.ts +++ b/packages/amplify-category-geo/src/__tests__/commands/geo/add.test.ts @@ -3,83 +3,82 @@ import { addResource } from '../../../provider-controllers/index'; import { ServiceName } from '../../../service-utils/constants'; import { run } from '../../../commands/geo/add'; -const mockAddResource = addResource as jest.MockedFunction< typeof addResource >; +const mockAddResource = addResource as jest.MockedFunction; mockAddResource.mockImplementation(async (_, service: string) => service); jest.mock('amplify-cli-core'); jest.mock('../../../provider-controllers/index'); - describe('add command tests', () => { - const provider = 'awscloudformation'; - let mockContext: $TSContext; - // construct mock amplify meta - const mockAmplifyMeta: $TSObject = { - providers: {} + const provider = 'awscloudformation'; + let mockContext: $TSContext; + // construct mock amplify meta + const mockAmplifyMeta: $TSObject = { + providers: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + mockContext = { + print: { + info: jest.fn(), + warning: jest.fn(), + }, + amplify: {}, + } as unknown as $TSContext; + mockAmplifyMeta.providers[provider] = { + Region: 'us-west-2', }; - - beforeEach(() => { - jest.clearAllMocks(); - mockContext = ({ - print: { - info: jest.fn(), - warning: jest.fn() - }, - amplify: {} - } as unknown) as $TSContext; - mockAmplifyMeta.providers[provider] = { - Region: 'us-west-2' - }; - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + }); + + it('add resource workflow is invoked for map service', async () => { + const service = ServiceName.Map; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); - it('add resource workflow is invoked for map service', async() => { - const service = ServiceName.Map; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); + await run(mockContext); - await run(mockContext); + expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + }); - expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + it('add resource workflow is invoked for place index service', async () => { + const service = ServiceName.PlaceIndex; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); - it('add resource workflow is invoked for place index service', async() => { - const service = ServiceName.PlaceIndex; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); + await run(mockContext); - await run(mockContext); + expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + }); - expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + it('add resource workflow is invoked for Map service in unsupported region', async () => { + mockAmplifyMeta.providers[provider] = { + Region: 'eu-west-2', + }; + const service = ServiceName.Map; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); - it('add resource workflow is invoked for Map service in unsupported region', async() => { - mockAmplifyMeta.providers[provider] = { - Region: 'eu-west-2' - }; - const service = ServiceName.Map; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + await run(mockContext); + expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + }); - await run(mockContext); - expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + it('add resource workflow is invoked for Place Index service in unsupported region', async () => { + mockAmplifyMeta.providers[provider] = { + Region: 'eu-west-2', + }; + const service = ServiceName.PlaceIndex; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); - it('add resource workflow is invoked for Place Index service in unsupported region', async() => { - mockAmplifyMeta.providers[provider] = { - Region: 'eu-west-2' - }; - const service = ServiceName.PlaceIndex; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); - - await run(mockContext); - expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); - }); + await run(mockContext); + expect(mockAddResource).toHaveBeenCalledWith(mockContext, service); + }); }); diff --git a/packages/amplify-category-geo/src/__tests__/commands/geo/update.test.ts b/packages/amplify-category-geo/src/__tests__/commands/geo/update.test.ts index da406887437..9698f423a8a 100644 --- a/packages/amplify-category-geo/src/__tests__/commands/geo/update.test.ts +++ b/packages/amplify-category-geo/src/__tests__/commands/geo/update.test.ts @@ -3,85 +3,84 @@ import { updateResource } from '../../../provider-controllers/index'; import { ServiceName } from '../../../service-utils/constants'; import { run } from '../../../commands/geo/update'; -const mockUpdateResource = updateResource as jest.MockedFunction< typeof updateResource >; +const mockUpdateResource = updateResource as jest.MockedFunction; mockUpdateResource.mockImplementation(async (_, service: string) => service); jest.mock('amplify-cli-core'); jest.mock('../../../provider-controllers/index'); - describe('update command tests', () => { - const provider = 'awscloudformation'; - let mockContext: $TSContext; - // construct mock amplify meta - const mockAmplifyMeta: $TSObject = { - providers: {} + const provider = 'awscloudformation'; + let mockContext: $TSContext; + // construct mock amplify meta + const mockAmplifyMeta: $TSObject = { + providers: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + mockContext = { + print: { + info: jest.fn(), + warning: jest.fn(), + }, + amplify: {}, + } as unknown as $TSContext; + mockAmplifyMeta.providers[provider] = { + Region: 'us-west-2', }; - - beforeEach(() => { - jest.clearAllMocks(); - mockContext = ({ - print: { - info: jest.fn(), - warning: jest.fn() - }, - amplify: {} - } as unknown) as $TSContext; - mockAmplifyMeta.providers[provider] = { - Region: 'us-west-2' - }; - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); - }); - - it('update resource workflow is invoked for map service', async() => { - const service = ServiceName.Map; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); - - await run(mockContext); + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + }); - expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + it('update resource workflow is invoked for map service', async () => { + const service = ServiceName.Map; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); - it('update resource workflow is invoked for place index service', async() => { - const service = ServiceName.PlaceIndex; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); + await run(mockContext); - await run(mockContext); + expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + }); - expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + it('update resource workflow is invoked for place index service', async () => { + const service = ServiceName.PlaceIndex; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); - it('update resource workflow is invoked for Map service in unsupported region', async() => { - mockAmplifyMeta.providers[provider] = { - Region: 'eu-west-2' - }; - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + await run(mockContext); - const service = ServiceName.Map; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); + expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + }); - await run(mockContext); - expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + it('update resource workflow is invoked for Map service in unsupported region', async () => { + mockAmplifyMeta.providers[provider] = { + Region: 'eu-west-2', + }; + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + + const service = ServiceName.Map; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); - it('update resource workflow is invoked for Place Index service in unsupported region', async() => { - mockAmplifyMeta.providers[provider] = { - Region: 'eu-west-2' - }; - stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); + await run(mockContext); + expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + }); - const service = ServiceName.PlaceIndex; - mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation( async () => { - return { service: service, providerName: provider }; - }); + it('update resource workflow is invoked for Place Index service in unsupported region', async () => { + mockAmplifyMeta.providers[provider] = { + Region: 'eu-west-2', + }; + stateManager.getMeta = jest.fn().mockReturnValue(mockAmplifyMeta); - await run(mockContext); - expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + const service = ServiceName.PlaceIndex; + mockContext.amplify.serviceSelectionPrompt = jest.fn().mockImplementation(async () => { + return { service: service, providerName: provider }; }); + + await run(mockContext); + expect(mockUpdateResource).toHaveBeenCalledWith(mockContext, service); + }); }); diff --git a/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/mapStack.test.ts.snap b/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/mapStack.test.ts.snap index d099e720af6..749c0375744 100644 --- a/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/mapStack.test.ts.snap +++ b/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/mapStack.test.ts.snap @@ -121,63 +121,63 @@ Object { "ZipFile": "const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - let params = { - MapName: event.ResourceProperties.mapName, - Configuration: { - Style: event.ResourceProperties.mapStyle - }, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createMap(params).promise(); - console.log(\\"create resource response data\\" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + let params = { + MapName: event.ResourceProperties.mapName, + Configuration: { + Style: event.ResourceProperties.mapStyle, + }, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createMap(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } - } - if (event.RequestType == 'Update') { - let params = { - MapName: event.ResourceProperties.mapName, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updateMap(params).promise(); - console.log(\\"update resource response data\\" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + if (event.RequestType == 'Update') { + let params = { + MapName: event.ResourceProperties.mapName, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updateMap(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + let params = { + MapName: event.ResourceProperties.mapName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deleteMap(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.mapName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - let params = { - MapName: event.ResourceProperties.mapName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deleteMap(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.mapName; - console.log(\\"delete resource response data\\" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } ", }, @@ -463,63 +463,63 @@ Object { "ZipFile": "const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - let params = { - MapName: event.ResourceProperties.mapName, - Configuration: { - Style: event.ResourceProperties.mapStyle - }, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createMap(params).promise(); - console.log(\\"create resource response data\\" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + let params = { + MapName: event.ResourceProperties.mapName, + Configuration: { + Style: event.ResourceProperties.mapStyle, + }, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createMap(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } - } - if (event.RequestType == 'Update') { - let params = { - MapName: event.ResourceProperties.mapName, - PricingPlan: event.ResourceProperties.pricingPlan - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updateMap(params).promise(); - console.log(\\"update resource response data\\" + JSON.stringify(res)); - if (res.MapName && res.MapArn) { + if (event.RequestType == 'Update') { + let params = { + MapName: event.ResourceProperties.mapName, + PricingPlan: event.ResourceProperties.pricingPlan, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updateMap(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.MapName && res.MapArn) { event.PhysicalResourceId = res.MapName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + let params = { + MapName: event.ResourceProperties.mapName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deleteMap(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.mapName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - let params = { - MapName: event.ResourceProperties.mapName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deleteMap(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.mapName; - console.log(\\"delete resource response data\\" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } ", }, diff --git a/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/placeIndexStack.test.ts.snap b/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/placeIndexStack.test.ts.snap index 3dbcab3c64c..81899ffacb6 100644 --- a/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/placeIndexStack.test.ts.snap +++ b/packages/amplify-category-geo/src/__tests__/service-stacks/__snapshots__/placeIndexStack.test.ts.snap @@ -122,67 +122,67 @@ Object { "ZipFile": "const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - const params = { - IndexName: event.ResourceProperties.indexName, - DataSource: event.ResourceProperties.dataSource, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse - } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createPlaceIndex(params).promise(); - console.log(\\"create resource response data\\" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + const params = { + IndexName: event.ResourceProperties.indexName, + DataSource: event.ResourceProperties.dataSource, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createPlaceIndex(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); - } - } - if (event.RequestType == 'Update') { - const params = { - IndexName: event.ResourceProperties.indexName, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updatePlaceIndex(params).promise(); - console.log(\\"update resource response data\\" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + } + if (event.RequestType == 'Update') { + const params = { + IndexName: event.ResourceProperties.indexName, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updatePlaceIndex(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + const params = { + IndexName: event.ResourceProperties.indexName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deletePlaceIndex(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.indexName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - const params = { - IndexName: event.ResourceProperties.indexName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deletePlaceIndex(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.indexName; - console.log(\\"delete resource response data\\" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } ", }, @@ -467,67 +467,67 @@ Object { "ZipFile": "const response = require('cfn-response'); const aws = require('aws-sdk'); exports.handler = async (event, context) => { - try { - console.log('REQUEST RECEIVED:' + JSON.stringify(event)); - if (event.RequestType == 'Create') { - const params = { - IndexName: event.ResourceProperties.indexName, - DataSource: event.ResourceProperties.dataSource, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse - } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.createPlaceIndex(params).promise(); - console.log(\\"create resource response data\\" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + try { + console.log('REQUEST RECEIVED:' + JSON.stringify(event)); + if (event.RequestType == 'Create') { + const params = { + IndexName: event.ResourceProperties.indexName, + DataSource: event.ResourceProperties.dataSource, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.createPlaceIndex(params).promise(); + console.log('create resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); - } - } - if (event.RequestType == 'Update') { - const params = { - IndexName: event.ResourceProperties.indexName, - PricingPlan: event.ResourceProperties.pricingPlan, - DataSourceConfiguration: { - IntendedUse: event.ResourceProperties.dataSourceIntendedUse } - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.updatePlaceIndex(params).promise(); - console.log(\\"update resource response data\\" + JSON.stringify(res)); - if (res.IndexName && res.IndexArn) { + } + if (event.RequestType == 'Update') { + const params = { + IndexName: event.ResourceProperties.indexName, + PricingPlan: event.ResourceProperties.pricingPlan, + DataSourceConfiguration: { + IntendedUse: event.ResourceProperties.dataSourceIntendedUse, + }, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.updatePlaceIndex(params).promise(); + console.log('update resource response data' + JSON.stringify(res)); + if (res.IndexName && res.IndexArn) { event.PhysicalResourceId = res.IndexName; await send(event, context, response.SUCCESS, res); - } - else { + } else { await send(event, context, response.FAILED, res); + } } + if (event.RequestType == 'Delete') { + const params = { + IndexName: event.ResourceProperties.indexName, + }; + const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); + const res = await locationClient.deletePlaceIndex(params).promise(); + event.PhysicalResourceId = event.ResourceProperties.indexName; + console.log('delete resource response data' + JSON.stringify(res)); + await send(event, context, response.SUCCESS, res); + } + } catch (err) { + console.log(err.stack); + const res = { Error: err }; + await send(event, context, response.FAILED, res); + throw err; } - if (event.RequestType == 'Delete') { - const params = { - IndexName: event.ResourceProperties.indexName - }; - const locationClient = new aws.Location({ apiVersion: '2020-11-19', region: event.ResourceProperties.region }); - const res = await locationClient.deletePlaceIndex(params).promise(); - event.PhysicalResourceId = event.ResourceProperties.indexName; - console.log(\\"delete resource response data\\" + JSON.stringify(res)); - await send(event, context, response.SUCCESS, res); - } - } catch(err) { - console.log(err.stack); - const res = {Error: err}; - await send(event, context, response.FAILED, res); - throw err; - } }; function send(event, context, status, data) { - return new Promise(() => { response.send(event, context, status, data) }); + return new Promise(() => { + response.send(event, context, status, data); + }); } ", }, diff --git a/packages/amplify-category-geo/src/__tests__/service-stacks/mapStack.test.ts b/packages/amplify-category-geo/src/__tests__/service-stacks/mapStack.test.ts index 4c8f9f44d33..4e71aac97f9 100644 --- a/packages/amplify-category-geo/src/__tests__/service-stacks/mapStack.test.ts +++ b/packages/amplify-category-geo/src/__tests__/service-stacks/mapStack.test.ts @@ -3,33 +3,33 @@ import { MapStack } from '../../service-stacks/mapStack'; import { App } from '@aws-cdk/core'; describe('cdk stack creation for map service', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); + beforeEach(() => { + jest.clearAllMocks(); + }); - it('creates Map policy for Authorized users only access type', async() => { - const stackProps = { - accessType: AccessType.AuthorizedUsers, - RegionMapping: { - 'eu-west-2': { - locationServiceRegion: 'eu-central-1' - } - } - } - const mapStack = new MapStack(new App(), 'MapStack', stackProps); - expect(mapStack.toCloudFormation()).toMatchSnapshot(); - }); + it('creates Map policy for Authorized users only access type', async () => { + const stackProps = { + accessType: AccessType.AuthorizedUsers, + RegionMapping: { + 'eu-west-2': { + locationServiceRegion: 'eu-central-1', + }, + }, + }; + const mapStack = new MapStack(new App(), 'MapStack', stackProps); + expect(mapStack.toCloudFormation()).toMatchSnapshot(); + }); - it('creates Map policy for Authorized and Guest users access type', async() => { - const stackProps = { - accessType: AccessType.AuthorizedAndGuestUsers, - RegionMapping: { - 'eu-west-2': { - locationServiceRegion: 'eu-central-1' - } - } - } - const mapStack = new MapStack(new App(), 'MapStack', stackProps); - expect(mapStack.toCloudFormation()).toMatchSnapshot(); - }); -}); \ No newline at end of file + it('creates Map policy for Authorized and Guest users access type', async () => { + const stackProps = { + accessType: AccessType.AuthorizedAndGuestUsers, + RegionMapping: { + 'eu-west-2': { + locationServiceRegion: 'eu-central-1', + }, + }, + }; + const mapStack = new MapStack(new App(), 'MapStack', stackProps); + expect(mapStack.toCloudFormation()).toMatchSnapshot(); + }); +}); diff --git a/packages/amplify-category-geo/src/__tests__/service-stacks/placeIndexStack.test.ts b/packages/amplify-category-geo/src/__tests__/service-stacks/placeIndexStack.test.ts index f4815078f77..3706386a6aa 100644 --- a/packages/amplify-category-geo/src/__tests__/service-stacks/placeIndexStack.test.ts +++ b/packages/amplify-category-geo/src/__tests__/service-stacks/placeIndexStack.test.ts @@ -3,33 +3,33 @@ import { PlaceIndexStack } from '../../service-stacks/placeIndexStack'; import { App } from '@aws-cdk/core'; describe('cdk stack creation for place index service', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); + beforeEach(() => { + jest.clearAllMocks(); + }); - it('creates place index policy for Authorized users only access type', async() => { - const stackProps = { - accessType: AccessType.AuthorizedUsers, - RegionMapping: { - 'eu-west-2': { - locationServiceRegion: 'eu-central-1' - } - } - } - const mapStack = new PlaceIndexStack(new App(), 'PlaceIndexStack', stackProps); - expect(mapStack.toCloudFormation()).toMatchSnapshot(); - }); + it('creates place index policy for Authorized users only access type', async () => { + const stackProps = { + accessType: AccessType.AuthorizedUsers, + RegionMapping: { + 'eu-west-2': { + locationServiceRegion: 'eu-central-1', + }, + }, + }; + const mapStack = new PlaceIndexStack(new App(), 'PlaceIndexStack', stackProps); + expect(mapStack.toCloudFormation()).toMatchSnapshot(); + }); - it('creates place index policy for Authorized and Guest users access type', async() => { - const stackProps = { - accessType: AccessType.AuthorizedAndGuestUsers, - RegionMapping: { - 'eu-west-2': { - locationServiceRegion: 'eu-central-1' - } - } - } - const mapStack = new PlaceIndexStack(new App(), 'PlaceIndexStack', stackProps); - expect(mapStack.toCloudFormation()).toMatchSnapshot(); - }); -}); \ No newline at end of file + it('creates place index policy for Authorized and Guest users access type', async () => { + const stackProps = { + accessType: AccessType.AuthorizedAndGuestUsers, + RegionMapping: { + 'eu-west-2': { + locationServiceRegion: 'eu-central-1', + }, + }, + }; + const mapStack = new PlaceIndexStack(new App(), 'PlaceIndexStack', stackProps); + expect(mapStack.toCloudFormation()).toMatchSnapshot(); + }); +}); diff --git a/packages/amplify-category-geo/src/commands/geo/add.ts b/packages/amplify-category-geo/src/commands/geo/add.ts index fad2b63c425..b52b04bc184 100644 --- a/packages/amplify-category-geo/src/commands/geo/add.ts +++ b/packages/amplify-category-geo/src/commands/geo/add.ts @@ -7,10 +7,15 @@ import { printer } from 'amplify-prompts'; export const name = 'add'; -export const run = async(context: $TSContext) => { +export const run = async (context: $TSContext) => { const { amplify } = context; try { - const result: {service: string, providerName: string} = await amplify.serviceSelectionPrompt(context, category, supportedServices, chooseServiceMessageAdd); + const result: { service: string; providerName: string } = await amplify.serviceSelectionPrompt( + context, + category, + supportedServices, + chooseServiceMessageAdd, + ); if (result.providerName !== provider) { printer.error(`Provider ${result.providerName} not configured for this category`); @@ -18,7 +23,6 @@ export const run = async(context: $TSContext) => { } return await addResource(context, result.service); - } catch (error: $TSAny) { if (error.message) { printer.error(error.message); diff --git a/packages/amplify-category-geo/src/commands/geo/console.ts b/packages/amplify-category-geo/src/commands/geo/console.ts index 1a1f4a4c411..07b57fabe30 100644 --- a/packages/amplify-category-geo/src/commands/geo/console.ts +++ b/packages/amplify-category-geo/src/commands/geo/console.ts @@ -9,7 +9,7 @@ export const name = 'console'; export const run = async (context: $TSContext) => { const { amplify } = context; - const result: {service: string, providerName: string} = await amplify.serviceSelectionPrompt(context, category, supportedServices); + const result: { service: string; providerName: string } = await amplify.serviceSelectionPrompt(context, category, supportedServices); if (result.providerName !== provider) { printer.error(`Provider ${result.providerName} not configured for this category`); diff --git a/packages/amplify-category-geo/src/commands/geo/update.ts b/packages/amplify-category-geo/src/commands/geo/update.ts index c1a4ad3eb72..bd5161453c7 100644 --- a/packages/amplify-category-geo/src/commands/geo/update.ts +++ b/packages/amplify-category-geo/src/commands/geo/update.ts @@ -7,10 +7,15 @@ import { printer } from 'amplify-prompts'; export const name = 'update'; -export const run = async(context: $TSContext) => { +export const run = async (context: $TSContext) => { const { amplify } = context; try { - const result: {service: string, providerName: string} = await amplify.serviceSelectionPrompt(context, category, supportedServices, chooseServiceMessageUpdate); + const result: { service: string; providerName: string } = await amplify.serviceSelectionPrompt( + context, + category, + supportedServices, + chooseServiceMessageUpdate, + ); if (result.providerName !== provider) { printer.error(`Provider ${result.providerName} not configured for this category`); @@ -18,8 +23,7 @@ export const run = async(context: $TSContext) => { } return await updateResource(context, result.service); - - } catch (error:$TSAny) { + } catch (error: $TSAny) { if (error.message) { printer.error(error.message); } diff --git a/packages/amplify-category-geo/src/index.ts b/packages/amplify-category-geo/src/index.ts index 117aad71798..770377a1413 100644 --- a/packages/amplify-category-geo/src/index.ts +++ b/packages/amplify-category-geo/src/index.ts @@ -10,26 +10,26 @@ import { ServiceName } from './service-utils/constants'; import { printer } from 'amplify-prompts'; export const executeAmplifyCommand = async (context: $TSContext) => { - switch(context.input.command) { - case 'add': - await addCommand.run(context); - break; - case 'update': - await updateCommand.run(context); - break; - case 'remove': - await removeCommand.run(context); - break; - case 'console': - await consoleCommand.run(context); - break; - case 'help': - await helpCommand.run(context); - break; - default: - printer.error(`The subcommand ${context.input.command} is not supported for ${category} category`); - break; - } + switch (context.input.command) { + case 'add': + await addCommand.run(context); + break; + case 'update': + await updateCommand.run(context); + break; + case 'remove': + await removeCommand.run(context); + break; + case 'console': + await consoleCommand.run(context); + break; + case 'help': + await helpCommand.run(context); + break; + default: + printer.error(`The subcommand ${context.input.command} is not supported for ${category} category`); + break; + } }; export const handleAmplifyEvent = async (context: $TSContext, args: $TSAny) => { @@ -38,31 +38,26 @@ export const handleAmplifyEvent = async (context: $TSContext, args: $TSAny) => { }; export const getPermissionPolicies = (context: $TSContext, resourceOpsMapping: $TSObject) => { - const amplifyMeta = stateManager.getMeta()?.[category]; - const permissionPolicies: $TSObject[] = []; - const resourceAttributes: $TSObject[] = []; + const amplifyMeta = stateManager.getMeta()?.[category]; + const permissionPolicies: $TSObject[] = []; + const resourceAttributes: $TSObject[] = []; - Object.keys(resourceOpsMapping).forEach(resourceName => { - try { - const service: ServiceName = amplifyMeta[resourceName].service as ServiceName; + Object.keys(resourceOpsMapping).forEach(resourceName => { + try { + const service: ServiceName = amplifyMeta[resourceName].service as ServiceName; - const { policy, attributes } = getServicePermissionPolicies( - context, - service, - resourceName, - resourceOpsMapping[resourceName], - ); - if (Array.isArray(policy)) { - permissionPolicies.push(...policy); - } else { - permissionPolicies.push(policy); - } - resourceAttributes.push({ resourceName, attributes, category }); - } catch (e) { - printer.error(`Could not get policies for ${category}: ${resourceName}`); - throw e; + const { policy, attributes } = getServicePermissionPolicies(context, service, resourceName, resourceOpsMapping[resourceName]); + if (Array.isArray(policy)) { + permissionPolicies.push(...policy); + } else { + permissionPolicies.push(policy); } - }); + resourceAttributes.push({ resourceName, attributes, category }); + } catch (e) { + printer.error(`Could not get policies for ${category}: ${resourceName}`); + throw e; + } + }); - return { permissionPolicies, resourceAttributes }; -} + return { permissionPolicies, resourceAttributes }; +}; diff --git a/packages/amplify-category-geo/src/provider-controllers/index.ts b/packages/amplify-category-geo/src/provider-controllers/index.ts index 553780dca92..965db65ef9a 100644 --- a/packages/amplify-category-geo/src/provider-controllers/index.ts +++ b/packages/amplify-category-geo/src/provider-controllers/index.ts @@ -11,19 +11,11 @@ import { TemplateMappings } from '../service-stacks/baseStack'; /** * Entry point for creating a new Geo resource */ -export const addResource = async ( - context: $TSContext, - service: string -): Promise => { - if(!projectHasAuth()) { - if ( - await prompter.yesOrNo( - 'geo category resources require auth (Amazon Cognito). Do you want to add auth now?', - ) - ){ +export const addResource = async (context: $TSContext, service: string): Promise => { + if (!projectHasAuth()) { + if (await prompter.yesOrNo('geo category resources require auth (Amazon Cognito). Do you want to add auth now?')) { await context.amplify.invokePluginMethod(context, 'auth', undefined, 'add', [context]); - } - else { + } else { printer.info('Please add auth (Amazon Cognito) to your project using "amplify add auth"'); return; } @@ -42,10 +34,7 @@ export const addResource = async ( /** * Entry point for updating existing Geo resource */ -export const updateResource = async ( - context: $TSContext, - service: string -): Promise => { +export const updateResource = async (context: $TSContext, service: string): Promise => { switch (service) { case ServiceName.Map: return updateMapResource(context); @@ -59,10 +48,7 @@ export const updateResource = async ( /** * Entry point for removing existing Geo resource */ -export const removeResource = async ( - context: $TSContext, - service: string -): Promise => { +export const removeResource = async (context: $TSContext, service: string): Promise => { switch (service) { case ServiceName.Map: return removeMapResource(context); @@ -73,9 +59,8 @@ export const removeResource = async ( } }; -export const projectHasAuth = () => !!Object.values( - stateManager.getMeta()?.auth || {} -).find(meta => (meta as $TSObject)?.service === 'Cognito'); +export const projectHasAuth = () => + !!Object.values(stateManager.getMeta()?.auth || {}).find(meta => (meta as $TSObject)?.service === 'Cognito'); export const printNextStepsSuccessMessage = (context: $TSContext) => { printer.blankLine(); @@ -100,10 +85,10 @@ export const openConsole = (service: string) => { let selection: string | undefined; switch (service) { case ServiceName.Map: - selection = "maps"; + selection = 'maps'; break; case ServiceName.PlaceIndex: - selection = "places"; + selection = 'places'; break; default: selection = undefined; @@ -117,15 +102,15 @@ export const openConsole = (service: string) => { const badServiceError = (service: string) => { return new Error(`amplify-category-geo is not configured to provide service type ${service}`); -} +}; export const insufficientInfoForUpdateError = (service: ServiceName) => { new Error(`Insufficient information to update ${getServiceFriendlyName(service)}. Please re-try and provide all inputs.`); -} +}; export const getTemplateMappings = async (context: $TSContext): Promise => { const Mappings: TemplateMappings = { - RegionMapping: {} + RegionMapping: {}, }; const providerPlugins = context.amplify.getProviderPlugins(context); const providerPlugin = await import(providerPlugins[provider]); diff --git a/packages/amplify-category-geo/src/service-stacks/baseStack.ts b/packages/amplify-category-geo/src/service-stacks/baseStack.ts index 6ce52a5dfac..53026628191 100644 --- a/packages/amplify-category-geo/src/service-stacks/baseStack.ts +++ b/packages/amplify-category-geo/src/service-stacks/baseStack.ts @@ -3,35 +3,35 @@ import { prepareApp } from '@aws-cdk/core/lib/private/prepare-app'; import { $TSObject } from 'amplify-cli-core'; export type TemplateMappings = { - RegionMapping: $TSObject + RegionMapping: $TSObject; }; export class BaseStack extends cdk.Stack { - protected parameters: Map; - protected regionMapping: cdk.CfnMapping; + protected parameters: Map; + protected regionMapping: cdk.CfnMapping; - constructor(scope: cdk.Construct, id: string, props:TemplateMappings) { - super(scope, id); - this.parameters = new Map(); + constructor(scope: cdk.Construct, id: string, props: TemplateMappings) { + super(scope, id); + this.parameters = new Map(); - this.regionMapping = new cdk.CfnMapping(this, 'RegionMapping', { - mapping: props.RegionMapping - }); - } + this.regionMapping = new cdk.CfnMapping(this, 'RegionMapping', { + mapping: props.RegionMapping, + }); + } - // construct the stack CFN input parameters - constructInputParameters(parameterNames: Array): Map { - let parametersMap: Map = new Map(); - parameterNames.forEach(parameterName => { - const inputParameter = new cdk.CfnParameter(this, parameterName, { type: 'String' }) - parametersMap.set(parameterName, inputParameter); - }); - return parametersMap; - } + // construct the stack CFN input parameters + constructInputParameters(parameterNames: Array): Map { + let parametersMap: Map = new Map(); + parameterNames.forEach(parameterName => { + const inputParameter = new cdk.CfnParameter(this, parameterName, { type: 'String' }); + parametersMap.set(parameterName, inputParameter); + }); + return parametersMap; + } - toCloudFormation() { - prepareApp(this); - const cfn = this._toCloudFormation(); - return cfn; - } + toCloudFormation() { + prepareApp(this); + const cfn = this._toCloudFormation(); + return cfn; + } } diff --git a/packages/amplify-category-geo/src/service-stacks/mapStack.ts b/packages/amplify-category-geo/src/service-stacks/mapStack.ts index 5cc39cb9409..9825d052789 100644 --- a/packages/amplify-category-geo/src/service-stacks/mapStack.ts +++ b/packages/amplify-category-geo/src/service-stacks/mapStack.ts @@ -13,126 +13,118 @@ import * as fs from 'fs-extra'; type MapStackProps = Pick & TemplateMappings; export class MapStack extends BaseStack { - protected readonly accessType: string; - protected readonly mapResource: cdk.CustomResource; - protected readonly mapRegion: string - protected readonly mapName: string - - constructor(scope: cdk.Construct, id: string, private readonly props: MapStackProps) { - super(scope, id, props); - - this.accessType = this.props.accessType; - this.mapRegion = this.regionMapping.findInMap(cdk.Fn.ref('AWS::Region'), 'locationServiceRegion'); - - this.parameters = this.constructInputParameters([ - 'authRoleName', - 'unauthRoleName', - 'mapName', - 'mapStyle', - 'pricingPlan', - 'env', - 'isDefault' - ]); - - this.mapName = Fn.join('-', [ - this.parameters.get('mapName')!.valueAsString, - this.parameters.get('env')!.valueAsString - ]); - this.mapResource = this.constructMapResource(); - this.constructMapPolicyResource(this.mapResource); - this.constructOutputs(); + protected readonly accessType: string; + protected readonly mapResource: cdk.CustomResource; + protected readonly mapRegion: string; + protected readonly mapName: string; + + constructor(scope: cdk.Construct, id: string, private readonly props: MapStackProps) { + super(scope, id, props); + + this.accessType = this.props.accessType; + this.mapRegion = this.regionMapping.findInMap(cdk.Fn.ref('AWS::Region'), 'locationServiceRegion'); + + this.parameters = this.constructInputParameters([ + 'authRoleName', + 'unauthRoleName', + 'mapName', + 'mapStyle', + 'pricingPlan', + 'env', + 'isDefault', + ]); + + this.mapName = Fn.join('-', [this.parameters.get('mapName')!.valueAsString, this.parameters.get('env')!.valueAsString]); + this.mapResource = this.constructMapResource(); + this.constructMapPolicyResource(this.mapResource); + this.constructOutputs(); + } + + private constructOutputs() { + new cdk.CfnOutput(this, 'Name', { + value: this.mapResource.getAtt('MapName').toString(), + }); + new cdk.CfnOutput(this, 'Style', { + value: this.parameters.get('mapStyle')!.valueAsString, + }); + new cdk.CfnOutput(this, 'Region', { + value: this.mapRegion, + }); + new cdk.CfnOutput(this, 'Arn', { + value: this.mapResource.getAtt('MapArn').toString(), + }); + } + + private constructMapResource(): cdk.CustomResource { + const geoCreateMapStatement = new iam.PolicyStatement({ + effect: Effect.ALLOW, + }); + geoCreateMapStatement.addActions('geo:CreateMap'); + geoCreateMapStatement.addAllResources(); + + const mapARN = cdk.Fn.sub('arn:aws:geo:${region}:${account}:map/${mapName}', { + region: this.mapRegion, + account: cdk.Fn.ref('AWS::AccountId'), + mapName: this.mapName, + }); + + const geoUpdateDeleteMapStatement = new iam.PolicyStatement({ + effect: Effect.ALLOW, + }); + geoUpdateDeleteMapStatement.addActions('geo:UpdateMap', 'geo:DeleteMap'); + geoUpdateDeleteMapStatement.addResources(mapARN); + + const mapStyle = this.parameters.get('mapStyle')!.valueAsString; + + const mapPricingPlan = this.parameters.get('pricingPlan')!.valueAsString; + + const customMapLambdaCode = fs.readFileSync(customMapLambdaCodePath, 'utf-8'); + const customMapLambda = new lambda.Function(this, 'CustomMapLambda', { + code: lambda.Code.fromInline(customMapLambdaCode), + handler: 'index.handler', + runtime: Runtime.NODEJS_14_X, + timeout: Duration.seconds(300), + }); + customMapLambda.addToRolePolicy(geoCreateMapStatement); + customMapLambda.addToRolePolicy(geoUpdateDeleteMapStatement); + + const mapCustomResource = new cdk.CustomResource(this, 'CustomMap', { + serviceToken: customMapLambda.functionArn, + resourceType: 'Custom::LambdaCallout', + properties: { + mapName: this.mapName, + mapStyle: mapStyle, + pricingPlan: mapPricingPlan, + region: this.mapRegion, + env: cdk.Fn.ref('env'), + }, + }); + + return mapCustomResource; + } + + // Grant read-only access to the Map for Authorized and/or Guest users + private constructMapPolicyResource(mapResource: cdk.CustomResource): CfnResource { + let policy = new iam.PolicyDocument({ + statements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['geo:GetMapStyleDescriptor', 'geo:GetMapGlyphs', 'geo:GetMapSprites', 'geo:GetMapTile'], + resources: [mapResource.getAtt('MapArn').toString()], + }), + ], + }); + + let cognitoRoles: Array = new Array(); + cognitoRoles.push(this.parameters.get('authRoleName')!.valueAsString); + if (this.accessType == AccessType.AuthorizedAndGuestUsers) { + cognitoRoles.push(this.parameters.get('unauthRoleName')!.valueAsString); } - private constructOutputs() { - new cdk.CfnOutput(this, 'Name', { - value: this.mapResource.getAtt('MapName').toString() - }); - new cdk.CfnOutput(this, 'Style', { - value: this.parameters.get('mapStyle')!.valueAsString - }); - new cdk.CfnOutput(this, 'Region', { - value: this.mapRegion - }); - new cdk.CfnOutput(this, 'Arn', { - value: this.mapResource.getAtt('MapArn').toString() - }); - } - - private constructMapResource(): cdk.CustomResource { - const geoCreateMapStatement = new iam.PolicyStatement({ - effect: Effect.ALLOW - }); - geoCreateMapStatement.addActions('geo:CreateMap'); - geoCreateMapStatement.addAllResources(); - - const mapARN = cdk.Fn.sub('arn:aws:geo:${region}:${account}:map/${mapName}', { - region: this.mapRegion, - account: cdk.Fn.ref('AWS::AccountId'), - mapName: this.mapName - }); - - const geoUpdateDeleteMapStatement = new iam.PolicyStatement({ - effect: Effect.ALLOW - }); - geoUpdateDeleteMapStatement.addActions('geo:UpdateMap', 'geo:DeleteMap'); - geoUpdateDeleteMapStatement.addResources(mapARN); - - const mapStyle = this.parameters.get('mapStyle')!.valueAsString; - - const mapPricingPlan = this.parameters.get('pricingPlan')!.valueAsString; - - const customMapLambdaCode = fs.readFileSync(customMapLambdaCodePath, 'utf-8'); - const customMapLambda = new lambda.Function(this, 'CustomMapLambda', { - code: lambda.Code.fromInline(customMapLambdaCode), - handler: 'index.handler', - runtime: Runtime.NODEJS_14_X, - timeout: Duration.seconds(300) - }); - customMapLambda.addToRolePolicy(geoCreateMapStatement); - customMapLambda.addToRolePolicy(geoUpdateDeleteMapStatement); - - const mapCustomResource = new cdk.CustomResource(this, 'CustomMap', { - serviceToken: customMapLambda.functionArn, - resourceType: 'Custom::LambdaCallout', - properties: { - mapName: this.mapName, - mapStyle: mapStyle, - pricingPlan: mapPricingPlan, - region: this.mapRegion, - env: cdk.Fn.ref('env'), - }, - }); - - return mapCustomResource; - } - - // Grant read-only access to the Map for Authorized and/or Guest users - private constructMapPolicyResource(mapResource: cdk.CustomResource): CfnResource { - let policy = new iam.PolicyDocument({ - statements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: [ - "geo:GetMapStyleDescriptor", - "geo:GetMapGlyphs", - "geo:GetMapSprites", - "geo:GetMapTile" - ], - resources: [mapResource.getAtt('MapArn').toString()], - }) - ], - }); - - let cognitoRoles: Array = new Array(); - cognitoRoles.push(this.parameters.get('authRoleName')!.valueAsString); - if (this.accessType == AccessType.AuthorizedAndGuestUsers) { - cognitoRoles.push(this.parameters.get('unauthRoleName')!.valueAsString); - } - - return new iam.CfnPolicy(this, 'MapPolicy', { - policyName: `${this.mapName}Policy`, - roles: cognitoRoles, - policyDocument: policy - }); - } + return new iam.CfnPolicy(this, 'MapPolicy', { + policyName: `${this.mapName}Policy`, + roles: cognitoRoles, + policyDocument: policy, + }); + } } diff --git a/packages/amplify-category-geo/src/service-stacks/placeIndexStack.ts b/packages/amplify-category-geo/src/service-stacks/placeIndexStack.ts index 70dc8d57c5d..eeb4da381c8 100644 --- a/packages/amplify-category-geo/src/service-stacks/placeIndexStack.ts +++ b/packages/amplify-category-geo/src/service-stacks/placeIndexStack.ts @@ -15,8 +15,8 @@ type PlaceIndexStackProps = Pick & TemplateM export class PlaceIndexStack extends BaseStack { protected readonly accessType: string; protected readonly placeIndexResource: cdk.CustomResource; - protected readonly placeIndexRegion: string - protected readonly placeIndexName: string + protected readonly placeIndexRegion: string; + protected readonly placeIndexName: string; constructor(scope: cdk.Construct, id: string, private readonly props: PlaceIndexStackProps) { super(scope, id, props); @@ -32,13 +32,10 @@ export class PlaceIndexStack extends BaseStack { 'dataSourceIntendedUse', 'pricingPlan', 'env', - 'isDefault' + 'isDefault', ]); - this.placeIndexName = Fn.join('-', [ - this.parameters.get('indexName')!.valueAsString, - this.parameters.get('env')!.valueAsString - ]); + this.placeIndexName = Fn.join('-', [this.parameters.get('indexName')!.valueAsString, this.parameters.get('env')!.valueAsString]); this.placeIndexResource = this.constructIndexResource(); this.constructIndexPolicyResource(this.placeIndexResource); @@ -47,19 +44,19 @@ export class PlaceIndexStack extends BaseStack { private constructOutputs() { new cdk.CfnOutput(this, 'Name', { - value: this.placeIndexResource.getAtt('IndexName').toString() + value: this.placeIndexResource.getAtt('IndexName').toString(), }); new cdk.CfnOutput(this, 'Region', { - value: this.placeIndexRegion + value: this.placeIndexRegion, }); new cdk.CfnOutput(this, 'Arn', { - value: this.placeIndexResource.getAtt('IndexArn').toString() + value: this.placeIndexResource.getAtt('IndexArn').toString(), }); } private constructIndexResource(): cdk.CustomResource { const geoCreateIndexStatement = new iam.PolicyStatement({ - effect: Effect.ALLOW + effect: Effect.ALLOW, }); geoCreateIndexStatement.addActions('geo:CreatePlaceIndex'); geoCreateIndexStatement.addAllResources(); @@ -67,11 +64,11 @@ export class PlaceIndexStack extends BaseStack { const placeIndexARN = cdk.Fn.sub('arn:aws:geo:${region}:${account}:place-index/${indexName}', { region: this.placeIndexRegion, account: cdk.Fn.ref('AWS::AccountId'), - indexName: this.placeIndexName + indexName: this.placeIndexName, }); const geoUpdateDeleteIndexStatement = new iam.PolicyStatement({ - effect: Effect.ALLOW + effect: Effect.ALLOW, }); geoUpdateDeleteIndexStatement.addActions('geo:UpdatePlaceIndex', 'geo:DeletePlaceIndex'); geoUpdateDeleteIndexStatement.addResources(placeIndexARN); @@ -87,7 +84,7 @@ export class PlaceIndexStack extends BaseStack { code: lambda.Code.fromInline(customPlaceIndexLambdaCode), handler: 'index.handler', runtime: Runtime.NODEJS_14_X, - timeout: Duration.seconds(300) + timeout: Duration.seconds(300), }); customPlaceIndexLambda.addToRolePolicy(geoCreateIndexStatement); customPlaceIndexLambda.addToRolePolicy(geoUpdateDeleteIndexStatement); @@ -102,7 +99,7 @@ export class PlaceIndexStack extends BaseStack { pricingPlan: indexPricingPlan, region: this.placeIndexRegion, env: cdk.Fn.ref('env'), - } + }, }); return placeIndexCustomResource; @@ -111,28 +108,25 @@ export class PlaceIndexStack extends BaseStack { // Grant read-only access to the Place Index for Authorized and/or Guest users private constructIndexPolicyResource(indexResource: cdk.CustomResource): CfnResource { let policy = new iam.PolicyDocument({ - statements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: [ - "geo:SearchPlaceIndexForPosition", - "geo:SearchPlaceIndexForText" - ], - resources: [indexResource.getAtt('IndexArn').toString()], - }) - ], + statements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['geo:SearchPlaceIndexForPosition', 'geo:SearchPlaceIndexForText'], + resources: [indexResource.getAtt('IndexArn').toString()], + }), + ], }); let cognitoRoles: Array = new Array(); cognitoRoles.push(this.parameters.get('authRoleName')!.valueAsString); if (this.accessType == AccessType.AuthorizedAndGuestUsers) { - cognitoRoles.push(this.parameters.get('unauthRoleName')!.valueAsString); + cognitoRoles.push(this.parameters.get('unauthRoleName')!.valueAsString); } return new iam.CfnPolicy(this, 'PlaceIndexPolicy', { - policyName: `${this.placeIndexName}Policy`, - roles: cognitoRoles, - policyDocument: policy + policyName: `${this.placeIndexName}Policy`, + roles: cognitoRoles, + policyDocument: policy, }); } } diff --git a/packages/amplify-category-geo/src/service-utils/constants.ts b/packages/amplify-category-geo/src/service-utils/constants.ts index 5be5540ad83..778077ed4a7 100644 --- a/packages/amplify-category-geo/src/service-utils/constants.ts +++ b/packages/amplify-category-geo/src/service-utils/constants.ts @@ -1,10 +1,10 @@ import * as path from 'path'; export const apiDocs = { - mapStyles: "https://docs.aws.amazon.com/location-maps/latest/APIReference/API_MapConfiguration.html", - pricingPlan: "https://aws.amazon.com/location/pricing/", - dataSourceUsage: "https://docs.aws.amazon.com/location-places/latest/APIReference/API_DataSourceConfiguration.html" -} + mapStyles: 'https://docs.aws.amazon.com/location-maps/latest/APIReference/API_MapConfiguration.html', + pricingPlan: 'https://aws.amazon.com/location/pricing/', + dataSourceUsage: 'https://docs.aws.amazon.com/location-places/latest/APIReference/API_DataSourceConfiguration.html', +}; export const previewBanner = 'Amplify Geo category is in developer preview and not intended for production use at this time.'; export const chooseServiceMessageAdd = 'Select which capability you want to add:'; @@ -20,5 +20,5 @@ export enum ServiceName { Map = 'Map', PlaceIndex = 'PlaceIndex', GeofenceCollection = 'GeofenceCollection', - Tracker = 'Tracker' + Tracker = 'Tracker', } diff --git a/packages/amplify-category-geo/src/service-utils/mapUtils.ts b/packages/amplify-category-geo/src/service-utils/mapUtils.ts index 46b47818bdb..85ff0f91a03 100644 --- a/packages/amplify-category-geo/src/service-utils/mapUtils.ts +++ b/packages/amplify-category-geo/src/service-utils/mapUtils.ts @@ -4,7 +4,14 @@ import _ from 'lodash'; import { parametersFileName, provider, ServiceName } from './constants'; import { category } from '../constants'; import { MapStack } from '../service-stacks/mapStack'; -import { updateParametersFile, getGeoServiceMeta, generateTemplateFile, updateDefaultResource, readResourceMetaParameters, checkAuthConfig } from './resourceUtils'; +import { + updateParametersFile, + getGeoServiceMeta, + generateTemplateFile, + updateDefaultResource, + readResourceMetaParameters, + checkAuthConfig, +} from './resourceUtils'; import { App } from '@aws-cdk/core'; import { getTemplateMappings } from '../provider-controllers'; @@ -26,57 +33,43 @@ export const createMapResource = async (context: $TSContext, parameters: MapPara await updateDefaultResource(context, ServiceName.Map); } - context.amplify.updateamplifyMetaAfterResourceAdd( - category, - parameters.name, - mapMetaParameters - ); + context.amplify.updateamplifyMetaAfterResourceAdd(category, parameters.name, mapMetaParameters); }; -export const modifyMapResource = async ( - context: $TSContext, - parameters: Pick - ) => { +export const modifyMapResource = async (context: $TSContext, parameters: Pick) => { // allow unauth access for identity pool if guest access is enabled await checkAuthConfig(context, parameters, ServiceName.Map); // generate CFN files const templateMappings = await getTemplateMappings(context); - const mapStack = new MapStack(new App(), 'MapStack', { ...parameters, ...templateMappings}); + const mapStack = new MapStack(new App(), 'MapStack', { ...parameters, ...templateMappings }); generateTemplateFile(mapStack, parameters.name); // update the default map if (parameters.isDefault) { - await updateDefaultResource(context, ServiceName.Map , parameters.name); + await updateDefaultResource(context, ServiceName.Map, parameters.name); } const paramsToUpdate = ['accessType']; paramsToUpdate.forEach(param => { - context.amplify.updateamplifyMetaAfterResourceUpdate( - category, - parameters.name, - param, - (parameters as $TSObject)[param] - ); + context.amplify.updateamplifyMetaAfterResourceUpdate(category, parameters.name, param, (parameters as $TSObject)[param]); }); }; -function saveCFNParameters( - parameters: Pick -) { - const params = { - authRoleName: { - "Ref": "AuthRoleName" - }, - unauthRoleName: { - "Ref": "UnauthRoleName" - }, - mapName: parameters.name, - mapStyle: getGeoMapStyle(parameters.dataProvider, parameters.mapStyleType), - pricingPlan: parameters.pricingPlan, - isDefault: parameters.isDefault - }; - updateParametersFile(params, parameters.name, parametersFileName); +function saveCFNParameters(parameters: Pick) { + const params = { + authRoleName: { + Ref: 'AuthRoleName', + }, + unauthRoleName: { + Ref: 'UnauthRoleName', + }, + mapName: parameters.name, + mapStyle: getGeoMapStyle(parameters.dataProvider, parameters.mapStyleType), + pricingPlan: parameters.pricingPlan, + isDefault: parameters.isDefault, + }; + updateParametersFile(params, parameters.name, parametersFileName); } /** @@ -89,7 +82,7 @@ export const constructMapMetaParameters = (params: MapParameters): MapMetaParame service: ServiceName.Map, mapStyle: getGeoMapStyle(params.dataProvider, params.mapStyleType), pricingPlan: params.pricingPlan, - accessType: params.accessType + accessType: params.accessType, }; return result; }; @@ -101,16 +94,16 @@ export type MapMetaParameters = Pick> => { - const currentMapMetaParameters = await readResourceMetaParameters(ServiceName.Map, mapName) as MapMetaParameters; + const currentMapMetaParameters = (await readResourceMetaParameters(ServiceName.Map, mapName)) as MapMetaParameters; return { mapStyleType: getMapStyleComponents(currentMapMetaParameters.mapStyle).mapStyleType, dataProvider: getMapStyleComponents(currentMapMetaParameters.mapStyle).dataProvider, pricingPlan: currentMapMetaParameters.pricingPlan, accessType: currentMapMetaParameters.accessType, - isDefault: currentMapMetaParameters.isDefault + isDefault: currentMapMetaParameters.isDefault, }; }; @@ -127,10 +120,7 @@ export const getMapFriendlyNames = async (mapNames: string[]): Promise }); }; -export const getMapIamPolicies = ( - resourceName: string, - crudOptions: string[] -): { policy: $TSObject[], attributes: string[] } => { +export const getMapIamPolicies = (resourceName: string, crudOptions: string[]): { policy: $TSObject[]; attributes: string[] } => { const policy = []; const actions = new Set(); @@ -169,7 +159,7 @@ export const getMapIamPolicies = ( ':map/', { Ref: `${category}${resourceName}Name`, - } + }, ], ], }, @@ -179,4 +169,4 @@ export const getMapIamPolicies = ( const attributes = ['Name']; return { policy, attributes }; -} +}; diff --git a/packages/amplify-category-geo/src/service-utils/placeIndexUtils.ts b/packages/amplify-category-geo/src/service-utils/placeIndexUtils.ts index e2154b3b24f..6761594e9cd 100644 --- a/packages/amplify-category-geo/src/service-utils/placeIndexUtils.ts +++ b/packages/amplify-category-geo/src/service-utils/placeIndexUtils.ts @@ -4,7 +4,13 @@ import _ from 'lodash'; import { parametersFileName, provider, ServiceName } from './constants'; import { category } from '../constants'; import { PlaceIndexStack } from '../service-stacks/placeIndexStack'; -import { updateParametersFile, generateTemplateFile, updateDefaultResource, readResourceMetaParameters, checkAuthConfig } from './resourceUtils'; +import { + updateParametersFile, + generateTemplateFile, + updateDefaultResource, + readResourceMetaParameters, + checkAuthConfig, +} from './resourceUtils'; import { App } from '@aws-cdk/core'; import { getTemplateMappings } from '../provider-controllers'; @@ -26,17 +32,13 @@ export const createPlaceIndexResource = async (context: $TSContext, parameters: await updateDefaultResource(context, ServiceName.PlaceIndex); } - context.amplify.updateamplifyMetaAfterResourceAdd( - category, - parameters.name, - placeIndexMetaParameters - ); + context.amplify.updateamplifyMetaAfterResourceAdd(category, parameters.name, placeIndexMetaParameters); }; export const modifyPlaceIndexResource = async ( context: $TSContext, - parameters: Pick - ) => { + parameters: Pick, +) => { // allow unauth access for identity pool if guest access is enabled await checkAuthConfig(context, parameters, ServiceName.PlaceIndex); @@ -47,37 +49,32 @@ export const modifyPlaceIndexResource = async ( // update the default place index if (parameters.isDefault) { - await updateDefaultResource(context, ServiceName.PlaceIndex , parameters.name); + await updateDefaultResource(context, ServiceName.PlaceIndex, parameters.name); } const paramsToUpdate = ['accessType']; paramsToUpdate.forEach(param => { - context.amplify.updateamplifyMetaAfterResourceUpdate( - category, - parameters.name, - param, - (parameters as $TSObject)[param] - ); + context.amplify.updateamplifyMetaAfterResourceUpdate(category, parameters.name, param, (parameters as $TSObject)[param]); }); }; function saveCFNParameters( - parameters: Pick + parameters: Pick, ) { - const params = { - authRoleName: { - "Ref": "AuthRoleName" - }, - unauthRoleName: { - "Ref": "UnauthRoleName" - }, - indexName: parameters.name, - dataProvider: parameters.dataProvider, - dataSourceIntendedUse: parameters.dataSourceIntendedUse, - pricingPlan: parameters.pricingPlan, - isDefault: parameters.isDefault - }; - updateParametersFile(params, parameters.name, parametersFileName); + const params = { + authRoleName: { + Ref: 'AuthRoleName', + }, + unauthRoleName: { + Ref: 'UnauthRoleName', + }, + indexName: parameters.name, + dataProvider: parameters.dataProvider, + dataSourceIntendedUse: parameters.dataSourceIntendedUse, + pricingPlan: parameters.pricingPlan, + isDefault: parameters.isDefault, + }; + updateParametersFile(params, parameters.name, parametersFileName); } /** @@ -91,7 +88,7 @@ export const constructPlaceIndexMetaParameters = (params: PlaceIndexParameters): dataProvider: params.dataProvider, dataSourceIntendedUse: params.dataSourceIntendedUse, pricingPlan: params.pricingPlan, - accessType: params.accessType + accessType: params.accessType, }; return result; }; @@ -99,28 +96,26 @@ export const constructPlaceIndexMetaParameters = (params: PlaceIndexParameters): /** * The Meta information stored for a Place Index Resource */ -export type PlaceIndexMetaParameters = Pick & { +export type PlaceIndexMetaParameters = Pick< + PlaceIndexParameters, + 'isDefault' | 'pricingPlan' | 'accessType' | 'dataSourceIntendedUse' | 'dataProvider' +> & { providerPlugin: string; service: string; -} +}; export const getCurrentPlaceIndexParameters = async (indexName: string): Promise> => { - const currentIndexMetaParameters = await readResourceMetaParameters(ServiceName.PlaceIndex, indexName) as PlaceIndexMetaParameters; + const currentIndexMetaParameters = (await readResourceMetaParameters(ServiceName.PlaceIndex, indexName)) as PlaceIndexMetaParameters; return { dataProvider: currentIndexMetaParameters.dataProvider, dataSourceIntendedUse: currentIndexMetaParameters.dataSourceIntendedUse, pricingPlan: currentIndexMetaParameters.pricingPlan, accessType: currentIndexMetaParameters.accessType, - isDefault: currentIndexMetaParameters.isDefault + isDefault: currentIndexMetaParameters.isDefault, }; }; -export const getPlaceIndexIamPolicies = ( - resourceName: string, - crudOptions: string[] -): { policy: $TSObject[], attributes: string[] } => { +export const getPlaceIndexIamPolicies = (resourceName: string, crudOptions: string[]): { policy: $TSObject[]; attributes: string[] } => { const policy = []; const actions = new Set(); @@ -157,7 +152,7 @@ export const getPlaceIndexIamPolicies = ( ':place-index/', { Ref: `${category}${resourceName}Name`, - } + }, ], ], }, @@ -167,4 +162,4 @@ export const getPlaceIndexIamPolicies = ( const attributes = ['Name']; return { policy, attributes }; -} +}; diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts index ce21fb37a25..a0f0885e00f 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/push-resources.ts @@ -4,7 +4,14 @@ import { onCategoryOutputsChange } from './on-category-outputs-change'; import { initializeEnv } from '../../initialize-env'; import { getProviderPlugins } from './get-provider-plugins'; import { getEnvInfo } from './get-env-info'; -import { EnvironmentDoesNotExistError, exitOnNextTick, stateManager, $TSAny, $TSContext, CustomPoliciesFormatError } from 'amplify-cli-core'; +import { + EnvironmentDoesNotExistError, + exitOnNextTick, + stateManager, + $TSAny, + $TSContext, + CustomPoliciesFormatError, +} from 'amplify-cli-core'; import { printer } from 'amplify-prompts'; export async function pushResources( @@ -82,7 +89,7 @@ export async function pushResources( if (await isValidGraphQLAuthError(err.message)) { retryPush = await handleValidGraphQLAuthError(context, err.message); } - if(!retryPush) { + if (!retryPush) { // Handle the errors and print them nicely for the user. context.print.error(`\n${err.message}`); throw err; @@ -98,11 +105,14 @@ export async function pushResources( } async function isValidGraphQLAuthError(message: string) { - if (message === `@auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.` - || message === `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.` - || message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.` - || message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.` - || message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.`) { + if ( + message === `@auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.` || + message === + `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.` || + message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.` || + message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.` || + message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.` + ) { return true; } } @@ -112,16 +122,25 @@ async function handleValidGraphQLAuthError(context: $TSContext, message: string) await addGraphQLAuthRequirement(context, 'AWS_IAM'); return true; } else if (!context?.parameters?.options?.yes) { - if (message === `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.`) { + if ( + message === + `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.` + ) { await addGraphQLAuthRequirement(context, 'AMAZON_COGNITO_USER_POOLS'); return true; - } else if (message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.`) { - await addGraphQLAuthRequirement(context, 'OPENID_CONNECT') + } else if ( + message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.` + ) { + await addGraphQLAuthRequirement(context, 'OPENID_CONNECT'); return true; - } else if (message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.`) { + } else if ( + message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.` + ) { await addGraphQLAuthRequirement(context, 'API_KEY'); return true; - } else if (message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.`) { + } else if ( + message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.` + ) { await addGraphQLAuthRequirement(context, 'AWS_LAMBDA'); return true; } diff --git a/packages/amplify-e2e-core/src/asciinema-recorder.ts b/packages/amplify-e2e-core/src/asciinema-recorder.ts index 49b8a908058..3e878077fc5 100644 --- a/packages/amplify-e2e-core/src/asciinema-recorder.ts +++ b/packages/amplify-e2e-core/src/asciinema-recorder.ts @@ -58,7 +58,9 @@ export class Recorder { cols: this.cols, rows: this.rows, cwd: this.cwd, - useConpty: false, + shell: true, + // Do not set useConpty. node-pty is smart enough to set it to true only on versions of Windows that support it. + // useConpty: true, ...this.options, }); this.addFrame(this.renderPrompt(this.cwd, this.cmd, this.args)); diff --git a/packages/amplify-e2e-core/src/categories/api.ts b/packages/amplify-e2e-core/src/categories/api.ts index 66c03980297..5f6089d92c1 100644 --- a/packages/amplify-e2e-core/src/categories/api.ts +++ b/packages/amplify-e2e-core/src/categories/api.ts @@ -94,7 +94,6 @@ export function addApiWithBlankSchema(cwd: string, opts: Partial((resolve, reject) => { let chain = spawn(getCLIPath(defaultOptions.testingWithLatestCodebase), ['add', 'api'], { cwd: projectDir, stripColors: true }) .wait('Please select from one of the below mentioned services:') - .sendCarriageReturn() + .sendCarriageReturn(); if (settings && Object.keys(settings).length > 0) { const authTypesToAdd = Object.keys(settings); @@ -426,9 +425,7 @@ export function addApi(projectDir: string, settings?: any) { if (authTypesToAdd.length > 1) { authTypesToAdd.shift(); - chain - .wait('Configure additional auth types?') - .sendConfirmYes(); + chain.wait('Configure additional auth types?').sendConfirmYes(); authTypesToSelectFrom = authTypesToSelectFrom.filter(x => x !== defaultType); @@ -442,9 +439,7 @@ export function addApi(projectDir: string, settings?: any) { setupAuthType(authType, chain, settings); }); } else { - chain - .wait('Configure additional auth types?') - .sendLine('n'); + chain.wait('Configure additional auth types?').sendLine('n'); } } diff --git a/packages/amplify-e2e-core/src/categories/auth.ts b/packages/amplify-e2e-core/src/categories/auth.ts index 9907c25b671..290c6cf6519 100644 --- a/packages/amplify-e2e-core/src/categories/auth.ts +++ b/packages/amplify-e2e-core/src/categories/auth.ts @@ -928,7 +928,7 @@ export function addAuthWithGroups(cwd: string): Promise { .wait('Do you want to configure Lambda Triggers for Cognito') .sendConfirmNo() .sendEof() - .run((err: Error) => err ? reject(err) : resolve()); + .run((err: Error) => (err ? reject(err) : resolve())); }); } diff --git a/packages/amplify-e2e-core/src/categories/geo.ts b/packages/amplify-e2e-core/src/categories/geo.ts index cae3c27619a..46fa7f4b74f 100644 --- a/packages/amplify-e2e-core/src/categories/geo.ts +++ b/packages/amplify-e2e-core/src/categories/geo.ts @@ -1,18 +1,18 @@ import { getCLIPath, nspawn as spawn, KEY_DOWN_ARROW, generateRandomShortId } from '..'; export type GeoConfig = { - isFirstGeoResource?: boolean - isAdditional?: boolean - isDefault?: boolean - resourceName?: string -} + isFirstGeoResource?: boolean; + isAdditional?: boolean; + isDefault?: boolean; + resourceName?: string; +}; const defaultGeoConfig: GeoConfig = { isFirstGeoResource: false, isAdditional: false, isDefault: true, - resourceName: '\r' -} + resourceName: '\r', +}; const defaultSearchIndexQuestion = `Set this search index as the default? It will be used in Amplify search index API calls if no explicit reference is provided.`; const defaultMapQuestion = `Set this Map as the default? It will be used in Amplify Map API calls if no explicit reference is provided.`; @@ -33,15 +33,14 @@ export function addMapWithDefault(cwd: string, settings: GeoConfig = {}): Promis .sendCarriageReturn(); if (config.isFirstGeoResource === true) { - chain.wait('Are you tracking commercial assets for your business in your app?') - .sendCarriageReturn(); + chain.wait('Are you tracking commercial assets for your business in your app?').sendCarriageReturn(); chain.wait('Successfully set RequestBasedUsage pricing plan for your Geo resources.'); } chain.wait('Do you want to configure advanced settings?').sendConfirmNo(); if (config.isAdditional === true) { - chain.wait(defaultMapQuestion) + chain.wait(defaultMapQuestion); if (config.isDefault === true) { chain.sendConfirmYes(); } else { @@ -54,7 +53,7 @@ export function addMapWithDefault(cwd: string, settings: GeoConfig = {}): Promis } else { reject(); } - }) + }); }); } @@ -75,28 +74,26 @@ export function addPlaceIndexWithDefault(cwd: string, settings: GeoConfig = {}): .sendCarriageReturn(); if (config.isFirstGeoResource === true) { - chain.wait('Are you tracking commercial assets for your business in your app?') - .sendConfirmNo(); + chain.wait('Are you tracking commercial assets for your business in your app?').sendConfirmNo(); chain.wait('Successfully set RequestBasedUsage pricing plan for your Geo resources.'); } - chain.wait('Do you want to configure advanced settings?') - .sendConfirmNo(); - if (config.isAdditional === true) { - chain.wait(defaultSearchIndexQuestion); - if (config.isDefault === true) { - chain.sendConfirmYes(); - } else { - chain.sendConfirmNo(); - } + chain.wait('Do you want to configure advanced settings?').sendConfirmNo(); + if (config.isAdditional === true) { + chain.wait(defaultSearchIndexQuestion); + if (config.isDefault === true) { + chain.sendConfirmYes(); + } else { + chain.sendConfirmNo(); } - chain.run((err: Error) => { - if (!err) { - resolve(); - } else { - reject(); - } - }) + } + chain.run((err: Error) => { + if (!err) { + resolve(); + } else { + reject(); + } + }); }); } @@ -122,7 +119,7 @@ export function updateMapWithDefault(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -148,7 +145,7 @@ export function updateSecondMapAsDefault(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -175,7 +172,7 @@ export function updatePlaceIndexWithDefault(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -202,7 +199,7 @@ export function updateSecondPlaceIndexAsDefault(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -225,7 +222,7 @@ export function removeMap(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -250,7 +247,7 @@ export function removeFirstDefaultMap(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -274,7 +271,7 @@ export function removePlaceIndex(cwd: string): Promise { } else { reject(); } - }) + }); }); } @@ -300,7 +297,7 @@ export function removeFirstDefaultPlaceIndex(cwd: string): Promise { } else { reject(); } - }) + }); }); } diff --git a/packages/amplify-e2e-core/src/cli-test-runner.js b/packages/amplify-e2e-core/src/cli-test-runner.js index ad6255698ea..2f6dc5d6098 100644 --- a/packages/amplify-e2e-core/src/cli-test-runner.js +++ b/packages/amplify-e2e-core/src/cli-test-runner.js @@ -1,16 +1,38 @@ -const circusRunner = require('jest-circus/runner'); -const throat = require('throat'); -const uuid = require('uuid'); +const circusRunner = require("jest-circus/runner"); +const throat = require("throat"); +const uuid = require("uuid"); const mutex = throat(1); -export const run = async (globalConfig, config, environment, runtime, testPath) => { +export const run = async ( + globalConfig, + config, + environment, + runtime, + testPath +) => { const CLITestRunner = {}; - environment.global.addCLITestRunnerLogs = logs => { + environment.global.addCLITestRunnerLogs = (logs) => { CLITestRunner.logs = logs; }; - environment.global.getRandomId = () => mutex(() => uuid.v4().split('-')[0]); - const result = await circusRunner(globalConfig, config, environment, runtime, testPath); + environment.global.getRandomId = () => mutex(() => uuid.v4().split("-")[0]); + const result = await circusRunner( + globalConfig, + config, + environment, + runtime, + testPath + ); + setTimeout(() => { + if (process.platform === "win32") { + // An issue with node-pty leaves open handles when running within jest + // This prevents the jest process from exiting without being forced. + // Exiting here as a workaround, only on windows. + // A timeout is used to give Jest time to render the list of passed/failed tests. + // See https://github.com/microsoft/node-pty/issues/437 + process.exit(result.numFailingTests !== 0); + } + }, 1000); result.CLITestRunner = CLITestRunner; return result; }; diff --git a/packages/amplify-e2e-core/src/index.ts b/packages/amplify-e2e-core/src/index.ts index 963e5e0e4b9..a0a8b486dc4 100644 --- a/packages/amplify-e2e-core/src/index.ts +++ b/packages/amplify-e2e-core/src/index.ts @@ -44,7 +44,7 @@ export function isTestingWithLatestCodebase(scriptRunnerPath) { export function getScriptRunnerPath(testingWithLatestCodebase = false) { if (!testingWithLatestCodebase) { return process.platform === 'win32' - ? 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe' + ? 'node.exe' : 'exec'; } diff --git a/packages/amplify-e2e-core/src/utils/nexpect.ts b/packages/amplify-e2e-core/src/utils/nexpect.ts index 42cbe32b56c..e105fd89da0 100644 --- a/packages/amplify-e2e-core/src/utils/nexpect.ts +++ b/packages/amplify-e2e-core/src/utils/nexpect.ts @@ -23,7 +23,7 @@ import { join, parse } from 'path'; import * as fs from 'fs-extra'; import * as os from 'os'; import { getScriptRunnerPath, isTestingWithLatestCodebase } from '..'; - +const RETURN = process.platform === 'win32' ? '\r' : EOL; const DEFAULT_NO_OUTPUT_TIMEOUT = process.env.AMPLIFY_TEST_TIMEOUT_SEC ? Number.parseInt(process.env.AMPLIFY_TEST_TIMEOUT_SEC, 10) * 1000 : 5 * 60 * 1000; // 5 Minutes @@ -155,7 +155,7 @@ function chain(context: Context): ExecutionContext { sendLine: function (line: string): ExecutionContext { let _sendline: ExecutionStep = { fn: () => { - context.process.write(`${line}${EOL}`); + context.process.write(`${line}${RETURN}`); return true; }, name: '_sendline', @@ -169,7 +169,7 @@ function chain(context: Context): ExecutionContext { sendCarriageReturn: function (): ExecutionContext { let _sendline: ExecutionStep = { fn: () => { - context.process.write(EOL); + context.process.write(RETURN); return true; }, name: '_sendline', @@ -231,7 +231,7 @@ function chain(context: Context): ExecutionContext { sendConfirmYes: function (): ExecutionContext { var _send: ExecutionStep = { fn: () => { - context.process.write(`Y${EOL}`); + context.process.write(`Y${RETURN}`); return true; }, name: '_send', @@ -245,7 +245,7 @@ function chain(context: Context): ExecutionContext { sendConfirmNo: function (): ExecutionContext { var _send: ExecutionStep = { fn: () => { - context.process.write(`N${EOL}`); + context.process.write(`N${RETURN}`); return true; }, name: '_send', @@ -259,7 +259,7 @@ function chain(context: Context): ExecutionContext { sendCtrlC: function (): ExecutionContext { var _send: ExecutionStep = { fn: () => { - context.process.write(`${CONTROL_C}${EOL}`); + context.process.write(`${CONTROL_C}${RETURN}`); return true; }, name: '_send', @@ -623,11 +623,16 @@ export function nspawn(command: string | string[], params: string[] = [], option } const testingWithLatestCodebase = isTestingWithLatestCodebase(command); - if (testingWithLatestCodebase) { + if (testingWithLatestCodebase || (process.platform === 'win32' && !command.endsWith('.exe'))) { params.unshift(command); command = getScriptRunnerPath(testingWithLatestCodebase); } + if (process.platform === 'win32' && !command.endsWith('powershell.exe')) { + params.unshift(command); + command = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'; + } + let childEnv = undefined; let pushEnv = undefined; @@ -648,6 +653,7 @@ export function nspawn(command: string | string[], params: string[] = [], option ...process.env, ...pushEnv, ...options.env, + NODE_OPTIONS: '--max_old_space_size=4096', }; // Undo ci-info detection, required for some tests diff --git a/packages/amplify-e2e-tests/src/__tests__/api_2.test.ts b/packages/amplify-e2e-tests/src/__tests__/api_2.test.ts index 0462834fe81..2b1e2fe0b66 100644 --- a/packages/amplify-e2e-tests/src/__tests__/api_2.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/api_2.test.ts @@ -1,26 +1,26 @@ import { - addApiWithBlankSchemaAndConflictDetection, - addApiWithoutSchema, - addFunction, - addRestApi, - addSimpleDDB, + addApiWithBlankSchemaAndConflictDetection, + addApiWithoutSchema, + addFunction, + addRestApi, + addSimpleDDB, amplifyPush, - amplifyPushUpdate, - apiDisableDataStore, - apiEnableDataStore, + amplifyPushUpdate, + apiDisableDataStore, + apiEnableDataStore, checkIfBucketExists, - createNewProjectDir, - deleteProject, - deleteProjectDir, - enableAdminUI, - getAppSyncApi, - getLocalEnvInfo, - getProjectMeta, - getTransformConfig, + createNewProjectDir, + deleteProject, + deleteProjectDir, + enableAdminUI, + getAppSyncApi, + getLocalEnvInfo, + getProjectMeta, + getTransformConfig, initJSProjectWithProfile, listAttachedRolePolicies, listRolePolicies, - updateApiSchema, + updateApiSchema, updateAPIWithResolutionStrategyWithModels, updateAuthAddAdminQueries, } from 'amplify-e2e-core'; @@ -32,7 +32,6 @@ import _ from 'lodash'; import * as path from 'path'; const providerName = 'awscloudformation'; - // to deal with bug in cognito-identity-js (global as any).fetch = require('node-fetch'); // to deal with subscriptions in node env diff --git a/packages/amplify-e2e-tests/src/__tests__/api_5.test.ts b/packages/amplify-e2e-tests/src/__tests__/api_5.test.ts index 7d80c569814..0411b8760b4 100644 --- a/packages/amplify-e2e-tests/src/__tests__/api_5.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/api_5.test.ts @@ -60,15 +60,8 @@ describe('amplify add api (REST)', () => { expect(meta.function).toBeDefined(); let seenAtLeastOneFunc = false; for (let key of Object.keys(meta.function)) { - const { - service, - build, - lastBuildTimeStamp, - lastPackageTimeStamp, - distZipFilename, - lastPushTimeStamp, - lastPushDirHash, - } = meta.function[key]; + const { service, build, lastBuildTimeStamp, lastPackageTimeStamp, distZipFilename, lastPushTimeStamp, lastPushDirHash } = + meta.function[key]; expect(service).toBe('Lambda'); expect(build).toBeTruthy(); expect(lastBuildTimeStamp).toBeDefined(); diff --git a/packages/amplify-e2e-tests/src/__tests__/feature-flags.test.ts b/packages/amplify-e2e-tests/src/__tests__/feature-flags.test.ts index 9f68cbe9a58..c66c2ee51db 100644 --- a/packages/amplify-e2e-tests/src/__tests__/feature-flags.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/feature-flags.test.ts @@ -1,5 +1,13 @@ import * as fs from 'fs-extra'; -import { initJSProjectWithProfile, deleteProject, addApiWithoutSchema, updateApiSchema, amplifyPush, amplifyPull, getAppId } from 'amplify-e2e-core'; +import { + initJSProjectWithProfile, + deleteProject, + addApiWithoutSchema, + updateApiSchema, + amplifyPush, + amplifyPull, + getAppId, +} from 'amplify-e2e-core'; import { createNewProjectDir, deleteProjectDir } from 'amplify-e2e-core'; import { pathManager } from 'amplify-cli-core'; import { addEnvironment } from '../environment/env'; diff --git a/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts b/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts index 391a9ddb32b..7745d3d1bdb 100644 --- a/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/function_1.test.ts @@ -223,9 +223,12 @@ describe('nodejs', () => { await amplifyPushAuth(projRoot); const meta = getProjectMeta(projRoot); - const { Name: table1Name, Arn: table1Arn, Region: table1Region, StreamArn: table1StreamArn } = Object.keys(meta.storage).map( - key => meta.storage[key], - )[0].output; + const { + Name: table1Name, + Arn: table1Arn, + Region: table1Region, + StreamArn: table1StreamArn, + } = Object.keys(meta.storage).map(key => meta.storage[key])[0].output; expect(table1Name).toBeDefined(); expect(table1Arn).toBeDefined(); diff --git a/packages/amplify-e2e-tests/src/__tests__/geo-add.test.ts b/packages/amplify-e2e-tests/src/__tests__/geo-add.test.ts index 27750c6d512..7571895b5a3 100644 --- a/packages/amplify-e2e-tests/src/__tests__/geo-add.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/geo-add.test.ts @@ -1,4 +1,4 @@ -import { +import { createNewProjectDir, deleteProject, deleteProjectDir, @@ -11,7 +11,7 @@ import { getMap, getPlaceIndex, generateRandomShortId, - getGeoJSConfiguration + getGeoJSConfiguration, } from 'amplify-e2e-core'; import { existsSync } from 'fs'; import path from 'path'; diff --git a/packages/amplify-e2e-tests/src/__tests__/geo-remove.test.ts b/packages/amplify-e2e-tests/src/__tests__/geo-remove.test.ts index ac2903614c5..0368556fe65 100644 --- a/packages/amplify-e2e-tests/src/__tests__/geo-remove.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/geo-remove.test.ts @@ -1,4 +1,4 @@ -import { +import { createNewProjectDir, deleteProject, deleteProjectDir, @@ -14,7 +14,7 @@ import { removeFirstDefaultMap, removeFirstDefaultPlaceIndex, generateResourceIdsInOrder, - getGeoJSConfiguration + getGeoJSConfiguration, } from 'amplify-e2e-core'; import { existsSync } from 'fs'; import path from 'path'; diff --git a/packages/amplify-e2e-tests/src/__tests__/geo-update.test.ts b/packages/amplify-e2e-tests/src/__tests__/geo-update.test.ts index a3d4c115eb0..5858c8db4e4 100644 --- a/packages/amplify-e2e-tests/src/__tests__/geo-update.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/geo-update.test.ts @@ -1,4 +1,4 @@ -import { +import { createNewProjectDir, deleteProject, deleteProjectDir, @@ -15,7 +15,7 @@ import { updateSecondMapAsDefault, updateSecondPlaceIndexAsDefault, generateResourceIdsInOrder, - getGeoJSConfiguration + getGeoJSConfiguration, } from 'amplify-e2e-core'; import { existsSync } from 'fs'; import path from 'path'; diff --git a/packages/amplify-e2e-tests/src/__tests__/pull.test.ts b/packages/amplify-e2e-tests/src/__tests__/pull.test.ts index 155ad825f7d..ec3e35dddae 100644 --- a/packages/amplify-e2e-tests/src/__tests__/pull.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/pull.test.ts @@ -25,7 +25,7 @@ describe('amplify pull', () => { }); it('pulling twice with noUpdateBackend does not re-prompt', async () => { - await initJSProjectWithProfile(projRoot, { + await initJSProjectWithProfile(projRoot, { disableAmplifyAppCreation: false, name: 'testapi', }); diff --git a/packages/amplify-e2e-tests/src/configure_tests.ts b/packages/amplify-e2e-tests/src/configure_tests.ts index fb3f9bab934..65232a82e81 100644 --- a/packages/amplify-e2e-tests/src/configure_tests.ts +++ b/packages/amplify-e2e-tests/src/configure_tests.ts @@ -29,4 +29,5 @@ process.nextTick(async () => { console.log(e.stack); process.exit(1); } + process.exit(); }); diff --git a/packages/amplify-frontend-javascript/lib/frontend-config-creator.js b/packages/amplify-frontend-javascript/lib/frontend-config-creator.js index dec64769136..ef8f52425f6 100644 --- a/packages/amplify-frontend-javascript/lib/frontend-config-creator.js +++ b/packages/amplify-frontend-javascript/lib/frontend-config-creator.js @@ -188,14 +188,11 @@ function getAWSExportsObject(resources) { // add geo config if geo resources exist if (Object.entries(geoConfig).length > 0) { - Object.assign( - configOutput, - { - geo: { - amazon_location_service: geoConfig - } - } - ); + Object.assign(configOutput, { + geo: { + amazon_location_service: geoConfig, + }, + }); } return configOutput; @@ -562,16 +559,16 @@ function getSumerianConfig(sumerianResources) { } function getMapConfig(mapResources) { - let defaultMap = ""; + let defaultMap = ''; const mapConfig = { - items: {} + items: {}, }; mapResources.forEach(mapResource => { const mapName = mapResource.output.Name; mapConfig.items[mapName] = { - style: mapResource.output.Style - } - if(mapResource.isDefault) { + style: mapResource.output.Style, + }; + if (mapResource.isDefault) { defaultMap = mapName; } }); @@ -580,14 +577,14 @@ function getMapConfig(mapResources) { } function getPlaceIndexConfig(placeIndexResources) { - let defaultPlaceIndex = ""; + let defaultPlaceIndex = ''; const placeIndexConfig = { - items: [] + items: [], }; placeIndexResources.forEach(placeIndexResource => { const placeIndexName = placeIndexResource.output.Name; placeIndexConfig.items.push(placeIndexName); - if(placeIndexResource.isDefault) { + if (placeIndexResource.isDefault) { defaultPlaceIndex = placeIndexName; } }); diff --git a/packages/amplify-provider-awscloudformation/src/aws-utils/aws-location.ts b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-location.ts index e01d7012f75..cef85c73fdc 100644 --- a/packages/amplify-provider-awscloudformation/src/aws-utils/aws-location.ts +++ b/packages/amplify-provider-awscloudformation/src/aws-utils/aws-location.ts @@ -21,16 +21,16 @@ const serviceRegionMap = { 'ap-northeast-2': 'us-west-2', 'eu-west-2': 'eu-west-1', 'eu-west-3': 'eu-west-1', - 'me-south-1': 'ap-southeast-1' + 'me-south-1': 'ap-southeast-1', }; export const getLocationSupportedRegion = (region: string): string => { - if (serviceRegionMap[region]) { + if (serviceRegionMap[region]) { return serviceRegionMap[region]; - } - return defaultLocationRegion; + } + return defaultLocationRegion; }; export const getLocationRegionMapping = (): $TSObject => { - return serviceRegionMap; -} + return serviceRegionMap; +}; diff --git a/packages/amplify-provider-awscloudformation/src/push-resources.ts b/packages/amplify-provider-awscloudformation/src/push-resources.ts index 9a289453fd0..1a754be954e 100644 --- a/packages/amplify-provider-awscloudformation/src/push-resources.ts +++ b/packages/amplify-provider-awscloudformation/src/push-resources.ts @@ -390,7 +390,7 @@ export async function run(context: $TSContext, resourceDefinition: $TSObject) { if (iterativeDeploymentWasInvoked) { await deploymentStateManager.failDeployment(); } - if(!await canAutoResolveGraphQLAuthError(error.message)) { + if (!(await canAutoResolveGraphQLAuthError(error.message))) { spinner.fail('An error occurred when pushing the resources to the cloud'); } rollbackLambdaLayers(layerResources); @@ -402,11 +402,14 @@ export async function run(context: $TSContext, resourceDefinition: $TSObject) { } async function canAutoResolveGraphQLAuthError(message: string) { - if (message === `@auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.` - || message === `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.` - || message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.` - || message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.` - || message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.`) { + if ( + message === `@auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.` || + message === + `@auth directive with 'userPools' provider found, but the project has no Cognito User Pools authentication provider configured.` || + message === `@auth directive with 'oidc' provider found, but the project has no OPENID_CONNECT authentication provider configured.` || + message === `@auth directive with 'apiKey' provider found, but the project has no API Key authentication provider configured.` || + message === `@auth directive with 'function' provider found, but the project has no Lambda authentication provider configured.` + ) { return true; } } diff --git a/packages/graphql-transformers-e2e-tests/src/__tests__/SearchableModelTransformerV2.e2e.test.ts b/packages/graphql-transformers-e2e-tests/src/__tests__/SearchableModelTransformerV2.e2e.test.ts index 6bcfcc2f814..7a77b2adba1 100644 --- a/packages/graphql-transformers-e2e-tests/src/__tests__/SearchableModelTransformerV2.e2e.test.ts +++ b/packages/graphql-transformers-e2e-tests/src/__tests__/SearchableModelTransformerV2.e2e.test.ts @@ -63,12 +63,12 @@ const createEntries = async () => { await waitForESPropagate(); }; -const waitForESPropagate = async (initialWaitSeconds = 5, maxRetryCount = 5 ) => { +const waitForESPropagate = async (initialWaitSeconds = 5, maxRetryCount = 5) => { const expectedCount = 8; let waitInMilliseconds = initialWaitSeconds * 1000; let currentRetryCount = 0; let searchResponse; - + do { await new Promise(r => setTimeout(r, waitInMilliseconds)); searchResponse = await GRAPHQL_CLIENT.query( @@ -84,7 +84,7 @@ const waitForESPropagate = async (initialWaitSeconds = 5, maxRetryCount = 5 ) => currentRetryCount += 1; waitInMilliseconds = waitInMilliseconds * 2; } while (searchResponse.data.searchPosts?.items?.length < expectedCount && currentRetryCount <= maxRetryCount); -} +}; beforeAll(async () => { const validSchema = ` diff --git a/scripts/split-e2e-tests.ts b/scripts/split-e2e-tests.ts index 477089ccefd..8a39f8b7cfa 100644 --- a/scripts/split-e2e-tests.ts +++ b/scripts/split-e2e-tests.ts @@ -11,55 +11,21 @@ const CONCURRENCY = 25; // Each of these failures should be independently investigated, resolved, and removed from this list. // For now, this list is being used to skip creation of circleci jobs for these tasks const WINDOWS_TEST_FAILURES = [ - 'amplify-app-amplify_e2e_tests', - 'analytics-amplify_e2e_tests', - 'api_1-amplify_e2e_tests', - 'api_2-amplify_e2e_tests', - 'api_3-amplify_e2e_tests', - 'api_4-amplify_e2e_tests', - 'api_5-amplify_e2e_tests', - 'auth_1-amplify_e2e_tests', - 'auth_2-amplify_e2e_tests', - 'auth_3-amplify_e2e_tests', - 'auth_4-amplify_e2e_tests', - // Auth tests are failing because - // us-east-1 region is not allowed in parent e2e test account - // and `singleSelect` for region is not working properly in windows - 'auth_5-amplify_e2e_tests', - 'auth_6-amplify_e2e_tests', - 'auth_7-amplify_e2e_tests', - 'auth_8-amplify_e2e_tests', - 'containers-api-amplify_e2e_tests', 'datastore-modelgen-amplify_e2e_tests', 'delete-amplify_e2e_tests', 'env-amplify_e2e_tests', 'feature-flags-amplify_e2e_tests', - 'frontend_config_drift-amplify_e2e_tests', 'function_1-amplify_e2e_tests', 'function_2-amplify_e2e_tests', 'function_3-amplify_e2e_tests', 'function_4-amplify_e2e_tests', - 'function_6-amplify_e2e_tests', 'function_5-amplify_e2e_tests', + 'function_6-amplify_e2e_tests', 'function_7-amplify_e2e_tests', 'function_8-amplify_e2e_tests', 'function_9-amplify_e2e_tests', - 'geo-add-amplify_e2e_tests', - 'geo-update-amplify_e2e_tests', 'geo-remove-amplify_e2e_tests', - 'hooks-amplify_e2e_tests', - 'hosting-amplify_e2e_tests', - 'hostingPROD-amplify_e2e_tests', - 'iam-permissions-boundary-amplify_e2e_tests', - 'import_auth_1-amplify_e2e_tests', - 'import_auth_2-amplify_e2e_tests', - 'import_auth_3-amplify_e2e_tests', - 'import_dynamodb_1-amplify_e2e_tests', - 'import_dynamodb_2-amplify_e2e_tests', - 'import_s3_1-amplify_e2e_tests', - 'import_s3_2-amplify_e2e_tests', - 'init-amplify_e2e_tests', - 'interactions-amplify_e2e_tests', + 'geo-update-amplify_e2e_tests', 'layer-1-amplify_e2e_tests', 'layer-2-amplify_e2e_tests', 'layer-3-amplify_e2e_tests', @@ -68,50 +34,40 @@ const WINDOWS_TEST_FAILURES = [ 'migration-api-connection-migration2-amplify_e2e_tests', 'migration-api-key-migration1-amplify_e2e_tests', 'migration-api-key-migration2-amplify_e2e_tests', - 'migration-api-key-migration3-amplify_e2e_tests', - 'migration-api-key-migration4-amplify_e2e_tests', - 'migration-api-key-migration5-amplify_e2e_tests', - 'migration-node-function-amplify_e2e_tests', - 'notifications-amplify_e2e_tests', - 'predictions-amplify_e2e_tests', 'pull-amplify_e2e_tests', - 'resolvers-amplify_e2e_tests', - 's3-sse-amplify_e2e_tests', - 'schema-auth-1-amplify_e2e_tests', - 'schema-auth-2-amplify_e2e_tests', - 'schema-auth-3-amplify_e2e_tests', - 'schema-auth-4-amplify_e2e_tests', - 'schema-auth-5-amplify_e2e_tests', - 'schema-auth-6-amplify_e2e_tests', - 'schema-auth-7-amplify_e2e_tests', - 'schema-auth-8-amplify_e2e_tests', - 'schema-auth-9-amplify_e2e_tests', - 'schema-auth-10-amplify_e2e_tests', - 'schema-auth-11-amplify_e2e_tests', - 'schema-auth-12-amplify_e2e_tests', - 'schema-auth-13-amplify_e2e_tests', - 'schema-connection-amplify_e2e_tests', - 'schema-data-access-patterns-amplify_e2e_tests', - 'schema-function-1-amplify_e2e_tests', - 'schema-function-2-amplify_e2e_tests', + 'schema-iterative-rollback-1-amplify_e2e_tests', + 'schema-iterative-rollback-2-amplify_e2e_tests', 'schema-iterative-update-1-amplify_e2e_tests', 'schema-iterative-update-2-amplify_e2e_tests', 'schema-iterative-update-3-amplify_e2e_tests', 'schema-iterative-update-4-amplify_e2e_tests', 'schema-iterative-update-locking-amplify_e2e_tests', - 'schema-iterative-rollback-1-amplify_e2e_tests', - 'schema-iterative-rollback-2-amplify_e2e_tests', - 'schema-key-amplify_e2e_tests_pkg', - 'schema-model-amplify_e2e_tests', - 'schema-predictions-amplify_e2e_tests', - 'schema-searchable-amplify_e2e_tests', - 'schema-versioned-amplify_e2e_tests', - 'storage-1-amplify_e2e_tests', - 'storage-2-amplify_e2e_tests', - 'storage-3-amplify_e2e_tests', - 'tags-amplify_e2e_tests', + 'schema-key-amplify_e2e_tests', + 'api_4-amplify_e2e_tests', + 'api_3-amplify_e2e_tests', + 'api_2-amplify_e2e_tests', + 'api_1-amplify_e2e_tests', + 'amplify-app-amplify_e2e_tests', + 'import_s3_1-amplify_e2e_tests', + 'import_s3_3-amplify_e2e_tests', + 'auth_4-amplify_e2e_tests', + 'auth_3-amplify_e2e_tests', 'custom_policies_container-amplify_e2e_tests', 'custom_policies_function-amplify_e2e_tests', + 'storage-4-amplify_e2e_tests', + 'resolvers-amplify_e2e_tests', + 'migration-api-key-migration3-amplify_e2e_tests', + 'migration-api-key-migration4-amplify_e2e_tests', + 'migration-api-key-migration5-amplify_e2e_tests', + + // 👇 These fail due to ExpiredToken. 👇 + // 👇 Tests should be split to speed up execution time. 👇 + 'geo-add-amplify_e2e_tests', + 'import_auth_1-amplify_e2e_tests', + 'import_auth_2-amplify_e2e_tests', + 'import_auth_3-amplify_e2e_tests', + 'import_dynamodb_2-amplify_e2e_tests', + 'import_s3_2-amplify_e2e_tests', ]; // Ensure to update packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts is also updated this gets updated