diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a7a29aaa55..4c450170e96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1135,14 +1135,6 @@ jobs: environment: TEST_SUITE: src/__tests__/function_5.test.ts CLI_REGION: ap-northeast-1 - defer-init-push-amplify_e2e_tests: - working_directory: ~/repo - docker: *ref_1 - resource_class: large - steps: *ref_4 - environment: - TEST_SUITE: src/__tests__/defer-init-push.test.ts - CLI_REGION: ap-southeast-1 configure-project-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1150,7 +1142,7 @@ jobs: steps: *ref_4 environment: TEST_SUITE: src/__tests__/configure-project.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: ap-southeast-1 api_4-amplify_e2e_tests: working_directory: ~/repo docker: *ref_1 @@ -1158,7 +1150,7 @@ jobs: steps: *ref_4 environment: TEST_SUITE: src/__tests__/api_4.test.ts - CLI_REGION: us-east-2 + CLI_REGION: ap-southeast-2 schema-iterative-update-4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 @@ -1839,16 +1831,6 @@ jobs: TEST_SUITE: src/__tests__/function_5.test.ts CLI_REGION: ap-northeast-1 steps: *ref_5 - defer-init-push-amplify_e2e_tests_pkg_linux: - working_directory: ~/repo - docker: *ref_1 - resource_class: large - environment: - AMPLIFY_DIR: /home/circleci/repo/out - AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux - TEST_SUITE: src/__tests__/defer-init-push.test.ts - CLI_REGION: ap-southeast-1 - steps: *ref_5 configure-project-amplify_e2e_tests_pkg_linux: working_directory: ~/repo docker: *ref_1 @@ -1857,7 +1839,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/configure-project.test.ts - CLI_REGION: ap-southeast-2 + CLI_REGION: ap-southeast-1 steps: *ref_5 api_4-amplify_e2e_tests_pkg_linux: working_directory: ~/repo @@ -1867,7 +1849,7 @@ jobs: AMPLIFY_DIR: /home/circleci/repo/out AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux TEST_SUITE: src/__tests__/api_4.test.ts - CLI_REGION: us-east-2 + CLI_REGION: ap-southeast-2 steps: *ref_5 workflows: version: 2 @@ -1967,10 +1949,10 @@ workflows: - master - done_with_node_e2e_tests: requires: + - schema-key-amplify_e2e_tests - analytics-amplify_e2e_tests - notifications-amplify_e2e_tests - schema-iterative-update-locking-amplify_e2e_tests - - api_4-amplify_e2e_tests - schema-auth-10-amplify_e2e_tests - hosting-amplify_e2e_tests - tags-amplify_e2e_tests @@ -1990,17 +1972,17 @@ workflows: - schema-iterative-update-2-amplify_e2e_tests - schema-data-access-patterns-amplify_e2e_tests - init-special-case-amplify_e2e_tests - - defer-init-push-amplify_e2e_tests + - configure-project-amplify_e2e_tests - feature-flags-amplify_e2e_tests - schema-versioned-amplify_e2e_tests - plugin-amplify_e2e_tests - - configure-project-amplify_e2e_tests + - api_4-amplify_e2e_tests - done_with_pkg_linux_e2e_tests: requires: + - schema-key-amplify_e2e_tests_pkg_linux - analytics-amplify_e2e_tests_pkg_linux - notifications-amplify_e2e_tests_pkg_linux - schema-iterative-update-locking-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux - schema-auth-10-amplify_e2e_tests_pkg_linux - hosting-amplify_e2e_tests_pkg_linux - tags-amplify_e2e_tests_pkg_linux @@ -2020,11 +2002,11 @@ workflows: - schema-iterative-update-2-amplify_e2e_tests_pkg_linux - schema-data-access-patterns-amplify_e2e_tests_pkg_linux - init-special-case-amplify_e2e_tests_pkg_linux - - defer-init-push-amplify_e2e_tests_pkg_linux + - configure-project-amplify_e2e_tests_pkg_linux - feature-flags-amplify_e2e_tests_pkg_linux - schema-versioned-amplify_e2e_tests_pkg_linux - plugin-amplify_e2e_tests_pkg_linux - - configure-project-amplify_e2e_tests_pkg_linux + - api_4-amplify_e2e_tests_pkg_linux - amplify_migration_tests_latest: context: - amplify-ecr-image-pull @@ -2205,12 +2187,6 @@ workflows: filters: *ref_9 requires: - function_2-amplify_e2e_tests - - api_4-amplify_e2e_tests: - context: *ref_7 - post-steps: *ref_8 - filters: *ref_9 - requires: - - schema-key-amplify_e2e_tests - api_2-amplify_e2e_tests: context: *ref_7 post-steps: *ref_8 @@ -2505,7 +2481,7 @@ workflows: filters: *ref_9 requires: - layer-amplify_e2e_tests - - defer-init-push-amplify_e2e_tests: + - configure-project-amplify_e2e_tests: context: *ref_7 post-steps: *ref_8 filters: *ref_9 @@ -2565,7 +2541,7 @@ workflows: filters: *ref_9 requires: - auth_3-amplify_e2e_tests - - configure-project-amplify_e2e_tests: + - api_4-amplify_e2e_tests: context: *ref_7 post-steps: *ref_8 filters: *ref_9 @@ -2643,12 +2619,6 @@ workflows: filters: *ref_12 requires: - function_2-amplify_e2e_tests_pkg_linux - - api_4-amplify_e2e_tests_pkg_linux: - context: *ref_10 - post-steps: *ref_11 - filters: *ref_12 - requires: - - schema-key-amplify_e2e_tests_pkg_linux - api_2-amplify_e2e_tests_pkg_linux: context: *ref_10 post-steps: *ref_11 @@ -2963,7 +2933,7 @@ workflows: filters: *ref_12 requires: - layer-amplify_e2e_tests_pkg_linux - - defer-init-push-amplify_e2e_tests_pkg_linux: + - configure-project-amplify_e2e_tests_pkg_linux: context: *ref_10 post-steps: *ref_11 filters: *ref_12 @@ -3027,7 +2997,7 @@ workflows: filters: *ref_12 requires: - auth_3-amplify_e2e_tests_pkg_linux - - configure-project-amplify_e2e_tests_pkg_linux: + - api_4-amplify_e2e_tests_pkg_linux: context: *ref_10 post-steps: *ref_11 filters: *ref_12 diff --git a/jest.config.js b/jest.config.js index c2451088759..2f7b0911ee7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -46,6 +46,7 @@ module.exports = { '/packages/amplify-graphql-docs-generator', '/packages/amplify-graphql-function-transformer', '/packages/amplify-graphql-http-transformer', + '/packages/amplify-graphql-searchable-transformer', '/packages/amplify-graphql-types-generator', '/packages/amplify-provider-awscloudformation', '/packages/amplify-storage-simulator', diff --git a/packages/amplify-app/CHANGELOG.md b/packages/amplify-app/CHANGELOG.md index 01b52c9aa81..e9e0c85865b 100644 --- a/packages/amplify-app/CHANGELOG.md +++ b/packages/amplify-app/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.24.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-app@2.24.0...amplify-app@2.24.1) (2021-05-18) + +**Note:** Version bump only for package amplify-app + + + + + +# [2.24.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-app@2.23.5...amplify-app@2.24.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + + + + ## [2.23.5](https://github.com/aws-amplify/amplify-cli/compare/amplify-app@2.23.3...amplify-app@2.23.5) (2021-05-03) diff --git a/packages/amplify-app/package.json b/packages/amplify-app/package.json index 8639f98ef0e..7c5a39b930f 100644 --- a/packages/amplify-app/package.json +++ b/packages/amplify-app/package.json @@ -1,6 +1,6 @@ { "name": "amplify-app", - "version": "2.23.5", + "version": "2.24.1", "description": "Amplify CLI", "repository": { "type": "git", @@ -30,8 +30,8 @@ "dependencies": { "amplify-frontend-android": "2.15.3", "amplify-frontend-flutter": "0.4.3", - "amplify-frontend-ios": "2.19.6", - "amplify-frontend-javascript": "2.21.6", + "amplify-frontend-ios": "2.20.1", + "amplify-frontend-javascript": "2.22.1", "chalk": "^3.0.0", "execa": "^4.1.0", "fs-extra": "^8.1.0", @@ -41,7 +41,7 @@ "node-emoji": "^1.10.0", "ora": "^4.0.3", "rimraf": "^3.0.0", - "semver": "^7.1.1", + "semver": "^7.3.5", "strip-ansi": "^6.0.0", "xcode": "^2.1.0", "yargs": "^15.1.0" diff --git a/packages/amplify-appsync-simulator/CHANGELOG.md b/packages/amplify-appsync-simulator/CHANGELOG.md index 25e9da8b909..e509df8dd53 100644 --- a/packages/amplify-appsync-simulator/CHANGELOG.md +++ b/packages/amplify-appsync-simulator/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.26.5](https://github.com/aws-amplify/amplify-cli/compare/amplify-appsync-simulator@1.26.4...amplify-appsync-simulator@1.26.5) (2021-05-18) + +**Note:** Version bump only for package amplify-appsync-simulator + + + + + ## [1.26.4](https://github.com/aws-amplify/amplify-cli/compare/amplify-appsync-simulator@1.26.2...amplify-appsync-simulator@1.26.4) (2021-05-03) diff --git a/packages/amplify-appsync-simulator/package.json b/packages/amplify-appsync-simulator/package.json index 2e40110c3c9..13738ee32fd 100644 --- a/packages/amplify-appsync-simulator/package.json +++ b/packages/amplify-appsync-simulator/package.json @@ -1,6 +1,6 @@ { "name": "amplify-appsync-simulator", - "version": "1.26.4", + "version": "1.26.5", "description": "An AppSync Simulator to test AppSync API.", "repository": { "type": "git", @@ -64,7 +64,7 @@ "@types/node": "^12.12.6", "@types/pino": "5.15.3", "@types/ws": "^7.2.3", - "amplify-graphiql-explorer": "1.6.0" + "amplify-graphiql-explorer": "1.6.1" }, "jest": { "testRunner": "jest-circus/runner", diff --git a/packages/amplify-category-analytics/CHANGELOG.md b/packages/amplify-category-analytics/CHANGELOG.md index 563fc9c20da..b7e8e1eeff5 100644 --- a/packages/amplify-category-analytics/CHANGELOG.md +++ b/packages/amplify-category-analytics/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.21.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-analytics@2.21.7...amplify-category-analytics@2.21.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-analytics + + + + + +## [2.21.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-analytics@2.21.6...amplify-category-analytics@2.21.7) (2021-05-14) + +**Note:** Version bump only for package amplify-category-analytics + + + + + ## [2.21.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-analytics@2.21.4...amplify-category-analytics@2.21.6) (2021-05-03) diff --git a/packages/amplify-category-analytics/package.json b/packages/amplify-category-analytics/package.json index 026385e9c3c..76c38392c0d 100644 --- a/packages/amplify-category-analytics/package.json +++ b/packages/amplify-category-analytics/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-analytics", - "version": "2.21.6", + "version": "2.21.8", "description": "amplify-cli analytics plugin", "repository": { "type": "git", @@ -15,7 +15,7 @@ "aws" ], "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "fs-extra": "^8.1.0", "inquirer": "^7.3.3", "uuid": "^3.4.0" diff --git a/packages/amplify-category-api/CHANGELOG.md b/packages/amplify-category-api/CHANGELOG.md index a51e4c3f31b..b8d8a4e5625 100644 --- a/packages/amplify-category-api/CHANGELOG.md +++ b/packages/amplify-category-api/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.31.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-api@2.31.7...amplify-category-api@2.31.8) (2021-05-18) + + +### Bug Fixes + +* make ECR repository name validation more strict ([#7337](https://github.com/aws-amplify/amplify-cli/issues/7337)) ([188efdd](https://github.com/aws-amplify/amplify-cli/commit/188efdde6ded25a06c6fb52e0b2abe04981b0993)) + + + + + +## [2.31.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-api@2.31.6...amplify-category-api@2.31.7) (2021-05-14) + + +### Bug Fixes + +* carry existing container secret config over ([#7224](https://github.com/aws-amplify/amplify-cli/issues/7224)) ([b2f3bf7](https://github.com/aws-amplify/amplify-cli/commit/b2f3bf7059ce3ca1e72cf6c451edd3e61699828a)) +* conditionally rebuild container apis on push ([#7175](https://github.com/aws-amplify/amplify-cli/issues/7175)) ([a27a033](https://github.com/aws-amplify/amplify-cli/commit/a27a033af0fe6a9db8becd15b713113c64e70eb3)) +* update overlapping REST path warning ([#7276](https://github.com/aws-amplify/amplify-cli/issues/7276)) ([3fc7534](https://github.com/aws-amplify/amplify-cli/commit/3fc75343ba228307080f3ef6a6cae4cf3387a007)) + + + + + ## [2.31.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-api@2.31.4...amplify-category-api@2.31.6) (2021-05-03) diff --git a/packages/amplify-category-api/package.json b/packages/amplify-category-api/package.json index e6dc4803cbf..d3315af66a8 100644 --- a/packages/amplify-category-api/package.json +++ b/packages/amplify-category-api/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-api", - "version": "2.31.6", + "version": "2.31.8", "description": "amplify-cli api plugin", "repository": { "type": "git", @@ -62,14 +62,14 @@ "@aws-cdk/cx-api": "~1.72.0", "@aws-cdk/region-info": "~1.72.0", "@graphql-tools/merge": "^6.0.18", - "amplify-cli-core": "1.21.2", - "amplify-util-headless-input": "1.4.3", + "amplify-cli-core": "1.22.1", + "amplify-util-headless-input": "1.4.5", "chalk": "^3.0.0", "constructs": "^3.2.0", "fs-extra": "^8.1.0", "graphql": "^14.5.8", "graphql-relational-schema-transformer": "2.17.3", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "inquirer": "^7.3.3", "js-yaml": "^4.0.0", "ora": "^4.0.3", diff --git a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/containers-walkthrough.ts b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/containers-walkthrough.ts index 199ff52e308..9b38fb744f7 100644 --- a/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/containers-walkthrough.ts +++ b/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/containers-walkthrough.ts @@ -69,8 +69,8 @@ async function askResourceName(context, allDefaultValues) { validate: amplify.inputValidation({ validation: { operator: 'regex', - value: '^[a-zA-Z0-9]+$', - onErrorMsg: 'Resource name should be alphanumeric', + value: '^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$', + onErrorMsg: 'Resource name should be alphanumeric with no uppercase letters', }, required: true, }), diff --git a/packages/amplify-category-auth/CHANGELOG.md b/packages/amplify-category-auth/CHANGELOG.md index 0aafb07da7c..1b3b7dbfef0 100644 --- a/packages/amplify-category-auth/CHANGELOG.md +++ b/packages/amplify-category-auth/CHANGELOG.md @@ -3,6 +3,41 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.31.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-auth@2.31.0...amplify-category-auth@2.31.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-category-auth + + + + + +# [2.31.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-auth@2.30.6...amplify-category-auth@2.31.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Bug Fixes + +* [#4657](https://github.com/aws-amplify/amplify-cli/issues/4657) preserve previous authSelections in update flow ([#7255](https://github.com/aws-amplify/amplify-cli/issues/7255)) ([afbaa08](https://github.com/aws-amplify/amplify-cli/commit/afbaa08ac54bb001b640c808cf136c124089e5fc)) +* e2e failed tests for auth Triggers PR ([#7262](https://github.com/aws-amplify/amplify-cli/issues/7262)) ([fedb6c4](https://github.com/aws-amplify/amplify-cli/commit/fedb6c49cf0695e21f59929e7d0554b59290f2f1)) +* ejs template fix when no triggers added ([#7267](https://github.com/aws-amplify/amplify-cli/issues/7267)) ([81786a8](https://github.com/aws-amplify/amplify-cli/commit/81786a8d654f3ba2550e59986d85a654e5ed44dd)) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-cli/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-cli/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + + + + ## [2.30.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-auth@2.30.4...amplify-category-auth@2.30.6) (2021-05-03) diff --git a/packages/amplify-category-auth/package.json b/packages/amplify-category-auth/package.json index 0270e559c49..a2b22367ce5 100644 --- a/packages/amplify-category-auth/package.json +++ b/packages/amplify-category-auth/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-auth", - "version": "2.30.6", + "version": "2.31.1", "description": "amplify-cli authentication plugin", "repository": { "type": "git", @@ -23,10 +23,10 @@ "test-watch": "jest --watch" }, "dependencies": { - "amplify-cli-core": "1.21.2", - "amplify-headless-interface": "1.5.3", - "amplify-util-headless-input": "1.4.3", - "amplify-util-import": "1.4.6", + "amplify-cli-core": "1.22.1", + "amplify-headless-interface": "1.6.1", + "amplify-util-headless-input": "1.4.5", + "amplify-util-import": "1.4.8", "aws-cdk": "~1.72.0", "aws-sdk": "^2.845.0", "chalk": "^3.0.0", diff --git a/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs b/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs index 817e3ff3f9c..1c8c1430b2a 100644 --- a/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs +++ b/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs @@ -127,7 +127,7 @@ Resources: Mutable: true <% } %> <% } %> - <%if (!props.breakCircularDependency && props.triggers && props.dependsOn) { %> + <%if (!props.breakCircularDependency && props.triggers && props.triggers !== '{}' && props.dependsOn) { %> LambdaConfig: <%if (props.dependsOn.find(i => i.resourceName.includes('CreateAuthChallenge'))) { %> CreateAuthChallenge: !Ref function<%=props.resourceName%>CreateAuthChallengeArn diff --git a/packages/amplify-category-auth/src/index.js b/packages/amplify-category-auth/src/index.js index 65217a4179b..e80c7564929 100644 --- a/packages/amplify-category-auth/src/index.js +++ b/packages/amplify-category-auth/src/index.js @@ -24,6 +24,12 @@ const { projectHasAuth } = require('./provider-utils/awscloudformation/utils/pro const { attachPrevParamsToContext } = require('./provider-utils/awscloudformation/utils/attach-prev-params-to-context'); const { stateManager } = require('amplify-cli-core'); +const { + doesConfigurationIncludeSMS, + loadResourceParameters, + loadImportedAuthParameters, +} = require('./provider-utils/awscloudformation/utils/auth-sms-workflow-helper'); + // this function is being kept for temporary compatability. async function add(context) { const { amplify } = context; @@ -424,6 +430,18 @@ async function importAuth(context) { return providerController.importResource(context, serviceSelection, undefined, undefined, false); } +async function isSMSWorkflowEnabled(context, resourceName) { + const { imported, userPoolId } = context.amplify.getImportedAuthProperties(context); + let userNameAndMfaConfig; + if (imported) { + userNameAndMfaConfig = await loadImportedAuthParameters(context, userPoolId); + } else { + userNameAndMfaConfig = loadResourceParameters(context, resourceName); + } + const result = doesConfigurationIncludeSMS(userNameAndMfaConfig); + return result; +} + module.exports = { externalAuthEnable, checkRequirements, @@ -439,4 +457,5 @@ module.exports = { uploadFiles, category, importAuth, + isSMSWorkflowEnabled, }; diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts index 16ead2f0a90..6fb82c39d19 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts @@ -137,6 +137,7 @@ export interface ProviderUtils { privateParams: $TSObject, envSpecificParams: string[], ): void; + loadResourceParameters(context: $TSContext, category: string, resourceName: string): Record; } export type ImportAuthHeadlessParameters = { diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-sms-workflow-helper.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-sms-workflow-helper.ts new file mode 100644 index 00000000000..fe316c565f1 --- /dev/null +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-sms-workflow-helper.ts @@ -0,0 +1,46 @@ +import { $TSContext } from 'amplify-cli-core'; +import { ProviderUtils } from '../import/types'; + +import { ServiceQuestionsResult } from '../service-walkthrough-types'; +import { supportedServices } from '../../supported-services'; + +export type UserPoolMessageConfiguration = { + mfaConfiguration?: string; + mfaTypes?: string[]; + usernameAttributes?: string[]; +}; + +export const doesConfigurationIncludeSMS = (request: UserPoolMessageConfiguration): boolean => { + if ((request.mfaConfiguration === 'OPTIONAL' || request.mfaConfiguration === 'ON') && request.mfaTypes?.includes('SMS Text Message')) { + return true; + } + + if (request.usernameAttributes?.includes('phone_number')) { + return true; + } + + return false; +}; + +const getProviderPlugin = (context: $TSContext): ProviderUtils => { + const serviceMetaData = supportedServices.Cognito; + const { provider } = serviceMetaData; + + return context.amplify.getPluginInstance(context, provider); +}; +export const loadResourceParameters = (context: $TSContext, resourceName: string): UserPoolMessageConfiguration => { + const providerPlugin = getProviderPlugin(context); + return providerPlugin.loadResourceParameters(context, 'auth', resourceName) as ServiceQuestionsResult; +}; + +export const loadImportedAuthParameters = async (context: $TSContext, userPoolName: string): Promise => { + const providerPlugin = getProviderPlugin(context); + const cognitoUserPoolService = await providerPlugin.createCognitoUserPoolService(context); + const userPoolDetails = await cognitoUserPoolService.getUserPoolDetails(userPoolName); + const mfaConfig = await cognitoUserPoolService.getUserPoolMfaConfig(userPoolName); + return { + mfaConfiguration: mfaConfig.MfaConfiguration, + usernameAttributes: userPoolDetails.UsernameAttributes, + mfaTypes: mfaConfig.SmsMfaConfiguration ? ['SMS Text Message'] : [], + }; +}; diff --git a/packages/amplify-category-function/CHANGELOG.md b/packages/amplify-category-function/CHANGELOG.md index 104166453e3..4731c0da8be 100644 --- a/packages/amplify-category-function/CHANGELOG.md +++ b/packages/amplify-category-function/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.31.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-function@2.31.7...amplify-category-function@2.31.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-function + + + + + +## [2.31.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-function@2.31.6...amplify-category-function@2.31.7) (2021-05-14) + + +### Bug Fixes + +* cross resource permission handling ([#7289](https://github.com/aws-amplify/amplify-cli/issues/7289)) ([4a9fb78](https://github.com/aws-amplify/amplify-cli/commit/4a9fb78d4e1fecdf79634c1782bdefa17d803632)) +* function e2e tests ([#7295](https://github.com/aws-amplify/amplify-cli/issues/7295)) ([5c918be](https://github.com/aws-amplify/amplify-cli/commit/5c918be56f36fb9182d07af4f87a6a8f9f05b6ed)) + + + + + ## [2.31.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-function@2.31.4...amplify-category-function@2.31.6) (2021-05-03) diff --git a/packages/amplify-category-function/package.json b/packages/amplify-category-function/package.json index ce36db52c93..df39c39028e 100644 --- a/packages/amplify-category-function/package.json +++ b/packages/amplify-category-function/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-function", - "version": "2.31.6", + "version": "2.31.8", "description": "amplify-cli function plugin", "repository": { "type": "git", @@ -22,14 +22,14 @@ "aws" ], "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", "cloudform-types": "^4.2.0", "enquirer": "^2.3.6", "folder-hash": "^3.3.2", "fs-extra": "^8.1.0", "globby": "^11.0.1", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "inquirer": "^7.3.3", "inquirer-datepicker": "^2.0.0", "jstreemap": "^1.28.2", diff --git a/packages/amplify-category-hosting/CHANGELOG.md b/packages/amplify-category-hosting/CHANGELOG.md index e715497288f..6dcb4f934fe 100644 --- a/packages/amplify-category-hosting/CHANGELOG.md +++ b/packages/amplify-category-hosting/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.7.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-hosting@2.7.7...amplify-category-hosting@2.7.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-hosting + + + + + +## [2.7.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-hosting@2.7.6...amplify-category-hosting@2.7.7) (2021-05-14) + +**Note:** Version bump only for package amplify-category-hosting + + + + + ## [2.7.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-hosting@2.7.4...amplify-category-hosting@2.7.6) (2021-05-03) diff --git a/packages/amplify-category-hosting/package.json b/packages/amplify-category-hosting/package.json index a35973cf752..7909b63a8b3 100644 --- a/packages/amplify-category-hosting/package.json +++ b/packages/amplify-category-hosting/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-hosting", - "version": "2.7.6", + "version": "2.7.8", "description": "amplify-cli hosting plugin", "repository": { "type": "git", @@ -18,7 +18,7 @@ "test": "jest --coverage" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "chalk": "^3.0.0", "fs-extra": "^8.1.0", "inquirer": "^7.3.3", diff --git a/packages/amplify-category-predictions/CHANGELOG.md b/packages/amplify-category-predictions/CHANGELOG.md index e4884bf45be..06dd93b6ec4 100644 --- a/packages/amplify-category-predictions/CHANGELOG.md +++ b/packages/amplify-category-predictions/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.8.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-predictions@2.8.7...amplify-category-predictions@2.8.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-predictions + + + + + +## [2.8.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-predictions@2.8.6...amplify-category-predictions@2.8.7) (2021-05-14) + +**Note:** Version bump only for package amplify-category-predictions + + + + + ## [2.8.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-predictions@2.8.4...amplify-category-predictions@2.8.6) (2021-05-03) diff --git a/packages/amplify-category-predictions/package.json b/packages/amplify-category-predictions/package.json index d02a23482ca..b8eaa49501b 100644 --- a/packages/amplify-category-predictions/package.json +++ b/packages/amplify-category-predictions/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-predictions", - "version": "2.8.6", + "version": "2.8.8", "description": "amplify-cli predictions plugin", "repository": { "type": "git", @@ -15,7 +15,7 @@ "aws" ], "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "aws-sdk": "^2.845.0", "chalk": "^3.0.0", "fs-extra": "^8.1.0", diff --git a/packages/amplify-category-storage/CHANGELOG.md b/packages/amplify-category-storage/CHANGELOG.md index 8e2f3ac9b9a..94cfb17acdb 100644 --- a/packages/amplify-category-storage/CHANGELOG.md +++ b/packages/amplify-category-storage/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-storage@2.11.7...amplify-category-storage@2.11.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-storage + + + + + +## [2.11.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-storage@2.11.6...amplify-category-storage@2.11.7) (2021-05-14) + +**Note:** Version bump only for package amplify-category-storage + + + + + ## [2.11.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-storage@2.11.4...amplify-category-storage@2.11.6) (2021-05-03) diff --git a/packages/amplify-category-storage/package.json b/packages/amplify-category-storage/package.json index 21e2959feae..a983e3da0be 100644 --- a/packages/amplify-category-storage/package.json +++ b/packages/amplify-category-storage/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-storage", - "version": "2.11.6", + "version": "2.11.8", "description": "amplify-cli storage plugin", "repository": { "type": "git", @@ -21,8 +21,8 @@ "aws" ], "dependencies": { - "amplify-cli-core": "1.21.2", - "amplify-util-import": "1.4.6", + "amplify-cli-core": "1.22.1", + "amplify-util-import": "1.4.8", "enquirer": "^2.3.6", "fs-extra": "^8.1.0", "inquirer": "^7.3.3", diff --git a/packages/amplify-category-xr/CHANGELOG.md b/packages/amplify-category-xr/CHANGELOG.md index c28a4dcda84..77a2a9d5f69 100644 --- a/packages/amplify-category-xr/CHANGELOG.md +++ b/packages/amplify-category-xr/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.8.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-xr@2.8.7...amplify-category-xr@2.8.8) (2021-05-18) + +**Note:** Version bump only for package amplify-category-xr + + + + + +## [2.8.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-xr@2.8.6...amplify-category-xr@2.8.7) (2021-05-14) + +**Note:** Version bump only for package amplify-category-xr + + + + + ## [2.8.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-category-xr@2.8.4...amplify-category-xr@2.8.6) (2021-05-03) diff --git a/packages/amplify-category-xr/package.json b/packages/amplify-category-xr/package.json index c6f192861ee..acdeace113b 100644 --- a/packages/amplify-category-xr/package.json +++ b/packages/amplify-category-xr/package.json @@ -1,6 +1,6 @@ { "name": "amplify-category-xr", - "version": "2.8.6", + "version": "2.8.8", "description": "amplify-cli xr plugin", "repository": { "type": "git", @@ -19,7 +19,7 @@ "test-watch": "jest --watch" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "chalk": "^3.0.0", "fs-extra": "^8.1.0", "inquirer": "^7.3.3" diff --git a/packages/amplify-cli-core/CHANGELOG.md b/packages/amplify-cli-core/CHANGELOG.md index e22995beda2..7f81c5b71a5 100644 --- a/packages/amplify-cli-core/CHANGELOG.md +++ b/packages/amplify-cli-core/CHANGELOG.md @@ -3,6 +3,40 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.22.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-cli-core@1.22.0...amplify-cli-core@1.22.1) (2021-05-18) + +**Note:** Version bump only for package amplify-cli-core + + + + + +# [1.22.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-cli-core@1.21.2...amplify-cli-core@1.22.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Bug Fixes + +* [#7243](https://github.com/aws-amplify/amplify-cli/issues/7243) yaml parsing should support all cfn functions ([#7245](https://github.com/aws-amplify/amplify-cli/issues/7245)) ([4130f2f](https://github.com/aws-amplify/amplify-cli/commit/4130f2fc460f2d038365c4314c6293c203a6520e)) + + +### Features + +* defer root stack creation to first `amplify push` ([#7174](https://github.com/aws-amplify/amplify-cli/issues/7174)) ([d28dd1c](https://github.com/aws-amplify/amplify-cli/commit/d28dd1caca86b19a858dab0e7aa907d1cc74c86a)) +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + +### Reverts + +* Revert "feat: defer root stack creation to first `amplify push` (#7174)" (#7306) ([78854eb](https://github.com/aws-amplify/amplify-cli/commit/78854ebd4a3d41d34d68736d6556045302101265)), closes [#7174](https://github.com/aws-amplify/amplify-cli/issues/7174) [#7306](https://github.com/aws-amplify/amplify-cli/issues/7306) + + + + + ## [1.21.2](https://github.com/aws-amplify/amplify-cli/compare/amplify-cli-core@1.21.0...amplify-cli-core@1.21.2) (2021-05-03) diff --git a/packages/amplify-cli-core/package.json b/packages/amplify-cli-core/package.json index 0190c2dda4b..8887ddf51e1 100644 --- a/packages/amplify-cli-core/package.json +++ b/packages/amplify-cli-core/package.json @@ -1,6 +1,6 @@ { "name": "amplify-cli-core", - "version": "1.21.2", + "version": "1.22.1", "description": "Amplify CLI Core", "repository": { "type": "git", @@ -33,7 +33,10 @@ "hjson": "^3.2.1", "js-yaml": "^4.0.0", "lodash": "^4.17.19", - "open": "^7.3.1" + "node-fetch": "^2.6.1", + "open": "^7.3.1", + "proxy-agent": "^4.0.1", + "semver": "^7.3.5" }, "devDependencies": { "@types/fs-extra": "^8.0.1", @@ -44,6 +47,7 @@ "@types/rimraf": "^3.0.0", "@types/uuid": "^8.0.0", "amplify-function-plugin-interface": "1.7.2", + "nock": "^13.0.11", "rimraf": "^3.0.0" }, "jest": { diff --git a/packages/amplify-cli-core/src/__tests__/banner-message/index.test.ts b/packages/amplify-cli-core/src/__tests__/banner-message/index.test.ts new file mode 100644 index 00000000000..78e0ac3bca7 --- /dev/null +++ b/packages/amplify-cli-core/src/__tests__/banner-message/index.test.ts @@ -0,0 +1,117 @@ +import nock from 'nock'; +import url from 'url'; +import { BannerMessage, AWS_AMPLIFY_DEFAULT_BANNER_URL, Message } from '../../banner-message'; + +const ONE_DAY = 1000 * 60 * 60 * 24; +let mockServer: nock.Interceptor; +let serverResponse: { version: string; messages: Message[] }; +describe('BannerMessage', () => { + beforeEach(async () => { + serverResponse = { + version: '1.0.0', + messages: [ + { + message: 'first message', + id: 'first', + conditions: { + enabled: true, + cliVersions: '4.41.0', + startTime: new Date(Date.now() - ONE_DAY).toISOString(), + endTime: new Date(Date.now() + ONE_DAY).toISOString(), + }, + }, + ], + }; + + const urlInfo = url.parse(AWS_AMPLIFY_DEFAULT_BANNER_URL); + mockServer = nock(`${urlInfo.protocol}//${urlInfo.host}`).get(urlInfo.pathname!); + + await BannerMessage.initialize('4.41.0'); + }); + afterEach(() => { + BannerMessage.releaseInstance(); + }); + + it('should return message by fetching it from remote url', async () => { + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toEqual('first message'); + }); + + it('should return message when there are no conditions', async () => { + delete serverResponse.messages[0].conditions; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toEqual('first message'); + }); + + it('should not throw error when server sends 404', async () => { + mockServer.reply(404, 'page not found'); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('Should not process the Banner response if the response version is not supported', async () => { + serverResponse.version = '20.2'; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('should not return message when the message version does not match', async () => { + serverResponse.messages[0].conditions!.cliVersions! = '110022.0.0'; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('should not show message when message is not enabled', async () => { + serverResponse.messages[0].conditions!.enabled = false; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('should show message when conditions.enabled is undefined', async () => { + (serverResponse.messages[0].conditions!.enabled as any) = undefined; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toEqual('first message'); + }); + + it('should not show message when startDate is after current Date', async () => { + serverResponse.messages[0].conditions!.endTime = undefined; + serverResponse.messages[0].conditions!.startTime = new Date(Date.now() + ONE_DAY).toISOString(); + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('should not show message when endDate is before current Date', async () => { + serverResponse.messages[0].conditions!.startTime = undefined; + serverResponse.messages[0].conditions!.endTime = new Date(Date.now() - ONE_DAY).toISOString(); + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toBeUndefined(); + }); + + it('should show message when start and endDate are not defined', async () => { + delete serverResponse.messages[0].conditions!.startTime; + delete serverResponse.messages[0]!.conditions!.endTime; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toEqual('first message'); + }); + + it('should show message when cliVersions is undefined', async () => { + delete serverResponse.messages[0].conditions!.cliVersions; + mockServer.reply(200, serverResponse, { 'Content-Type': 'application/json' }); + const result = await BannerMessage.getMessage('first'); + expect(result).toEqual('first message'); + }); + + it('should throw error when BannerMessage is not initialized', async () => { + BannerMessage.releaseInstance(); + await expect(() => BannerMessage.getMessage('first')).rejects.toThrowError('BannerMessage is not initialized'); + }); +}); diff --git a/packages/amplify-cli-core/src/banner-message/index.ts b/packages/amplify-cli-core/src/banner-message/index.ts new file mode 100644 index 00000000000..eb53db9ab7c --- /dev/null +++ b/packages/amplify-cli-core/src/banner-message/index.ts @@ -0,0 +1,96 @@ +import fetch from 'node-fetch'; +import semver from 'semver'; +import ProxyAgent from 'proxy-agent'; +import { getLogger } from '../logger'; + +export type Message = { + message: string; + id: string; + conditions?: { + enabled: boolean; + cliVersions?: string; + startTime?: string; + endTime?: string; + }; +}; + +export const AWS_AMPLIFY_DEFAULT_BANNER_URL: string = 'https://aws-amplify.github.io/amplify-cli/banner-message.json'; +const MAX_SUPPORTED_MESSAGE_CONFIG_VERSION = '1.0.0'; + +const logger = getLogger('amplify-cli-core', 'banner-message/index.ts'); + +export class BannerMessage { + private static instance?: BannerMessage; + private messages: Message[] = []; + + public static initialize = (cliVersion: string): BannerMessage => { + if (!BannerMessage.instance) { + BannerMessage.instance = new BannerMessage(cliVersion); + } + + return BannerMessage.instance; + }; + + private static ensureInitialized = () => { + if (!BannerMessage.instance) { + throw new Error('BannerMessage is not initialized'); + } + }; + + private constructor(private cliVersion: string) {} + + private fetchMessages = async (url: string): Promise => { + try { + logger.info(`fetch banner messages from ${url}`); + const proxy = process.env.HTTP_PROXY || process.env.HTTPS_PROXY; + const fetchOptions = proxy ? { agent: new ProxyAgent(proxy) } : {}; + const result = await fetch(url, fetchOptions); + const body = await result.json(); + if (!semver.satisfies(body.version, MAX_SUPPORTED_MESSAGE_CONFIG_VERSION)) { + return; + } + this.messages = body.messages ?? []; + } catch (e) { + // network error should not cause CLI execution failure + logger.error('fetch banner message failed', e); + } + }; + + public static getMessage = async (messageId: string): Promise => { + BannerMessage.ensureInitialized(); + return BannerMessage.instance!.getMessages(messageId); + }; + + getMessages = async (messageId: string): Promise => { + if (!this.messages.length) { + await this.fetchMessages(process.env.AMPLIFY_CLI_BANNER_MESSAGE_URL ?? AWS_AMPLIFY_DEFAULT_BANNER_URL); + } + + const matchingMessageItems = this.messages.filter( + m => + m.id === messageId && + m.conditions?.enabled !== false && + (m.conditions?.cliVersions ? semver.satisfies(this.cliVersion, m.conditions.cliVersions) : true), + ); + + const messageItem = matchingMessageItems.find(m => { + if (m.conditions) { + const currentTime = Date.now(); + const startTime = m.conditions?.startTime ? Date.parse(m.conditions?.startTime) : currentTime; + const endTime = m.conditions?.endTime ? Date.parse(m.conditions?.endTime) : currentTime; + return currentTime >= startTime && currentTime <= endTime; + } + return true; + }); + + return messageItem?.message; + }; + + /** + * @internal + * package private method used in unit tests to release the instance + */ + public static releaseInstance = (): void => { + BannerMessage.instance = undefined; + }; +} diff --git a/packages/amplify-cli-core/src/feature-flags/featureFlags.ts b/packages/amplify-cli-core/src/feature-flags/featureFlags.ts index 944e74d7858..2e930666235 100644 --- a/packages/amplify-cli-core/src/feature-flags/featureFlags.ts +++ b/packages/amplify-cli-core/src/feature-flags/featureFlags.ts @@ -614,6 +614,12 @@ export class FeatureFlags { defaultValueForExistingProjects: false, defaultValueForNewProjects: true, }, + { + name: 'handleListNullabilityTransparently', + type: 'boolean', + defaultValueForExistingProjects: false, + defaultValueForNewProjects: true, + } ]); this.registerFlag('appSync', [ diff --git a/packages/amplify-cli-core/src/index.ts b/packages/amplify-cli-core/src/index.ts index f7ca92c37d6..84961ac83c2 100644 --- a/packages/amplify-cli-core/src/index.ts +++ b/packages/amplify-cli-core/src/index.ts @@ -18,6 +18,7 @@ export * from './cliConstants'; export * from './deploymentSecretsHelper'; export * from './deploymentState'; export * from './utils'; +export * from './banner-message'; // Temporary types until we can finish full type definition across the whole CLI @@ -175,13 +176,12 @@ interface AmplifyToolkit { getEnvDetails: () => $TSAny; getEnvInfo: () => $TSAny; getProviderPlugins: (context: $TSContext) => $TSAny; - getPluginInstance: () => $TSAny; + getPluginInstance: (context: $TSContext, pluginName: string) => $TSAny; getProjectConfig: () => $TSAny; getProjectDetails: () => $TSAny; getProjectMeta: () => $TSMeta; getResourceStatus: (category?: $TSAny, resourceName?: $TSAny, providerName?: $TSAny, filteredResources?: $TSAny) => $TSAny; getResourceOutputs: () => $TSAny; - getTags: (context: $TSContext) => $TSAny; getWhen: () => $TSAny; inputValidation: (input: $TSAny) => (value: $TSAny) => boolean | string; listCategories: () => $TSAny; @@ -197,7 +197,7 @@ interface AmplifyToolkit { filteredResources?: { category: string; resourceName: string }[], ) => $TSAny; storeCurrentCloudBackend: () => $TSAny; - readJsonFile: (file: string) => $TSAny; + readJsonFile: () => $TSAny; removeEnvFromCloud: () => $TSAny; removeDeploymentSecrets: (context: $TSContext, category: string, resource: string) => void; removeResource: () => $TSAny; diff --git a/packages/amplify-cli-core/src/logger/index.ts b/packages/amplify-cli-core/src/logger/index.ts new file mode 100644 index 00000000000..468c3f38cca --- /dev/null +++ b/packages/amplify-cli-core/src/logger/index.ts @@ -0,0 +1,12 @@ +import { Redactor, logger } from 'amplify-cli-logger'; + +export const getLogger = (moduleName: string, fileName: string) => { + return { + info: (message: string, args: any = {}) => { + logger.logInfo({ message: `${moduleName}.${fileName}.${message}(${Redactor(JSON.stringify(args))}` }); + }, + error: (message: string, error: Error) => { + logger.logError({ message: `${moduleName}.${fileName}.${message}`, error }); + }, + }; +}; diff --git a/packages/amplify-cli/CHANGELOG.md b/packages/amplify-cli/CHANGELOG.md index f798c221dcb..f085bb71653 100644 --- a/packages/amplify-cli/CHANGELOG.md +++ b/packages/amplify-cli/CHANGELOG.md @@ -3,6 +3,42 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.51.1](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/cli@4.51.0...@aws-amplify/cli@4.51.1) (2021-05-18) + +**Note:** Version bump only for package @aws-amplify/cli + + + + + +# [4.51.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/cli@4.50.2...@aws-amplify/cli@4.51.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Bug Fixes + +* cross resource permission handling ([#7289](https://github.com/aws-amplify/amplify-cli/issues/7289)) ([4a9fb78](https://github.com/aws-amplify/amplify-cli/commit/4a9fb78d4e1fecdf79634c1782bdefa17d803632)) +* respect headless frontend input ([#7257](https://github.com/aws-amplify/amplify-cli/issues/7257)) ([aab4275](https://github.com/aws-amplify/amplify-cli/commit/aab4275ef3aba2c648b53ca46ecf530d2521cbc9)) + + +### Features + +* defer root stack creation to first `amplify push` ([#7174](https://github.com/aws-amplify/amplify-cli/issues/7174)) ([d28dd1c](https://github.com/aws-amplify/amplify-cli/commit/d28dd1caca86b19a858dab0e7aa907d1cc74c86a)) +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) +* **amplify-frontend-ios:** amplify-xcode integration ([#6867](https://github.com/aws-amplify/amplify-cli/issues/6867)) ([338cea2](https://github.com/aws-amplify/amplify-cli/commit/338cea2f574bab242311989bc5024b9e149bd48b)) + + +### Reverts + +* Revert "feat: defer root stack creation to first `amplify push` (#7174)" (#7306) ([78854eb](https://github.com/aws-amplify/amplify-cli/commit/78854ebd4a3d41d34d68736d6556045302101265)), closes [#7174](https://github.com/aws-amplify/amplify-cli/issues/7174) [#7306](https://github.com/aws-amplify/amplify-cli/issues/7306) + + + + + ## [4.50.2](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/cli@4.50.0...@aws-amplify/cli@4.50.2) (2021-05-03) diff --git a/packages/amplify-cli/package.json b/packages/amplify-cli/package.json index 2d25c21d443..cc483397f16 100644 --- a/packages/amplify-cli/package.json +++ b/packages/amplify-cli/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/cli", - "version": "4.50.2", + "version": "4.51.1", "description": "Amplify CLI", "repository": { "type": "git", @@ -33,39 +33,39 @@ "node": ">=12.0.0" }, "dependencies": { - "amplify-app": "2.23.5", - "amplify-category-analytics": "2.21.6", - "amplify-category-api": "2.31.6", - "amplify-category-auth": "2.30.6", - "amplify-category-function": "2.31.6", - "amplify-category-hosting": "2.7.6", + "amplify-app": "2.24.1", + "amplify-category-analytics": "2.21.8", + "amplify-category-api": "2.31.8", + "amplify-category-auth": "2.31.1", + "amplify-category-function": "2.31.8", + "amplify-category-hosting": "2.7.8", "amplify-category-interactions": "2.6.2", "amplify-category-notifications": "2.19.1", - "amplify-category-predictions": "2.8.6", - "amplify-category-storage": "2.11.6", - "amplify-category-xr": "2.8.6", - "amplify-cli-core": "1.21.2", + "amplify-category-predictions": "2.8.8", + "amplify-category-storage": "2.11.8", + "amplify-category-xr": "2.8.8", + "amplify-cli-core": "1.22.1", "amplify-cli-logger": "1.1.0", "amplify-codegen": "^2.23.1", - "amplify-console-hosting": "1.8.6", - "amplify-container-hosting": "1.3.6", + "amplify-console-hosting": "1.8.8", + "amplify-container-hosting": "1.3.8", "amplify-dotnet-function-runtime-provider": "1.5.4", - "amplify-dotnet-function-template-provider": "1.5.6", + "amplify-dotnet-function-template-provider": "1.5.8", "amplify-frontend-android": "2.15.3", "amplify-frontend-flutter": "0.4.3", - "amplify-frontend-ios": "2.19.6", - "amplify-frontend-javascript": "2.21.6", - "amplify-go-function-runtime-provider": "1.7.6", + "amplify-frontend-ios": "2.20.1", + "amplify-frontend-javascript": "2.22.1", + "amplify-go-function-runtime-provider": "1.8.1", "amplify-go-function-template-provider": "1.3.7", - "amplify-java-function-runtime-provider": "1.7.6", + "amplify-java-function-runtime-provider": "1.8.1", "amplify-java-function-template-provider": "1.5.5", "amplify-nodejs-function-runtime-provider": "1.5.5", - "amplify-nodejs-function-template-provider": "1.6.6", - "amplify-provider-awscloudformation": "4.47.0", - "amplify-python-function-runtime-provider": "1.7.6", + "amplify-nodejs-function-template-provider": "1.6.8", + "amplify-provider-awscloudformation": "4.49.0", + "amplify-python-function-runtime-provider": "1.8.1", "amplify-python-function-template-provider": "1.3.9", - "amplify-util-import": "1.4.6", - "amplify-util-mock": "3.30.6", + "amplify-util-import": "1.4.8", + "amplify-util-mock": "3.31.1", "aws-sdk": "^2.845.0", "chalk": "^3.0.0", "ci-info": "^2.0.0", @@ -81,7 +81,7 @@ "fs-extra": "^8.1.0", "glob": "^7.1.6", "global-prefix": "^3.0.0", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "gunzip-maybe": "^1.4.2", "hidefile": "^3.0.0", "ini": "^1.3.5", @@ -93,7 +93,7 @@ "parse-json": "^5.0.0", "progress": "^2.0.3", "promise-sequential": "^1.1.1", - "semver": "^7.1.1", + "semver": "^7.3.5", "tar-fs": "^2.1.1", "update-notifier": "^4.1.0", "which": "^2.0.2", diff --git a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get_all_envs.test.ts b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-all-envs.test.ts similarity index 100% rename from packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get_all_envs.test.ts rename to packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-all-envs.test.ts diff --git a/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-amplify-appId.test.ts b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-amplify-appId.test.ts new file mode 100644 index 00000000000..18311896e92 --- /dev/null +++ b/packages/amplify-cli/src/__tests__/extensions/amplify-helpers/get-amplify-appId.test.ts @@ -0,0 +1,18 @@ +import { getAmplifyAppId } from '../../../extensions/amplify-helpers/get-amplify-appId'; + +jest.mock('../../../extensions/amplify-helpers/get-project-meta.ts', () => ({ + getProjectMeta: jest.fn().mockImplementation(() => ({ + providers: { + awscloudformation: { + AmplifyAppId: 'testAmplifyAppId', + }, + }, + })), +})); + +describe('getAmplifyAppId', () => { + it('should return the AmplifyAppId from the meta data.', () => { + const appId = getAmplifyAppId(); + expect(appId).toEqual('testAmplifyAppId'); + }); +}); diff --git a/packages/amplify-cli/src/__tests__/test-aborting.test.ts b/packages/amplify-cli/src/__tests__/test-aborting.test.ts index 1a92f461f50..739058866ca 100644 --- a/packages/amplify-cli/src/__tests__/test-aborting.test.ts +++ b/packages/amplify-cli/src/__tests__/test-aborting.test.ts @@ -32,6 +32,9 @@ describe('test SIGINT with execute', () => { FeatureFlags: { initialize: jest.fn(), }, + BannerMessage: { + initialize: jest.fn(), + }, PathConstants: { TeamProviderFileName: 'team-provider-info.json', DeploymentSecretsFileName: 'deployment-secrets.json', diff --git a/packages/amplify-cli/src/commands/push.ts b/packages/amplify-cli/src/commands/push.ts index 82fe294cefd..8efa0234b1e 100644 --- a/packages/amplify-cli/src/commands/push.ts +++ b/packages/amplify-cli/src/commands/push.ts @@ -2,7 +2,6 @@ import sequential from 'promise-sequential'; import ora from 'ora'; import { $TSContext, $TSObject, stateManager, exitOnNextTick } from 'amplify-cli-core'; import { getProviderPlugins } from '../extensions/amplify-helpers/get-provider-plugins'; -import { onSuccess } from '../init-steps/s9-onSuccess'; const spinner = ora(''); @@ -45,7 +44,6 @@ export const run = async (context: $TSContext) => { if (context.parameters.options.force) { context.exeInfo.forcePush = true; } - context.exeInfo.deferredInitCallback = onSuccess; await syncCurrentCloudBackend(context); return await context.amplify.pushResources(context); } catch (e) { diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/envResourceParams.ts b/packages/amplify-cli/src/extensions/amplify-helpers/envResourceParams.ts index 49af880b43c..956f581c273 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/envResourceParams.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/envResourceParams.ts @@ -75,12 +75,7 @@ export function saveEnvResourceParameters(context: $TSContext, category: string, stateManager.setTeamProviderInfo(undefined, teamProviderInfo); // write hostedUIProviderCreds to deploymentSecrets const deploymentSecrets = stateManager.getDeploymentSecrets(); - let rootStackId; - try { - rootStackId = getRootStackId(); - } catch (err) { - return; - } + const rootStackId = getRootStackId(); if (hostedUIProviderCreds) { stateManager.setDeploymentSecrets( mergeDeploymentSecrets({ diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/get-root-stack-id.ts b/packages/amplify-cli/src/extensions/amplify-helpers/get-root-stack-id.ts index 7dc9e095847..b1b285ae127 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/get-root-stack-id.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/get-root-stack-id.ts @@ -4,8 +4,8 @@ export function getRootStackId(): string { const teamProviderInfo = stateManager.getTeamProviderInfo(); const { envName } = stateManager.getLocalEnvInfo(); const envTeamProviderInfo = teamProviderInfo[envName]; - const stackId = envTeamProviderInfo?.awscloudformation?.StackId; - if (typeof stackId === 'string') { + if (envTeamProviderInfo && envTeamProviderInfo.awscloudformation) { + const stackId = envTeamProviderInfo.awscloudformation.StackId; return stackId.split('/')[2]; } throw new Error('Root stack Id not found'); diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/resource-status.ts b/packages/amplify-cli/src/extensions/amplify-helpers/resource-status.ts index dbe2e6491e3..ac6d9c4fc5f 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/resource-status.ts +++ b/packages/amplify-cli/src/extensions/amplify-helpers/resource-status.ts @@ -486,16 +486,12 @@ export async function showResourceTable(category, resourceName, filteredResource table(tableOptions, { format: 'markdown' }); - // in the case of a deferred init, need to also check there are resources in the project - // checking for length > 1 because for some reason the aws cfn provider is in the resources list but it's not a resource - const updateTags = tagsUpdated && allResources.length > 1; - - if (updateTags) { + if (tagsUpdated) { print.info('\nTag Changes Detected'); } const resourceChanged = - resourcesToBeCreated.length + resourcesToBeUpdated.length + resourcesToBeSynced.length + resourcesToBeDeleted.length > 0 || updateTags; + resourcesToBeCreated.length + resourcesToBeUpdated.length + resourcesToBeSynced.length + resourcesToBeDeleted.length > 0 || tagsUpdated; return resourceChanged; } diff --git a/packages/amplify-cli/src/index.ts b/packages/amplify-cli/src/index.ts index 2ac8b8cbc0a..83806e2f115 100644 --- a/packages/amplify-cli/src/index.ts +++ b/packages/amplify-cli/src/index.ts @@ -8,6 +8,8 @@ import { pathManager, stateManager, TeamProviderInfoMigrateError, + BannerMessage, + JSONUtilities, } from 'amplify-cli-core'; import { isCI } from 'ci-info'; import { EventEmitter } from 'events'; @@ -38,7 +40,7 @@ Error.stackTraceLimit = Number.MAX_SAFE_INTEGER; let errorHandler = (e: Error) => {}; -process.on('uncaughtException', function (error) { +process.on('uncaughtException', function(error) { // Invoke the configured error handler if it is already configured if (errorHandler) { errorHandler(error); @@ -57,7 +59,7 @@ process.on('uncaughtException', function (error) { }); // In this handler we have to rethrow the error otherwise the process stucks there. -process.on('unhandledRejection', function (error) { +process.on('unhandledRejection', function(error) { throw error; }); @@ -65,6 +67,7 @@ process.on('unhandledRejection', function (error) { export async function run() { try { deleteOldVersion(); + let pluginPlatform = await getPluginPlatform(); let input = getCommandLineInput(pluginPlatform); // with non-help command supplied, give notification before execution @@ -73,6 +76,10 @@ export async function run() { notify({ defer: false, isGlobal: true }); } + // Initialize Banner messages. These messages are set on the server side + const pkg = JSONUtilities.readJson<$TSAny>(path.join(__dirname, '..', 'package.json')); + BannerMessage.initialize(pkg.version); + ensureFilePermissions(pathManager.getAWSCredentialsFilePath()); ensureFilePermissions(pathManager.getAWSConfigFilePath()); diff --git a/packages/amplify-cli/src/init-steps/s9-onSuccess.ts b/packages/amplify-cli/src/init-steps/s9-onSuccess.ts index 4c7de3af5c1..940a772d858 100644 --- a/packages/amplify-cli/src/init-steps/s9-onSuccess.ts +++ b/packages/amplify-cli/src/init-steps/s9-onSuccess.ts @@ -6,7 +6,6 @@ import { getProviderPlugins } from '../extensions/amplify-helpers/get-provider-p import { insertAmplifyIgnore } from '../extensions/amplify-helpers/git-manager'; import { writeReadMeFile } from '../extensions/amplify-helpers/docs-manager'; import { initializeEnv } from '../initialize-env'; -import _ from 'lodash'; export async function onHeadlessSuccess(context: $TSContext) { const frontendPlugins = getFrontendPlugins(context); @@ -109,19 +108,12 @@ function generateLocalTagsFile(context: $TSContext) { } export function generateAmplifyMetaFile(context: $TSContext) { - const { projectPath } = context.exeInfo.localEnvInfo; - - const { isNewEnv } = context.exeInfo; - - // store amplifyMeta - const meta = isNewEnv ? {} : stateManager.getMeta(projectPath, { throwIfNotExist: false }) || {}; - _.merge(meta, context.exeInfo.amplifyMeta); - stateManager.setMeta(projectPath, meta); + if (context.exeInfo.isNewEnv) { + const { projectPath } = context.exeInfo.localEnvInfo; - // store current cloud meta - const currMeta = isNewEnv ? {} : stateManager.getCurrentMeta(projectPath, { throwIfNotExist: false }) || {}; - _.merge(currMeta, context.exeInfo.amplifyMeta); - stateManager.setCurrentMeta(projectPath, currMeta); + stateManager.setCurrentMeta(projectPath, context.exeInfo.amplifyMeta); + stateManager.setMeta(projectPath, context.exeInfo.amplifyMeta); + } } function generateNonRuntimeFiles(context: $TSContext) { diff --git a/packages/amplify-cli/src/initialize-env.ts b/packages/amplify-cli/src/initialize-env.ts index 953805580da..0679d9d99c1 100644 --- a/packages/amplify-cli/src/initialize-env.ts +++ b/packages/amplify-cli/src/initialize-env.ts @@ -81,12 +81,6 @@ export async function initializeEnv(context: $TSContext, currentAmplifyMeta?: $T await sequential(categoryInitializationTasks); - // this function can now be called on the push codepath in the case of a deffered root stack push - // in that case, we don't need to push here as that will happen automatically down the road - if (context?.input?.command === 'push') { - return; - } - if (context.exeInfo.forcePush === undefined) { context.exeInfo.forcePush = await context.amplify.confirmPrompt( 'Do you want to push your resources to the cloud for your environment?', diff --git a/packages/amplify-console-hosting/CHANGELOG.md b/packages/amplify-console-hosting/CHANGELOG.md index a5259e8f97e..5f4a31e6927 100644 --- a/packages/amplify-console-hosting/CHANGELOG.md +++ b/packages/amplify-console-hosting/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.8.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-console-hosting@1.8.7...amplify-console-hosting@1.8.8) (2021-05-18) + +**Note:** Version bump only for package amplify-console-hosting + + + + + +## [1.8.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-console-hosting@1.8.6...amplify-console-hosting@1.8.7) (2021-05-14) + +**Note:** Version bump only for package amplify-console-hosting + + + + + ## [1.8.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-console-hosting@1.8.4...amplify-console-hosting@1.8.6) (2021-05-03) diff --git a/packages/amplify-console-hosting/package.json b/packages/amplify-console-hosting/package.json index e871ebb3d30..10ebcf9e689 100644 --- a/packages/amplify-console-hosting/package.json +++ b/packages/amplify-console-hosting/package.json @@ -1,12 +1,12 @@ { "name": "amplify-console-hosting", - "version": "1.8.6", + "version": "1.8.8", "description": "cli plugin for AWS Amplify Console hosting", "main": "index.js", "author": "Amazon Web Services", "license": "Apache-2.0", "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "archiver": "^3.1.1", "aws-sdk": "^2.845.0", "chalk": "^3.0.0", diff --git a/packages/amplify-console-integration-tests/CHANGELOG.md b/packages/amplify-console-integration-tests/CHANGELOG.md index c2a044c094a..bc401921725 100644 --- a/packages/amplify-console-integration-tests/CHANGELOG.md +++ b/packages/amplify-console-integration-tests/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.6.1](https://github.com/aws-amplify/amplify-console-integration-tests/compare/amplify-console-integration-tests@1.6.0...amplify-console-integration-tests@1.6.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-console-integration-tests + + + + + +# [1.6.0](https://github.com/aws-amplify/amplify-console-integration-tests/compare/amplify-console-integration-tests@1.5.6...amplify-console-integration-tests@1.6.0) (2021-05-14) + + +### Features + +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-console-integration-tests/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-console-integration-tests/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + + + + ## [1.5.6](https://github.com/aws-amplify/amplify-console-integration-tests/compare/amplify-console-integration-tests@1.5.4...amplify-console-integration-tests@1.5.6) (2021-05-03) diff --git a/packages/amplify-console-integration-tests/package.json b/packages/amplify-console-integration-tests/package.json index 0e51f956ded..0cb4ed1b608 100644 --- a/packages/amplify-console-integration-tests/package.json +++ b/packages/amplify-console-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "amplify-console-integration-tests", - "version": "1.5.6", + "version": "1.6.1", "description": "", "repository": { "type": "git", @@ -22,7 +22,7 @@ }, "dependencies": { "@types/ini": "^1.3.30", - "amplify-e2e-core": "1.18.2", + "amplify-e2e-core": "1.19.1", "aws-sdk": "^2.845.0", "dotenv": "^8.2.0", "esm": "^3.2.25", diff --git a/packages/amplify-container-hosting/CHANGELOG.md b/packages/amplify-container-hosting/CHANGELOG.md index 063a8a56ea7..527f66284ce 100644 --- a/packages/amplify-container-hosting/CHANGELOG.md +++ b/packages/amplify-container-hosting/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.3.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-container-hosting@1.3.7...amplify-container-hosting@1.3.8) (2021-05-18) + +**Note:** Version bump only for package amplify-container-hosting + + + + + +## [1.3.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-container-hosting@1.3.6...amplify-container-hosting@1.3.7) (2021-05-14) + +**Note:** Version bump only for package amplify-container-hosting + + + + + ## [1.3.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-container-hosting@1.3.4...amplify-container-hosting@1.3.6) (2021-05-03) diff --git a/packages/amplify-container-hosting/package.json b/packages/amplify-container-hosting/package.json index 31ece1c4ce3..399bdf40075 100644 --- a/packages/amplify-container-hosting/package.json +++ b/packages/amplify-container-hosting/package.json @@ -1,6 +1,6 @@ { "name": "amplify-container-hosting", - "version": "1.3.6", + "version": "1.3.8", "description": "amplify-cli hosting plugin for containers", "repository": { "type": "git", @@ -18,7 +18,7 @@ "test": "jest --coverage --passWithNoTests" }, "dependencies": { - "amplify-category-api": "2.31.6", + "amplify-category-api": "2.31.8", "chalk": "^3.0.0", "fs-extra": "^8.1.0", "inquirer": "^7.3.3", diff --git a/packages/amplify-dotnet-function-template-provider/CHANGELOG.md b/packages/amplify-dotnet-function-template-provider/CHANGELOG.md index 915429dbedd..e35c72516d1 100644 --- a/packages/amplify-dotnet-function-template-provider/CHANGELOG.md +++ b/packages/amplify-dotnet-function-template-provider/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.5.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-dotnet-function-template-provider@1.5.7...amplify-dotnet-function-template-provider@1.5.8) (2021-05-18) + +**Note:** Version bump only for package amplify-dotnet-function-template-provider + + + + + +## [1.5.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-dotnet-function-template-provider@1.5.6...amplify-dotnet-function-template-provider@1.5.7) (2021-05-14) + +**Note:** Version bump only for package amplify-dotnet-function-template-provider + + + + + ## [1.5.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-dotnet-function-template-provider@1.5.4...amplify-dotnet-function-template-provider@1.5.6) (2021-05-03) diff --git a/packages/amplify-dotnet-function-template-provider/package.json b/packages/amplify-dotnet-function-template-provider/package.json index 591bea2cc32..5a2a6913a29 100644 --- a/packages/amplify-dotnet-function-template-provider/package.json +++ b/packages/amplify-dotnet-function-template-provider/package.json @@ -1,6 +1,6 @@ { "name": "amplify-dotnet-function-template-provider", - "version": "1.5.6", + "version": "1.5.8", "description": ".NET Core templates supplied by the Amplify Team", "repository": { "type": "git", @@ -22,9 +22,9 @@ "clean": "rimraf lib tsconfig.tsbuildinfo" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/inquirer": "^6.5.0", diff --git a/packages/amplify-dynamodb-simulator/CHANGELOG.md b/packages/amplify-dynamodb-simulator/CHANGELOG.md index e6677207d9d..c18e9de4fa1 100644 --- a/packages/amplify-dynamodb-simulator/CHANGELOG.md +++ b/packages/amplify-dynamodb-simulator/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.18.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-dynamodb-simulator@1.18.7...amplify-dynamodb-simulator@1.18.8) (2021-05-18) + +**Note:** Version bump only for package amplify-dynamodb-simulator + + + + + +## [1.18.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-dynamodb-simulator@1.18.6...amplify-dynamodb-simulator@1.18.7) (2021-05-14) + +**Note:** Version bump only for package amplify-dynamodb-simulator + + + + + ## [1.18.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-dynamodb-simulator@1.18.4...amplify-dynamodb-simulator@1.18.6) (2021-05-03) diff --git a/packages/amplify-dynamodb-simulator/package.json b/packages/amplify-dynamodb-simulator/package.json index 6c3c4f14795..89b45e09c07 100644 --- a/packages/amplify-dynamodb-simulator/package.json +++ b/packages/amplify-dynamodb-simulator/package.json @@ -1,6 +1,6 @@ { "name": "amplify-dynamodb-simulator", - "version": "1.18.6", + "version": "1.18.8", "description": "DynamoDB emulator nodejs wrapper", "repository": { "type": "git", @@ -20,7 +20,7 @@ "test": "jest" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "aws-sdk": "^2.845.0", "detect-port": "^1.3.0", "event-to-promise": "^0.8.0", diff --git a/packages/amplify-e2e-core/CHANGELOG.md b/packages/amplify-e2e-core/CHANGELOG.md index 3e316a24ae7..bf99f9b2652 100644 --- a/packages/amplify-e2e-core/CHANGELOG.md +++ b/packages/amplify-e2e-core/CHANGELOG.md @@ -3,6 +3,38 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.19.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-core@1.19.0...amplify-e2e-core@1.19.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + + +### Bug Fixes + +* nexpect pathname parsing ([#7324](https://github.com/aws-amplify/amplify-cli/issues/7324)) ([#7325](https://github.com/aws-amplify/amplify-cli/issues/7325)) ([ed8dc22](https://github.com/aws-amplify/amplify-cli/commit/ed8dc221d92585a74e7e8214dcd721f5d27d5d11)) + + + + + +# [1.19.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-core@1.18.2...amplify-e2e-core@1.19.0) (2021-05-14) + + +### Features + +* defer root stack creation to first `amplify push` ([#7174](https://github.com/aws-amplify/amplify-cli/issues/7174)) ([d28dd1c](https://github.com/aws-amplify/amplify-cli/commit/d28dd1caca86b19a858dab0e7aa907d1cc74c86a)) +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-cli/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-cli/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + +### Reverts + +* Revert "feat: defer root stack creation to first `amplify push` (#7174)" (#7306) ([78854eb](https://github.com/aws-amplify/amplify-cli/commit/78854ebd4a3d41d34d68736d6556045302101265)), closes [#7174](https://github.com/aws-amplify/amplify-cli/issues/7174) [#7306](https://github.com/aws-amplify/amplify-cli/issues/7306) + + + + + ## [1.18.2](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-core@1.18.0...amplify-e2e-core@1.18.2) (2021-05-03) diff --git a/packages/amplify-e2e-core/package.json b/packages/amplify-e2e-core/package.json index 90eed4637c7..dd7ea152784 100644 --- a/packages/amplify-e2e-core/package.json +++ b/packages/amplify-e2e-core/package.json @@ -1,6 +1,6 @@ { "name": "amplify-e2e-core", - "version": "1.18.2", + "version": "1.19.1", "description": "", "repository": { "type": "git", @@ -22,12 +22,12 @@ "clean": "rimraf ./lib" }, "dependencies": { - "amplify-cli-core": "1.21.2", - "amplify-headless-interface": "1.5.3", + "amplify-cli-core": "1.22.1", + "amplify-headless-interface": "1.6.1", "chalk": "^3.0.0", "execa": "^4.1.0", "fs-extra": "^8.1.0", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "jest-environment-node": "^26.6.2", "lodash": "^4.17.19", "node-pty-prebuilt-multiarch": "^0.9.0", diff --git a/packages/amplify-e2e-core/src/categories/auth.ts b/packages/amplify-e2e-core/src/categories/auth.ts index a229f34df8a..71837cca985 100644 --- a/packages/amplify-e2e-core/src/categories/auth.ts +++ b/packages/amplify-e2e-core/src/categories/auth.ts @@ -1302,3 +1302,49 @@ export function updateAuthAddAdminQueries(projectDir: string, groupName: string }); }); } + +export function updateAuthWithoutTrigger(cwd: string, settings: any): Promise { + return new Promise((resolve, reject) => { + spawn(getCLIPath(), ['update', 'auth'], { cwd, stripColors: true }) + .wait('What do you want to do?') + .send(KEY_DOWN_ARROW) + .sendCarriageReturn() + .wait('Select the authentication/authorization services that you want to use:') + .send(KEY_DOWN_ARROW) + .sendCarriageReturn() + .wait('Do you want to add User Pool Groups?') + .send(KEY_DOWN_ARROW) + .sendCarriageReturn() + .wait('Do you want to add an admin queries API?') + .send(KEY_DOWN_ARROW) + .sendCarriageReturn() + .wait('Multifactor authentication (MFA) user login options:') + .sendCarriageReturn() + .wait('Email based user registration/forgot password:') + .sendCarriageReturn() + .wait('Please specify an email verification subject:') + .sendCarriageReturn() + .wait('Please specify an email verification message:') + .sendCarriageReturn() + .wait('Do you want to override the default password policy for this User Pool?') + .sendCarriageReturn() + .wait("Specify the app's refresh token expiration period (in days):") + .sendCarriageReturn() + .wait('Do you want to specify the user attributes this app can read and write?') + .sendCarriageReturn() + .wait('Do you want to enable any of the following capabilities?') + .sendCarriageReturn() + .wait('Do you want to use an OAuth flow?') + .send(KEY_DOWN_ARROW) + .sendCarriageReturn() + .wait('Do you want to configure Lambda Triggers for Cognito?') + .sendLine('n') + .run((err: Error) => { + if (!err) { + resolve(); + } else { + reject(err); + } + }); + }); +} diff --git a/packages/amplify-e2e-core/src/init/deleteProject.ts b/packages/amplify-e2e-core/src/init/deleteProject.ts index 782fdfdc84a..5af02b32229 100644 --- a/packages/amplify-e2e-core/src/init/deleteProject.ts +++ b/packages/amplify-e2e-core/src/init/deleteProject.ts @@ -2,9 +2,6 @@ import { nspawn as spawn, retry, getCLIPath, describeCloudFormationStack, getPro export const deleteProject = async (cwd: string, profileConfig?: any): Promise => { const { StackName: stackName, Region: region } = getProjectMeta(cwd).providers.awscloudformation; - if (!stackName || !region) { - return; - } await retry( () => describeCloudFormationStack(stackName, region, profileConfig), stack => stack.StackStatus.endsWith('_COMPLETE'), diff --git a/packages/amplify-e2e-core/src/utils/nexpect.ts b/packages/amplify-e2e-core/src/utils/nexpect.ts index 9fa878f9797..239f8a4e226 100644 --- a/packages/amplify-e2e-core/src/utils/nexpect.ts +++ b/packages/amplify-e2e-core/src/utils/nexpect.ts @@ -19,6 +19,7 @@ import { AssertionError } from 'assert'; import strip = require('strip-ansi'); import { EOL } from 'os'; import retimer = require('retimer'); +import { join, parse } from 'path'; const DEFAULT_NO_OUTPUT_TIMEOUT = 5 * 60 * 1000; // 5 Minutes const EXIT_CODE_TIMEOUT = 2; @@ -592,9 +593,10 @@ export function nspawn(command: string | string[], params: string[] = [], option params = command; command = params.shift(); } else if (typeof command === 'string') { - command = command.split(' '); - params = params || command.slice(1); - command = command[0]; + const parsedPath = parse(command); + const parsedArgs = parsedPath.base.split(' '); + command = join(parsedPath.dir, parsedArgs[0]); + params = params || parsedArgs.slice(1); } let childEnv = undefined; diff --git a/packages/amplify-e2e-tests/CHANGELOG.md b/packages/amplify-e2e-tests/CHANGELOG.md index ca10c95b421..4890b8c29eb 100644 --- a/packages/amplify-e2e-tests/CHANGELOG.md +++ b/packages/amplify-e2e-tests/CHANGELOG.md @@ -3,6 +3,35 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.40.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-tests@2.40.0...amplify-e2e-tests@2.40.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-e2e-tests + + + + + +# [2.40.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-tests@2.39.2...amplify-e2e-tests@2.40.0) (2021-05-14) + + +### Features + +* defer root stack creation to first `amplify push` ([#7174](https://github.com/aws-amplify/amplify-cli/issues/7174)) ([d28dd1c](https://github.com/aws-amplify/amplify-cli/commit/d28dd1caca86b19a858dab0e7aa907d1cc74c86a)) +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-cli/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-cli/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + +### Reverts + +* Revert "feat: defer root stack creation to first `amplify push` (#7174)" (#7306) ([78854eb](https://github.com/aws-amplify/amplify-cli/commit/78854ebd4a3d41d34d68736d6556045302101265)), closes [#7174](https://github.com/aws-amplify/amplify-cli/issues/7174) [#7306](https://github.com/aws-amplify/amplify-cli/issues/7306) + + + + + ## [2.39.2](https://github.com/aws-amplify/amplify-cli/compare/amplify-e2e-tests@2.39.0...amplify-e2e-tests@2.39.2) (2021-05-03) diff --git a/packages/amplify-e2e-tests/package.json b/packages/amplify-e2e-tests/package.json index ca328290fb8..f0ed16e7fb8 100644 --- a/packages/amplify-e2e-tests/package.json +++ b/packages/amplify-e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "amplify-e2e-tests", - "version": "2.39.2", + "version": "2.40.1", "description": "", "repository": { "type": "git", @@ -22,8 +22,8 @@ "clean-e2e-resources": "ts-node ./src/cleanup-e2e-resources.ts" }, "dependencies": { - "amplify-cli-core": "1.21.2", - "amplify-e2e-core": "1.18.2", + "amplify-cli-core": "1.22.1", + "amplify-e2e-core": "1.19.1", "aws-amplify": "^3.0.8", "aws-appsync": "^4.0.3", "aws-sdk": "^2.845.0", @@ -33,7 +33,7 @@ "fs-extra": "^8.1.0", "graphql-schema-diff": "^2.2.0", "graphql-tag": "^2.10.1", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "lodash": "^4.17.19", "promise-sequential": "^1.1.1", "rimraf": "^3.0.0", diff --git a/packages/amplify-e2e-tests/src/__tests__/defer-init-push.test.ts b/packages/amplify-e2e-tests/src/__tests__/defer-init-push.test.ts deleted file mode 100644 index 9b1071dc439..00000000000 --- a/packages/amplify-e2e-tests/src/__tests__/defer-init-push.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { - addFunction, - amplifyInitYes, - amplifyPushAuth, - createNewProjectDir, - deleteProject, - deleteProjectDir, - getLocalEnvInfo, - getTeamProviderInfo, - initJSProjectWithProfile, -} from 'amplify-e2e-core'; -import { addEnvironment, addEnvironmentYes, checkoutEnvironment, removeEnvironment } from '../environment/env'; - -describe('defer root stack push', () => { - let projRoot: string; - beforeEach(async () => { - projRoot = await createNewProjectDir('defer-init-push'); - }); - - afterEach(async () => { - await deleteProject(projRoot); - deleteProjectDir(projRoot); - }); - - it('does not create a root stack on interactive init', async () => { - await initJSProjectWithProfile(projRoot, { name: 'deferInitPush', envName: 'dev' }); - const tpi_before = getTeamProviderInfo(projRoot); - expect(tpi_before?.dev?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - await addFunction(projRoot, { functionTemplate: 'Hello World' }, 'nodejs'); - await amplifyPushAuth(projRoot); - const tpi_after = getTeamProviderInfo(projRoot); - expect(tpi_after?.dev?.awscloudformation?.DeploymentBucketName).toBeDefined(); - }); - - it('does not create a root stack on interactive env add', async () => { - await initJSProjectWithProfile(projRoot, { name: 'deferInitPush', envName: 'dev' }); - const tpi_dev = getTeamProviderInfo(projRoot); - expect(tpi_dev?.dev?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - await addEnvironment(projRoot, { envName: 'test' }); - const tpi_test = getTeamProviderInfo(projRoot); - expect(tpi_test?.test?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - }); - - it('creates a root stack on headless init', async () => { - await amplifyInitYes(projRoot); - const tpi_after = getTeamProviderInfo(projRoot); - expect(tpi_after?.dev?.awscloudformation?.DeploymentBucketName).toBeDefined(); - }); - - it('creates a root stack on headless env add', async () => { - await initJSProjectWithProfile(projRoot, { name: 'deferInitPush', envName: 'dev' }); - const tpi_dev = getTeamProviderInfo(projRoot); - expect(tpi_dev?.dev?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - await addEnvironmentYes(projRoot, { envName: 'test' }); - const tpi_test = getTeamProviderInfo(projRoot); - expect(tpi_test?.test?.awscloudformation?.DeploymentBucketName).toBeDefined(); - }); - - it('can checkout unpushed environment', async () => { - await initJSProjectWithProfile(projRoot, { name: 'deferInitPush', envName: 'dev' }); - const tpi_dev = getTeamProviderInfo(projRoot); - expect(tpi_dev?.dev?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - await addEnvironment(projRoot, { envName: 'test' }); - const tpi_test = getTeamProviderInfo(projRoot); - expect(tpi_test?.test?.awscloudformation?.DeploymentBucketName).toBeUndefined(); - await checkoutEnvironment(projRoot, { envName: 'dev' }); - const localEnvInfo = getLocalEnvInfo(projRoot); - expect(localEnvInfo?.envName).toEqual('dev'); - }); - - it('can remove unpushed environment', async () => { - await initJSProjectWithProfile(projRoot, { name: 'deferInitPush', envName: 'dev' }); - await addEnvironment(projRoot, { envName: 'test' }); - await checkoutEnvironment(projRoot, { envName: 'dev' }); - const tpi_before = getTeamProviderInfo(projRoot); - expect(Object.keys(tpi_before).sort()).toEqual(['dev', 'test']); - await removeEnvironment(projRoot, { envName: 'test' }); - const tpi_after = getTeamProviderInfo(projRoot); - expect(Object.keys(tpi_after)).toEqual(['dev']); - }); -}); diff --git a/packages/amplify-frontend-ios/CHANGELOG.md b/packages/amplify-frontend-ios/CHANGELOG.md index 64adb55172b..5d43a3a4ca0 100644 --- a/packages/amplify-frontend-ios/CHANGELOG.md +++ b/packages/amplify-frontend-ios/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.20.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-ios@2.20.0...amplify-frontend-ios@2.20.1) (2021-05-18) + +**Note:** Version bump only for package amplify-frontend-ios + + + + + +# [2.20.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-ios@2.19.6...amplify-frontend-ios@2.20.0) (2021-05-14) + + +### Bug Fixes + +* remove optional chaining in JS file ([#7287](https://github.com/aws-amplify/amplify-cli/issues/7287)) ([abb64f6](https://github.com/aws-amplify/amplify-cli/commit/abb64f618e6b5e52b40d779568c06eed305ac179)) + + +### Features + +* **amplify-frontend-ios:** amplify-xcode integration ([#6867](https://github.com/aws-amplify/amplify-cli/issues/6867)) ([338cea2](https://github.com/aws-amplify/amplify-cli/commit/338cea2f574bab242311989bc5024b9e149bd48b)) + + + + + ## [2.19.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-ios@2.19.4...amplify-frontend-ios@2.19.6) (2021-05-03) diff --git a/packages/amplify-frontend-ios/package.json b/packages/amplify-frontend-ios/package.json index daf5d4a2494..ccf4b8a0973 100644 --- a/packages/amplify-frontend-ios/package.json +++ b/packages/amplify-frontend-ios/package.json @@ -1,6 +1,6 @@ { "name": "amplify-frontend-ios", - "version": "2.19.6", + "version": "2.20.1", "description": "amplify-cli front-end plugin for xcode projects", "repository": { "type": "git", @@ -21,7 +21,7 @@ "test-watch": "jest --watch" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "execa": "^4.1.0", "fs-extra": "^8.1.0", "graphql-config": "^2.2.1", diff --git a/packages/amplify-frontend-javascript/CHANGELOG.md b/packages/amplify-frontend-javascript/CHANGELOG.md index 36f6802332f..1d3f62c2e32 100644 --- a/packages/amplify-frontend-javascript/CHANGELOG.md +++ b/packages/amplify-frontend-javascript/CHANGELOG.md @@ -3,6 +3,32 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.22.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-javascript@2.22.0...amplify-frontend-javascript@2.22.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + + +### Bug Fixes + +* respect headless frontend JS config input ([#7328](https://github.com/aws-amplify/amplify-cli/issues/7328)) ([4cc2b2c](https://github.com/aws-amplify/amplify-cli/commit/4cc2b2c9bb7fa04d5722f758cdad7e7b8c3cafc7)) + + + + + +# [2.22.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-javascript@2.21.6...amplify-frontend-javascript@2.22.0) (2021-05-14) + + +### Features + +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-cli/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-cli/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + + + + ## [2.21.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-frontend-javascript@2.21.4...amplify-frontend-javascript@2.21.6) (2021-05-03) diff --git a/packages/amplify-frontend-javascript/lib/framework-config-mapping.js b/packages/amplify-frontend-javascript/lib/framework-config-mapping.js index f36e9424338..4328df978c9 100644 --- a/packages/amplify-frontend-javascript/lib/framework-config-mapping.js +++ b/packages/amplify-frontend-javascript/lib/framework-config-mapping.js @@ -80,22 +80,34 @@ function getAngularConfig(context, projectPath) { } function getProjectConfiguration(context, framework, projectPath) { + let config; + switch (framework) { case 'angular': - return getAngularConfig(context, projectPath); + config = getAngularConfig(context, projectPath); + break; case 'ember': - return emberConfig; + config = emberConfig; + break; case 'ionic': - return ionicConfig; + config = ionicConfig; + break; case 'react': - return reactConfig; + config = reactConfig; + break; case 'react-native': - return reactNativeConfig; + config = reactNativeConfig; + break; case 'vue': - return vueConfig; + config = vueConfig; + break; default: - return defaultConfig; + config = defaultConfig; } + + const headlessConfig = _.get(context, 'exeInfo.inputParams.javascript.config', {}); + config = Object.assign({}, config, headlessConfig); + return config; } function getSupportedFrameworks() { diff --git a/packages/amplify-frontend-javascript/package.json b/packages/amplify-frontend-javascript/package.json index b35f20a1ca3..3972508f0c8 100644 --- a/packages/amplify-frontend-javascript/package.json +++ b/packages/amplify-frontend-javascript/package.json @@ -1,6 +1,6 @@ { "name": "amplify-frontend-javascript", - "version": "2.21.6", + "version": "2.22.1", "description": "amplify-cli front-end plugin for JavaScript projects", "repository": { "type": "git", @@ -16,7 +16,7 @@ "aws" ], "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "chalk": "^3.0.0", "execa": "^4.1.0", "fs-extra": "^8.1.0", diff --git a/packages/amplify-go-function-runtime-provider/CHANGELOG.md b/packages/amplify-go-function-runtime-provider/CHANGELOG.md index 05ea8fbeaf7..9a9009a398d 100644 --- a/packages/amplify-go-function-runtime-provider/CHANGELOG.md +++ b/packages/amplify-go-function-runtime-provider/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.8.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-go-function-runtime-provider@1.8.0...amplify-go-function-runtime-provider@1.8.1) (2021-05-18) + +**Note:** Version bump only for package amplify-go-function-runtime-provider + + + + + +# [1.8.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-go-function-runtime-provider@1.7.6...amplify-go-function-runtime-provider@1.8.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + + + + ## [1.7.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-go-function-runtime-provider@1.7.4...amplify-go-function-runtime-provider@1.7.6) (2021-05-03) diff --git a/packages/amplify-go-function-runtime-provider/package.json b/packages/amplify-go-function-runtime-provider/package.json index 570a17ed031..98a685132c6 100644 --- a/packages/amplify-go-function-runtime-provider/package.json +++ b/packages/amplify-go-function-runtime-provider/package.json @@ -1,6 +1,6 @@ { "name": "amplify-go-function-runtime-provider", - "version": "1.7.6", + "version": "1.8.1", "description": "Provides functionality related to functions in Go 1.x on AWS", "repository": { "type": "git", @@ -21,14 +21,14 @@ "clean": "rimraf lib tsconfig.tsbuildinfo resources/localinvoke/go.sum resources/localinvoke/main resources/localinvoke/main.exe" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", "archiver": "^3.1.1", "execa": "^4.1.0", "fs-extra": "^8.1.0", "glob": "^7.1.6", "portfinder": "^1.0.25", - "semver": "^7.1.3", + "semver": "^7.3.5", "which": "^2.0.2" }, "devDependencies": { diff --git a/packages/amplify-graphiql-explorer/CHANGELOG.md b/packages/amplify-graphiql-explorer/CHANGELOG.md index e4827f775cf..50e9dfb9b5a 100644 --- a/packages/amplify-graphiql-explorer/CHANGELOG.md +++ b/packages/amplify-graphiql-explorer/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.6.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-graphiql-explorer@1.6.0...amplify-graphiql-explorer@1.6.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-graphiql-explorer + + + + + # [1.6.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-graphiql-explorer@1.4.3...amplify-graphiql-explorer@1.6.0) (2021-05-03) diff --git a/packages/amplify-graphiql-explorer/package.json b/packages/amplify-graphiql-explorer/package.json index 4361011eef9..538cf22d1e4 100644 --- a/packages/amplify-graphiql-explorer/package.json +++ b/packages/amplify-graphiql-explorer/package.json @@ -1,6 +1,6 @@ { "name": "amplify-graphiql-explorer", - "version": "1.6.0", + "version": "1.6.1", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.11.4", @@ -26,7 +26,7 @@ "license": "Apache-2.0", "scripts": { "start": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts start", - "build": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts build", + "build": "cross-env SKIP_PREFLIGHT_CHECK=true react-scripts --max-old-space-size=8192 build", "eject": "react-scripts eject" }, "eslintConfig": { diff --git a/packages/amplify-graphql-docs-generator/CHANGELOG.md b/packages/amplify-graphql-docs-generator/CHANGELOG.md index 80820ed89d5..7b93a334eb5 100644 --- a/packages/amplify-graphql-docs-generator/CHANGELOG.md +++ b/packages/amplify-graphql-docs-generator/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.2.4](https://github.com/aws-amplify/amplify-cli/compare/amplify-graphql-docs-generator@2.2.3...amplify-graphql-docs-generator@2.2.4) (2021-05-14) + +**Note:** Version bump only for package amplify-graphql-docs-generator + + + + + ## [2.2.3](https://github.com/aws-amplify/amplify-cli/compare/amplify-graphql-docs-generator@2.2.1...amplify-graphql-docs-generator@2.2.3) (2021-05-03) diff --git a/packages/amplify-graphql-docs-generator/package.json b/packages/amplify-graphql-docs-generator/package.json index 4605e5bfdfc..7117f936e33 100644 --- a/packages/amplify-graphql-docs-generator/package.json +++ b/packages/amplify-graphql-docs-generator/package.json @@ -1,6 +1,6 @@ { "name": "amplify-graphql-docs-generator", - "version": "2.2.3", + "version": "2.2.4", "description": "amplify graphql docs generator plugin", "repository": { "type": "git", diff --git a/packages/amplify-graphql-function-transformer/CHANGELOG.md b/packages/amplify-graphql-function-transformer/CHANGELOG.md index 4171be71750..c9edb653cbc 100644 --- a/packages/amplify-graphql-function-transformer/CHANGELOG.md +++ b/packages/amplify-graphql-function-transformer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.1](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-function-transformer@0.3.0...@aws-amplify/graphql-function-transformer@0.3.1) (2021-05-18) + +**Note:** Version bump only for package @aws-amplify/graphql-function-transformer + + + + + # 0.3.0 (2021-05-03) diff --git a/packages/amplify-graphql-function-transformer/package.json b/packages/amplify-graphql-function-transformer/package.json index f5f6b77bbed..8c4a7516057 100644 --- a/packages/amplify-graphql-function-transformer/package.json +++ b/packages/amplify-graphql-function-transformer/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/graphql-function-transformer", - "version": "0.3.0", + "version": "0.3.1", "description": "Amplify GraphQL @function tranformer", "repository": { "type": "git", @@ -27,8 +27,8 @@ "test": "jest" }, "dependencies": { - "@aws-amplify/graphql-transformer-core": "0.5.0", - "@aws-amplify/graphql-transformer-interfaces": "1.5.0", + "@aws-amplify/graphql-transformer-core": "0.6.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", "@aws-cdk/aws-lambda": "~1.72.0", "@aws-cdk/core": "~1.72.0", "graphql": "^14.5.8", diff --git a/packages/amplify-graphql-http-transformer/CHANGELOG.md b/packages/amplify-graphql-http-transformer/CHANGELOG.md index 466fb7003e1..c0443e4a3d8 100644 --- a/packages/amplify-graphql-http-transformer/CHANGELOG.md +++ b/packages/amplify-graphql-http-transformer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.1](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-http-transformer@0.3.0...@aws-amplify/graphql-http-transformer@0.3.1) (2021-05-18) + +**Note:** Version bump only for package @aws-amplify/graphql-http-transformer + + + + + # 0.3.0 (2021-05-03) diff --git a/packages/amplify-graphql-http-transformer/package.json b/packages/amplify-graphql-http-transformer/package.json index 4871e11af8c..4f4b7d4aeb4 100644 --- a/packages/amplify-graphql-http-transformer/package.json +++ b/packages/amplify-graphql-http-transformer/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/graphql-http-transformer", - "version": "0.3.0", + "version": "0.3.1", "description": "Amplify GraphQL @http tranformer", "repository": { "type": "git", @@ -27,8 +27,8 @@ "test": "jest" }, "dependencies": { - "@aws-amplify/graphql-transformer-core": "0.5.0", - "@aws-amplify/graphql-transformer-interfaces": "1.5.0", + "@aws-amplify/graphql-transformer-core": "0.6.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", "@aws-cdk/core": "~1.72.0", "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", diff --git a/packages/amplify-graphql-model-transformer/CHANGELOG.md b/packages/amplify-graphql-model-transformer/CHANGELOG.md index 7aba329a74c..4e2c36c18c4 100644 --- a/packages/amplify-graphql-model-transformer/CHANGELOG.md +++ b/packages/amplify-graphql-model-transformer/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.4.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-model-transformer@0.3.6...@aws-amplify/graphql-model-transformer@0.4.0) (2021-05-18) + + +### Features + +* port [@searchable](https://github.com/searchable) to GraphQL Transformer v2 ([#7291](https://github.com/aws-amplify/amplify-cli/issues/7291)) ([37a2df2](https://github.com/aws-amplify/amplify-cli/commit/37a2df2365fe4bf0eddf285a159221e34f695fe2)) + + + + + ## [0.3.6](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-model-transformer@0.3.4...@aws-amplify/graphql-model-transformer@0.3.6) (2021-05-03) diff --git a/packages/amplify-graphql-model-transformer/package.json b/packages/amplify-graphql-model-transformer/package.json index e79c280639c..e6158963033 100644 --- a/packages/amplify-graphql-model-transformer/package.json +++ b/packages/amplify-graphql-model-transformer/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/graphql-model-transformer", - "version": "0.3.6", + "version": "0.4.0", "description": "Amplfy graphql @model tranformer", "repository": { "type": "git", @@ -26,8 +26,8 @@ "clean": "rimraf ./lib" }, "dependencies": { - "@aws-amplify/graphql-transformer-core": "0.5.0", - "@aws-amplify/graphql-transformer-interfaces": "1.5.0", + "@aws-amplify/graphql-transformer-core": "0.6.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", "@aws-cdk/assets": "~1.72.0", "@aws-cdk/aws-applicationautoscaling": "~1.72.0", "@aws-cdk/aws-autoscaling-common": "~1.72.0", diff --git a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts index 8a03b97231c..5b32a182cc8 100644 --- a/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts +++ b/packages/amplify-graphql-model-transformer/src/graphql-model-transformer.ts @@ -12,7 +12,7 @@ import { TransformerPrepareStepContextProvider, TransformerResolverProvider, } from '@aws-amplify/graphql-transformer-interfaces'; -import { AttributeType, ITable, Table, TableEncryption } from '@aws-cdk/aws-dynamodb'; +import { AttributeType, ITable, StreamViewType, Table, TableEncryption } from '@aws-cdk/aws-dynamodb'; import { RemovalPolicy } from '@aws-cdk/core'; import { DirectiveNode, InputObjectTypeDefinitionNode, InputValueDefinitionNode, ObjectTypeDefinitionNode } from 'graphql'; import { @@ -257,6 +257,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme name: 'id', type: AttributeType.STRING, }, + stream: StreamViewType.NEW_AND_OLD_IMAGES, encryption: TableEncryption.DEFAULT, removalPolicy: RemovalPolicy.DESTROY, }); diff --git a/packages/amplify-graphql-searchable-transformer/CHANGELOG.md b/packages/amplify-graphql-searchable-transformer/CHANGELOG.md new file mode 100644 index 00000000000..dafa7f17c04 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/CHANGELOG.md @@ -0,0 +1,11 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.2.0 (2021-05-18) + + +### Features + +* port [@searchable](https://github.com/searchable) to GraphQL Transformer v2 ([#7291](https://github.com/aws-amplify/amplify-cli/issues/7291)) ([37a2df2](https://github.com/aws-amplify/amplify-cli/commit/37a2df2365fe4bf0eddf285a159221e34f695fe2)) diff --git a/packages/amplify-graphql-searchable-transformer/Readme.md b/packages/amplify-graphql-searchable-transformer/Readme.md new file mode 100644 index 00000000000..4b9564287c4 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/Readme.md @@ -0,0 +1,18 @@ +# GraphQL @searchable Transformer + +# Reference Documentation + +### @searchable + +The `@searchable` directive handles streaming the data of an `@model` object type to +Elasticsearch and configures search resolvers that search that information. + +#### Definition + +```graphql +# Streams data from dynamodb into elasticsearch and exposes search capabilities. +directive @searchable(queries: SearchableQueryMap) on OBJECT +input SearchableQueryMap { + search: String +} +``` diff --git a/packages/amplify-graphql-searchable-transformer/package.json b/packages/amplify-graphql-searchable-transformer/package.json new file mode 100644 index 00000000000..e506aec8e20 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/package.json @@ -0,0 +1,64 @@ +{ + "name": "@aws-amplify/graphql-searchable-transformer", + "version": "0.2.0", + "description": "Amplfy GraphQL @searchable transformer", + "repository": { + "type": "git", + "url": "https://github.com/aws-amplify/amplify-cli.git", + "directory": "packages/amplify-graphql-searchable-transformer" + }, + "author": "Amazon Web Services", + "license": "Apache-2.0", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "keywords": [ + "graphql", + "cloudformation", + "aws", + "amplify" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "tsc && cd streaming-lambda && bestzip --force node ../lib/streaming-lambda.zip python_streaming_function.py", + "watch": "tsc -w", + "clean": "rimraf ./lib", + "test": "jest" + }, + "dependencies": { + "@aws-amplify/graphql-transformer-core": "0.6.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", + "@aws-cdk/aws-appsync": "~1.72.0", + "@aws-cdk/aws-dynamodb": "~1.72.0", + "@aws-cdk/aws-ec2": "~1.72.0", + "@aws-cdk/aws-elasticsearch": "1.72.0", + "@aws-cdk/aws-iam": "~1.72.0", + "@aws-cdk/aws-lambda": "~1.72.0", + "@aws-cdk/core": "~1.72.0", + "graphql": "^14.5.8", + "graphql-mapping-template": "4.18.1", + "graphql-transformer-common": "4.19.3" + }, + "devDependencies": { + "@aws-cdk/assert": "~1.72.0", + "@types/fs-extra": "^8.0.1", + "@types/node": "^10.17.13" + }, + "jest": { + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "testURL": "http://localhost", + "testRegex": "(src/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "moduleFileExtensions": [ + "ts", + "tsx", + "js", + "jsx", + "json", + "node" + ], + "collectCoverage": true + } +} diff --git a/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap new file mode 100644 index 00000000000..7e4413e53e8 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/__tests__/__snapshots__/amplify-graphql-searchable-transformer.tests.ts.snap @@ -0,0 +1,1762 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Test SearchableModelTransformer validation happy case 1`] = ` +" +type Post { + id: ID! + title: String! + createdAt: String + updatedAt: String +} + +input SearchableStringFilterInput { + ne: String + gt: String + lt: String + gte: String + lte: String + eq: String + match: String + matchPhrase: String + matchPhrasePrefix: String + multiMatch: String + exists: Boolean + wildcard: String + regexp: String + range: [String] +} + +input SearchableIntFilterInput { + ne: Int + gt: Int + lt: Int + gte: Int + lte: Int + eq: Int + range: [Int] +} + +input SearchableFloatFilterInput { + ne: Float + gt: Float + lt: Float + gte: Float + lte: Float + eq: Float + range: [Float] +} + +input SearchableBooleanFilterInput { + eq: Boolean + ne: Boolean +} + +input SearchableIDFilterInput { + ne: ID + gt: ID + lt: ID + gte: ID + lte: ID + eq: ID + match: ID + matchPhrase: ID + matchPhrasePrefix: ID + multiMatch: ID + exists: Boolean + wildcard: ID + regexp: ID + range: [ID] +} + +input SearchablePostFilterInput { + id: SearchableIDFilterInput + title: SearchableStringFilterInput + createdAt: SearchableStringFilterInput + updatedAt: SearchableStringFilterInput + and: [SearchablePostFilterInput] + or: [SearchablePostFilterInput] + not: SearchablePostFilterInput +} + +enum SearchableSortDirection { + asc + desc +} + +enum SearchablePostSortableFields { + id + title + createdAt + updatedAt +} + +input SearchablePostSortInput { + field: SearchablePostSortableFields + direction: SearchableSortDirection +} + +type SearchablePostConnection { + items: [Post] + nextToken: String + total: Int +} + +type Query { + searchPosts(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String, from: Int): SearchablePostConnection + getPost(id: ID!): Post + listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection +} + +input ModelStringInput { + ne: String + eq: String + le: String + lt: String + ge: String + gt: String + contains: String + notContains: String + between: [String] + beginsWith: String + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +input ModelIntInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelFloatInput { + ne: Float + eq: Float + le: Float + lt: Float + ge: Float + gt: Float + between: [Float] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelBooleanInput { + ne: Boolean + eq: Boolean + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelIDInput { + ne: ID + eq: ID + le: ID + lt: ID + ge: ID + gt: ID + contains: ID + notContains: ID + between: [ID] + beginsWith: ID + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +enum ModelAttributeTypes { + binary + binarySet + bool + list + map + number + numberSet + string + stringSet + _null +} + +input ModelSizeInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] +} + +type ModelPostConnection { + items: [Post] + nextToken: String +} + +input ModelPostFilterInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostFilterInput] + or: [ModelPostFilterInput] + not: ModelPostFilterInput +} + +input ModelPostConditionInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostConditionInput] + or: [ModelPostConditionInput] + not: ModelPostConditionInput +} + +input CreatePostInput { + id: ID + title: String! + createdAt: String + updatedAt: String +} + +type Mutation { + createPost(input: CreatePostInput!, condition: ModelPostConditionInput): Post + updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post + deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post +} + +input UpdatePostInput { + id: ID! + title: String + createdAt: String + updatedAt: String +} + +input DeletePostInput { + id: ID! +} + +type Subscription { + onCreatePost: Post @aws_subscribe(mutations: [\\"createPost\\"]) + onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) + onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) +} + +" +`; + +exports[`Test SearchableModelTransformer vtl 1`] = ` +Object { + "Mutation.createPost.init.1.req.vtl": "## [Start] Initialization default values. ** +$util.qr($ctx.stash.put(\\"defaultValues\\", $util.defaultIfNull($ctx.stash.defaultValues, {}))) +#set( $createdAt = $util.time.nowISO8601() ) +$util.qr($ctx.stash.defaultValues.put(\\"id\\", $util.autoId())) +$util.qr($ctx.stash.defaultValues.put(\\"createdAt\\", $createdAt)) +$util.qr($ctx.stash.defaultValues.put(\\"updatedAt\\", $createdAt)) +$util.toJson({ + \\"version\\": \\"2018-05-29\\", + \\"payload\\": {} +}) +## [End] Initialization default values. **", + "Mutation.createPost.req.vtl": "## [Start] Create Request template. ** +## Begin - KeyCondition ** +#if( $ctx.stash.metadata.modelObjectKey ) + #set( $keyConditionExpr = {} ) + #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) + $util.qr($keyConditionExpr.add(\\"$entry.key\\", { + \\"attributeExists\\": true +})) + #end + $util.qr($ctx.stash.conditions.add($keyConditionExpr)) +#else + $util.qr($ctx.stash.conditions.add({ + \\"id\\": { + \\"attributeExists\\": false + } +})) +#end +## End - KeyCondition ** +## Set the default values to put request ** +#set( $mergedValues = $util.defaultIfNull($ctx.stash.defaultValues, {}) ) +## copy the values from input ** +$util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) +## set the typename ** +$util.qr($mergedValues.put(\\"__typename\\", \\"Post\\")) +#set( $PutObject = { + \\"version\\": \\"2018-05-29\\", + \\"operation\\": \\"PutItem\\", + \\"attributeValues\\": $util.dynamodb.toMapValues($mergedValues), + \\"condition\\": $condition +} ) +#if( $context.args.condition ) + $util.qr($ctx.stash.conditions.add($context.args.condition)) +#end +## Begin - KeyCondtion ** +#if( $ctx.stash.metadata.modelObjectKey ) + #set( $keyConditionExpr = {} ) + #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) + $util.qr($keyConditionExpr.put(\\"$entry.key\\", { + \\"attributeExists\\": false +})) + #end + $util.qr($ctx.stash.conditions.add($keyConditionExpr)) +#else + $util.qr($ctx.stash.conditions.add({ + \\"id\\": { + \\"attributeExists\\": false + } +})) +#end +## End - KeyCondition ** +## Start Condtion block ** +#if( $ctx.stash.conditions && $inputConditionObjectName.size() != 0 ) + #set( $mergedConditions = { + \\"and\\": $ctx.stash.conditions +} ) + #set( $Conditions = $util.parseJson($util.transform.toDynamoDBConditionExpression($mergedConditions)) ) + #if( $Conditions.expressionValues && $Conditions.expressionValues.size() == 0 ) + #set( $Conditions = { + \\"expression\\": $Conditions.expression, + \\"expressionNames\\": $Conditions.expressionNames +} ) + #end + ## End Condtion block ** +#end +#if( $Conditions ) + $util.qr($PutObject.put(\\"condition\\", $Conditions)) +#end +#if( $ctx.stash.metadata.modelObject ) + $PutObject.put(\\"id\\", $ctx.stash.metadata.modelObject) +#else + #set( $Key = { + \\"id\\": $util.dynamodb.toDynamoDB($mergedValues.id) +} ) + $util.qr($PutObject.put(\\"key\\", $Key)) +#end +$util.toJson($PutObject) +## [End] Create Request template. **", + "Mutation.createPost.res.vtl": "## [Start] Get ResponseTemplate. ** +#if( $ctx.error ) + $util.error($ctx.error.message, $ctx.error.type) +#else + $util.toJson($ctx.result) +#end +## [End] Get ResponseTemplate. **", + "Mutation.deletePost.req.vtl": "## [Start] Delete Request template. ** +#set( $DeleteRequest = { + \\"version\\": \\"2018-05-29\\", + \\"operation\\": \\"DeleteItem\\" +} ) +#if( $ctx.stash.metadata.modelObjectKey ) + #set( $Key = $ctx.stash.metadata.modelObjectKey ) +#else + #set( $Key = { + \\"id\\": $util.dynamodb.toDynamoDB($ctx.args.input.id) +} ) +#end +$util.qr($DeleteRequest.put(\\"key\\", $Key)) +## Begin - key condition ** +#if( $ctx.stash.metadata.modelObjectKey ) + #set( $keyConditionExpr = {} ) + #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) + $util.qr($keyConditionExpr.put(\\"$entry.key\\", { + \\"attributeExists\\": true +})) + #end + $util.qr($ctx.stash.conditions.add($keyConditionExpr)) +#else + $util.qr($ctx.stash.conditions.add({ + \\"id\\": { + \\"attributeExists\\": true + } +})) +#end +## End - key condition ** +#if( $context.args.condition ) + $util.qr($ctx.stash.conditions.add($context.args.condition)) +#end +## Start Condtion block ** +#if( $ctx.stash.conditions && $inputConditionObjectName.size() != 0 ) + #set( $mergedConditions = { + \\"and\\": $ctx.stash.conditions +} ) + #set( $Conditions = $util.parseJson($util.transform.toDynamoDBConditionExpression($mergedConditions)) ) + #if( $Conditions.expressionValues && $Conditions.expressionValues.size() == 0 ) + #set( $Conditions = { + \\"expression\\": $Conditions.expression, + \\"expressionNames\\": $Conditions.expressionNames +} ) + #end + ## End Condtion block ** +#end +#if( $Conditions ) + $util.qr($DeleteRequest.put(\\"condition\\", $Conditions)) +#end +$util.toJson($DeleteRequest) +## [End] Delete Request template. **", + "Mutation.deletePost.res.vtl": "## [Start] Get ResponseTemplate. ** +#if( $ctx.error ) + $util.error($ctx.error.message, $ctx.error.type) +#else + $util.toJson($ctx.result) +#end +## [End] Get ResponseTemplate. **", + "Mutation.updatePost.init.1.req.vtl": "## [Start] Initialization default values. ** +$util.qr($ctx.stash.put(\\"defaultValues\\", $util.defaultIfNull($ctx.stash.defaultValues, {}))) +#set( $updatedAt = $util.time.nowISO8601() ) +$util.qr($ctx.stash.defaultValues.put(\\"updatedAt\\", $updatedAt)) +$util.toJson({ + \\"version\\": \\"2018-05-29\\", + \\"payload\\": {} +}) +## [End] Initialization default values. **", + "Mutation.updatePost.req.vtl": "## [Start] Mutation Update resolver. ** +## Set the default values to put request ** +#set( $mergedValues = $util.defaultIfNull($ctx.stash.defaultValues, {}) ) +## copy the values from input ** +$util.qr($mergedValues.putAll($util.defaultIfNull($ctx.args.input, {}))) +## set the typename ** +## Initialize the vars for creating ddb expression ** +#set( $expNames = {} ) +#set( $expValues = {} ) +#set( $expSet = {} ) +#set( $expAdd = {} ) +#set( $expRemove = [] ) +#if( $ctx.stash.metadata.modelObjetKey ) + #set( $Key = $util.dynamodb.toDynamoDB($ctx.stash.metadata.modelObjetKey) ) +#else + #set( $Key = { + \\"id\\": $util.dynamodb.toDynamoDB($ctx.args.input.id) +} ) +#end +## Model key ** +#if( $ctx.stash.metadata.modelObjetKey ) + #foreach( $entry in $ctx.stash.metadata.modelObjetKey.entrySet() ) + $util.qr($keyFields.add(\\"$entry.key\\")) + #end +#else + #set( $keyFields = [\\"id\\"] ) +#end +#foreach( $entry in $util.map.copyAndRemoveAllKeys($mergedValues, $keyFields).entrySet() ) + #if( $util.isNull($entry.value) ) + #set( $discard = $expRemove.add(\\"#$entry.key\\") ) + $util.qr($expNames.put(\\"#$entry.key\\", \\"$entry.key\\")) + #else + $util.qr($expSet.put(\\"#$entry.key\\", \\":$entry.key\\")) + $util.qr($expNames.put(\\"#$entry.key\\", \\"$entry.key\\")) + $util.qr($expValues.put(\\":$entry.key\\", $util.dynamodb.toDynamoDB($entry.value))) + #end +#end +#set( $expression = \\"\\" ) +#if( !$expSet.isEmpty() ) + #set( $expression = \\"SET\\" ) + #foreach( $entry in $expSet.entrySet() ) + #set( $expression = \\"$expression $entry.key = $entry.value\\" ) + #if( $foreach.hasNext() ) + #set( $expression = \\"$expression,\\" ) + #end + #end +#end +#if( !$expAdd.isEmpty() ) + #set( $expression = \\"$expression ADD\\" ) + #foreach( $entry in $expAdd.entrySet() ) + #set( $expression = \\"$expression $entry.key $entry.value\\" ) + #if( $foreach.hasNext() ) + #set( $expression = \\"$expression,\\" ) + #end + #end +#end +#if( !$expRemove.isEmpty() ) + #set( $expression = \\"$expression REMOVE\\" ) + #foreach( $entry in $expRemove ) + #set( $expression = \\"$expression $entry\\" ) + #if( $foreach.hasNext() ) + #set( $expression = \\"$expression,\\" ) + #end + #end +#end +#set( $update = {} ) +$util.qr($update.put(\\"expression\\", \\"$expression\\")) +#if( !$expNames.isEmpty() ) + $util.qr($update.put(\\"expressionNames\\", $expNames)) +#end +#if( !$expValues.isEmpty() ) + $util.qr($update.put(\\"expressionValues\\", $expValues)) +#end +## Begin - key condition ** +#if( $ctx.stash.metadata.modelObjectKey ) + #set( $keyConditionExpr = {} ) + #foreach( $entry in $ctx.stash.metadata.modelObjectKey.entrySet() ) + $util.qr($keyConditionExpr.put(\\"$entry.key\\", { + \\"attributeExists\\": true +})) + #end + $util.qr($ctx.stash.conditions.add($keyConditionExpr)) +#else + $util.qr($ctx.stash.conditions.add({ + \\"id\\": { + \\"attributeExists\\": true + } +})) +#end +## End - key condition ** +#if( $context.args.condition ) + $util.qr($ctx.stash.conditions.add($context.args.condition)) +#end +## Start Condtion block ** +#if( $ctx.stash.conditions && $inputConditionObjectName.size() != 0 ) + #set( $mergedConditions = { + \\"and\\": $ctx.stash.conditions +} ) + #set( $Conditions = $util.parseJson($util.transform.toDynamoDBConditionExpression($mergedConditions)) ) + #if( $Conditions.expressionValues && $Conditions.expressionValues.size() == 0 ) + #set( $Conditions = { + \\"expression\\": $Conditions.expression, + \\"expressionNames\\": $Conditions.expressionNames +} ) + #end + ## End Condtion block ** +#end +#set( $UpdateItem = { + \\"version\\": \\"2018-05-29\\", + \\"operation\\": \\"UpdateItem\\", + \\"key\\": $Key, + \\"update\\": $update +} ) +#if( $Conditions ) + $util.qr($UpdateItem.put(\\"condition\\", $Conditions)) +#end +$util.toJson($UpdateItem) +## [End] Mutation Update resolver. **", + "Mutation.updatePost.res.vtl": "## [Start] Get ResponseTemplate. ** +#if( $ctx.error ) + $util.error($ctx.error.message, $ctx.error.type) +#else + $util.toJson($ctx.result) +#end +## [End] Get ResponseTemplate. **", + "Query.getPost.req.vtl": "## [Start] Get Request template. ** +#set( $GetRequest = { + \\"version\\": \\"2018-05-29\\", + \\"operation\\": \\"GetItem\\" +} ) +#if( $ctx.stash.metadata.modelKeyObject ) + #set( $Key = $ctx.stash.metadata.modelKeyObject ) +#else + #set( $key = { + \\"id\\": $util.dynamodb.toDynamoDB($ctx.args.id) +} ) +#end +$util.qr($GetRequest.put(\\"key\\", $key)) +$util.toJson($GetRequest) +## [End] Get Request template. **", + "Query.getPost.res.vtl": "## [Start] Get ResponseTemplate. ** +#if( $ctx.error ) + $util.error($ctx.error.message, $ctx.error.type) +#else + $util.toJson($ctx.result) +#end +## [End] Get ResponseTemplate. **", + "Query.listPosts.req.vtl": "## [Start] List Request. ** +#set( $limit = $util.defaultIfNull($context.args.limit, 100) ) +#set( $ListRequest = { + \\"version\\": \\"2018-05-29\\", + \\"limit\\": $limit +} ) +#if( $context.args.nextToken ) + #set( $ListRequest.nextToken = $context.args.nextToken ) +#end +#if( $context.args.filter ) + #set( $filterExpression = $util.parseJson($util.transform.toDynamoDBFilterExpression($$ctx.args.filter)) ) + #if( !$util.isNullOrBlank($filterExpression.expression) ) + #if( $filterEpression.expressionValues.size() == 0 ) + $util.qr($filterEpression.remove(\\"expressionValues\\")) + #end + #set( $ListRequest.filter = $filterExpression ) + #end +#end +#if( !$$util.isNull($ctx.stash.modelQuery) ) + #set( $Query = $util.parseJson($util.transform.toDynamoDBFilterExpression($ctx.stash.modelQuery)) ) + $util.qr($ListRequest.put(\\"operation\\", \\"Query\\")) + $util.qr($ListRequest.put(\\"query\\", $Query)) + #if( !$util.isNull($ctx.args.sortDirection) && $ctx.args.sortDirection == \\"DESC\\" ) + #set( $ListRequest.scanIndexForward = false ) + #else + #set( $ListRequest.scanIndexForward = true ) + #end +#else + $util.qr($ListRequest.put(\\"operation\\", \\"Scan\\")) +#end +#if( !$util.isNull($ctx.stash.metadata.index) ) + #set( $ListRequest.IndexName = $ctx.stash.metadata.index ) +#end +$util.toJson($ListRequest) +## [End] List Request. **", + "Query.listPosts.res.vtl": "## [Start] Get ResponseTemplate. ** +#if( $ctx.error ) + $util.error($ctx.error.message, $ctx.error.type) +#else + $util.toJson($ctx.result) +#end +## [End] Get ResponseTemplate. **", + "Query.searchPosts.req.vtl": "#set( $indexPath = \\"/post/doc/_search\\" ) +#set( $nonKeywordFields = [] ) +#if( $util.isNullOrEmpty($context.args.sort) ) + #set( $sortDirection = \\"desc\\" ) + #set( $sortField = \\"id\\" ) +#else + #set( $sortDirection = $util.defaultIfNull($context.args.sort.direction, \\"desc\\") ) + #set( $sortField = $util.defaultIfNull($context.args.sort.field, \\"id\\") ) +#end +#if( $nonKeywordFields.contains($sortField) ) + #set( $sortField0 = $util.toJson($sortField) ) +#else + #set( $sortField0 = $util.toJson(\\"\${sortField}.keyword\\") ) +#end +{ + \\"version\\": \\"2018-05-29\\", + \\"operation\\": \\"GET\\", + \\"path\\": \\"$indexPath\\", + \\"params\\": { + \\"body\\": { + #if( $context.args.nextToken )\\"search_after\\": [$util.toJson($context.args.nextToken)], #end + #if( $context.args.from )\\"from\\": $context.args.from, #end + \\"size\\": #if( $context.args.limit ) $context.args.limit #else 100 #end, + \\"sort\\": [{$sortField0: { \\"order\\" : $util.toJson($sortDirection) }}], + \\"version\\": false, + \\"query\\": #if( $context.args.filter ) +$util.transform.toElasticsearchQueryDSL($ctx.args.filter) +#else +{ + \\"match_all\\": {} + } +#end + } + } +}", + "Query.searchPosts.res.vtl": "#set( $es_items = [] ) +#foreach( $entry in $context.result.hits.hits ) + #if( !$foreach.hasNext ) + #set( $nextToken = $entry.sort.get(0) ) + #end + $util.qr($es_items.add($entry.get(\\"_source\\"))) +#end +$util.toJson({ + \\"items\\": $es_items, + \\"total\\": $ctx.result.hits.total, + \\"nextToken\\": $nextToken +})", + "Subscription.onCreatePost.req.vtl": "## [Start] Subscription Request template. ** +$util.toJson({ + \\"version\\": \\"2018-05-29\\", + \\"payload\\": {} +}) +## [End] Subscription Request template. **", + "Subscription.onCreatePost.res.vtl": "## [Start] Subscription Resonse template. ** +$util.toJson(null) +## [End] Subscription Resonse template. **", + "Subscription.onDeletePost.req.vtl": "## [Start] Subscription Request template. ** +$util.toJson({ + \\"version\\": \\"2018-05-29\\", + \\"payload\\": {} +}) +## [End] Subscription Request template. **", + "Subscription.onDeletePost.res.vtl": "## [Start] Subscription Resonse template. ** +$util.toJson(null) +## [End] Subscription Resonse template. **", + "Subscription.onUpdatePost.req.vtl": "## [Start] Subscription Request template. ** +$util.toJson({ + \\"version\\": \\"2018-05-29\\", + \\"payload\\": {} +}) +## [End] Subscription Request template. **", + "Subscription.onUpdatePost.res.vtl": "## [Start] Subscription Resonse template. ** +$util.toJson(null) +## [End] Subscription Resonse template. **", +} +`; + +exports[`Test SearchableModelTransformer with multiple model searchable directives 1`] = ` +" +type Post { + id: ID! + title: String! + createdAt: String + updatedAt: String +} + +type User { + id: ID! + name: String! + createdAt: AWSDateTime! + updatedAt: AWSDateTime! +} + +input SearchableStringFilterInput { + ne: String + gt: String + lt: String + gte: String + lte: String + eq: String + match: String + matchPhrase: String + matchPhrasePrefix: String + multiMatch: String + exists: Boolean + wildcard: String + regexp: String + range: [String] +} + +input SearchableIntFilterInput { + ne: Int + gt: Int + lt: Int + gte: Int + lte: Int + eq: Int + range: [Int] +} + +input SearchableFloatFilterInput { + ne: Float + gt: Float + lt: Float + gte: Float + lte: Float + eq: Float + range: [Float] +} + +input SearchableBooleanFilterInput { + eq: Boolean + ne: Boolean +} + +input SearchableIDFilterInput { + ne: ID + gt: ID + lt: ID + gte: ID + lte: ID + eq: ID + match: ID + matchPhrase: ID + matchPhrasePrefix: ID + multiMatch: ID + exists: Boolean + wildcard: ID + regexp: ID + range: [ID] +} + +input SearchablePostFilterInput { + id: SearchableIDFilterInput + title: SearchableStringFilterInput + createdAt: SearchableStringFilterInput + updatedAt: SearchableStringFilterInput + and: [SearchablePostFilterInput] + or: [SearchablePostFilterInput] + not: SearchablePostFilterInput +} + +enum SearchableSortDirection { + asc + desc +} + +enum SearchablePostSortableFields { + id + title + createdAt + updatedAt +} + +input SearchablePostSortInput { + field: SearchablePostSortableFields + direction: SearchableSortDirection +} + +type SearchablePostConnection { + items: [Post] + nextToken: String + total: Int +} + +type Query { + searchPosts(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String, from: Int): SearchablePostConnection + searchUsers(filter: SearchableUserFilterInput, sort: SearchableUserSortInput, limit: Int, nextToken: String, from: Int): SearchableUserConnection + getPost(id: ID!): Post + listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection + getUser(id: ID!): User + listUsers(filter: ModelUserFilterInput, limit: Int, nextToken: String): ModelUserConnection +} + +input SearchableUserFilterInput { + id: SearchableIDFilterInput + name: SearchableStringFilterInput + and: [SearchableUserFilterInput] + or: [SearchableUserFilterInput] + not: SearchableUserFilterInput +} + +enum SearchableUserSortableFields { + id + name +} + +input SearchableUserSortInput { + field: SearchableUserSortableFields + direction: SearchableSortDirection +} + +type SearchableUserConnection { + items: [User] + nextToken: String + total: Int +} + +input ModelStringInput { + ne: String + eq: String + le: String + lt: String + ge: String + gt: String + contains: String + notContains: String + between: [String] + beginsWith: String + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +input ModelIntInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelFloatInput { + ne: Float + eq: Float + le: Float + lt: Float + ge: Float + gt: Float + between: [Float] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelBooleanInput { + ne: Boolean + eq: Boolean + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelIDInput { + ne: ID + eq: ID + le: ID + lt: ID + ge: ID + gt: ID + contains: ID + notContains: ID + between: [ID] + beginsWith: ID + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +enum ModelAttributeTypes { + binary + binarySet + bool + list + map + number + numberSet + string + stringSet + _null +} + +input ModelSizeInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] +} + +type ModelPostConnection { + items: [Post] + nextToken: String +} + +input ModelPostFilterInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostFilterInput] + or: [ModelPostFilterInput] + not: ModelPostFilterInput +} + +input ModelPostConditionInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostConditionInput] + or: [ModelPostConditionInput] + not: ModelPostConditionInput +} + +input CreatePostInput { + id: ID + title: String! + createdAt: String + updatedAt: String +} + +type Mutation { + createPost(input: CreatePostInput!, condition: ModelPostConditionInput): Post + updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post + deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post + createUser(input: CreateUserInput!, condition: ModelUserConditionInput): User + updateUser(input: UpdateUserInput!, condition: ModelUserConditionInput): User + deleteUser(input: DeleteUserInput!, condition: ModelUserConditionInput): User +} + +input UpdatePostInput { + id: ID! + title: String + createdAt: String + updatedAt: String +} + +input DeletePostInput { + id: ID! +} + +type Subscription { + onCreatePost: Post @aws_subscribe(mutations: [\\"createPost\\"]) + onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) + onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) + onCreateUser: User @aws_subscribe(mutations: [\\"createUser\\"]) + onUpdateUser: User @aws_subscribe(mutations: [\\"updateUser\\"]) + onDeleteUser: User @aws_subscribe(mutations: [\\"deleteUser\\"]) +} + +type ModelUserConnection { + items: [User] + nextToken: String +} + +input ModelUserFilterInput { + id: ModelIDInput + name: ModelStringInput + and: [ModelUserFilterInput] + or: [ModelUserFilterInput] + not: ModelUserFilterInput +} + +input ModelUserConditionInput { + id: ModelIDInput + name: ModelStringInput + and: [ModelUserConditionInput] + or: [ModelUserConditionInput] + not: ModelUserConditionInput +} + +input CreateUserInput { + id: ID + name: String! +} + +input UpdateUserInput { + id: ID! + name: String +} + +input DeleteUserInput { + id: ID! +} + +" +`; + +exports[`Test SearchableModelTransformer with only create mutations 1`] = ` +" +type Post { + id: ID! + title: String! + createdAt: String + updatedAt: String +} + +input SearchableStringFilterInput { + ne: String + gt: String + lt: String + gte: String + lte: String + eq: String + match: String + matchPhrase: String + matchPhrasePrefix: String + multiMatch: String + exists: Boolean + wildcard: String + regexp: String + range: [String] +} + +input SearchableIntFilterInput { + ne: Int + gt: Int + lt: Int + gte: Int + lte: Int + eq: Int + range: [Int] +} + +input SearchableFloatFilterInput { + ne: Float + gt: Float + lt: Float + gte: Float + lte: Float + eq: Float + range: [Float] +} + +input SearchableBooleanFilterInput { + eq: Boolean + ne: Boolean +} + +input SearchableIDFilterInput { + ne: ID + gt: ID + lt: ID + gte: ID + lte: ID + eq: ID + match: ID + matchPhrase: ID + matchPhrasePrefix: ID + multiMatch: ID + exists: Boolean + wildcard: ID + regexp: ID + range: [ID] +} + +input SearchablePostFilterInput { + id: SearchableIDFilterInput + title: SearchableStringFilterInput + createdAt: SearchableStringFilterInput + updatedAt: SearchableStringFilterInput + and: [SearchablePostFilterInput] + or: [SearchablePostFilterInput] + not: SearchablePostFilterInput +} + +enum SearchableSortDirection { + asc + desc +} + +enum SearchablePostSortableFields { + id + title + createdAt + updatedAt +} + +input SearchablePostSortInput { + field: SearchablePostSortableFields + direction: SearchableSortDirection +} + +type SearchablePostConnection { + items: [Post] + nextToken: String + total: Int +} + +type Query { + searchPosts(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String, from: Int): SearchablePostConnection + getPost(id: ID!): Post + listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection +} + +input ModelStringInput { + ne: String + eq: String + le: String + lt: String + ge: String + gt: String + contains: String + notContains: String + between: [String] + beginsWith: String + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +input ModelIntInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelFloatInput { + ne: Float + eq: Float + le: Float + lt: Float + ge: Float + gt: Float + between: [Float] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelBooleanInput { + ne: Boolean + eq: Boolean + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelIDInput { + ne: ID + eq: ID + le: ID + lt: ID + ge: ID + gt: ID + contains: ID + notContains: ID + between: [ID] + beginsWith: ID + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +enum ModelAttributeTypes { + binary + binarySet + bool + list + map + number + numberSet + string + stringSet + _null +} + +input ModelSizeInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] +} + +type ModelPostConnection { + items: [Post] + nextToken: String +} + +input ModelPostFilterInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostFilterInput] + or: [ModelPostFilterInput] + not: ModelPostFilterInput +} + +input ModelPostConditionInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostConditionInput] + or: [ModelPostConditionInput] + not: ModelPostConditionInput +} + +input CreatePostInput { + id: ID + title: String! + createdAt: String + updatedAt: String +} + +type Mutation { + customCreatePost(input: CreatePostInput!, condition: ModelPostConditionInput): Post + updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post + deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post +} + +input UpdatePostInput { + id: ID! + title: String + createdAt: String + updatedAt: String +} + +input DeletePostInput { + id: ID! +} + +type Subscription { + onCreatePost: Post @aws_subscribe(mutations: [\\"customCreatePost\\"]) + onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) + onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) +} + +" +`; + +exports[`Test SearchableModelTransformer with query overrides 1`] = ` +" +type Post { + id: ID! + title: String! + createdAt: String + updatedAt: String +} + +input SearchableStringFilterInput { + ne: String + gt: String + lt: String + gte: String + lte: String + eq: String + match: String + matchPhrase: String + matchPhrasePrefix: String + multiMatch: String + exists: Boolean + wildcard: String + regexp: String + range: [String] +} + +input SearchableIntFilterInput { + ne: Int + gt: Int + lt: Int + gte: Int + lte: Int + eq: Int + range: [Int] +} + +input SearchableFloatFilterInput { + ne: Float + gt: Float + lt: Float + gte: Float + lte: Float + eq: Float + range: [Float] +} + +input SearchableBooleanFilterInput { + eq: Boolean + ne: Boolean +} + +input SearchableIDFilterInput { + ne: ID + gt: ID + lt: ID + gte: ID + lte: ID + eq: ID + match: ID + matchPhrase: ID + matchPhrasePrefix: ID + multiMatch: ID + exists: Boolean + wildcard: ID + regexp: ID + range: [ID] +} + +input SearchablePostFilterInput { + id: SearchableIDFilterInput + title: SearchableStringFilterInput + createdAt: SearchableStringFilterInput + updatedAt: SearchableStringFilterInput + and: [SearchablePostFilterInput] + or: [SearchablePostFilterInput] + not: SearchablePostFilterInput +} + +enum SearchableSortDirection { + asc + desc +} + +enum SearchablePostSortableFields { + id + title + createdAt + updatedAt +} + +input SearchablePostSortInput { + field: SearchablePostSortableFields + direction: SearchableSortDirection +} + +type SearchablePostConnection { + items: [Post] + nextToken: String + total: Int +} + +type Query { + customSearchPost(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String, from: Int): SearchablePostConnection + getPost(id: ID!): Post + listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection +} + +input ModelStringInput { + ne: String + eq: String + le: String + lt: String + ge: String + gt: String + contains: String + notContains: String + between: [String] + beginsWith: String + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +input ModelIntInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelFloatInput { + ne: Float + eq: Float + le: Float + lt: Float + ge: Float + gt: Float + between: [Float] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelBooleanInput { + ne: Boolean + eq: Boolean + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelIDInput { + ne: ID + eq: ID + le: ID + lt: ID + ge: ID + gt: ID + contains: ID + notContains: ID + between: [ID] + beginsWith: ID + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +enum ModelAttributeTypes { + binary + binarySet + bool + list + map + number + numberSet + string + stringSet + _null +} + +input ModelSizeInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] +} + +type ModelPostConnection { + items: [Post] + nextToken: String +} + +input ModelPostFilterInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostFilterInput] + or: [ModelPostFilterInput] + not: ModelPostFilterInput +} + +input ModelPostConditionInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostConditionInput] + or: [ModelPostConditionInput] + not: ModelPostConditionInput +} + +input CreatePostInput { + id: ID + title: String! + createdAt: String + updatedAt: String +} + +type Mutation { + createPost(input: CreatePostInput!, condition: ModelPostConditionInput): Post + updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post + deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post +} + +input UpdatePostInput { + id: ID! + title: String + createdAt: String + updatedAt: String +} + +input DeletePostInput { + id: ID! +} + +type Subscription { + onCreatePost: Post @aws_subscribe(mutations: [\\"createPost\\"]) + onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) + onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) +} + +" +`; + +exports[`Test SearchableModelTransformer with sort fields 1`] = ` +" +type Post { + id: ID! + title: String! + createdAt: String + updatedAt: String +} + +input SearchableStringFilterInput { + ne: String + gt: String + lt: String + gte: String + lte: String + eq: String + match: String + matchPhrase: String + matchPhrasePrefix: String + multiMatch: String + exists: Boolean + wildcard: String + regexp: String + range: [String] +} + +input SearchableIntFilterInput { + ne: Int + gt: Int + lt: Int + gte: Int + lte: Int + eq: Int + range: [Int] +} + +input SearchableFloatFilterInput { + ne: Float + gt: Float + lt: Float + gte: Float + lte: Float + eq: Float + range: [Float] +} + +input SearchableBooleanFilterInput { + eq: Boolean + ne: Boolean +} + +input SearchableIDFilterInput { + ne: ID + gt: ID + lt: ID + gte: ID + lte: ID + eq: ID + match: ID + matchPhrase: ID + matchPhrasePrefix: ID + multiMatch: ID + exists: Boolean + wildcard: ID + regexp: ID + range: [ID] +} + +input SearchablePostFilterInput { + id: SearchableIDFilterInput + title: SearchableStringFilterInput + createdAt: SearchableStringFilterInput + updatedAt: SearchableStringFilterInput + and: [SearchablePostFilterInput] + or: [SearchablePostFilterInput] + not: SearchablePostFilterInput +} + +enum SearchableSortDirection { + asc + desc +} + +enum SearchablePostSortableFields { + id + title + createdAt + updatedAt +} + +input SearchablePostSortInput { + field: SearchablePostSortableFields + direction: SearchableSortDirection +} + +type SearchablePostConnection { + items: [Post] + nextToken: String + total: Int +} + +type Query { + searchPosts(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String, from: Int): SearchablePostConnection + getPost(id: ID!): Post + listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection +} + +input ModelStringInput { + ne: String + eq: String + le: String + lt: String + ge: String + gt: String + contains: String + notContains: String + between: [String] + beginsWith: String + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +input ModelIntInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelFloatInput { + ne: Float + eq: Float + le: Float + lt: Float + ge: Float + gt: Float + between: [Float] + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelBooleanInput { + ne: Boolean + eq: Boolean + attributeExists: Boolean + attributeType: ModelAttributeTypes +} + +input ModelIDInput { + ne: ID + eq: ID + le: ID + lt: ID + ge: ID + gt: ID + contains: ID + notContains: ID + between: [ID] + beginsWith: ID + attributeExists: Boolean + attributeType: ModelAttributeTypes + size: ModelSizeInput +} + +enum ModelAttributeTypes { + binary + binarySet + bool + list + map + number + numberSet + string + stringSet + _null +} + +input ModelSizeInput { + ne: Int + eq: Int + le: Int + lt: Int + ge: Int + gt: Int + between: [Int] +} + +type ModelPostConnection { + items: [Post] + nextToken: String +} + +input ModelPostFilterInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostFilterInput] + or: [ModelPostFilterInput] + not: ModelPostFilterInput +} + +input ModelPostConditionInput { + id: ModelIDInput + title: ModelStringInput + createdAt: ModelStringInput + updatedAt: ModelStringInput + and: [ModelPostConditionInput] + or: [ModelPostConditionInput] + not: ModelPostConditionInput +} + +input CreatePostInput { + id: ID + title: String! + createdAt: String + updatedAt: String +} + +type Mutation { + createPost(input: CreatePostInput!, condition: ModelPostConditionInput): Post + updatePost(input: UpdatePostInput!, condition: ModelPostConditionInput): Post + deletePost(input: DeletePostInput!, condition: ModelPostConditionInput): Post +} + +input UpdatePostInput { + id: ID! + title: String + createdAt: String + updatedAt: String +} + +input DeletePostInput { + id: ID! +} + +type Subscription { + onCreatePost: Post @aws_subscribe(mutations: [\\"createPost\\"]) + onUpdatePost: Post @aws_subscribe(mutations: [\\"updatePost\\"]) + onDeletePost: Post @aws_subscribe(mutations: [\\"deletePost\\"]) +} + +" +`; diff --git a/packages/amplify-graphql-searchable-transformer/src/__tests__/amplify-graphql-searchable-transformer.tests.ts b/packages/amplify-graphql-searchable-transformer/src/__tests__/amplify-graphql-searchable-transformer.tests.ts new file mode 100644 index 00000000000..613c4c0ab04 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/__tests__/amplify-graphql-searchable-transformer.tests.ts @@ -0,0 +1,294 @@ +import { GraphQLTransform } from '@aws-amplify/graphql-transformer-core'; +import { SearchableModelTransformer } from '../'; +import { ModelTransformer } from '@aws-amplify/graphql-model-transformer'; +import { anything, countResources, expect as cdkExpect, haveResource } from '@aws-cdk/assert'; +import { parse } from 'graphql'; + +test('Test SearchableModelTransformer validation happy case', () => { + const validSchema = ` + type Post @model @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + parse(out.schema); + expect(out.schema).toMatchSnapshot(); +}); + +test('Test SearchableModelTransformer vtl', () => { + const validSchema = ` + type Post @model @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + + const out = transformer.transform(validSchema); + expect(parse(out.schema)).toBeDefined(); + expect(out.pipelineFunctions).toMatchSnapshot(); +}); + +test('Test SearchableModelTransformer with query overrides', () => { + const validSchema = `type Post @model @searchable(queries: { search: "customSearchPost" }) { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + expect(parse(out.schema)).toBeDefined(); + expect(out.schema).toMatchSnapshot(); +}); + +test('Test SearchableModelTransformer with only create mutations', () => { + const validSchema = `type Post @model(mutations: { create: "customCreatePost" }) @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + expect(out.schema).toBeDefined(); + expect(out.schema).toMatchSnapshot(); +}); + +test('Test SearchableModelTransformer with multiple model searchable directives', () => { + const validSchema = ` + type Post @model @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + + type User @model @searchable { + id: ID! + name: String! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + expect(out.schema).toBeDefined(); + expect(out.schema).toMatchSnapshot(); +}); + +test('Test SearchableModelTransformer with sort fields', () => { + const validSchema = ` + type Post @model @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + expect(out.schema).toBeDefined(); + expect(out.schema).toMatchSnapshot(); +}); + +test('it generates expected resources', () => { + const validSchema = ` + type Post @model @searchable { + id: ID! + title: String! + createdAt: String + updatedAt: String + } + type Todo @model @searchable { + id: ID! + name: String! + description: String + createdAt: String + updatedAt: String + } + type Comment @model { + id: ID! + content: String! + } + `; + const transformer = new GraphQLTransform({ + transformers: [new ModelTransformer(), new SearchableModelTransformer()], + }); + const out = transformer.transform(validSchema); + expect(out).toBeDefined(); + const searchableStack = out.stacks.SearchableStack; + cdkExpect(searchableStack).to( + haveResource('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'lambda.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + }), + ); + cdkExpect(searchableStack).to( + haveResource('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'appsync.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + }), + ); + + cdkExpect(searchableStack).to( + haveResource('AWS::AppSync::DataSource', { + ApiId: { + Ref: anything(), + }, + Name: 'ElasticSearchDataSource', + Type: 'AMAZON_ELASTICSEARCH', + ElasticsearchConfig: { + AwsRegion: { + 'Fn::Select': [ + 3, + { + 'Fn::Split': [ + ':', + { + 'Fn::GetAtt': ['ElasticSearchDomain', 'Arn'], + }, + ], + }, + ], + }, + Endpoint: { + 'Fn::Join': [ + '', + [ + 'https://', + { + 'Fn::GetAtt': ['ElasticSearchDomain', 'DomainEndpoint'], + }, + ], + ], + }, + }, + ServiceRoleArn: { + 'Fn::GetAtt': ['ElasticSearchAccessIAMRoleAAA3FF0B', 'Arn'], + }, + }), + ); + cdkExpect(searchableStack).to(countResources('AWS::AppSync::Resolver', 2)); + cdkExpect(searchableStack).to( + haveResource('AWS::AppSync::Resolver', { + ApiId: { + Ref: anything(), + }, + FieldName: anything(), + TypeName: 'Query', + Kind: 'PIPELINE', + PipelineConfig: { + Functions: [ + { + 'Fn::GetAtt': [anything(), 'FunctionId'], + }, + ], + }, + RequestMappingTemplate: { + 'Fn::Join': [ + '', + [ + anything(), + { + Ref: anything(), + }, + '"))\n$util.qr($ctx.stash.put("endpoint", "https://', + { + 'Fn::GetAtt': ['ElasticSearchDomain', 'DomainEndpoint'], + }, + '"))\n$util.toJson({})', + ], + ], + }, + ResponseMappingTemplate: '$util.toJson($ctx.prev.result)', + }), + ); + cdkExpect(searchableStack).to( + haveResource('AWS::AppSync::FunctionConfiguration', { + ApiId: { + Ref: anything(), + }, + DataSourceName: { + 'Fn::GetAtt': [anything(), 'Name'], + }, + FunctionVersion: '2018-05-29', + Name: anything(), + RequestMappingTemplateS3Location: { + 'Fn::Join': [ + '', + [ + 's3://', + { + Ref: anything(), + }, + '/', + { + Ref: anything(), + }, + anything(), + ], + ], + }, + ResponseMappingTemplateS3Location: { + 'Fn::Join': [ + '', + [ + 's3://', + { + Ref: anything(), + }, + '/', + { + Ref: anything(), + }, + anything(), + ], + ], + }, + }), + ); +}); diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnOutput.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnOutput.ts new file mode 100644 index 00000000000..2a3029ef9a4 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnOutput.ts @@ -0,0 +1,17 @@ +import { Construct, Fn } from '@aws-cdk/core'; +import { CfnOutput } from '@aws-cdk/core'; +import { ResourceConstants } from 'graphql-transformer-common'; + +export const createStackOutputs = (stack: Construct, endpoint: string, apiId: string, arn: string): void => { + const { ElasticsearchDomainArn, ElasticsearchDomainEndpoint } = ResourceConstants.OUTPUTS; + new CfnOutput(stack, ElasticsearchDomainArn, { + value: arn, + description: 'Elasticsearch instance Domain ARN.', + exportName: Fn.join(':', [apiId, 'GetAtt', 'Elasticsearch', 'DomainArn']).toString(), + }); + new CfnOutput(stack, ElasticsearchDomainEndpoint, { + value: 'https://' + endpoint, + description: 'Elasticsearch instance Domain Endpoint.', + exportName: Fn.join(':', [apiId, 'GetAtt', 'Elasticsearch', 'DomainEndpoint']).toString(), + }); +}; diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnParameters.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnParameters.ts new file mode 100644 index 00000000000..b54a2d26b53 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-cfnParameters.ts @@ -0,0 +1,131 @@ +import { ResourceConstants } from 'graphql-transformer-common'; +import { CfnParameter, Stack } from '@aws-cdk/core'; + +export function createParametersStack(stack: Stack): Map { + const { + ElasticsearchAccessIAMRoleName, + ElasticsearchStreamingLambdaHandlerName, + ElasticsearchStreamingLambdaRuntime, + ElasticsearchStreamingFunctionName, + ElasticsearchStreamingIAMRoleName, + ElasticsearchDebugStreamingLambda, + ElasticsearchInstanceCount, + ElasticsearchInstanceType, + ElasticsearchEBSVolumeGB, + } = ResourceConstants.PARAMETERS; + return new Map([ + [ + ElasticsearchAccessIAMRoleName, + new CfnParameter(stack, ElasticsearchAccessIAMRoleName, { + description: 'The name of the IAM role assumed by AppSync for Elasticsearch.', + default: 'AppSyncElasticsearchRole', + }), + ], + + [ + ElasticsearchStreamingLambdaHandlerName, + new CfnParameter(stack, ElasticsearchStreamingLambdaHandlerName, { + description: 'The name of the lambda handler.', + default: 'python_streaming_function.lambda_handler', + }), + ], + + [ + ElasticsearchStreamingLambdaRuntime, + new CfnParameter(stack, ElasticsearchStreamingLambdaRuntime, { + description: `The lambda runtime \ + (https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime)`, + default: 'python3.6', + }), + ], + + [ + ElasticsearchStreamingFunctionName, + new CfnParameter(stack, ElasticsearchStreamingFunctionName, { + description: 'The name of the streaming lambda function.', + default: 'DdbToEsFn', + }), + ], + + [ + ElasticsearchAccessIAMRoleName, + new CfnParameter(stack, ElasticsearchStreamingIAMRoleName, { + description: 'The name of the streaming lambda function IAM role.', + default: 'SearchableLambdaIAMRole', + }), + ], + + [ + ElasticsearchDebugStreamingLambda, + new CfnParameter(stack, ElasticsearchDebugStreamingLambda, { + description: 'Enable debug logs for the Dynamo -> ES streaming lambda.', + default: 1, + type: 'Number', + allowedValues: ['0', '1'], + }), + ], + + [ + ElasticsearchInstanceCount, + new CfnParameter(stack, ElasticsearchInstanceCount, { + description: 'The number of instances to launch into the Elasticsearch domain.', + default: 1, + type: 'Number', + }), + ], + + [ + ElasticsearchInstanceType, + new CfnParameter(stack, ElasticsearchInstanceType, { + description: 'The type of instance to launch into the Elasticsearch domain.', + default: 't2.small.elasticsearch', + allowedValues: [ + 't2.small.elasticsearch', + 't2.medium.elasticsearch', + 'c4.large.elasticsearch', + 'c4.xlarge.elasticsearch', + 'c4.2xlarge.elasticsearch', + 'c4.4xlarge.elasticsearch', + 'c4.8xlarge.elasticsearch', + 'm3.medium.elasticsearch', + 'm3.large.elasticsearch', + 'm3.xlarge.elasticsearch', + 'm3.2xlarge.elasticsearch', + 'm4.large.elasticsearch', + 'm4.xlarge.elasticsearch', + 'm4.2xlarge.elasticsearch', + 'm4.4xlarge.elasticsearch', + 'm4.10xlarge.elasticsearch', + 'r3.large.elasticsearch', + 'r3.xlarge.elasticsearch', + 'r3.2xlarge.elasticsearch', + 'r3.4xlarge.elasticsearch', + 'r3.8xlarge.elasticsearch', + 'r4.large.elasticsearch', + 'r4.xlarge.elasticsearch', + 'r4.2xlarge.elasticsearch', + 'r4.4xlarge.elasticsearch', + 'r4.8xlarge.elasticsearch', + 'r4.16xlarge.elasticsearch', + 'i2.xlarge.elasticsearch', + 'i2.2xlarge.elasticsearch', + 'i3.large.elasticsearch', + 'i3.xlarge.elasticsearch', + 'i3.2xlarge.elasticsearch', + 'i3.4xlarge.elasticsearch', + 'i3.8xlarge.elasticsearch', + 'i3.16xlarge.elasticsearch', + ], + }), + ], + + [ + ElasticsearchEBSVolumeGB, + new CfnParameter(stack, ElasticsearchEBSVolumeGB, { + description: 'The size in GB of the EBS volumes that contain our data.', + default: 10, + type: 'Number', + }), + ], + ]); +} diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-datasource.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-datasource.ts new file mode 100644 index 00000000000..058c8961cec --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-datasource.ts @@ -0,0 +1,28 @@ +import { GraphQLAPIProvider } from '@aws-amplify/graphql-transformer-interfaces'; +import { BaseDataSource } from '@aws-cdk/aws-appsync'; +import { IRole } from '@aws-cdk/aws-iam'; +import { ResourceConstants } from 'graphql-transformer-common'; +import assert from 'assert'; +import { Stack } from '@aws-cdk/core'; + +export const createEsDataSource = ( + stack: Stack, + graphqlApiProvider: GraphQLAPIProvider, + domainEndpoint: string, + role: IRole, + region?: string, +): BaseDataSource => { + const { ElasticsearchDataSourceLogicalID } = ResourceConstants.RESOURCES; + assert(region); + const dsEndpoint = 'https://' + domainEndpoint; + return graphqlApiProvider.addElasticSearchDataSource( + ElasticsearchDataSourceLogicalID, + region, + dsEndpoint, + { + serviceRole: role, + name: ElasticsearchDataSourceLogicalID, + }, + stack, + ); +}; diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-domain.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-domain.ts new file mode 100644 index 00000000000..aa1a070107e --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-es-domain.ts @@ -0,0 +1,50 @@ +import { EbsDeviceVolumeType } from '@aws-cdk/aws-ec2'; +import { CfnDomain, Domain, ElasticsearchVersion } from '@aws-cdk/aws-elasticsearch'; +import { IRole, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; +import { CfnParameter, Construct, Fn } from '@aws-cdk/core'; +import { ResourceConstants } from 'graphql-transformer-common'; + +export const createEsDomain = (stack: Construct, parameterMap: Map, apiId: string): Domain => { + const { ElasticsearchEBSVolumeGB, ElasticsearchInstanceType, ElasticsearchInstanceCount } = ResourceConstants.PARAMETERS; + const { ElasticsearchDomainLogicalID } = ResourceConstants.RESOURCES; + const { HasEnvironmentParameter } = ResourceConstants.CONDITIONS; + + const domain = new Domain(stack, ElasticsearchDomainLogicalID, { + version: ElasticsearchVersion.V6_2, + ebs: { + enabled: true, + volumeType: EbsDeviceVolumeType.GP2, + volumeSize: parameterMap.get(ElasticsearchEBSVolumeGB)?.valueAsNumber, + }, + zoneAwareness: { + enabled: false, + }, + domainName: Fn.conditionIf(HasEnvironmentParameter, Fn.ref('AWS::NoValue'), 'd' + apiId).toString(), + }); + + (domain.node.defaultChild as CfnDomain).elasticsearchClusterConfig = { + instanceCount: parameterMap.get(ElasticsearchInstanceCount)?.valueAsNumber, + instanceType: parameterMap.get(ElasticsearchInstanceType)?.valueAsString, + }; + + return domain; +}; + +export const createEsDomainRole = ( + stack: Construct, + parameterMap: Map, + apiId: string, + envParam: CfnParameter, +): IRole => { + const { ElasticsearchAccessIAMRoleLogicalID } = ResourceConstants.RESOURCES; + const { ElasticsearchAccessIAMRoleName } = ResourceConstants.PARAMETERS; + const { HasEnvironmentParameter } = ResourceConstants.CONDITIONS; + return new Role(stack, ElasticsearchAccessIAMRoleLogicalID, { + assumedBy: new ServicePrincipal('appsync.amazonaws.com'), + roleName: Fn.conditionIf( + HasEnvironmentParameter, + Fn.join('-', [parameterMap.get(ElasticsearchAccessIAMRoleName)!.valueAsString, apiId, envParam.valueAsString]), + Fn.join('-', [parameterMap.get(ElasticsearchAccessIAMRoleName)!.valueAsString, apiId, envParam.valueAsString]), + ).toString(), + }); +}; diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-layer-cfnMapping.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-layer-cfnMapping.ts new file mode 100644 index 00000000000..dbdab552b62 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-layer-cfnMapping.ts @@ -0,0 +1,74 @@ +import { CfnMapping, Construct } from '@aws-cdk/core'; + +export function setMappings(scope: Construct): CfnMapping { + return new CfnMapping(scope, 'LayerResourceMapping', { + mapping: { + 'ap-northeast-1': { + layerRegion: 'arn:aws:lambda:ap-northeast-1:249908578461:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-east-1': { + layerRegion: 'arn:aws:lambda:us-east-1:668099181075:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-southeast-1': { + layerRegion: 'arn:aws:lambda:ap-southeast-1:468957933125:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'eu-west-1': { + layerRegion: 'arn:aws:lambda:eu-west-1:399891621064:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-west-1': { + layerRegion: 'arn:aws:lambda:us-west-1:325793726646:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-east-1': { + layerRegion: 'arn:aws:lambda:ap-east-1:118857876118:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-northeast-2': { + layerRegion: 'arn:aws:lambda:ap-northeast-2:296580773974:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-northeast-3': { + layerRegion: 'arn:aws:lambda:ap-northeast-3:961244031340:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-south-1': { + layerRegion: 'arn:aws:lambda:ap-south-1:631267018583:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ap-southeast-2': { + layerRegion: 'arn:aws:lambda:ap-southeast-2:817496625479:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'ca-central-1': { + layerRegion: 'arn:aws:lambda:ca-central-1:778625758767:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'eu-central-1': { + layerRegion: 'arn:aws:lambda:eu-central-1:292169987271:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'eu-north-1': { + layerRegion: 'arn:aws:lambda:eu-north-1:642425348156:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'eu-west-2': { + layerRegion: 'arn:aws:lambda:eu-west-2:142628438157:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'eu-west-3': { + layerRegion: 'arn:aws:lambda:eu-west-3:959311844005:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'sa-east-1': { + layerRegion: 'arn:aws:lambda:sa-east-1:640010853179:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-east-2': { + layerRegion: 'arn:aws:lambda:us-east-2:259788987135:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-west-2': { + layerRegion: 'arn:aws:lambda:us-west-2:420165488524:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'cn-north-1': { + layerRegion: 'arn:aws-cn:lambda:cn-north-1:683298794825:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'cn-northwest-1': { + layerRegion: 'arn:aws-cn:lambda:cn-northwest-1:382066503313:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-gov-west-1': { + layerRegion: 'arn:aws-us-gov:lambda:us-gov-west-1:556739011827:layer:AWSLambda-Python-AWS-SDK:1', + }, + 'us-gov-east-1': { + layerRegion: 'arn:aws-us-gov:lambda:us-gov-east-1:138526772879:layer:AWSLambda-Python-AWS-SDK:1', + }, + }, + }); +} diff --git a/packages/amplify-graphql-searchable-transformer/src/cdk/create-streaming-lambda.ts b/packages/amplify-graphql-searchable-transformer/src/cdk/create-streaming-lambda.ts new file mode 100644 index 00000000000..14599784fae --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/cdk/create-streaming-lambda.ts @@ -0,0 +1,83 @@ +import { GraphQLAPIProvider } from '@aws-amplify/graphql-transformer-interfaces'; +import { EventSourceMapping, IFunction, LayerVersion, Runtime, StartingPosition } from '@aws-cdk/aws-lambda'; +import { CfnParameter, Construct, Fn, Stack } from '@aws-cdk/core'; +import { Effect, IRole, Policy, PolicyStatement, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; +import { ResourceConstants, SearchableResourceIDs } from 'graphql-transformer-common'; +import * as path from 'path'; +import assert from 'assert'; + +export const createLambda = ( + stack: Stack, + apiGraphql: GraphQLAPIProvider, + parameterMap: Map, + lambdaRole: IRole, + endpoint: string, + isProjectUsingDataStore: boolean, + region?: string, +): IFunction => { + assert(region); + const { ElasticsearchStreamingLambdaFunctionLogicalID } = ResourceConstants.RESOURCES; + const { ElasticsearchStreamingLambdaHandlerName, ElasticsearchDebugStreamingLambda } = ResourceConstants.PARAMETERS; + const enviroment: { [key: string]: string } = { + ES_ENDPOINT: 'https://' + endpoint, + ES_REGION: region, + DEBUG: parameterMap.get(ElasticsearchDebugStreamingLambda)!.valueAsString, + ES_USE_EXTERNAL_VERSIONING: isProjectUsingDataStore.toString(), + }; + + return apiGraphql.addLambdaFunction( + ElasticsearchStreamingLambdaFunctionLogicalID, + 'functions/' + ElasticsearchStreamingLambdaFunctionLogicalID + '.zip', + parameterMap.get(ElasticsearchStreamingLambdaHandlerName)!.valueAsString, + path.resolve(__dirname, '..', '..', 'lib', 'streaming-lambda.zip'), + Runtime.PYTHON_3_6, + [ + LayerVersion.fromLayerVersionArn( + stack, + 'LambdaLayerVersion', + Fn.findInMap('LayerResourceMapping', Fn.ref('AWS::Region'), 'layerRegion'), + ), + ], + lambdaRole, + enviroment, + stack, + ); +}; + +export const createLambdaRole = (stack: Construct, parameterMap: Map): IRole => { + const { ElasticsearchStreamingLambdaIAMRoleLogicalID } = ResourceConstants.RESOURCES; + const { ElasticsearchStreamingIAMRoleName } = ResourceConstants.PARAMETERS; + const role = new Role(stack, ElasticsearchStreamingLambdaIAMRoleLogicalID, { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + roleName: parameterMap.get(ElasticsearchStreamingIAMRoleName)?.valueAsString, + }); + role.attachInlinePolicy( + new Policy(stack, 'CloudwatchLogsAccess', { + statements: [ + new PolicyStatement({ + actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'], + effect: Effect.ALLOW, + resources: ['arn:aws:logs:*:*:*'], + }), + ], + }), + ); + + return role; +}; + +export const createEventSourceMapping = ( + stack: Construct, + type: string, + target: IFunction, + tableStreamArn?: string, +): EventSourceMapping => { + assert(tableStreamArn); + return new EventSourceMapping(stack, SearchableResourceIDs.SearchableEventSourceMappingID(type), { + eventSourceArn: tableStreamArn, + target, + batchSize: 1, + enabled: true, + startingPosition: StartingPosition.LATEST, + }); +}; diff --git a/packages/amplify-graphql-searchable-transformer/src/definitions.ts b/packages/amplify-graphql-searchable-transformer/src/definitions.ts new file mode 100644 index 00000000000..609983fa745 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/definitions.ts @@ -0,0 +1,238 @@ +import { + ObjectTypeDefinitionNode, + InputValueDefinitionNode, + InputObjectTypeDefinitionNode, + FieldDefinitionNode, + Kind, + TypeNode, + EnumTypeDefinitionNode, + EnumValueDefinitionNode, +} from 'graphql'; +import { graphqlName, makeNamedType, isScalar, makeListType, getBaseType, SearchableResourceIDs } from 'graphql-transformer-common'; + +const ID_CONDITIONS = [ + 'ne', + 'gt', + 'lt', + 'gte', + 'lte', + 'eq', + 'match', + 'matchPhrase', + 'matchPhrasePrefix', + 'multiMatch', + 'exists', + 'wildcard', + 'regexp', + 'range', +]; +const STRING_CONDITIONS = ID_CONDITIONS; +const INT_CONDITIONS = ['ne', 'gt', 'lt', 'gte', 'lte', 'eq', 'range']; +const FLOAT_CONDITIONS = ['ne', 'gt', 'lt', 'gte', 'lte', 'eq', 'range']; +const BOOLEAN_CONDITIONS = ['eq', 'ne']; +import assert from 'assert'; + +export function makeSearchableScalarInputObject(type: string): InputObjectTypeDefinitionNode { + const name = SearchableResourceIDs.SearchableFilterInputTypeName(type); + const conditions = getScalarConditions(type); + const fields: InputValueDefinitionNode[] = conditions.map((condition: string) => ({ + kind: Kind.INPUT_VALUE_DEFINITION, + name: { kind: 'Name' as const, value: condition }, + type: getScalarFilterInputType(condition, type, name), + // TODO: Service does not support new style descriptions so wait. + // description: field.description, + directives: [], + })); + return { + kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, + // TODO: Service does not support new style descriptions so wait. + // description: { + // kind: 'StringValue', + // value: `Input type for ${obj.name.value} mutations` + // }, + name: { + kind: 'Name', + value: name, + }, + fields, + directives: [], + }; +} + +export function makeSearchableXFilterInputObject(obj: ObjectTypeDefinitionNode): InputObjectTypeDefinitionNode { + const name = SearchableResourceIDs.SearchableFilterInputTypeName(obj.name.value); + assert(obj.fields); + const fields: InputValueDefinitionNode[] = obj.fields + .filter((field: FieldDefinitionNode) => isScalar(field.type)) + .map( + (field: FieldDefinitionNode) => + ({ + kind: Kind.INPUT_VALUE_DEFINITION, + name: field.name, + type: makeNamedType(SearchableResourceIDs.SearchableFilterInputTypeName(getBaseType(field.type))), + // TODO: Service does not support new style descriptions so wait. + // description: field.description, + directives: [], + } as InputValueDefinitionNode), + ); + + fields.push( + { + kind: Kind.INPUT_VALUE_DEFINITION, + name: { + kind: 'Name', + value: 'and', + }, + type: makeListType(makeNamedType(name)), + // TODO: Service does not support new style descriptions so wait. + // description: field.description, + directives: [], + }, + { + kind: Kind.INPUT_VALUE_DEFINITION, + name: { + kind: 'Name', + value: 'or', + }, + type: makeListType(makeNamedType(name)), + // TODO: Service does not support new style descriptions so wait. + // description: field.description, + directives: [], + }, + { + kind: Kind.INPUT_VALUE_DEFINITION, + name: { + kind: 'Name', + value: 'not', + }, + type: makeNamedType(name), + // TODO: Service does not support new style descriptions so wait. + // description: field.description, + directives: [], + }, + ); + return { + kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, + name: { + kind: 'Name', + value: name, + }, + fields, + directives: [], + }; +} + +export function makeSearchableSortDirectionEnumObject(): EnumTypeDefinitionNode { + const name = graphqlName(`SearchableSortDirection`); + return { + kind: Kind.ENUM_TYPE_DEFINITION, + name: { + kind: 'Name', + value: name, + }, + values: [ + { + kind: Kind.ENUM_VALUE_DEFINITION, + name: { kind: 'Name', value: 'asc' }, + directives: [], + }, + { + kind: Kind.ENUM_VALUE_DEFINITION, + name: { kind: 'Name', value: 'desc' }, + directives: [], + }, + ], + directives: [], + }; +} + +export function makeSearchableXSortableFieldsEnumObject(obj: ObjectTypeDefinitionNode): EnumTypeDefinitionNode { + const name = graphqlName(`Searchable${obj.name.value}SortableFields`); + assert(obj.fields); + const values: EnumValueDefinitionNode[] = obj.fields + .filter((field: FieldDefinitionNode) => isScalar(field.type)) + .map((field: FieldDefinitionNode) => ({ + kind: Kind.ENUM_VALUE_DEFINITION, + name: field.name, + directives: [], + })); + + return { + kind: Kind.ENUM_TYPE_DEFINITION, + name: { + kind: 'Name', + value: name, + }, + values, + directives: [], + }; +} + +export function makeSearchableXSortInputObject(obj: ObjectTypeDefinitionNode): InputObjectTypeDefinitionNode { + const name = graphqlName(`Searchable${obj.name.value}SortInput`); + return { + kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, + // TODO: Service does not support new style descriptions so wait. + // description: { + // kind: 'StringValue', + // value: `Input type for ${obj.name.value} delete mutations` + // }, + name: { + kind: 'Name', + value: name, + }, + fields: [ + { + kind: Kind.INPUT_VALUE_DEFINITION, + name: { kind: 'Name', value: 'field' }, + type: makeNamedType(`Searchable${obj.name.value}SortableFields`), + // TODO: Service does not support new style descriptions so wait. + // description: { + // kind: 'StringValue', + // value: `The id of the ${obj.name.value} to delete.` + // }, + directives: [], + }, + { + kind: Kind.INPUT_VALUE_DEFINITION, + name: { kind: 'Name', value: 'direction' }, + type: makeNamedType('SearchableSortDirection'), + // TODO: Service does not support new style descriptions so wait. + // description: { + // kind: 'StringValue', + // value: `The id of the ${obj.name.value} to delete.` + // }, + directives: [], + }, + ], + directives: [], + }; +} + +function getScalarFilterInputType(condition: string, type: string, filterInputName: string): TypeNode { + switch (condition) { + case 'range': + return makeListType(makeNamedType(type)); + case 'exists': + return makeNamedType('Boolean'); + default: + return makeNamedType(type); + } +} + +function getScalarConditions(type: string): string[] { + switch (type) { + case 'String': + return STRING_CONDITIONS; + case 'ID': + return ID_CONDITIONS; + case 'Int': + return INT_CONDITIONS; + case 'Float': + return FLOAT_CONDITIONS; + case 'Boolean': + return BOOLEAN_CONDITIONS; + default: + throw 'Valid types are String, ID, Int, Float, Boolean'; + } +} diff --git a/packages/amplify-graphql-searchable-transformer/src/generate-resolver-vtl.ts b/packages/amplify-graphql-searchable-transformer/src/generate-resolver-vtl.ts new file mode 100644 index 00000000000..032537c0855 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/generate-resolver-vtl.ts @@ -0,0 +1,88 @@ +import { + ElasticsearchMappingTemplate, + print, + str, + ref, + obj, + set, + iff, + list, + raw, + forEach, + compoundExpression, + qref, + toJson, + ifElse, + int, + Expression, + bool, + methodCall, +} from 'graphql-mapping-template'; +import { ResourceConstants } from 'graphql-transformer-common'; + +export function requestTemplate(primaryKey: string, nonKeywordFields: Expression[], includeVersion: boolean = false, type: string): string { + return print( + compoundExpression([ + set(ref('indexPath'), str(`/${type.toLowerCase()}/doc/_search`)), + set(ref('nonKeywordFields'), list(nonKeywordFields)), + ifElse( + ref('util.isNullOrEmpty($context.args.sort)'), + compoundExpression([set(ref('sortDirection'), str('desc')), set(ref('sortField'), str(primaryKey))]), + compoundExpression([ + set(ref('sortDirection'), ref('util.defaultIfNull($context.args.sort.direction, "desc")')), + set(ref('sortField'), ref(`util.defaultIfNull($context.args.sort.field, "${primaryKey}")`)), + ]), + ), + ifElse( + ref('nonKeywordFields.contains($sortField)'), + compoundExpression([set(ref('sortField0'), ref('util.toJson($sortField)'))]), + compoundExpression([set(ref('sortField0'), ref('util.toJson("${sortField}.keyword")'))]), + ), + ElasticsearchMappingTemplate.searchItem({ + path: str('$indexPath'), + size: ifElse(ref('context.args.limit'), ref('context.args.limit'), int(ResourceConstants.DEFAULT_SEARCHABLE_PAGE_LIMIT), true), + search_after: list([ref('util.toJson($context.args.nextToken)')]), + from: ref('context.args.from'), + version: bool(includeVersion), + query: ifElse( + ref('context.args.filter'), + ref('util.transform.toElasticsearchQueryDSL($ctx.args.filter)'), + obj({ + match_all: obj({}), + }), + ), + sort: list([raw('{$sortField0: { "order" : $util.toJson($sortDirection) }}')]), + }), + ]), + ); +} + +export function responseTemplate(includeVersion = false) { + return print( + compoundExpression([ + set(ref('es_items'), list([])), + forEach(ref('entry'), ref('context.result.hits.hits'), [ + iff(raw('!$foreach.hasNext'), set(ref('nextToken'), ref('entry.sort.get(0)'))), + ...getSourceMapper(includeVersion), + ]), + toJson( + obj({ + items: ref('es_items'), + total: ref('ctx.result.hits.total'), + nextToken: ref('nextToken'), + }), + ), + ]), + ); +} + +function getSourceMapper(includeVersion: boolean) { + if (includeVersion) { + return [ + set(ref('row'), methodCall(ref('entry.get'), str('_source'))), + qref('$row.put("_version", $entry.get("_version"))'), + qref('$es_items.add($row)'), + ]; + } + return [qref('$es_items.add($entry.get("_source"))')]; +} diff --git a/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts b/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts new file mode 100644 index 00000000000..db39d2f9cf3 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/graphql-searchable-transformer.ts @@ -0,0 +1,256 @@ +import { TransformerPluginBase, InvalidDirectiveError, MappingTemplate, DirectiveWrapper } from '@aws-amplify/graphql-transformer-core'; +import { + DataSourceProvider, + TransformerContextProvider, + TransformerSchemaVisitStepContextProvider, +} from '@aws-amplify/graphql-transformer-interfaces'; +import { DynamoDbDataSource } from '@aws-cdk/aws-appsync'; +import { Table } from '@aws-cdk/aws-dynamodb'; +import { CfnCondition, CfnParameter, Fn, IConstruct } from '@aws-cdk/core'; +import { DirectiveNode, InputObjectTypeDefinitionNode, ObjectTypeDefinitionNode } from 'graphql'; +import { Expression, str } from 'graphql-mapping-template'; +import { + ResourceConstants, + getBaseType, + ModelResourceIDs, + STANDARD_SCALARS, + blankObject, + blankObjectExtension, + extensionWithFields, + makeField, + makeListType, + makeNamedType, + makeInputValueDefinition, + graphqlName, + plurality, + toUpper, +} from 'graphql-transformer-common'; +import { createParametersStack as createParametersInStack } from './cdk/create-cfnParameters'; +import { requestTemplate, responseTemplate } from './generate-resolver-vtl'; +import { + makeSearchableScalarInputObject, + makeSearchableSortDirectionEnumObject, + makeSearchableXFilterInputObject, + makeSearchableXSortableFieldsEnumObject, + makeSearchableXSortInputObject, +} from './definitions'; +import assert from 'assert'; +import { setMappings } from './cdk/create-layer-cfnMapping'; +import { createEsDomain, createEsDomainRole } from './cdk/create-es-domain'; +import { createEsDataSource } from './cdk/create-es-datasource'; +import { createEventSourceMapping, createLambda, createLambdaRole } from './cdk/create-streaming-lambda'; +import { createStackOutputs } from './cdk/create-cfnOutput'; + +const nonKeywordTypes = ['Int', 'Float', 'Boolean', 'AWSTimestamp', 'AWSDate', 'AWSDateTime']; +const STACK_NAME = 'SearchableStack'; +export class SearchableModelTransformer extends TransformerPluginBase { + searchableObjectTypeDefinitions: { node: ObjectTypeDefinitionNode; fieldName: string }[]; + constructor() { + super( + 'amplify-searchable-transformer', + /* GraphQL */ ` + directive @searchable(queries: SearchableQueryMap) on OBJECT + input SearchableQueryMap { + search: String + } + `, + ); + this.searchableObjectTypeDefinitions = []; + } + + generateResolvers = (context: TransformerContextProvider): void => { + const { Env } = ResourceConstants.PARAMETERS; + + const { HasEnvironmentParameter } = ResourceConstants.CONDITIONS; + + const stack = context.stackManager.createStack(STACK_NAME); + + setMappings(stack); + + const envParam = context.stackManager.getParameter(Env) as CfnParameter; + + new CfnCondition(stack, HasEnvironmentParameter, { + expression: Fn.conditionNot(Fn.conditionEquals(envParam, ResourceConstants.NONE)), + }); + + const isProjectUsingDataStore = false; + + stack.templateOptions.description = 'An auto-generated nested stack for searchable.'; + stack.templateOptions.templateFormatVersion = '2010-09-09'; + + const parameterMap = createParametersInStack(stack); + + const domain = createEsDomain(stack, parameterMap, context.api.apiId); + + const elasticsearchRole = createEsDomainRole(stack, parameterMap, context.api.apiId, envParam); + + domain.grantReadWrite(elasticsearchRole); + + const datasource = createEsDataSource( + stack, + context.api, + domain.domainEndpoint, + elasticsearchRole, + stack.parseArn(domain.domainArn).region, + ); + + // streaming lambda role + const lambdaRole = createLambdaRole(stack, parameterMap); + domain.grantWrite(lambdaRole); + + // creates streaming lambda + const lambda = createLambda( + stack, + context.api, + parameterMap, + lambdaRole, + domain.domainEndpoint, + isProjectUsingDataStore, + stack.parseArn(domain.domainArn).region, + ); + + for (const def of this.searchableObjectTypeDefinitions) { + const type = def.node.name.value; + const typeName = context.output.getQueryTypeName(); + const table = getTable(context, def.node); + const ddbTable = table as Table; + assert(ddbTable); + + ddbTable.grantStreamRead(lambdaRole); + + // creates event source mapping from ddb to lambda + createEventSourceMapping(stack, type, lambda, ddbTable.tableStreamArn); + + const { attributeName } = (table as any).keySchema.find((att: any) => att.keyType === 'HASH'); + assert(typeName); + const resolver = context.resolvers.generateQueryResolver( + typeName, + def.fieldName, + datasource as DataSourceProvider, + MappingTemplate.s3MappingTemplateFromString( + requestTemplate(attributeName, getNonKeywordFields(def.node), false, type), + `${typeName}.${def.fieldName}.req.vtl`, + ), + MappingTemplate.s3MappingTemplateFromString(responseTemplate(false), `${typeName}.${def.fieldName}.res.vtl`), + ); + resolver.mapToStack(stack); + context.resolvers.addResolver(type, def.fieldName, resolver); + } + + createStackOutputs(stack, domain.domainEndpoint, context.api.apiId, domain.domainArn); + }; + + object = (definition: ObjectTypeDefinitionNode, directive: DirectiveNode, ctx: TransformerSchemaVisitStepContextProvider): void => { + const modelDirective = definition?.directives?.find(dir => dir.name.value === 'model'); + if (!modelDirective) { + throw new InvalidDirectiveError('Types annotated with @searchable must also be annotated with @model.'); + } + + const directiveWrapped = new DirectiveWrapper(directive); + const directiveArguments = directiveWrapped.getArguments({}) as any; + let shouldMakeSearch = true; + let searchFieldNameOverride = undefined; + + if (directiveArguments.queries) { + if (!directiveArguments.queries.search) { + shouldMakeSearch = false; + } else { + searchFieldNameOverride = directiveArguments.queries.search; + } + } + const fieldName = searchFieldNameOverride ? searchFieldNameOverride : graphqlName(`search${plurality(toUpper(definition.name.value))}`); + this.searchableObjectTypeDefinitions.push({ + node: definition, + fieldName, + }); + + if (shouldMakeSearch) { + this.generateSearchableInputs(ctx, definition); + this.generateSearchableXConnectionType(ctx, definition); + const queryField = makeField( + fieldName, + [ + makeInputValueDefinition('filter', makeNamedType(`Searchable${definition.name.value}FilterInput`)), + makeInputValueDefinition('sort', makeNamedType(`Searchable${definition.name.value}SortInput`)), + makeInputValueDefinition('limit', makeNamedType('Int')), + makeInputValueDefinition('nextToken', makeNamedType('String')), + makeInputValueDefinition('from', makeNamedType('Int')), + ], + makeNamedType(`Searchable${definition.name.value}Connection`), + ); + + ctx.output.addQueryFields([queryField]); + } + }; + + private generateSearchableXConnectionType(ctx: TransformerSchemaVisitStepContextProvider, definition: ObjectTypeDefinitionNode): void { + const searchableXConnectionName = `Searchable${definition.name.value}Connection`; + if (ctx.output.hasType(searchableXConnectionName)) { + return; + } + + // Create the TableXConnection + const connectionType = blankObject(searchableXConnectionName); + ctx.output.addObject(connectionType); + + // Create TableXConnection type with items and nextToken + let connectionTypeExtension = blankObjectExtension(searchableXConnectionName); + connectionTypeExtension = extensionWithFields(connectionTypeExtension, [ + makeField('items', [], makeListType(makeNamedType(definition.name.value))), + ]); + connectionTypeExtension = extensionWithFields(connectionTypeExtension, [ + makeField('nextToken', [], makeNamedType('String')), + makeField('total', [], makeNamedType('Int')), + ]); + ctx.output.addObjectExtension(connectionTypeExtension); + } + + private generateSearchableInputs(ctx: TransformerSchemaVisitStepContextProvider, definition: ObjectTypeDefinitionNode): void { + const inputs: string[] = Object.keys(STANDARD_SCALARS); + inputs + .filter(input => !ctx.output.hasType(`Searchable${input}FilterInput`)) + .map(makeSearchableScalarInputObject) + .forEach((node: InputObjectTypeDefinitionNode) => ctx.output.addInput(node)); + + const searchableXQueryFilterInput = makeSearchableXFilterInputObject(definition); + if (!ctx.output.hasType(searchableXQueryFilterInput.name.value)) { + ctx.output.addInput(searchableXQueryFilterInput); + } + + if (!ctx.output.hasType('SearchableSortDirection')) { + const searchableSortDirection = makeSearchableSortDirectionEnumObject(); + ctx.output.addEnum(searchableSortDirection); + } + + if (!ctx.output.hasType(`Searchable${definition.name.value}SortableFields`)) { + const searchableXSortableFieldsDirection = makeSearchableXSortableFieldsEnumObject(definition); + ctx.output.addEnum(searchableXSortableFieldsDirection); + } + + if (!ctx.output.hasType(`Searchable${definition.name.value}SortInput`)) { + const searchableXSortableInputDirection = makeSearchableXSortInputObject(definition); + ctx.output.addInput(searchableXSortableInputDirection); + } + } +} + +function getTable(context: TransformerContextProvider, definition: ObjectTypeDefinitionNode): IConstruct { + const ddbDataSource = context.dataSources.get(definition) as DynamoDbDataSource; + const tableName = ModelResourceIDs.ModelTableResourceID(definition.name.value); + const table = ddbDataSource.ds.stack.node.findChild(tableName); + return table; +} + +function getNonKeywordFields(def: ObjectTypeDefinitionNode): Expression[] { + const nonKeywordTypeSet = new Set(nonKeywordTypes); + + return def.fields?.filter(field => nonKeywordTypeSet.has(getBaseType(field.type))).map(field => str(field.name.value)) || []; +} + +interface SearchableQueryMap { + search?: string; +} + +interface SearchableDirectiveArgs { + queries?: SearchableQueryMap; +} diff --git a/packages/amplify-graphql-searchable-transformer/src/index.ts b/packages/amplify-graphql-searchable-transformer/src/index.ts new file mode 100644 index 00000000000..27ff2f1145a --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/src/index.ts @@ -0,0 +1 @@ +export { SearchableModelTransformer } from './graphql-searchable-transformer'; diff --git a/packages/amplify-graphql-searchable-transformer/streaming-lambda/python_streaming_function.py b/packages/amplify-graphql-searchable-transformer/streaming-lambda/python_streaming_function.py new file mode 100644 index 00000000000..f72a39b2dc1 --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/streaming-lambda/python_streaming_function.py @@ -0,0 +1,257 @@ +import base64 +import json +import logging +import os +import time +import traceback +from urllib.parse import urlparse, quote + +from botocore.auth import SigV4Auth +from botocore.awsrequest import AWSRequest +from botocore.credentials import get_credentials +from botocore.endpoint import BotocoreHTTPSession +from botocore.session import Session +from boto3.dynamodb.types import TypeDeserializer + + +# The following parameters are required to configure the ES cluster +ES_ENDPOINT = os.environ['ES_ENDPOINT'] +ES_REGION = os.environ['ES_REGION'] +DEBUG = True if os.environ['DEBUG'] == "1" else False +ES_USE_EXTERNAL_VERSIONING = True if os.environ['ES_USE_EXTERNAL_VERSIONING'] == "true" else False + +# ElasticSearch 6 deprecated having multiple mapping types in an index. Default to doc. +DOC_TYPE = 'doc' +ES_MAX_RETRIES = 3 # Max number of retries for exponential backoff + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG if DEBUG else logging.INFO) +logger.info("Streaming to ElasticSearch") + +# custom encoder changes +# - sets to lists +class DDBTypesEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return list(obj) + return json.JSONEncoder.default(self, obj) + +# Subclass of boto's TypeDeserializer for DynamoDB to adjust for DynamoDB Stream format. +class StreamTypeDeserializer(TypeDeserializer): + def _deserialize_n(self, value): + return float(value) + + def _deserialize_b(self, value): + return value # Already in Base64 + + +class ES_Exception(Exception): + '''Capture status_code from request''' + status_code = 0 + payload = '' + + def __init__(self, status_code, payload): + self.status_code = status_code + self.payload = payload + Exception.__init__( + self, 'ES_Exception: status_code={}, payload={}'.format(status_code, payload)) + + +# Low-level POST data to Amazon Elasticsearch Service generating a Sigv4 signed request +def post_data_to_es(payload, region, creds, host, path, method='POST', proto='https://'): + '''Post data to ES endpoint with SigV4 signed http headers''' + req = AWSRequest(method=method, url=proto + host + + quote(path), data=payload, headers={'Host': host, 'Content-Type': 'application/json'}) + SigV4Auth(creds, 'es', region).add_auth(req) + http_session = BotocoreHTTPSession() + res = http_session.send(req.prepare()) + if res.status_code >= 200 and res.status_code <= 299: + return res._content + else: + raise ES_Exception(res.status_code, res._content) + + +# High-level POST data to Amazon Elasticsearch Service with exponential backoff +# according to suggested algorithm: http://docs.aws.amazon.com/general/latest/gr/api-retries.html +def post_to_es(payload): + '''Post data to ES cluster with exponential backoff''' + + # Get aws_region and credentials to post signed URL to ES + es_region = ES_REGION or os.environ['AWS_REGION'] + session = Session({'region': es_region}) + creds = get_credentials(session) + es_url = urlparse(ES_ENDPOINT) + # Extract the domain name in ES_ENDPOINT + es_endpoint = es_url.netloc or es_url.path + + # Post data with exponential backoff + retries = 0 + while retries < ES_MAX_RETRIES: + if retries > 0: + seconds = (2 ** retries) * .1 + logger.debug('Waiting for %.1f seconds', seconds) + time.sleep(seconds) + + try: + es_ret_str = post_data_to_es( + payload, es_region, creds, es_endpoint, '/_bulk') + logger.debug('Return from ES: %s', es_ret_str) + es_ret = json.loads(es_ret_str) + + if es_ret['errors']: + logger.error( + 'ES post unsuccessful, errors present, took=%sms', es_ret['took']) + # Filter errors + es_errors = [item for item in es_ret['items'] + if item.get('index', {}).get('error')] + logger.error('List of items with errors: %s', + json.dumps(es_errors)) + else: + logger.info('ES post successful, took=%sms', es_ret['took']) + break # Sending to ES was ok, break retry loop + except ES_Exception as e: + if (e.status_code >= 500) and (e.status_code <= 599): + retries += 1 # Candidate for retry + else: + raise # Stop retrying, re-raise exception + + +# Extracts the DynamoDB table from an ARN +# ex: arn:aws:dynamodb:eu-west-1:123456789012:table/table-name/stream/2015-11-13T09:23:17.104 should return 'table-name' +def get_table_name_from_arn(arn): + return arn.split(':')[5].split('/')[1] + + +# Compute a compound doc index from the key(s) of the object in lexicographic order: "k1=key_val1|k2=key_val2" +def compute_doc_index(keys_raw, deserializer, formatIndex=False): + index = [] + for key in sorted(keys_raw): + if formatIndex: + index.append('{}={}'.format( + key, deserializer.deserialize(keys_raw[key]))) + else: + index.append(deserializer.deserialize(keys_raw[key])) + return '|'.join(map(str,index)) + +def _lambda_handler(event, context): + logger.debug('Event: %s', event) + records = event['Records'] + + ddb_deserializer = StreamTypeDeserializer() + es_actions = [] # Items to be added/updated/removed from ES - for bulk API + cnt_insert = cnt_modify = cnt_remove = 0 + + for record in records: + # Handle both native DynamoDB Streams or Streams data from Kinesis (for manual replay) + logger.debug('Record: %s', record) + if record.get('eventSource') == 'aws:dynamodb': + ddb = record['dynamodb'] + ddb_table_name = get_table_name_from_arn(record['eventSourceARN']) + doc_seq = ddb['SequenceNumber'] + elif record.get('eventSource') == 'aws:kinesis': + ddb = json.loads(base64.b64decode(record['kinesis']['data'])) + ddb_table_name = ddb['SourceTable'] + doc_seq = record['kinesis']['sequenceNumber'] + else: + logger.error('Ignoring non-DynamoDB event sources: %s', + record.get('eventSource')) + continue + + # Compute DynamoDB table, type and index for item + doc_table = ddb_table_name.lower() + doc_type = DOC_TYPE + doc_table_parts = doc_table.split('-') + doc_es_index_name = doc_table_parts[0] if len(doc_table_parts) > 0 else doc_table + + # Dispatch according to event TYPE + event_name = record['eventName'].upper() # INSERT, MODIFY, REMOVE + logger.debug('doc_table=%s, event_name=%s, seq=%s', + doc_table, event_name, doc_seq) + + # Treat events from a Kinesis stream as INSERTs + if event_name == 'AWS:KINESIS:RECORD': + event_name = 'INSERT' + + is_ddb_insert_or_update = (event_name == 'INSERT') or (event_name == 'MODIFY') + is_ddb_delete = event_name == 'REMOVE' + image_name = 'NewImage' if is_ddb_insert_or_update else 'OldImage' + + if image_name not in ddb: + logger.warning( + 'Cannot process stream if it does not contain ' + image_name) + continue + logger.debug(image_name + ': %s', ddb[image_name]) + # Deserialize DynamoDB type to Python types + doc_fields = ddb_deserializer.deserialize({'M': ddb[image_name]}) + + # Sync enabled APIs do soft delete. We need to delete the record in ES if _deleted field is set + if ES_USE_EXTERNAL_VERSIONING and event_name == 'MODIFY' and '_deleted' in doc_fields and doc_fields['_deleted']: + is_ddb_insert_or_update = False + is_ddb_delete = True + + # Update counters + if event_name == 'INSERT': + cnt_insert += 1 + elif event_name == 'MODIFY': + cnt_modify += 1 + elif event_name == 'REMOVE': + cnt_remove += 1 + else: + logger.warning('Unsupported event_name: %s', event_name) + + logger.debug('Deserialized doc_fields: %s', doc_fields) + + if ('Keys' in ddb): + doc_id = compute_doc_index(ddb['Keys'], ddb_deserializer) + else: + logger.error('Cannot find keys in ddb record') + + # If DynamoDB INSERT or MODIFY, send 'index' to ES + if is_ddb_insert_or_update: + # Generate ES payload for item + action = {'index': {'_index': doc_es_index_name, + '_type': doc_type, + '_id': doc_id}} + # Add external versioning if necessary + if ES_USE_EXTERNAL_VERSIONING and '_version' in doc_fields: + action['index'].update([ + ('version_type', 'external'), + ('_version', doc_fields['_version']) + ]) + doc_fields.pop('_ttl', None) + doc_fields.pop('_version', None) + # Append ES Action line with 'index' directive + es_actions.append(json.dumps(action)) + # Append JSON payload + es_actions.append(json.dumps(doc_fields, cls=DDBTypesEncoder)) + # migration step remove old key if it exists + if ('id' in doc_fields) and (event_name == 'MODIFY') : + action = {'delete': {'_index': doc_es_index_name, '_type': doc_type, + '_id': compute_doc_index(ddb['Keys'], ddb_deserializer, True)}} + es_actions.append(json.dumps(action)) + # If DynamoDB REMOVE, send 'delete' to ES + elif is_ddb_delete: + action = {'delete': {'_index': doc_es_index_name, + '_type': doc_type, '_id': doc_id}} + if ES_USE_EXTERNAL_VERSIONING and '_version' in doc_fields: + action['delete'].update([ + ('version_type', 'external'), + ('_version', doc_fields['_version']) + ]) + # Action line with 'delete' directive + es_actions.append(json.dumps(action)) + + # Prepare bulk payload + es_actions.append('') # Add one empty line to force final \n + es_payload = '\n'.join(es_actions) + logger.info('Posting to ES: inserts=%s updates=%s deletes=%s, total_lines=%s, bytes_total=%s', + cnt_insert, cnt_modify, cnt_remove, len(es_actions) - 1, len(es_payload)) + post_to_es(es_payload) # Post to ES with exponential backoff + + +# Global lambda handler - catches all exceptions to avoid dead letter in the DynamoDB Stream +def lambda_handler(event, context): + try: + return _lambda_handler(event, context) + except Exception: + logger.error(traceback.format_exc()) diff --git a/packages/amplify-graphql-searchable-transformer/tsconfig.json b/packages/amplify-graphql-searchable-transformer/tsconfig.json new file mode 100644 index 00000000000..f9f02980f1b --- /dev/null +++ b/packages/amplify-graphql-searchable-transformer/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib" + }, + "references": [ + {"path": "../amplify-graphql-transformer-interfaces"}, + {"path": "../graphql-mapping-template"} + ] +} diff --git a/packages/amplify-graphql-transformer-core/CHANGELOG.md b/packages/amplify-graphql-transformer-core/CHANGELOG.md index 203f9ea026c..9ae68c160fa 100644 --- a/packages/amplify-graphql-transformer-core/CHANGELOG.md +++ b/packages/amplify-graphql-transformer-core/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.6.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-transformer-core@0.5.0...@aws-amplify/graphql-transformer-core@0.6.0) (2021-05-18) + + +### Features + +* port [@searchable](https://github.com/searchable) to GraphQL Transformer v2 ([#7291](https://github.com/aws-amplify/amplify-cli/issues/7291)) ([37a2df2](https://github.com/aws-amplify/amplify-cli/commit/37a2df2365fe4bf0eddf285a159221e34f695fe2)) + + + + + # [0.5.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-transformer-core@0.3.4...@aws-amplify/graphql-transformer-core@0.5.0) (2021-05-03) diff --git a/packages/amplify-graphql-transformer-core/package.json b/packages/amplify-graphql-transformer-core/package.json index edaa6c9813c..78313cd3f40 100644 --- a/packages/amplify-graphql-transformer-core/package.json +++ b/packages/amplify-graphql-transformer-core/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/graphql-transformer-core", - "version": "0.5.0", + "version": "0.6.0", "description": "A framework to transform from GraphQL SDL to AWS CloudFormation.", "repository": { "type": "git", @@ -26,7 +26,7 @@ "clean": "rimraf ./lib" }, "dependencies": { - "@aws-amplify/graphql-transformer-interfaces": "1.5.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", "@aws-cdk/assets": "~1.72.0", "@aws-cdk/aws-applicationautoscaling": "~1.72.0", "@aws-cdk/aws-appsync": "~1.72.0", diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/elasticsearch-datasource.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/elasticsearch-datasource.ts new file mode 100644 index 00000000000..123e55922bb --- /dev/null +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/elasticsearch-datasource.ts @@ -0,0 +1,31 @@ +import { BackedDataSourceProps, BaseDataSource } from '@aws-cdk/aws-appsync'; +import { Construct } from '@aws-cdk/core'; + +/** + * Properties for an AppSync Elasticsearch data source + */ +export interface ElasticsearchDataSourceProps extends BackedDataSourceProps { + /** + * Region for the Amazon Elasticsearch Service domain + */ + readonly region: string; + /** + * Endpoint for the Amazon Elasticsearch Service domain + */ + readonly endpoint: string; +} + +/** + * An AppSync data source backed by Elasticsearch + */ +export class ElasticsearchDataSource extends BaseDataSource { + constructor(scope: Construct, id: string, props: ElasticsearchDataSourceProps) { + super(scope, id, props, { + type: 'AMAZON_ELASTICSEARCH', + elasticsearchConfig: { + awsRegion: props.region, + endpoint: props.endpoint, + }, + }); + } +} diff --git a/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts b/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts index ddf4eb72966..bda3bd9e56d 100644 --- a/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts +++ b/packages/amplify-graphql-transformer-core/src/cdk-compat/template-asset.ts @@ -4,15 +4,40 @@ import { S3MappingTemplateProvider, InlineMappingTemplateProvider, MappingTemplateType, + S3MappingFunctionCodeProvider, } from '@aws-amplify/graphql-transformer-interfaces'; import { FileAsset } from './file-asset'; +import * as fs from 'fs-extra'; + +export class S3MappingFunctionCode implements S3MappingFunctionCodeProvider { + public readonly type = MappingTemplateType.S3_LOCATION; + private asset?: FileAsset; + private fileName: string; + private filePath: string; + + constructor(fileName: string, filePath: string) { + this.fileName = fileName; + this.filePath = filePath; + } + + bind(scope: cdk.Construct): FileAsset { + if (!this.asset) { + this.asset = new FileAsset(scope, `Code${this.fileName}`, { + fileContent: this.filePath, + fileName: this.fileName, + }); + } + return this.asset; + } +} export class S3MappingTemplate implements S3MappingTemplateProvider { private content: string; private name: string; private asset?: FileAsset; public readonly type = MappingTemplateType.S3_LOCATION; - static fromFile(): S3MappingTemplate { - throw new Error('Not implemented'); + static fromFile(name: string, path: string): S3MappingTemplate { + const fileContents = fs.readFileSync(path, { encoding: 'utf-8' }); + return new S3MappingTemplate(fileContents, name); } static fromInlineTemplate(code: string, templateName?: string): S3MappingTemplate { @@ -21,10 +46,7 @@ export class S3MappingTemplate implements S3MappingTemplateProvider { constructor(content: string, name?: string) { this.content = content; - const assetHash = crypto - .createHash('sha256') - .update(content) - .digest('hex'); + const assetHash = crypto.createHash('sha256').update(content).digest('hex'); this.name = name || `mapping-template-${assetHash}.vtl`; } @@ -38,7 +60,7 @@ export class S3MappingTemplate implements S3MappingTemplateProvider { } return this.asset.s3Url; } - substitueValues(values: Record): void { + substitueValues(values: Record): void { let name = this.name; Object.entries(values).forEach(([key, value]) => { const regex = new RegExp(`({${key}})`, 'g'); @@ -65,7 +87,7 @@ export class MappingTemplate { static s3MappingTemplateFromString( template: string, templateName: string, - type: 'pipeline' | 'resolver' = 'pipeline', + type: 'pipeline' | 'resolver' | 'function' = 'pipeline', ): S3MappingTemplate { const templatePrefix = type == 'pipeline' ? 'pipelineFunctions' : 'resolvers'; return new S3MappingTemplate(template, `${templatePrefix}/${templateName}`); diff --git a/packages/amplify-graphql-transformer-core/src/graphql-api.ts b/packages/amplify-graphql-transformer-core/src/graphql-api.ts index 98253682e03..ade3d41b20e 100644 --- a/packages/amplify-graphql-transformer-core/src/graphql-api.ts +++ b/packages/amplify-graphql-transformer-core/src/graphql-api.ts @@ -1,4 +1,5 @@ import { APIIAMResourceProvider, GraphQLAPIProvider, MappingTemplateProvider } from '@aws-amplify/graphql-transformer-interfaces'; +import { ElasticSearchDataSourceOptions } from '@aws-amplify/graphql-transformer-interfaces/src/graphql-api-provider'; import { ApiKeyConfig, AuthorizationConfig, @@ -22,13 +23,14 @@ import { UserPoolDefaultAction, } from '@aws-cdk/aws-appsync'; import { ITable } from '@aws-cdk/aws-dynamodb'; -import { Grant, IGrantable, ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; -import { IFunction } from '@aws-cdk/aws-lambda'; +import { Grant, IGrantable, IRole, ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; +import { CfnFunction, Code, Function, IFunction, ILayerVersion, Runtime } from '@aws-cdk/aws-lambda'; import { CfnResource, Construct, Duration, Stack, Token } from '@aws-cdk/core'; import { toCamelCase } from 'graphql-transformer-common'; import { AppSyncFunctionConfiguration } from './appsync-function'; +import { ElasticsearchDataSource } from './cdk-compat/elasticsearch-datasource'; import { TransformerSchema } from './cdk-compat/schema-asset'; -import { InlineTemplate } from './cdk-compat/template-asset'; +import { InlineTemplate, S3MappingFunctionCode } from './cdk-compat/template-asset'; export interface GraphqlApiProps { /** @@ -215,6 +217,21 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { } } + addElasticSearchDataSource( + name: string, + awsRegion: string, + endpoint: string, + options?: ElasticSearchDataSourceOptions, + stack?: Stack, + ): ElasticsearchDataSource { + if (this.dataSources.has(name)) { + throw new Error(`DataSource ${name} already exists in the API`); + } + const data = this.doAddElasticSearchDataSource(name, endpoint, awsRegion, options, stack); + this.dataSources.set(options?.name || name, data); + return data; + } + public addHttpDataSource(name: string, endpoint: string, options?: DataSourceOptions, stack?: Stack): HttpDataSource { if (this.dataSources.has(name)) { throw new Error(`DataSource ${name} already exists in the API`); @@ -271,6 +288,35 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { return fn; } + addLambdaFunction( + functionName: string, + functionKey: string, + handlerName: string, + filePath: string, + runtime: Runtime, + layers?: ILayerVersion[], + role?: IRole, + environment?: { [key: string]: string }, + stack?: Stack, + ): IFunction { + const dummycode = `if __name__ == "__main__":`; // assing dummy code so as to be overriden later + const fn = new Function(stack || this, functionName, { + code: Code.fromInline(dummycode), + handler: handlerName, + runtime, + role, + layers, + environment, + }); + fn.addLayers(); + const functionCode = new S3MappingFunctionCode(functionKey, filePath).bind(fn); + (fn.node.defaultChild as CfnFunction).code = { + s3Key: functionCode.s3ObjectKey, + s3Bucket: functionCode.s3BucketName, + }; + return fn; + } + /** * Adds an IAM policy statement associated with this GraphQLApi to an IAM * principal's policy. @@ -442,6 +488,31 @@ export class GraphQLApi extends GraphqlApiBase implements GraphQLAPIProvider { }); } + /** + * add a new elasticsearch data source to this API + * + * @param id The data source's id + * @param endpoint The elasticsearch endpoint + * @param region The elasticsearch datasource region + * @param options The optional configuration for this data source + * @param stack Stack to which the elasticsearch datasource needs to be created in + */ + protected doAddElasticSearchDataSource( + id: string, + endpoint: string, + region: string, + options?: ElasticSearchDataSourceOptions, + stack?: Stack, + ): ElasticsearchDataSource { + return new ElasticsearchDataSource(stack ?? this, id, { + api: this, + name: options?.name, + endpoint, + region, + serviceRole: options?.serviceRole, + }); + } + /** * add a new Lambda data source to this API * diff --git a/packages/amplify-graphql-transformer-core/src/index.ts b/packages/amplify-graphql-transformer-core/src/index.ts index 2627ae4e75d..e3488cb0be9 100644 --- a/packages/amplify-graphql-transformer-core/src/index.ts +++ b/packages/amplify-graphql-transformer-core/src/index.ts @@ -26,6 +26,7 @@ export { TransformerProjectConfig, } from './config/index'; export { collectDirectives, collectDirectivesByTypeNames, DirectiveWrapper } from './utils'; +export * from './errors'; export { TransformerModelBase, TransformerModelEnhancerBase, TransformerPluginBase } from './transformation/transformer-plugin-base'; /** * Returns the extra set of directives that are supported by AppSync service @@ -35,5 +36,3 @@ export const getAppSyncServiceExtraDirectives = (): string => { }; export { MappingTemplate } from './cdk-compat'; - -export { TransformerContractError } from './errors'; diff --git a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts index 9960b1ce847..0bd632467b9 100644 --- a/packages/amplify-graphql-transformer-core/src/transformation/transform.ts +++ b/packages/amplify-graphql-transformer-core/src/transformation/transform.ts @@ -306,17 +306,19 @@ export class GraphQLTransform { const fileAssets = stackManager.getMappingTemplates(); const pipelineFunctions: Record = {}; const resolvers: Record = {}; - + const functions: Record = {}; for (let [templateName, template] of fileAssets) { if (templateName.startsWith('pipelineFunctions/')) { pipelineFunctions[templateName.replace('pipelineFunctions/', '')] = template; } else if (templateName.startsWith('resolvers/')) { resolvers[templateName.replace('resolvers/', '')] = template; + } else if (templateName.startsWith('functions/')) { + functions[templateName.replace('functions/', '')] = template; } } const schema = fileAssets.get('schema.graphql') || ''; return { - functions: {}, + functions, pipelineFunctions, stackMapping: {}, resolvers, diff --git a/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts b/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts index 58e1d937f17..10a4766eb65 100644 --- a/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts +++ b/packages/amplify-graphql-transformer-core/src/transformer-context/output.ts @@ -204,6 +204,10 @@ export class TransformerOutput implements TransformerContextOutputProvider { return this.nodeMap[name]; } + public hasType(name: string): boolean { + return name in this.nodeMap; + } + /** * Add an object type definition node to the context. If the type already * exists an error will be thrown. diff --git a/packages/amplify-graphql-transformer-interfaces/CHANGELOG.md b/packages/amplify-graphql-transformer-interfaces/CHANGELOG.md index 0f751e39405..b5cebff576c 100644 --- a/packages/amplify-graphql-transformer-interfaces/CHANGELOG.md +++ b/packages/amplify-graphql-transformer-interfaces/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.6.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-transformer-interfaces@1.5.0...@aws-amplify/graphql-transformer-interfaces@1.6.0) (2021-05-18) + + +### Features + +* port [@searchable](https://github.com/searchable) to GraphQL Transformer v2 ([#7291](https://github.com/aws-amplify/amplify-cli/issues/7291)) ([37a2df2](https://github.com/aws-amplify/amplify-cli/commit/37a2df2365fe4bf0eddf285a159221e34f695fe2)) + + + + + # [1.5.0](https://github.com/aws-amplify/amplify-cli/compare/@aws-amplify/graphql-transformer-interfaces@1.3.1...@aws-amplify/graphql-transformer-interfaces@1.5.0) (2021-05-03) diff --git a/packages/amplify-graphql-transformer-interfaces/package.json b/packages/amplify-graphql-transformer-interfaces/package.json index b48ddf37735..04c0e539b4e 100644 --- a/packages/amplify-graphql-transformer-interfaces/package.json +++ b/packages/amplify-graphql-transformer-interfaces/package.json @@ -1,6 +1,6 @@ { "name": "@aws-amplify/graphql-transformer-interfaces", - "version": "1.5.0", + "version": "1.6.0", "description": "Amplify GraphQL transformer interface definitions", "repository": { "type": "git", diff --git a/packages/amplify-graphql-transformer-interfaces/src/graphql-api-provider.ts b/packages/amplify-graphql-transformer-interfaces/src/graphql-api-provider.ts index 0cf11f92f7b..801fe5d0de8 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/graphql-api-provider.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/graphql-api-provider.ts @@ -1,15 +1,8 @@ -import { - NoneDataSource, - HttpDataSource, - DynamoDbDataSource, - LambdaDataSource, - BaseDataSource, - CfnResolver, -} from '@aws-cdk/aws-appsync'; -import { IFunction } from '@aws-cdk/aws-lambda'; +import { NoneDataSource, HttpDataSource, DynamoDbDataSource, LambdaDataSource, BaseDataSource, CfnResolver } from '@aws-cdk/aws-appsync'; +import { IFunction, ILayerVersion, Runtime } from '@aws-cdk/aws-lambda'; import { ITable } from '@aws-cdk/aws-dynamodb'; -import { CfnResource, Construct, IConstruct, Stack } from '@aws-cdk/core'; -import { Grant, IGrantable } from '@aws-cdk/aws-iam'; +import { CfnResource, Construct, IAsset, IConstruct, Stack } from '@aws-cdk/core'; +import { Grant, IGrantable, IRole } from '@aws-cdk/aws-iam'; export interface AppSyncFunctionConfigurationProvider extends IConstruct { readonly arn: string; @@ -30,19 +23,29 @@ export interface DataSourceOptions { readonly description?: string; } -export enum TemplateType { +export interface ElasticSearchDataSourceOptions extends DataSourceOptions { + /** + * ServiceRole for the Amazon Elasticsearch + */ + readonly serviceRole: IRole; +} + +export enum TemplateType { INLINE = 'INLINE', - S3_LOCATION = 'S3_LOCATION' + S3_LOCATION = 'S3_LOCATION', } export interface InlineMappingTemplateProvider { - type: TemplateType.INLINE + type: TemplateType.INLINE; bind(scope: Construct): string; } export interface S3MappingTemplateProvider { - type: TemplateType.S3_LOCATION - bind( - scope: Construct, - ): string; + type: TemplateType.S3_LOCATION; + bind(scope: Construct): string; +} + +export interface S3MappingFunctionCodeProvider { + type: TemplateType.S3_LOCATION; + bind(scope: Construct): IAsset; } export type MappingTemplateProvider = InlineMappingTemplateProvider | S3MappingTemplateProvider; @@ -53,7 +56,13 @@ export interface GraphQLAPIProvider { addDynamoDbDataSource(name: string, table: ITable, options?: DataSourceOptions, stack?: Stack): DynamoDbDataSource; addNoneDataSource(name: string, options?: DataSourceOptions, stack?: Stack): NoneDataSource; addLambdaDataSource(name: string, lambdaFunction: IFunction, options?: DataSourceOptions, stack?: Stack): LambdaDataSource; - + addElasticSearchDataSource( + name: string, + endpoint: string, + region: string, + options?: ElasticSearchDataSourceOptions, + stack?: Stack, + ): BaseDataSource; addAppSyncFunction: ( name: string, requestMappingTemplate: MappingTemplateProvider, @@ -72,6 +81,18 @@ export interface GraphQLAPIProvider { stack?: Stack, ) => CfnResolver; + addLambdaFunction: ( + functionName: string, + functionKey: string, + handlerName: string, + filePath: string, + runtime: Runtime, + layers?: ILayerVersion[], + role?: IRole, + environment?: { [key: string]: string }, + stack?: Stack, + ) => IFunction; + getDataSource: (name: string) => BaseDataSource | void; hasDataSource: (name: string) => boolean; // getDefaultAuthorization(): Readonly; diff --git a/packages/amplify-graphql-transformer-interfaces/src/index.ts b/packages/amplify-graphql-transformer-interfaces/src/index.ts index c4fa2e6520f..0c3e79bd031 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/index.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/index.ts @@ -14,7 +14,7 @@ export { TransformerPrepareStepContextProvider, TransformerSchemaVisitStepContextProvider, TransformerValidationStepContextProvider, - TransformerResourceHelperProvider + TransformerResourceHelperProvider, } from './transformer-context'; export { TransformerPluginProvider, TransformerPluginType } from './transformer-plugin-provider'; export { @@ -32,6 +32,7 @@ export { DataSourceOptions, MappingTemplateProvider, S3MappingTemplateProvider, + S3MappingFunctionCodeProvider, InlineMappingTemplateProvider, APIIAMResourceProvider, TemplateType as MappingTemplateType, diff --git a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transformer-context-output-provider.ts b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transformer-context-output-provider.ts index 4d35ce2dae8..a2235f2da65 100644 --- a/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transformer-context-output-provider.ts +++ b/packages/amplify-graphql-transformer-interfaces/src/transformer-context/transformer-context-output-provider.ts @@ -58,6 +58,8 @@ export interface TransformerContextOutputProvider { getType(name: string): TypeSystemDefinitionNode | undefined; + hasType(name: string): boolean; + /** * Add an object type definition node to the context. If the type already * exists an error will be thrown. diff --git a/packages/amplify-headless-interface/CHANGELOG.md b/packages/amplify-headless-interface/CHANGELOG.md index 42618bcb16d..1afec53738e 100644 --- a/packages/amplify-headless-interface/CHANGELOG.md +++ b/packages/amplify-headless-interface/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.6.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-headless-interface@1.6.0...amplify-headless-interface@1.6.1) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-headless-interface + + + + + +# [1.6.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-headless-interface@1.5.3...amplify-headless-interface@1.6.0) (2021-05-14) + + +### Features + +* Support for Apple Sign In ([#7265](https://github.com/aws-amplify/amplify-cli/issues/7265)) ([9f5e659](https://github.com/aws-amplify/amplify-cli/commit/9f5e659d63362c7f47eaa147c68d40d5bcc36fcc)) + + + + + ## [1.5.3](https://github.com/aws-amplify/amplify-cli/compare/amplify-headless-interface@1.5.2...amplify-headless-interface@1.5.3) (2021-01-08) **Note:** Version bump only for package amplify-headless-interface diff --git a/packages/amplify-headless-interface/package.json b/packages/amplify-headless-interface/package.json index 8060f359b80..3edae68d215 100644 --- a/packages/amplify-headless-interface/package.json +++ b/packages/amplify-headless-interface/package.json @@ -1,6 +1,6 @@ { "name": "amplify-headless-interface", - "version": "1.5.3", + "version": "1.6.1", "description": "interfaces for amplify headless mode payloads", "main": "lib/index.js", "scripts": { diff --git a/packages/amplify-java-function-runtime-provider/CHANGELOG.md b/packages/amplify-java-function-runtime-provider/CHANGELOG.md index 3408a0f00aa..c956ec017d7 100644 --- a/packages/amplify-java-function-runtime-provider/CHANGELOG.md +++ b/packages/amplify-java-function-runtime-provider/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.8.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-java-function-runtime-provider@1.8.0...amplify-java-function-runtime-provider@1.8.1) (2021-05-18) + +**Note:** Version bump only for package amplify-java-function-runtime-provider + + + + + +# [1.8.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-java-function-runtime-provider@1.7.6...amplify-java-function-runtime-provider@1.8.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + + + + ## [1.7.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-java-function-runtime-provider@1.7.4...amplify-java-function-runtime-provider@1.7.6) (2021-05-03) diff --git a/packages/amplify-java-function-runtime-provider/package.json b/packages/amplify-java-function-runtime-provider/package.json index 023f3aca0e2..e8803c76c01 100644 --- a/packages/amplify-java-function-runtime-provider/package.json +++ b/packages/amplify-java-function-runtime-provider/package.json @@ -1,6 +1,6 @@ { "name": "amplify-java-function-runtime-provider", - "version": "1.7.6", + "version": "1.8.1", "description": "Provides functionality related to functions in JAVA on AWS", "repository": { "type": "git", @@ -21,12 +21,12 @@ "clean": "rimraf lib tsconfig.tsbuildinfo" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", "execa": "^4.1.0", "fs-extra": "^8.1.0", "glob": "^7.1.6", - "semver": "^7.1.3", + "semver": "^7.3.5", "which": "^2.0.2" }, "devDependencies": { diff --git a/packages/amplify-migration-tests/CHANGELOG.md b/packages/amplify-migration-tests/CHANGELOG.md index 47e2b173cd7..7c0f357a172 100644 --- a/packages/amplify-migration-tests/CHANGELOG.md +++ b/packages/amplify-migration-tests/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.21.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-migration-tests@2.21.7...amplify-migration-tests@2.21.8) (2021-05-18) + + + +## 4.51.1 (2021-05-18) + +**Note:** Version bump only for package amplify-migration-tests + + + + + +## [2.21.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-migration-tests@2.21.6...amplify-migration-tests@2.21.7) (2021-05-14) + +**Note:** Version bump only for package amplify-migration-tests + + + + + ## [2.21.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-migration-tests@2.21.4...amplify-migration-tests@2.21.6) (2021-05-03) diff --git a/packages/amplify-migration-tests/package.json b/packages/amplify-migration-tests/package.json index 213c137a548..31d2741ead6 100644 --- a/packages/amplify-migration-tests/package.json +++ b/packages/amplify-migration-tests/package.json @@ -1,6 +1,6 @@ { "name": "amplify-migration-tests", - "version": "2.21.6", + "version": "2.21.8", "description": "", "repository": { "type": "git", @@ -24,12 +24,12 @@ "setup-profile": "ts-node ./src/configure_tests.ts" }, "dependencies": { - "amplify-e2e-core": "1.18.2", + "amplify-e2e-core": "1.19.1", "aws-sdk": "^2.845.0", "dotenv": "^8.2.0", "esm": "^3.2.25", "fs-extra": "^8.1.0", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "rimraf": "^3.0.0", "uuid": "^8.2.0" }, diff --git a/packages/amplify-migration-tests/src/__tests__/update_tests/auth_migration_update.test.ts b/packages/amplify-migration-tests/src/__tests__/update_tests/auth_migration_update.test.ts index dcca0f0ae2c..73fd070b06d 100644 --- a/packages/amplify-migration-tests/src/__tests__/update_tests/auth_migration_update.test.ts +++ b/packages/amplify-migration-tests/src/__tests__/update_tests/auth_migration_update.test.ts @@ -1,5 +1,6 @@ import { addAuthWithCustomTrigger, + addAuthWithDefault, amplifyPushAuth, createNewProjectDir, deleteProject, @@ -9,6 +10,7 @@ import { getUserPool, getUserPoolClients, updateAuthWithoutCustomTrigger, + updateAuthWithoutTrigger, } from 'amplify-e2e-core'; import * as fs from 'fs-extra'; import { join } from 'path'; @@ -59,4 +61,14 @@ describe('amplify auth migration', () => { expect(updatedDirContents.includes('email-filter-denylist.js')).toBeTruthy(); expect(updatedFunction.Configuration.Environment.Variables.MODULES).toEqual('email-filter-denylist'); }); + + it('...should init a project and add auth with default, and then update with latest and push', async () => { + // init, add and push auth with installed cli + await initJSProjectWithProfile(projRoot, { name: 'authMigration' }); + await addAuthWithDefault(projRoot, {}); + await amplifyPushAuth(projRoot); + // update and push with codebase + await updateAuthWithoutTrigger(projRoot, { testingWithLatestCodebase: true }); + await amplifyPushAuth(projRoot, true); + }); }); diff --git a/packages/amplify-nodejs-function-template-provider/CHANGELOG.md b/packages/amplify-nodejs-function-template-provider/CHANGELOG.md index 910213632b9..e239595da78 100644 --- a/packages/amplify-nodejs-function-template-provider/CHANGELOG.md +++ b/packages/amplify-nodejs-function-template-provider/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.6.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-nodejs-function-template-provider@1.6.7...amplify-nodejs-function-template-provider@1.6.8) (2021-05-18) + +**Note:** Version bump only for package amplify-nodejs-function-template-provider + + + + + +## [1.6.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-nodejs-function-template-provider@1.6.6...amplify-nodejs-function-template-provider@1.6.7) (2021-05-14) + +**Note:** Version bump only for package amplify-nodejs-function-template-provider + + + + + ## [1.6.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-nodejs-function-template-provider@1.6.4...amplify-nodejs-function-template-provider@1.6.6) (2021-05-03) diff --git a/packages/amplify-nodejs-function-template-provider/package.json b/packages/amplify-nodejs-function-template-provider/package.json index 12fefd1ec12..9eae07ac88e 100644 --- a/packages/amplify-nodejs-function-template-provider/package.json +++ b/packages/amplify-nodejs-function-template-provider/package.json @@ -1,6 +1,6 @@ { "name": "amplify-nodejs-function-template-provider", - "version": "1.6.6", + "version": "1.6.8", "description": "Node JS templates supplied by the Amplify Team", "repository": { "type": "git", @@ -21,9 +21,9 @@ "clean": "rimraf lib tsconfig.tsbuildinfo" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "lodash": "^4.17.19" }, "devDependencies": { diff --git a/packages/amplify-provider-awscloudformation/CHANGELOG.md b/packages/amplify-provider-awscloudformation/CHANGELOG.md index 19719eed20c..10e502b39a5 100644 --- a/packages/amplify-provider-awscloudformation/CHANGELOG.md +++ b/packages/amplify-provider-awscloudformation/CHANGELOG.md @@ -3,6 +3,47 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [4.49.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-provider-awscloudformation@4.48.0...amplify-provider-awscloudformation@4.49.0) (2021-05-18) + + +### Features + +* port [@searchable](https://github.com/searchable) to GraphQL Transformer v2 ([#7291](https://github.com/aws-amplify/amplify-cli/issues/7291)) ([37a2df2](https://github.com/aws-amplify/amplify-cli/commit/37a2df2365fe4bf0eddf285a159221e34f695fe2)) + + + + + +# [4.48.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-provider-awscloudformation@4.47.0...amplify-provider-awscloudformation@4.48.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Bug Fixes + +* handle legacy string permissions ([#7305](https://github.com/aws-amplify/amplify-cli/issues/7305)) ([a6b6ad7](https://github.com/aws-amplify/amplify-cli/commit/a6b6ad74fa7118ca1aae4f61e2e604688c0354e3)) +* **amplify-provider-awscloudformation:** add logger to iterative deploys ([#7278](https://github.com/aws-amplify/amplify-cli/issues/7278)) ([4671717](https://github.com/aws-amplify/amplify-cli/commit/4671717ccd79031592bde12c550428b0aa11d750)) +* conditionally rebuild container apis on push ([#7175](https://github.com/aws-amplify/amplify-cli/issues/7175)) ([a27a033](https://github.com/aws-amplify/amplify-cli/commit/a27a033af0fe6a9db8becd15b713113c64e70eb3)) +* e2e failed tests for auth Triggers PR ([#7262](https://github.com/aws-amplify/amplify-cli/issues/7262)) ([fedb6c4](https://github.com/aws-amplify/amplify-cli/commit/fedb6c49cf0695e21f59929e7d0554b59290f2f1)) +* show error message when project initalization fail ([98682ac](https://github.com/aws-amplify/amplify-cli/commit/98682ac4c6fcce4b7ac4d8c69e646d3b8712d325)) + + +### Features + +* defer root stack creation to first `amplify push` ([#7174](https://github.com/aws-amplify/amplify-cli/issues/7174)) ([d28dd1c](https://github.com/aws-amplify/amplify-cli/commit/d28dd1caca86b19a858dab0e7aa907d1cc74c86a)) +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + +### Reverts + +* Revert "feat: defer root stack creation to first `amplify push` (#7174)" (#7306) ([78854eb](https://github.com/aws-amplify/amplify-cli/commit/78854ebd4a3d41d34d68736d6556045302101265)), closes [#7174](https://github.com/aws-amplify/amplify-cli/issues/7174) [#7306](https://github.com/aws-amplify/amplify-cli/issues/7306) + + + + + # [4.47.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-provider-awscloudformation@4.45.0...amplify-provider-awscloudformation@4.47.0) (2021-05-03) diff --git a/packages/amplify-provider-awscloudformation/package.json b/packages/amplify-provider-awscloudformation/package.json index d33cf0946c0..4a4b1fc67fe 100644 --- a/packages/amplify-provider-awscloudformation/package.json +++ b/packages/amplify-provider-awscloudformation/package.json @@ -1,6 +1,6 @@ { "name": "amplify-provider-awscloudformation", - "version": "4.47.0", + "version": "4.49.0", "description": "AWS CloudFormation Provider", "repository": { "type": "git", @@ -24,11 +24,12 @@ "watch": "tsc --watch" }, "dependencies": { - "@aws-amplify/graphql-function-transformer": "0.3.0", - "@aws-amplify/graphql-http-transformer": "0.3.0", - "@aws-amplify/graphql-model-transformer": "0.3.6", - "@aws-amplify/graphql-transformer-core": "0.5.0", - "@aws-amplify/graphql-transformer-interfaces": "1.5.0", + "@aws-amplify/graphql-function-transformer": "0.3.1", + "@aws-amplify/graphql-http-transformer": "0.3.1", + "@aws-amplify/graphql-model-transformer": "0.4.0", + "@aws-amplify/graphql-searchable-transformer": "0.2.0", + "@aws-amplify/graphql-transformer-core": "0.6.0", + "@aws-amplify/graphql-transformer-interfaces": "1.6.0", "@aws-cdk/assets": "~1.72.0", "@aws-cdk/aws-autoscaling": "~1.72.0", "@aws-cdk/aws-batch": "~1.72.0", @@ -67,10 +68,10 @@ "@aws-cdk/custom-resources": "~1.72.0", "@aws-cdk/region-info": "~1.72.0", "@octokit/rest": "^18.0.9", - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-cli-logger": "1.1.0", "amplify-codegen": "^2.23.1", - "amplify-util-import": "1.4.6", + "amplify-util-import": "1.4.8", "archiver": "^3.1.1", "aws-sdk": "^2.845.0", "bottleneck": "2.19.5", @@ -87,16 +88,16 @@ "fs-extra": "^8.1.0", "glob": "^7.1.6", "graphql": "^14.5.8", - "graphql-auth-transformer": "6.24.6", - "graphql-connection-transformer": "4.21.6", - "graphql-dynamodb-transformer": "6.22.6", - "graphql-elasticsearch-transformer": "4.11.6", - "graphql-function-transformer": "2.5.6", - "graphql-http-transformer": "4.17.6", - "graphql-key-transformer": "2.23.6", - "graphql-predictions-transformer": "2.5.6", - "graphql-transformer-core": "6.28.6", - "graphql-versioned-transformer": "4.17.6", + "graphql-auth-transformer": "6.24.8", + "graphql-connection-transformer": "4.21.8", + "graphql-dynamodb-transformer": "6.22.8", + "graphql-elasticsearch-transformer": "4.11.8", + "graphql-function-transformer": "2.5.8", + "graphql-http-transformer": "4.17.8", + "graphql-key-transformer": "2.23.8", + "graphql-predictions-transformer": "2.5.8", + "graphql-transformer-core": "6.28.8", + "graphql-versioned-transformer": "4.17.8", "ignore": "^5.1.8", "import-from": "^3.0.0", "import-global": "^0.1.0", diff --git a/packages/amplify-provider-awscloudformation/src/__tests__/initializer.test.ts b/packages/amplify-provider-awscloudformation/src/__tests__/initializer.test.ts index a22279b14d9..71b2dd2bbe1 100644 --- a/packages/amplify-provider-awscloudformation/src/__tests__/initializer.test.ts +++ b/packages/amplify-provider-awscloudformation/src/__tests__/initializer.test.ts @@ -34,10 +34,6 @@ describe('run', () => { amplify: { getTags: jest.fn(), }, - input: { - options: '--yes', - command: 'init', - }, }; CloudFormation_mock.mockImplementation( () => diff --git a/packages/amplify-provider-awscloudformation/src/delete-env.js b/packages/amplify-provider-awscloudformation/src/delete-env.js index ef5f268ad9f..d078b4bccd2 100644 --- a/packages/amplify-provider-awscloudformation/src/delete-env.js +++ b/packages/amplify-provider-awscloudformation/src/delete-env.js @@ -6,23 +6,19 @@ const { S3 } = require('./aws-utils/aws-s3'); const { deleteEnv } = require('./amplify-service-manager'); const { S3BackendZipFileName, ProviderName } = require('./constants'); const { downloadZip, extractZip } = require('./zip-util'); -const { stateManager } = require('amplify-cli-core'); async function run(context, envName, deleteS3) { const credentials = await loadConfigurationForEnv(context, envName); const cfn = await new Cloudformation(context, null, credentials); const s3 = await S3.getInstance(context, credentials); let removeBucket = false; - const deploymentBucketName = stateManager.getTeamProviderInfo()?.[envName]?.[ProviderName]?.DeploymentBucketName; + let deploymentBucketName; let storageCategoryBucketName; - // if this env has not been initialized in the cloud, early return - if (!deploymentBucketName) { - return; - } - if (deleteS3) { - if (!!deploymentBucketName && (await s3.ifBucketExists(deploymentBucketName))) { + const projectDetails = context.amplify.getProjectDetails(); + deploymentBucketName = projectDetails.teamProviderInfo[envName][ProviderName].DeploymentBucketName; + if (await s3.ifBucketExists(deploymentBucketName)) { const amplifyDir = context.amplify.pathManager.getAmplifyDirPath(); const tempDir = path.join(amplifyDir, envName, '.temp'); storageCategoryBucketName = await getStorageCategoryBucketNameFromCloud(context, envName, s3, tempDir); diff --git a/packages/amplify-provider-awscloudformation/src/display-helpful-urls.js b/packages/amplify-provider-awscloudformation/src/display-helpful-urls.js index 10b00d209af..475048d26ec 100644 --- a/packages/amplify-provider-awscloudformation/src/display-helpful-urls.js +++ b/packages/amplify-provider-awscloudformation/src/display-helpful-urls.js @@ -1,4 +1,9 @@ +// @ts-check const chalk = require('chalk'); +const { BannerMessage } = require('amplify-cli-core'); +const { fileLogger } = require('./utils/aws-logger'); + +const logger = fileLogger('display-helpful-urls'); async function displayHelpfulURLs(context, resourcesToBeCreated) { context.print.info(''); @@ -9,6 +14,7 @@ async function displayHelpfulURLs(context, resourcesToBeCreated) { showContainerHostingInfo(context, resourcesToBeCreated); showHostedUIURLs(context, resourcesToBeCreated); await showRekognitionURLS(context, resourcesToBeCreated); + await showCognitoSandBoxMessage(context, resourcesToBeCreated); context.print.info(''); } @@ -91,15 +97,17 @@ function showRestAPIURL(context, resourcesToBeCreated) { } function showContainerHostingInfo(context, resourcesToBeCreated) { - const resource = resourcesToBeCreated.find(resource => resource.category === 'hosting' && resource.service === 'ElasticContainer' && !resource.hostedZoneId); + const resource = resourcesToBeCreated.find( + resource => resource.category === 'hosting' && resource.service === 'ElasticContainer' && !resource.hostedZoneId, + ); if (resource && resource.output) { const { output: { LoadBalancerCnameDomainName, LoadBalancerAliasDomainName, CloudfrontDistributionAliasDomainName, - CloudfrontDistributionCnameDomainName - } + CloudfrontDistributionCnameDomainName, + }, } = resource; context.print.info(`Make sure to add the following CNAMEs to your domain’s DNS records:\n`); @@ -162,6 +170,34 @@ function showHostedUIURLs(context, resourcesToBeCreated) { } } +async function showCognitoSandBoxMessage(context, resources) { + const smsSandBoxMessage = await BannerMessage.getMessage('COGNITO_SMS_SANDBOX_UPDATE_WARNING'); + if (!smsSandBoxMessage) { + return; + } + + const cognitoResource = resources.filter(resource => resource.service === 'Cognito'); + + if (cognitoResource.length > 0) { + const log = logger('showCognitoSandBoxMessage', [cognitoResource[0].resourceName]); + try { + log(); + const smsWorkflowEnabled = await await context.amplify.invokePluginMethod(context, 'auth', 'cognito', 'isSMSWorkflowEnabled', [ + context, + cognitoResource[0].resourceName, + ]); + if (smsWorkflowEnabled) { + context.print.warning(smsSandBoxMessage); + return; + } + } catch (e) { + if (e.name !== 'MethodNotFound') { + log(e); + } + } + } +} + async function showRekognitionURLS(context, resourcesToBeCreated) { const resource = resourcesToBeCreated.find(resource => { if (resource.identifyType && resource.identifyType === 'identifyEntities') { diff --git a/packages/amplify-provider-awscloudformation/src/ensure-root-stack.ts b/packages/amplify-provider-awscloudformation/src/ensure-root-stack.ts deleted file mode 100644 index 84d03d6c897..00000000000 --- a/packages/amplify-provider-awscloudformation/src/ensure-root-stack.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { $TSContext, stateManager } from 'amplify-cli-core'; -import constants from './constants'; -import { run as initializeRootStack } from './initializer'; - -/** - * Checks if the root stack exists. - * If not it is created and the deployment bucket is populated with current cloud backend and other meta files - */ -export const ensureRootStack = async (context: $TSContext): Promise<$TSContext> => { - if (rootStackExists()) { - return context; - } - await initializeRootStack(context); - await context.exeInfo.deferredInitCallback(context); - return context; -}; - -export const rootStackExists = () => { - const meta = stateManager.getMeta(); - return !!meta?.providers?.[constants.ProviderName]?.DeploymentBucketName; -}; diff --git a/packages/amplify-provider-awscloudformation/src/graphql-transformer/transform-graphql-schema.ts b/packages/amplify-provider-awscloudformation/src/graphql-transformer/transform-graphql-schema.ts index 65e06ce4b3b..e9c01823397 100644 --- a/packages/amplify-provider-awscloudformation/src/graphql-transformer/transform-graphql-schema.ts +++ b/packages/amplify-provider-awscloudformation/src/graphql-transformer/transform-graphql-schema.ts @@ -13,6 +13,8 @@ import { import { ModelTransformer } from '@aws-amplify/graphql-model-transformer'; import { FunctionTransformer } from '@aws-amplify/graphql-function-transformer'; import { HttpTransformer } from '@aws-amplify/graphql-http-transformer'; +import { SearchableModelTransformer } from '@aws-amplify/graphql-searchable-transformer'; + import { ProviderName as providerName } from '../constants'; import { hashDirectory } from '../upload-appsync-files'; import { writeDeploymentToDisk } from './utils'; @@ -44,7 +46,7 @@ function warnOnAuth(context, map) { } function getTransformerFactory(context, resourceDir) { - return async () => { + return async (options?: TransformerFactoryArgs) => { const transformerList: TransformerPluginProvider[] = [ new ModelTransformer(), new FunctionTransformer(), @@ -52,9 +54,9 @@ function getTransformerFactory(context, resourceDir) { // TODO: initialize transformer plugins ]; - // if (addSearchableTransformer) { - // transformerList.push(new SearchableModelTransformer()); - // } + if (options?.addSearchableTransformer) { + transformerList.push(new SearchableModelTransformer()); + } const customTransformersConfig = await readTransformerConfiguration(resourceDir); const customTransformers = (customTransformersConfig && customTransformersConfig.transformers @@ -271,7 +273,7 @@ export async function transformGraphQLSchema(context, options) { buildParameters, projectDirectory: resourceDir, transformersFactory: transformerListFactory, - transformersFactoryArgs: [searchableTransformerFlag, storageConfig], + transformersFactoryArgs: { addSearchableTransformer: searchableTransformerFlag, storageConfig }, rootStackFileName: 'cloudformation-template.json', currentCloudBackendDirectory: previouslyDeployedBackendDir, minify: options.minify, @@ -314,7 +316,7 @@ async function getPreviousDeploymentRootKey(previouslyDeployedBackendDir) { } export async function getDirectiveDefinitions(context, resourceDir) { - const transformList = await getTransformerFactory(context, resourceDir)(); + const transformList = await getTransformerFactory(context, resourceDir)({ addSearchableTransformer: true }); const appSynDirectives = getAppSyncServiceExtraDirectives(); const transformDirectives = transformList .map(transformPluginInst => [transformPluginInst.directive, ...transformPluginInst.typeDefinitions].map(node => print(node)).join('\n')) diff --git a/packages/amplify-provider-awscloudformation/src/initialize-env.ts b/packages/amplify-provider-awscloudformation/src/initialize-env.ts index b8d5bb17420..6825d6de3f9 100644 --- a/packages/amplify-provider-awscloudformation/src/initialize-env.ts +++ b/packages/amplify-provider-awscloudformation/src/initialize-env.ts @@ -8,33 +8,25 @@ const { downloadZip, extractZip } = require('./zip-util'); const { S3BackendZipFileName } = require('./constants'); const { fileLogger } = require('./utils/aws-logger'); const logger = fileLogger('initialize-env'); -import { JSONUtilities, PathConstants, stateManager, $TSMeta, $TSContext, pathManager } from 'amplify-cli-core'; -import { ProviderName as providerName } from './constants'; -import { rootStackExists } from './ensure-root-stack'; +import { JSONUtilities, PathConstants, stateManager, $TSMeta, $TSContext } from 'amplify-cli-core'; export async function run(context: $TSContext, providerMetadata: $TSMeta) { if (context.exeInfo && context.exeInfo.isNewEnv) { return context; } - // empty #current-cloud-backend dir and reset default meta file - resetCurrentCloudBackend(); - - // if this environment is not pushed yet, early return - if (!rootStackExists()) { - return context; - } - - const amplifyDir = pathManager.getAmplifyDirPath(); + const amplifyDir = context.amplify.pathManager.getAmplifyDirPath(); const tempDir = path.join(amplifyDir, '.temp'); - const currentCloudBackendDir = pathManager.getCurrentCloudBackendDirPath(); - const backendDir = pathManager.getBackendDirPath(); + const currentCloudBackendDir = context.amplify.pathManager.getCurrentCloudBackendDirPath(); + const backendDir = context.amplify.pathManager.getBackendDirPath(); const s3 = await S3.getInstance(context); const cfnItem = await new Cloudformation(context); const file = await downloadZip(s3, tempDir, S3BackendZipFileName); const unzippeddir = await extractZip(tempDir, file); + fs.removeSync(currentCloudBackendDir); + // Move out cli.*json if exists in the temp directory into the amplify directory before copying backand and // current cloud backend directories. const cliJSONFiles = glob.sync(PathConstants.CLIJSONFileNameGlob, { @@ -116,16 +108,4 @@ export async function run(context: $TSContext, providerMetadata: $TSMeta) { if (hasMigratedResources) { stateManager.setCurrentMeta(undefined, amplifyMeta); } - return context; } - -const resetCurrentCloudBackend = () => { - const currentCloudBackendDir = pathManager.getCurrentCloudBackendDirPath(); - fs.removeSync(currentCloudBackendDir); - fs.ensureDirSync(currentCloudBackendDir); - stateManager.setCurrentMeta(undefined, { - providers: { - [providerName]: {}, - }, - }); -}; diff --git a/packages/amplify-provider-awscloudformation/src/initializer.ts b/packages/amplify-provider-awscloudformation/src/initializer.js similarity index 61% rename from packages/amplify-provider-awscloudformation/src/initializer.ts rename to packages/amplify-provider-awscloudformation/src/initializer.js index c1147d07b30..e4b99ce64a3 100644 --- a/packages/amplify-provider-awscloudformation/src/initializer.ts +++ b/packages/amplify-provider-awscloudformation/src/initializer.js @@ -1,9 +1,6 @@ -import { $TSContext, $TSAny, pathManager, PathConstants, stateManager, JSONUtilities } from 'amplify-cli-core'; -import _ from 'lodash'; -import * as configurationManager from './configuration-manager'; - const moment = require('moment'); const path = require('path'); +const { pathManager, PathConstants, stateManager, JSONUtilities } = require('amplify-cli-core'); const glob = require('glob'); const archiver = require('./utils/archiver'); const fs = require('fs-extra'); @@ -12,6 +9,7 @@ const sequential = require('promise-sequential'); const Cloudformation = require('./aws-utils/aws-cfn'); const { S3 } = require('./aws-utils/aws-s3'); const constants = require('./constants'); +const configurationManager = require('./configuration-manager'); const amplifyServiceManager = require('./amplify-service-manager'); const amplifyServiceMigrate = require('./amplify-service-migrate'); const { fileLogger } = require('./utils/aws-logger'); @@ -19,10 +17,79 @@ const { prePushCfnTemplateModifier } = require('./pre-push-cfn-processor/pre-pus const logger = fileLogger('attach-backend'); const { configurePermissionBoundaryForInit } = require('./permission-boundary/permission-boundary'); -export async function run(context) { +async function run(context) { await configurationManager.init(context); - if (doInitializeInCloud(context)) { - await initializeRootStack(context); + if (!context.exeInfo || context.exeInfo.isNewEnv) { + context.exeInfo = context.exeInfo || {}; + const { projectName } = context.exeInfo.projectConfig; + const initTemplateFilePath = path.join(__dirname, '..', 'resources', 'rootStackTemplate.json'); + const timeStamp = `${moment().format('Hmmss')}`; + const { envName = '' } = context.exeInfo.localEnvInfo; + let stackName = normalizeStackName(`amplify-${projectName}-${envName}-${timeStamp}`); + const awsConfig = await configurationManager.getAwsConfig(context); + + await configurePermissionBoundaryForInit(context); + + const amplifyServiceParams = { + context, + awsConfig, + projectName, + envName, + stackName, + }; + const { amplifyAppId, verifiedStackName, deploymentBucketName } = await amplifyServiceManager.init(amplifyServiceParams); + + stackName = verifiedStackName; + const Tags = context.amplify.getTags(context); + + const authRoleName = `${stackName}-authRole`; + const unauthRoleName = `${stackName}-unauthRole`; + + const rootStack = JSONUtilities.readJson(initTemplateFilePath); + await prePushCfnTemplateModifier(rootStack); + // Track Amplify Console generated stacks + if (!!process.env.CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_DELETION) { + rootStack.Description = 'Root Stack for AWS Amplify Console'; + } + + const params = { + StackName: stackName, + Capabilities: ['CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'], + TemplateBody: JSON.stringify(rootStack), + Parameters: [ + { + ParameterKey: 'DeploymentBucketName', + ParameterValue: deploymentBucketName, + }, + { + ParameterKey: 'AuthRoleName', + ParameterValue: authRoleName, + }, + { + ParameterKey: 'UnauthRoleName', + ParameterValue: unauthRoleName, + }, + ], + Tags, + }; + + const spinner = ora(); + spinner.start('Initializing project in the cloud...'); + + try { + const cfnItem = await new Cloudformation(context, 'init', awsConfig); + const stackDescriptionData = await cfnItem.createResourceStack(params); + + processStackCreationData(context, amplifyAppId, stackDescriptionData); + cloneCLIJSONForNewEnvironment(context); + + spinner.succeed('Successfully created initial AWS cloud resources for deployments.'); + + return context; + } catch (e) { + spinner.fail('Root stack creation failed'); + throw e; + } } else if ( // This part of the code is invoked by the `amplify init --appId xxx` command // on projects that are already fully setup by `amplify init` with the Amplify CLI version prior to 4.0.0. @@ -36,10 +103,7 @@ export async function run(context) { context.exeInfo.inputParams.amplify.appId ) { await amplifyServiceMigrate.run(context); - } else { - setCloudFormationOutputInContext(context, {}); } - cloneCLIJSONForNewEnvironment(context); } function processStackCreationData(context, amplifyAppId, stackDescriptiondata) { @@ -52,7 +116,18 @@ function processStackCreationData(context, amplifyAppId, stackDescriptiondata) { if (amplifyAppId) { metadata[constants.AmplifyAppIdLabel] = amplifyAppId; } - setCloudFormationOutputInContext(context, metadata); + + context.exeInfo.amplifyMeta = {}; + if (!context.exeInfo.amplifyMeta.providers) { + context.exeInfo.amplifyMeta.providers = {}; + } + context.exeInfo.amplifyMeta.providers[constants.ProviderName] = metadata; + + if (context.exeInfo.isNewEnv) { + const { envName } = context.exeInfo.localEnvInfo; + context.exeInfo.teamProviderInfo[envName] = {}; + context.exeInfo.teamProviderInfo[envName][constants.ProviderName] = metadata; + } } else { throw new Error('No stack data present'); } @@ -78,81 +153,9 @@ function cloneCLIJSONForNewEnvironment(context) { } } -async function initializeRootStack(context: $TSContext) { - context.exeInfo = context.exeInfo || {}; - const { projectName } = context.exeInfo.projectConfig; - const initTemplateFilePath = path.join(__dirname, '..', 'resources', 'rootStackTemplate.json'); - const timeStamp = `${moment().format('Hmmss')}`; - const { envName = '' } = context.exeInfo.localEnvInfo; - let stackName = normalizeStackName(`amplify-${projectName}-${envName}-${timeStamp}`); - const awsConfig = await configurationManager.getAwsConfig(context); - - await configurePermissionBoundaryForInit(context); - - const amplifyServiceParams = { - context, - awsConfig, - projectName, - envName, - stackName, - }; - const { amplifyAppId, verifiedStackName, deploymentBucketName } = await amplifyServiceManager.init(amplifyServiceParams); - - stackName = verifiedStackName; - const Tags = context.amplify.getTags(context); - - const authRoleName = `${stackName}-authRole`; - const unauthRoleName = `${stackName}-unauthRole`; - - const rootStack = JSONUtilities.readJson<$TSAny>(initTemplateFilePath); - await prePushCfnTemplateModifier(rootStack); - // Track Amplify Console generated stacks - if (!!process.env.CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_DELETION) { - rootStack.Description = 'Root Stack for AWS Amplify Console'; - } - - const params = { - StackName: stackName, - Capabilities: ['CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'], - TemplateBody: JSON.stringify(rootStack), - Parameters: [ - { - ParameterKey: 'DeploymentBucketName', - ParameterValue: deploymentBucketName, - }, - { - ParameterKey: 'AuthRoleName', - ParameterValue: authRoleName, - }, - { - ParameterKey: 'UnauthRoleName', - ParameterValue: unauthRoleName, - }, - ], - Tags, - }; - - const spinner = ora(); - spinner.start('Initializing project in the cloud...'); - - try { - const cfnItem = await new Cloudformation(context, 'init', awsConfig); - const stackDescriptionData = await cfnItem.createResourceStack(params); - - processStackCreationData(context, amplifyAppId, stackDescriptionData); - - spinner.succeed('Successfully created initial AWS cloud resources for deployments.'); - - return context; - } catch (e) { - spinner.fail('Root stack creation failed'); - throw e; - } -} - -export async function onInitSuccessful(context: $TSContext) { +async function onInitSuccessful(context) { configurationManager.onInitSuccessful(context); - if (doInitializeInCloud(context)) { + if (context.exeInfo.isNewEnv) { context = await storeCurrentCloudBackend(context); await storeArtifactsForAmplifyService(context); } @@ -223,15 +226,6 @@ function storeArtifactsForAmplifyService(context) { }); } -function setCloudFormationOutputInContext(context: $TSContext, cfnOutput: object) { - _.set(context, ['exeInfo', 'amplifyMeta', 'providers', constants.ProviderName], cfnOutput); - - const { envName } = context.exeInfo.localEnvInfo; - if (envName) { - _.set(context, ['exeInfo', 'teamProviderInfo', envName, constants.ProviderName], cfnOutput); - } -} - async function uploadFile(s3, filePath, key) { if (fs.existsSync(filePath)) { const s3Params = { @@ -257,10 +251,7 @@ function normalizeStackName(stackName) { return result; } -const doInitializeInCloud = (context: $TSContext): boolean => { - const hasCommandLineArgs = !_.isEmpty(context?.input?.options); - const isHeadlessInit = context?.input?.command === 'init' && hasCommandLineArgs; - const isHeadlessEnvAdd = context?.input?.command === 'env' && context?.input?.subCommands?.[0] === 'add' && hasCommandLineArgs; - const isPush = context?.input?.command === 'push'; - return !context.exeInfo || (context.exeInfo.isNewEnv && isHeadlessInit) || (context.exeInfo.isNewEnv && isHeadlessEnvAdd) || isPush; +module.exports = { + run, + onInitSuccessful, }; diff --git a/packages/amplify-provider-awscloudformation/src/push-resources.ts b/packages/amplify-provider-awscloudformation/src/push-resources.ts index f939775af87..e6cd5eab0f4 100644 --- a/packages/amplify-provider-awscloudformation/src/push-resources.ts +++ b/packages/amplify-provider-awscloudformation/src/push-resources.ts @@ -43,7 +43,6 @@ import { APIGW_AUTH_STACK_LOGICAL_ID, loadApiWithPrivacyParams } from './utils/c import { createEnvLevelConstructs } from './utils/env-level-constructs'; import { NETWORK_STACK_LOGICAL_ID } from './network/stack'; import { preProcessCFNTemplate } from './pre-push-cfn-processor/cfn-pre-processor'; -import { ensureRootStack } from './ensure-root-stack'; import { AUTH_TRIGGER_STACK, AUTH_TRIGGER_TEMPLATE } from './utils/upload-auth-trigger-template'; import { ensureValidFunctionModelDependencies } from './utils/remove-dependent-function'; @@ -69,7 +68,6 @@ const deploymentInProgressErrorMessage = (context: $TSContext) => { }; export async function run(context: $TSContext, resourceDefinition: $TSObject) { - context = await ensureRootStack(context); const deploymentStateManager = await DeploymentStateManager.createDeploymentStateManager(context); let iterativeDeploymentWasInvoked = false; diff --git a/packages/amplify-provider-awscloudformation/src/utils/consolidate-apigw-policies.ts b/packages/amplify-provider-awscloudformation/src/utils/consolidate-apigw-policies.ts index 297a28c0c7a..d0ba16ff46f 100644 --- a/packages/amplify-provider-awscloudformation/src/utils/consolidate-apigw-policies.ts +++ b/packages/amplify-provider-awscloudformation/src/utils/consolidate-apigw-policies.ts @@ -1,5 +1,6 @@ +import * as fs from 'fs'; import * as path from 'path'; -import { $TSAny, $TSContext, $TSObject, JSONUtilities } from 'amplify-cli-core'; +import { $TSAny, $TSContext, $TSObject, JSONUtilities, pathManager } from 'amplify-cli-core'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import { prepareApp } from '@aws-cdk/core/lib/private/prepare-app'; @@ -85,7 +86,7 @@ class ApiGatewayAuthStack extends cdk.Stack { state.path = path; if (apiGateway.params.privacy.auth) { - state.methods = path?.privacy?.auth ?? []; + state.methods = Array.isArray(path?.privacy?.auth) ? path.privacy.auth : []; state.roleCount = authRoleCount; state.roleName = authRoleName; state.policyDocSize = authPolicyDocSize; @@ -96,7 +97,7 @@ class ApiGatewayAuthStack extends cdk.Stack { } if (apiGateway.params.privacy.unauth) { - state.methods = path?.privacy?.unauth ?? []; + state.methods = Array.isArray(path?.privacy?.unauth) ? path.privacy.unauth : []; state.roleCount = unauthRoleCount; state.roleName = unauthRoleName; state.policyDocSize = unauthPolicyDocSize; @@ -177,6 +178,11 @@ export function consolidateApiGatewayPolicies(context: $TSContext, stackName: st const { amplifyMeta } = context.amplify.getProjectDetails(); const apis = amplifyMeta?.api ?? {}; + try { + const cfnPath = path.join(pathManager.getBackendDirPath(), 'api', `${APIGW_AUTH_STACK_LOGICAL_ID}.json`); + fs.unlinkSync(cfnPath); + } catch {} + Object.keys(apis).forEach(resourceName => { const resource = apis[resourceName]; const apiParams = loadApiWithPrivacyParams(context, resourceName, resource); @@ -191,13 +197,13 @@ export function consolidateApiGatewayPolicies(context: $TSContext, stackName: st }); if (apiGateways.length === 0) { - return {}; + return { APIGatewayAuthURL: undefined }; } - return createApiGatewayAuthResources(context, stackName, apiGateways); + return { APIGatewayAuthURL: createApiGatewayAuthResources(context, stackName, apiGateways) }; } -function createApiGatewayAuthResources(context: $TSContext, stackName: string, apiGateways: $TSAny): $TSObject { +function createApiGatewayAuthResources(context: $TSContext, stackName: string, apiGateways: $TSAny): string | undefined { const stack = new ApiGatewayAuthStack(undefined, 'Amplify', { description: 'API Gateway policy stack created using Amplify CLI', stackName, @@ -206,13 +212,15 @@ function createApiGatewayAuthResources(context: $TSContext, stackName: string, a const cfn = stack.toCloudFormation(); const { amplify } = context; const { DeploymentBucketName } = amplify.getProjectMeta()?.providers?.[ProviderName] ?? {}; - const cfnPath = path.join((amplify.pathManager as any).getBackendDirPath(), 'api', `${APIGW_AUTH_STACK_LOGICAL_ID}.json`); + const cfnPath = path.join(pathManager.getBackendDirPath(), 'api', `${APIGW_AUTH_STACK_LOGICAL_ID}.json`); + + if (!cfn.Resources || Object.keys(cfn.Resources).length === 0) { + return; + } JSONUtilities.writeJson(cfnPath, cfn); - return { - APIGatewayAuthURL: `https://s3.amazonaws.com/${DeploymentBucketName}/amplify-cfn-templates/${S3_UPLOAD_PATH}`, - }; + return `https://s3.amazonaws.com/${DeploymentBucketName}/amplify-cfn-templates/${S3_UPLOAD_PATH}`; } export function loadApiWithPrivacyParams(context: $TSContext, name: string, resource: any): object | undefined { @@ -280,6 +288,16 @@ function updateExistingApiCfn(context: $TSContext, api: $TSObject): void { path.policyResourceName = String(path.name).replace(/{[a-zA-Z0-9\-]+}/g, '*'); modified = true; } + + if (typeof path?.privacy?.auth === 'string') { + path.privacy.auth = convertPermissionStringToCrud(path.privacy.auth); + modified = true; + } + + if (typeof path?.privacy?.unauth === 'string') { + path.privacy.unauth = convertPermissionStringToCrud(path.privacy.unauth); + modified = true; + } }); } @@ -289,3 +307,13 @@ function updateExistingApiCfn(context: $TSContext, api: $TSObject): void { JSONUtilities.writeJson(apiParamsFile, api.params); } } + +function convertPermissionStringToCrud(permissions: string): string[] { + if (permissions === 'r') { + return ['/GET']; + } else if (permissions === 'rw') { + return ['/POST', '/GET', '/PUT', '/PATCH', '/DELETE']; + } + + return []; +} diff --git a/packages/amplify-python-function-runtime-provider/CHANGELOG.md b/packages/amplify-python-function-runtime-provider/CHANGELOG.md index c899696cd14..2590df73da1 100644 --- a/packages/amplify-python-function-runtime-provider/CHANGELOG.md +++ b/packages/amplify-python-function-runtime-provider/CHANGELOG.md @@ -3,6 +3,34 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.8.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-python-function-runtime-provider@1.8.0...amplify-python-function-runtime-provider@1.8.1) (2021-05-18) + +**Note:** Version bump only for package amplify-python-function-runtime-provider + + + + + +# [1.8.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-python-function-runtime-provider@1.7.6...amplify-python-function-runtime-provider@1.8.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Bug Fixes + +* get pipenv py version from Pipfile ([#7254](https://github.com/aws-amplify/amplify-cli/issues/7254)) ([866f261](https://github.com/aws-amplify/amplify-cli/commit/866f2614a2eb2476961526566f78081e4e58f41f)) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + + + + ## [1.7.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-python-function-runtime-provider@1.7.4...amplify-python-function-runtime-provider@1.7.6) (2021-05-03) diff --git a/packages/amplify-python-function-runtime-provider/package.json b/packages/amplify-python-function-runtime-provider/package.json index d9ff66f6150..4777d904a06 100644 --- a/packages/amplify-python-function-runtime-provider/package.json +++ b/packages/amplify-python-function-runtime-provider/package.json @@ -1,6 +1,6 @@ { "name": "amplify-python-function-runtime-provider", - "version": "1.7.6", + "version": "1.8.1", "description": "Provides functionality related to functions in Python on AWS", "repository": { "type": "git", @@ -21,13 +21,13 @@ "clean": "rimraf lib tsconfig.tsbuildinfo" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "amplify-function-plugin-interface": "1.7.2", "archiver": "^3.1.1", "execa": "^4.1.0", "glob": "^7.1.6", "ini": "^1.3.5", - "semver": "^7.1.3", + "semver": "^7.3.5", "which": "^2.0.2" }, "devDependencies": { diff --git a/packages/amplify-util-headless-input/CHANGELOG.md b/packages/amplify-util-headless-input/CHANGELOG.md index c7cbf5714c0..560c2580635 100644 --- a/packages/amplify-util-headless-input/CHANGELOG.md +++ b/packages/amplify-util-headless-input/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.4.5](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-headless-input@1.4.4...amplify-util-headless-input@1.4.5) (2021-05-18) + +**Note:** Version bump only for package amplify-util-headless-input + + + + + +## [1.4.4](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-headless-input@1.4.3...amplify-util-headless-input@1.4.4) (2021-05-14) + +**Note:** Version bump only for package amplify-util-headless-input + + + + + ## [1.4.3](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-headless-input@1.4.2...amplify-util-headless-input@1.4.3) (2021-01-08) **Note:** Version bump only for package amplify-util-headless-input diff --git a/packages/amplify-util-headless-input/package.json b/packages/amplify-util-headless-input/package.json index 6f456778dac..8b5bd57bc1c 100644 --- a/packages/amplify-util-headless-input/package.json +++ b/packages/amplify-util-headless-input/package.json @@ -1,6 +1,6 @@ { "name": "amplify-util-headless-input", - "version": "1.4.3", + "version": "1.4.5", "description": "Logic for validating objects against JSON-schema specs and performing version upgrades when necessary / possible", "main": "lib/index.js", "scripts": { @@ -16,7 +16,7 @@ "license": "Apache-2.0", "dependencies": { "ajv": "^6.12.2", - "amplify-headless-interface": "1.5.3" + "amplify-headless-interface": "1.6.1" }, "devDependencies": { "@types/json-schema": "^7.0.5" diff --git a/packages/amplify-util-import/CHANGELOG.md b/packages/amplify-util-import/CHANGELOG.md index b01ae9a9b57..8801fdb6180 100644 --- a/packages/amplify-util-import/CHANGELOG.md +++ b/packages/amplify-util-import/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.4.8](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-import@1.4.7...amplify-util-import@1.4.8) (2021-05-18) + +**Note:** Version bump only for package amplify-util-import + + + + + +## [1.4.7](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-import@1.4.6...amplify-util-import@1.4.7) (2021-05-14) + +**Note:** Version bump only for package amplify-util-import + + + + + ## [1.4.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-import@1.4.4...amplify-util-import@1.4.6) (2021-05-03) diff --git a/packages/amplify-util-import/package.json b/packages/amplify-util-import/package.json index b7c3fd0ff43..8b8de79f0a8 100644 --- a/packages/amplify-util-import/package.json +++ b/packages/amplify-util-import/package.json @@ -1,6 +1,6 @@ { "name": "amplify-util-import", - "version": "1.4.6", + "version": "1.4.8", "description": "Resource import support package", "main": "lib/index.js", "scripts": { @@ -16,7 +16,7 @@ "author": "Amazon Web Services", "license": "Apache-2.0", "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "aws-sdk": "^2.845.0" }, "devDependencies": { diff --git a/packages/amplify-util-mock/CHANGELOG.md b/packages/amplify-util-mock/CHANGELOG.md index 01d8a94b9de..fc5866a7044 100644 --- a/packages/amplify-util-mock/CHANGELOG.md +++ b/packages/amplify-util-mock/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.31.1](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-mock@3.31.0...amplify-util-mock@3.31.1) (2021-05-18) + +**Note:** Version bump only for package amplify-util-mock + + + + + +# [3.31.0](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-mock@3.30.6...amplify-util-mock@3.31.0) (2021-05-14) + + + +# 4.51.0 (2021-05-13) + + +### Features + +* prep work for SMS Sandbox support ([#7302](https://github.com/aws-amplify/amplify-cli/issues/7302)) ([d1f85d2](https://github.com/aws-amplify/amplify-cli/commit/d1f85d2e0a9c367b71defefe6d9e00737f681ca4)) + + + + + ## [3.30.6](https://github.com/aws-amplify/amplify-cli/compare/amplify-util-mock@3.30.4...amplify-util-mock@3.30.6) (2021-05-03) diff --git a/packages/amplify-util-mock/package.json b/packages/amplify-util-mock/package.json index 3b67018e6fb..d42275b3fdb 100644 --- a/packages/amplify-util-mock/package.json +++ b/packages/amplify-util-mock/package.json @@ -1,6 +1,6 @@ { "name": "amplify-util-mock", - "version": "3.30.6", + "version": "3.31.1", "description": "amplify cli plugin providing local testing", "repository": { "type": "git", @@ -25,12 +25,12 @@ }, "dependencies": { "@hapi/topo": "^5.0.0", - "amplify-appsync-simulator": "1.26.4", - "amplify-category-function": "2.31.6", - "amplify-cli-core": "1.21.2", + "amplify-appsync-simulator": "1.26.5", + "amplify-category-function": "2.31.8", + "amplify-cli-core": "1.22.1", "amplify-codegen": "^2.23.1", - "amplify-dynamodb-simulator": "1.18.6", - "amplify-provider-awscloudformation": "4.47.0", + "amplify-dynamodb-simulator": "1.18.8", + "amplify-provider-awscloudformation": "4.49.0", "amplify-storage-simulator": "1.5.2", "chokidar": "^3.3.1", "detect-port": "^1.3.0", @@ -38,7 +38,7 @@ "execa": "^4.1.0", "fs-extra": "^8.1.0", "lodash": "^4.17.19", - "semver": "^7.1.3", + "semver": "^7.3.5", "which": "^2.0.2" }, "devDependencies": { @@ -53,14 +53,14 @@ "aws-sdk": "^2.845.0", "aws-sdk-mock": "^5.1.0", "axios": "^0.21.1", - "graphql-auth-transformer": "6.24.6", - "graphql-connection-transformer": "4.21.6", - "graphql-dynamodb-transformer": "6.22.6", - "graphql-function-transformer": "2.5.6", - "graphql-key-transformer": "2.23.6", + "graphql-auth-transformer": "6.24.8", + "graphql-connection-transformer": "4.21.8", + "graphql-dynamodb-transformer": "6.22.8", + "graphql-function-transformer": "2.5.8", + "graphql-key-transformer": "2.23.8", "graphql-tag": "^2.10.1", - "graphql-transformer-core": "6.28.6", - "graphql-versioned-transformer": "4.17.6", + "graphql-transformer-core": "6.28.8", + "graphql-versioned-transformer": "4.17.8", "isomorphic-fetch": "^2.2.1", "jsonwebtoken": "^8.5.1", "node-fetch": "^2.6.1", diff --git a/packages/graphql-auth-transformer/CHANGELOG.md b/packages/graphql-auth-transformer/CHANGELOG.md index ad3d5582dab..0cd7a152e9c 100644 --- a/packages/graphql-auth-transformer/CHANGELOG.md +++ b/packages/graphql-auth-transformer/CHANGELOG.md @@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [6.24.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-auth-transformer@6.24.7...graphql-auth-transformer@6.24.8) (2021-05-18) + + +### Bug Fixes + +* **graphql-dynamodb-transformer:** make primary key non null on del ([#6337](https://github.com/aws-amplify/amplify-cli/issues/6337)) ([4a5c679](https://github.com/aws-amplify/amplify-cli/commit/4a5c6795680b6b88efb19b923ee234253ca30c35)), closes [#2564](https://github.com/aws-amplify/amplify-cli/issues/2564) + + + + + +## [6.24.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-auth-transformer@6.24.6...graphql-auth-transformer@6.24.7) (2021-05-14) + + +### Bug Fixes + +* **graphql-auth-transformer:** fixes [@auth](https://github.com/auth) directives for Admin UI ([#7035](https://github.com/aws-amplify/amplify-cli/issues/7035)) ([d4f2f1e](https://github.com/aws-amplify/amplify-cli/commit/d4f2f1e9f5bfd1803711dcb1ba50ca845005a7e5)) + + + + + ## [6.24.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-auth-transformer@6.24.4...graphql-auth-transformer@6.24.6) (2021-05-03) diff --git a/packages/graphql-auth-transformer/package.json b/packages/graphql-auth-transformer/package.json index 35b21751feb..1c1fedcda57 100644 --- a/packages/graphql-auth-transformer/package.json +++ b/packages/graphql-auth-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-auth-transformer", - "version": "6.24.6", + "version": "6.24.8", "description": "Implements the @auth directive for the appsync model transform.", "repository": { "type": "git", @@ -24,17 +24,17 @@ }, "dependencies": { "graphql": "^14.5.8", - "graphql-connection-transformer": "4.21.6", + "graphql-connection-transformer": "4.21.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/node": "^12.12.6", "cloudform-types": "^4.2.0", - "graphql-dynamodb-transformer": "6.22.6", - "graphql-elasticsearch-transformer": "4.11.6", - "graphql-function-transformer": "2.5.6", + "graphql-dynamodb-transformer": "6.22.8", + "graphql-elasticsearch-transformer": "4.11.8", + "graphql-function-transformer": "2.5.8", "rimraf": "^3.0.0" }, "jest": { diff --git a/packages/graphql-auth-transformer/src/__tests__/__snapshots__/SearchableAuthTransformer.test.ts.snap b/packages/graphql-auth-transformer/src/__tests__/__snapshots__/SearchableAuthTransformer.test.ts.snap index 8037606b5a4..e7cb539695c 100644 --- a/packages/graphql-auth-transformer/src/__tests__/__snapshots__/SearchableAuthTransformer.test.ts.snap +++ b/packages/graphql-auth-transformer/src/__tests__/__snapshots__/SearchableAuthTransformer.test.ts.snap @@ -98,7 +98,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { diff --git a/packages/graphql-connection-transformer/CHANGELOG.md b/packages/graphql-connection-transformer/CHANGELOG.md index 5a96bb0f858..29a06352c2a 100644 --- a/packages/graphql-connection-transformer/CHANGELOG.md +++ b/packages/graphql-connection-transformer/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.21.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@4.21.7...graphql-connection-transformer@4.21.8) (2021-05-18) + + +### Bug Fixes + +* **graphql-dynamodb-transformer:** make primary key non null on del ([#6337](https://github.com/aws-amplify/amplify-cli/issues/6337)) ([4a5c679](https://github.com/aws-amplify/amplify-cli/commit/4a5c6795680b6b88efb19b923ee234253ca30c35)), closes [#2564](https://github.com/aws-amplify/amplify-cli/issues/2564) + + + + + +## [4.21.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@4.21.6...graphql-connection-transformer@4.21.7) (2021-05-14) + +**Note:** Version bump only for package graphql-connection-transformer + + + + + ## [4.21.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-connection-transformer@4.21.4...graphql-connection-transformer@4.21.6) (2021-05-03) diff --git a/packages/graphql-connection-transformer/package.json b/packages/graphql-connection-transformer/package.json index 6f99939fd0d..b8cc2f8703e 100644 --- a/packages/graphql-connection-transformer/package.json +++ b/packages/graphql-connection-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-connection-transformer", - "version": "4.21.6", + "version": "4.21.8", "description": "An AppSync model transform for connecting objects.", "repository": { "type": "git", @@ -24,11 +24,11 @@ "dependencies": { "cloudform-types": "^4.2.0", "graphql": "^14.5.8", - "graphql-dynamodb-transformer": "6.22.6", - "graphql-key-transformer": "2.23.6", + "graphql-dynamodb-transformer": "6.22.8", + "graphql-key-transformer": "2.23.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/node": "^12.12.6" diff --git a/packages/graphql-connection-transformer/src/__tests__/__snapshots__/NewConnectionTransformer.test.ts.snap b/packages/graphql-connection-transformer/src/__tests__/__snapshots__/NewConnectionTransformer.test.ts.snap index 941af7b75a0..1b6888b99cd 100644 --- a/packages/graphql-connection-transformer/src/__tests__/__snapshots__/NewConnectionTransformer.test.ts.snap +++ b/packages/graphql-connection-transformer/src/__tests__/__snapshots__/NewConnectionTransformer.test.ts.snap @@ -164,7 +164,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! _version: Int } @@ -229,7 +229,7 @@ input UpdatePostEditorInput { } input DeletePostEditorInput { - id: ID + id: ID! _version: Int } @@ -268,7 +268,7 @@ input UpdateUserInput { } input DeleteUserInput { - id: ID + id: ID! _version: Int } @@ -440,7 +440,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -487,7 +487,7 @@ input UpdatePostEditorInput { } input DeletePostEditorInput { - id: ID + id: ID! } input ModelPostEditorConditionInput { @@ -522,7 +522,7 @@ input UpdateUserInput { } input DeleteUserInput { - id: ID + id: ID! } input ModelUserConditionInput { diff --git a/packages/graphql-dynamodb-transformer/CHANGELOG.md b/packages/graphql-dynamodb-transformer/CHANGELOG.md index ae52e1ed705..c48e5afb97f 100644 --- a/packages/graphql-dynamodb-transformer/CHANGELOG.md +++ b/packages/graphql-dynamodb-transformer/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [6.22.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-dynamodb-transformer@6.22.7...graphql-dynamodb-transformer@6.22.8) (2021-05-18) + + +### Bug Fixes + +* **graphql-dynamodb-transformer:** make primary key non null on del ([#6337](https://github.com/aws-amplify/amplify-cli/issues/6337)) ([4a5c679](https://github.com/aws-amplify/amplify-cli/commit/4a5c6795680b6b88efb19b923ee234253ca30c35)), closes [#2564](https://github.com/aws-amplify/amplify-cli/issues/2564) + + + + + +## [6.22.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-dynamodb-transformer@6.22.6...graphql-dynamodb-transformer@6.22.7) (2021-05-14) + +**Note:** Version bump only for package graphql-dynamodb-transformer + + + + + ## [6.22.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-dynamodb-transformer@6.22.4...graphql-dynamodb-transformer@6.22.6) (2021-05-03) diff --git a/packages/graphql-dynamodb-transformer/package.json b/packages/graphql-dynamodb-transformer/package.json index 72a147aace1..d69601297ad 100644 --- a/packages/graphql-dynamodb-transformer/package.json +++ b/packages/graphql-dynamodb-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-dynamodb-transformer", - "version": "6.22.6", + "version": "6.22.8", "description": "An AppSync model transform that takes a simple model and creates a DynamoDB table, DynamoDB stream.", "repository": { "type": "git", @@ -28,7 +28,7 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "md5": "^2.2.1", "pluralize": "^8.0.0" }, diff --git a/packages/graphql-dynamodb-transformer/src/__tests__/__snapshots__/DynamoDBModelTransformer.test.ts.snap b/packages/graphql-dynamodb-transformer/src/__tests__/__snapshots__/DynamoDBModelTransformer.test.ts.snap index 49371d1c15d..a9ce3ea1a9a 100644 --- a/packages/graphql-dynamodb-transformer/src/__tests__/__snapshots__/DynamoDBModelTransformer.test.ts.snap +++ b/packages/graphql-dynamodb-transformer/src/__tests__/__snapshots__/DynamoDBModelTransformer.test.ts.snap @@ -128,7 +128,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -292,7 +292,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -577,7 +577,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -877,7 +877,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -1276,7 +1276,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -1563,7 +1563,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -1708,7 +1708,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { diff --git a/packages/graphql-dynamodb-transformer/src/definitions.ts b/packages/graphql-dynamodb-transformer/src/definitions.ts index f7b1755355f..38e0fe59286 100644 --- a/packages/graphql-dynamodb-transformer/src/definitions.ts +++ b/packages/graphql-dynamodb-transformer/src/definitions.ts @@ -266,7 +266,7 @@ export function makeDeleteInputObject(obj: ObjectTypeDefinitionNode, isSync: boo { kind: Kind.INPUT_VALUE_DEFINITION, name: { kind: 'Name', value: 'id' }, - type: makeNamedType('ID'), + type: wrapNonNull(makeNamedType('ID')), // TODO: Service does not support new style descriptions so wait. // description: { // kind: 'StringValue', diff --git a/packages/graphql-elasticsearch-transformer/CHANGELOG.md b/packages/graphql-elasticsearch-transformer/CHANGELOG.md index 7aac127cc86..9c9deb54951 100644 --- a/packages/graphql-elasticsearch-transformer/CHANGELOG.md +++ b/packages/graphql-elasticsearch-transformer/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.11.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-elasticsearch-transformer@4.11.7...graphql-elasticsearch-transformer@4.11.8) (2021-05-18) + + +### Bug Fixes + +* **graphql-dynamodb-transformer:** make primary key non null on del ([#6337](https://github.com/aws-amplify/amplify-cli/issues/6337)) ([4a5c679](https://github.com/aws-amplify/amplify-cli/commit/4a5c6795680b6b88efb19b923ee234253ca30c35)), closes [#2564](https://github.com/aws-amplify/amplify-cli/issues/2564) + + + + + +## [4.11.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-elasticsearch-transformer@4.11.6...graphql-elasticsearch-transformer@4.11.7) (2021-05-14) + +**Note:** Version bump only for package graphql-elasticsearch-transformer + + + + + ## [4.11.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-elasticsearch-transformer@4.11.4...graphql-elasticsearch-transformer@4.11.6) (2021-05-03) diff --git a/packages/graphql-elasticsearch-transformer/package.json b/packages/graphql-elasticsearch-transformer/package.json index a656ce8c6e6..e2ef9604519 100644 --- a/packages/graphql-elasticsearch-transformer/package.json +++ b/packages/graphql-elasticsearch-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-elasticsearch-transformer", - "version": "4.11.6", + "version": "4.11.8", "description": "An AppSync model transform that creates an ElasticSearch index with the queries to match.", "repository": { "type": "git", @@ -27,12 +27,12 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/node": "^12.12.6", "bestzip": "^2.1.5", - "graphql-dynamodb-transformer": "6.22.6" + "graphql-dynamodb-transformer": "6.22.8" }, "jest": { "transform": { diff --git a/packages/graphql-elasticsearch-transformer/src/__tests__/__snapshots__/SearchableModelTransformer.test.ts.snap b/packages/graphql-elasticsearch-transformer/src/__tests__/__snapshots__/SearchableModelTransformer.test.ts.snap index 28c5e1b4f54..b14fb844581 100644 --- a/packages/graphql-elasticsearch-transformer/src/__tests__/__snapshots__/SearchableModelTransformer.test.ts.snap +++ b/packages/graphql-elasticsearch-transformer/src/__tests__/__snapshots__/SearchableModelTransformer.test.ts.snap @@ -155,7 +155,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -374,7 +374,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -419,7 +419,7 @@ input UpdateUserInput { } input DeleteUserInput { - id: ID + id: ID! } input SearchableStringFilterInput { @@ -834,7 +834,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { @@ -1043,7 +1043,7 @@ input UpdatePostInput { } input DeletePostInput { - id: ID + id: ID! } type Mutation { diff --git a/packages/graphql-function-transformer/CHANGELOG.md b/packages/graphql-function-transformer/CHANGELOG.md index e606ee8cefb..a3e005c25b9 100644 --- a/packages/graphql-function-transformer/CHANGELOG.md +++ b/packages/graphql-function-transformer/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.5.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-function-transformer@2.5.7...graphql-function-transformer@2.5.8) (2021-05-18) + +**Note:** Version bump only for package graphql-function-transformer + + + + + +## [2.5.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-function-transformer@2.5.6...graphql-function-transformer@2.5.7) (2021-05-14) + +**Note:** Version bump only for package graphql-function-transformer + + + + + ## [2.5.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-function-transformer@2.5.4...graphql-function-transformer@2.5.6) (2021-05-03) diff --git a/packages/graphql-function-transformer/package.json b/packages/graphql-function-transformer/package.json index 8a555c08fc6..47b8c50ca02 100644 --- a/packages/graphql-function-transformer/package.json +++ b/packages/graphql-function-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-function-transformer", - "version": "2.5.6", + "version": "2.5.8", "description": "Implements the @function directive.", "repository": { "type": "git", @@ -27,7 +27,7 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "jest": { "transform": { diff --git a/packages/graphql-http-transformer/CHANGELOG.md b/packages/graphql-http-transformer/CHANGELOG.md index 170600c072a..977f1f0884e 100644 --- a/packages/graphql-http-transformer/CHANGELOG.md +++ b/packages/graphql-http-transformer/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.17.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-http-transformer@4.17.7...graphql-http-transformer@4.17.8) (2021-05-18) + +**Note:** Version bump only for package graphql-http-transformer + + + + + +## [4.17.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-http-transformer@4.17.6...graphql-http-transformer@4.17.7) (2021-05-14) + +**Note:** Version bump only for package graphql-http-transformer + + + + + ## [4.17.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-http-transformer@4.17.4...graphql-http-transformer@4.17.6) (2021-05-03) diff --git a/packages/graphql-http-transformer/package.json b/packages/graphql-http-transformer/package.json index 161f24fcc3e..3cdccf20384 100644 --- a/packages/graphql-http-transformer/package.json +++ b/packages/graphql-http-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-http-transformer", - "version": "4.17.6", + "version": "4.17.8", "description": "An AppSync model transform for HTTP resolvers.", "repository": { "type": "git", @@ -26,7 +26,7 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/node": "^12.12.6" diff --git a/packages/graphql-key-transformer/CHANGELOG.md b/packages/graphql-key-transformer/CHANGELOG.md index 08f82a752f2..8eae5bcbe35 100644 --- a/packages/graphql-key-transformer/CHANGELOG.md +++ b/packages/graphql-key-transformer/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.23.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-key-transformer@2.23.7...graphql-key-transformer@2.23.8) (2021-05-18) + +**Note:** Version bump only for package graphql-key-transformer + + + + + +## [2.23.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-key-transformer@2.23.6...graphql-key-transformer@2.23.7) (2021-05-14) + +**Note:** Version bump only for package graphql-key-transformer + + + + + ## [2.23.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-key-transformer@2.23.4...graphql-key-transformer@2.23.6) (2021-05-03) diff --git a/packages/graphql-key-transformer/package.json b/packages/graphql-key-transformer/package.json index 4184f97c7dc..062eb949219 100644 --- a/packages/graphql-key-transformer/package.json +++ b/packages/graphql-key-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-key-transformer", - "version": "2.23.6", + "version": "2.23.8", "description": "Implements the @key directive.", "repository": { "type": "git", @@ -24,10 +24,10 @@ "dependencies": { "cloudform-types": "^4.2.0", "graphql": "^14.5.8", - "graphql-dynamodb-transformer": "6.22.6", + "graphql-dynamodb-transformer": "6.22.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "jest": { "testURL": "http://localhost", diff --git a/packages/graphql-predictions-transformer/CHANGELOG.md b/packages/graphql-predictions-transformer/CHANGELOG.md index efbac649f67..c2ca1bfe0cd 100644 --- a/packages/graphql-predictions-transformer/CHANGELOG.md +++ b/packages/graphql-predictions-transformer/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.5.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-predictions-transformer@2.5.7...graphql-predictions-transformer@2.5.8) (2021-05-18) + +**Note:** Version bump only for package graphql-predictions-transformer + + + + + +## [2.5.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-predictions-transformer@2.5.6...graphql-predictions-transformer@2.5.7) (2021-05-14) + +**Note:** Version bump only for package graphql-predictions-transformer + + + + + ## [2.5.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-predictions-transformer@2.5.4...graphql-predictions-transformer@2.5.6) (2021-05-03) diff --git a/packages/graphql-predictions-transformer/package.json b/packages/graphql-predictions-transformer/package.json index 17000a1458d..8cacae5debd 100644 --- a/packages/graphql-predictions-transformer/package.json +++ b/packages/graphql-predictions-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-predictions-transformer", - "version": "2.5.6", + "version": "2.5.8", "description": "Implements the @predictions directive.", "repository": { "type": "git", @@ -27,7 +27,7 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "bestzip": "^2.1.5" diff --git a/packages/graphql-transformer-core/CHANGELOG.md b/packages/graphql-transformer-core/CHANGELOG.md index b0332cedfdc..3f90edf8ac3 100644 --- a/packages/graphql-transformer-core/CHANGELOG.md +++ b/packages/graphql-transformer-core/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [6.28.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformer-core@6.28.7...graphql-transformer-core@6.28.8) (2021-05-18) + +**Note:** Version bump only for package graphql-transformer-core + + + + + +## [6.28.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformer-core@6.28.6...graphql-transformer-core@6.28.7) (2021-05-14) + +**Note:** Version bump only for package graphql-transformer-core + + + + + ## [6.28.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformer-core@6.28.4...graphql-transformer-core@6.28.6) (2021-05-03) diff --git a/packages/graphql-transformer-core/package.json b/packages/graphql-transformer-core/package.json index ce891cfabc6..e8af5282651 100644 --- a/packages/graphql-transformer-core/package.json +++ b/packages/graphql-transformer-core/package.json @@ -1,6 +1,6 @@ { "name": "graphql-transformer-core", - "version": "6.28.6", + "version": "6.28.8", "description": "A framework to transform from GraphQL SDL to AWS CloudFormation.", "repository": { "type": "git", @@ -23,7 +23,7 @@ "clean": "rimraf ./lib" }, "dependencies": { - "amplify-cli-core": "1.21.2", + "amplify-cli-core": "1.22.1", "cloudform-types": "^4.2.0", "deep-diff": "^1.0.2", "fs-extra": "^8.1.0", diff --git a/packages/graphql-transformers-e2e-tests/CHANGELOG.md b/packages/graphql-transformers-e2e-tests/CHANGELOG.md index 8b5800ac5e1..316459115e6 100644 --- a/packages/graphql-transformers-e2e-tests/CHANGELOG.md +++ b/packages/graphql-transformers-e2e-tests/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [6.23.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformers-e2e-tests@6.23.7...graphql-transformers-e2e-tests@6.23.8) (2021-05-18) + +**Note:** Version bump only for package graphql-transformers-e2e-tests + + + + + +## [6.23.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformers-e2e-tests@6.23.6...graphql-transformers-e2e-tests@6.23.7) (2021-05-14) + +**Note:** Version bump only for package graphql-transformers-e2e-tests + + + + + ## [6.23.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-transformers-e2e-tests@6.23.4...graphql-transformers-e2e-tests@6.23.6) (2021-05-03) diff --git a/packages/graphql-transformers-e2e-tests/package.json b/packages/graphql-transformers-e2e-tests/package.json index bd08a7f8125..7327e96a840 100644 --- a/packages/graphql-transformers-e2e-tests/package.json +++ b/packages/graphql-transformers-e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "graphql-transformers-e2e-tests", - "version": "6.23.6", + "version": "6.23.8", "description": "End to end functional tests for appsync supported transformers.", "private": true, "repository": { @@ -27,7 +27,7 @@ "cloudform-types": "^4.2.0", "graphql": "^14.5.8", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6", + "graphql-transformer-core": "6.28.8", "moment": "^2.24.0" }, "devDependencies": { @@ -39,16 +39,16 @@ "aws-sdk": "^2.845.0", "execa": "4.1.0", "fs-extra": "^8.1.0", - "graphql-auth-transformer": "6.24.6", - "graphql-connection-transformer": "4.21.6", - "graphql-dynamodb-transformer": "6.22.6", - "graphql-elasticsearch-transformer": "4.11.6", - "graphql-function-transformer": "2.5.6", - "graphql-http-transformer": "4.17.6", - "graphql-key-transformer": "2.23.6", - "graphql-predictions-transformer": "2.5.6", + "graphql-auth-transformer": "6.24.8", + "graphql-connection-transformer": "4.21.8", + "graphql-dynamodb-transformer": "6.22.8", + "graphql-elasticsearch-transformer": "4.11.8", + "graphql-function-transformer": "2.5.8", + "graphql-http-transformer": "4.17.8", + "graphql-key-transformer": "2.23.8", + "graphql-predictions-transformer": "2.5.8", "graphql-tag": "^2.10.1", - "graphql-versioned-transformer": "4.17.6", + "graphql-versioned-transformer": "4.17.8", "isomorphic-fetch": "^2.2.1", "jest-junit": "^12.0.0", "node-fetch": "^2.6.1", diff --git a/packages/graphql-versioned-transformer/CHANGELOG.md b/packages/graphql-versioned-transformer/CHANGELOG.md index ddb59e43041..6c881a51768 100644 --- a/packages/graphql-versioned-transformer/CHANGELOG.md +++ b/packages/graphql-versioned-transformer/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.17.8](https://github.com/aws-amplify/amplify-cli/compare/graphql-versioned-transformer@4.17.7...graphql-versioned-transformer@4.17.8) (2021-05-18) + +**Note:** Version bump only for package graphql-versioned-transformer + + + + + +## [4.17.7](https://github.com/aws-amplify/amplify-cli/compare/graphql-versioned-transformer@4.17.6...graphql-versioned-transformer@4.17.7) (2021-05-14) + +**Note:** Version bump only for package graphql-versioned-transformer + + + + + ## [4.17.6](https://github.com/aws-amplify/amplify-cli/compare/graphql-versioned-transformer@4.17.4...graphql-versioned-transformer@4.17.6) (2021-05-03) diff --git a/packages/graphql-versioned-transformer/package.json b/packages/graphql-versioned-transformer/package.json index 68aaef2006a..60134348d75 100644 --- a/packages/graphql-versioned-transformer/package.json +++ b/packages/graphql-versioned-transformer/package.json @@ -1,6 +1,6 @@ { "name": "graphql-versioned-transformer", - "version": "4.17.6", + "version": "4.17.8", "description": "A GraphQL transform that enabled object versioning and conflict resolution for a @model type.", "repository": { "type": "git", @@ -25,11 +25,11 @@ "graphql": "^14.5.8", "graphql-mapping-template": "4.18.1", "graphql-transformer-common": "4.19.3", - "graphql-transformer-core": "6.28.6" + "graphql-transformer-core": "6.28.8" }, "devDependencies": { "@types/node": "^12.12.6", - "graphql-dynamodb-transformer": "6.22.6" + "graphql-dynamodb-transformer": "6.22.8" }, "jest": { "transform": { diff --git a/tsconfig.base.json b/tsconfig.base.json index 5a740d5a0c8..52922e9d939 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -57,7 +57,8 @@ "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, "resolveJsonModule": true, "preserveConstEnums": true, - "pretty": true + "pretty": true, + "stripInternal": true }, "exclude": ["**/__mocks__/**/*", "**/__tests__/**/*", "**/lib/**/*"] } diff --git a/yarn.lock b/yarn.lock index 11070192cf7..32be6413219 100644 --- a/yarn.lock +++ b/yarn.lock @@ -749,7 +749,7 @@ "@aws-cdk/region-info" "1.72.0" constructs "^3.2.0" -"@aws-cdk/aws-elasticsearch@~1.72.0": +"@aws-cdk/aws-elasticsearch@1.72.0", "@aws-cdk/aws-elasticsearch@~1.72.0": version "1.72.0" resolved "https://registry.yarnpkg.com/@aws-cdk/aws-elasticsearch/-/aws-elasticsearch-1.72.0.tgz#2fa5463ab7252a2190704dda202a7e0174a1d4e5" integrity sha512-XdSFPRspfNoCL1hnP83mLH1DnfBnbD6DDRZ8hBH542p+fOuSjbW5+VGPlEzqYmfWs7fVis1VD4QKM1p450Bjng== @@ -7035,6 +7035,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.2.tgz#2de1ed6670439387da1c9f549a2ade2b0a799256" integrity sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA== +"@types/node@^10.17.13": + version "10.17.59" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.59.tgz#03f440ccf746a27f7da6e141e6cbae64681dbd2f" + integrity sha512-7Uc8IRrL8yZz5ti45RaFxpbU8TxlzdC3HvxV+hOWo1EyLsuKv/w7y0n+TwZzwL3vdx3oZ2k3ubxPq131hNtXyg== + "@types/node@^12.12.6": version "12.19.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.1.tgz#303f74c8a2b35644594139e948b2be470ae1186f" @@ -14548,9 +14553,9 @@ hoopy@^0.1.4: integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hpack.js@^2.1.6: version "2.1.6" @@ -18119,6 +18124,16 @@ nock@^12.0.3: lodash "^4.17.13" propagate "^2.0.0" +nock@^13.0.11: + version "13.0.11" + resolved "https://registry.npmjs.org/nock/-/nock-13.0.11.tgz#ba733252e720897ca50033205c39db0c7470f331" + integrity sha512-sKZltNkkWblkqqPAsjYW0bm3s9DcHRPiMOyKO/PkfJ+ANHZ2+LA2PLe22r4lLrKgXaiSaDQwW3qGsJFtIpQIeQ== + dependencies: + debug "^4.1.0" + json-stringify-safe "^5.0.1" + lodash.set "^4.3.2" + propagate "^2.0.0" + node-abi@^2.7.0: version "2.19.1" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.1.tgz#6aa32561d0a5e2fdb6810d8c25641b657a8cea85" @@ -18149,7 +18164,7 @@ node-fetch@2.1.2: node-fetch@2.6.1, node-fetch@^2.2.0, node-fetch@^2.5.0, node-fetch@^2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== node-fetch@^1.0.1: @@ -20315,7 +20330,7 @@ proxy-addr@~2.0.5: proxy-agent@^4.0.0, proxy-agent@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-4.0.1.tgz#326c3250776c7044cd19655ccbfadf2e065a045c" + resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-4.0.1.tgz#326c3250776c7044cd19655ccbfadf2e065a045c" integrity sha512-ODnQnW2jc/FUVwHHuaZEfN5otg/fMbvMxz9nMSUQfJ9JU7q2SZvSULSsjLloVgJOiv9yhc8GlNMKc4GkFmcVEA== dependencies: agent-base "^6.0.0" @@ -21640,7 +21655,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2: +semver@7.3.2, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -21652,6 +21667,13 @@ semver@7.x, semver@^7.2.1: dependencies: lru-cache "^6.0.0" +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"