diff --git a/.circleci/config.base.yml b/.circleci/config.base.yml index 14c1807cc58..a7f04ccdf5b 100644 --- a/.circleci/config.base.yml +++ b/.circleci/config.base.yml @@ -2,6 +2,7 @@ version: 2.1 machine: environment: PATH: '${PATH}:${HOME}/${CIRCLE_PROJECT_REPONAME}/node_modules/.bin' + defaults: &defaults working_directory: ~/repo docker: diff --git a/packages/amplify-appsync-simulator/src/index.ts b/packages/amplify-appsync-simulator/src/index.ts index 9273524d2af..879f5bafb9f 100644 --- a/packages/amplify-appsync-simulator/src/index.ts +++ b/packages/amplify-appsync-simulator/src/index.ts @@ -52,7 +52,6 @@ export class AmplifyAppSyncSimulator { } catch (e) { console.log('Could not start AppSync mock endpoint'); console.log(e); - throw e; } } diff --git a/packages/amplify-category-analytics/commands/analytics/add.js b/packages/amplify-category-analytics/commands/analytics/add.js index 53ad0f7668f..c177fe55147 100644 --- a/packages/amplify-category-analytics/commands/analytics/add.js +++ b/packages/amplify-category-analytics/commands/analytics/add.js @@ -30,14 +30,13 @@ module.exports = { print.success('Some next steps:'); print.info('"amplify push" builds all of your local backend resources and provisions them in the cloud'); print.info( - '"amplify publish" builds all your local backend and front-end resources (if you have hosting category added) and provisions them in the cloud', + '"amplify publish" builds all your local backend and front-end resources (if you have hosting category added) and provisions them in the cloud' ); print.info(''); }) .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the analytics resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-analytics/commands/analytics/push.js b/packages/amplify-category-analytics/commands/analytics/push.js index dc95f3856cd..35ab9f2e4e9 100644 --- a/packages/amplify-category-analytics/commands/analytics/push.js +++ b/packages/amplify-category-analytics/commands/analytics/push.js @@ -10,7 +10,6 @@ module.exports = { return amplify.pushResources(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when pushing the analytics resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-analytics/commands/analytics/remove.js b/packages/amplify-category-analytics/commands/analytics/remove.js index f4d2666ec43..e2ebe40efa5 100644 --- a/packages/amplify-category-analytics/commands/analytics/remove.js +++ b/packages/amplify-category-analytics/commands/analytics/remove.js @@ -10,7 +10,6 @@ module.exports = { return amplify.removeResource(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when removing the analytics resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-analytics/commands/analytics/update.js b/packages/amplify-category-analytics/commands/analytics/update.js index 04e14324c98..3aebdad6496 100644 --- a/packages/amplify-category-analytics/commands/analytics/update.js +++ b/packages/amplify-category-analytics/commands/analytics/update.js @@ -38,7 +38,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error(`There was an error updating the ${category} resource`); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/add-graphql-datasource.js b/packages/amplify-category-api/commands/api/add-graphql-datasource.js index 502535dce18..2290f6db061 100644 --- a/packages/amplify-category-api/commands/api/add-graphql-datasource.js +++ b/packages/amplify-category-api/commands/api/add-graphql-datasource.js @@ -86,7 +86,7 @@ module.exports = { answers.secretStoreArn, answers.dbClusterArn, answers.databaseName, - AWS, + AWS ); /** @@ -148,14 +148,13 @@ module.exports = { print.success('Some next steps:'); print.info('"amplify push" will build all your local backend resources and provision it in the cloud'); print.info( - '"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud', + '"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud' ); print.info(''); }) .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the datasource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/add.js b/packages/amplify-category-api/commands/api/add.js index 7e199ba9efd..cebc5de0146 100644 --- a/packages/amplify-category-api/commands/api/add.js +++ b/packages/amplify-category-api/commands/api/add.js @@ -30,14 +30,13 @@ module.exports = { print.success('Some next steps:'); print.info('"amplify push" will build all your local backend resources and provision it in the cloud'); print.info( - '"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud', + '"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud' ); print.info(''); }) .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the API resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/console.js b/packages/amplify-category-api/commands/api/console.js index e487d884df5..6970d423e2b 100644 --- a/packages/amplify-category-api/commands/api/console.js +++ b/packages/amplify-category-api/commands/api/console.js @@ -20,7 +20,6 @@ module.exports = { .catch(err => { context.print.error('Error opening console.'); context.print.info(err.message); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/gql-compile.js b/packages/amplify-category-api/commands/api/gql-compile.js index cc1b55a8409..09564f53053 100644 --- a/packages/amplify-category-api/commands/api/gql-compile.js +++ b/packages/amplify-category-api/commands/api/gql-compile.js @@ -13,7 +13,6 @@ module.exports = { }); } catch (err) { context.print.error(err.toString()); - context.telemetry.emitError(err); } }, }; diff --git a/packages/amplify-category-api/commands/api/push.js b/packages/amplify-category-api/commands/api/push.js index c25e80f69ba..324b969e796 100644 --- a/packages/amplify-category-api/commands/api/push.js +++ b/packages/amplify-category-api/commands/api/push.js @@ -10,7 +10,6 @@ module.exports = { return amplify.pushResources(context, category, resourceName).catch(err => { context.print.error('There was an error pushing the API resource'); context.print.error(err.toString()); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/remove.js b/packages/amplify-category-api/commands/api/remove.js index aa4fcfefeaa..c6ae3c5c4dd 100644 --- a/packages/amplify-category-api/commands/api/remove.js +++ b/packages/amplify-category-api/commands/api/remove.js @@ -23,7 +23,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error removing the api resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-api/commands/api/update.js b/packages/amplify-category-api/commands/api/update.js index 3daba9911df..7c31d07468d 100644 --- a/packages/amplify-category-api/commands/api/update.js +++ b/packages/amplify-category-api/commands/api/update.js @@ -22,7 +22,6 @@ module.exports = { .catch(err => { context.print.error(err.message); console.log(err.stack); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-auth/commands/auth/enable.js b/packages/amplify-category-auth/commands/auth/enable.js index 5d504380de9..85c4463e2a7 100644 --- a/packages/amplify-category-auth/commands/auth/enable.js +++ b/packages/amplify-category-auth/commands/auth/enable.js @@ -83,7 +83,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the auth resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-auth/commands/auth/push.js b/packages/amplify-category-auth/commands/auth/push.js index 4a24b7decc0..e96c25899c4 100644 --- a/packages/amplify-category-auth/commands/auth/push.js +++ b/packages/amplify-category-auth/commands/auth/push.js @@ -16,7 +16,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error pushing the auth resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-auth/commands/auth/remove.js b/packages/amplify-category-auth/commands/auth/remove.js index 72e9b197988..26308b81dcd 100644 --- a/packages/amplify-category-auth/commands/auth/remove.js +++ b/packages/amplify-category-auth/commands/auth/remove.js @@ -21,7 +21,6 @@ module.exports = { return amplify.removeResource(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error removing the auth resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-auth/commands/auth/update.js b/packages/amplify-category-auth/commands/auth/update.js index 71571c896dd..1bf9e379317 100644 --- a/packages/amplify-category-auth/commands/auth/update.js +++ b/packages/amplify-category-auth/commands/auth/update.js @@ -103,7 +103,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the auth resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-auth/index.js b/packages/amplify-category-auth/index.js index f863d5107fa..1f8a91274ab 100644 --- a/packages/amplify-category-auth/index.js +++ b/packages/amplify-category-auth/index.js @@ -60,7 +60,6 @@ async function add(context) { .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the auth resource'); - context.telemetry.emitError(err); }); } @@ -262,7 +261,6 @@ async function console(context) { .catch(err => { context.print.info(err.stack); context.print.error('There was an error trying to open the auth web console.'); - throw err; }); } diff --git a/packages/amplify-category-auth/provider-utils/awscloudformation/utils/trigger-file-uploader.js b/packages/amplify-category-auth/provider-utils/awscloudformation/utils/trigger-file-uploader.js index 054d0165ed5..c60b748ac26 100644 --- a/packages/amplify-category-auth/provider-utils/awscloudformation/utils/trigger-file-uploader.js +++ b/packages/amplify-category-auth/provider-utils/awscloudformation/utils/trigger-file-uploader.js @@ -66,7 +66,6 @@ async function uploadFile(s3Client, hostingBucketName, filePath, file) { .promise() .catch(e => { console.log('e', e); - throw e; }); return data; diff --git a/packages/amplify-category-auth/tests/commands/enable.test.js b/packages/amplify-category-auth/tests/commands/enable.test.js index 24580f8f9c5..d770f440f8a 100644 --- a/packages/amplify-category-auth/tests/commands/enable.test.js +++ b/packages/amplify-category-auth/tests/commands/enable.test.js @@ -19,9 +19,6 @@ describe('auth enable: ', () => { info: jest.fn(), error: jest.fn(), }, - telemetry: { - emitError: jest.fn(), - }, }; it('enable run method should exist', () => { diff --git a/packages/amplify-category-auth/tests/commands/update.test.js b/packages/amplify-category-auth/tests/commands/update.test.js index c961907c5a4..1fc870e88d9 100644 --- a/packages/amplify-category-auth/tests/commands/update.test.js +++ b/packages/amplify-category-auth/tests/commands/update.test.js @@ -34,9 +34,6 @@ describe('auth update: ', () => { info: jest.fn(), error: jest.fn(), }, - telemetry: { - emitError: jest.fn(), - }, }; const dependencies = ['analytics', 'api', 'function', 'storage']; diff --git a/packages/amplify-category-function/src/commands/function/add.ts b/packages/amplify-category-function/src/commands/function/add.ts index a6b66766c2e..8deb4ac968b 100644 --- a/packages/amplify-category-function/src/commands/function/add.ts +++ b/packages/amplify-category-function/src/commands/function/add.ts @@ -42,7 +42,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the function resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-function/src/commands/function/build.ts b/packages/amplify-category-function/src/commands/function/build.ts index 5a0a70fd398..3519fab1bd0 100644 --- a/packages/amplify-category-function/src/commands/function/build.ts +++ b/packages/amplify-category-function/src/commands/function/build.ts @@ -11,7 +11,6 @@ module.exports = { return amplify.buildResources(context, categoryName, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error building the function resources'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-function/src/commands/function/push.ts b/packages/amplify-category-function/src/commands/function/push.ts index ade00ab9e74..fd8313f2bfa 100644 --- a/packages/amplify-category-function/src/commands/function/push.ts +++ b/packages/amplify-category-function/src/commands/function/push.ts @@ -11,7 +11,6 @@ module.exports = { return amplify.pushResources(context, categoryName, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when pushing the function resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-function/src/commands/function/remove.ts b/packages/amplify-category-function/src/commands/function/remove.ts index 662b462197b..71d053fa3ba 100644 --- a/packages/amplify-category-function/src/commands/function/remove.ts +++ b/packages/amplify-category-function/src/commands/function/remove.ts @@ -11,7 +11,6 @@ module.exports = { return amplify.removeResource(context, categoryName, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when removing the function resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-function/src/commands/function/update.ts b/packages/amplify-category-function/src/commands/function/update.ts index 552ee448378..79a96a445a2 100644 --- a/packages/amplify-category-function/src/commands/function/update.ts +++ b/packages/amplify-category-function/src/commands/function/update.ts @@ -22,7 +22,6 @@ module.exports = { .then(() => context.print.success('Successfully updated resource')) .catch(err => { context.print.error(err.stack); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/execPermissionsWalkthrough.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/execPermissionsWalkthrough.ts index 17c9c1e5a33..fef57faf9e2 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/execPermissionsWalkthrough.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/execPermissionsWalkthrough.ts @@ -185,7 +185,6 @@ export async function askExecRolePermissionsQuestions(context, allDefaultValues, } catch (e) { context.print.warning(`Policies cannot be added for ${category}`); context.print.info(e.stack); - context.telemetry.emitError(e); } } diff --git a/packages/amplify-category-hosting/commands/hosting/push.js b/packages/amplify-category-hosting/commands/hosting/push.js index 335db120f0c..3672a440f6e 100644 --- a/packages/amplify-category-hosting/commands/hosting/push.js +++ b/packages/amplify-category-hosting/commands/hosting/push.js @@ -10,7 +10,6 @@ module.exports = { return amplify.pushResources(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error pushing the hosting resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-hosting/commands/hosting/remove.js b/packages/amplify-category-hosting/commands/hosting/remove.js index 1ce3d477ae1..2422bb2d0f2 100644 --- a/packages/amplify-category-hosting/commands/hosting/remove.js +++ b/packages/amplify-category-hosting/commands/hosting/remove.js @@ -21,7 +21,6 @@ module.exports = { } catch (err) { context.print.info(err.stack); context.print.error('There was an error removing the hosting resource'); - context.telemetry.emitError(err); } } else { process.exit(1); diff --git a/packages/amplify-category-interactions/commands/interactions/add.js b/packages/amplify-category-interactions/commands/interactions/add.js index 24684f704ec..3dc84c427e9 100644 --- a/packages/amplify-category-interactions/commands/interactions/add.js +++ b/packages/amplify-category-interactions/commands/interactions/add.js @@ -28,7 +28,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error adding the interactions resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-interactions/commands/interactions/push.js b/packages/amplify-category-interactions/commands/interactions/push.js index 2d8d13621f2..c72d9d64861 100644 --- a/packages/amplify-category-interactions/commands/interactions/push.js +++ b/packages/amplify-category-interactions/commands/interactions/push.js @@ -10,7 +10,6 @@ module.exports = { return amplify.pushResources(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error pushing the interactions resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-interactions/commands/interactions/remove.js b/packages/amplify-category-interactions/commands/interactions/remove.js index 887384438bc..d72f22ceaa3 100644 --- a/packages/amplify-category-interactions/commands/interactions/remove.js +++ b/packages/amplify-category-interactions/commands/interactions/remove.js @@ -10,7 +10,6 @@ module.exports = { return amplify.removeResource(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error removing the interactions resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-interactions/commands/interactions/update.js b/packages/amplify-category-interactions/commands/interactions/update.js index 54588c2b0d1..4e5c6642cf2 100644 --- a/packages/amplify-category-interactions/commands/interactions/update.js +++ b/packages/amplify-category-interactions/commands/interactions/update.js @@ -22,7 +22,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('There was an error updating the interactions resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-predictions/commands/predictions/add.js b/packages/amplify-category-predictions/commands/predictions/add.js index 6f08277f626..1291235b6e8 100644 --- a/packages/amplify-category-predictions/commands/predictions/add.js +++ b/packages/amplify-category-predictions/commands/predictions/add.js @@ -27,13 +27,12 @@ module.exports = { print.success('Some next steps:'); print.info('"amplify push" builds all of your local backend resources and provisions them in the cloud'); print.info( - '"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud', + '"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud' ); print.info(''); }) .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when adding the predictions resource'); - context.telemetry.emitError(err); }), }; diff --git a/packages/amplify-category-predictions/commands/predictions/remove.js b/packages/amplify-category-predictions/commands/predictions/remove.js index e12f87ff5da..e66bd1146bb 100644 --- a/packages/amplify-category-predictions/commands/predictions/remove.js +++ b/packages/amplify-category-predictions/commands/predictions/remove.js @@ -70,7 +70,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when removing the predictions resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-predictions/commands/predictions/update.js b/packages/amplify-category-predictions/commands/predictions/update.js index 0f09d6b1a16..4a35b530ee8 100644 --- a/packages/amplify-category-predictions/commands/predictions/update.js +++ b/packages/amplify-category-predictions/commands/predictions/update.js @@ -22,6 +22,5 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when updating predictions resource!'); - context.telemetry.emitError(err); }), }; diff --git a/packages/amplify-category-predictions/index.js b/packages/amplify-category-predictions/index.js index 1d77fd3b359..9b7f34dfaeb 100644 --- a/packages/amplify-category-predictions/index.js +++ b/packages/amplify-category-predictions/index.js @@ -51,7 +51,6 @@ async function console(context) { .catch(err => { context.print.error('Error opening console.'); context.print.info(err.message); - context.telemetry.emitError(err); }); } diff --git a/packages/amplify-category-storage/commands/storage/add.js b/packages/amplify-category-storage/commands/storage/add.js index cd83cbf1ccc..dd5d059fc4f 100644 --- a/packages/amplify-category-storage/commands/storage/add.js +++ b/packages/amplify-category-storage/commands/storage/add.js @@ -29,14 +29,13 @@ module.exports = { print.success('Some next steps:'); print.info('"amplify push" builds all of your local backend resources and provisions them in the cloud'); print.info( - '"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud', + '"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud' ); print.info(''); }) .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when adding the storage resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-storage/commands/storage/push.js b/packages/amplify-category-storage/commands/storage/push.js index a088e6ec99a..fdaf4a1ebe7 100644 --- a/packages/amplify-category-storage/commands/storage/push.js +++ b/packages/amplify-category-storage/commands/storage/push.js @@ -10,7 +10,6 @@ module.exports = { return amplify.pushResources(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when pushing the storage resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-storage/commands/storage/remove.js b/packages/amplify-category-storage/commands/storage/remove.js index 64238722b67..44e8a21a733 100644 --- a/packages/amplify-category-storage/commands/storage/remove.js +++ b/packages/amplify-category-storage/commands/storage/remove.js @@ -10,7 +10,6 @@ module.exports = { return amplify.removeResource(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('An error occurred when removing the storage resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-storage/commands/storage/update.js b/packages/amplify-category-storage/commands/storage/update.js index 3fec1d2b328..e6073b6c53b 100644 --- a/packages/amplify-category-storage/commands/storage/update.js +++ b/packages/amplify-category-storage/commands/storage/update.js @@ -22,7 +22,6 @@ module.exports = { .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when updating the storage resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-xr/commands/xr/push.js b/packages/amplify-category-xr/commands/xr/push.js index b086218fb69..dd92ff85e85 100644 --- a/packages/amplify-category-xr/commands/xr/push.js +++ b/packages/amplify-category-xr/commands/xr/push.js @@ -9,7 +9,6 @@ module.exports = { return context.amplify.pushResources(context, category, resourceName).catch(err => { context.print.info(err.stack); context.print.error('There was an error pushing the XR resource'); - context.telemetry.emitError(err); }); }, }; diff --git a/packages/amplify-category-xr/lib/xr-manager.js b/packages/amplify-category-xr/lib/xr-manager.js index c6366a8075a..32173e3c11c 100644 --- a/packages/amplify-category-xr/lib/xr-manager.js +++ b/packages/amplify-category-xr/lib/xr-manager.js @@ -228,7 +228,6 @@ async function remove(context) { }) .catch(err => { context.print.info(err.stack); - context.telemetry.emitError(err); }); } diff --git a/packages/amplify-cli/package.json b/packages/amplify-cli/package.json index 28937ece1bd..68b898dd41a 100644 --- a/packages/amplify-cli/package.json +++ b/packages/amplify-cli/package.json @@ -88,8 +88,7 @@ }, "devDependencies": { "@types/node": "^10.17.13", - "@types/parse-json": "^4.0.0", - "nock": "^12.0.3" + "@types/parse-json": "^4.0.0" }, "jest": { "transform": { diff --git a/packages/amplify-cli/scripts/post-install.js b/packages/amplify-cli/scripts/post-install.js index e85b986453f..1c603931d03 100755 --- a/packages/amplify-cli/scripts/post-install.js +++ b/packages/amplify-cli/scripts/post-install.js @@ -2,7 +2,6 @@ require = require('esm')(module, { cache: false }); const chalk = require('chalk'); const fs = require('fs-extra'); const path = require('path'); -const { EOL } = require('os'); // Delete stale ESM cache try { @@ -13,30 +12,18 @@ try { } catch (e) { // could not delete the cache directory but don't want to fail the installation } -console.log(EOL); +console.log('\n'); console.log(chalk.green('----------------------------------------')); console.log(chalk.green('Successfully installed the Amplify CLI')); console.log(chalk.green('----------------------------------------')); -console.log(EOL); +console.log('\n'); console.log(chalk.green('JavaScript Getting Started - https://docs.amplify.aws/start')); -console.log(EOL); +console.log('\n'); console.log(chalk.green('Android Getting Started - https://docs.amplify.aws/start/q/integration/android')); -console.log(EOL); +console.log('\n'); console.log(chalk.green('iOS Getting Started - https://docs.amplify.aws/start/q/integration/ios')); -console.log(EOL); - -console.log( - chalk.blue( - `Amplify CLI collects anonymized usage data, which is used to help understand${EOL}\ -how to improve the product. If you don't wish to send anonymized Amplify CLI${EOL}\ -usage data to AWS, run `, - ) + - chalk.blue.italic.bgWhite('amplify configure --usage-data-off ') + - chalk.blue(` to opt-out.${EOL}${EOL}\ -Learn more - https://docs.amplify.aws/cli/reference/usage-tracking`), -); -console.log(EOL); +console.log('\n'); if (fs.existsSync('../lib/plugin-manager.js')) { require('../lib/plugin-manager').scan(); diff --git a/packages/amplify-cli/src/__tests__/context-manager.test.ts b/packages/amplify-cli/src/__tests__/context-manager.test.ts index e1092e970ce..741366dbf0a 100644 --- a/packages/amplify-cli/src/__tests__/context-manager.test.ts +++ b/packages/amplify-cli/src/__tests__/context-manager.test.ts @@ -1,79 +1,19 @@ import { Input } from '../domain/input'; import { PluginPlatform } from '../domain/plugin-platform'; -import * as appConfig from '../app-config'; -import { constructContext, attachTelemetry } from '../context-manager'; -import { Context } from '../domain/context'; -import { PluginInfo } from '../domain/plugin-info'; -import { PluginManifest } from '../domain/plugin-manifest'; -import * as Telemetry from '../domain/amplify-telemetry'; -import { init } from '../app-config'; -jest.mock('../domain/amplify-telemetry/', () => { - return { - Telemetry: { - Instance: { - init: jest.fn(), - }, - }, - NoTelemetry: { - Instance: { - init: jest.fn(), - }, - }, - }; -}); -jest.mock('../app-config'); - -describe('test attachTelemetry', () => { - const version = 'latestversion'; - const mockContext: Context = jest.genMockFromModule('../domain/context'); +import { constructContext } from '../context-manager'; - mockContext.input = new Input([ +test('constructContext', () => { + const mockProcessArgv = [ '/Users/userName/.nvm/versions/node/v8.11.4/bin/node', '/Users/userName/.nvm/versions/node/v8.11.4/bin/amplify', 'status', - ]); - mockContext.pluginPlatform = new PluginPlatform(); - mockContext.pluginPlatform.plugins['core'] = [new PluginInfo('', version, '', new PluginManifest('', ''))]; - - beforeAll(() => {}); - afterEach(() => { - jest.clearAllMocks(); - }); - - it('constructContext', () => { - const context = constructContext(mockContext.pluginPlatform, mockContext.input); - expect(context).toBeDefined(); - expect(context.amplify).toBeDefined(); - expect(context.pluginPlatform).toEqual(mockContext.pluginPlatform); - expect(context.input).toEqual(mockContext.input); - }); - - it('test with usage data enabled', () => { - const returnValue = { - usageDataConfig: { - installationUuid: 'uuid', - isUsageTrackingEnabled: true, - }, - setValues: jest.fn(), - }; - const mockedInit = appConfig.init as jest.Mock; - mockedInit.mockReturnValue(returnValue); - attachTelemetry(mockContext); - expect(Telemetry.Telemetry.Instance.init).toBeCalledWith(returnValue.usageDataConfig.installationUuid, version, mockContext.input); - }); - - it('test with usage data enabled', () => { - const returnValue = { - usageDataConfig: { - installationUuid: 'uuid', - isUsageTrackingEnabled: false, - }, - setValues: jest.fn(), - }; - const mockedInit = appConfig.init as jest.Mock; - mockedInit.mockReturnValue(returnValue); - attachTelemetry(mockContext); - expect(Telemetry.NoTelemetry.Instance.init).toBeCalledWith(returnValue.usageDataConfig.installationUuid, version, mockContext.input); - }); + ]; + const mockPluginPlatform = new PluginPlatform(); + const mockInput = new Input(mockProcessArgv); + const context = constructContext(mockPluginPlatform, mockInput); + expect(context).toBeDefined(); + expect(context.amplify).toBeDefined(); + expect(context.pluginPlatform).toEqual(mockPluginPlatform); + expect(context.input).toEqual(mockInput); }); diff --git a/packages/amplify-cli/src/__tests__/redaction.test.ts b/packages/amplify-cli/src/__tests__/redaction.test.ts deleted file mode 100644 index ddc9a2959b1..00000000000 --- a/packages/amplify-cli/src/__tests__/redaction.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import redactInput from '../domain/amplify-telemetry/identifiable-input-regex'; -import { Input } from '../domain/input'; - -describe('input-redaction', () => { - const input = new Input([ - '/usr/local/bin/node', - '/usr/local/bin/amplify-dev', - 'init', - '--amplify', - '{"envName":"mydevabc"}', // 4 - '--providers', - '{"awscloudformation":{"configLevel":"project","useProfile":true,"profileName":"default"}}', - '--categories', - '{"notifications":{"Pinpoint":{\n"SMS":{\n"Enabled":true},"Email":{\n"Enabled":true,"FromAddress":"xxx@amzon.com","Identity":"identityArn","RoleArn":"roleArn"},"APNS":{\n"Enabled":true,"DefaultAuthenticationMethod":"Certificate","P12FilePath":"p12filePath","Password":"p12FilePasswordIfAny"},"FCM":{\n"Enabled":true,"ApiKey":"fcmapikey"}}}}', // 8 - '--yes', - ]); - input.command = 'init'; - input.options = { - amplify: '{"envName":"mydevabc"}', - providers: '{"awscloudformation":{"configLevel":"project","useProfile":true,"profileName":"default"}}', - categories: - '{"notifications":{"Pinpoint":{\n"SMS":{\n"Enabled":true},"Email":{\n"Enabled":true,"FromAddress":"xxx@amzon.com","Identity":"identityArn","RoleArn":"roleArn"},"APNS":{\n"Enabled":true,"DefaultAuthenticationMethod":"Certificate","P12FilePath":"p12filePath","Password":"p12FilePasswordIfAny"},"FCM":{\n"Enabled":true,"ApiKey":"fcmapikey"}}}}', - yes: true, - }; - - it('should redact argv and options', () => { - const replacementstring = 'noseethis'; - const redactedInput = redactInput(input, false, replacementstring); - expect(redactedInput.argv.length).toEqual(10); - const redactedCategoriesJsonFromArg = JSON.parse(redactedInput.argv[8]); - expect(redactedCategoriesJsonFromArg.notifications.Pinpoint.APNS.Password).toEqual(replacementstring); - expect(redactedCategoriesJsonFromArg.notifications.Pinpoint.Email.FromAddress).toEqual(replacementstring); - expect(redactedCategoriesJsonFromArg.notifications.Pinpoint.Email.Identity).toEqual(replacementstring); - expect(redactedCategoriesJsonFromArg.notifications.Pinpoint.Email.RoleArn).toEqual(replacementstring); - expect(redactedCategoriesJsonFromArg.notifications.Pinpoint.FCM.ApiKey).toEqual(replacementstring); - expect(redactedInput.options).toBeDefined(); - const options = redactedInput.options || {}; - const redactedCategoriesJsonFromOptions = JSON.parse(options.categories.toString()); - expect(redactedCategoriesJsonFromOptions.notifications.Pinpoint.APNS.Password).toEqual(replacementstring); - expect(redactedCategoriesJsonFromOptions.notifications.Pinpoint.Email.FromAddress).toEqual(replacementstring); - expect(redactedCategoriesJsonFromOptions.notifications.Pinpoint.Email.Identity).toEqual(replacementstring); - expect(redactedCategoriesJsonFromOptions.notifications.Pinpoint.Email.RoleArn).toEqual(replacementstring); - expect(redactedCategoriesJsonFromOptions.notifications.Pinpoint.FCM.ApiKey).toEqual(replacementstring); - const deletedInput = redactInput(input, true, replacementstring); - expect(deletedInput.argv).toBeFalsy(); - expect(deletedInput.options).toBeFalsy(); - }); -}); diff --git a/packages/amplify-cli/src/__tests__/telemetry.test.ts b/packages/amplify-cli/src/__tests__/telemetry.test.ts deleted file mode 100644 index 7839983c552..00000000000 --- a/packages/amplify-cli/src/__tests__/telemetry.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -import url from 'url'; -import nock from 'nock'; -import uuid from 'uuid'; - -import { Telemetry } from '../domain/amplify-telemetry/Telemetry'; -import { getUrl } from '../domain/amplify-telemetry/getTelemetryUrl'; -import { Input } from '../domain/input'; - -const baseOriginalUrl = 'https://cli.amplify'; -const pathToUrl = '/metrics'; -const originalUrl = `${baseOriginalUrl}${pathToUrl}`; - -describe('test telemetry', () => { - beforeAll(() => { - process.env = Object.assign(process.env, { AMPLIFY_CLI_BETA_USAGE_TRACKING_URL: originalUrl }); - }); - afterAll(() => { - nock.cleanAll(); - delete process.env.AMPLIFY_CLI_BETA_USAGE_TRACKING_URL; - }); - - it('test getUrl', () => { - const testUrl = getUrl(); - const parseOrginalUrl = url.parse(originalUrl); - expect(testUrl).toEqual(parseOrginalUrl); - }); - - it('test instance', () => { - const a = Telemetry.Instance; - const b = Telemetry.Instance; - a.init(uuid.v4(), '', new Input([])); - b.init(uuid.v4(), '', new Input([])); - expect(a).toEqual(b); - }); -}); - -describe('test telemetry calls', () => { - beforeAll(() => { - process.env = Object.assign(process.env, { AMPLIFY_CLI_BETA_USAGE_TRACKING_URL: originalUrl }); - }); - afterAll(() => { - nock.cleanAll(); - jest.clearAllMocks(); - delete process.env.AMPLIFY_CLI_BETA_USAGE_TRACKING_URL; - }); - const scope = nock(baseOriginalUrl, { - reqheaders: { - 'content-type': 'application/json', - }, - }).persist(); - it('test https with 503', async () => { - scope.post(pathToUrl, () => true).reply(503, 'Service Unavailable'); - await checkTelemetry(); - }); - - it('test https with 400', async () => { - scope.post(pathToUrl, () => true).reply(400, 'Bad Request'); - await checkTelemetry(); - }); - - it('test https with 302 redirect', async () => { - scope - .post(pathToUrl, () => true) - .reply(302, undefined, { - Location: 'https://somewhere/metrics', - }) - .post('/metrics') - .reply(400, 'Bad Request'); - await checkTelemetry(); - }); - - it('test https with 200 long randomstring', async () => { - scope.post(pathToUrl, () => true).reply(200, '1234567890'.repeat(14)); - await checkTelemetry(); - }); - - it('test delay', async () => { - scope.post(pathToUrl, () => true).delay(10000); - await checkTelemetry(); - }); -}); - -async function checkTelemetry() { - const abortResponse = await Telemetry.Instance.emitAbort(); - expect(abortResponse).toBeUndefined(); - const errorResponse = await Telemetry.Instance.emitError(new Error('something went wrong')); - expect(errorResponse).toBeUndefined(); - - const successResponse = await Telemetry.Instance.emitSuccess(); - expect(successResponse).toBeUndefined(); - const invokeResponse = await Telemetry.Instance.emitInvoke(); - expect(invokeResponse).toBeUndefined(); -} diff --git a/packages/amplify-cli/src/__tests__/version-manager.test.ts b/packages/amplify-cli/src/__tests__/version-manager.test.ts deleted file mode 100644 index 24c10deb33a..00000000000 --- a/packages/amplify-cli/src/__tests__/version-manager.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { getUrl } from '../domain/amplify-telemetry/getTelemetryUrl'; -import { TelemetryPayload } from '../domain/amplify-telemetry/TelemetryPayload'; -import { getLatestApiVersion, getLatestPayloadVersion } from '../domain/amplify-telemetry/VersionManager'; -import { Input } from '../domain/input'; -describe('test version manager', () => { - it('url version should be the latest URL', () => { - const url = getUrl(); - const apiVersion = getLatestApiVersion(); - expect(url.pathname).toContain(apiVersion); - }); - - it('payload version should be the latest', () => { - const payload = new TelemetryPayload('', '', '', new Input([]), new Error(''), ''); - expect(payload.payloadVersion).toEqual(getLatestPayloadVersion()); - }); -}); diff --git a/packages/amplify-cli/src/app-config/config.ts b/packages/amplify-cli/src/app-config/config.ts deleted file mode 100644 index 1d0e50648d4..00000000000 --- a/packages/amplify-cli/src/app-config/config.ts +++ /dev/null @@ -1,52 +0,0 @@ -import fs from 'fs-extra'; -import uuid from 'uuid'; -import _ from 'lodash'; - -import { Context } from '../domain/context'; -import { getPath } from './getPath'; - -export function init(context: Context) { - const configPath = getPath(context); - if (fs.existsSync(configPath)) { - Config.Instance.setValues(fs.readFileSync(configPath)); - } else { - write(context, Config.Instance); - } - return getConfig(); -} - -export function getConfig() { - return Config.Instance; -} - -export function write(context: Context, keyValues: Object) { - Config.Instance.setValues(keyValues); - fs.writeFileSync(getPath(context), JSON.stringify(Config.Instance)); -} - -class Config { - usageDataConfig: UsageDataConfig; - private static instance: Config; - public static get Instance(): Config { - if (!this.instance) { - this.instance = new Config(); - } - return this.instance; - } - private constructor() { - this.usageDataConfig = new UsageDataConfig(); - } - - setValues(keyValues: any) { - Config.instance = _.merge(Config.instance, keyValues); - } -} - -class UsageDataConfig { - installationUuid: String; - isUsageTrackingEnabled: boolean; - constructor() { - this.installationUuid = uuid.v4(); - this.isUsageTrackingEnabled = true; - } -} diff --git a/packages/amplify-cli/src/app-config/getPath.ts b/packages/amplify-cli/src/app-config/getPath.ts deleted file mode 100644 index af4a7d9f688..00000000000 --- a/packages/amplify-cli/src/app-config/getPath.ts +++ /dev/null @@ -1,12 +0,0 @@ -import os from 'os'; -import path from 'path'; -import { Context } from '../domain/context'; -import fs from 'fs-extra'; - -export function getPath(context: Context) { - const executable = path.basename(context.input.argv[1]); - const dir = path.join(os.homedir(), '.amplify'); - const configPath = path.join(dir, `${executable}-configuration.json`); - fs.ensureDirSync(dir); - return configPath; -} diff --git a/packages/amplify-cli/src/app-config/index.ts b/packages/amplify-cli/src/app-config/index.ts deleted file mode 100644 index f03c2281a91..00000000000 --- a/packages/amplify-cli/src/app-config/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './config'; diff --git a/packages/amplify-cli/src/attach-backend.js b/packages/amplify-cli/src/attach-backend.js index bc85d313e9b..98dcc4ad663 100644 --- a/packages/amplify-cli/src/attach-backend.js +++ b/packages/amplify-cli/src/attach-backend.js @@ -24,7 +24,7 @@ async function attachBackend(context, inputParams) { restoreOriginalAmplifyFolder(context); context.print.error('Failed to pull the backend.'); context.print.info(util.inspect(e)); - context.telemetry.emitError(e); + process.exit(1); }); } diff --git a/packages/amplify-cli/src/commands/configure.js b/packages/amplify-cli/src/commands/configure.js index 8134ef3cd78..c7e74d052eb 100644 --- a/packages/amplify-cli/src/commands/configure.js +++ b/packages/amplify-cli/src/commands/configure.js @@ -5,7 +5,6 @@ const configureNewUser = require('../configure-new-user'); const onFailure = require('../config-steps/c9-onFailure'); const onSuccess = require('../config-steps/c9-onSuccess'); const { normalizeInputParams } = require('../input-params-manager'); -import { write } from '../app-config'; module.exports = { name: 'configure', @@ -14,13 +13,6 @@ module.exports = { await configureNewUser.run(context); } - if (context.parameters.options['usage-data-off']) { - write(context, { usageDataConfig: { isUsageTrackingEnabled: false } }); - } - if (context.parameters.options['usage-data-on']) { - write(context, { usageDataConfig: { isUsageTrackingEnabled: true } }); - } - if (context.parameters.first === 'project') { constructExeInfo(context); await analyzeProject diff --git a/packages/amplify-cli/src/commands/plugin.ts b/packages/amplify-cli/src/commands/plugin.ts index 2321535d934..275262794f3 100644 --- a/packages/amplify-cli/src/commands/plugin.ts +++ b/packages/amplify-cli/src/commands/plugin.ts @@ -17,7 +17,6 @@ export async function run(context: Context) { .catch(err => { context.print.error(`Error executing command amplify plugin ${subCommand}`); context.print.error(err.message || err.stack || JSON.stringify(err)); - context.telemetry.emitError(err); process.exit(1); }); } diff --git a/packages/amplify-cli/src/context-manager.ts b/packages/amplify-cli/src/context-manager.ts index 8daf6842dec..39d64b5f998 100644 --- a/packages/amplify-cli/src/context-manager.ts +++ b/packages/amplify-cli/src/context-manager.ts @@ -2,28 +2,15 @@ import { Context } from './domain/context'; import { Input } from './domain/input'; import { PluginPlatform } from './domain/plugin-platform'; import { attachExtentions } from './context-extensions'; -import { init } from './app-config'; -import { Telemetry, NoTelemetry } from './domain/amplify-telemetry'; export function constructContext(pluginPlatform: PluginPlatform, input: Input): Context { const context = new Context(pluginPlatform, input); + attachExtentions(context); - return context; -} -export function attachTelemetry(context: Context) { - const { AMPLIFY_CLI_ENABLE_USAGE_DATA } = process.env; - const config = init(context); - const usageTrackingEnabled = AMPLIFY_CLI_ENABLE_USAGE_DATA - ? AMPLIFY_CLI_ENABLE_USAGE_DATA === 'true' - : config.usageDataConfig.isUsageTrackingEnabled; - if (usageTrackingEnabled) context.telemetry = Telemetry.Instance; - else context.telemetry = NoTelemetry.Instance; - context.telemetry.init(config.usageDataConfig.installationUuid, getVersion(context), context.input); + return context; } -const getVersion = (context: Context) => context.pluginPlatform.plugins.core[0].packageVersion; - export function persistContext(context: Context): void { // write to the backend and current backend // and get the frontend plugin to write to the config files. diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/ITelemetry.ts b/packages/amplify-cli/src/domain/amplify-telemetry/ITelemetry.ts deleted file mode 100644 index 35f2217f726..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/ITelemetry.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Input } from '../input'; - -export interface ITelemetry { - emitError(error: Error): Promise; - emitInvoke(): Promise; - emitAbort(): Promise; - emitSuccess(): Promise; - init(installationUuid: String, version: String, input: Input): void; -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/NoTelemetry.ts b/packages/amplify-cli/src/domain/amplify-telemetry/NoTelemetry.ts deleted file mode 100644 index 878761356cf..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/NoTelemetry.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ITelemetry } from './ITelemetry'; - -export class NoTelemetry implements ITelemetry { - emitError(error: Error): Promise { - return Promise.resolve(); - } - emitInvoke(): Promise { - return Promise.resolve(); - } - emitAbort(): Promise { - return Promise.resolve(); - } - emitSuccess(): Promise { - return Promise.resolve(); - } - init(installationUuid: String, version: String, input: any): void {} - - private static instance: NoTelemetry; - static get Instance(): ITelemetry { - if (!NoTelemetry.instance) NoTelemetry.instance = new NoTelemetry(); - return NoTelemetry.instance; - } -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/Telemetry.ts b/packages/amplify-cli/src/domain/amplify-telemetry/Telemetry.ts deleted file mode 100644 index 72e821565ad..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/Telemetry.ts +++ /dev/null @@ -1,84 +0,0 @@ -import uuid from 'uuid'; -import { Input } from '../input'; -import https from 'https'; -import { UrlWithStringQuery } from 'url'; -import redactInput from './identifiable-input-regex'; -import { TelemetryPayload } from './TelemetryPayload'; -import { getUrl } from './getTelemetryUrl'; -import { ITelemetry } from './ITelemetry'; - -export class Telemetry implements ITelemetry { - sessionUuid: String; - installationUuid: String = ''; - version: String = ''; - input: Input; - url: UrlWithStringQuery; - requestTimeout: number = 100; - private static instance: Telemetry; - - private constructor() { - this.sessionUuid = uuid.v4(); - this.url = getUrl(); - this.input = new Input([]); - } - - init(installationUuid: String, version: String, input: Input): void { - this.installationUuid = installationUuid; - this.version = version; - this.input = redactInput(input, true); - } - - static get Instance(): ITelemetry { - if (!Telemetry.instance) Telemetry.instance = new Telemetry(); - return Telemetry.instance; - } - - emitError(error: Error | null): Promise { - return this.emit(error, WorkflowState.Failed); - } - emitInvoke(): Promise { - return this.emit(null, WorkflowState.Invoke); - } - emitAbort(): Promise { - return this.emit(null, WorkflowState.Aborted); - } - emitSuccess(): Promise { - return this.emit(null, WorkflowState.Successful); - } - - async emit(error: Error | null, state: String): Promise { - const payload = new TelemetryPayload(this.sessionUuid, this.installationUuid, this.version, this.input, error, state); - return this.send(payload); - } - - async send(payload: TelemetryPayload) { - return new Promise((resolve, _) => { - const data = JSON.stringify(payload); - const req = https.request({ - hostname: this.url.hostname, - port: this.url.port, - path: this.url.path, - method: 'POST', - headers: { - 'content-type': 'application/json', - 'content-length': data.length, - }, - }); - req.on('error', () => {}); - req.setTimeout(this.requestTimeout, () => { - resolve(); - }); - req.write(data); - req.end(() => { - resolve(); - }); - }); - } -} - -enum WorkflowState { - Successful = 'SUCCEEDED', - Invoke = 'INVOKED', - Aborted = 'ABORTED', - Failed = 'FAILED', -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/TelemetryPayload.ts b/packages/amplify-cli/src/domain/amplify-telemetry/TelemetryPayload.ts deleted file mode 100644 index 9f691ff1c0f..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/TelemetryPayload.ts +++ /dev/null @@ -1,38 +0,0 @@ -import os from 'os'; -import { Input } from '../input'; -import { getLatestPayloadVersion } from './VersionManager'; - -export class TelemetryPayload { - sessionUuid: String; - installationUuid: String; - amplifyCliVersion: String; - input: Input | null; - timestamp: String; - error!: SerializableError; - payloadVersion: String; - osPlatform: String; - osRelease: String; - nodeVersion: String; - state: String; - constructor(sessionUuid: String, installationUuid: String, version: String, input: Input, error: Error | null, state: String) { - this.sessionUuid = sessionUuid; - this.installationUuid = installationUuid; - this.amplifyCliVersion = version; - this.input = input; - this.timestamp = new Date().toISOString(); - this.osPlatform = os.platform(); - this.osRelease = os.release(); - this.nodeVersion = process.versions.node; - this.state = state; - this.payloadVersion = getLatestPayloadVersion(); - if (error) { - this.error = new SerializableError(error); - } - } -} -export class SerializableError { - name: String; - constructor(error: Error) { - this.name = error.name; - } -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/VersionManager.ts b/packages/amplify-cli/src/domain/amplify-telemetry/VersionManager.ts deleted file mode 100644 index 8190a20368f..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/VersionManager.ts +++ /dev/null @@ -1,23 +0,0 @@ -import semver from 'semver'; - -const APIVersionToPayloadVersion = new Map>([['v1.0', ['1.0.0']]]); - -export function getLatestApiVersion(): string { - return [...APIVersionToPayloadVersion.keys()].reduce(getMaxVersion, '0'); -} - -function getMaxVersion(previousValue: string, currentValue: string, _: number, _a: string[]): string { - const cleanVer = semver.coerce(currentValue); - const cleanPreviousVer = semver.coerce(previousValue); - if (cleanVer === null || cleanPreviousVer == null) throw new Error('version format is wrong '); - if (semver.gt(cleanVer, cleanPreviousVer)) { - return currentValue; - } - return previousValue; -} - -export function getLatestPayloadVersion(): String { - const versions = APIVersionToPayloadVersion.get(getLatestApiVersion()); - if (!versions) throw new Error(`No Payload Versions mapped to API Version ${getLatestApiVersion}`); - return versions.reduce(getMaxVersion, '0'); -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/getTelemetryUrl.ts b/packages/amplify-cli/src/domain/amplify-telemetry/getTelemetryUrl.ts deleted file mode 100644 index 695a1f50d3a..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/getTelemetryUrl.ts +++ /dev/null @@ -1,10 +0,0 @@ -import url, { UrlWithStringQuery } from 'url'; -import { getLatestApiVersion } from './VersionManager'; - -const version = getLatestApiVersion(); -const prodUrl = `https://aws-amplify-cli-telemetry.us-east-1.amazonaws.com/${version}/metrics`; -export function getUrl(): UrlWithStringQuery { - if (process.env.AMPLIFY_CLI_BETA_USAGE_TRACKING_URL && typeof process.env.AMPLIFY_CLI_BETA_USAGE_TRACKING_URL === 'string') - return url.parse(process.env.AMPLIFY_CLI_BETA_USAGE_TRACKING_URL || ''); - return url.parse(prodUrl); -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/identifiable-input-regex.ts b/packages/amplify-cli/src/domain/amplify-telemetry/identifiable-input-regex.ts deleted file mode 100644 index 8e7d2846f58..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/identifiable-input-regex.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Input } from '../input'; - -const containsToRedact = ['key', 'id', 'password', 'name', 'arn', 'address', 'app']; -const quotes = '\\\\?"'; -const keyMatcher = `\\w*?(${containsToRedact.join('|')})\\w*?`; -const completeMatch = `${quotes}(${keyMatcher})${quotes}:\\s?${quotes}([^!\\\\?"]+)${quotes}`; -//matches any string with contiansToRedact in it -const keyregex: RegExp = new RegExp(keyMatcher, 'gmi'); -// matches any json and gives values in json -const jsonregex: RegExp = new RegExp(completeMatch, 'gmi'); -function testReplaceJsonValues(json: string, redactedInput: string): string { - if (!json) return json; - let s: string = json.toString(); - if (jsonregex.test(s)) { - jsonregex.lastIndex = 0; - let m: RegExpExecArray | null; - let valuesToRedact = []; - - //find all values to redact - do { - m = jsonregex.exec(s); - if (m != null) { - valuesToRedact.push(m[3]); - } - } while (m !== null); - - //replace them - valuesToRedact.forEach(val => { - s = s.replace(val, redactedInput); - }); - } else { - return json; - } - return s; -} - -export default function redactInput(originalInput: Input, deleteArgAndOption: Boolean, replacementString: string = '************'): Input { - const input: Input = JSON.parse(JSON.stringify(originalInput)); - const argv = input.argv; - const length = argv.length; - let redactString: Boolean = false; - if (deleteArgAndOption) { - delete input.argv; - delete input.options; - return input; - } - for (var i = 0; i < length; i++) { - argv[i] = testReplaceJsonValues(argv[i], replacementString); - if (redactString) { - if (!isJson(argv[i])) argv[i] = replacementString; - redactString = false; - continue; - } - if (!isJson(argv[i]) && keyregex.test(argv[i])) { - redactString = true; - continue; - } - } - if (input.options) { - Object.keys(input.options).forEach(key => { - if (key && input.options && input.options[key] && typeof input.options[key] === 'string') { - if (keyregex.test(key) && !isJson(input.options[key].toString())) { - input.options[key] = replacementString; - } else if (typeof input.options[key] === 'string') { - input.options[key] = testReplaceJsonValues(input.options[key].toString(), replacementString); - } - } - }); - } - - return input; -} - -function isJson(s: string): Boolean { - try { - JSON.parse(s); - return true; - } catch (_) { - return false; - } -} diff --git a/packages/amplify-cli/src/domain/amplify-telemetry/index.ts b/packages/amplify-cli/src/domain/amplify-telemetry/index.ts deleted file mode 100644 index 3473fc266b7..00000000000 --- a/packages/amplify-cli/src/domain/amplify-telemetry/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ITelemetry } from './ITelemetry'; -import { NoTelemetry } from './NoTelemetry'; -import { Telemetry } from './Telemetry'; - -export { ITelemetry, NoTelemetry, Telemetry }; diff --git a/packages/amplify-cli/src/domain/context.ts b/packages/amplify-cli/src/domain/context.ts index 50d8f0ab76d..0d14202420a 100644 --- a/packages/amplify-cli/src/domain/context.ts +++ b/packages/amplify-cli/src/domain/context.ts @@ -1,15 +1,12 @@ import { Input } from './input'; import { AmplifyToolkit } from './amplify-toolkit'; import { PluginPlatform } from './plugin-platform'; -import { ITelemetry } from './amplify-telemetry'; export class Context { amplify: AmplifyToolkit; - telemetry!: ITelemetry; constructor(public pluginPlatform: PluginPlatform, public input: Input) { this.amplify = new AmplifyToolkit(); } - // ToDo: this is to attach gluegun extensions and other attached properties // already used by the plugins. // After the new platform is stablized, we probably should disallow arbituary diff --git a/packages/amplify-cli/src/domain/error.ts b/packages/amplify-cli/src/domain/error.ts deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/amplify-cli/src/extensions/amplify-helpers/remove-resource.js b/packages/amplify-cli/src/extensions/amplify-helpers/remove-resource.js index 896441d4f25..3fbb3eb0890 100644 --- a/packages/amplify-cli/src/extensions/amplify-helpers/remove-resource.js +++ b/packages/amplify-cli/src/extensions/amplify-helpers/remove-resource.js @@ -69,7 +69,6 @@ async function removeResource(context, category, resourceName) { .catch(err => { context.print.info(err.stack); context.print.error('An error occurred when removing the resources from the local directory'); - context.telemetry.emitError(err); }); } diff --git a/packages/amplify-cli/src/index.ts b/packages/amplify-cli/src/index.ts index d9fd8360323..73be16a3e42 100644 --- a/packages/amplify-cli/src/index.ts +++ b/packages/amplify-cli/src/index.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import { Input } from './domain/input'; import { getPluginPlatform, scan } from './plugin-manager'; import { getCommandLineInput, verifyInput } from './input-manager'; -import { constructContext, persistContext, attachTelemetry } from './context-manager'; +import { constructContext, persistContext } from './context-manager'; import { print } from './context-extensions'; import { executeCommand } from './execution-manager'; import { Context } from './domain/context'; @@ -20,11 +20,9 @@ EventEmitter.defaultMaxListeners = 1000; // entry from commandline export async function run() { - let input = null; - let errorHandler = (e: Error) => {}; try { let pluginPlatform = await getPluginPlatform(); - input = getCommandLineInput(pluginPlatform); + let input = getCommandLineInput(pluginPlatform); // with non-help command supplied, give notification before execution if (input.command !== 'help') { // Checks for available update, defaults to a 1 day interval for notification @@ -50,16 +48,11 @@ export async function run() { throw new Error(verificationResult.message); } } + rewireDeprecatedCommands(input); const context = constructContext(pluginPlatform, input); - - await attachTelemetry(context); - errorHandler = boundErrorHandler.bind(context); - process.on('SIGINT', sigIntHandler.bind(context)); await checkProjectConfigVersion(context); - context.telemetry.emitInvoke(); await executeCommand(context); - context.telemetry.emitSuccess(); persistContext(context); // no command supplied defaults to help, give update notification at end of execution if (input.command === 'help') { @@ -69,7 +62,6 @@ export async function run() { return 0; } catch (e) { // ToDo: add logging to the core, and log execution errors using the unified core logging. - errorHandler(e); if (e.message) { print.error(e.message); } @@ -80,16 +72,8 @@ export async function run() { } } -function boundErrorHandler(this: Context, e: Error) { - this.telemetry.emitError(e); -} -function sigIntHandler(this: Context, e: any) { - this.telemetry.emitAbort(); -} - // entry from library call export async function execute(input: Input): Promise { - let errorHandler = (e: Error) => {}; try { let pluginPlatform = await getPluginPlatform(); let verificationResult = verifyInput(pluginPlatform, input); @@ -110,18 +94,12 @@ export async function execute(input: Input): Promise { } } - const context = await constructContext(pluginPlatform, input); - await attachTelemetry(context); - errorHandler = boundErrorHandler.bind(context); - process.on('SIGINT', sigIntHandler.bind(context)); - context.telemetry.emitInvoke(); + const context = constructContext(pluginPlatform, input); await executeCommand(context); - context.telemetry.emitSuccess(); persistContext(context); return 0; } catch (e) { // ToDo: add logging to the core, and log execution errors using the unified core logging. - errorHandler(e); if (e.message) { print.error(e.message); } diff --git a/packages/amplify-cli/tests/amplify-helpers/input-validation.test.js b/packages/amplify-cli/tests/amplify-helpers/input-validation.test.js new file mode 100644 index 00000000000..7857c5016f8 --- /dev/null +++ b/packages/amplify-cli/tests/amplify-helpers/input-validation.test.js @@ -0,0 +1,158 @@ +const { inputValidation } = require('../../lib/extensions/amplify-helpers/input-validation'); + +describe('input-validation helper: ', () => { + let question = {}; + const rejectionString = 'A response is required for this field'; + + it('...should be exported', () => { + expect(inputValidation).toBeDefined(); + }); + + it('...should return a function', () => { + expect(typeof inputValidation()).toEqual('function'); + }); + + describe('case: question does not have validation', () => { + it('...promise should resolve(true) if input is not present and question is not required', async () => { + await expect(inputValidation(question)(null)).toEqual(true); + }); + + it('...promise should resolve(true) if input is present and question is required', async () => { + question = { required: true }; + await expect(inputValidation(question)('val')).toEqual(true); + }); + + it('...promise should reject(e) if input is not present but question is required', async () => { + question = { required: true }; + await expect(inputValidation(question)(null)).toEqual(rejectionString); + }); + }); + + describe('case: validation operator "includes" and input is string', () => { + beforeEach(() => { + question.validation = { + operator: 'includes', + value: 'test-value', + onErrorMsg: 'not validated', + }; + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)('')).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should reject if input does not include value', async () => { + await expect(inputValidation(question)('my-other-value')).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should resolve(true) if input includes value', async () => { + await expect(inputValidation(question)('test-value')).toEqual(true); + }); + }); + + describe('case: validation operator "includes" and input is string', () => { + beforeEach(() => { + question.validation = { + operator: 'includes', + value: 'test-value', + onErrorMsg: 'not validated', + }; + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)([])).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should reject if input does not include value', async () => { + await expect(inputValidation(question)(['other-value'])).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should resolve(true) if input includes value', async () => { + await expect(inputValidation(question)(['test-value', 'other-value'])).toEqual(true); + }); + }); + + describe('case: validation operator "regex"', () => { + beforeEach(() => { + question.validation = { + operator: 'regex', + value: '^([a-zA-Z0-9]){1,128}$', + onErrorMsg: 'not validated', + }; + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)('')).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should reject if input fails regex test', async () => { + await expect(inputValidation(question)('@@1')).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should resolve(true) if input passes regex test', async () => { + await expect(inputValidation(question)('hello1')).toEqual(true); + }); + }); + + describe('case: validation operator "range"', () => { + beforeEach(() => { + question.validation = { + operator: 'range', + value: { min: 1, max: 10 }, + onErrorMsg: 'not validated', + }; + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)('')).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should reject if input fails range test', async () => { + await expect(inputValidation(question)(0)).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should resolve(true) if input passes range test', async () => { + await expect(inputValidation(question)(5)).toEqual(true); + }); + }); + + describe('case: validation operator "noEmptyArray"', () => { + beforeEach(() => { + question.validation = { + operator: 'noEmptyArray', + onErrorMsg: 'not validated', + }; + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)()).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should reject if input is empty', async () => { + await expect(inputValidation(question)([])).toEqual(question.validation.onErrorMsg); + }); + + it('...promise should resolve(true) if input is populated array', async () => { + await expect(inputValidation(question)([1, 2])).toEqual(true); + }); + }); + + describe('case: questions is required but gets to end of function without hitting test', () => { + beforeEach(() => { + question = { + validation: {}, + required: true, + }; + }); + + it('...promise should reject(e) if input is not present but question is required', async () => { + await expect(inputValidation(question)()).toEqual(rejectionString); + }); + + it('...promise should resolve(true) if input equals anything truthy', async () => { + await expect(inputValidation(question)('val')).toEqual(true); + await expect(inputValidation(question)(1)).toEqual(true); + await expect(inputValidation(question)(['index'])).toEqual(true); + }); + }); +}); diff --git a/packages/amplify-console-hosting/hosting/index.js b/packages/amplify-console-hosting/hosting/index.js index 33ebaa7c801..28a6c5c91f5 100644 --- a/packages/amplify-console-hosting/hosting/index.js +++ b/packages/amplify-console-hosting/hosting/index.js @@ -104,7 +104,6 @@ async function remove(context) { return amplify.removeResource(context, category, resource).catch(err => { context.print.info(err.stack); context.print.error(REMOVE_ERROR_MESSAGE); - context.telemetry.emitError(err); }); }