Skip to content

Commit

Permalink
feat(amplify-frontend-javascript): generate amplifyconfiguration.json…
Browse files Browse the repository at this point in the history
… for JS projects (#13246)

* feat: generate amplifyconfiguration.json in JS frontend projects

* chore: update codebuild for new e2e tests

* fix: fix typo

* fix: test

---------

Co-authored-by: Kamil Sobol <[email protected]>
  • Loading branch information
bombguy and sobolk authored Sep 20, 2023
1 parent f1f3118 commit 49457b1
Show file tree
Hide file tree
Showing 8 changed files with 472 additions and 351 deletions.
597 changes: 303 additions & 294 deletions codebuild_specs/e2e_workflow_generated.yml

Large diffs are not rendered by default.

97 changes: 49 additions & 48 deletions codebuild_specs/wait_for_ids.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
[
"l_S3server_api_8_function_8",
"l_amplify_app",
"l_amplify_configure_env_2_init_d",
"l_analytics_kinesis_analytics_pinpoint_flutter_analytics_pinpoint_js",
"l_api_1_layer_1_api_key_migration4",
"l_android_notifications_pinpoint_config_flutter_analytics_pinpoint_config_flutter_notifications_pinpoint_config",
"l_api_2b_api_6c_api_9a",
"l_api_5_apigw_api_lambda_auth_1",
"l_api_6a_auth_7b_export_pull_b",
"l_api_6b_api_1_layer_1",
"l_api_7_export_pull_a_function_9a",
"l_api_8_function_8_schema_iterative_update_locking",
"l_api_9b_custom_policies_container_function_9b",
"l_api_connection_migration2_api_4_containers_api_secrets",
"l_api_graphql_v2_migration_v10",
"l_api_key_migration2_schema_searchable_api_key_migration1",
"l_api_key_migration1_schema_auth_14_api_3",
"l_api_key_migration4_schema_iterative_update_4_function_1",
"l_api_key_migration_2_v8",
"l_api_key_migration_v8",
"l_api_lambda_auth_2_layer_2_schema_auth_13",
"l_api_lambda_auth_1_api_key_migration2_schema_searchable",
"l_api_rest_basic_migration_v10",
"l_api_rest_lambda_migration_v10",
"l_api_rest_serverless_migration_v10",
Expand All @@ -30,6 +29,7 @@
"l_auth_4b_auth_8a_export_pull_d",
"l_auth_4c_auth_5a_auth_5c",
"l_auth_5g_hosted_ui_user_groups_s3_access",
"l_auth_6_function_2a_schema_connection_2",
"l_auth_7a_auth_8c_feature_flags",
"l_auth_9_custom_resources_env_5",
"l_auth_add_all_migration_v10",
Expand All @@ -44,23 +44,22 @@
"l_container_hosting_init_b_notifications_apns",
"l_containers_api_1",
"l_containers_api_2",
"l_containers_api_secrets_storage_4_schema_auth_10",
"l_custom_resource_with_storage_dynamodb_simulator_export_pull_c",
"l_custom_stack_migration_v10",
"l_datastore_modelgen",
"l_diagnose_hooks_a_mock_api",
"l_dynamodb_simulator_export_pull_c_function_12",
"l_env_1_geo_add_a_init_a",
"l_env_3",
"l_env_4_frontend_config_drift_schema_auth_4d",
"l_flutter_analytics_pinpoint_config_flutter_notifications_pinpoint_config_ios_analytics_pinpoint_config",
"l_function_10_function_9c_function_permissions",
"l_function_11_function_2b_function_7",
"l_function_13_function_14_function_15",
"l_function_2a_schema_connection_2_schema_function_1",
"l_function_12_function_13_function_14",
"l_function_15_function_2d_general_config_headless_init",
"l_function_2c_function_3b_function_4",
"l_function_2d_general_config_headless_init_help",
"l_function_3a_init_special_case_http_migration",
"l_function_5_schema_iterative_update_1_auth_6",
"l_function_6_storage_2_export",
"l_function_7_api_connection_migration2_api_4",
"l_function_9b_schema_iterative_update_2_storage_1a",
"l_function_migration_update_v8",
"l_geo_add_b_s3_sse_schema_auth_4a",
"l_geo_add_d_geo_import_3_hosting",
Expand All @@ -70,15 +69,16 @@
"l_geo_import_1a_geo_import_2_global_sandbox_b",
"l_geo_import_1b_global_sandbox_a_init_e",
"l_geo_migration_v10",
"l_geo_multi_env_searchable_datastore_resolvers",
"l_geo_remove_1",
"l_geo_remove_2",
"l_geo_remove_3",
"l_geo_update_1",
"l_geo_update_2",
"l_git_clone_attach_init_c_layer_4",
"l_git_clone_migration_tests_v10",
"l_help_hooks_c_init_force_push",
"l_hooks_b_notifications_analytics_compatibility_sms_1_plugin",
"l_hooks_c_init_force_push_interactions_1",
"l_hostingPROD",
"l_iam_permissions_boundary_node_function_notifications_sms",
"l_import_auth_1a",
Expand All @@ -96,9 +96,10 @@
"l_import_s3_2c",
"l_import_s3_3",
"l_init_f_auth_5d_configure_project",
"l_interactions_2_minify_cloudformation_notifications_multi_env",
"l_interactions_1_interactions_2_minify_cloudformation",
"l_interactions_schema_model_a_tags",
"l_ios_notifications_pinpoint_config_javascript_analytics_pinpoint_config_javascript_notifications_pinpoint_config",
"l_ios_analytics_pinpoint_config_ios_notifications_pinpoint_config_javascript_analytics_pinpoint_config",
"l_javascript_notifications_pinpoint_config_pr_previews_multi_env_1_pull_2",
"l_layer_3_api_connection_migration_api_key_migration3",
"l_notifications_analytics_compatibility_in_app_2_schema_auth_11_c_schema_auth_2b",
"l_notifications_analytics_compatibility_sms_2_analytics_2_global_sandbox_c",
Expand All @@ -108,16 +109,16 @@
"l_notifications_migration_3_v8",
"l_notifications_migration_4_v8",
"l_notifications_migration_v8",
"l_notifications_multi_env_notifications_sms_update_opensearch_simulator",
"l_notifications_sms_pull_pull_auth_10",
"l_notifications_sms_update_opensearch_simulator_parameter_store_1",
"l_parameter_store_2_android_analytics_pinpoint_config_android_notifications_pinpoint_config",
"l_parameter_store_1_parameter_store_2_android_analytics_pinpoint_config",
"l_pinpoint_region_migration_v10",
"l_pr_previews_multi_env_1_pull_2_push",
"l_predictions_schema_auth_11_b_schema_auth_1b",
"l_push_smoketest_ios_smoketest",
"l_scaffold_v10",
"l_schema_auth_11_a",
"l_schema_auth_12_schema_auth_3_schema_function_2",
"l_schema_auth_14_api_3_api_6b",
"l_schema_auth_13_function_5_schema_iterative_update_1",
"l_schema_auth_15",
"l_schema_auth_2a_schema_auth_7a_schema_auth_7b",
"l_schema_auth_4b_schema_model_e_schema_versioned",
Expand All @@ -131,28 +132,29 @@
"l_schema_auth_9_b_schema_iterative_rollback_1_predictions_migration",
"l_schema_auth_9_c_storage_3_auth_11",
"l_schema_connection_1",
"l_schema_iterative_update_2_storage_1a_storage_1b",
"l_schema_iterative_update_4_function_1_storage_5",
"l_schema_function_1_api_9b_custom_policies_container",
"l_schema_iterative_update_locking_api_lambda_auth_2_layer_2",
"l_schema_key_api_5_apigw",
"l_schema_model_b_schema_model_d_auth_5f",
"l_schema_predictions_model_migration_auth_3c",
"l_searchable_datastore_resolvers_schema_key",
"l_searchable_migration",
"l_smoketest_ios_smoketest_S3server",
"l_storage_4_schema_auth_10_geo_multi_env",
"l_storage_1b_function_11_function_2b",
"l_storage_5",
"l_storage_migration_v10",
"l_studio_modelgen_custom_transformers_notifications_in_app_messaging_env_1",
"l_uibuilder",
"l_user_groups_build_function_custom_resource_with_storage",
"l_user_groups_js_frontend_config_build_function",
"w_analytics_kinesis_analytics_pinpoint_flutter_analytics_pinpoint_js",
"w_api_10_api_7_export_pull_a",
"w_api_1_layer_1_api_key_migration4",
"w_api_2a_api_2b_api_6c",
"w_api_3_api_6b_api_1",
"w_api_4_containers_api_secrets_storage_4",
"w_api_5_apigw_api_lambda_auth_1",
"w_api_6a_auth_7b_export_pull_b",
"w_api_8_schema_iterative_update_locking_api_lambda_auth_2",
"w_api_9a_auth_2h_auth_5g",
"w_api_9b_custom_policies_container_function_9b",
"w_api_connection_migration2_api_4_containers_api_secrets",
"w_api_key_migration2_schema_searchable_api_key_migration1",
"w_api_key_migration3_predictions_schema_auth_11_b",
"w_apigw_api_lambda_auth_1_api_key_migration2",
"w_auth_11_auth_1b_delete",
"w_auth_2a_auth_2b_auth_2d",
"w_auth_2c",
Expand All @@ -161,29 +163,27 @@
"w_auth_4a_auth_7a_auth_8c",
"w_auth_5a_auth_5c_env_1",
"w_auth_5e_auth_8b_geo_add_b",
"w_auth_6_function_2a_schema_connection_2",
"w_auth_8a_export_pull_d_schema_auth_5a",
"w_build_function_dynamodb_simulator_export_pull_c",
"w_configure_project_init_c_layer_4",
"w_containers_api_1",
"w_containers_api_2",
"w_custom_policies_function_storage_2_iam_permissions_boundary",
"w_env_3",
"w_env_5_function_10_function_9c",
"w_export_pull_c_function_12_function_13",
"w_feature_flags_geo_import_1b_global_sandbox_a",
"w_frontend_config_drift_schema_auth_4d_schema_auth_6a",
"w_function_1",
"w_function_11_function_2b_api_connection_migration2",
"w_function_12_function_13_function_14",
"w_function_2a_schema_connection_2_schema_function_1",
"w_function_14_function_2d_general_config_headless_init",
"w_function_2c_interactions_schema_model_a",
"w_function_2d_general_config_headless_init_help",
"w_function_5_schema_iterative_update_1_auth_6",
"w_function_9a_geo_headless_api_key_migration5",
"w_function_9b_schema_iterative_update_2_storage_1a",
"w_function_permissions_geo_import_1a_geo_import_2",
"w_geo_add_a_init_a_schema_auth_4c",
"w_geo_add_c_geo_add_d_geo_import_3",
"w_geo_remove_1",
"w_global_sandbox_b_schema_auth_5d_schema_auth_6b",
"w_help_init_force_push_interactions_1",
"w_hooks_b_notifications_analytics_compatibility_sms_1_plugin",
"w_hosted_ui_user_groups_s3_access_user_groups",
"w_hostingPROD",
Expand All @@ -194,21 +194,21 @@
"w_init_b_notifications_apns_notifications_fcm",
"w_init_d_init_f_auth_5d",
"w_init_e_notifications_analytics_compatibility_in_app_2_schema_auth_11_c",
"w_init_force_push_interactions_1_interactions_2",
"w_init_special_case_http_migration_schema_auth_12",
"w_layer_1_api_key_migration4_schema_iterative_update_4",
"w_minify_cloudformation_notifications_multi_env_notifications_sms_update",
"w_interactions_2_minify_cloudformation_notifications_multi_env",
"w_js_frontend_config_build_function_dynamodb_simulator",
"w_model_migration_auth_3c_auth_4c",
"w_node_function_notifications_sms_schema_auth_4b",
"w_notifications_analytics_compatibility_sms_2_analytics_2_global_sandbox_c",
"w_notifications_in_app_messaging",
"w_notifications_in_app_messaging_env_2_with_babel_config_amplify_configure",
"w_notifications_sms_pull_auth_10_container_hosting",
"w_parameter_store_1_parameter_store_2_push",
"w_resolvers_schema_key_api_5",
"w_notifications_sms_update_parameter_store_1_parameter_store_2",
"w_push_smoketest_ios_smoketest",
"w_s3_sse_schema_auth_4a_schema_model_b",
"w_schema_auth_10_geo_multi_env_searchable_datastore",
"w_schema_auth_11_a",
"w_schema_auth_13_function_5_schema_iterative_update_1",
"w_schema_auth_14_api_3_api_6b",
"w_schema_auth_15",
"w_schema_auth_1a_schema_auth_5b_schema_auth_8b",
"w_schema_auth_1b_schema_auth_2a_schema_auth_7a",
Expand All @@ -221,14 +221,15 @@
"w_schema_auth_9_a_schema_auth_9_c_storage_3",
"w_schema_connection_1",
"w_schema_data_access_patterns_schema_model_c_schema_predictions",
"w_schema_iterative_update_2_storage_1a_storage_1b",
"w_schema_function_1_api_9b_custom_policies_container",
"w_schema_iterative_update_3_auth_migration_amplify_remove",
"w_schema_iterative_update_locking_api_lambda_auth_2_schema_auth_13",
"w_schema_iterative_update_4_function_1",
"w_schema_model_d_auth_5f_env_4",
"w_schema_model_e_schema_versioned_auth_1c",
"w_schema_searchable_api_key_migration1_schema_auth_14",
"w_searchable_datastore_resolvers_schema_key",
"w_searchable_migration",
"w_smoketest_ios_smoketest_api_8",
"w_storage_1b_function_11_function_2b",
"w_storage_4_schema_auth_10_geo_multi_env",
"w_studio_modelgen_custom_transformers_notifications_in_app_messaging_env_1",
"w_tags_auth_1a_auth_trigger"
]
2 changes: 2 additions & 0 deletions packages/amplify-e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"@aws-sdk/client-dynamodb": "^3.303.0",
"@aws-sdk/client-s3": "^3.303.0",
"@aws-sdk/client-ssm": "^3.303.0",
"@babel/core": "^7.10.5",
"@babel/plugin-transform-modules-commonjs": "7.10.4",
"amplify-dynamodb-simulator": "2.9.0",
"amplify-headless-interface": "1.17.4",
"amplify-storage-simulator": "1.11.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as fs from 'fs-extra';
import execa from 'execa';

import {
addAuthWithDefault,
amplifyPushAuth,
createNewProjectDir,
deleteProject,
deleteProjectDir,
getNpxPath,
initJSProjectWithProfile,
} from '@aws-amplify/amplify-e2e-core';
import * as babel from '@babel/core';
import * as babelTransformEsmToCjs from '@babel/plugin-transform-modules-commonjs';
import Module from 'module';

describe('JS frontend config tests', () => {
let projRoot: string;
let appRoot: string;

beforeEach(async () => {
projRoot = await createNewProjectDir('aws-exports-test');
appRoot = await createReactApp(projRoot, 'reactapp');
});

afterEach(async () => {
// extra delete in case test fails, delete is noop if project was already deleted
await deleteProject(appRoot);
deleteProjectDir(projRoot);
});

test('both aws-exports.js & amplifyconfiguration.json is generated', async () => {
// amplify init, this will generate aws-exports in the project
await initJSProjectWithProfile(appRoot, { name: 'reactapp' });

// check if amplify init generated project files
expect(fs.existsSync(`${appRoot}/src/aws-exports.js`)).toBeTruthy();
expect(fs.existsSync(`${appRoot}/src/amplifyconfiguration.json`)).toBeTruthy();

const initialAwsExportsModule = readAwsExports(appRoot, `${appRoot}/src/aws-exports.js`);
const initialAmplifyConfiguration = fs.readJSONSync(`${appRoot}/src/amplifyconfiguration.json`);

// contents should match
expect(initialAwsExportsModule).toMatchObject(initialAmplifyConfiguration);

// should update both aws-exports.js & amplifyconfiguration.json
// add a category
await addAuthWithDefault(appRoot);
await amplifyPushAuth(appRoot);

// when aws-exports updates, both files should still exist
const awsExportsModule = readAwsExports(appRoot, `${appRoot}/src/aws-exports.js`);
const amplifyConfiguration = fs.readJSONSync(`${appRoot}/src/amplifyconfiguration.json`);

// config should have updated
expect(amplifyConfiguration.aws_user_pools_id).toBeDefined();

// contents should match
expect(amplifyConfiguration).toMatchObject(awsExportsModule);
expect(amplifyConfiguration).not.toStrictEqual(initialAmplifyConfiguration);

// both aws-exports.js & amplifyconfiguration.json should be removed on delete
await deleteProject(appRoot);

// when amplify app gets deleted, all config should be removed
expect(fs.existsSync(`${appRoot}/src/aws-exports.js`)).toBeFalsy();
expect(fs.existsSync(`${appRoot}/src/amplifyconfiguration.json`)).toBeFalsy();
});
});

// returns path to react project directory
async function createReactApp(cwd: string, projectName: string) {
const projectRoot = `${cwd}/${projectName}`;

execa.sync(getNpxPath(), ['create-react-app', '--scripts-version', '5.0.1', projectName, '--use-npm'], { cwd, encoding: 'utf-8' });

return projectRoot;
}

/**
* Reads and transpiles aws exports. Jest doesn't like ES6 modules.
*/
function readAwsExports(projectPath: string, targetFilePath: string) {
const fileContents = fs.readFileSync(targetFilePath, 'utf-8');
// transpile the file contents to CommonJS
const { code } = babel.transformSync(fileContents, {
plugins: [babelTransformEsmToCjs],
configFile: false,
babelrc: false,
});
const mod = new Module('test_module');
// @ts-ignore
mod._compile(code, 'aws-exports.js');
// add paths to the module to account for node_module imports in aws-exports.js (should there be any)
mod.paths = [projectPath];
// the transpiled result will contain `exports.default`
return mod.exports?.default || mod.exports;
}
4 changes: 3 additions & 1 deletion packages/amplify-frontend-javascript/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ async function createFrontendConfigsAtPath(context, amplifyResources, amplifyClo
const cloudOutputsForFrontend = amplifyCloudResources.outputsForFrontend;

const amplifyConfig = await getAWSExports(context, newOutputsForFrontend, cloudOutputsForFrontend);
await generateAwsExportsAtPath(context, path.join(exportPath, constants.exportsFilename), amplifyConfig);

context.amplify.writeObjectAsJson(path.join(exportPath, constants.exportsJSONFilename), amplifyConfig, true);
await generateAwsExportsAtPath(context, path.join(exportPath, constants.exportsJSFilename), amplifyConfig);
}

async function createFrontendConfigs(context, amplifyResources, amplifyCloudResources) {
Expand Down
3 changes: 2 additions & 1 deletion packages/amplify-frontend-javascript/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ module.exports = {
ProjectScanBaseScore: 10,
ProjectScanMaxScore: 90,
configFilename: 'amplify-config.js',
exportsFilename: 'aws-exports.js',
exportsJSFilename: 'aws-exports.js',
exportsJSONFilename: 'amplifyconfiguration.json',
};
Loading

0 comments on commit 49457b1

Please sign in to comment.