├── .codebuild ├── android_canary_workflow.yml ├── build_linux.yml ├── build_windows.yml ├── canary_workflow.yml ├── canary_workflow_base.yml ├── cleanup_e2e_resources.yml ├── cleanup_workflow.yml ├── deploy.yml ├── deprecate.yml ├── deprecate_workflow.yml ├── e2e_workflow.yml ├── e2e_workflow_base.yml ├── install_linux.yml ├── ios_canary_workflow.yml ├── lint.yml ├── pr_workflow.yml ├── publish_to_local_registry.yml ├── release_workflow.yml ├── run_android_modelgen_e2e_test.yml ├── run_canary_android_modelgen_e2e_test.yml ├── run_canary_e2e_tests.yml ├── run_canary_ios_modelgen_e2e_test.yml ├── run_e2e_tests.yml ├── run_e2e_tests_windows.yml ├── run_gen2_e2e_test.yml ├── run_gen2_e2e_test_windows.yml ├── run_ios_modelgen_e2e_test.yml ├── run_regionalized_android_modelgen_e2e_test.yml ├── run_regionalized_ios_modelgen_e2e_test.yml ├── run_regionalized_ts_modelgen_e2e_test.yml ├── scripts │ ├── artifact-storage-path-allow-list-codebuild.ts │ ├── build_windows.sh │ ├── e2e_test_windows.sh │ ├── gen2_e2e_test_windows.sh │ ├── lint_pr.sh │ ├── local_publish_helpers.sh │ ├── post_e2e_test.sh │ ├── publish.sh │ ├── run-ios-modelgen-e2e-test.sh │ ├── scan_artifacts.ts │ ├── test_windows.sh │ └── verdaccio.yaml ├── test.yml ├── test_windows.yml ├── ts_canary_workflow.yml ├── verify_api_extract.yml └── verify_dependency_licenses_extract.yml ├── .editorconfig ├── .eslintrc.js ├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── 1.gen2_bug_report.yaml │ ├── 2.gen1_bug_report.yaml │ ├── 3.feature_request.yaml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build-swift-modelgen.yml │ ├── closed-issue-message.yml │ └── codeql.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── FeatureFlags.md ├── LICENSE ├── README-relationships.md ├── Readme.md ├── commitlint.config.js ├── dependency_licenses.txt ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── amplify-codegen-e2e-core │ ├── CHANGELOG.md │ ├── Readme.md │ ├── dist │ │ └── index.html │ ├── environment.js │ ├── package.json │ ├── reporter.js │ ├── runner.js │ ├── src │ │ ├── asciinema-recorder.ts │ │ ├── categories │ │ │ ├── analytics.ts │ │ │ ├── api.ts │ │ │ ├── auth.ts │ │ │ ├── codegen.ts │ │ │ ├── hosting.ts │ │ │ ├── index.ts │ │ │ ├── interactions.ts │ │ │ ├── lambda-function.ts │ │ │ ├── lambda-layer.ts │ │ │ ├── notifications.ts │ │ │ ├── predictions.ts │ │ │ └── storage.ts │ │ ├── cli-test-environment.js │ │ ├── cli-test-runner.js │ │ ├── configure │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── init │ │ │ ├── adminUI.ts │ │ │ ├── amplifyPull.ts │ │ │ ├── amplifyPush.ts │ │ │ ├── android.ts │ │ │ ├── cra.ts │ │ │ ├── deleteProject.ts │ │ │ ├── index.ts │ │ │ ├── initProjectHelper.ts │ │ │ ├── pull-headless.ts │ │ │ └── swift.ts │ │ ├── nexpect-reporter.js │ │ └── utils │ │ │ ├── add-ci-tags.ts │ │ │ ├── admin-ui.ts │ │ │ ├── api.ts │ │ │ ├── appsync.ts │ │ │ ├── envVars.ts │ │ │ ├── feature-flags.ts │ │ │ ├── frontend-config-helper.ts │ │ │ ├── getAppId.ts │ │ │ ├── getCommandPath.ts │ │ │ ├── graphql-config-helper.ts │ │ │ ├── headless.ts │ │ │ ├── index.ts │ │ │ ├── isWindows.ts │ │ │ ├── nexpect.ts │ │ │ ├── pinpoint.ts │ │ │ ├── projectMeta.ts │ │ │ ├── readJsonFile.ts │ │ │ ├── request.ts │ │ │ ├── retrier.ts │ │ │ ├── sdk-calls.ts │ │ │ ├── selectors.ts │ │ │ ├── sleep.ts │ │ │ └── transformConfig.ts │ └── tsconfig.json ├── amplify-codegen-e2e-tests │ ├── CHANGELOG.md │ ├── Readme.md │ ├── functions │ │ ├── get-api-appsync.js │ │ └── mutation-appsync.js │ ├── package.json │ ├── schemas │ │ ├── admin-modelgen.graphql │ │ ├── initial_key_blog.graphql │ │ ├── iterative-push │ │ │ ├── add-one-key-multiple-models │ │ │ │ ├── final-schema.graphql │ │ │ │ └── initial-schema.graphql │ │ │ ├── add-remove-and-update-key │ │ │ │ ├── final-schema.graphql │ │ │ │ └── initial-schema.graphql │ │ │ ├── change-model-name │ │ │ │ ├── final-schema.graphql │ │ │ │ └── initial-schema.graphql │ │ │ └── multiple-key-delete │ │ │ │ ├── final-schema.graphql │ │ │ │ └── initial-schema.graphql │ │ ├── key-conflict-detection.graphql │ │ ├── migrations_connection │ │ │ ├── add_a_sort_key.graphql │ │ │ ├── add_a_sort_key_before_remove.graphql │ │ │ ├── cant_add_a_sort_key.graphql │ │ │ ├── cant_add_and_remove_at_same_time.graphql │ │ │ ├── cant_change_connection_field_name.graphql │ │ │ ├── initial_schema.graphql │ │ │ ├── remove_connection.graphql │ │ │ └── remove_old_connection_after.graphql │ │ ├── migrations_key │ │ │ ├── add_gsi.graphql │ │ │ ├── cant_add_lsi.graphql │ │ │ ├── cant_add_more_gsi.graphql │ │ │ ├── cant_add_multiple_gsi.graphql │ │ │ ├── cant_change_gsi.graphql │ │ │ ├── cant_change_key_schema.graphql │ │ │ ├── cant_change_lsi.graphql │ │ │ ├── cant_remove_more_gsi.graphql │ │ │ ├── cant_update_delete_gsi.graphql │ │ │ ├── four_gsi_model_schema.graphql │ │ │ ├── four_key_model_schema.graphql │ │ │ ├── initial_schema.graphql │ │ │ ├── initial_schema1.graphql │ │ │ ├── simple_key.graphql │ │ │ ├── three_gsi_model_schema.graphql │ │ │ └── two_key_model_schema.graphql │ │ ├── migrations_searchable │ │ │ ├── initial_searchable.graphql │ │ │ └── updated_searchable.graphql │ │ ├── modelgen │ │ │ ├── model_gen_schema_with_aws_scalars.graphql │ │ │ ├── model_gen_schema_with_errors.graphql │ │ │ └── schema_with_connected_pk.graphql │ │ ├── multi-gsi.graphql │ │ ├── next_key_blog.graphql │ │ ├── sdl │ │ │ ├── schema.graphql │ │ │ └── schema.json │ │ ├── selective_sync.graphql │ │ ├── simple_model.graphql │ │ └── two-model-schema.graphql │ ├── src │ │ ├── __tests__ │ │ │ ├── add-codegen-android.test.ts │ │ │ ├── add-codegen-ios.test.ts │ │ │ ├── add-codegen-js.test.ts │ │ │ ├── backends │ │ │ │ └── graphql-generator-gen2 │ │ │ │ │ ├── handlers │ │ │ │ │ ├── mutation.ts │ │ │ │ │ └── query.ts │ │ │ │ │ └── resource.ts │ │ │ ├── build-app-android.test.ts │ │ │ ├── build-app-swift.test.ts │ │ │ ├── build-app-ts.test.ts │ │ │ ├── codegen-matrix.test.ts │ │ │ ├── configure-codegen-android.test.ts │ │ │ ├── configure-codegen-ios.test.ts │ │ │ ├── configure-codegen-js.test.ts │ │ │ ├── datastore-modelgen-android.test.ts │ │ │ ├── datastore-modelgen-flutter.test.ts │ │ │ ├── datastore-modelgen-ios.test.ts │ │ │ ├── datastore-modelgen-js.test.ts │ │ │ ├── env-codegen.test.ts │ │ │ ├── feature-flags.test.ts │ │ │ ├── graphql-codegen-android.test.ts │ │ │ ├── graphql-codegen-ios.test.ts │ │ │ ├── graphql-codegen-js.test.ts │ │ │ ├── graphql-documents-generator.test.ts │ │ │ ├── graphql-generator-app.test.ts │ │ │ ├── graphql-generator-gen2.test.ts │ │ │ ├── model-introspection-codegen.test.ts │ │ │ ├── pull-codegen.test.ts │ │ │ ├── push-codegen-admin-modelgen.test.ts │ │ │ ├── push-codegen-android.test.ts │ │ │ ├── push-codegen-ios.test.ts │ │ │ ├── push-codegen-js.test.ts │ │ │ ├── remove-codegen-android.test.ts │ │ │ ├── remove-codegen-ios.test.ts │ │ │ ├── remove-codegen-js.test.ts │ │ │ ├── uninitialized-project-codegen-js.test.ts │ │ │ ├── uninitialized-project-modelgen-android.test.ts │ │ │ ├── uninitialized-project-modelgen-flutter.test.ts │ │ │ ├── uninitialized-project-modelgen-ios.test.ts │ │ │ └── uninitialized-project-modelgen-js.test.ts │ │ ├── amplify-app-helpers │ │ │ ├── amplify-app-setup.ts │ │ │ └── amplify-app-validation.ts │ │ ├── aws-exports │ │ │ └── awsExports.ts │ │ ├── aws-matchers │ │ │ ├── iamMatcher.ts │ │ │ ├── index.ts │ │ │ └── s3matcher.ts │ │ ├── cleanup-e2e-resources.ts │ │ ├── codegen-tests-base │ │ │ ├── add-codegen.ts │ │ │ ├── configure-codegen.ts │ │ │ ├── datastore-modelgen.ts │ │ │ ├── graphql-codegen.ts │ │ │ ├── index.ts │ │ │ ├── push-codegen.ts │ │ │ ├── remove-codegen.ts │ │ │ ├── test-setup.ts │ │ │ └── uninitialized-modelgen.ts │ │ ├── configure_tests.ts │ │ ├── environment │ │ │ └── env.ts │ │ ├── gen2-codegen-tests-base │ │ │ ├── commands.ts │ │ │ ├── index.ts │ │ │ └── test-graphql-client-codegen.ts │ │ ├── import-helpers │ │ │ ├── expects.ts │ │ │ ├── index.ts │ │ │ ├── settings.ts │ │ │ ├── types.ts │ │ │ ├── utilities.ts │ │ │ └── walkthroughs.ts │ │ ├── init-special-cases │ │ │ └── index.ts │ │ ├── plugin │ │ │ ├── index.ts │ │ │ ├── new-plugin.ts │ │ │ └── verifyPluginStructure.ts │ │ ├── schema-api-directives │ │ │ ├── authHelper.ts │ │ │ ├── common.ts │ │ │ ├── functionTester.ts │ │ │ ├── index.ts │ │ │ └── tests │ │ │ │ ├── auth-combiningAuthRules1.ts │ │ │ │ ├── auth-combiningAuthRules2.ts │ │ │ │ ├── auth-combiningAuthRules3.ts │ │ │ │ ├── auth-customClaims.ts │ │ │ │ ├── auth-dynamicGroup1.ts │ │ │ │ ├── auth-dynamicGroup2.ts │ │ │ │ ├── auth-dynamicGroup3.ts │ │ │ │ ├── auth-fieldLevelAuth1.ts │ │ │ │ ├── auth-fieldLevelAuth2.ts │ │ │ │ ├── auth-fieldLevelAuth3.ts │ │ │ │ ├── auth-fieldLevelAuth4.ts │ │ │ │ ├── auth-fieldLevelAuth5.ts │ │ │ │ ├── auth-fieldLevelAuth6.ts │ │ │ │ ├── auth-fieldLevelAuth7.ts │ │ │ │ ├── auth-fieldLevelAuth8.ts │ │ │ │ ├── auth-generatesDynamicGroup.ts │ │ │ │ ├── auth-generatesOwner.ts │ │ │ │ ├── auth-generatesStaticGroup.ts │ │ │ │ ├── auth-owner1.ts │ │ │ │ ├── auth-owner2.ts │ │ │ │ ├── auth-owner3.ts │ │ │ │ ├── auth-owner4.ts │ │ │ │ ├── auth-owner5.ts │ │ │ │ ├── auth-owner6.ts │ │ │ │ ├── auth-owner7.ts │ │ │ │ ├── auth-ownerMultiAuthRules.ts │ │ │ │ ├── auth-private1.ts │ │ │ │ ├── auth-private2.ts │ │ │ │ ├── auth-public1.ts │ │ │ │ ├── auth-public2.ts │ │ │ │ ├── auth-staticGroup1.ts │ │ │ │ ├── auth-staticGroup2.ts │ │ │ │ ├── auth-subscriptions1.ts │ │ │ │ ├── auth-subscriptions2.ts │ │ │ │ ├── auth-subscriptions3.ts │ │ │ │ ├── auth-usingOidc.ts │ │ │ │ ├── connection-belongsTo.ts │ │ │ │ ├── connection-hasMany.ts │ │ │ │ ├── connection-hasOne1.ts │ │ │ │ ├── connection-hasOne2.ts │ │ │ │ ├── connection-limit.ts │ │ │ │ ├── connection-manyToMany.ts │ │ │ │ ├── data-access-patterns.ts │ │ │ │ ├── function-chaining.ts │ │ │ │ ├── function-differentRegion.ts │ │ │ │ ├── function-example1.ts │ │ │ │ ├── function-example2.ts │ │ │ │ ├── function-usage.ts │ │ │ │ ├── key-howTo1.ts │ │ │ │ ├── key-howTo2.ts │ │ │ │ ├── key-howTo3.ts │ │ │ │ ├── key-howTo4.ts │ │ │ │ ├── model-generates.ts │ │ │ │ ├── model-usage1.ts │ │ │ │ ├── model-usage2.ts │ │ │ │ ├── model-usage3.ts │ │ │ │ ├── model-usage4.ts │ │ │ │ ├── predictions-usage-image.jpg │ │ │ │ ├── predictions-usage.ts │ │ │ │ ├── searchable-usage.ts │ │ │ │ └── versioned-usage.ts │ │ ├── setup-tests.ts │ │ ├── types │ │ │ └── SandboxApp.ts │ │ └── utils │ │ │ └── index.ts │ ├── test-apps │ │ ├── android │ │ │ ├── .gitignore │ │ │ ├── app │ │ │ │ ├── .gitignore │ │ │ │ ├── build.gradle │ │ │ │ ├── proguard-rules.pro │ │ │ │ └── src │ │ │ │ │ ├── androidTest │ │ │ │ │ └── java │ │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── android │ │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ │ │ ├── main │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── java │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── example │ │ │ │ │ │ │ └── android │ │ │ │ │ │ │ └── MyAndroidApp.java │ │ │ │ │ └── res │ │ │ │ │ │ ├── drawable-v24 │ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ │ ├── values-night │ │ │ │ │ │ └── themes.xml │ │ │ │ │ │ ├── values │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── themes.xml │ │ │ │ │ │ └── xml │ │ │ │ │ │ ├── backup_rules.xml │ │ │ │ │ │ └── data_extraction_rules.xml │ │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── android │ │ │ │ │ └── ExampleUnitTest.java │ │ │ ├── build.gradle │ │ │ ├── gradle.properties │ │ │ ├── gradle │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── docsgen-react-app │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── cypress.config.js │ │ │ ├── cypress │ │ │ │ └── support │ │ │ │ │ ├── component-index.html │ │ │ │ │ └── component.js │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ ├── index.html │ │ │ │ ├── introspection-schema.json │ │ │ │ ├── manifest.json │ │ │ │ ├── schema.graphql │ │ │ │ └── sdl-schema.graphql │ │ │ └── src │ │ │ │ ├── App.css │ │ │ │ ├── App.cy.js │ │ │ │ ├── App.js │ │ │ │ ├── index.css │ │ │ │ └── index.js │ │ ├── graphql-generator-app │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── config-overrides.js │ │ │ ├── cypress.config.ts │ │ │ ├── cypress │ │ │ │ └── support │ │ │ │ │ ├── commands.ts │ │ │ │ │ ├── component-index.html │ │ │ │ │ └── component.ts │ │ │ ├── package.json │ │ │ ├── public │ │ │ │ └── index.html │ │ │ ├── src │ │ │ │ ├── App.cy.js │ │ │ │ ├── App.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── polyfills │ │ │ │ │ ├── fs-extra.js │ │ │ │ │ └── process-shim.js │ │ │ │ ├── schemas.ts │ │ │ │ └── testCases.ts │ │ │ └── tsconfig.json │ │ ├── swift │ │ │ ├── .gitignore │ │ │ ├── swift.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ └── project.xcworkspace │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── swift │ │ │ │ ├── Assets.xcassets │ │ │ │ ├── AccentColor.colorset │ │ │ │ │ └── Contents.json │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ │ ├── ContentView.swift │ │ │ │ ├── Preview Content │ │ │ │ └── Preview Assets.xcassets │ │ │ │ │ └── Contents.json │ │ │ │ └── swiftApp.swift │ │ └── ts │ │ │ ├── .eslintignore │ │ │ ├── .gitignore │ │ │ ├── .vscode │ │ │ └── settings.json │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ └── index.html │ │ │ ├── scripts │ │ │ └── set-schema.js │ │ │ ├── src │ │ │ ├── App.tsx │ │ │ └── index.tsx │ │ │ └── tsconfig.json │ ├── tsconfig.json │ └── typings │ │ └── aws-matchers.d.ts ├── amplify-codegen │ ├── .npmignore │ ├── CHANGELOG.md │ ├── amplify-plugin.json │ ├── awsAppSyncDirectives.graphql │ ├── commands │ │ └── codegen │ │ │ ├── add.js │ │ │ ├── codegen.js │ │ │ ├── configure.js │ │ │ ├── model-introspection.js │ │ │ ├── models.js │ │ │ ├── remove.js │ │ │ ├── statements.js │ │ │ └── types.js │ ├── package.json │ ├── src │ │ ├── amplify-plugin-index.js │ │ ├── callbacks │ │ │ ├── postPushCallback.js │ │ │ ├── prePushAddCallback.js │ │ │ └── prePushUpdateCallback.js │ │ ├── codegen-config │ │ │ ├── AmplifyCodeGenConfig.js │ │ │ ├── index.js │ │ │ └── utils │ │ │ │ ├── graphQlToAmplifyConfig.js │ │ │ │ └── index.js │ │ ├── commands │ │ │ ├── add.js │ │ │ ├── configure.js │ │ │ ├── generateStatementsAndType.js │ │ │ ├── model-intropection.js │ │ │ ├── models.js │ │ │ ├── remove.js │ │ │ ├── statements.js │ │ │ └── types.js │ │ ├── constants.js │ │ ├── errors │ │ │ └── index.js │ │ ├── index.js │ │ ├── utils │ │ │ ├── downloadIntrospectionSchema.js │ │ │ ├── ensureIntrospectionSchema.js │ │ │ ├── generateIntrospectionSchema.js │ │ │ ├── generateIntrospectionSchemaWithProgress.js │ │ │ ├── getAndroidResDir.js │ │ │ ├── getAppSyncAPIDetails.js │ │ │ ├── getAppSyncAPIInfo.js │ │ │ ├── getAppSyncAPIInfoFromProject.js │ │ │ ├── getAppSyncAPIs.js │ │ │ ├── getFrontEndFramework.js │ │ │ ├── getFrontEndHandler.js │ │ │ ├── getGraphQLDocPath.js │ │ │ ├── getIncludePattern.js │ │ │ ├── getModelSchemaPathParam.js │ │ │ ├── getOutputDirParam.js │ │ │ ├── getProjectAWSRegion.js │ │ │ ├── getProjectRoot.js │ │ │ ├── getRelativeTypesPath.js │ │ │ ├── getSDLSchemaLocation.js │ │ │ ├── getSchemaDownloadLocation.js │ │ │ ├── index.js │ │ │ ├── input-params-manager.js │ │ │ ├── isAppSyncApiPendingPush.js │ │ │ ├── isCodegenConfigured.js │ │ │ ├── readSchemaFromFile.js │ │ │ ├── switchToSDLSchema.js │ │ │ ├── updateAmplifyMeta.js │ │ │ ├── validateAmplifyFlutterMinSupportedVersion.js │ │ │ ├── validateAmplifyFlutterVersion.js │ │ │ └── validateDartSDK.js │ │ └── walkthrough │ │ │ ├── add.js │ │ │ ├── changeAppSyncRegions.js │ │ │ ├── configure.js │ │ │ └── questions │ │ │ ├── apiTarget.js │ │ │ ├── changeRegion.js │ │ │ ├── generateCode.js │ │ │ ├── generateDocs.js │ │ │ ├── generatedFileName.js │ │ │ ├── languageTarget.js │ │ │ ├── maxDepth.js │ │ │ ├── queryFilePattern.js │ │ │ ├── selectFramework.js │ │ │ ├── selectFrontend.js │ │ │ ├── selectProject.js │ │ │ ├── selectRegions.js │ │ │ ├── updateCode.js │ │ │ └── updateDocs.js │ └── tests │ │ ├── callbacks │ │ ├── postPushCallback.test.js │ │ ├── prePushAddCallback.test.js │ │ └── prePushUpdateCallback.test.js │ │ ├── cli │ │ └── add.test.js │ │ ├── codegen-config │ │ ├── AmplifyCodegenConfig.test.js │ │ ├── getCodegenConfig.test.js │ │ ├── index.test.js │ │ └── utils │ │ │ └── graphQlToAmplifyConfig.test.js │ │ ├── commands │ │ ├── __snapshots__ │ │ │ ├── add.test.js.snap │ │ │ └── models.test.js.snap │ │ ├── add.test.js │ │ ├── blog-introspection-schema.json │ │ ├── configure.test.js │ │ ├── generateStatementsAndTypes.test.js │ │ ├── mock-fs-setup.js │ │ ├── model-introspection.test.js │ │ ├── models.test.js │ │ ├── statements-mock-fs.test.js │ │ ├── statements.test.js │ │ ├── types-mock-fs.test.js │ │ └── types.test.js │ │ ├── utils │ │ ├── downloadIntrospectionSchema.test.js │ │ ├── getAppSyncAPIDetail.test.js │ │ ├── getAppSyncAPIs.test.js │ │ ├── getFrontendHandler.test.js │ │ ├── getGraphQLDocPath.test.js │ │ ├── getModelSchemaPathParam.test.js │ │ ├── getOutputDirParam.test.js │ │ ├── getProjectRoot.test.js │ │ ├── getRelativeTypesPath.test.js │ │ ├── getSchemaDownloadLocation.test.js │ │ ├── isAppSyncApiPendingPush.test.js │ │ ├── validateAmplifyFlutterMinSupportedVersion.test.js │ │ └── validateDartSDK.test.js │ │ └── walkthrough │ │ ├── add.test.js │ │ ├── configure.test.js │ │ └── questions │ │ ├── apiTarget.test.js │ │ ├── generateCode.test.js │ │ ├── generateDocs.test.js │ │ ├── languageTarget.test.js │ │ ├── queryFilePattern.test.js │ │ ├── selectProject.test.js │ │ └── updateDocs.test.js ├── appsync-modelgen-plugin │ ├── .npmignore │ ├── API.md │ ├── CHANGELOG.md │ ├── package.json │ ├── schemas │ │ └── introspection │ │ │ └── 1 │ │ │ └── ModelIntrospectionSchema.json │ ├── scripts │ │ ├── generateSchemas.ts │ │ └── generateStandaloneValidationFunction.ts │ ├── src │ │ ├── __tests__ │ │ │ ├── utils │ │ │ │ ├── fieldUtils.test.ts │ │ │ │ ├── process-auth.test.ts │ │ │ │ ├── process-connections-v2.test.ts │ │ │ │ ├── process-connections.test.ts │ │ │ │ ├── process-has-many.test.ts │ │ │ │ ├── process-index.test.ts │ │ │ │ ├── process-primary-key.test.ts │ │ │ │ └── validate-java.ts │ │ │ ├── validate.test.ts │ │ │ └── visitors │ │ │ │ ├── __snapshots__ │ │ │ │ ├── appsync-dart-visitor.test.ts.snap │ │ │ │ ├── appsync-java-api-lazyload-css-visitor.test.ts.snap │ │ │ │ ├── appsync-java-visitor.test.ts.snap │ │ │ │ ├── appsync-javascript-visitor.test.ts.snap │ │ │ │ ├── appsync-json-metadata-visitor.test.ts.snap │ │ │ │ ├── appsync-model-introspection-visitor.test.ts.snap │ │ │ │ ├── appsync-swift-visitor.test.ts.snap │ │ │ │ ├── appsync-typescript-visitor.test.ts.snap │ │ │ │ └── appsync-visitor.test.ts.snap │ │ │ │ ├── appsync-dart-visitor.test.ts │ │ │ │ ├── appsync-java-api-lazyload-css-visitor.test.ts │ │ │ │ ├── appsync-java-visitor.test.ts │ │ │ │ ├── appsync-javascript-visitor.test.ts │ │ │ │ ├── appsync-json-metadata-visitor.test.ts │ │ │ │ ├── appsync-model-introspection-visitor.test.ts │ │ │ │ ├── appsync-swift-visitor.test.ts │ │ │ │ ├── appsync-typescript-visitor.test.ts │ │ │ │ ├── appsync-visitor.test.ts │ │ │ │ └── gqlv2-regression-tests │ │ │ │ ├── __snapshots__ │ │ │ │ ├── appsync-dart-visitor.test.ts.snap │ │ │ │ ├── appsync-java-visitor.test.ts.snap │ │ │ │ ├── appsync-javascript-visitor.test.ts.snap │ │ │ │ └── appsync-swift-visitor.test.ts.snap │ │ │ │ ├── appsync-dart-visitor.test.ts │ │ │ │ ├── appsync-java-visitor.test.ts │ │ │ │ ├── appsync-javascript-visitor.test.ts │ │ │ │ └── appsync-swift-visitor.test.ts │ │ ├── configs │ │ │ ├── dart-config.ts │ │ │ ├── java-config.ts │ │ │ └── swift-config.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ └── introspection │ │ │ │ ├── index.ts │ │ │ │ └── model-schema.ts │ │ ├── languages │ │ │ ├── dart-declaration-block.ts │ │ │ ├── java-declaration-block.ts │ │ │ ├── swift-declaration-block.ts │ │ │ └── typescript-declaration-block.ts │ │ ├── plugin.ts │ │ ├── preset.ts │ │ ├── scalars │ │ │ ├── index.ts │ │ │ └── supported-scalars.ts │ │ ├── types │ │ │ └── sync.ts │ │ ├── utils │ │ │ ├── constants.ts │ │ │ ├── fieldUtils.ts │ │ │ ├── generateLicense.ts │ │ │ ├── get-type-info.ts │ │ │ ├── process-auth.ts │ │ │ ├── process-belongs-to.ts │ │ │ ├── process-connections-v2.ts │ │ │ ├── process-connections.ts │ │ │ ├── process-conversation.ts │ │ │ ├── process-has-many.ts │ │ │ ├── process-has-one.ts │ │ │ ├── process-index.ts │ │ │ ├── process-primary-key.ts │ │ │ ├── sort.ts │ │ │ ├── stringUtils.ts │ │ │ ├── validate-field-name.ts │ │ │ └── warn.ts │ │ ├── validate-cjs.js │ │ └── visitors │ │ │ ├── appsync-dart-visitor.ts │ │ │ ├── appsync-java-visitor.ts │ │ │ ├── appsync-javascript-visitor.ts │ │ │ ├── appsync-json-metadata-visitor.ts │ │ │ ├── appsync-model-introspection-visitor.ts │ │ │ ├── appsync-swift-visitor.ts │ │ │ ├── appsync-typescript-visitor.ts │ │ │ └── appsync-visitor.ts │ └── tsconfig.json ├── graphql-docs-generator │ ├── .gitignore │ ├── .npmignore │ ├── API.md │ ├── CHANGELOG.md │ ├── README.md │ ├── __integration__ │ │ ├── __snapshots__ │ │ │ └── e2e.test.ts.snap │ │ └── e2e.test.ts │ ├── __tests__ │ │ └── generator │ │ │ ├── generate.test.ts │ │ │ ├── generateAllOperations.test.ts │ │ │ ├── generateOperation.test.ts │ │ │ ├── getArgs.test.ts │ │ │ ├── getBody.test.ts │ │ │ ├── getFields.test.ts │ │ │ ├── getFragments.test.ts │ │ │ └── utils │ │ │ ├── getSchemaType.test.ts │ │ │ ├── getType.test.ts │ │ │ └── isRequired.test.ts │ ├── bin │ │ └── cli │ ├── fixtures │ │ ├── caseTypes.graphql │ │ ├── complex-obj.gql │ │ ├── complex-obj.json │ │ ├── foo.gql │ │ ├── foo.json │ │ ├── fragments.graphql │ │ ├── heroQuery.graphql │ │ ├── mutations.graphql │ │ ├── queries.graphql │ │ ├── schema.graphql │ │ ├── schema.json │ │ └── subscriptions.graphql │ ├── package.json │ ├── src │ │ ├── cli.ts │ │ ├── generator │ │ │ ├── generate.ts │ │ │ ├── generateAllOperations.ts │ │ │ ├── generateOperation.ts │ │ │ ├── getArgs.ts │ │ │ ├── getBody.ts │ │ │ ├── getFields.ts │ │ │ ├── getFragment.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── utils │ │ │ │ ├── getSchemaType.ts │ │ │ │ ├── getType.ts │ │ │ │ ├── isList.ts │ │ │ │ ├── isRequired.ts │ │ │ │ ├── isRequiredList.ts │ │ │ │ ├── isS3Object.ts │ │ │ │ ├── loading.ts │ │ │ │ └── templates.ts │ │ ├── index.ts │ │ └── logger.ts │ ├── test-operations.graphql │ ├── test.graphql │ └── tsconfig.json ├── graphql-generator │ ├── .npmignore │ ├── API.md │ ├── CHANGELOG.md │ ├── package.json │ ├── scripts │ │ └── check-codegen-version.sh │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ ├── models.test.ts.snap │ │ │ │ ├── statements.test.ts.snap │ │ │ │ └── types.test.ts.snap │ │ │ ├── models.test.ts │ │ │ ├── profiler.test.ts │ │ │ ├── schemas │ │ │ │ ├── blog-introspection.json │ │ │ │ ├── blog-model.graphql │ │ │ │ └── blog-sdl.graphql │ │ │ ├── statements.test.ts │ │ │ ├── types.test.ts │ │ │ ├── utils.ts │ │ │ └── utils │ │ │ │ ├── GraphQLStatementsFormatter.test.ts │ │ │ │ ├── __snapshots__ │ │ │ │ ├── GraphQLStatementsFormatter.test.ts.snap │ │ │ │ └── maps.test.ts.snap │ │ │ │ └── maps.test.ts │ │ ├── index.ts │ │ ├── models.ts │ │ ├── profiler.ts │ │ ├── statements.ts │ │ ├── types.ts │ │ ├── typescript.ts │ │ ├── utils │ │ │ ├── GraphQLStatementsFormatter.ts │ │ │ ├── index.ts │ │ │ └── maps.ts │ │ └── vendor │ │ │ └── @graphql-codegen │ │ │ └── core │ │ │ ├── LICENSE │ │ │ ├── MAINTENANCE.md │ │ │ ├── README.md │ │ │ ├── VERSION │ │ │ ├── codegen.ts │ │ │ ├── execute-plugin.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ └── tsconfig.json └── graphql-types-generator │ ├── .npmignore │ ├── API.md │ ├── CHANGELOG.md │ ├── awsAppSyncDirectives.graphql │ ├── fixtures │ ├── .eslintrc.js │ ├── angular.ts │ ├── complex-obj.json │ ├── output.ts │ ├── starwars-schema.json │ ├── starwars.service.ts │ ├── statements.js │ ├── test.json │ ├── test.ts │ ├── todo-schema.json │ ├── todo-statements.js │ └── todo.service.ts │ ├── package.json │ ├── src │ ├── angular │ │ └── index.ts │ ├── cli.js │ ├── compiler │ │ ├── index.ts │ │ ├── legacyIR.ts │ │ └── visitors │ │ │ ├── collectAndMergeFields.ts │ │ │ ├── collectFragmentsReferenced.ts │ │ │ ├── generateOperationId.ts │ │ │ ├── inlineRedundantTypeConditions.ts │ │ │ └── typeCase.ts │ ├── errors.ts │ ├── flow-modern │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── codeGeneration.ts.snap │ │ │ ├── codeGeneration.ts │ │ │ └── helpers.ts │ │ ├── codeGeneration.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── language.ts │ │ ├── printer.ts │ │ └── types │ │ │ ├── augment-babel-types.ts │ │ │ └── babel7.ts │ ├── flow │ │ ├── codeGeneration.js │ │ ├── index.js │ │ ├── language.js │ │ └── types.js │ ├── generate.ts │ ├── index.ts │ ├── loading.ts │ ├── polyfills.js │ ├── scala │ │ ├── codeGeneration.js │ │ ├── index.js │ │ ├── language.js │ │ ├── naming.js │ │ ├── types.js │ │ └── values.js │ ├── serializeToJSON.ts │ ├── swift │ │ ├── appSyncCompatibilityTypes.ts │ │ ├── aws-scalar-helper.ts │ │ ├── codeGeneration.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── language.ts │ │ └── s3Wrapper.ts │ ├── types.ts │ ├── typescript │ │ ├── codeGeneration.ts │ │ ├── index.ts │ │ ├── language.ts │ │ └── types.ts │ ├── utilities │ │ ├── CodeGenerator.ts │ │ ├── array.ts │ │ ├── complextypes.ts │ │ ├── getOutputFileName.ts │ │ ├── graphql.ts │ │ └── printing.ts │ └── validation.ts │ ├── test │ ├── __snapshots__ │ │ └── jsonOutput.ts.snap │ ├── angular │ │ ├── __snapshots__ │ │ │ ├── angularv6.ts.snap │ │ │ └── index.js.snap │ │ ├── angularv6.ts │ │ └── index.js │ ├── compiler │ │ ├── legacyIR.js │ │ └── visitors │ │ │ ├── conditionalFields.ts │ │ │ ├── generateOperationId.ts │ │ │ └── typeCase.ts │ ├── complexTypes.ts │ ├── fixtures │ │ ├── misc │ │ │ ├── invalid-gqlQueries.js │ │ │ ├── queryWithScalarAndEnumType.graphql │ │ │ ├── schema.graphql │ │ │ ├── schema.json │ │ │ ├── subscriptionSchema.graphql │ │ │ ├── subscriptionSchema.json │ │ │ └── subscriptionSchemaWithParameters.graphql │ │ └── starwars │ │ │ ├── AnonymousQuery.graphql │ │ │ ├── ExplicitTypename.graphql │ │ │ ├── HeroAndFriends.graphql │ │ │ ├── HeroAndFriendsNames.graphql │ │ │ ├── HeroAppearsIn.graphql │ │ │ ├── HeroName.graphql │ │ │ ├── TwoHeroes.graphql │ │ │ ├── TypenameAlias.graphql │ │ │ ├── gqlQueries.js │ │ │ ├── schema.graphql │ │ │ └── schema.json │ ├── flow │ │ ├── __snapshots__ │ │ │ └── codeGeneration.js.snap │ │ └── codeGeneration.js │ ├── jsonOutput.ts │ ├── loading.ts │ ├── scala │ │ ├── __snapshots__ │ │ │ ├── codeGeneration.js.snap │ │ │ └── language.js.snap │ │ ├── codeGeneration.js │ │ ├── language.js │ │ └── types.js │ ├── swift │ │ ├── __snapshots__ │ │ │ ├── codeGeneration.ts.snap │ │ │ └── language.ts.snap │ │ ├── codeGeneration.ts │ │ ├── language.ts │ │ └── typeNameFromGraphQLType.ts │ ├── test-utils │ │ ├── helpers.ts │ │ └── matchers.ts │ ├── typescript │ │ ├── __snapshots__ │ │ │ └── codeGeneration.js.snap │ │ └── codeGeneration.js │ ├── utilities │ │ └── getOutputFileName.test.ts │ ├── validation.ts │ └── valueFromValueNode.ts │ └── tsconfig.json ├── scripts ├── api-extractor.json ├── cloud-release.sh ├── cloud-utils.sh ├── components │ ├── dist_tag_mover.ts │ ├── git_client.ts │ ├── npm_client.ts │ ├── release_deprecator.ts │ └── release_tag_to_name_and_version.ts ├── create-private-package-manifest.sh ├── deprecate_release.ts ├── e2e-test-regions.json ├── extract-api.ts ├── extract-dependency-licenses.sh ├── sample.env ├── split-canary-tests.ts ├── split-e2e-tests.ts ├── test-swift-modelgen.sh ├── test-timings.data.json ├── verify-dependency-licenses.sh ├── verify-extract-api.sh ├── view-test-artifacts.sh └── view-test-artifacts.ts ├── shared-scripts.sh ├── tsconfig.base.json └── yarn.lock /.codebuild/build_linux.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _buildLinux 8 | artifacts: 9 | files: 10 | - 'shared-scripts.sh' -------------------------------------------------------------------------------- /.codebuild/build_windows.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: powershell.exe 4 | phases: 5 | build: 6 | commands: 7 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 8 | - bash ./.codebuild/scripts/build_windows.sh 9 | artifacts: 10 | files: 11 | - 'shared-scripts.sh' 12 | -------------------------------------------------------------------------------- /.codebuild/canary_workflow_base.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | compute-type: BUILD_GENERAL1_LARGE 5 | batch: 6 | fast-fail: false 7 | build-graph: 8 | - identifier: build_linux 9 | buildspec: .codebuild/build_linux.yml 10 | env: 11 | compute-type: BUILD_GENERAL1_LARGE 12 | - identifier: test 13 | buildspec: .codebuild/test.yml 14 | env: 15 | compute-type: BUILD_GENERAL1_LARGE 16 | depend-on: 17 | - build_linux 18 | - identifier: publish_to_local_registry 19 | buildspec: .codebuild/publish_to_local_registry.yml 20 | env: 21 | compute-type: BUILD_GENERAL1_MEDIUM 22 | depend-on: 23 | - build_linux 24 | -------------------------------------------------------------------------------- /.codebuild/cleanup_e2e_resources.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | CI: true 6 | CODEBUILD: true 7 | 8 | phases: 9 | build: 10 | commands: 11 | - source ./shared-scripts.sh && _cleanupE2EResources 12 | artifacts: 13 | files: 14 | - '**/*' 15 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports -------------------------------------------------------------------------------- /.codebuild/cleanup_workflow.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | CI: true 6 | CODEBUILD: true 7 | 8 | phases: 9 | build: 10 | commands: 11 | - yarn production-build 12 | - cd packages/amplify-codegen-e2e-tests && yarn clean-e2e-resources 13 | artifacts: 14 | files: 15 | - '**/*' 16 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports -------------------------------------------------------------------------------- /.codebuild/deploy.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | git-credential-helper: yes 5 | phases: 6 | build: 7 | commands: 8 | - source ./shared-scripts.sh && _deploy 9 | -------------------------------------------------------------------------------- /.codebuild/deprecate.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | git-credential-helper: yes 5 | phases: 6 | build: 7 | commands: 8 | - source ./shared-scripts.sh && _deprecate 9 | -------------------------------------------------------------------------------- /.codebuild/deprecate_workflow.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | compute-type: BUILD_GENERAL1_SMALL 5 | 6 | batch: 7 | fast-fail: false 8 | build-graph: 9 | - identifier: install_linux 10 | buildspec: .codebuild/install_linux.yml 11 | - identifier: deprecate 12 | buildspec: .codebuild/deprecate.yml 13 | depend-on: 14 | - install_linux 15 | -------------------------------------------------------------------------------- /.codebuild/install_linux.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _installLinux 8 | artifacts: 9 | files: 10 | - 'shared-scripts.sh' 11 | -------------------------------------------------------------------------------- /.codebuild/lint.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _lint -------------------------------------------------------------------------------- /.codebuild/publish_to_local_registry.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _publishToLocalRegistry 8 | 9 | artifacts: 10 | files: 11 | - 'shared-scripts.sh' -------------------------------------------------------------------------------- /.codebuild/run_canary_e2e_tests.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin 6 | AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify 7 | CI: true 8 | CODEBUILD: true 9 | NODE_OPTIONS: --max-old-space-size=8096 10 | 11 | phases: 12 | build: 13 | commands: 14 | - source ./shared-scripts.sh && _setupE2ETestsLinux 15 | - codebuild-breakpoint 16 | - source ./shared-scripts.sh && _runE2ETestsLinux 17 | post_build: 18 | commands: 19 | - source ./shared-scripts.sh && _unassumeTestAccountCredentials 20 | - aws sts get-caller-identity 21 | - source ./shared-scripts.sh && _scanArtifacts && _emitCodegenCanaryMetric 22 | 23 | artifacts: 24 | files: 25 | - '**/*' 26 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports -------------------------------------------------------------------------------- /.codebuild/run_e2e_tests.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin 6 | AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify 7 | CI: true 8 | CODEBUILD: true 9 | NODE_OPTIONS: --max-old-space-size=8096 10 | 11 | phases: 12 | build: 13 | commands: 14 | - source ./shared-scripts.sh && _setupE2ETestsLinux 15 | - codebuild-breakpoint 16 | - source ./shared-scripts.sh && _runE2ETestsLinux 17 | post_build: 18 | commands: 19 | - source ./shared-scripts.sh && _unassumeTestAccountCredentials 20 | - aws sts get-caller-identity 21 | - source ./shared-scripts.sh && _scanArtifacts 22 | 23 | artifacts: 24 | files: 25 | - '**/*' 26 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports -------------------------------------------------------------------------------- /.codebuild/run_e2e_tests_windows.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: powershell.exe 4 | variables: 5 | AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin 6 | AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify 7 | CI: true 8 | CODEBUILD: true 9 | NODE_OPTIONS: --max-old-space-size=8096 10 | SKIP_SET_NPM_PREFIX: true 11 | phases: 12 | build: 13 | commands: 14 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 15 | - bash ./.codebuild/scripts/e2e_test_windows.sh 16 | post_build: 17 | commands: 18 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 19 | - bash ./.codebuild/scripts/post_e2e_test.sh 20 | 21 | artifacts: 22 | files: 23 | - '**/*' 24 | base-directory: $Env:CODEBUILD_SRC_DIR\packages\amplify-codegen-e2e-tests\amplify-e2e-reports 25 | -------------------------------------------------------------------------------- /.codebuild/run_gen2_e2e_test.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | CI: true 6 | CODEBUILD: true 7 | NODE_OPTIONS: --max-old-space-size=8096 8 | 9 | phases: 10 | build: 11 | commands: 12 | - source ./shared-scripts.sh && _setupGen2E2ETestsLinux 13 | - source ./shared-scripts.sh && _runGen2E2ETestsLinux 14 | post_build: 15 | commands: 16 | - source ./shared-scripts.sh && _unassumeTestAccountCredentials 17 | - aws sts get-caller-identity 18 | - source ./shared-scripts.sh && _scanArtifacts 19 | 20 | artifacts: 21 | files: 22 | - '**/*' 23 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports 24 | -------------------------------------------------------------------------------- /.codebuild/run_gen2_e2e_test_windows.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: powershell.exe 4 | variables: 5 | CI: true 6 | CODEBUILD: true 7 | NODE_OPTIONS: --max-old-space-size=8096 8 | phases: 9 | build: 10 | commands: 11 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 12 | - bash ./.codebuild/scripts/gen2_e2e_test_windows.sh 13 | post_build: 14 | commands: 15 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 16 | - bash ./.codebuild/scripts/post_e2e_test.sh 17 | 18 | artifacts: 19 | files: 20 | - '**/*' 21 | base-directory: $Env:CODEBUILD_SRC_DIR\packages\amplify-codegen-e2e-tests\amplify-e2e-reports 22 | -------------------------------------------------------------------------------- /.codebuild/run_regionalized_ts_modelgen_e2e_test.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin 6 | AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify 7 | CI: true 8 | CODEBUILD: true 9 | NODE_OPTIONS: --max-old-space-size=8096 10 | 11 | phases: 12 | build: 13 | commands: 14 | - source ./shared-scripts.sh && _setupE2ETestsLinux 15 | - codebuild-breakpoint 16 | - source ./shared-scripts.sh && _runE2ETestsLinux 17 | post_build: 18 | commands: 19 | - source ./shared-scripts.sh && _unassumeTestAccountCredentials 20 | - aws sts get-caller-identity 21 | - source ./shared-scripts.sh && _scanArtifacts && _emitRegionalizedCanaryMetric 22 | 23 | artifacts: 24 | files: 25 | - '**/*' 26 | base-directory: $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports -------------------------------------------------------------------------------- /.codebuild/scripts/build_windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | source ./shared-scripts.sh && _buildWindows 7 | -------------------------------------------------------------------------------- /.codebuild/scripts/e2e_test_windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | source ./shared-scripts.sh && _setupE2ETestsWindows 7 | codebuild-breakpoint 8 | source ./shared-scripts.sh && _runE2ETestsWindows 9 | -------------------------------------------------------------------------------- /.codebuild/scripts/gen2_e2e_test_windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | source ./shared-scripts.sh && _setupGen2E2ETestsWindows 7 | codebuild-breakpoint 8 | source ./shared-scripts.sh && _runGen2E2ETestsWindows 9 | -------------------------------------------------------------------------------- /.codebuild/scripts/lint_pr.sh: -------------------------------------------------------------------------------- 1 | set -xeo pipefail 2 | # extract the PR number from the PR link 3 | PR_NUM=${CODEBUILD_WEBHOOK_TRIGGER##*/} 4 | PROJECT_USERNAME=aws-amplify 5 | REPO_NAME=amplify-codegen 6 | 7 | if [ -z "$PR_NUM" ]; then 8 | echo "Could not determine PR number. Cannot determine fork point for linting. Skipping linting." 9 | exit 10 | fi 11 | 12 | # get PR file list, filter out removed files, filter only JS/TS files, then pass to the linter 13 | curl -fsSL https://api.github.com/repos/$PROJECT_USERNAME/$REPO_NAME/pulls/$PR_NUM/files | jq -r '.[] | select(.status!="removed") | .filename' | (grep -E '\.(js|jsx|ts|tsx)$' || true) | xargs yarn eslint --quiet 14 | set +x 15 | -------------------------------------------------------------------------------- /.codebuild/scripts/post_e2e_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | source ./shared-scripts.sh && _unassumeTestAccountCredentials 7 | aws sts get-caller-identity 8 | source ./shared-scripts.sh && _scanArtifacts 9 | -------------------------------------------------------------------------------- /.codebuild/scripts/test_windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | source ./shared-scripts.sh && _testWindows 7 | -------------------------------------------------------------------------------- /.codebuild/test.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | variables: 5 | NODE_OPTIONS: --max-old-space-size=8192 6 | phases: 7 | build: 8 | commands: 9 | - source ./shared-scripts.sh && _testLinux 10 | artifacts: 11 | files: 12 | - 'shared-scripts.sh' 13 | reports: 14 | coverage-report: 15 | files: 16 | - 'packages/*/coverage/clover.xml' 17 | file-format: 'CLOVERXML' 18 | -------------------------------------------------------------------------------- /.codebuild/test_windows.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: powershell.exe 4 | phases: 5 | build: 6 | commands: 7 | # commands need to be run in stand-alone bash scripts so that bash can be used on windows 8 | - bash ./.codebuild/scripts/test_windows.sh 9 | artifacts: 10 | files: 11 | - 'shared-scripts.sh' 12 | -------------------------------------------------------------------------------- /.codebuild/verify_api_extract.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _verifyAPIExtract -------------------------------------------------------------------------------- /.codebuild/verify_dependency_licenses_extract.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | shell: bash 4 | phases: 5 | build: 6 | commands: 7 | - source ./shared-scripts.sh && _verifyDependencyLicensesExtract -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | trim_trailing_spaces = true 9 | insert_final_newline = true 10 | max_line_length = 140 11 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Data team has general approval permissions 2 | * @aws-amplify/amplify-data 3 | 4 | # API approval - public surface and dependencies. 5 | **/API.md @aws-amplify/amplify-data-admins 6 | 7 | # Vendor code changes 8 | packages/**/vendor/** @aws-amplify/amplify-data-admins 9 | 10 | # Dependency Licensing approval 11 | dependency_licenses.txt @aws-amplify/amplify-data-admins 12 | 13 | # Changes to CI/CD scripts/buildspecs need admin approval 14 | /scripts/ @aws-amplify/amplify-data-admins 15 | /shared-scripts.sh @aws-amplify/amplify-data-admins 16 | /.codebuild/ @aws-amplify/amplify-data-admins 17 | /.codebuild/e2e_workflow.yml @aws-amplify/amplify-data 18 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | 3 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 4 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 5 | opensource-codeofconduct@amazon.com with any additional questions or comments. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: I want help writing my Amplify application 4 | url: https://discord.com/invite/amplify 5 | about: Check out the `*-help` channels on Amplify's community Discord to ask your questions about building applications with the CLI or other Amplify libraries. 6 | -------------------------------------------------------------------------------- /.github/workflows/build-swift-modelgen.yml: -------------------------------------------------------------------------------- 1 | name: 'Test compiling Swift Modelgen output' 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | MODELS_S3_URL: 7 | description: 'S3 URL for models' 8 | required: true 9 | 10 | env: 11 | MODELS_S3_URL: ${{ inputs.MODELS_S3_URL }} 12 | 13 | jobs: 14 | Build-Swift-Modelgen: 15 | name: Build 16 | runs-on: macos-13-xlarge 17 | permissions: 18 | actions: read 19 | contents: read 20 | 21 | strategy: 22 | fail-fast: true 23 | 24 | steps: 25 | - name: Mask S3 URL 26 | run: echo "::add-mask::$MODELS_S3_URL" 27 | 28 | - name: Checkout repository 29 | uses: actions/checkout@v3 30 | 31 | - name: Check Xcode and Swift versions 32 | run: | 33 | xcodebuild -version 34 | swift --version 35 | 36 | - name: Build Swift Models 37 | run: ./scripts/test-swift-modelgen.sh 38 | -------------------------------------------------------------------------------- /.github/workflows/closed-issue-message.yml: -------------------------------------------------------------------------------- 1 | name: Closed Issue Message 2 | on: 3 | issues: 4 | types: [closed] 5 | jobs: 6 | auto_comment: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: aws-actions/closed-issue-message@v1 10 | with: 11 | # These inputs are both required 12 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 13 | message: | 14 | This issue is now closed. Comments on closed issues are hard for our team to see. 15 | If you need more assistance, please open a new issue that references this one. 16 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | analyze: 9 | name: Analyze 10 | runs-on: ubuntu-latest 11 | permissions: 12 | actions: read 13 | contents: read 14 | security-events: write 15 | 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | language: [ 'javascript' ] 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v3 24 | with: 25 | # Minimal depth 2 so we can checkout the commit before possible merge commit. 26 | fetch-depth: 2 27 | 28 | - name: Initialize CodeQL 29 | uses: github/codeql-action/init@v2 30 | with: 31 | languages: ${{ matrix.language }} 32 | 33 | - name: Autobuild 34 | uses: github/codeql-action/autobuild@v2 35 | 36 | - name: Perform CodeQL Analysis 37 | uses: github/codeql-action/analyze@v2 38 | with: 39 | category: "/language:${{ matrix.language }}" 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | node_modules 3 | lerna-debug.log 4 | npm-debug.log 5 | yarn-error.log 6 | coverage 7 | .nyc_output 8 | .env 9 | package-lock.json 10 | .vscode/* 11 | !.vscode/settings.json 12 | !.vscode/extensions.json 13 | packages/graphql-generator/lib 14 | packages/appsync-modelgen-plugin/lib 15 | packages/graphql-docs-generator/lib 16 | packages/graphql-types-generator/lib 17 | packages/amplify-codegen-e2e-core/lib 18 | packages/amplify-codegen-e2e-tests/lib 19 | packages/amplify-codegen-e2e-tests/amplify-e2e-reports/ 20 | packages/amplify-codegen-e2e-tests/src/__tests__/amplify-e2e-reports/ 21 | packages/*/node_modules 22 | packages/*/package-lock.json 23 | **/.env 24 | !packages/amplify-codegen-e2e-tests/projects-templates/create-react-app-auth-amplify/.env 25 | packages/**/reports/junit/* 26 | test.out.log 27 | *.tsbuildinfo 28 | package-lock.json 29 | .idea 30 | scripts/.env 31 | .codebuild/debug_workflow.yml 32 | .npmrc 33 | verdaccio-logs.txt 34 | scripts/components/private_packages.ts 35 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # un-ignore that, so it gets included. 2 | !./packages/*/package.json 3 | !./packages/amplify-codegen/package.json 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/dist 3 | **/package.json 4 | **/yarn.lock 5 | **/package-lock.json 6 | **/.eslintrc.js 7 | **/tsconfig.json 8 | packages/*/CHANGELOG.md 9 | scripts/components/private_packages.ts 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "printWidth": 140, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "useTabs": false, 9 | "arrowParens": "avoid", 10 | "jsxSingleQuote": true, 11 | "trailingComma": "all" 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "Orta.vscode-jest"] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.rulers": [140], 3 | "files.exclude": { 4 | "**/.git": true, 5 | "**/node_modules": true, 6 | "**/build": true, 7 | "**/coverage": true 8 | }, 9 | "editor.formatOnSave": false, 10 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], 11 | "eslint.alwaysShowStatus": true, 12 | "eslint.format.enable": true, 13 | "eslint.lintTask.enable": true, 14 | "eslint.packageManager": "yarn", 15 | "eslint.quiet": true, 16 | "editor.codeActionsOnSave": { 17 | "source.fixAll.eslint": "explicit" 18 | }, 19 | "jest.enableInlineErrorMessages": true, 20 | "jest.showCoverageOnLoad": true, 21 | "jest.runAllTestsFirst": false 22 | } 23 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-lerna-scopes', '@commitlint/config-conventional'], 3 | }; 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | bail: false, 4 | verbose: true, 5 | testRunner: 'jest-circus/runner', 6 | testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'], 7 | testPathIgnorePatterns: [ 8 | '**/*.d.ts', 9 | '**/__e2e__/', 10 | '**/__integration__/' 11 | ], 12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'core', 'node'], 13 | collectCoverage: true, 14 | collectCoverageFrom: ['src/**/.(ts|tsx|js|jsx)$', '!src/**/*.test.(ts|tsx|js|jsx)$', '!src/**/*.d.ts'], 15 | coverageDirectory: 'coverage', 16 | projects: [ 17 | '/packages/appsync-modelgen-plugin', 18 | '/packages/graphql-docs-generator', 19 | '/packages/graphql-types-generator' 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "3.22.1", 3 | "packages": ["packages/*"], 4 | "version": "independent", 5 | "npmClient": "yarn", 6 | "useWorkspaces": true 7 | } 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/Readme.md: -------------------------------------------------------------------------------- 1 | # Amplify Codegen E2E core 2 | 3 | This package contains the code shared between end to end test packages. -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/environment.js: -------------------------------------------------------------------------------- 1 | // Allow people to use `amplify-codegen-e2e-core/environment` as a runner. 2 | const environment = require('./lib/cli-test-environment'); 3 | module.exports = environment; 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/reporter.js: -------------------------------------------------------------------------------- 1 | // Allow people to use `amplify-codegen-e2e-core/environment` as a runner. 2 | const reporter = require('./lib/nexpect-reporter'); 3 | module.exports = reporter; 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/runner.js: -------------------------------------------------------------------------------- 1 | // Allow people to use `amplify-codegen-e2e-core/runner` as a runner. 2 | const runner = require('./lib/cli-test-runner'); 3 | module.exports = runner; 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/categories/index.ts: -------------------------------------------------------------------------------- 1 | export * from './analytics'; 2 | export * from './api'; 3 | export * from './auth'; 4 | export * from './codegen'; 5 | export * from './hosting'; 6 | export * from './interactions'; 7 | export * from './lambda-function'; 8 | export * from './lambda-layer'; 9 | export * from './notifications'; 10 | export * from './predictions'; 11 | export * from './storage'; 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/categories/interactions.ts: -------------------------------------------------------------------------------- 1 | import { nspawn as spawn, getCLIPath } from '..'; 2 | 3 | export function addSampleInteraction(cwd: string, settings: any): Promise { 4 | return new Promise((resolve, reject) => { 5 | spawn(getCLIPath(), ['add', 'interactions'], { cwd, stripColors: true }) 6 | .wait('Provide a friendly resource name that will be used to label this category') 7 | .sendCarriageReturn() 8 | .wait('Would you like to start with a sample chatbot') 9 | .sendCarriageReturn() 10 | .wait('Choose a sample chatbot:') 11 | .sendCarriageReturn() 12 | .wait("Please indicate if your use of this bot is subject to the Children's") 13 | .sendLine('y') 14 | .sendEof() 15 | .run((err: Error) => { 16 | if (!err) { 17 | resolve(); 18 | } else { 19 | reject(err); 20 | } 21 | }); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/categories/notifications.ts: -------------------------------------------------------------------------------- 1 | import { nspawn as spawn, getCLIPath, singleSelect } from '..'; 2 | 3 | export type NotificationSettings = { 4 | resourceName: string; 5 | }; 6 | 7 | export const addSMSNotification = async (cwd: string, settings: NotificationSettings): Promise => { 8 | return new Promise((resolve, reject) => { 9 | let chain = spawn(getCLIPath(), ['add', 'notification'], { cwd, stripColors: true }); 10 | 11 | singleSelect(chain.wait('Choose the push notification channel to enable'), 'SMS', ['APNS', 'FCM', 'Email', 'SMS']); 12 | 13 | chain 14 | .wait('Provide your pinpoint resource name') 15 | .sendLine(settings.resourceName) 16 | .wait('The SMS channel has been successfully enabled') 17 | .sendEof() 18 | .run((err: Error) => { 19 | if (!err) { 20 | resolve(undefined); 21 | } else { 22 | reject(err); 23 | } 24 | }); 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/cli-test-runner.js: -------------------------------------------------------------------------------- 1 | const circusRunner = require('jest-circus/runner'); 2 | const throat = require('throat'); 3 | const uuid = require('uuid'); 4 | 5 | const mutex = throat(1); 6 | export const run = async (globalConfig, config, environment, runtime, testPath) => { 7 | const CLITestRunner = {}; 8 | environment.global.addCLITestRunnerLogs = logs => { 9 | CLITestRunner.logs = logs; 10 | }; 11 | 12 | environment.global.getRandomId = () => mutex(() => uuid.v4().split('-')[0]); 13 | const result = await circusRunner(globalConfig, config, environment, runtime, testPath); 14 | result.CLITestRunner = CLITestRunner; 15 | return result; 16 | }; 17 | 18 | module.exports = run; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/init/deleteProject.ts: -------------------------------------------------------------------------------- 1 | import { nspawn as spawn, retry, getCLIPath, describeCloudFormationStack, getProjectMeta } from '..'; 2 | 3 | export const deleteProject = async (cwd: string, profileConfig?: any): Promise => { 4 | const { StackName: stackName, Region: region } = getProjectMeta(cwd).providers.awscloudformation; 5 | await retry( 6 | () => describeCloudFormationStack(stackName, region, profileConfig), 7 | stack => stack.StackStatus.endsWith('_COMPLETE'), 8 | ); 9 | return new Promise((resolve, reject) => { 10 | const noOutputTimeout = 1000 * 60 * 20; // 20 minutes; 11 | spawn(getCLIPath(), ['delete'], { cwd, stripColors: true, noOutputTimeout }) 12 | .wait('Are you sure you want to continue?') 13 | .sendLine('y') 14 | .wait('Project deleted locally.') 15 | .run((err: Error) => { 16 | if (!err) { 17 | resolve(); 18 | } else { 19 | reject(err); 20 | } 21 | }); 22 | }); 23 | }; 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/init/index.ts: -------------------------------------------------------------------------------- 1 | export * from './amplifyPull'; 2 | export * from './amplifyPush'; 3 | export * from './deleteProject'; 4 | export * from './initProjectHelper'; 5 | export * from './pull-headless'; 6 | export * from './adminUI'; 7 | export * from './cra'; 8 | export * from './swift'; 9 | export * from './android'; 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/init/swift.ts: -------------------------------------------------------------------------------- 1 | /* commands for an XCode Swift App */ 2 | import { nspawn as spawn } from '..'; 3 | 4 | const defaultSettings = { 5 | scheme: undefined, 6 | target: undefined, 7 | project: undefined, 8 | disableCIDetection: false, 9 | }; 10 | 11 | export function swiftBuild(cwd: string, settings: Object = {}): Promise { 12 | return new Promise((resolve, reject) => { 13 | const s = { ...defaultSettings, ...settings }; 14 | 15 | const args = ['build']; 16 | if (s.scheme) args.push('-scheme', s.scheme); 17 | if (s.target) args.push('-target', s.target); 18 | if (s.project) args.push('-project', s.project); 19 | const chain = spawn('xcodebuild', args, { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); 20 | 21 | chain.run((err: Error) => { 22 | if (err) { 23 | reject(err); 24 | } else { 25 | resolve(); 26 | } 27 | }); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/admin-ui.ts: -------------------------------------------------------------------------------- 1 | import * as https from 'https'; 2 | import * as url from 'url'; 3 | const uri = 'https://e7auv6no3g.execute-api.us-east-1.amazonaws.com/wave3Prod/AppState'; 4 | 5 | export async function getAdminApp(body: any): Promise { 6 | const adminUiUrl = url.parse(uri); 7 | return new Promise((resolve, reject) => { 8 | let str = ''; 9 | const req = https.request( 10 | { 11 | hostname: adminUiUrl.hostname, 12 | port: adminUiUrl.port, 13 | path: adminUiUrl.path, 14 | method: 'POST', 15 | }, 16 | res => { 17 | res.on('data', chunk => { 18 | str += chunk; 19 | }); 20 | res.on('end', () => { 21 | resolve(str); 22 | }); 23 | }, 24 | ); 25 | req.on('error', err => { 26 | reject(err); 27 | }); 28 | req.write(JSON.stringify(body)); 29 | req.end(); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/api.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as fs from 'fs-extra'; 3 | import { TRANSFORM_CONFIG_FILE_NAME } from 'graphql-transformer-core'; 4 | 5 | export function updateSchema(projectDir: string, projectName: string, schemaText: string) { 6 | const schemaPath = path.join(projectDir, 'amplify', 'backend', 'api', projectName, 'schema.graphql'); 7 | fs.writeFileSync(schemaPath, schemaText); 8 | } 9 | 10 | export function updateConfig(projectDir: string, projectName: string, config: any = {}) { 11 | const configPath = path.join(projectDir, 'amplify', 'backend', 'api', projectName, TRANSFORM_CONFIG_FILE_NAME); 12 | fs.writeFileSync(configPath, JSON.stringify(config, null, 4)); 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/appsync.ts: -------------------------------------------------------------------------------- 1 | import url from 'url'; 2 | import path from 'path'; 3 | import fs from 'fs-extra'; 4 | import { post } from '../utils/request'; 5 | 6 | export async function appsyncGraphQLRequest(resource: { [id: string]: any }, op: { query: string; variables: string | null }) { 7 | const postData = JSON.stringify(op); 8 | const target = url.parse(resource.output.GraphQLAPIEndpointOutput); 9 | return await post({ 10 | body: postData, 11 | hostname: target.host, 12 | path: target.path, 13 | headers: { 14 | 'Content-Type': 'application/x-www-form-urlencoded', 15 | 'Content-Length': postData.length, 16 | 'X-Api-Key': resource.output.GraphQLAPIKeyOutput, 17 | }, 18 | }); 19 | } 20 | 21 | export const getProjectSchema = (projRoot: string, apiName: string) => { 22 | const schemaFilePath = path.join(projRoot, 'amplify', 'backend', 'api', apiName, 'schema.graphql'); 23 | return fs.readFileSync(schemaFilePath, 'utf8'); 24 | }; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/getAppId.ts: -------------------------------------------------------------------------------- 1 | import { getBackendAmplifyMeta } from './projectMeta'; 2 | 3 | export function getAppId(projRoot: string): string { 4 | const meta = getBackendAmplifyMeta(projRoot); 5 | return meta.providers.awscloudformation.AmplifyAppId; 6 | } 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/getCommandPath.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | /* Get the full absolute path of a command with `which` 3 | * 4 | * Windows executors on CB fail to spawn a command with custom nexpect unless the full path is used. 5 | */ 6 | export function getCommandPath(command: string): string { 7 | return execSync(`which ${command}`) 8 | .toString() 9 | .trim(); 10 | } 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/isWindows.ts: -------------------------------------------------------------------------------- 1 | import os from 'os'; 2 | 3 | export function isWindows(): boolean { 4 | return os.platform() === 'win32' 5 | } 6 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/readJsonFile.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | 3 | function stripBOM(content: string) { 4 | if (content.charCodeAt(0) === 0xfeff) { 5 | content = content.slice(1); 6 | } 7 | return content; 8 | } 9 | 10 | export function readJsonFile(jsonFilePath, encoding: BufferEncoding = 'utf8') { 11 | return JSON.parse(stripBOM(fs.readFileSync(jsonFilePath, encoding))); 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/request.ts: -------------------------------------------------------------------------------- 1 | const https = require('https'); 2 | 3 | export function post({ body, ...options }) { 4 | return new Promise((resolve, reject) => { 5 | const req = https.request( 6 | { 7 | method: 'POST', 8 | ...options, 9 | }, 10 | res => { 11 | const chunks = []; 12 | res.on('data', data => chunks.push(data)); 13 | res.on('end', () => { 14 | let body = Buffer.concat(chunks); 15 | if (res.headers['content-type'].startsWith('application/json')) { 16 | body = JSON.parse(body.toString()); 17 | } 18 | resolve(body); 19 | }); 20 | }, 21 | ); 22 | 23 | req.on('error', reject); 24 | if (body) { 25 | req.write(body); 26 | } 27 | req.end(); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/sleep.ts: -------------------------------------------------------------------------------- 1 | export function sleep(millis) { 2 | return new Promise(resolve => setTimeout(resolve, millis)); 3 | } 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/src/utils/transformConfig.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as fs from 'fs-extra'; 3 | import { TRANSFORM_CONFIG_FILE_NAME, TransformConfig } from 'graphql-transformer-core'; 4 | 5 | export function getTransformConfig(projectRoot: string, apiName: string): TransformConfig { 6 | const metaFilePath = path.join(projectRoot, 'amplify', 'backend', 'api', apiName, TRANSFORM_CONFIG_FILE_NAME); 7 | return JSON.parse(fs.readFileSync(metaFilePath, 'utf8')); 8 | } 9 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "allowJs": true, 6 | "target": "es6", 7 | "module": "commonjs", 8 | "sourceMap": true, 9 | "esModuleInterop": true, 10 | "rootDir": "./src", 11 | "types": ["jest", "node"], 12 | "outDir": "lib", 13 | "lib": ["es2015", "es2016.array.include", "esnext.asynciterable", "dom"], 14 | "typeRoots": ["../../node_modules/@types", "node_modules/@types"] 15 | }, 16 | "include": ["src/**/*"], 17 | "exclude": ["node_modules", "lib"] 18 | } 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/functions/get-api-appsync.js: -------------------------------------------------------------------------------- 1 | // /* eslint-disable no-console */ 2 | const AWS = require('aws-sdk'); 3 | 4 | const getGqlApi = async (idKey) => { 5 | const appsync = new AWS.AppSync({ region: process.env.REGION }); 6 | return await appsync.getGraphqlApi({ apiId: process.env[idKey] }).promise(); 7 | } 8 | 9 | exports.handler = async (event) => { 10 | return await getGqlApi(event.idKey); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/functions/mutation-appsync.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | require("isomorphic-fetch"); 3 | const AWS = require('aws-sdk'); 4 | const AWSAppSyncClient = require("aws-appsync").default; 5 | const { AUTH_TYPE } = require("aws-appsync"); 6 | const gql = require('graphql-tag'); 7 | 8 | const runGQLMutation = async (gql_url, mutation, variables) => { 9 | const client = new AWSAppSyncClient({ 10 | url: process.env[gql_url], 11 | region: process.env.REGION, 12 | auth: { 13 | type: AUTH_TYPE.AWS_IAM, 14 | credentials: AWS.config.credentials 15 | }, 16 | disableOffline: true 17 | }); 18 | return await client.mutate({ mutation: gql(mutation), variables }); 19 | }; 20 | 21 | exports.handler = async (event) => { 22 | return await runGQLMutation(event.urlKey, event.mutation, event.variables); 23 | }; 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/initial_key_blog.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | blogId: ID! 3 | taskId: ID! 4 | content: String 5 | createdAt: String 6 | } 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/add-one-key-multiple-models/final-schema.graphql: -------------------------------------------------------------------------------- 1 | type Something 2 | @model 3 | @auth(rules: [{ allow: private, provider: iam }]) 4 | @key(name: "byTodo", fields: ["todoID"]) 5 | @key(name: "byTodo2", fields: ["todo2ID"]) 6 | @key(name: "byTodo3", fields: ["todo3ID"]) { 7 | id: ID! 8 | todoID: ID! 9 | todo2ID: ID! 10 | todo3ID: ID! 11 | } 12 | 13 | type Todo @model { 14 | id: ID! 15 | name: String! 16 | description: String 17 | addfield2: String 18 | reltn: [Something] @connection(keyName: "byTodo", fields: ["id"]) 19 | } 20 | 21 | type Todo2 @model { 22 | id: ID! 23 | name: String! 24 | description: String 25 | addfield2: String 26 | reltn: [Something] @connection(keyName: "byTodo2", fields: ["id"]) 27 | } 28 | 29 | type Todo3 @model { 30 | id: ID! 31 | name: String! 32 | description: String 33 | addfield2: String 34 | reltn: [Something] @connection(keyName: "byTodo3", fields: ["id"]) 35 | } 36 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/add-one-key-multiple-models/initial-schema.graphql: -------------------------------------------------------------------------------- 1 | type Something 2 | @model 3 | @auth(rules: [{ allow: private, provider: iam }]) 4 | @key(name: "byTodo", fields: ["todoID"]) 5 | @key(name: "byTodo2", fields: ["todo2ID"]) { 6 | id: ID! 7 | todoID: ID! 8 | todo2ID: ID! 9 | } 10 | 11 | type Todo @model { 12 | id: ID! 13 | name: String! 14 | description: String 15 | addfield2: String 16 | reltn: [Something] @connection(keyName: "byTodo", fields: ["id"]) 17 | } 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/add-remove-and-update-key/final-schema.graphql: -------------------------------------------------------------------------------- 1 | type Blog @model { 2 | id: ID! 3 | name: String! 4 | posts: [Post] @connection(keyName: "byBlog4", fields: ["id"]) 5 | } 6 | 7 | type Post 8 | @model 9 | @key(name: "byBlog1", fields: ["blogID", "createdAt"]) # edit 10 | # New keys 11 | @key(name: "byBlog4", fields: ["blogID"]) 12 | @key(name: "byBlog5", fields: ["blogID"]) 13 | @key(name: "byBlog6", fields: ["blogID"]) { 14 | id: ID! 15 | title: String! 16 | blogID: ID! 17 | blog: Blog @connection(fields: ["blogID"]) 18 | comments: [Comment] @connection(keyName: "byPost", fields: ["id"]) 19 | createdAt: AWSTimestamp 20 | } 21 | 22 | type Comment @model @key(name: "byPost", fields: ["postID", "content"]) { 23 | id: ID! 24 | postID: ID! 25 | post: Post @connection(fields: ["postID"]) 26 | content: String! 27 | } 28 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/add-remove-and-update-key/initial-schema.graphql: -------------------------------------------------------------------------------- 1 | type Blog @model { 2 | id: ID! 3 | name: String! 4 | posts: [Post] @connection(keyName: "byBlog1", fields: ["id"]) 5 | } 6 | 7 | type Post 8 | @model 9 | @key(name: "byBlog1", fields: ["blogID"]) 10 | @key(name: "byBlog2", fields: ["blogID"]) 11 | @key(name: "byBlog3", fields: ["blogID"]) { 12 | id: ID! 13 | title: String! 14 | blogID: ID! 15 | blog: Blog @connection(fields: ["blogID"]) 16 | comments: [Comment] @connection(keyName: "byPost", fields: ["id"]) 17 | } 18 | 19 | type Comment @model @key(name: "byPost", fields: ["postID", "content"]) { 20 | id: ID! 21 | postID: ID! 22 | post: Post @connection(fields: ["postID"]) 23 | content: String! 24 | } 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/change-model-name/final-schema.graphql: -------------------------------------------------------------------------------- 1 | type Comment @model @key(name: "byTodos", fields: ["todoID"]) { 2 | id: ID! 3 | todoID: ID! 4 | } 5 | 6 | type Todos @model { 7 | id: ID! 8 | name: String! 9 | description: String 10 | addfield2: String 11 | Comments: [Comment] @connection(keyName: "byTodos", fields: ["id"]) 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/change-model-name/initial-schema.graphql: -------------------------------------------------------------------------------- 1 | type Comment @model @key(name: "byTodo", fields: ["todoID"]) { 2 | id: ID! 3 | todoID: ID! 4 | } 5 | 6 | type Todo @model { 7 | id: ID! 8 | name: String! 9 | description: String 10 | addfield2: String 11 | Comments: [Comment] @connection(keyName: "byTodo", fields: ["id"]) 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/multiple-key-delete/final-schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo3 @model { 2 | id: ID! 3 | } 4 | 5 | type Something @model { 6 | id: ID! 7 | } 8 | 9 | type Todo @model { 10 | id: ID! 11 | name: String! 12 | description: String 13 | addfield2: String 14 | } 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/iterative-push/multiple-key-delete/initial-schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo3 @model { 2 | id: ID! 3 | Something: [Something] @connection(keyName: "byTodo3", fields: ["id"]) 4 | } 5 | 6 | type Something @model @key(name: "byTodo3", fields: ["todo3ID"]) @key(name: "byTodo", fields: ["todoID"]) { 7 | id: ID! 8 | todo3ID: ID! 9 | todoID: ID! 10 | } 11 | 12 | type Todo @model { 13 | id: ID! 14 | name: String! 15 | description: String 16 | addfield2: String 17 | Something: [Something] @connection(keyName: "byTodo", fields: ["id"]) 18 | } 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/key-conflict-detection.graphql: -------------------------------------------------------------------------------- 1 | type Note @model @key(fields: ["noteId"]) { 2 | noteId: String! 3 | note: String 4 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/add_a_sort_key.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostComments", sortField: "createdAt") 5 | createdAt: String! 6 | } 7 | 8 | type Comment @model { 9 | id: ID! 10 | content: String! 11 | post: Post @connection(name: "PostComments", sortField: "createdAt") 12 | createdAt: String! 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/add_a_sort_key_before_remove.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostComments") 5 | recentComments: [Comment] @connection(name: "PostCommentsByCreatedAt", keyField: "commentPostId", sortField: "createdAt") 6 | createdAt: String! 7 | } 8 | 9 | type Comment @model { 10 | id: ID! 11 | content: String! 12 | post: Post @connection(name: "PostComments") 13 | parentPost: Post @connection(name: "PostCommentsByCreatedAt", keyField: "commentPostId", sortField: "createdAt") 14 | createdAt: String! 15 | } 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/cant_add_a_sort_key.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostComments", sortField: "createdAt") 5 | createdAt: String! 6 | } 7 | 8 | type Comment @model { 9 | id: ID! 10 | content: String! 11 | post: Post @connection(name: "PostComments", sortField: "createdAt") 12 | createdAt: String! 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/cant_add_and_remove_at_same_time.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | } 5 | 6 | type Comment @model { 7 | id: ID! 8 | content: String! 9 | author: User @connection(name: "UserComments") 10 | } 11 | 12 | type User @model { 13 | id: ID! 14 | name: String 15 | comments: [Comment] @connection(name: "UserComments") 16 | } 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/cant_change_connection_field_name.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostComments") 5 | } 6 | 7 | type Comment @model { 8 | id: ID! 9 | content: String! 10 | parentPost: Post @connection(name: "PostComments") 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/initial_schema.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostComments") 5 | } 6 | 7 | type Comment @model { 8 | id: ID! 9 | content: String! 10 | post: Post @connection(name: "PostComments") 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/remove_connection.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] 5 | } 6 | 7 | type Comment @model { 8 | id: ID! 9 | content: String! 10 | post: Post 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_connection/remove_old_connection_after.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String! 4 | comments: [Comment] @connection(name: "PostCommentsByCreatedAt", keyField: "commentPostId", sortField: "createdAt") 5 | createdAt: String! 6 | } 7 | 8 | type Comment @model { 9 | id: ID! 10 | content: String! 11 | post: Post @connection(name: "PostCommentsByCreatedAt", keyField: "commentPostId", sortField: "createdAt") 12 | createdAt: String! 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/add_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "SomeGSI", fields: ["name", "id"]) 6 | @key(name: "NewValidGSI", fields: ["version", "id"]) { 7 | id: ID! 8 | id2: ID! 9 | name: String! 10 | name2: String! 11 | version: String! 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_add_lsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "AnotherLSI", fields: ["id", "name2"]) 6 | @key(name: "SomeGSI", fields: ["name", "id"]) { 7 | id: ID! 8 | id2: ID! 9 | name: String! 10 | name2: String! 11 | version: String! 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_add_more_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "SomeGSI", fields: ["name", "id"]) 6 | @key(name: "SomeGSI1", fields: ["name2", "id"]) 7 | @key(name: "SomeGSI2", fields: ["version", "id"]) { 8 | id: ID! 9 | id2: ID! 10 | name: String! 11 | name2: String! 12 | version: String! 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_add_multiple_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(name: "byDescription", fields: ["description"]) 4 | @key(name: "byCreatedAt", fields: ["createdAt"]) 5 | @key(name: "byUpdatedAt", fields: ["updatedAt"]) { 6 | id: ID! 7 | name: String! 8 | description: String 9 | createdAt: AWSDateTime 10 | updatedAt: AWSDateTime 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_change_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "SomeGSI", fields: ["name", "id2"]) { 6 | id: ID! 7 | id2: ID! 8 | name: String! 9 | name2: String! 10 | version: String! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_change_key_schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model @key(fields: ["id", "name2"]) @key(name: "SomeLSI", fields: ["id", "name"]) @key(name: "SomeGSI", fields: ["name", "id"]) { 2 | id: ID! 3 | id2: ID! 4 | name: String! 5 | name2: String! 6 | version: String! 7 | } 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_change_lsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name2"]) 5 | @key(name: "SomeGSI", fields: ["name", "id"]) { 6 | id: ID! 7 | id2: ID! 8 | name: String! 9 | name2: String! 10 | version: String! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_remove_more_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model @key(name: "SomeGSI2", fields: ["version", "id"]) { 2 | id: ID! 3 | id2: ID! 4 | name: String! 5 | name2: String! 6 | version: String! 7 | } 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/cant_update_delete_gsi.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "SomeGSI", fields: ["name2", "id"]) { 6 | id: ID! 7 | id2: ID! 8 | name: String! 9 | name2: String! 10 | version: String! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/four_gsi_model_schema.graphql: -------------------------------------------------------------------------------- 1 | type Task 2 | @model 3 | @key(name: "gsi0", fields: ["name"]) 4 | @key(name: "gsi1", fields: ["taskID", "createdAt"]) 5 | @key(name: "gsi3", fields: ["name", "taskID"]) 6 | @key(name: "gsi2", fields: ["version"]) { 7 | id: ID! 8 | taskID: ID! 9 | name: String! 10 | version: String! 11 | createdAt: AWSDateTime 12 | updatedAt: AWSDateTime 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/four_key_model_schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model 2 | @key(name: "byDescription", fields: ["description"]) 3 | @key(name: "byName", fields: ["name"]) 4 | { 5 | id: ID! 6 | name: String! 7 | description: String 8 | } 9 | 10 | 11 | type Post @model @key(name: "byCreatedAt", fields: ["createdAt"]) 12 | @key(name: "byUpdatedAt", fields: ["updatedAt"]) 13 | { 14 | id: ID! 15 | name: String! 16 | description: String 17 | createdAt: AWSDateTime 18 | updatedAt: AWSDateTime 19 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/initial_schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(fields: ["id", "version"]) 4 | @key(name: "SomeLSI", fields: ["id", "name"]) 5 | @key(name: "SomeGSI", fields: ["name", "id"]) { 6 | id: ID! 7 | id2: ID! 8 | name: String! 9 | name2: String! 10 | version: String! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/initial_schema1.graphql: -------------------------------------------------------------------------------- 1 | type Todo 2 | @model 3 | @key(name: "SomeGSI", fields: ["name", "id"]) 4 | @key(name: "SomeGSI1", fields: ["name2", "id"]) 5 | @key(name: "SomeGSI2", fields: ["version", "id"]) { 6 | id: ID! 7 | id2: ID! 8 | name: String! 9 | name2: String! 10 | version: String! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/simple_key.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model @key(name: "byDescription", fields: ["description"]) { 2 | id: ID! 3 | name: String! 4 | description: String 5 | } 6 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/three_gsi_model_schema.graphql: -------------------------------------------------------------------------------- 1 | type Task 2 | @model 3 | @key(name: "gsi0", fields: ["name"]) 4 | @key(name: "gsi1", fields: ["taskID", "createdAt"]) 5 | @key(name: "gsi2", fields: ["version"]) { 6 | id: ID! 7 | taskID: ID! 8 | name: String! 9 | version: String! 10 | createdAt: AWSDateTime 11 | updatedAt: AWSDateTime 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_key/two_key_model_schema.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model @key(name: "byDescription", fields: ["description"]) { 2 | id: ID! 3 | name: String! 4 | description: String 5 | } 6 | 7 | 8 | type Post @model @key(name: "byCreatedAt", fields: ["createdAt"]) { 9 | id: ID! 10 | name: String! 11 | description: String 12 | createdAt: AWSDateTime 13 | updatedAt: AWSDateTime 14 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_searchable/initial_searchable.graphql: -------------------------------------------------------------------------------- 1 | type User @model @searchable { 2 | id: ID! 3 | name: String! 4 | createdAt: AWSDate 5 | userItems: [String] 6 | } 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/migrations_searchable/updated_searchable.graphql: -------------------------------------------------------------------------------- 1 | type User @model @searchable { 2 | id: ID! 3 | name: String! 4 | description: String 5 | createdAt: AWSDate 6 | userItems: [String] 7 | } 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/modelgen/model_gen_schema_with_errors.graphql: -------------------------------------------------------------------------------- 1 | type MyType @model { 2 | missingType: Missing 3 | } 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/modelgen/schema_with_connected_pk.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | postId: ID! @primaryKey 3 | node: PostNode! @belongsTo(fields: ["postId"]) 4 | title: String! 5 | } 6 | 7 | type PostNode @model { 8 | id: ID! 9 | post: Post! @hasOne 10 | } 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/multi-gsi.graphql: -------------------------------------------------------------------------------- 1 | type Person 2 | @model 3 | @key(fields: ["id", "firstName", "lastName"]) 4 | @key(name: "byNameAndAge", fields: ["firstName", "age", "birthDate"], queryField: "getPersonByNameAndAge") 5 | @key(name: "byNicknameAndHeight", fields: ["firstName", "nickname", "height"], queryField: "getPersonByNicknameAndHeight") { 6 | id: ID! 7 | firstName: String! 8 | lastName: String! 9 | birthDate: AWSDate 10 | nickname: String 11 | age: Int 12 | height: Int 13 | eyeColor: String 14 | } 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/next_key_blog.graphql: -------------------------------------------------------------------------------- 1 | type Post @model @key(name: "ByDate", fields: ["blogId", "createdAt"]) { 2 | # Key attributes 3 | id: ID! 4 | blogId: ID! 5 | createdAt: String 6 | 7 | # Other 8 | content: String 9 | } 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/sdl/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | echo: String 3 | } 4 | 5 | type Mutation { 6 | mymutation: String 7 | } 8 | 9 | type Subscription { 10 | mysub: String 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/selective_sync.graphql: -------------------------------------------------------------------------------- 1 | type Comment 2 | @model 3 | @key(name: "byUsername", fields: ["username", "createdAt"], queryField: "commentsByUsername") 4 | @key(name: "byeditor", fields: ["editor", "createdAt"], queryField: "commentsByeditors") { 5 | id: ID! 6 | content: String 7 | username: String! 8 | createdAt: String! 9 | editor: String! 10 | data1: String 11 | data2: String 12 | } 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/simple_model.graphql: -------------------------------------------------------------------------------- 1 | type Todo @model { 2 | id: ID! 3 | content: String 4 | } 5 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/schemas/two-model-schema.graphql: -------------------------------------------------------------------------------- 1 | type Post @model { 2 | id: ID! 3 | title: String 4 | comments: [Comment!]! @connection(keyName: "byPost", fields: ["id"]) 5 | } 6 | 7 | type Comment @model @key(name: "byPost", fields: ["postID"]) { 8 | id: ID! 9 | content: String 10 | postID: ID! 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/add-codegen-android.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_ANDROID_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testAddCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen add tests - Android', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('addCodegenAndroid'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Adding codegen works as expected`, async () => { 18 | await testAddCodegen(DEFAULT_ANDROID_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/add-codegen-ios.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_IOS_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testAddCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen add tests - iOS', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('addCodegenIOS'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Adding codegen works as expected`, async () => { 18 | await testAddCodegen(DEFAULT_IOS_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/backends/graphql-generator-gen2/handlers/mutation.ts: -------------------------------------------------------------------------------- 1 | import type { Schema } from '../resource' 2 | 3 | export const handler: Schema["echoMutation"]["functionHandler"] = async (event, context) => { 4 | return { 5 | id: 'todo1', 6 | content: `Echoing content: ${event.arguments.requiredContent}`, 7 | status: 'COMPLETED', 8 | createdAt: performance.now().toString(), 9 | updatedAt: performance.now().toString(), 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/backends/graphql-generator-gen2/handlers/query.ts: -------------------------------------------------------------------------------- 1 | import type { Schema } from '../resource' 2 | 3 | export const handler: Schema["echoQuery"]["functionHandler"] = async (event, context) => { 4 | const start = performance.now(); 5 | return { 6 | content: `Echoing content: ${event.arguments.content}`, 7 | executionDuration: performance.now() - start 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/configure-codegen-android.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_ANDROID_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testConfigureCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen configure tests - Android', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('configureCodegenAndroid'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Updating codegen configuration works as expected`, async () => { 18 | await testConfigureCodegen(DEFAULT_ANDROID_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/configure-codegen-ios.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_IOS_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testConfigureCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen configure tests - iOS', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('configureCodegenIOS'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Updating codegen configuration works as expected`, async () => { 18 | await testConfigureCodegen(DEFAULT_IOS_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/configure-codegen-js.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_JS_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testConfigureCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen configure tests - JS', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('configureCodegenJS'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Updating codegen configuration works as expected`, async () => { 18 | await testConfigureCodegen(DEFAULT_JS_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/graphql-codegen-android.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_ANDROID_CONFIG, 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testGraphQLCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('GraphQL codegen tests - Android', () => { 10 | let projectRoot: string; 11 | 12 | beforeEach(async () => { 13 | projectRoot = await createNewProjectDir('graphqlCodegenAndroid'); 14 | }); 15 | 16 | afterEach(async () => { 17 | await deleteAmplifyProject(projectRoot); 18 | }); 19 | 20 | it(`Should generate files in correct place and not delete src files in Android project`, async() => { 21 | await testGraphQLCodegen(DEFAULT_ANDROID_CONFIG, projectRoot, schema) 22 | }); 23 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/graphql-codegen-ios.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_IOS_CONFIG, 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testGraphQLCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('GraphQL codegen tests - iOS', () => { 10 | let projectRoot: string; 11 | 12 | beforeEach(async () => { 13 | projectRoot = await createNewProjectDir('graphqlCodegenIOS'); 14 | }); 15 | 16 | afterEach(async () => { 17 | await deleteAmplifyProject(projectRoot); 18 | }); 19 | 20 | it(`Should generate files in correct place and not delete src files in iOS project`, async() => { 21 | await testGraphQLCodegen(DEFAULT_IOS_CONFIG, projectRoot, schema) 22 | }); 23 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/graphql-codegen-js.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_JS_CONFIG, 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testGraphQLCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('GraphQL codegen tests - JS', () => { 10 | let projectRoot: string; 11 | 12 | beforeEach(async () => { 13 | projectRoot = await createNewProjectDir('graphqlCodegenJS'); 14 | }); 15 | 16 | afterEach(async () => { 17 | await deleteAmplifyProject(projectRoot); 18 | }); 19 | 20 | it(`Should generate files in correct place and not delete src files in JS project`, async() => { 21 | await testGraphQLCodegen(DEFAULT_JS_CONFIG, projectRoot, schema) 22 | }); 23 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/graphql-generator-app.test.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_JS_CONFIG, craInstall, craBuild, cypressRun, isWindows } from '@aws-amplify/amplify-codegen-e2e-core'; 2 | import path from 'path'; 3 | 4 | describe('GraphQL documents generator e2e tests', () => { 5 | let apiName: string; 6 | const projectRoot = path.resolve('test-apps', 'graphql-generator-app'); 7 | const config = DEFAULT_JS_CONFIG; 8 | 9 | beforeAll(async () => { 10 | await craInstall(projectRoot, { ...config }); 11 | }); 12 | 13 | // skip cypress test on windows 14 | (isWindows() ? it.skip : it)('graphql generator does not crash in browser', async () => { 15 | await cypressRun(projectRoot, { componentsTesting: true }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/push-codegen-admin-modelgen.test.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_JS_CONFIG, createNewProjectDir } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testPushAdminModelgen, testPushCodegen } from "../codegen-tests-base"; 3 | 4 | const schema = 'admin-modelgen.graphql'; 5 | 6 | describe('Amplify push with codegen tests - admin modelgen', () => { 7 | let projectRoot: string; 8 | beforeEach(async () => { 9 | projectRoot = await createNewProjectDir('pushCodegenAdminModelgen'); 10 | }); 11 | 12 | afterEach(async () => { 13 | await deleteAmplifyProject(projectRoot); 14 | }); 15 | 16 | it(`should not throw error for executing the admin modelgen step required by studio CMS usage post push given the schema with input, union and interface types`, async () => { 17 | await testPushAdminModelgen(DEFAULT_JS_CONFIG, projectRoot, schema); 18 | }); 19 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/push-codegen-android.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_ANDROID_CONFIG 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testPushCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('Amplify push with codegen tests - Android', () => { 10 | let projectRoot: string; 11 | beforeEach(async () => { 12 | projectRoot = await createNewProjectDir('pushCodegenAndroid'); 13 | }); 14 | 15 | afterEach(async () => { 16 | await deleteAmplifyProject(projectRoot); 17 | }); 18 | 19 | it(`should prompt codegen add/update and not delete user files`, async () => { 20 | await testPushCodegen(DEFAULT_ANDROID_CONFIG, projectRoot, schema); 21 | }); 22 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/push-codegen-ios.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_IOS_CONFIG 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testPushCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('Amplify push with codegen tests - iOS', () => { 10 | let projectRoot: string; 11 | beforeEach(async () => { 12 | projectRoot = await createNewProjectDir('pushCodegenIOS'); 13 | }); 14 | 15 | afterEach(async () => { 16 | await deleteAmplifyProject(projectRoot); 17 | }); 18 | 19 | it(`should prompt codegen add/update and not delete user files`, async () => { 20 | await testPushCodegen(DEFAULT_IOS_CONFIG, projectRoot, schema); 21 | }); 22 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/push-codegen-js.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createNewProjectDir, 3 | DEFAULT_JS_CONFIG 4 | } from "@aws-amplify/amplify-codegen-e2e-core"; 5 | import { deleteAmplifyProject, testPushCodegen } from '../codegen-tests-base'; 6 | 7 | const schema = 'simple_model.graphql'; 8 | 9 | describe('Amplify push with codegen tests - JS', () => { 10 | let projectRoot: string; 11 | beforeEach(async () => { 12 | projectRoot = await createNewProjectDir('pushCodegenJS'); 13 | }); 14 | 15 | afterEach(async () => { 16 | await deleteAmplifyProject(projectRoot); 17 | }); 18 | 19 | it(`should prompt codegen add/update and not delete user files`, async () => { 20 | await testPushCodegen(DEFAULT_JS_CONFIG, projectRoot, schema); 21 | }); 22 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/remove-codegen-android.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_ANDROID_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testRemoveCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen remove tests - Android', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('removeCodegenAndroid'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Does not delete files during codegen remove`, async () => { 18 | await testRemoveCodegen(DEFAULT_ANDROID_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/__tests__/remove-codegen-ios.test.ts: -------------------------------------------------------------------------------- 1 | import { createNewProjectDir, DEFAULT_IOS_CONFIG } from "@aws-amplify/amplify-codegen-e2e-core"; 2 | import { deleteAmplifyProject, testRemoveCodegen } from '../codegen-tests-base'; 3 | 4 | const schema = 'simple_model.graphql'; 5 | 6 | describe('codegen remove tests - iOS', () => { 7 | let projectRoot: string; 8 | 9 | beforeEach(async () => { 10 | projectRoot = await createNewProjectDir('removeCodegenIOS'); 11 | }); 12 | 13 | afterEach(async () => { 14 | await deleteAmplifyProject(projectRoot); 15 | }); 16 | 17 | it(`Does not delete files during codegen remove`, async () => { 18 | await testRemoveCodegen(DEFAULT_IOS_CONFIG, projectRoot, schema); 19 | }); 20 | }); -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/aws-exports/awsExports.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | 4 | export function getAWSExportsPath(projRoot: string): string { 5 | return path.join(projRoot, 'src', 'aws-exports.js'); 6 | } 7 | 8 | export function getAWSExports(projectRoot: string) { 9 | const awsExportsPath = getAWSExportsPath(projectRoot); 10 | // From Jest 25, ESM modules can only be loaded with mjs extension and Jest takes over 11 | // require, that's why we need to copy the file. 12 | const awsExportsMJSPath = awsExportsPath.replace('.js', '.mjs'); 13 | fs.copySync(awsExportsPath, awsExportsMJSPath, { overwrite: true }); 14 | const localRequire = require('esm')(module); 15 | return localRequire(awsExportsMJSPath); 16 | } 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/aws-matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './iamMatcher'; 2 | export * from './s3matcher'; 3 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/aws-matchers/s3matcher.ts: -------------------------------------------------------------------------------- 1 | import { S3 } from 'aws-sdk'; 2 | 3 | export const toBeAS3Bucket = async (bucketName: string) => { 4 | const s3 = new S3(); 5 | let pass: boolean; 6 | try { 7 | await s3.headBucket({ Bucket: bucketName }).promise(); 8 | pass = true; 9 | } catch (e) { 10 | pass = false; 11 | } 12 | 13 | const messageStr = pass ? `expected S3 bucket ${bucketName} exist` : `expected S3 bucket ${bucketName} does exist`; 14 | return { 15 | message: () => messageStr, 16 | pass, 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/codegen-tests-base/index.ts: -------------------------------------------------------------------------------- 1 | export * from './test-setup'; 2 | export * from './add-codegen'; 3 | export * from './graphql-codegen'; 4 | export * from './configure-codegen'; 5 | export * from './remove-codegen'; 6 | export * from './datastore-modelgen'; 7 | export * from './push-codegen'; 8 | export * from './uninitialized-modelgen'; 9 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/gen2-codegen-tests-base/index.ts: -------------------------------------------------------------------------------- 1 | export * from './commands'; 2 | export * from './test-graphql-client-codegen'; 3 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/gen2-codegen-tests-base/test-graphql-client-codegen.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { isNotEmptyDir } from "../utils"; 3 | import { ClientCodegenConfig, generateGraphqlClientCode } from "./commands"; 4 | import { existsSync } from 'fs-extra'; 5 | import { deleteProjectDir } from '@aws-amplify/amplify-codegen-e2e-core'; 6 | 7 | export const testGraphqlClientCodegen = async (projectRoot: string, config: ClientCodegenConfig) => { 8 | const outputPath = path.join(projectRoot, config.outDir) 9 | if (existsSync(outputPath)) { 10 | deleteProjectDir(outputPath); 11 | } 12 | await expect(generateGraphqlClientCode(projectRoot, config)).resolves.not.toThrow(); 13 | 14 | expect(isNotEmptyDir(outputPath)).toBe(true); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/import-helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './settings'; 3 | export * from './expects'; 4 | export * from './utilities'; 5 | export * from './walkthroughs'; 6 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/auth-owner1.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | export const schema = ` 3 | # The simplest case 4 | type Post @model @auth(rules: [{allow: owner}]) { 5 | id: ID! 6 | title: String! 7 | } 8 | 9 | ##owner1`; 10 | //mutations 11 | export const mutation = ` 12 | mutation CreatePost( 13 | $input: CreatePostInput! 14 | $condition: ModelPostConditionInput 15 | ) { 16 | createPost(input: $input, condition: $condition) { 17 | id 18 | title 19 | createdAt 20 | updatedAt 21 | owner 22 | } 23 | }`; 24 | export const input_mutation = { 25 | input: { 26 | id: '1', 27 | title: 'title1', 28 | }, 29 | }; 30 | export const expected_result_mutation = { 31 | data: { 32 | createPost: { 33 | id: '1', 34 | title: 'title1', 35 | createdAt: '', 36 | updatedAt: '', 37 | owner: 'user1', 38 | }, 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/auth-owner3.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | export const schema = ` 3 | # owner identity specified explicitly on every object 4 | type Post @model @auth(rules: [{ allow: owner, operations: [create] }]) { 5 | id: ID! 6 | title: String! 7 | } 8 | 9 | ##auth/owner3`; 10 | //mutations 11 | export const mutation = ` 12 | mutation CreatePost( 13 | $input: CreatePostInput! 14 | $condition: ModelPostConditionInput 15 | ) { 16 | createPost(input: $input, condition: $condition) { 17 | id 18 | title 19 | createdAt 20 | updatedAt 21 | } 22 | }`; 23 | export const input_mutation = { 24 | input: { 25 | id: '1', 26 | title: 'title1', 27 | }, 28 | }; 29 | export const expected_result_mutation = { 30 | data: { 31 | createPost: { 32 | id: '1', 33 | title: 'title1', 34 | createdAt: '', 35 | updatedAt: '', 36 | }, 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/auth-owner4.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | export const schema = ` 3 | # owner identity not stored on objects 4 | type Post @model @auth(rules: [{ allow: owner, operations: [read] }]) { 5 | id: ID! 6 | title: String! 7 | } 8 | 9 | ##auth/owner4`; 10 | //mutations 11 | export const mutation = ` 12 | mutation CreatePost( 13 | $input: CreatePostInput! 14 | $condition: ModelPostConditionInput 15 | ) { 16 | createPost(input: $input, condition: $condition) { 17 | id 18 | title 19 | createdAt 20 | updatedAt 21 | } 22 | }`; 23 | export const input_mutation = { 24 | input: { 25 | id: '1', 26 | title: 'title1', 27 | }, 28 | }; 29 | export const expected_result_mutation = { 30 | data: { 31 | createPost: { 32 | id: '1', 33 | title: 'title1', 34 | createdAt: '', 35 | updatedAt: '', 36 | }, 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/connection-limit.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | export const schema = ` 3 | type Post @model { 4 | id: ID! 5 | title: String! 6 | comments: [Comment] @connection(limit: 50) 7 | } 8 | 9 | type Comment @model { 10 | id: ID! 11 | content: String! 12 | } 13 | 14 | #connection/limit`; 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/function-usage.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | const env = '${env}'; 3 | export const schema = ` 4 | #change: inserted "" placeholder, the test will replace it with the actual function name 5 | type Query { 6 | echo(msg: String): String @function(name: "-${env}") 7 | } 8 | `; 9 | //functions 10 | export const func = ` 11 | //#error: context.done is deprecated, use async and return 12 | exports.handler = async event => { 13 | return event.arguments.msg; 14 | }; 15 | `; 16 | //queries 17 | export const query = ` 18 | #extra 19 | query Echo { 20 | echo(msg: "query message") 21 | } 22 | `; 23 | export const expected_result_query = { 24 | data: { 25 | echo: 'query message', 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/model-usage2.ts: -------------------------------------------------------------------------------- 1 | //schema 2 | export const schema = ` 3 | type Post @model(queries: { get: "post" }, mutations: null, subscriptions: null) { 4 | id: ID! 5 | title: String! 6 | tags: [String!]! 7 | } 8 | 9 | ##model/usage2`; 10 | //mutations 11 | export const mutation = ` 12 | mutation CreatePost { 13 | createPost(input: { 14 | id: "1", 15 | title: "title1", 16 | tags: ["tag1"] 17 | }) { 18 | id 19 | title 20 | tags 21 | createdAt 22 | updatedAt 23 | } 24 | }`; 25 | export const expected_result_mutation = { 26 | graphQLErrors: [ 27 | { 28 | message: 'Schema is not configured for mutations.', 29 | }, 30 | ], 31 | }; 32 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/predictions-usage-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/src/schema-api-directives/tests/predictions-usage-image.jpg -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/setup-tests.ts: -------------------------------------------------------------------------------- 1 | import { toBeIAMRoleWithArn, toHaveValidPolicyConditionMatchingIdpId, toBeAS3Bucket } from './aws-matchers'; 2 | 3 | expect.extend({ toBeIAMRoleWithArn }); 4 | expect.extend({ toHaveValidPolicyConditionMatchingIdpId }); 5 | expect.extend({ toBeAS3Bucket }); 6 | 7 | // tslint:disable-next-line: no-magic-numbers 8 | const JEST_TIMEOUT = 1000 * 60 * 60; // 1 hour 9 | 10 | jest.setTimeout(JEST_TIMEOUT); 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/types/SandboxApp.ts: -------------------------------------------------------------------------------- 1 | export type SandboxApp = { 2 | backendManagerAppId: string; 3 | versionId: string; 4 | shareable: boolean; 5 | shareableId: string; 6 | schema: string; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { existsSync, writeFileSync, readdirSync, mkdirSync } from "fs"; 2 | import path from 'path'; 3 | 4 | export function isNotEmptyDir(dirPath: string) : boolean { 5 | return existsSync(dirPath) && readdirSync(dirPath).length > 0; 6 | } 7 | 8 | export function generateSourceCode(projectRoot: string, srcDir: string) : string { 9 | const userFileData = 'This is a pre-existing file.'; 10 | const srcCodePath = path.join(projectRoot, srcDir, 'sample.txt'); 11 | if (!existsSync(path.dirname(srcCodePath))) { 12 | mkdirSync(path.dirname(srcCodePath), {recursive: true}); 13 | } 14 | writeFileSync(srcCodePath, userFileData); 15 | return srcCodePath; 16 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | 17 | amplify 18 | app/src/main/java/com/amplifyframework/datastore/generated/model/ 19 | 20 | #amplify-do-not-edit-begin 21 | amplify/\#current-cloud-backend 22 | amplify/.config/local-* 23 | amplify/logs 24 | amplify/mock-data 25 | amplify/mock-api-resources 26 | amplify/backend/amplify-meta.json 27 | amplify/backend/.temp 28 | build/ 29 | dist/ 30 | node_modules/ 31 | aws-exports.js 32 | awsconfiguration.json 33 | amplifyconfiguration.json 34 | amplifyconfiguration.dart 35 | amplify-build-config.json 36 | amplify-gradle-config.json 37 | amplifytools.xcconfig 38 | .secret-* 39 | **.sample 40 | #amplify-do-not-edit-end 41 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/androidTest/java/com/example/android/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.android; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.example.android", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/java/com/example/android/MyAndroidApp.java: -------------------------------------------------------------------------------- 1 | package com.example.android; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.amplifyframework.AmplifyException; 7 | import com.amplifyframework.core.Amplify; 8 | 9 | public class MyAndroidApp extends Application { 10 | public void onCreate() { 11 | super.onCreate(); 12 | 13 | try { 14 | Amplify.configure(getApplicationContext()); 15 | Log.i("MyAmplifyApp", "Initialized Amplify"); 16 | } catch (AmplifyException error) { 17 | Log.e("MyAmplifyApp", "Could not initialize Amplify", error); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | android 3 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/app/src/test/java/com/example/android/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.android; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | plugins { 3 | id 'com.android.application' version '7.2.1' apply false 4 | id 'com.android.library' version '7.2.1' apply false 5 | } 6 | 7 | task clean(type: Delete) { 8 | delete rootProject.buildDir 9 | } 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/amplify-codegen-e2e-tests/test-apps/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Nov 23 13:01:50 MST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "android" 16 | include ':app' 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | #amplify-do-not-edit-begin 26 | amplify/\#current-cloud-backend 27 | amplify/.config/local-* 28 | amplify/logs 29 | amplify/mock-data 30 | amplify/mock-api-resources 31 | amplify/backend/amplify-meta.json 32 | amplify/backend/.temp 33 | build/ 34 | dist/ 35 | node_modules/ 36 | aws-exports.js 37 | awsconfiguration.json 38 | amplifyconfiguration.json 39 | amplifyconfiguration.dart 40 | amplify-build-config.json 41 | amplify-gradle-config.json 42 | amplifytools.xcconfig 43 | .secret-* 44 | **.sample 45 | #amplify-do-not-edit-end 46 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/README.md: -------------------------------------------------------------------------------- 1 | This is a test React application. 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.\ 10 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 11 | 12 | The page will reload when you make changes.\ 13 | You may also see any lint errors in the console. 14 | 15 | ### `npm run build` 16 | 17 | Builds the app for production to the `build` folder.\ 18 | It correctly bundles React in production mode and optimizes the build for the best performance. 19 | 20 | The build is minified and the filenames include the hashes.\ 21 | Your app is ready to be deployed! 22 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("cypress"); 2 | 3 | module.exports = defineConfig({ 4 | component: { 5 | devServer: { 6 | framework: "create-react-app", 7 | bundler: "webpack", 8 | }, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/cypress/support/component-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Components App 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/cypress/support/component.js: -------------------------------------------------------------------------------- 1 | import { mount } from 'cypress/react18'; 2 | 3 | Cypress.Commands.add('mount', mount); 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | React App 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Sample App for e2e testing", 4 | "icons": [], 5 | "start_url": ".", 6 | "display": "standalone", 7 | "theme_color": "#000000", 8 | "background_color": "#ffffff" 9 | } 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/public/schema.graphql: -------------------------------------------------------------------------------- 1 | # This "input" configures a global authorization rule to enable public access to 2 | # all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules 3 | input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY! 4 | 5 | type Todo @model { 6 | id: ID! 7 | name: String! 8 | description: String 9 | } 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/docsgen-react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress'; 2 | 3 | process.env.NODE_ENV = 'test'; 4 | process.env.BABEL_ENV = 'test'; 5 | require('react-app-rewired/config/webpack.config')('development'); 6 | export default defineConfig({ 7 | component: { 8 | devServer: { 9 | framework: 'create-react-app', 10 | bundler: 'webpack', 11 | }, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/cypress/support/commands.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // This file needs to exist for cypress tests to function 3 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/cypress/support/component-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Components App 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/src/App.cy.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import App from './App'; 3 | 4 | describe('graphql-generator does not crash in browser', () => { 5 | beforeEach(() => { 6 | cy.mount(); 7 | }); 8 | 9 | const testCases = [ 10 | 'generate-models-java', 11 | 'generate-models-javascript', 12 | 'generate-models-typescript', 13 | 'generate-models-dart', 14 | 'generate-models-introspection', 15 | ]; 16 | 17 | testCases.forEach(testCase => { 18 | it(testCase, {}, () => { 19 | cy.get(`#${testCase}_button`).click(); 20 | cy.get(`#${testCase}_result`).contains('✅', { timeout: 5000 }); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/first */ 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom/client'; 4 | import App from './App'; 5 | 6 | 7 | const root = ReactDOM.createRoot( 8 | document.getElementById('root') as HTMLElement 9 | ); 10 | root.render( 11 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/src/polyfills/fs-extra.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | 4 | module.exports = new Proxy( 5 | {}, 6 | { 7 | get: (target, prop) => { 8 | if (prop in target) { 9 | return target[prop]; 10 | } 11 | 12 | console.warn(`Attempted to call fs-extra.${String(prop)}, which is not supported in the browser.`); 13 | return () => { 14 | throw new Error(`fs-extra.${String(prop)} is not supported in the browser.`); 15 | }; 16 | }, 17 | }, 18 | ); 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/src/polyfills/process-shim.js: -------------------------------------------------------------------------------- 1 | // polyfil for window.performance.now 2 | 3 | const performanceNow = function() { 4 | return new Date().getTime(); 5 | }; 6 | 7 | // generate timestamp or delta 8 | // see http://nodejs.org/api/process.html#process_process_hrtime 9 | /** 10 | * @param {number[]} previousTimestamp 11 | */ 12 | export default function hrtime(previousTimestamp) { 13 | const clocktime = performanceNow.call(performance) * 1e-3; 14 | let seconds = Math.floor(clocktime); 15 | let nanoseconds = Math.floor((clocktime % 1) * 1e9); 16 | 17 | if (previousTimestamp) { 18 | seconds = seconds - previousTimestamp[0]; 19 | nanoseconds = nanoseconds - previousTimestamp[1]; 20 | 21 | if (nanoseconds < 0) { 22 | seconds--; 23 | nanoseconds += 1e9; 24 | } 25 | } 26 | 27 | return [seconds, nanoseconds]; 28 | } 29 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/src/schemas.ts: -------------------------------------------------------------------------------- 1 | export const modelSchema = ` 2 | type Blog @model { 3 | id: ID! 4 | name: String! 5 | posts: [Post] @hasMany 6 | } 7 | 8 | type Post @model { 9 | id: ID! 10 | title: String! 11 | blog: Blog @belongsTo 12 | comments: [Comment] @hasMany 13 | } 14 | 15 | type Comment @model { 16 | id: ID! 17 | post: Post @belongsTo 18 | content: String! 19 | } 20 | `; 21 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/graphql-generator-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "idiom": "universal" 5 | } 6 | ], 7 | "info": { 8 | "author": "xcode", 9 | "version": 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "platform": "ios", 6 | "size": "1024x1024" 7 | } 8 | ], 9 | "info": { 10 | "author": "xcode", 11 | "version": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // swift 4 | // 5 | // Created by Pilcher, Dane on 11/21/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | VStack { 13 | Image(systemName: "globe") 14 | .imageScale(.large) 15 | .foregroundColor(.accentColor) 16 | Text("Hello, world!") 17 | } 18 | .padding() 19 | } 20 | } 21 | 22 | struct ContentView_Previews: PreviewProvider { 23 | static var previews: some View { 24 | ContentView() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "author": "xcode", 4 | "version": 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/swift/swift/swiftApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // swiftApp.swift 3 | // swift 4 | // 5 | // Created by Pilcher, Dane on 11/21/22. 6 | // 7 | 8 | import SwiftUI 9 | import Amplify 10 | import AWSDataStorePlugin 11 | 12 | @main 13 | struct swiftApp: App { 14 | init() { 15 | configureAmplify() 16 | } 17 | var body: some Scene { 18 | WindowGroup { 19 | ContentView() 20 | } 21 | } 22 | } 23 | 24 | func configureAmplify() { 25 | let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels()) 26 | do { 27 | try Amplify.add(plugin: dataStorePlugin) 28 | try Amplify.configure() 29 | print("Initialized Amplify"); 30 | } catch { 31 | // simplified error handling for the tutorial 32 | print("Could not initialize Amplify: \(error)") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/.eslintignore: -------------------------------------------------------------------------------- 1 | src/models 2 | src/graphql 3 | src/API.ts 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | 26 | yarn.lock 27 | package-lock.json 28 | 29 | amplify 30 | src/models 31 | .graphqlconfig.yml 32 | 33 | #amplify-do-not-edit-begin 34 | amplify/\#current-cloud-backend 35 | amplify/.config/local-* 36 | amplify/logs 37 | amplify/mock-data 38 | amplify/backend/amplify-meta.json 39 | amplify/backend/.temp 40 | build/ 41 | dist/ 42 | node_modules/ 43 | aws-exports.js 44 | awsconfiguration.json 45 | amplifyconfiguration.json 46 | amplifyconfiguration.dart 47 | amplify-build-config.json 48 | amplify-gradle-config.json 49 | amplifytools.xcconfig 50 | .secret-* 51 | **.sample 52 | #amplify-do-not-edit-end 53 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "amplify/.config": true, 4 | "amplify/**/*-parameters.json": true, 5 | "amplify/**/amplify.state": true, 6 | "amplify/**/transform.conf.json": true, 7 | "amplify/#current-cloud-backend": true, 8 | "amplify/backend/amplify-meta.json": true, 9 | "amplify/backend/awscloudformation": true 10 | } 11 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/README.md: -------------------------------------------------------------------------------- 1 | # Local Setup 2 | 3 | - `amplify init` 4 | - use `CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION=1` to disable app creation. 5 | - `amplify add api` (enable conflict resolution) 6 | - `amplify add api` 7 | - `npm run set-schema ` 8 | - `amplify codegen models` 9 | - `npm run build` 10 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/scripts/set-schema.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const { schemas } = require('@aws-amplify/graphql-schema-test-library'); 4 | 5 | const schemaName = process.argv.slice(2, 3)[0]; 6 | if (!schemaName) { 7 | throw new Error('A schema name must be supplied.'); 8 | } 9 | const schema = schemas[schemaName]; 10 | if (!schema) { 11 | throw new Error(`${schemaName} does not exist in the schema test library.\nPossible schemas: ${Object.keys(schemas).join(', ')}`); 12 | } 13 | 14 | console.log(schema.sdl); 15 | 16 | let projectName = ''; 17 | try { 18 | projectName = fs.readdirSync(path.join('amplify', 'backend', 'api'))[0]; 19 | } catch (e) { 20 | throw new Error('No API found. Follow instructions in README to setup.'); 21 | } 22 | 23 | const fileContents = `input AMPLIFY { globalAuthRule: AuthRule = { allow: public } }\n${schema.sdl}`; 24 | fs.writeFileSync(path.join('amplify/backend/api', projectName, 'schema.graphql'), fileContents); 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | // import and use to avoid tree shaking 3 | import * as models from './models'; 4 | import * as queries from './graphql/queries'; 5 | import * as mutations from './graphql/mutations'; 6 | import * as subscriptions from './graphql/subscriptions'; 7 | // don't need to import API.ts becuase it is imported by graphql statements 8 | 9 | function App() { 10 | useEffect(() => { 11 | console.log(models); 12 | console.log(queries); 13 | console.log(mutations); 14 | console.log(subscriptions); 15 | }, []); 16 | return
; 17 | } 18 | 19 | export default App; 20 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { Amplify } from 'aws-amplify'; 4 | import App from './App'; 5 | import awsconfig from './aws-exports'; 6 | 7 | Amplify.configure(awsconfig); 8 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 9 | root.render( 10 | 11 | 12 | , 13 | ); 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/test-apps/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "skipLibCheck": true, 4 | "target": "es5", 5 | "module": "commonjs", 6 | "sourceMap": true, 7 | "esModuleInterop": true, 8 | "rootDir": "./src", 9 | "types": ["jest", "node"], 10 | "outDir": "lib", 11 | "lib": ["es2015", "es2016.array.include", "esnext.asynciterable", "dom"], 12 | "declaration": true, 13 | "typeRoots": ["../../node_modules/@types", "node_modules/@types", "./typings"] 14 | }, 15 | "exclude": ["node_modules", "lib", "__tests__"] 16 | } -------------------------------------------------------------------------------- /packages/amplify-codegen-e2e-tests/typings/aws-matchers.d.ts: -------------------------------------------------------------------------------- 1 | namespace jest { 2 | interface Matchers { 3 | toBeIAMRoleWithArn(roleName: string, arn?: string): R; 4 | toBeAS3Bucket(bucketName: string): R; 5 | toHaveValidPolicyConditionMatchingIdpId(idpId: string): R; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen/.npmignore: -------------------------------------------------------------------------------- 1 | **/__mocks__/** 2 | **/__tests__/** 3 | src 4 | tests 5 | tsconfig.json 6 | tsconfig.tsbuildinfo 7 | -------------------------------------------------------------------------------- /packages/amplify-codegen/amplify-plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codegen", 3 | "type": "util", 4 | "commands": ["add", "codegen", "configure", "remove", "statements", "types", "models", "model-introspection"], 5 | "commandAliases": { 6 | "update": "configure", 7 | "statement": "statements", 8 | "model": "models" 9 | }, 10 | "eventHandlers": [] 11 | } 12 | -------------------------------------------------------------------------------- /packages/amplify-codegen/awsAppSyncDirectives.graphql: -------------------------------------------------------------------------------- 1 | scalar AWSDate 2 | scalar AWSTime 3 | scalar AWSDateTime 4 | scalar AWSTimestamp 5 | scalar AWSEmail 6 | scalar AWSJSON 7 | scalar AWSURL 8 | scalar AWSPhone 9 | scalar AWSIPAddress 10 | scalar BigInt 11 | scalar Double 12 | 13 | directive @aws_subscribe(mutations: [String!]!) on FIELD_DEFINITION 14 | 15 | # Allows transformer libraries to deprecate directive arguments. 16 | directive @deprecated(reason: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION | ENUM | ENUM_VALUE 17 | 18 | directive @aws_auth(cognito_groups: [String!]!) on FIELD_DEFINITION 19 | directive @aws_api_key on FIELD_DEFINITION | OBJECT 20 | directive @aws_iam on FIELD_DEFINITION | OBJECT 21 | directive @aws_lambda on FIELD_DEFINITION | OBJECT 22 | directive @aws_oidc on FIELD_DEFINITION | OBJECT 23 | directive @aws_cognito_user_pools(cognito_groups: [String!]) on FIELD_DEFINITION | OBJECT 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/add.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src/index'); 2 | const constants = require('../../src/constants'); 3 | 4 | const featureName = 'add'; 5 | 6 | module.exports = { 7 | name: featureName, 8 | run: async context => { 9 | try { 10 | const { options = {} } = context.parameters; 11 | const keys = Object.keys(options); 12 | // frontend and framework are undocumented, but are read when apiId is also supplied 13 | const { apiId = null, region, yes, frontend, framework, debug, ...rest } = options; 14 | const extraOptions = Object.keys(rest); 15 | if (extraOptions.length) { 16 | const paramMsg = extraOptions.length > 1 ? 'Invalid parameters' : 'Invalid parameter'; 17 | context.print.info(`${paramMsg} ${keys.join(', ')}`); 18 | context.print.info(constants.INFO_MESSAGE_ADD_ERROR); 19 | return; 20 | } 21 | await codeGen.add(context, apiId, region); 22 | } catch (ex) { 23 | context.print.error(ex.message); 24 | } 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/configure.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src/index'); 2 | 3 | const featureName = 'configure'; 4 | 5 | module.exports = { 6 | name: featureName, 7 | alias: 'update', 8 | run: async context => { 9 | try { 10 | await codeGen.configure(context); 11 | } catch (ex) { 12 | context.print.error(ex.message); 13 | } 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/model-introspection.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src'); 2 | const { exitOnNextTick } = require('@aws-amplify/amplify-cli-core'); 3 | const featureName = 'model-introspection'; 4 | 5 | module.exports = { 6 | name: featureName, 7 | run: async context => { 8 | try { 9 | await codeGen.generateModelIntrospection(context); 10 | } catch (ex) { 11 | context.print.info(ex.message); 12 | console.log(ex.stack); 13 | await context.usageData.emitError(ex); 14 | exitOnNextTick(1); 15 | } 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/models.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src'); 2 | const { exitOnNextTick } = require('@aws-amplify/amplify-cli-core'); 3 | const getOutputDirParam = require('../../src/utils/getOutputDirParam'); 4 | 5 | const featureName = 'models'; 6 | 7 | module.exports = { 8 | name: featureName, 9 | run: async context => { 10 | try { 11 | await codeGen.generateModels(context, { overrideOutputDir: getOutputDirParam(context, false) }); 12 | } catch (ex) { 13 | context.print.info(ex.message); 14 | console.log(ex.stack); 15 | await context.usageData.emitError(ex); 16 | exitOnNextTick(1); 17 | } 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/remove.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src/index'); 2 | 3 | const featureName = 'remove'; 4 | 5 | module.exports = { 6 | name: featureName, 7 | run: async context => { 8 | try { 9 | await codeGen.remove(context); 10 | } catch (ex) { 11 | context.print.error(ex.message); 12 | } 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/statements.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src'); 2 | const { exitOnNextTick } = require('@aws-amplify/amplify-cli-core'); 3 | const featureName = 'statements'; 4 | 5 | module.exports = { 6 | name: featureName, 7 | run: async context => { 8 | try { 9 | const forceDownloadSchema = !context.parameters.options.nodownload; 10 | const { maxDepth } = context.parameters.options; 11 | await codeGen.generateStatements(context, forceDownloadSchema, maxDepth); 12 | } catch (ex) { 13 | context.print.info(ex.message); 14 | await context.usageData.emitError(ex); 15 | exitOnNextTick(1); 16 | } 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/commands/codegen/types.js: -------------------------------------------------------------------------------- 1 | const codeGen = require('../../src'); 2 | const { exitOnNextTick } = require('@aws-amplify/amplify-cli-core'); 3 | const featureName = 'types'; 4 | 5 | module.exports = { 6 | name: featureName, 7 | run: async context => { 8 | try { 9 | const forceDownloadSchema = !context.parameters.options.nodownload; 10 | await codeGen.generateTypes(context, forceDownloadSchema); 11 | } catch (ex) { 12 | context.print.info(ex.message); 13 | await context.usageData.emitError(ex); 14 | exitOnNextTick(1); 15 | } 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/amplify-plugin-index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const pluginName = 'codegen'; 4 | 5 | async function executeAmplifyCommand(context) { 6 | let commandPath = path.normalize(path.join(__dirname, '../commands')); 7 | commandPath = path.join(commandPath, pluginName, context.input.command); 8 | const commandModule = require(commandPath); 9 | await commandModule.run(context); 10 | } 11 | 12 | async function handleAmplifyEvent(context, args) { 13 | context.print.info(`${pluginName} handleAmplifyEvent to be implemented`); 14 | context.print.info(`Received event args ${args}`); 15 | } 16 | 17 | module.exports = { 18 | executeAmplifyCommand, 19 | handleAmplifyEvent, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/codegen-config/utils/index.js: -------------------------------------------------------------------------------- 1 | const graphQlToAmplifyConfig = require('./graphQlToAmplifyConfig'); 2 | 3 | module.exports = { graphQlToAmplifyConfig }; 4 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/commands/configure.js: -------------------------------------------------------------------------------- 1 | const { loadConfig } = require('../codegen-config'); 2 | const configureProjectWalkThrough = require('../walkthrough/configure'); 3 | const add = require('./add'); 4 | 5 | async function configure(context) { 6 | let withoutInit = false; 7 | try { 8 | context.amplify.getProjectMeta(); 9 | } catch (e) { 10 | withoutInit = true; 11 | } 12 | const config = loadConfig(context, withoutInit); 13 | if (!config.getProjects().length) { 14 | await add(context); 15 | return; 16 | } 17 | const project = await configureProjectWalkThrough(context, config.getProjects(), withoutInit); 18 | config.addProject(project); 19 | config.save(); 20 | console.log('Codegen configured. Remember to run "amplify codegen" to generate your types and statements.') 21 | } 22 | 23 | module.exports = configure; 24 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/errors/index.js: -------------------------------------------------------------------------------- 1 | class AmplifyCodeGenNotSupportedError extends Error {} 2 | 3 | class AmplifyCodeGenNoAppSyncAPIAvailableError extends Error {} 4 | class AmplifyCodeGenNoProjectAvailableError extends Error {} 5 | 6 | class AmplifyCodeGenAPINotFoundError extends Error {} 7 | class AmplifyCodeGenAPIPendingPush extends Error {} 8 | 9 | module.exports = { 10 | AmplifyCodeGenNotSupportedError, 11 | AmplifyCodeGenNoAppSyncAPIAvailableError, 12 | AmplifyCodeGenNoProjectAvailableError, 13 | AmplifyCodeGenAPINotFoundError, 14 | AmplifyCodeGenAPIPendingPush, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/generateIntrospectionSchemaWithProgress.js: -------------------------------------------------------------------------------- 1 | const Ora = require('ora'); 2 | 3 | const downloadIntrospectionSchema = require('./downloadIntrospectionSchema'); 4 | const constants = require('../constants'); 5 | 6 | async function downloadSchemaWithProgressSpinner(context, apiId, downloadLocation, region) { 7 | if (!downloadLocation.endsWith('.graphql')) { 8 | const downloadSpinner = new Ora(constants.INFO_MESSAGE_DOWNLOADING_SCHEMA); 9 | downloadSpinner.start(); 10 | try { 11 | const schemaLocation = await downloadIntrospectionSchema(context, apiId, downloadLocation, region); 12 | downloadSpinner.succeed(constants.INFO_MESSAGE_DOWNLOAD_SUCCESS); 13 | return schemaLocation; 14 | } catch (e) { 15 | downloadSpinner.fail(constants.INFO_MESSAGE_DOWNLOAD_ERROR); 16 | throw e; 17 | } 18 | } 19 | return downloadLocation; 20 | } 21 | 22 | module.exports = downloadSchemaWithProgressSpinner; 23 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getAndroidResDir.js: -------------------------------------------------------------------------------- 1 | const getFrontendHandler = require('./getFrontEndHandler'); 2 | 3 | const AMPLIFY_FRONTEND_ANDROID_CONFIG_KEY = 'android'; 4 | function getAndroidResDir(context) { 5 | // XXX: create a util function in CLI core and use it 6 | const { amplify } = context; 7 | const frontEndHandler = getFrontendHandler(context); 8 | if (frontEndHandler !== 'android') { 9 | throw new Error('Not an android project'); 10 | } 11 | const config = amplify.getProjectConfig(); 12 | const frontendConfig = config[AMPLIFY_FRONTEND_ANDROID_CONFIG_KEY]; 13 | return frontendConfig.config.ResDir; 14 | } 15 | 16 | module.exports = getAndroidResDir; 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getAppSyncAPIDetails.js: -------------------------------------------------------------------------------- 1 | const getAppSyncAPIs = require('./getAppSyncAPIs'); 2 | 3 | function getAppSyncAPIDetails(context) { 4 | const meta = context.amplify.getProjectMeta(); 5 | const appSyncAPIs = getAppSyncAPIs(meta.api); 6 | if (!appSyncAPIs.length) { 7 | return []; 8 | } 9 | return appSyncAPIs.map(api => ({ 10 | name: api.name, 11 | endpoint: api.output.GraphQLAPIEndpointOutput, 12 | id: api.output.GraphQLAPIIdOutput, 13 | authConfig: api.output.authConfig, 14 | })); 15 | } 16 | 17 | module.exports = getAppSyncAPIDetails; 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getAppSyncAPIInfoFromProject.js: -------------------------------------------------------------------------------- 1 | const getAppSyncAPIInfo = require('./getAppSyncAPIInfo'); 2 | 3 | /* Get AppSync api info if api id and region are avialable. 4 | * Otherwise return undefined. 5 | */ 6 | async function getAppSyncAPIInfoFromProject(context, project) { 7 | if (project.amplifyExtension.apiId && project.amplifyExtension.region) { 8 | const { 9 | amplifyExtension: { apiId, region }, 10 | } = project; 11 | return getAppSyncAPIInfo(context, apiId, region); 12 | } 13 | return undefined; 14 | } 15 | module.exports = getAppSyncAPIInfoFromProject; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getAppSyncAPIs.js: -------------------------------------------------------------------------------- 1 | function getAppSyncAPIs(allAPIs = {}) { 2 | const appSyncAPIs = Object.keys(allAPIs).reduce((acc, apiName) => { 3 | const api = allAPIs[apiName]; 4 | if (api.service === 'AppSync') { 5 | acc.push({ ...api, name: apiName }); 6 | } 7 | return acc; 8 | }, []); 9 | return appSyncAPIs; 10 | } 11 | 12 | module.exports = getAppSyncAPIs; 13 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getFrontEndFramework.js: -------------------------------------------------------------------------------- 1 | const getFrontendHandler = require('./getFrontEndHandler'); 2 | 3 | function getFrontEndFramework(context, withoutInit = false, decoupleFrontend = '', decoupleFramework = '') { 4 | const { amplify } = context; 5 | let frontendHandler = decoupleFrontend; 6 | if (!withoutInit) { 7 | frontendHandler = getFrontendHandler(context); 8 | } 9 | if (frontendHandler === 'javascript') { 10 | if (!withoutInit) { 11 | const projectConfig = amplify.getProjectConfig(); 12 | return projectConfig.javascript.framework; 13 | } 14 | return decoupleFramework; 15 | } 16 | return ''; 17 | } 18 | 19 | module.exports = getFrontEndFramework; 20 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getFrontEndHandler.js: -------------------------------------------------------------------------------- 1 | function getFrontendHandler(context) { 2 | const { amplify } = context; 3 | const projectConfig = amplify.getProjectConfig(); 4 | return projectConfig.frontend; 5 | } 6 | 7 | module.exports = getFrontendHandler; 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getGraphQLDocPath.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | const globParent = require('glob-parent'); 3 | 4 | function getGraphQLDocPath(frontend, graphQLDirectory, includePathGlob) { 5 | if (frontend === 'android') { 6 | return join(graphQLDirectory, 'com/amazonaws/amplify/generated/graphql'); 7 | } 8 | return Array.isArray(includePathGlob) && includePathGlob.length > 0 9 | ? globParent(includePathGlob[0]) 10 | : graphQLDirectory; 11 | } 12 | 13 | module.exports = getGraphQLDocPath; 14 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getIncludePattern.js: -------------------------------------------------------------------------------- 1 | const { join, dirname } = require('path'); 2 | 3 | function getIncludePatterns(language, schemaLocation) { 4 | let graphQLDirectory; 5 | let graphQLExtension; 6 | switch (language) { 7 | case 'android': 8 | graphQLDirectory = dirname(schemaLocation); 9 | graphQLExtension = '*.graphql'; 10 | break; 11 | case 'typescript': 12 | graphQLDirectory = join('src', 'graphql'); 13 | graphQLExtension = '*.ts'; 14 | break; 15 | case 'javascript': 16 | case 'flow': 17 | graphQLDirectory = join('src', 'graphql'); 18 | graphQLExtension = '*.js'; 19 | break; 20 | case 'angular': 21 | graphQLDirectory = join('src', 'graphql'); 22 | graphQLExtension = '*.graphql'; 23 | break; 24 | default: 25 | graphQLDirectory = 'graphql'; 26 | graphQLExtension = '*.graphql'; 27 | } 28 | 29 | return { 30 | graphQLDirectory, 31 | graphQLExtension, 32 | }; 33 | } 34 | 35 | module.exports = getIncludePatterns; 36 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getOutputDirParam.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const getProjectRoot = require('./getProjectRoot'); 3 | 4 | /** 5 | * Retrieve the output directory parameter from the command line. Throws on invalid value, 6 | * or if isRequired is set and the flag isn't in the options. Returns null on optional and not defined. 7 | * @param {!import('@aws-amplify/amplify-cli-core').$TSContext} context the CLI invocation context 8 | * @param {!boolean} isRequired whether or not the flag is required 9 | * @returns {!string} the absolute path to the output directory 10 | */ 11 | function getOutputDirParam(context, isRequired) { 12 | const outputDirParam = context.parameters?.options?.['output-dir']; 13 | if ( isRequired && !outputDirParam ) { 14 | throw new Error('Expected --output-dir flag to be set'); 15 | } 16 | if ( !outputDirParam ) { 17 | return null; 18 | } 19 | return path.isAbsolute(outputDirParam) ? outputDirParam : path.join(getProjectRoot(context), outputDirParam); 20 | } 21 | 22 | module.exports = getOutputDirParam; 23 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getProjectAWSRegion.js: -------------------------------------------------------------------------------- 1 | function getProjectAWSRegion(context) { 2 | const projectMeta = context.amplify.getProjectMeta(); 3 | const { awscloudformation } = projectMeta.providers; 4 | return awscloudformation.Region; 5 | } 6 | 7 | module.exports = getProjectAWSRegion; 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getProjectRoot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Find the project root. 3 | * @param {!import('@aws-amplify/amplify-cli-core').$TSContext} context the amplify runtime context 4 | * @returns {!string} the project root, or cwd 5 | */ 6 | const getProjectRoot = (context) => { 7 | try { 8 | return context.amplify.getEnvInfo().projectPath; 9 | } catch (_) { 10 | return process.cwd(); 11 | } 12 | }; 13 | 14 | module.exports = getProjectRoot; 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getRelativeTypesPath.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | function getRelativeTypesPath(opsGenDirectory, generatedFileName) { 4 | if (generatedFileName) { 5 | const relativePath = path 6 | .relative(opsGenDirectory, generatedFileName) 7 | // ensure posix path separators are used 8 | // Fallback to \ because path.win32 is not implemented by path-browserify 9 | .split(path.win32?.sep || '\\') 10 | .join(path.posix.sep); 11 | 12 | // generatedFileName is in same directory as opsGenDirectory 13 | // i.e. generatedFileName: src/graphql/API.ts, opsGenDirectory: src/graphql 14 | if (!relativePath.startsWith('.')) { 15 | // path.join will strip prefixed ./ 16 | return `./${relativePath}`; 17 | } 18 | 19 | return relativePath; 20 | } 21 | return null; 22 | } 23 | 24 | module.exports = getRelativeTypesPath; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/getSDLSchemaLocation.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | function getSDLSchemaLocation(apiName) { 4 | return path.join('amplify', 'backend', 'api', apiName, 'build', 'schema.graphql'); 5 | } 6 | 7 | module.exports = getSDLSchemaLocation; 8 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/isAppSyncApiPendingPush.js: -------------------------------------------------------------------------------- 1 | async function isAppSyncApiPendingPush(context) { 2 | const resourceStatus = await context.amplify.getResourceStatus('api'); 3 | const appSyncResources = []; 4 | ['resourcesToBeCreated', 'resourcesToBeUpdated'].forEach(opName => { 5 | const status = resourceStatus[opName]; 6 | status.forEach(resource => { 7 | if (resource.service === 'AppSync') { 8 | appSyncResources.push(resource); 9 | } 10 | }); 11 | }); 12 | 13 | return appSyncResources.length > 0; 14 | } 15 | 16 | module.exports = isAppSyncApiPendingPush; 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/isCodegenConfigured.js: -------------------------------------------------------------------------------- 1 | const { loadConfig } = require('../codegen-config'); 2 | 3 | function isCodegenConfigured(context, apiName) { 4 | const config = loadConfig(context); 5 | const projects = config.getProjects(); 6 | if (apiName) { 7 | const isConfigured = projects.find(p => p.projectName === apiName); 8 | return isConfigured !== undefined; 9 | } 10 | 11 | return projects.length > 0; 12 | } 13 | 14 | module.exports = isCodegenConfigured; 15 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/readSchemaFromFile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | function readSchemaFromFile(schemaPath) { 4 | if (!fs.existsSync(schemaPath)) { 5 | throw new Error(`Cannot find GraphQL schema file: ${schemaPath}`); 6 | } 7 | return fs.readFileSync(schemaPath, 'utf8'); 8 | } 9 | 10 | module.exports = { readSchemaFromFile }; 11 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/switchToSDLSchema.js: -------------------------------------------------------------------------------- 1 | const { loadConfig } = require('../codegen-config'); 2 | const getSDLSchemaPath = require('./getSDLSchemaLocation'); 3 | const getFrontendHandler = require('./getFrontEndHandler'); 4 | 5 | function switchToSDLSchema(context, apiName) { 6 | if (getFrontendHandler(context) === 'android') { 7 | return false; 8 | } 9 | const config = loadConfig(context); 10 | const projects = config.getProjects(); 11 | const project = projects.find(p => p.projectName === apiName); 12 | if (project) { 13 | if (project.schema.endsWith('.json')) { 14 | project.schema = getSDLSchemaPath(apiName); 15 | config.addProject(project); 16 | config.save(); 17 | return true; 18 | } 19 | return false; 20 | } 21 | throw new Error(`Codegen is not configured with API ${apiName}`); 22 | } 23 | 24 | module.exports = switchToSDLSchema; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/validateAmplifyFlutterMinSupportedVersion.js: -------------------------------------------------------------------------------- 1 | const { validateAmplifyFlutterVersion } = require('./validateAmplifyFlutterVersion'); 2 | 3 | const MINIMUM_SUPPORTED_VERSION_CONSTRAINT = '>=0.6.0'; 4 | 5 | function validateAmplifyFlutterMinSupportedVersion(projectRoot) { 6 | return validateAmplifyFlutterVersion(projectRoot, MINIMUM_SUPPORTED_VERSION_CONSTRAINT); 7 | } 8 | 9 | module.exports = { validateAmplifyFlutterMinSupportedVersion, MINIMUM_SUPPORTED_VERSION_CONSTRAINT }; -------------------------------------------------------------------------------- /packages/amplify-codegen/src/utils/validateDartSDK.js: -------------------------------------------------------------------------------- 1 | const yaml = require('js-yaml'); 2 | const path = require('path'); 3 | const fs = require('fs-extra'); 4 | const semver = require('semver'); 5 | 6 | const PUBSPEC_FILE_NAME = 'pubspec.yaml'; 7 | 8 | function validateDartSDK(context, projectRoot) { 9 | try { 10 | const config = yaml.load(fs.readFileSync(path.join(projectRoot, PUBSPEC_FILE_NAME), 'utf8')); 11 | const version = semver.minVersion(config.environment.sdk); 12 | if (semver.satisfies(version, '>= 2.12.0', { includePrerelease: true })) { 13 | context.print.warning('\nDetected Dart SDK version 2.12.0 or above'); 14 | return true; 15 | } 16 | context.print.warning('\nDetected Dart SDK version below 2.12.0'); 17 | return false; 18 | } catch (e) { 19 | context.print.warning('\nCould not detect Dart SDK version, defaulting to 2.12.0'); 20 | return true; 21 | } 22 | } 23 | 24 | module.exports = { PUBSPEC_FILE_NAME, validateDartSDK }; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/changeAppSyncRegions.js: -------------------------------------------------------------------------------- 1 | const askShouldTryWithDifferentRegion = require('./questions/changeRegion'); 2 | const changeRegion = require('./questions/selectRegions'); 3 | 4 | async function changeAppSyncRegion(context, currentRegion) { 5 | const regions = await context.amplify.executeProviderUtils(context, 'awscloudformation', 'getRegionMappings'); 6 | 7 | const shouldRetry = await askShouldTryWithDifferentRegion(); 8 | const region = shouldRetry && (await changeRegion(regions, currentRegion)); 9 | return { 10 | shouldRetry, 11 | region, 12 | }; 13 | } 14 | 15 | module.exports = changeAppSyncRegion; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/apiTarget.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askAppSyncAPITarget(context, apis, selectedApi = null) { 6 | const choices = apis.map(api => ({ name: api.name, value: api.id })); 7 | if (apis.length === 1) { 8 | return apis[0].id; 9 | } 10 | 11 | const answer = await inquirer.prompt([ 12 | { 13 | name: 'apiId', 14 | message: constants.PROMPT_MSG_API_LIST, 15 | type: 'list', 16 | choices, 17 | default: selectedApi || null, 18 | }, 19 | ]); 20 | 21 | return answer.apiId; 22 | } 23 | 24 | module.exports = askAppSyncAPITarget; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/changeRegion.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askShouldChangeRegion() { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'changeRegion', 9 | message: constants.PROMPT_MSG_CHANGE_REGION, 10 | type: 'confirm', 11 | default: true, 12 | }, 13 | ]); 14 | 15 | return answer.changeRegion; 16 | } 17 | 18 | module.exports = askShouldChangeRegion; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/generateCode.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askGenerateCode() { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'confirmGenerateCode', 9 | message: constants.PROMPT_MSG_GENERATE_CODE, 10 | type: 'confirm', 11 | default: true, 12 | }, 13 | ]); 14 | 15 | return answer.confirmGenerateCode; 16 | } 17 | 18 | module.exports = askGenerateCode; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/generateDocs.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askGenerateDocs() { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'confirmGenerateOperations', 9 | message: constants.PROMPT_MSG_GENERATE_OPS, 10 | type: 'confirm', 11 | default: true, 12 | }, 13 | ]); 14 | 15 | return answer.confirmGenerateOperations; 16 | } 17 | 18 | module.exports = askGenerateDocs; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/generatedFileName.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | const { getOutputFileName } = require('@aws-amplify/graphql-types-generator'); 3 | 4 | const constants = require('../../constants'); 5 | 6 | async function askGeneratedFileName(name, target) { 7 | const answers = await inquirer.prompt([ 8 | { 9 | name: 'generatedFileName', 10 | type: 'input', 11 | message: constants.PROMPT_MSG_FILE_NAME, 12 | default: getOutputFileName(name, target), 13 | }, 14 | ]); 15 | return answers.generatedFileName; 16 | } 17 | 18 | module.exports = askGeneratedFileName; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/maxDepth.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askMaxDepth(defaultDepth = 2) { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'maxDepth', 9 | message: constants.PROMPT_MSG_MAX_DEPTH, 10 | type: 'input', 11 | validate: val => { 12 | const num = Number.parseInt(val, 10); 13 | return Number.isInteger(num) && Number.isFinite(num) && num > 0 ? true : constants.ERROR_MSG_MAX_DEPTH; 14 | }, 15 | default: defaultDepth, 16 | }, 17 | ]); 18 | 19 | return Number.parseInt(answer.maxDepth, 10); 20 | } 21 | 22 | module.exports = askMaxDepth; 23 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/queryFilePattern.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askCodeGenQueryFilePattern(includePattern = ['**/*.graphql']) { 6 | const answers = await inquirer.prompt([ 7 | { 8 | name: 'includePattern', 9 | type: 'input', 10 | message: constants.PROMPT_MSG_GQL_FILE_PATTERN, 11 | default: includePattern.join(','), 12 | }, 13 | ]); 14 | return answers.includePattern.split(',').map(pattern => pattern.trim()); 15 | } 16 | 17 | module.exports = askCodeGenQueryFilePattern; 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/selectFramework.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | async function askForFramework(frameworks) { 4 | const selectFramework = { 5 | type: 'list', 6 | name: 'selectedFramework', 7 | message: 'What javascript framework are you using', 8 | choices: frameworks, 9 | default: 'react', 10 | }; 11 | const answer = await inquirer.prompt(selectFramework); 12 | return answer.selectedFramework; 13 | } 14 | 15 | module.exports = askForFramework; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/selectFrontend.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | async function askForFrontend(frontends) { 4 | const selectFrontend = { 5 | type: 'list', 6 | name: 'selectedFrontend', 7 | message: "Choose the type of app that you're building", 8 | choices: frontends, 9 | default: 'javascript', 10 | }; 11 | const answer = await inquirer.prompt(selectFrontend); 12 | return answer.selectedFrontend; 13 | } 14 | 15 | module.exports = askForFrontend; 16 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/selectProject.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const { AmplifyCodeGenNoAppSyncAPIAvailableError } = require('../../errors'); 4 | const constants = require('../../constants'); 5 | 6 | async function askForProject(context, projects) { 7 | if (projects.length === 0) { 8 | throw new AmplifyCodeGenNoAppSyncAPIAvailableError(constants.ERROR_CODEGEN_NO_API_AVAILABLE); 9 | } 10 | if (projects.length === 1) { 11 | return projects[0].value; 12 | } 13 | const answer = await inquirer.prompt([ 14 | { 15 | name: 'projectName', 16 | message: constants.PROMPT_MSG_SELECT_PROJECT, 17 | type: 'list', 18 | choices: projects, 19 | }, 20 | ]); 21 | return answer.projectName; 22 | } 23 | 24 | module.exports = askForProject; 25 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/selectRegions.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function selectRegions(regions, currentRegion) { 6 | const regionMap = Object.keys(regions).map(r => ({ 7 | value: r, 8 | name: regions[r], 9 | })); 10 | const answer = await inquirer.prompt([ 11 | { 12 | name: 'region', 13 | type: 'list', 14 | message: constants.PROMPT_MSG_SELECT_REGION, 15 | choices: regionMap, 16 | default: currentRegion || null, 17 | }, 18 | ]); 19 | return answer.region; 20 | } 21 | 22 | module.exports = selectRegions; 23 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/updateCode.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askUpdateCode() { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'confirmUpdateCode', 9 | message: constants.PROMPT_MSG_UPDATE_CODE, 10 | type: 'confirm', 11 | default: true, 12 | }, 13 | ]); 14 | 15 | return answer.confirmUpdateCode; 16 | } 17 | 18 | module.exports = askUpdateCode; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/src/walkthrough/questions/updateDocs.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const constants = require('../../constants'); 4 | 5 | async function askUpdateDocs() { 6 | const answer = await inquirer.prompt([ 7 | { 8 | name: 'confirmUpdateDocs', 9 | message: constants.PROMPT_MSG_UPDATE_STATEMENTS, 10 | type: 'confirm', 11 | default: true, 12 | }, 13 | ]); 14 | 15 | return answer.confirmUpdateDocs; 16 | } 17 | 18 | module.exports = askUpdateDocs; 19 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/codegen-config/index.test.js: -------------------------------------------------------------------------------- 1 | const AmplifyCodeGenConfig = require('../../src/codegen-config/AmplifyCodeGenConfig'); 2 | 3 | const { loadConfig, getCodegenConfig } = require('../../src/codegen-config'); 4 | 5 | jest.mock('../../src/codegen-config/AmplifyCodeGenConfig'); 6 | const MOCK_PROJECT_ROOT = 'mockpath'; 7 | const MOCK_CONTEXT = { 8 | amplify: { 9 | getEnvInfo: jest.fn().mockReturnValue({ projectPath: MOCK_PROJECT_ROOT }) 10 | } 11 | }; 12 | 13 | describe('codegen-config', () => { 14 | it('is singleton', () => { 15 | loadConfig(MOCK_CONTEXT); 16 | expect(AmplifyCodeGenConfig).toHaveBeenCalledWith(MOCK_PROJECT_ROOT); 17 | loadConfig(MOCK_CONTEXT); 18 | expect(AmplifyCodeGenConfig).toHaveBeenCalledTimes(1); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/utils/getFrontendHandler.test.js: -------------------------------------------------------------------------------- 1 | const getFrontendHandler = require('../../src/utils/getFrontEndHandler'); 2 | 3 | describe('getFrontendHandler', () => { 4 | const mockFrontEndHandler = 'someRandomHandler'; 5 | const mockProjectConfig = { 6 | frontend: 'someRandomHandler', 7 | }; 8 | const mockGetProjectConfig = jest.fn(); 9 | const mockContext = { 10 | amplify: { 11 | getProjectConfig: mockGetProjectConfig, 12 | }, 13 | }; 14 | beforeEach(() => { 15 | mockGetProjectConfig.mockReturnValue(mockProjectConfig); 16 | }); 17 | it('should get the frontend handler from the project config', () => { 18 | expect(getFrontendHandler(mockContext)).toEqual(mockFrontEndHandler); 19 | expect(mockGetProjectConfig).toHaveBeenCalled(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/utils/getProjectRoot.test.js: -------------------------------------------------------------------------------- 1 | const getProjectRoot = require('../../src/utils/getProjectRoot'); 2 | const path = require('path'); 3 | const process = require('process'); 4 | 5 | const PROJECT_PATH = path.join(__dirname, 'project'); 6 | 7 | describe('getProjectRoot', () => { 8 | it('returns project path from context when it returns', () => { 9 | expect(getProjectRoot(({ 10 | amplify: { 11 | getEnvInfo: () => ({ projectPath: PROJECT_PATH }), 12 | }, 13 | }))).toEqual(PROJECT_PATH); 14 | }); 15 | 16 | it('returns os.cwd when context throws', () => { 17 | expect(getProjectRoot(({ 18 | amplify: { 19 | getEnvInfo: () => { 20 | throw new Error(); 21 | }, 22 | }, 23 | }))).toEqual(process.cwd()); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/walkthrough/questions/generateCode.test.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const askGenerateCode = require('../../../src/walkthrough/questions/generateCode'); 4 | 5 | jest.mock('inquirer'); 6 | 7 | describe('shouldGenerateCode', () => { 8 | inquirer.prompt.mockReturnValue({ confirmGenerateCode: false }); 9 | it('should confirm users if they want to generate the code', async () => { 10 | const answer = await askGenerateCode(); 11 | expect(answer).toBe(false); 12 | const questions = inquirer.prompt.mock.calls[0][0]; 13 | expect(questions[0].name).toEqual('confirmGenerateCode'); 14 | expect(questions[0].type).toEqual('confirm'); 15 | expect(questions[0].default).toEqual(true); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/walkthrough/questions/generateDocs.test.js: -------------------------------------------------------------------------------- 1 | const generateDocs = require('../../../src/walkthrough/questions/generateDocs'); 2 | const { prompt } = require('inquirer'); 3 | 4 | jest.mock('inquirer'); 5 | prompt.mockReturnValue({ 6 | confirmGenerateOperations: true, 7 | }); 8 | describe('generateDocs', () => { 9 | it('should ask if the user if they want to generate GraphQL Docs from schema', async () => { 10 | const asnwer = await generateDocs(); 11 | expect(asnwer).toEqual(true); 12 | expect(prompt).toHaveBeenCalled(); 13 | const callArgs = prompt.mock.calls[0][0][0]; 14 | expect(callArgs.name).toEqual('confirmGenerateOperations'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/walkthrough/questions/queryFilePattern.test.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const askCodegneQueryFilePattern = require('../../../src/walkthrough/questions/queryFilePattern'); 4 | 5 | jest.mock('inquirer'); 6 | 7 | describe('askCodegneQueryFilePattern', () => { 8 | const includePattern = 'src/**/*.gql'; 9 | inquirer.prompt.mockReturnValue({ includePattern }); 10 | it('should ask user for query file pattern', async () => { 11 | const answer = await askCodegneQueryFilePattern(); 12 | expect(answer).toEqual([includePattern]); 13 | const questions = inquirer.prompt.mock.calls[0][0]; 14 | expect(questions[0].name).toEqual('includePattern'); 15 | expect(questions[0].type).toEqual('input'); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/amplify-codegen/tests/walkthrough/questions/updateDocs.test.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer'); 2 | 3 | const updateDocs = require('../../../src/walkthrough/questions/updateDocs'); 4 | 5 | jest.mock('inquirer'); 6 | 7 | describe('shouldUpdateDocs', () => { 8 | inquirer.prompt.mockReturnValue({ confirmUpdateDocs: false }); 9 | it('should confirm users if they want to update the docs', async () => { 10 | const answer = await updateDocs(); 11 | expect(answer).toBe(false); 12 | const questions = inquirer.prompt.mock.calls[0][0]; 13 | expect(questions[0].name).toEqual('confirmUpdateDocs'); 14 | expect(questions[0].type).toEqual('confirm'); 15 | expect(questions[0].default).toEqual(true); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/.npmignore: -------------------------------------------------------------------------------- 1 | **/__mocks__/** 2 | **/__tests__/** 3 | src 4 | scripts 5 | tsconfig.json 6 | tsconfig.tsbuildinfo 7 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/scripts/generateStandaloneValidationFunction.ts: -------------------------------------------------------------------------------- 1 | import Ajv from 'ajv'; 2 | import modelIntrospectionSchemaDefinition from '../schemas/introspection/1/ModelIntrospectionSchema.json' 3 | import { join } from 'path'; 4 | import { writeFileSync } from 'fs'; 5 | 6 | const standaloneCode = require("ajv/dist/standalone").default 7 | 8 | const ajv = new Ajv({ code: { source: true } }); 9 | const validate = ajv.compile(modelIntrospectionSchemaDefinition); 10 | 11 | let moduleCode = standaloneCode(ajv, validate) 12 | 13 | // Now you can write the module code to file 14 | writeFileSync(join(__dirname, "../src/validate-cjs.js"), moduleCode) -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/__tests__/utils/fieldUtils.test.ts: -------------------------------------------------------------------------------- 1 | import { toCamelCase } from "../../utils/fieldUtils"; 2 | 3 | describe('Field util function tests', () => { 4 | describe('toCamelCase test', () => { 5 | it('should construct the string array to a camel case phrase', () => { 6 | const words: string[] = ['AMPlify', 'data', 'build', 'time']; 7 | expect(toCamelCase(words)).toBe('aMPlifyDataBuildTime'); 8 | }); 9 | }); 10 | }); -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/__tests__/utils/validate-java.ts: -------------------------------------------------------------------------------- 1 | import { parse } from 'java-ast'; 2 | 3 | export function validateJava(content: string): void { 4 | const originalErr = console['error']; 5 | const collectedErrors: string[] = []; 6 | console['error'] = (errorStr: string) => { 7 | collectedErrors.push(errorStr); 8 | }; 9 | parse(content); 10 | console['error'] = originalErr; 11 | 12 | if (collectedErrors.length > 0) { 13 | const mergedErrors = collectedErrors.join('\n'); 14 | 15 | throw new Error(`Invalid Java code:\n${mergedErrors}`); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/configs/swift-config.ts: -------------------------------------------------------------------------------- 1 | export const schemaTypeMap: Record = { 2 | ID: '.string', 3 | String: '.string', 4 | Int: '.int', 5 | Float: '.double', 6 | Boolean: '.bool', 7 | AWSDate: '.date', 8 | AWSTime: '.time', 9 | AWSDateTime: '.dateTime', 10 | AWSTimestamp: '.int', 11 | AWSEmail: '.string', 12 | AWSJSON: '.string', 13 | AWSURL: '.string', 14 | AWSPhone: '.string', 15 | AWSIPAddress: '.string', 16 | }; 17 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | import { RawDocumentsConfig } from '@graphql-codegen/visitor-plugin-common'; 2 | 3 | export interface AppSyncModelPluginConfig extends RawDocumentsConfig { 4 | directives?: string; 5 | } 6 | 7 | export * from './plugin'; 8 | export * from './preset'; 9 | export * from './interfaces/introspection'; 10 | export { SyncTypes } from './types/sync' 11 | 12 | export const addToSchema = (config: AppSyncModelPluginConfig) => { 13 | const result: string[] = []; 14 | if (config.scalars) { 15 | if (typeof config.scalars === 'string') { 16 | result.push(config.scalars); 17 | } else { 18 | result.push(...Object.keys(config.scalars).map(scalar => `scalar ${scalar}`)); 19 | } 20 | } 21 | if (config.directives) { 22 | if (typeof config.directives === 'string') { 23 | result.push(config.directives); 24 | } 25 | } 26 | 27 | return result.join('\n'); 28 | }; 29 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/interfaces/introspection/index.ts: -------------------------------------------------------------------------------- 1 | export * from './model-schema'; -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/scalars/supported-scalars.ts: -------------------------------------------------------------------------------- 1 | // Used only in tests. Directive definition will be passed as part of the configuration when modelgen is run using CLI 2 | export const scalars = [ 3 | 'ID', 4 | 'String', 5 | 'Int', 6 | 'Float', 7 | 'Boolean', 8 | 'AWSDate', 9 | 'AWSDateTime', 10 | 'AWSTime', 11 | 'AWSTimestamp', 12 | 'AWSEmail', 13 | 'AWSJSON', 14 | 'AWSURL', 15 | 'AWSPhone', 16 | 'AWSIPAddress', 17 | ] 18 | .map(typeName => `scalar ${typeName}`) 19 | .join(); 20 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const TransformerV2DirectiveName = { 2 | HAS_ONE: 'hasOne', 3 | HAS_MANY: 'hasMany', 4 | BELONGS_TO: 'belongsTo', 5 | MODEL: 'model', 6 | AUTH: 'auth', 7 | PRIMARY_KEY: 'primaryKey', 8 | INDEX: 'index', 9 | DEFAULT: 'default', 10 | SEARCHABLE: 'searchable', 11 | GENERATION: 'generation', 12 | CONVERSATION: 'conversation', 13 | }; 14 | export const DEFAULT_HASH_KEY_FIELD = 'id'; 15 | export const DEFAULT_CREATED_TIME = 'createdAt'; 16 | export const DEFAULT_UPDATED_TIME = 'updatedAt'; 17 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/generateLicense.ts: -------------------------------------------------------------------------------- 1 | export function generateLicense(): string { 2 | return `/* 3 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"). 6 | * You may not use this file except in compliance with the License. 7 | * A copy of the License is located at 8 | * 9 | * http://aws.amazon.com/apache2.0 10 | * 11 | * or in the "license" file accompanying this file. This file is distributed 12 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | * express or implied. See the License for the specific language governing 14 | * permissions and limitations under the License. 15 | */`; 16 | } 17 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/process-primary-key.ts: -------------------------------------------------------------------------------- 1 | import { CodeGenModel } from '../visitors/appsync-visitor'; 2 | import { getDirective } from './fieldUtils'; 3 | 4 | /** 5 | * Maps @primaryKey directives back to how they would be represented with the old @key directive 6 | * @param model The model to translate 7 | */ 8 | export const processPrimaryKey = (model: CodeGenModel) => { 9 | const alreadyHasPrimaryKeySanityCheck = model.directives.some( 10 | directive => directive.name === 'key' && directive.arguments.name === undefined, 11 | ); 12 | if (alreadyHasPrimaryKeySanityCheck) { 13 | return; 14 | } 15 | const primaryKeyField = model.fields.find(field => getDirective(field)('primaryKey')); 16 | if (!primaryKeyField) { 17 | return; 18 | } 19 | const primaryKeyDirective = getDirective(primaryKeyField)('primaryKey')!; 20 | model.directives.push({ 21 | name: 'key', 22 | arguments: { 23 | fields: [primaryKeyField.name].concat((primaryKeyDirective.arguments.sortKeyFields as string[]) ?? []), 24 | }, 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/sort.ts: -------------------------------------------------------------------------------- 1 | export function sortFields(a: { name: string }, b: { name: string }) { 2 | if (a.name > b.name) return 1; 3 | if (a.name == b.name) return 0; 4 | return -1; 5 | } 6 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/stringUtils.ts: -------------------------------------------------------------------------------- 1 | export function toUpper(word: string): string { 2 | return word.charAt(0).toUpperCase() + word.slice(1); 3 | } 4 | 5 | export function toLower(word: string): string { 6 | return word.charAt(0).toLowerCase() + word.slice(1); 7 | } 8 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/validate-field-name.ts: -------------------------------------------------------------------------------- 1 | import { camelCase } from "change-case"; 2 | import { CodeGenModelMap } from "../visitors/appsync-visitor"; 3 | 4 | /** 5 | * Validate if two field names have identical camelCase output. This will cause compile error in Java modelgen output. 6 | * e.g 'due_date' and 'dueDate' will result in the same 'dueDate' 7 | */ 8 | export function validateFieldName(models: CodeGenModelMap) : void { 9 | Object.entries(models).forEach(([modelName, model]) => { 10 | let validateMap: any = {}; 11 | model.fields.forEach(field => { 12 | const key = camelCase(field.name) 13 | if (key in validateMap) { 14 | throw new Error(`Fields "${field.name}" and "${validateMap[key]}" in ${model.name} cannot be used at the same time which will result in the duplicate builder method.`); 15 | } 16 | validateMap[key] = field.name; 17 | }); 18 | }); 19 | } -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/src/utils/warn.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | const printedWarnings: string[] = []; 3 | 4 | export function printWarning(message: string): void { 5 | if (!printedWarnings.includes(message)) { 6 | console.warn(`${chalk.bgYellow.black('warning:')} ${message}`); 7 | printedWarnings.push(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/appsync-modelgen-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib", 6 | "allowJs": true, 7 | }, 8 | "include": [ 9 | "src/**/*", 10 | "src/schemas/**/*.json" 11 | ], 12 | "exclude": [ 13 | "scripts", 14 | "lib", 15 | "src/__tests__", 16 | "coverage", 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/.npmignore: -------------------------------------------------------------------------------- 1 | **/__mocks__/** 2 | **/__tests__/** 3 | __integration__ 4 | src 5 | fixtures 6 | tsconfig.json 7 | tsconfig.tsbuildinfo -------------------------------------------------------------------------------- /packages/graphql-docs-generator/__tests__/generator/utils/isRequired.test.ts: -------------------------------------------------------------------------------- 1 | import isRequired from '../../../src/generator/utils/isRequired'; 2 | import { 3 | GraphQLScalarType, 4 | Kind, 5 | GraphQLInt, 6 | GraphQLObjectType, 7 | GraphQLString, 8 | GraphQLNonNull, 9 | GraphQLList, 10 | GraphQLInputObjectType, 11 | } from 'graphql'; 12 | describe('isRequired', () => { 13 | const testObj = new GraphQLInputObjectType({ 14 | name: 'Address', 15 | fields: { 16 | street: { type: GraphQLString }, 17 | requiredInt: { type: new GraphQLNonNull(GraphQLInt) }, 18 | }, 19 | }); 20 | 21 | it('should return false for null types', () => { 22 | expect(isRequired(testObj.getFields().street.type)).toEqual(false); 23 | }); 24 | 25 | it('should return true for non null types', () => { 26 | expect(isRequired(testObj.getFields().requiredInt.type)).toEqual(true); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/bin/cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const cli = require('../lib/cli') 4 | cli.run() -------------------------------------------------------------------------------- /packages/graphql-docs-generator/fixtures/foo.gql: -------------------------------------------------------------------------------- 1 | # this is an auto generated file. This will be overwritten 2 | query GetCompleteEvent($eventId: ID!) { 3 | getCompleteEvent(eventId: $eventId) { 4 | _id 5 | createdOn 6 | en { 7 | name 8 | info 9 | banner 10 | nextVenue { 11 | address 12 | date 13 | } 14 | previousVenues { 15 | address 16 | date 17 | } 18 | previousSpeakers 19 | nextSpeaker 20 | gallery 21 | attendees 22 | alertMessage 23 | eventJoinLink 24 | status 25 | } 26 | hi { 27 | name 28 | info 29 | banner 30 | nextVenue { 31 | address 32 | date 33 | } 34 | previousVenues { 35 | address 36 | date 37 | } 38 | previousSpeakers 39 | nextSpeaker 40 | gallery 41 | attendees 42 | alertMessage 43 | eventJoinLink 44 | status 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/fixtures/fragments.graphql: -------------------------------------------------------------------------------- 1 | # this is an auto generated file. This will be overwritten 2 | fragment S3Object on S3Object { 3 | bucket 4 | key 5 | region 6 | } 7 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/fixtures/heroQuery.graphql: -------------------------------------------------------------------------------- 1 | query hero { 2 | hero { 3 | name, 4 | friends { 5 | name 6 | } 7 | friendsConnection { 8 | totalCount, 9 | } 10 | appearsIn 11 | ...HeroFragment 12 | ...DroidFragment 13 | } 14 | } 15 | 16 | fragment DroidFragment on Droid { 17 | primaryFunction 18 | } 19 | 20 | fragment HeroFragment on Human { 21 | height 22 | } 23 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/fixtures/queries.graphql: -------------------------------------------------------------------------------- 1 | # this is an auto generated file. This will be overwritten 2 | query SinglePost($id: ID!) { 3 | singlePost(id: $id) { 4 | id 5 | author 6 | title 7 | content 8 | url 9 | ups 10 | downs 11 | file { 12 | ...S3Object 13 | } 14 | version 15 | } 16 | } 17 | query GetPost($id: ID!) { 18 | getPost(id: $id) { 19 | id 20 | author 21 | title 22 | content 23 | url 24 | ups 25 | downs 26 | file { 27 | ...S3Object 28 | } 29 | version 30 | } 31 | } 32 | query ListPosts($first: Int, $after: String) { 33 | listPosts(first: $first, after: $after) { 34 | items { 35 | id 36 | author 37 | title 38 | content 39 | url 40 | ups 41 | downs 42 | version 43 | } 44 | nextToken 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/generateOperation.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLField, GraphQLSchema } from 'graphql'; 2 | 3 | import getArgs from './getArgs'; 4 | import getBody from './getBody'; 5 | import { GQLTemplateGenericOp, GQLTemplateArgDeclaration, GQLTemplateOpBody, GQLDocsGenOptions } from './types'; 6 | 7 | export default function generateOperation( 8 | operation: GraphQLField, 9 | schema: GraphQLSchema, 10 | maxDepth: number = 3, 11 | options: GQLDocsGenOptions 12 | ): GQLTemplateGenericOp { 13 | const args: Array = getArgs(operation.args); 14 | const body: GQLTemplateOpBody = getBody(operation, schema, maxDepth, options); 15 | return { 16 | args, 17 | body, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/getArgs.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLArgument } from 'graphql'; 2 | 3 | import getType from './utils/getType'; 4 | import isList from './utils/isList'; 5 | import isRequired from './utils/isRequired'; 6 | import isRequiredList from './utils/isRequiredList'; 7 | 8 | import { GQLTemplateArgDeclaration } from './types'; 9 | 10 | export default function getArgs(args: GraphQLArgument[]): Array { 11 | const argMaps = args.map((arg: GraphQLArgument) => ({ 12 | name: arg.name, 13 | type: getType(arg.type).name, 14 | isRequired: isRequired(arg.type), 15 | isList: isList(arg.type), 16 | isListRequired: isRequiredList(arg.type), 17 | defaultValue: arg.defaultValue, 18 | })); 19 | return argMaps; 20 | } 21 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/getBody.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLField, GraphQLSchema } from 'graphql'; 2 | 3 | import getFields from './getFields'; 4 | import { GQLTemplateOpBody, GQLTemplateArgInvocation, GQLTemplateField, GQLDocsGenOptions } from './types'; 5 | 6 | export default function getBody( 7 | op: GraphQLField, 8 | schema: GraphQLSchema, 9 | maxDepth: number = 3, 10 | options: GQLDocsGenOptions 11 | ): GQLTemplateOpBody { 12 | const args: Array = op.args.map(arg => ({ 13 | name: arg.name, 14 | value: `\$${arg.name}`, 15 | })); 16 | const fields: GQLTemplateField = getFields(op, schema, maxDepth, options); 17 | return { 18 | args, 19 | ...fields, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | import generate from './generate'; 3 | export { generateMutations, generateSubscriptions, generateQueries, lowerCaseFirstLetter } from './generateAllOperations'; 4 | export { buildSchema } from './utils/loading'; 5 | export { getTemplatePartials, getOperationPartial, getExternalFragmentPartial } from './utils/templates'; 6 | export default generate; 7 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/getSchemaType.ts: -------------------------------------------------------------------------------- 1 | import { SchemaType } from '../types'; 2 | 3 | /* 4 | Determines if the schema is GraphQL SDL or Introspection, 5 | which are the current supported formats. 6 | */ 7 | export const getSchemaType = (schema: string) => { 8 | try { 9 | const schemaData = JSON.parse(schema); 10 | 11 | if (schemaData.data || schemaData.__schema) { 12 | return SchemaType.INTROSPECTION; 13 | } 14 | } 15 | catch { 16 | return SchemaType.SDL; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/getType.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLList, GraphQLNonNull, GraphQLType } from 'graphql'; 2 | 3 | import { GQLConcreteType } from '../types'; 4 | 5 | export default function getType(typeObj: GraphQLType): GQLConcreteType { 6 | if (typeObj instanceof GraphQLList || typeObj instanceof GraphQLNonNull) { 7 | return getType(typeObj.ofType); 8 | } 9 | return typeObj; 10 | } 11 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/isList.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLType, isNonNullType, isListType } from 'graphql'; 2 | 3 | export default function isList(typeObj: GraphQLType): boolean { 4 | if (isNonNullType(typeObj)) { 5 | return isList(typeObj.ofType); 6 | } 7 | return isListType(typeObj); 8 | } 9 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/isRequired.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLType, isNonNullType, isListType } from 'graphql'; 2 | export default function isRequired(typeObj: GraphQLType): boolean { 3 | if (isNonNullType(typeObj) && isListType(typeObj.ofType)) { 4 | // See if it's a Non-null List of Non-null Types 5 | return isRequired(typeObj.ofType.ofType); 6 | } 7 | if (isListType(typeObj)) { 8 | // See if it's a Nullable List of Non-null Types 9 | return isNonNullType(typeObj.ofType); 10 | } 11 | return isNonNullType(typeObj); 12 | } 13 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/isRequiredList.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLType, isNonNullType, isListType } from 'graphql'; 2 | export default function isRequired(typeObj: GraphQLType): boolean { 3 | return isNonNullType(typeObj) && isListType(typeObj.ofType); 4 | } 5 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/generator/utils/isS3Object.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLType, isObjectType, isScalarType } from 'graphql'; 2 | import getType from './getType'; 3 | const S3_FIELD_NAMES = ['bucket', 'key', 'region']; 4 | export default function isS3Object(typeObj: GraphQLType): boolean { 5 | if (isObjectType(typeObj)) { 6 | const fields = typeObj.getFields(); 7 | const fieldName = typeObj.name; 8 | const hasS3Fields = S3_FIELD_NAMES.every(s3Field => { 9 | const field = fields[s3Field]; 10 | try { 11 | const type = getType(field.type); 12 | return field && isScalarType(type) && type.name === 'String'; 13 | } catch (e) { 14 | return false; 15 | } 16 | }); 17 | return hasS3Fields && fieldName === 'S3Object'; 18 | } 19 | return false; 20 | } 21 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/src/logger.ts: -------------------------------------------------------------------------------- 1 | export function logError(error: Error): void { 2 | console.error(error.message); 3 | } 4 | 5 | export function logMessage(message: String): void { 6 | console.log(message); 7 | } 8 | -------------------------------------------------------------------------------- /packages/graphql-docs-generator/test-operations.graphql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-amplify/amplify-codegen/57eabd9c613f19b7c889ce747c84c0afd9ee039a/packages/graphql-docs-generator/test-operations.graphql -------------------------------------------------------------------------------- /packages/graphql-docs-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "lib", 7 | "experimentalDecorators": true, 8 | "emitDecoratorMetadata": true, 9 | "sourceRoot": "src", 10 | "lib": [ 11 | "es2017", 12 | "dom", 13 | "esnext.asynciterable", 14 | "dom" 15 | ], 16 | "declaration": true 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | "lib", 21 | "__tests__" 22 | ], 23 | "include": [ 24 | "src/" 25 | ] 26 | } -------------------------------------------------------------------------------- /packages/graphql-generator/.npmignore: -------------------------------------------------------------------------------- 1 | **/__mocks__/** 2 | **/__tests__/** 3 | src 4 | tsconfig.json 5 | tsconfig.tsbuildinfo 6 | -------------------------------------------------------------------------------- /packages/graphql-generator/scripts/check-codegen-version.sh: -------------------------------------------------------------------------------- 1 | diff --ignore-space-change \ 2 | ./src/vendor/@graphql-codegen/core/VERSION \ 3 | <(yarn list --pattern @graphql-codegen/core | grep @graphql-codegen/core | cut -d '@' -f 3) || \ 4 | ( \ 5 | echo 'The version of @graphql-codegen/core has changed. Please go through the instructions in ./vendors/@graphql-codegen/core/MAINTENANCE.md' \ 6 | && exit 1 \ 7 | ) -------------------------------------------------------------------------------- /packages/graphql-generator/src/__tests__/profiler.test.ts: -------------------------------------------------------------------------------- 1 | import { createNoopProfiler } from "../profiler"; 2 | 3 | describe('createNoopProfiler', () => { 4 | test('a provided profiler is executed', () => { 5 | const profiler = createNoopProfiler() 6 | let wasExecuted = false; 7 | expect(profiler).toBeDefined(); 8 | 9 | profiler.run(() => { 10 | wasExecuted = true 11 | }, "Test"); 12 | 13 | expect(wasExecuted).toBe(true); 14 | expect(profiler.collect()).toEqual([]); 15 | }) 16 | }) -------------------------------------------------------------------------------- /packages/graphql-generator/src/__tests__/schemas/blog-model.graphql: -------------------------------------------------------------------------------- 1 | type Blog @model { 2 | id: ID! 3 | name: String! 4 | posts: [Post] @hasMany 5 | } 6 | 7 | type Post @model { 8 | id: ID! 9 | title: String! 10 | blog: Blog @belongsTo 11 | comments: [Comment] @hasMany 12 | } 13 | 14 | type Comment @model { 15 | id: ID! 16 | post: Post @belongsTo 17 | content: String! 18 | } 19 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/__tests__/utils.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | 4 | export function readSchema(schemaName: string): string { 5 | return fs.readFileSync(path.join(__dirname, 'schemas', schemaName), 'utf8'); 6 | } 7 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/__tests__/utils/__snapshots__/maps.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`maps statementsTargetToFileExtensionMap 1`] = ` 4 | Object { 5 | "angular": "graphql", 6 | "flow": "js", 7 | "graphql": "graphql", 8 | "javascript": "js", 9 | "typescript": "ts", 10 | } 11 | `; 12 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/__tests__/utils/maps.test.ts: -------------------------------------------------------------------------------- 1 | import { statementsTargetToFileExtensionMap } from '../../utils'; 2 | 3 | describe('maps', () => { 4 | test('statementsTargetToFileExtensionMap', () => { 5 | expect(statementsTargetToFileExtensionMap).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/index.ts: -------------------------------------------------------------------------------- 1 | export { generateModels, generateModelsSync } from './models'; 2 | export { generateStatements } from './statements'; 3 | export { generateTypes } from './types'; 4 | 5 | export type { 6 | TypesTarget, 7 | ModelsTarget, 8 | StatementsTarget, 9 | GenerateTypesOptions, 10 | GenerateModelsOptions, 11 | GenerateStatementsOptions, 12 | GeneratedOutput 13 | } from './typescript'; 14 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/profiler.ts: -------------------------------------------------------------------------------- 1 | import { ProfilerEvent } from "@graphql-codegen/plugin-helpers"; 2 | 3 | interface Profiler { 4 | run(fn: () => T, name: string, cat?: string): T; 5 | collect(): ProfilerEvent[]; 6 | } 7 | export function createNoopProfiler(): Profiler { 8 | return { 9 | run(fn) { 10 | return fn(); 11 | }, 12 | collect() { 13 | return []; 14 | }, 15 | }; 16 | }; -------------------------------------------------------------------------------- /packages/graphql-generator/src/types.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { generate, generateFromString } from '@aws-amplify/graphql-types-generator'; 3 | import { GenerateTypesOptions, GeneratedOutput } from './typescript'; 4 | 5 | export async function generateTypes(options: GenerateTypesOptions): Promise { 6 | const { schema, target, queries, multipleSwiftFiles = false, introspection = false, amplifyJsLibraryVersion } = options; 7 | 8 | const generatedOutput = await generateFromString(schema, introspection, queries, target, multipleSwiftFiles, { 9 | addTypename: true, 10 | complexObjectSupport: 'auto', 11 | amplifyJsLibraryVersion, 12 | }); 13 | 14 | return Object.fromEntries(Object.entries(generatedOutput).map(([filepath, contents]) => [path.basename(filepath), contents])); 15 | } 16 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { GraphQLStatementsFormatter } from './GraphQLStatementsFormatter'; 2 | export { statementsTargetToFileExtensionMap } from './maps'; 3 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/utils/maps.ts: -------------------------------------------------------------------------------- 1 | import { StatementsTarget, FileExtension } from '../typescript'; 2 | 3 | export const statementsTargetToFileExtensionMap: { [key in StatementsTarget]: FileExtension } = { 4 | javascript: 'js', 5 | graphql: 'graphql', 6 | flow: 'js', 7 | typescript: 'ts', 8 | angular: 'graphql', 9 | }; 10 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/vendor/@graphql-codegen/core/README.md: -------------------------------------------------------------------------------- 1 | This package code is forked from [this version](https://github.com/dotansimha/graphql-code-generator/tree/%40graphql-codegen/core%402.6.8) 2 | of the `@graphql-codegen/core` library, which is [adapted to function without the async behavior](MAINTENANCE.md). This was done to allow 3 | codegen to be run during the CDK build process. Ideally this change would be supported on [the public package](https://github.com/dotansimha/graphql-code-generator/issues/10149) 4 | and consumed for our usecase. This fork is intended to support the CDK usecase until sync execution is supported by the source repository. -------------------------------------------------------------------------------- /packages/graphql-generator/src/vendor/@graphql-codegen/core/VERSION: -------------------------------------------------------------------------------- 1 | 2.6.8 2 | -------------------------------------------------------------------------------- /packages/graphql-generator/src/vendor/@graphql-codegen/core/index.ts: -------------------------------------------------------------------------------- 1 | export { codegen } from './codegen'; 2 | export { executePlugin, ExecutePluginOptions } from './execute-plugin'; 3 | -------------------------------------------------------------------------------- /packages/graphql-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "rootDir": "src", 5 | "outDir": "lib", 6 | }, 7 | "exclude": [ 8 | "lib", 9 | "src/__tests__" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/.npmignore: -------------------------------------------------------------------------------- 1 | **/__mocks__/** 2 | **/__tests__/** 3 | src 4 | fixtures 5 | test 6 | tsconfig.json 7 | tsconfig.tsbuildinfo 8 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/awsAppSyncDirectives.graphql: -------------------------------------------------------------------------------- 1 | scalar AWSDate 2 | scalar AWSTime 3 | scalar AWSDateTime 4 | scalar AWSTimestamp 5 | scalar AWSEmail 6 | scalar AWSJSON 7 | scalar AWSURL 8 | scalar AWSPhone 9 | scalar AWSIPAddress 10 | scalar BigInt 11 | scalar Double 12 | 13 | directive @aws_subscribe(mutations: [String!]!) on FIELD_DEFINITION 14 | 15 | # Allows transformer libraries to deprecate directive arguments. 16 | directive @deprecated(reason: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION | ENUM | ENUM_VALUE 17 | 18 | directive @aws_auth(cognito_groups: [String!]!) on FIELD_DEFINITION 19 | directive @aws_api_key on FIELD_DEFINITION | OBJECT 20 | directive @aws_iam on FIELD_DEFINITION | OBJECT 21 | directive @aws_lambda on FIELD_DEFINITION | OBJECT 22 | directive @aws_oidc on FIELD_DEFINITION | OBJECT 23 | directive @aws_cognito_user_pools(cognito_groups: [String!]) on FIELD_DEFINITION | OBJECT 24 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/fixtures/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rules: { 3 | 'import/no-extraneous-dependencies': 'off' 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/compiler/visitors/inlineRedundantTypeConditions.ts: -------------------------------------------------------------------------------- 1 | import { SelectionSet, Selection } from '../'; 2 | 3 | export function inlineRedundantTypeConditions(selectionSet: SelectionSet): SelectionSet { 4 | const selections: Selection[] = []; 5 | 6 | for (const selection of selectionSet.selections) { 7 | if ( 8 | selection.kind === 'TypeCondition' && 9 | selectionSet.possibleTypes.every(type => selection.selectionSet.possibleTypes.includes(type)) 10 | ) { 11 | selections.push(...inlineRedundantTypeConditions(selection.selectionSet).selections); 12 | } else { 13 | selections.push(selection); 14 | } 15 | } 16 | 17 | return { 18 | possibleTypes: selectionSet.possibleTypes, 19 | selections, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/flow-modern/index.ts: -------------------------------------------------------------------------------- 1 | export { generateSource } from './codeGeneration'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/flow-modern/types/augment-babel-types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Augment incomplete definitions in `@types/babel-types` 3 | */ 4 | import 'babel-types'; 5 | 6 | declare module 'babel-types' { 7 | interface StringLiteralTypeAnnotation { 8 | value: string; 9 | } 10 | 11 | interface ObjectTypeAnnotation { 12 | exact: boolean; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/flow-modern/types/babel7.ts: -------------------------------------------------------------------------------- 1 | // Suppress missing types for @babel/types and @babel/generator by 2 | // creating an alias for them to babel-types and babel-generator respectively. 3 | 4 | declare module '@babel/types' { 5 | export * from 'babel-types'; 6 | } 7 | declare module '@babel/generator' { 8 | export * from 'babel-generator'; 9 | 10 | import Generator from 'babel-generator'; 11 | export default Generator; 12 | } 13 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/flow/index.js: -------------------------------------------------------------------------------- 1 | export { generateSource } from './codeGeneration'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/index.ts: -------------------------------------------------------------------------------- 1 | import './polyfills'; 2 | 3 | export { default as generate, generateFromString } from './generate'; 4 | export type { Target } from './types'; 5 | export { getOutputFileName } from './utilities/getOutputFileName'; 6 | export { extractDocumentFromJavascript } from './loading'; 7 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/polyfills.js: -------------------------------------------------------------------------------- 1 | import 'core-js/stable/object/values'; 2 | import 'core-js/stable/object/entries'; 3 | import 'core-js/stable/array/flat-map'; 4 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/scala/index.js: -------------------------------------------------------------------------------- 1 | export { generateSource } from './codeGeneration'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/swift/aws-scalar-helper.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLScalarType } from 'graphql'; 2 | 3 | interface INameToValueMap { 4 | [key: string]: any; 5 | } 6 | 7 | export const awsScalarMap: INameToValueMap = { 8 | AWSDate: 'String', 9 | AWSTime: 'String', 10 | AWSDateTime: 'String', 11 | AWSTimestamp: 'Int', 12 | AWSEmail: 'String', 13 | AWSJSON: 'String', 14 | AWSURL: 'String', 15 | AWSPhone: 'String', 16 | AWSIPAddress: 'String', 17 | }; 18 | 19 | export function getTypeForAWSScalar(type: GraphQLScalarType): string { 20 | return awsScalarMap[type.name]; 21 | } 22 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/swift/index.ts: -------------------------------------------------------------------------------- 1 | export { generateSource } from './codeGeneration'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/types.ts: -------------------------------------------------------------------------------- 1 | export type Target = 'json' | 'swift' | 'ts' | 'typescript' | 'flow' | 'scala' | 'flow-modern' | 'angular'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/typescript/index.ts: -------------------------------------------------------------------------------- 1 | export { generateSource } from './codeGeneration'; 2 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/src/utilities/array.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | interface Array { 5 | flatMap(callbackfn: (value: T, index: number, array: T[]) => U[] | undefined, thisArg?: any): U[]; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/misc/invalid-gqlQueries.js: -------------------------------------------------------------------------------- 1 | const gql = String.raw; 2 | 3 | export const hello = gql`world and other words`; 4 | 5 | export const foo = `bar`; 6 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/AnonymousQuery.graphql: -------------------------------------------------------------------------------- 1 | { 2 | hero { 3 | name 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/ExplicitTypename.graphql: -------------------------------------------------------------------------------- 1 | query HeroName { 2 | hero { 3 | __typename 4 | name 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/HeroAndFriends.graphql: -------------------------------------------------------------------------------- 1 | query HeroAndFriends($episode: Episode) { 2 | hero(episode: $episode) { 3 | ...heroDetails 4 | } 5 | } 6 | 7 | fragment heroDetails on Character { 8 | name 9 | ... on Droid { 10 | primaryFunction 11 | } 12 | ... on Human { 13 | height 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/HeroAndFriendsNames.graphql: -------------------------------------------------------------------------------- 1 | query HeroAndFriendsNames($episode: Episode) { 2 | hero(episode: $episode) { 3 | name 4 | friends { 5 | name 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/HeroAppearsIn.graphql: -------------------------------------------------------------------------------- 1 | query HeroAppearsIn { 2 | hero { 3 | name 4 | appearsIn 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/HeroName.graphql: -------------------------------------------------------------------------------- 1 | query HeroName { 2 | hero { 3 | name 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/TwoHeroes.graphql: -------------------------------------------------------------------------------- 1 | query TwoHeroes { 2 | r2: hero { 3 | name 4 | } 5 | luke: hero(episode: EMPIRE) { 6 | name 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/TypenameAlias.graphql: -------------------------------------------------------------------------------- 1 | query HeroName { 2 | hero { 3 | __typename: name 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/fixtures/starwars/gqlQueries.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { gql, graphql } from 'react-apollo'; 3 | 4 | const Query = gql` 5 | query HeroAndFriends($episode: Episode) { 6 | hero(episode: $episode) { 7 | ...heroDetails 8 | } 9 | } 10 | 11 | fragment heroDetails on Character { 12 | name 13 | ... on Droid { 14 | primaryFunction 15 | } 16 | ... on Human { 17 | height 18 | } 19 | } 20 | 21 | ${'this should be ignored'} 22 | `; 23 | 24 | const AnotherQuery = gql` 25 | query HeroName { 26 | hero { 27 | name 28 | } 29 | } 30 | `; 31 | 32 | function Component() { 33 | return
; 34 | } 35 | 36 | export default graphql(Query)(Component); 37 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/scala/__snapshots__/language.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Scala code generation: Basic language constructs should handle multi-line descriptions 1`] = ` 4 | "/** 5 | * A hero 6 | */ 7 | case class Hero() { 8 | /** 9 | * A multiline comment 10 | * on the hero's name. 11 | */ 12 | val name: String = { 13 | } 14 | /** 15 | * A multiline comment 16 | * on the hero's age. 17 | */ 18 | val age: String = { 19 | } 20 | }" 21 | `; 22 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/swift/__snapshots__/language.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Swift code generation: Basic language constructs should handle multi-line descriptions 1`] = ` 4 | "/// A hero 5 | public struct Hero { 6 | /// A multiline comment 7 | /// on the hero's name. 8 | public var name: String 9 | /// A multiline comment 10 | /// on the hero's age. 11 | public var age: String 12 | }" 13 | `; 14 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/test-utils/helpers.ts: -------------------------------------------------------------------------------- 1 | import { parse, GraphQLSchema } from 'graphql'; 2 | import { compileToIR, CompilerOptions } from '../../src/compiler'; 3 | import { loadSchema } from '../../src/loading'; 4 | 5 | export const starWarsSchema = loadSchema(require.resolve('../fixtures/starwars/schema.json')); 6 | 7 | export function compile(source: string, schema: GraphQLSchema = starWarsSchema, options: CompilerOptions = {}) { 8 | const document = parse(source); 9 | return compileToIR(schema, document, options); 10 | } 11 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/test/validation.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { loadSchema, loadAndMergeQueryDocuments } from '../src/loading'; 4 | 5 | import { validateQueryDocument } from '../src/validation'; 6 | 7 | const schema = loadSchema(require.resolve('./fixtures/starwars/schema.json')); 8 | 9 | describe('Validation', () => { 10 | function loadQueryDocument(filename: string) { 11 | return loadAndMergeQueryDocuments([path.join(__dirname, './fixtures/starwars', filename)]); 12 | } 13 | 14 | test(`should throw an error for AnonymousQuery.graphql`, () => { 15 | const document = loadQueryDocument('AnonymousQuery.graphql'); 16 | 17 | expect(() => validateQueryDocument(schema, document)).toThrow('Validation of GraphQL query document failed'); 18 | }); 19 | 20 | test(`should throw an error for TypenameAlias.graphql`, () => { 21 | const document = loadQueryDocument('TypenameAlias.graphql'); 22 | 23 | expect(() => validateQueryDocument(schema, document)).toThrow('Validation of GraphQL query document failed'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/graphql-types-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "outDir": "lib", 8 | "lib": ["es2017", "esnext.asynciterable", "dom"], 9 | "declaration": true, 10 | "removeComments": true, 11 | "strict": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noUnusedParameters": true, 15 | "noUnusedLocals": true, 16 | "allowJs": true, 17 | "allowUnreachableCode": true, 18 | "skipLibCheck": true 19 | }, 20 | "include" : [ 21 | "src/**/*" 22 | ] 23 | } -------------------------------------------------------------------------------- /scripts/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "mainEntryPointFilePath": "/lib/index.d.ts", 4 | "bundledPackages": [], 5 | "newlineKind": "lf", 6 | 7 | "apiReport": { 8 | "enabled": true, 9 | "reportFileName": "API.md", 10 | "reportFolder": "/" 11 | }, 12 | 13 | "docModel": { 14 | "enabled": false 15 | }, 16 | 17 | "dtsRollup": { 18 | "enabled": false 19 | }, 20 | 21 | "tsdocMetadata": { 22 | "enabled": false 23 | }, 24 | 25 | "messages": { 26 | "compilerMessageReporting": { 27 | "default": { 28 | "logLevel": "none" 29 | } 30 | }, 31 | 32 | "extractorMessageReporting": { 33 | "default": { 34 | "logLevel": "none" 35 | } 36 | }, 37 | 38 | "tsdocMessageReporting": { 39 | "default": { 40 | "logLevel": "none" 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /scripts/components/release_tag_to_name_and_version.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Splits a release tag of @ into its constituent parts 3 | */ 4 | export const releaseTagToNameAndVersion = (releaseTag: string) => { 5 | const indexOfLastAt = releaseTag.lastIndexOf('@'); 6 | return { 7 | packageName: releaseTag.slice(0, indexOfLastAt), 8 | version: releaseTag.slice(indexOfLastAt + 1), 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /scripts/create-private-package-manifest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set exit on error to true 4 | set -e 5 | 6 | # create a new file to store the private packages 7 | # this will be imported and used in the Git Client to determine the packages to deprecate 8 | 9 | echo 'export default [' > scripts/components/private_packages.ts 10 | grep -l packages/*/package.json -e '"private": "\?true"\?' | xargs cat | jq .name | tr -s '\n' ',' >> scripts/components/private_packages.ts 11 | echo '];' >> scripts/components/private_packages.ts 12 | -------------------------------------------------------------------------------- /scripts/extract-dependency-licenses.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | yarn licenses generate-disclaimer \ 4 | --ignore-platform \ 5 | --ignore-engines \ 6 | --ignore-optional \ 7 | --silent \ 8 | --no-progress \ 9 | --frozen-lockfile > dependency_licenses_temp.txt 10 | 11 | sed \ 12 | -e '/WORKSPACE AGGREGATOR/d' \ 13 | -e '/workspace-aggregator/d' \ 14 | dependency_licenses_temp.txt > dependency_licenses.txt 15 | 16 | rm dependency_licenses_temp.txt 17 | -------------------------------------------------------------------------------- /scripts/sample.env: -------------------------------------------------------------------------------- 1 | E2E_ACCOUNT_BETA= 2 | E2E_ACCOUNT_PROD= 3 | RELEASE_ACCOUNT_PROD= -------------------------------------------------------------------------------- /scripts/verify-dependency-licenses.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | change_dependency_licenses=$(git status | grep dependency_licenses.txt | wc -l) 4 | 5 | if [[ change_dependency_licenses -gt 0 ]]; then 6 | echo "Detected license change. Please run 'yarn extract-dependency-licenses' and add dependency_licenses.txt file changes to the change set." 7 | exit 1; 8 | fi 9 | -------------------------------------------------------------------------------- /scripts/verify-extract-api.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | changed_api_extracts=$(git status | grep API.md | wc -l) 4 | 5 | if [[ changed_api_extracts -gt 0 ]]; then 6 | echo "Detected api change. Please run 'yarn extract-api' and add API.md file changes to the change set." 7 | git status | grep API.md 8 | exit 1; 9 | fi 10 | --------------------------------------------------------------------------------