From fe038a4f0fcf085e90be9c410a7e0151776384bf Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:51:36 -0700 Subject: [PATCH 01/30] feat: create amplify skip prompts for `--yes` option (#507) * feat: add env ci support * test: update unit tests * feat: create amplify --yes option * chore: remove un-used code * feat: support Panage Manager env var * chore: add comments * chore: remove env.CI * chore: update changeset * chore: rename PACKAGE_MANAGER_EXECUTABLE * fix: tests * fix npm -> npx --- .changeset/metal-tomatoes-check.md | 6 ++++++ .../create-amplify/src/get_project_root.test.ts | 17 ++++++++++++++++- packages/create-amplify/src/get_project_root.ts | 9 ++++++++- .../src/npm_package_manager_controller.test.ts | 2 +- .../src/npm_package_manager_controller.ts | 9 ++++++--- .../create-amplify/src/tsconfig_initializer.ts | 16 ++++++++++++---- 6 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 .changeset/metal-tomatoes-check.md diff --git a/.changeset/metal-tomatoes-check.md b/.changeset/metal-tomatoes-check.md new file mode 100644 index 00000000000..cb02e03b2b4 --- /dev/null +++ b/.changeset/metal-tomatoes-check.md @@ -0,0 +1,6 @@ +--- +'create-amplify': patch +--- + +1. Create Amplify (temporarily) uses environment variable for Package Manager +2. Create Amplify uses `yes` option to choose the default value for prompts diff --git a/packages/create-amplify/src/get_project_root.test.ts b/packages/create-amplify/src/get_project_root.test.ts index 333c9974744..601cde9b71e 100644 --- a/packages/create-amplify/src/get_project_root.test.ts +++ b/packages/create-amplify/src/get_project_root.test.ts @@ -2,8 +2,8 @@ import { afterEach, describe, it } from 'node:test'; import assert from 'assert'; import fsp from 'fs/promises'; import path from 'path'; -import { getProjectRoot } from './get_project_root.js'; import { AmplifyPrompter } from '@aws-amplify/cli-core'; +import { getProjectRoot } from './get_project_root.js'; const originalEnv = process.env; @@ -68,4 +68,19 @@ void describe('getProjectRoot', () => { ); assert.equal(projectRoot, path.resolve(userInput)); }); + + void it('use default options if `yes`', async (ctx) => { + process.env.npm_config_yes = 'false'; + process.argv = ['node', 'test.js', '--yes']; + const userInput = 'test'; + const fsMkDirSyncMock = ctx.mock.method(fsp, 'mkdir', () => undefined); + ctx.mock.method(fsp, 'stat', () => Promise.reject(new Error())); + ctx.mock.method(AmplifyPrompter, 'input', () => Promise.resolve(userInput)); + + const projectRoot = await getProjectRoot(); + + assert.equal(fsMkDirSyncMock.mock.callCount(), 1); + assert.equal(fsMkDirSyncMock.mock.calls[0].arguments[0], process.cwd()); + assert.equal(projectRoot, process.cwd()); + }); }); diff --git a/packages/create-amplify/src/get_project_root.ts b/packages/create-amplify/src/get_project_root.ts index bb9dc4f84be..cb693c3d25f 100644 --- a/packages/create-amplify/src/get_project_root.ts +++ b/packages/create-amplify/src/get_project_root.ts @@ -1,5 +1,6 @@ import fsp from 'fs/promises'; import path from 'path'; +import yargs from 'yargs'; import { AmplifyPrompter } from '@aws-amplify/cli-core'; import { logger } from './logger.js'; @@ -7,7 +8,13 @@ import { logger } from './logger.js'; * Returns the project root directory. */ export const getProjectRoot = async () => { - const useDefault = process.env.npm_config_yes === 'true'; + const argv = await yargs(process.argv.slice(2)).options({ + yes: { + type: 'boolean', + default: false, + }, + }).argv; + const useDefault = process.env.npm_config_yes === 'true' || argv.yes === true; const defaultProjectRoot = '.'; let projectRoot: string = useDefault ? defaultProjectRoot diff --git a/packages/create-amplify/src/npm_package_manager_controller.test.ts b/packages/create-amplify/src/npm_package_manager_controller.test.ts index 7504d2c3480..f555d3ba80f 100644 --- a/packages/create-amplify/src/npm_package_manager_controller.test.ts +++ b/packages/create-amplify/src/npm_package_manager_controller.test.ts @@ -12,7 +12,7 @@ void describe('NpmPackageManagerController', () => { await npmPackageManagerController.installDependencies(['testDep'], 'dev'); assert.deepStrictEqual(execaMock.mock.calls[0].arguments, [ 'npm', - ['install', 'testDep', '--save-dev'], + ['install', 'testDep', '-D'], { cwd: 'testPath', stdio: 'inherit' }, ]); }); diff --git a/packages/create-amplify/src/npm_package_manager_controller.ts b/packages/create-amplify/src/npm_package_manager_controller.ts index 39e6ee44068..65c98f0ab7a 100644 --- a/packages/create-amplify/src/npm_package_manager_controller.ts +++ b/packages/create-amplify/src/npm_package_manager_controller.ts @@ -15,7 +15,8 @@ export class NpmPackageManagerController implements PackageManagerController { private readonly projectRoot: string, private readonly execa = _execa ) {} - private readonly executableName = 'npm'; + private readonly executableName = + process.env.PACKAGE_MANAGER_EXECUTABLE || 'npm'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. /** * Installs the given package names as devDependencies @@ -24,9 +25,11 @@ export class NpmPackageManagerController implements PackageManagerController { packageNames: string[], type: DependencyType ): Promise => { - const args = ['install'].concat(...packageNames); + const args = [this.executableName === 'yarn' ? 'add' : 'install'].concat( + ...packageNames + ); if (type === 'dev') { - args.push('--save-dev'); + args.push('-D'); } await this.execa(this.executableName, args, { stdio: 'inherit', diff --git a/packages/create-amplify/src/tsconfig_initializer.ts b/packages/create-amplify/src/tsconfig_initializer.ts index 114f1fdb031..5c88dc8198e 100644 --- a/packages/create-amplify/src/tsconfig_initializer.ts +++ b/packages/create-amplify/src/tsconfig_initializer.ts @@ -17,6 +17,8 @@ export class TsConfigInitializer { private readonly existsSync = _existsSync, private readonly execa = _execa ) {} + private readonly executableName = + process.env.PACKAGE_MANAGER_EXECUTABLE || 'npx'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. /** * If tsconfig.json already exists, this is a noop. Otherwise, `npx tsc --init` is executed to create a tsconfig.json file @@ -27,7 +29,9 @@ export class TsConfigInitializer { return; } this.logger.log( - 'No tsconfig.json file found in the current directory. Running `npx tsc --init`...' + `No tsconfig.json file found in the current directory. Running \`${ + this.executableName === 'npm' ? 'npx' : this.executableName + } tsc --init\`...` ); const packageJson = await this.packageJsonReader.readPackageJson(); @@ -53,20 +57,24 @@ export class TsConfigInitializer { } try { - await this.execa('npx', tscArgs, { + await this.execa(this.executableName, tscArgs, { stdio: 'inherit', cwd: this.projectRoot, }); } catch { throw new Error( - '`npx tsc --init` did not exit successfully. Initialize a valid TypeScript configuration before continuing.' + `\`${ + this.executableName === 'npm' ? 'npx' : this.executableName + } tsc --init\` did not exit successfully. Initialize a valid TypeScript configuration before continuing.` ); } if (!this.tsConfigJsonExists()) { // this should only happen if the customer exits out of npx tsc --init before finishing throw new Error( - 'tsconfig.json does not exist after running `npx tsc --init`. Initialize a valid TypeScript configuration before continuing.' + `tsconfig.json does not exist after running \`${ + this.executableName === 'npm' ? 'npx' : this.executableName + } tsc --init\`. Initialize a valid TypeScript configuration before continuing.` ); } }; From c7af23964717bb1989fb2d0c3ce2406eaaa1a8d6 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:59:47 -0700 Subject: [PATCH 02/30] feat: init e2e test workflow for Package Manager Support (#533) * test: init e2e flow test * fix GH hash * use dynamic pkg manager * setup nodejs with npm * setup more pkg managers * install pkg managers * fix yarn1 and change step name * fix yarn1 * fix yarn1 * split yarn1 into 2 steps * fix yarn1 * fix yarn1 win * exclude bun on windows * yarn1 windows * setup yarn3 * yarn3 * yarn3 yarnPath * yarn use 3rd party action * try yarn3 * set yarn 3.6.x * set yarn berry * set yarn stable and pass --yes * feat: add env ci support * test: update unit tests * feat: create amplify --yes option * chore: remove un-used code * feat: support Panage Manager env var * chore: add comments * chore: remove env.CI * chore: update changeset * chore: rename PACKAGE_MANAGER_EXECUTABLE * fix: tests * use Env Var PACKAGE_MANAGER_EXECUTABLE * fix npm -> npx, remove bun * fix npm -> npx * change -- --yes * chore: update package.lock * chore: remove @alpha * fix: clean up yarn * fix: change yarn1 to yarn * chore: rename yarn step * chore: use env * fix: yarn-stable env var * add comments * chore: update sample app with new imports (#541) * feat: use "use client"; directive in generated react components (#540) * fix: flatten prop types auth (#534) * fix: flatten auth login with types * chore: update snapshots * chore: update api * chore: add changeset * chore: add TODO --------- Co-authored-by: Amplifiyer <51211245+Amplifiyer@users.noreply.github.com> Co-authored-by: Spencer Stolworthy Co-authored-by: awsluja <110861985+awsluja@users.noreply.github.com> --- .github/workflows/poc-e2e-flow-test.yml | 57 +++++++++++++++++++ .../src/tsconfig_initializer.ts | 12 ++-- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/poc-e2e-flow-test.yml diff --git a/.github/workflows/poc-e2e-flow-test.yml b/.github/workflows/poc-e2e-flow-test.yml new file mode 100644 index 00000000000..9f1870dc93d --- /dev/null +++ b/.github/workflows/poc-e2e-flow-test.yml @@ -0,0 +1,57 @@ +# Description: This workflow mimic the flow of behaviors when user using Amplify CLI; + +name: 'poc-e2e-flow-test' + +on: # TODO: need to change the trigger + push: + branches: + - poc/e2e-test + +jobs: + create-amplify-project: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + node-version: [18] + pkg-manager: [npm, yarn, yarn-stable, pnpm] + runs-on: ${{ matrix.os }} + env: + PACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). + steps: + - name: Checkout aws-amplify/amplify-cli repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1. TODO: try only fetch .github/workflow + - name: Setup Node.js + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #4.0.0 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - name: Local Publish create-amplify + shell: bash + run: npm run install:local && npm run build && npm run vend + - name: ${{matrix.pkg-manager}}-create-amplify-project + if: matrix.pkg-manager != 'yarn-stable' + shell: bash + run: + | # TODO: last step `create amplify` should be replaced by `run e2e` + mkdir -p /tmp/amplify-project; cd /tmp/amplify-project + npm install -g ${{matrix.pkg-manager}} + echo "$(${{matrix.pkg-manager}}) config set registry http://localhost:4873" + ${{matrix.pkg-manager}} config set registry http://localhost:4873 + echo "$(${{matrix.pkg-manager}}) config get registry" + ${{matrix.pkg-manager}} config get registry + ${{matrix.pkg-manager}} create amplify --yes + + - name: yarn-stable-create-amplify-project + if: matrix.pkg-manager == 'yarn-stable' + shell: bash + run: + | # TODO: last step `create amplify` should be replaced by `run e2e` + mkdir -p /tmp/amplify-project; cd /tmp/amplify-project + corepack enable + echo "yarn set version stable" + yarn set version stable + echo "yarn version $(yarn --version)" + yarn config set unsafeHttpWhitelist localhost + yarn config set npmRegistryServer http://localhost:4873 + PACKAGE_MANAGER_EXECUTABLE=yarn yarn create amplify --yes diff --git a/packages/create-amplify/src/tsconfig_initializer.ts b/packages/create-amplify/src/tsconfig_initializer.ts index 5c88dc8198e..0ad229653d0 100644 --- a/packages/create-amplify/src/tsconfig_initializer.ts +++ b/packages/create-amplify/src/tsconfig_initializer.ts @@ -57,10 +57,14 @@ export class TsConfigInitializer { } try { - await this.execa(this.executableName, tscArgs, { - stdio: 'inherit', - cwd: this.projectRoot, - }); + await this.execa( + this.executableName === 'npm' ? 'npx' : this.executableName, + tscArgs, + { + stdio: 'inherit', + cwd: this.projectRoot, + } + ); } catch { throw new Error( `\`${ From 6c0036f4310953368adda62afb723e503969aeee Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Thu, 2 Nov 2023 14:17:29 -0700 Subject: [PATCH 03/30] fix: pnpm init and env var (#563) * fix: npm_project_initializer to use env var * fix: pnpm init --- .../src/npm_project_initializer.ts | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/create-amplify/src/npm_project_initializer.ts b/packages/create-amplify/src/npm_project_initializer.ts index 856abfca7c4..4ef53b272ff 100644 --- a/packages/create-amplify/src/npm_project_initializer.ts +++ b/packages/create-amplify/src/npm_project_initializer.ts @@ -16,6 +16,9 @@ export class NpmProjectInitializer { private readonly execa = _execa ) {} + private readonly executableName = + process.env.PACKAGE_MANAGER_EXECUTABLE || 'npm'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. + /** * If package.json already exists, this is a noop. Otherwise, `npm init` is executed to create a package.json file */ @@ -24,18 +27,23 @@ export class NpmProjectInitializer { // if package.json already exists, no need to do anything return; } + this.logger.log( - 'No package.json file found in the current directory. Running `npm init`...' + `No package.json file found in the current directory. Running \`${this.executableName} init\`...` ); try { - await this.execa('npm', ['init', '--yes'], { - stdio: 'inherit', - cwd: this.projectRoot, - }); + await this.execa( + this.executableName, + this.executableName === 'pnpm' ? ['init'] : ['init', '--yes'], + { + stdio: 'inherit', + cwd: this.projectRoot, + } + ); } catch { throw new Error( - '`npm init` did not exit successfully. Initialize a valid JavaScript package before continuing.' + `\`${this.executableName} init\` did not exit successfully. Initialize a valid JavaScript package before continuing.` ); } @@ -51,7 +59,7 @@ export class NpmProjectInitializer { if (!this.packageJsonExists()) { // this should only happen if the customer exits out of npm init before finishing throw new Error( - 'package.json does not exist after running `npm init`. Initialize a valid JavaScript package before continuing.' + `package.json does not exist after running \`${this.executableName} init\`. Initialize a valid JavaScript package before continuing.'` ); } }; From 67507139f2b30285dc8bf17975752b0677f38b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Fri, 10 Nov 2023 13:01:09 -0800 Subject: [PATCH 04/30] chore: update package.lock --- package-lock.json | 176 +++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f9e166ca7c..01a2d37fec3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19428,12 +19428,12 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.2.4", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.1" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/plugin-types": "^0.4.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19442,19 +19442,19 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.3.4", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.2.2", - "@aws-amplify/backend-data": "^0.4.0", - "@aws-amplify/backend-function": "^0.1.4", - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/backend-secret": "^0.2.1", - "@aws-amplify/backend-storage": "^0.2.1", + "@aws-amplify/backend-auth": "^0.3.0", + "@aws-amplify/backend-data": "^0.5.0", + "@aws-amplify/backend-function": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/backend-secret": "^0.3.0", + "@aws-amplify/backend-storage": "^0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/plugin-types": "^0.3.1", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "@aws-sdk/client-amplify": "^3.440.0" }, "devDependencies": { @@ -19468,16 +19468,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.2.2", - "@aws-amplify/backend-output-storage": "0.2.0", - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/auth-construct-alpha": "^0.3.0", + "@aws-amplify/backend-output-storage": "0.2.1", + "@aws-amplify/plugin-types": "^0.4.0" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.3" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19486,19 +19486,19 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.4.0", + "version": "0.5.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "0.2.1", "@aws-amplify/data-schema-types": "^0.4.2", "@aws-amplify/graphql-api-construct": "^1.3.0", - "@aws-amplify/plugin-types": "^0.3.1" + "@aws-amplify/plugin-types": "^0.4.0" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4" + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19507,11 +19507,11 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "execa": "^7.2.0", "tsx": "^3.12.6" }, @@ -19522,17 +19522,17 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.1.4", + "version": "0.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "0.2.0", + "@aws-amplify/backend-output-storage": "0.2.1", "@aws-amplify/function-construct-alpha": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/plugin-types": "^0.4.0", "execa": "^7.1.1" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.4" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19541,10 +19541,10 @@ }, "packages/backend-output-schemas": { "name": "@aws-amplify/backend-output-schemas", - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/plugin-types": "0.3.1" + "@aws-amplify/plugin-types": "0.4.0" }, "peerDependencies": { "zod": "^3.21.4" @@ -19552,11 +19552,11 @@ }, "packages/backend-output-storage": { "name": "@aws-amplify/backend-output-storage", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.1" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0" @@ -19564,7 +19564,7 @@ }, "packages/backend-platform-test-stubs": { "name": "@aws-amplify/backend-platform-test-stubs", - "version": "0.2.0", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "aws-cdk-lib": "^2.100.0", @@ -19573,11 +19573,11 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.1.2", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "@aws-sdk/client-ssm": "^3.398.0" }, "devDependencies": { @@ -19586,16 +19586,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.2.2", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.0", - "@aws-amplify/storage-construct-alpha": "^0.2.0" + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/plugin-types": "^0.4.0", + "@aws-amplify/storage-construct-alpha": "^0.2.1" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.3" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19604,18 +19604,18 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.5.0", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/backend-secret": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.2.1", - "@aws-amplify/deployed-backend-client": "^0.2.0", + "@aws-amplify/client-config": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", "@aws-amplify/form-generator": "^0.3.0", - "@aws-amplify/model-generator": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/sandbox": "^0.2.4", + "@aws-amplify/model-generator": "^0.2.1", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/sandbox": "^0.3.0", "@aws-sdk/credential-provider-ini": "^3.360.0", "@aws-sdk/credential-providers": "^3.360.0", "@aws-sdk/region-config-resolver": "^3.433.0", @@ -19760,12 +19760,12 @@ }, "packages/client-config": { "name": "@aws-amplify/client-config", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/deployed-backend-client": "^0.2.1", - "@aws-amplify/model-generator": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", + "@aws-amplify/model-generator": "^0.2.1", "@aws-sdk/client-amplify": "^3.376.0", "@aws-sdk/client-cloudformation": "^3.376.0", "@aws-sdk/client-ssm": "^3.398.0", @@ -19773,12 +19773,12 @@ "zod": "^3.21.4" }, "devDependencies": { - "@aws-amplify/platform-core": "^0.1.3", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/types": "^3.370.0" } }, "packages/create-amplify": { - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", @@ -19904,11 +19904,11 @@ }, "packages/deployed-backend-client": { "name": "@aws-amplify/deployed-backend-client", - "version": "0.2.2", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/platform-core": "^0.1.2", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-amplify": "^3.329.0", "@aws-sdk/client-cloudformation": "^3.329.0", "@aws-sdk/client-s3": "^3.329.0", @@ -19949,15 +19949,15 @@ }, "packages/integration-tests": { "name": "@aws-amplify/integration-tests", - "version": "0.2.4", + "version": "0.3.0", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/backend": "0.3.4", - "@aws-amplify/backend-auth": "0.2.3", - "@aws-amplify/backend-secret": "^0.2.1", - "@aws-amplify/backend-storage": "0.2.2", + "@aws-amplify/backend": "0.4.0", + "@aws-amplify/backend-auth": "0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", + "@aws-amplify/backend-storage": "0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-amplify": "^3.440.0", "@aws-sdk/client-cloudformation": "^3.421.0", "execa": "^8.0.1", @@ -20023,11 +20023,11 @@ }, "packages/model-generator": { "name": "@aws-amplify/model-generator", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/deployed-backend-client": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", "@aws-amplify/graphql-generator": "^0.1.3", "@aws-amplify/graphql-types-generator": "^3.4.4", "@aws-sdk/client-appsync": "^3.398.0", @@ -20043,15 +20043,15 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.1.4", + "version": "0.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/plugin-types": "^0.4.0" } }, "packages/plugin-types": { "name": "@aws-amplify/plugin-types", - "version": "0.3.1", + "version": "0.4.0", "license": "Apache-2.0", "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -20060,15 +20060,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.2.4", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "0.2.3", - "@aws-amplify/backend-secret": "^0.2.1", + "@aws-amplify/backend-deployer": "0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "0.2.3", - "@aws-amplify/deployed-backend-client": "^0.2.1", - "@aws-amplify/platform-core": "^0.1.4", + "@aws-amplify/client-config": "0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/credential-providers": "^3.382.0", "@aws-sdk/types": "^3.378.0", @@ -20116,14 +20116,14 @@ }, "packages/storage-construct": { "name": "@aws-amplify/storage-construct-alpha", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1" }, "devDependencies": { - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/plugin-types": "^0.4.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", From d5eab4ac73b190b77996a626ee312b5bc59fd430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Fri, 10 Nov 2023 15:48:46 -0800 Subject: [PATCH 05/30] chore: update package.lock --- package-lock.json | 176 +++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f9e166ca7c..e7a91de794a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19428,12 +19428,12 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.2.4", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.1" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/plugin-types": "^0.4.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19442,19 +19442,19 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.3.4", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.2.2", - "@aws-amplify/backend-data": "^0.4.0", - "@aws-amplify/backend-function": "^0.1.4", - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/backend-secret": "^0.2.1", - "@aws-amplify/backend-storage": "^0.2.1", + "@aws-amplify/backend-auth": "^0.3.0", + "@aws-amplify/backend-data": "^0.5.0", + "@aws-amplify/backend-function": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/backend-secret": "^0.3.0", + "@aws-amplify/backend-storage": "^0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/plugin-types": "^0.3.1", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "@aws-sdk/client-amplify": "^3.440.0" }, "devDependencies": { @@ -19468,16 +19468,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.2.2", - "@aws-amplify/backend-output-storage": "0.2.0", - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/auth-construct-alpha": "^0.3.0", + "@aws-amplify/backend-output-storage": "0.2.1", + "@aws-amplify/plugin-types": "^0.4.0" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.3" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19486,19 +19486,19 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.4.0", + "version": "0.5.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "0.2.1", "@aws-amplify/data-schema-types": "^0.4.2", "@aws-amplify/graphql-api-construct": "^1.3.0", - "@aws-amplify/plugin-types": "^0.3.1" + "@aws-amplify/plugin-types": "^0.4.0" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4" + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19507,11 +19507,11 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "execa": "^7.2.0", "tsx": "^3.12.6" }, @@ -19522,17 +19522,17 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.1.4", + "version": "0.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "0.2.0", + "@aws-amplify/backend-output-storage": "0.2.1", "@aws-amplify/function-construct-alpha": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/plugin-types": "^0.4.0", "execa": "^7.1.1" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.4" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19541,10 +19541,10 @@ }, "packages/backend-output-schemas": { "name": "@aws-amplify/backend-output-schemas", - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/plugin-types": "0.3.1" + "@aws-amplify/plugin-types": "0.4.0" }, "peerDependencies": { "zod": "^3.21.4" @@ -19552,11 +19552,11 @@ }, "packages/backend-output-storage": { "name": "@aws-amplify/backend-output-storage", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.1" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0" @@ -19564,7 +19564,7 @@ }, "packages/backend-platform-test-stubs": { "name": "@aws-amplify/backend-platform-test-stubs", - "version": "0.2.0", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "aws-cdk-lib": "^2.100.0", @@ -19573,11 +19573,11 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.2.1", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.1.2", - "@aws-amplify/plugin-types": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/plugin-types": "^0.4.0", "@aws-sdk/client-ssm": "^3.398.0" }, "devDependencies": { @@ -19586,16 +19586,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.2.2", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "^0.2.0", - "@aws-amplify/plugin-types": "^0.3.0", - "@aws-amplify/storage-construct-alpha": "^0.2.0" + "@aws-amplify/backend-output-storage": "^0.2.1", + "@aws-amplify/plugin-types": "^0.4.0", + "@aws-amplify/storage-construct-alpha": "^0.2.1" }, "devDependencies": { - "@aws-amplify/backend-platform-test-stubs": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.3" + "@aws-amplify/backend-platform-test-stubs": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -19604,18 +19604,18 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.5.0", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/backend-secret": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.2.1", - "@aws-amplify/deployed-backend-client": "^0.2.0", + "@aws-amplify/client-config": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", "@aws-amplify/form-generator": "^0.3.0", - "@aws-amplify/model-generator": "^0.2.0", - "@aws-amplify/platform-core": "^0.1.4", - "@aws-amplify/sandbox": "^0.2.4", + "@aws-amplify/model-generator": "^0.2.1", + "@aws-amplify/platform-core": "^0.2.0", + "@aws-amplify/sandbox": "^0.3.0", "@aws-sdk/credential-provider-ini": "^3.360.0", "@aws-sdk/credential-providers": "^3.360.0", "@aws-sdk/region-config-resolver": "^3.433.0", @@ -19760,12 +19760,12 @@ }, "packages/client-config": { "name": "@aws-amplify/client-config", - "version": "0.2.3", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/deployed-backend-client": "^0.2.1", - "@aws-amplify/model-generator": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", + "@aws-amplify/model-generator": "^0.2.1", "@aws-sdk/client-amplify": "^3.376.0", "@aws-sdk/client-cloudformation": "^3.376.0", "@aws-sdk/client-ssm": "^3.398.0", @@ -19773,12 +19773,12 @@ "zod": "^3.21.4" }, "devDependencies": { - "@aws-amplify/platform-core": "^0.1.3", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/types": "^3.370.0" } }, "packages/create-amplify": { - "version": "0.2.3", + "version": "0.3.1", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", @@ -19904,11 +19904,11 @@ }, "packages/deployed-backend-client": { "name": "@aws-amplify/deployed-backend-client", - "version": "0.2.2", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/platform-core": "^0.1.2", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-amplify": "^3.329.0", "@aws-sdk/client-cloudformation": "^3.329.0", "@aws-sdk/client-s3": "^3.329.0", @@ -19949,15 +19949,15 @@ }, "packages/integration-tests": { "name": "@aws-amplify/integration-tests", - "version": "0.2.4", + "version": "0.3.1", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/backend": "0.3.4", - "@aws-amplify/backend-auth": "0.2.3", - "@aws-amplify/backend-secret": "^0.2.1", - "@aws-amplify/backend-storage": "0.2.2", + "@aws-amplify/backend": "0.4.0", + "@aws-amplify/backend-auth": "0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", + "@aws-amplify/backend-storage": "0.3.0", "@aws-amplify/data-schema": "^0.11.0", - "@aws-amplify/platform-core": "^0.1.4", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-amplify": "^3.440.0", "@aws-sdk/client-cloudformation": "^3.421.0", "execa": "^8.0.1", @@ -20023,11 +20023,11 @@ }, "packages/model-generator": { "name": "@aws-amplify/model-generator", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.0", - "@aws-amplify/deployed-backend-client": "^0.2.0", + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", "@aws-amplify/graphql-generator": "^0.1.3", "@aws-amplify/graphql-types-generator": "^3.4.4", "@aws-sdk/client-appsync": "^3.398.0", @@ -20043,15 +20043,15 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.1.4", + "version": "0.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/plugin-types": "^0.4.0" } }, "packages/plugin-types": { "name": "@aws-amplify/plugin-types", - "version": "0.3.1", + "version": "0.4.0", "license": "Apache-2.0", "peerDependencies": { "aws-cdk-lib": "^2.103.0", @@ -20060,15 +20060,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.2.4", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "0.2.3", - "@aws-amplify/backend-secret": "^0.2.1", + "@aws-amplify/backend-deployer": "0.3.0", + "@aws-amplify/backend-secret": "^0.3.0", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "0.2.3", - "@aws-amplify/deployed-backend-client": "^0.2.1", - "@aws-amplify/platform-core": "^0.1.4", + "@aws-amplify/client-config": "0.3.0", + "@aws-amplify/deployed-backend-client": "^0.3.0", + "@aws-amplify/platform-core": "^0.2.0", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/credential-providers": "^3.382.0", "@aws-sdk/types": "^3.378.0", @@ -20116,14 +20116,14 @@ }, "packages/storage-construct": { "name": "@aws-amplify/storage-construct-alpha", - "version": "0.2.0", + "version": "0.2.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.2.1", - "@aws-amplify/backend-output-storage": "^0.2.0" + "@aws-amplify/backend-output-schemas": "^0.3.0", + "@aws-amplify/backend-output-storage": "^0.2.1" }, "devDependencies": { - "@aws-amplify/plugin-types": "^0.3.0" + "@aws-amplify/plugin-types": "^0.4.0" }, "peerDependencies": { "aws-cdk-lib": "^2.103.0", From c34a987a5d4a574e1c09602eeb53620649303408 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:32:37 -0800 Subject: [PATCH 06/30] test: use GH workflow for e2e test of create amplify (#636) * feat: setup GH workflow for create amplify * chore: changeset * fix: add pkg type for modern yarn * fix npm install * feat: test Node v20 and Node v19 * feat: test Node v20 and yarn-stable with Node 19 * feat: exclude yarn-stable * feat: include node 20 and exclude node 19 * feat: use node 20 for others, use node 19 for yarn-stable * chore: add TODO to use Node 20 --- .changeset/small-readers-check.md | 7 + .github/workflows/poc-e2e-flow-test.yml | 93 +++++---- .../src/npm_package_manager_controller.ts | 20 +- .../src/tsconfig_initializer.ts | 7 +- .../src/test-e2e/create_amplify.test.ts | 192 ++++++++++++++++-- 5 files changed, 256 insertions(+), 63 deletions(-) create mode 100644 .changeset/small-readers-check.md diff --git a/.changeset/small-readers-check.md b/.changeset/small-readers-check.md new file mode 100644 index 00000000000..7d3dc296122 --- /dev/null +++ b/.changeset/small-readers-check.md @@ -0,0 +1,7 @@ +--- +'@aws-amplify/integration-tests': patch +'create-amplify': patch +--- + +- Support yarn, pnpm via env var +- Add e2e test against yarn, pnpm diff --git a/.github/workflows/poc-e2e-flow-test.yml b/.github/workflows/poc-e2e-flow-test.yml index 9f1870dc93d..63fd37e8ea8 100644 --- a/.github/workflows/poc-e2e-flow-test.yml +++ b/.github/workflows/poc-e2e-flow-test.yml @@ -5,53 +5,70 @@ name: 'poc-e2e-flow-test' on: # TODO: need to change the trigger push: branches: - - poc/e2e-test + - poc/e2e-create-amplify jobs: - create-amplify-project: + install: strategy: - fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - node-version: [18] - pkg-manager: [npm, yarn, yarn-stable, pnpm] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} + steps: + - name: Checkout aws-amplify/amplify-cli repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Setup Node.js + uses: ./.github/actions/setup_node + - name: Install or Restore Cache + uses: ./.github/actions/install_with_cache + build: + runs-on: ubuntu-latest + needs: + - install + steps: + - name: Checkout aws-amplify/amplify-cli repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Setup Node.js + uses: ./.github/actions/setup_node + - name: Build or Restore Build Cache + uses: ./.github/actions/build_with_cache + run_e2e_tests: + strategy: + # will finish running other test matrices even if one fails + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + pkg-manager: [npm, yarn, pnpm] + node-version: [20] + include: + - os: ubuntu-latest + pkg-manager: yarn-stable + node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released + - os: macos-latest + pkg-manager: yarn-stable + node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released + - os: windows-latest + pkg-manager: yarn-stable + node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released env: - PACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). + ACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + needs: + - build + permissions: + # these permissions are required for the configure-aws-credentials action to get a JWT from GitHub + id-token: write + contents: read steps: - name: Checkout aws-amplify/amplify-cli repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1. TODO: try only fetch .github/workflow + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Setup Node.js - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #4.0.0 + uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # version 3.8.1 with: node-version: ${{ matrix.node-version }} - cache: npm - - name: Local Publish create-amplify - shell: bash - run: npm run install:local && npm run build && npm run vend - - name: ${{matrix.pkg-manager}}-create-amplify-project - if: matrix.pkg-manager != 'yarn-stable' - shell: bash - run: - | # TODO: last step `create amplify` should be replaced by `run e2e` - mkdir -p /tmp/amplify-project; cd /tmp/amplify-project - npm install -g ${{matrix.pkg-manager}} - echo "$(${{matrix.pkg-manager}}) config set registry http://localhost:4873" - ${{matrix.pkg-manager}} config set registry http://localhost:4873 - echo "$(${{matrix.pkg-manager}}) config get registry" - ${{matrix.pkg-manager}} config get registry - ${{matrix.pkg-manager}} create amplify --yes - - - name: yarn-stable-create-amplify-project - if: matrix.pkg-manager == 'yarn-stable' + - name: Restore Build Cache + uses: ./.github/actions/restore_build_cache + - name: Run E2E tests with ${{ matrix.pkg-manager }} shell: bash - run: - | # TODO: last step `create amplify` should be replaced by `run e2e` - mkdir -p /tmp/amplify-project; cd /tmp/amplify-project - corepack enable - echo "yarn set version stable" - yarn set version stable - echo "yarn version $(yarn --version)" - yarn config set unsafeHttpWhitelist localhost - yarn config set npmRegistryServer http://localhost:4873 - PACKAGE_MANAGER_EXECUTABLE=yarn yarn create amplify --yes + run: | + PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/create_amplify.test.ts diff --git a/packages/create-amplify/src/npm_package_manager_controller.ts b/packages/create-amplify/src/npm_package_manager_controller.ts index e5cc8ce4361..546c581de44 100644 --- a/packages/create-amplify/src/npm_package_manager_controller.ts +++ b/packages/create-amplify/src/npm_package_manager_controller.ts @@ -16,8 +16,11 @@ export class NpmPackageManagerController implements PackageManagerController { private readonly projectRoot: string, private readonly execa = _execa ) {} - private readonly executableName = - process.env.PACKAGE_MANAGER_EXECUTABLE || 'npm'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. + private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE + ? 'npm' + : process.env.PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. /** * Installs the given package names as devDependencies @@ -34,9 +37,18 @@ export class NpmPackageManagerController implements PackageManagerController { } try { - await executeWithDebugLogger(this.projectRoot, 'npm', args, this.execa); + await executeWithDebugLogger( + this.projectRoot, + this.executableName, + args, + this.execa + ); } catch { - throw new Error(`\`npm ${args.join(' ')}\` did not exit successfully.`); + throw new Error( + `\`${this.executableName} ${args.join( + ' ' + )}\` did not exit successfully.` + ); } }; } diff --git a/packages/create-amplify/src/tsconfig_initializer.ts b/packages/create-amplify/src/tsconfig_initializer.ts index b17c4c27440..d6aba8a5b91 100644 --- a/packages/create-amplify/src/tsconfig_initializer.ts +++ b/packages/create-amplify/src/tsconfig_initializer.ts @@ -18,8 +18,11 @@ export class TsConfigInitializer { private readonly existsSync = _existsSync, private readonly execa = _execa ) {} - private readonly executableName = - process.env.PACKAGE_MANAGER_EXECUTABLE || 'npx'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. + private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE + ? 'npx' + : process.env.PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. /** * If tsconfig.json already exists, this is a noop. Otherwise, `npx tsc --init` is executed to create a tsconfig.json file diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index e21648a331a..3f18df07958 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -7,19 +7,87 @@ import { after, afterEach, before, beforeEach, describe, it } from 'node:test'; import assert from 'assert'; import { glob } from 'glob'; -void describe('create-amplify script', () => { - before(async () => { - // start a local npm proxy and publish the current codebase to the proxy - await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); - await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); +type PackageManagerExecutable = 'npm' | 'yarn' | 'yarn-stable' | 'pnpm'; - // nuke the npx cache to ensure we are installing packages from the npm proxy +const packageManagerSetup = async ( + packageManagerExecutable: PackageManagerExecutable, + dir: string +) => { + const execaOptions = { + cwd: dir, + stdio: 'inherit' as const, + }; + + if (packageManagerExecutable === 'npm') { const { stdout } = await execa('npm', ['config', 'get', 'cache']); const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); if (existsSync(npxCacheLocation)) { await fs.rm(npxCacheLocation, { recursive: true }); } + } else if (packageManagerExecutable.startsWith('yarn')) { + if (packageManagerExecutable === 'yarn-stable') { + await execa('yarn', ['set', 'version', 'stable'], execaOptions); + await execa('npm', ['pkg', 'set', 'type=module'], execaOptions); // `npm pkg set type="module"` only run when package.json does not exist, so we need to run it manually here + + await execa( + 'yarn', + ['config', 'set', 'npmRegistryServer', 'http://localhost:4873'], + execaOptions + ); + await execa( + 'yarn', + ['config', 'set', 'unsafeHttpWhitelist', 'localhost'], + execaOptions + ); + } else { + await execa( + packageManagerExecutable, + ['config', 'set', 'registry', 'http://localhost:4873'], + execaOptions + ); + await execa( + packageManagerExecutable, + ['config', 'get', 'registry'], + execaOptions + ); + } + await execa( + packageManagerExecutable === 'yarn-stable' + ? 'yarn' + : packageManagerExecutable, + ['cache', 'clean'], + execaOptions + ); + } else if (packageManagerExecutable === 'pnpm') { + await execa(packageManagerExecutable, ['--version']); + await execa(packageManagerExecutable, [ + 'config', + 'set', + 'registry', + 'http://localhost:4873', + ]); + await execa(packageManagerExecutable, ['config', 'get', 'registry']); + + await execa(packageManagerExecutable, ['store', 'clear']); + } +}; + +void describe('create-amplify script', () => { + const { PACKAGE_MANAGER_EXECUTABLE = 'npm' } = process.env; + + before(async () => { + // start a local npm proxy and publish the current codebase to the proxy + await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); + await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); + + if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { + await execa('npm', ['install', '-g', 'yarn'], { stdio: 'inherit' }); + } else if (PACKAGE_MANAGER_EXECUTABLE === 'pnpm') { + await execa('npm', ['install', '-g', PACKAGE_MANAGER_EXECUTABLE], { + stdio: 'inherit', + }); + } }); after(async () => { @@ -28,8 +96,30 @@ void describe('create-amplify script', () => { }); let tempDir: string; + beforeEach(async () => { - tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); + const tempDirPath = await fs.mkdtemp( + path.join(os.tmpdir(), 'test-create-amplify') + ); + tempDir = path.join(tempDirPath); + + const { stdout } = await execa( + PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, + ['--version'], + { + cwd: tempDir, + } + ); + + console.log(`Using ${PACKAGE_MANAGER_EXECUTABLE} version ${stdout}`); + + // nuke the npx cache to ensure we are installing packages from the npm proxy + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir + ); }); afterEach(async () => { @@ -55,10 +145,17 @@ void describe('create-amplify script', () => { ); } - await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, - stdio: 'inherit', - }); + await execa( + PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, + ['create', 'amplify', '--yes'], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + const packageJsonPath = path.resolve(tempDir, 'package.json'); const packageJsonObject = JSON.parse( await fs.readFile(packageJsonPath, 'utf-8') @@ -121,7 +218,11 @@ void describe('create-amplify script', () => { // assert that project compiles successfully await execa( - 'npx', + PACKAGE_MANAGER_EXECUTABLE === 'npm' + ? 'npx' + : PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, [ 'tsc', '--noEmit', @@ -140,9 +241,50 @@ void describe('create-amplify script', () => { } ); + if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { + await execa( + PACKAGE_MANAGER_EXECUTABLE === 'npm' + ? 'npx' + : PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, + ['add', 'aws-cdk', 'aws-cdk-lib', 'constructs'], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable') { + await execa( + 'yarn', + [ + 'add', + '-D', + 'tsx', + 'graphql', + 'pluralize', + 'zod', + '@aws-amplify/platform-core', + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + + await execa('node', ['--version'], { + cwd: tempDir, + }); + } + } + // assert that project synthesizes successfully await execa( - 'npx', + PACKAGE_MANAGER_EXECUTABLE === 'npm' + ? 'npx' + : PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, [ 'cdk', 'synth', @@ -153,7 +295,13 @@ void describe('create-amplify script', () => { '--context', `amplify-backend-type=sandbox`, '--app', - "'npx tsx amplify/backend.ts'", + `'${ + PACKAGE_MANAGER_EXECUTABLE === 'npm' + ? 'npx' + : PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE + } tsx amplify/backend.ts'`, '--quiet', ], { @@ -168,11 +316,17 @@ void describe('create-amplify script', () => { const amplifyDirPath = path.join(tempDir, 'amplify'); await fs.mkdir(amplifyDirPath, { recursive: true }); - const result = await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, - stdio: 'pipe', - reject: false, - }); + const result = await execa( + PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE, + ['create', 'amplify', '--yes'], + { + cwd: tempDir, + stdio: 'pipe', + reject: false, + } + ); assert.equal(result.exitCode, 1); assert.ok( result.stderr From cd46cf8f1841de6b628c7af985a41f850ae518e1 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:35:47 -0800 Subject: [PATCH 07/30] fix: e2e tests (#771) * chore: change branch to poc/pms-create-amplify * fix: gitIgnore test * fix: refactor e2e for pms * chore: update package.lock * chore: update package.lock * temp: refactor * temp: run 1 test * temp: fix npx * temp: install packages for yarn * temp: update initial_project_file_generator * temp: install ts for yarn * temp: ignore node_modules and yarn.lock * temp: create yarn.lock for yarn stable * temp: fix yarn-stable init * temp: fix --help * fix: assert for gitignore * chore: change yarn stable install * fix: not install yarn stable globally * add @yarnpkg/sdks base * yarn stable use node-modules * remove emoji * remove @yarnpkg/sdks * yarn stable use node 18.18 * yarn stable use node 20 * chore: re-enable all tests * Revert "chore: re-enable all tests" This reverts commit f7a167b769bc8804acc8329656fe3319556b05d8. * chore: uncomment test * chore: enable all initialStatues * test: change concurrencyLevel for yarn and yarn stable * add yarn-stable to test fails fast * chore: update changeset * chore: change workflow trigger * chore: yarn not install typescript in root folder * chore: update package.lock * Revert "chore: yarn not install typescript in root folder" This reverts commit 0d83dd0598ea03abfc9d9ab48c61b7bfc4d9c43c. * chore: remove comment * chore: fix typo * chore: rename yarn-classic and yarn modern --- .changeset/itchy-pigs-switch.md | 2 + .github/workflows/poc-e2e-flow-test.yml | 19 +- package-lock.json | 2130 +++++++++-------- .../src/initial_project_file_generator.ts | 37 +- .../src/npm_package_manager_controller.ts | 8 +- .../src/npm_project_initializer.ts | 7 +- .../src/test-e2e/create_amplify.test.ts | 489 ++-- 7 files changed, 1485 insertions(+), 1207 deletions(-) create mode 100644 .changeset/itchy-pigs-switch.md diff --git a/.changeset/itchy-pigs-switch.md b/.changeset/itchy-pigs-switch.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/itchy-pigs-switch.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.github/workflows/poc-e2e-flow-test.yml b/.github/workflows/poc-e2e-flow-test.yml index 63fd37e8ea8..41ee16f2f7f 100644 --- a/.github/workflows/poc-e2e-flow-test.yml +++ b/.github/workflows/poc-e2e-flow-test.yml @@ -5,7 +5,10 @@ name: 'poc-e2e-flow-test' on: # TODO: need to change the trigger push: branches: - - poc/e2e-create-amplify + - poc/package-manager-support + pull_request: + branches: + - poc/package-manager-support jobs: install: @@ -37,20 +40,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - pkg-manager: [npm, yarn, pnpm] + pkg-manager: [npm, yarn-classic, yarn-modern, pnpm] node-version: [20] - include: - - os: ubuntu-latest - pkg-manager: yarn-stable - node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released - - os: macos-latest - pkg-manager: yarn-stable - node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released - - os: windows-latest - pkg-manager: yarn-stable - node-version: 19 # TODO: use Node 20 once https://github.com/yarnpkg/berry/pull/5961 is released env: - ACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). + PACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). runs-on: ${{ matrix.os }} timeout-minutes: 60 needs: diff --git a/package-lock.json b/package-lock.json index 03f2dd01131..d60bdadce9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -509,9 +509,9 @@ } }, "node_modules/@aws-amplify/data-construct": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@aws-amplify/data-construct/-/data-construct-1.4.2.tgz", - "integrity": "sha512-Pk99yI+JAy8J+ukH8nFHR05vqqynxhePakOo8/hnrgDmN3kcNCKUCAba0M0csPzJRdI3gf5ulOuRxoOLs1VjeA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@aws-amplify/data-construct/-/data-construct-1.4.3.tgz", + "integrity": "sha512-1+v2MMTa7i+a2YMdxqEtHj+ISnexQcjPpK4MuksIt0AFemCSdf5Wqq1Im9BhMBlPqJqWRiiyTq4qyGyfG+3Hag==", "bundleDependencies": [ "@aws-amplify/backend-output-schemas", "@aws-amplify/backend-output-storage", @@ -554,21 +554,21 @@ "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.2", - "@aws-amplify/graphql-api-construct": "1.4.2", - "@aws-amplify/graphql-auth-transformer": "3.2.2", - "@aws-amplify/graphql-default-value-transformer": "2.1.11", - "@aws-amplify/graphql-function-transformer": "2.1.10", - "@aws-amplify/graphql-http-transformer": "2.1.10", - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-maps-to-transformer": "3.3.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-predictions-transformer": "2.1.10", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-searchable-transformer": "2.3.2", - "@aws-amplify/graphql-sql-transformer": "0.1.2", - "@aws-amplify/graphql-transformer": "1.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-api-construct": "1.4.3", + "@aws-amplify/graphql-auth-transformer": "3.2.3", + "@aws-amplify/graphql-default-value-transformer": "2.1.12", + "@aws-amplify/graphql-function-transformer": "2.1.11", + "@aws-amplify/graphql-http-transformer": "2.1.11", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-maps-to-transformer": "3.3.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-predictions-transformer": "2.1.11", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-searchable-transformer": "2.3.3", + "@aws-amplify/graphql-sql-transformer": "0.1.3", + "@aws-amplify/graphql-transformer": "1.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "@aws-amplify/platform-core": "^0.2.0", "@aws-amplify/plugin-types": "^0.4.1", "charenc": "^0.0.2", @@ -617,14 +617,14 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-auth-transformer": { - "version": "3.2.2", + "version": "3.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -637,12 +637,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-default-value-transformer": { - "version": "2.1.11", + "version": "2.1.12", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -650,12 +650,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-function-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -666,12 +666,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-http-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -682,13 +682,13 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-index-transformer": { - "version": "2.2.2", + "version": "2.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -699,12 +699,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-maps-to-transformer": { - "version": "3.3.2", + "version": "3.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" }, @@ -714,12 +714,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-model-transformer": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -730,12 +730,12 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-predictions-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -746,14 +746,14 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-relational-transformer": { - "version": "2.2.2", + "version": "2.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -765,13 +765,13 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-searchable-transformer": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -782,13 +782,13 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-sql-transformer": { - "version": "0.1.2", + "version": "0.1.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -799,23 +799,23 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-transformer": { - "version": "1.3.2", + "version": "1.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-auth-transformer": "3.2.2", - "@aws-amplify/graphql-default-value-transformer": "2.1.11", - "@aws-amplify/graphql-function-transformer": "2.1.10", - "@aws-amplify/graphql-http-transformer": "2.1.10", - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-maps-to-transformer": "3.3.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-predictions-transformer": "2.1.10", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-searchable-transformer": "2.3.2", - "@aws-amplify/graphql-sql-transformer": "0.1.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0" + "@aws-amplify/graphql-auth-transformer": "3.2.3", + "@aws-amplify/graphql-default-value-transformer": "2.1.12", + "@aws-amplify/graphql-function-transformer": "2.1.11", + "@aws-amplify/graphql-http-transformer": "2.1.11", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-maps-to-transformer": "3.3.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-predictions-transformer": "2.1.11", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-searchable-transformer": "2.3.3", + "@aws-amplify/graphql-sql-transformer": "0.1.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1" }, "peerDependencies": { "aws-cdk-lib": "^2.80.0", @@ -823,11 +823,11 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-transformer-core": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "fs-extra": "^8.1.0", "graphql": "^15.5.0", "graphql-transformer-common": "4.26.2", @@ -843,7 +843,7 @@ } }, "node_modules/@aws-amplify/data-construct/node_modules/@aws-amplify/graphql-transformer-interfaces": { - "version": "3.3.0", + "version": "3.3.1", "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -1085,9 +1085,9 @@ "link": true }, "node_modules/@aws-amplify/graphql-api-construct": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@aws-amplify/graphql-api-construct/-/graphql-api-construct-1.4.2.tgz", - "integrity": "sha512-MZglRlIk6ScZoD2FQDUcrfiXiJzCuTkTLW0n3kJdrEydERQvMcXePCbJWiDQN0/scbB0vU7foDRNZfbdTxv8GA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@aws-amplify/graphql-api-construct/-/graphql-api-construct-1.4.3.tgz", + "integrity": "sha512-pem9OcUnLc2bzaV8uiT+nOaLfBvKYVA6jZZwQ5pEmKqMfqA1gYKjjowfOXTWXXFLXUQ0fJXCfcOl1Qg+St15rQ==", "bundleDependencies": [ "@aws-amplify/backend-output-schemas", "@aws-amplify/backend-output-storage", @@ -1130,20 +1130,20 @@ "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.2", - "@aws-amplify/graphql-auth-transformer": "3.2.2", - "@aws-amplify/graphql-default-value-transformer": "2.1.11", - "@aws-amplify/graphql-function-transformer": "2.1.10", - "@aws-amplify/graphql-http-transformer": "2.1.10", - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-maps-to-transformer": "3.3.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-predictions-transformer": "2.1.10", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-searchable-transformer": "2.3.2", - "@aws-amplify/graphql-sql-transformer": "0.1.2", - "@aws-amplify/graphql-transformer": "1.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-auth-transformer": "3.2.3", + "@aws-amplify/graphql-default-value-transformer": "2.1.12", + "@aws-amplify/graphql-function-transformer": "2.1.11", + "@aws-amplify/graphql-http-transformer": "2.1.11", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-maps-to-transformer": "3.3.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-predictions-transformer": "2.1.11", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-searchable-transformer": "2.3.3", + "@aws-amplify/graphql-sql-transformer": "0.1.3", + "@aws-amplify/graphql-transformer": "1.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "@aws-amplify/platform-core": "^0.2.0", "@aws-amplify/plugin-types": "^0.4.1", "charenc": "^0.0.2", @@ -1192,14 +1192,14 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-auth-transformer": { - "version": "3.2.2", + "version": "3.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -1212,12 +1212,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-default-value-transformer": { - "version": "2.1.11", + "version": "2.1.12", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -1225,12 +1225,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-function-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1241,12 +1241,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-http-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1257,13 +1257,13 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-index-transformer": { - "version": "2.2.2", + "version": "2.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1274,12 +1274,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-maps-to-transformer": { - "version": "3.3.2", + "version": "3.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" }, @@ -1289,12 +1289,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-model-transformer": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1305,12 +1305,12 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-predictions-transformer": { - "version": "2.1.10", + "version": "2.1.11", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1321,14 +1321,14 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-relational-transformer": { - "version": "2.2.2", + "version": "2.2.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2", @@ -1340,13 +1340,13 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-searchable-transformer": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1357,13 +1357,13 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-sql-transformer": { - "version": "0.1.2", + "version": "0.1.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "graphql": "^15.5.0", "graphql-mapping-template": "4.20.12", "graphql-transformer-common": "4.26.2" @@ -1374,23 +1374,23 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-transformer": { - "version": "1.3.2", + "version": "1.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-auth-transformer": "3.2.2", - "@aws-amplify/graphql-default-value-transformer": "2.1.11", - "@aws-amplify/graphql-function-transformer": "2.1.10", - "@aws-amplify/graphql-http-transformer": "2.1.10", - "@aws-amplify/graphql-index-transformer": "2.2.2", - "@aws-amplify/graphql-maps-to-transformer": "3.3.2", - "@aws-amplify/graphql-model-transformer": "2.3.2", - "@aws-amplify/graphql-predictions-transformer": "2.1.10", - "@aws-amplify/graphql-relational-transformer": "2.2.2", - "@aws-amplify/graphql-searchable-transformer": "2.3.2", - "@aws-amplify/graphql-sql-transformer": "0.1.2", - "@aws-amplify/graphql-transformer-core": "2.3.2", - "@aws-amplify/graphql-transformer-interfaces": "3.3.0" + "@aws-amplify/graphql-auth-transformer": "3.2.3", + "@aws-amplify/graphql-default-value-transformer": "2.1.12", + "@aws-amplify/graphql-function-transformer": "2.1.11", + "@aws-amplify/graphql-http-transformer": "2.1.11", + "@aws-amplify/graphql-index-transformer": "2.2.3", + "@aws-amplify/graphql-maps-to-transformer": "3.3.3", + "@aws-amplify/graphql-model-transformer": "2.3.3", + "@aws-amplify/graphql-predictions-transformer": "2.1.11", + "@aws-amplify/graphql-relational-transformer": "2.2.3", + "@aws-amplify/graphql-searchable-transformer": "2.3.3", + "@aws-amplify/graphql-sql-transformer": "0.1.3", + "@aws-amplify/graphql-transformer-core": "2.3.3", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1" }, "peerDependencies": { "aws-cdk-lib": "^2.80.0", @@ -1398,11 +1398,11 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-transformer-core": { - "version": "2.3.2", + "version": "2.3.3", "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@aws-amplify/graphql-transformer-interfaces": "3.3.0", + "@aws-amplify/graphql-transformer-interfaces": "3.3.1", "fs-extra": "^8.1.0", "graphql": "^15.5.0", "graphql-transformer-common": "4.26.2", @@ -1418,7 +1418,7 @@ } }, "node_modules/@aws-amplify/graphql-api-construct/node_modules/@aws-amplify/graphql-transformer-interfaces": { - "version": "3.3.0", + "version": "3.3.1", "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -2604,25 +2604,25 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-amplify": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-amplify/-/client-amplify-3.454.0.tgz", - "integrity": "sha512-VHxtZEh7/q5rrUssfkuv20fQoB4WDlRB5Tz4VsiY1qQiIYWfvYUFs8wV0VNiggIKGfXCYQPs6AmqUZftMNx6Gw==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-amplify/-/client-amplify-3.461.0.tgz", + "integrity": "sha512-KR2UpMUkiMzStyNhRsXnl5oOjAKcKimxmOJF3FJt+j3nVJKRV0j3BRqTyjnLcrekgu2QOZcQBRIQsoKslXgJWg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -2653,25 +2653,25 @@ } }, "node_modules/@aws-sdk/client-amplifyuibuilder": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-amplifyuibuilder/-/client-amplifyuibuilder-3.454.0.tgz", - "integrity": "sha512-eIaLb46vA7/8lwUHOzba8TFT7PtgSooq4Yj7VPzZ+wGSFoDwPaP8H0viONKIsQnsGc1k0dV6jkA4hRmqgBIsRg==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-amplifyuibuilder/-/client-amplifyuibuilder-3.461.0.tgz", + "integrity": "sha512-5PejKafdSKAmfq1FCHoAN5qRwMo7gy/O2Fo/pGBdgUby1OycybvsZb5qBLoiio7nk3hctwsZIhS8g2hUznmJpQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -2702,26 +2702,34 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-amplifyuibuilder/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@aws-sdk/client-appsync": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-appsync/-/client-appsync-3.454.0.tgz", - "integrity": "sha512-M8BpD2oXg+/V/nsrHx9VMviOuIZfHzST8Nx+ilClIqNGTNx5IDUmacbnKzUqogeQn/utjAwePb87k5whzkDR5A==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-appsync/-/client-appsync-3.461.0.tgz", + "integrity": "sha512-PSmLxON0/h3tEtDzKoQKPR4YOTOM1iwaDv3g9mZiDlasN/MVckrccTqAY2m2mCTcGoiBIAieuU6m0reI5C6EvA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -2753,25 +2761,25 @@ } }, "node_modules/@aws-sdk/client-cloudformation": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.454.0.tgz", - "integrity": "sha512-CKOE5u2gLt/BjHYX6a0uKGsWPBic9uOzlTwqnpqXEmVSb25xv5ULHOUmYfmSyw2TWXwxEe4a6ZwBL0MYJGrEUw==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.461.0.tgz", + "integrity": "sha512-A2u9B9IxSfx+NpWMRA/3rRTcddm3pj0set87pMmOgpmaQRxo9s7DHc6/0MANkd/y65ckEtP6wdPabt53yOEl5w==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -2804,26 +2812,34 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-cloudformation/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.454.0.tgz", - "integrity": "sha512-6Z3xYsgONJsZrn6P5XvKAgWxmUittGmp5jdX64LSz5OoPgkn0uGd01c2EACSKVivHUBc190gPg8Hg2BBmWjsMA==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.461.0.tgz", + "integrity": "sha512-rttO5tsvNqZghQwUgPk67LSo+0Yy4ItmsI3sgl81WDUP2A9Q4rwB8L99gLWroUz1uJtBujQ/HoYu6GN4kRa3MQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -2854,26 +2870,26 @@ } }, "node_modules/@aws-sdk/client-cognito-identity-provider": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.454.0.tgz", - "integrity": "sha512-puWrIjMboMAuJ/0poB1TNKZyr9Lpv1jHcSFrUIRezDPxs+lLi/Mvkcb7GVt5WHaC4+PHsk7UglbhNQIm3fRo4A==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.461.0.tgz", + "integrity": "sha512-sRXdjVLj72oOsRT75wfm5CWnPxdS7bu69X/2Dh+dhKnDz0IvQeRtpMR3dvMGJ8rqG6cWncAgcah6fegJtdF3ag==", "dev": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -3367,33 +3383,33 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.454.0.tgz", - "integrity": "sha512-vBx4iB1c4mEz+twMnl6angC1/IpnmXaT8L6Kl9uNiurFsb6N4tCyrJ24kECdsOSTM7ePXvE1fKst8zAh6MW5ZA==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.461.0.tgz", + "integrity": "sha512-pvEWMb2djn3bjD9lelYQhyG8KKKrUMm5MlSaSPwqVTL97iKm/Zbk+Ord6n8qMyPl5JHGmNdfg0tZFxC1qXeHTw==", "dependencies": { "@aws-crypto/sha1-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-bucket-endpoint": "3.451.0", - "@aws-sdk/middleware-expect-continue": "3.451.0", - "@aws-sdk/middleware-flexible-checksums": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-location-constraint": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-sdk-s3": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-ssec": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-bucket-endpoint": "3.460.0", + "@aws-sdk/middleware-expect-continue": "3.460.0", + "@aws-sdk/middleware-flexible-checksums": "3.461.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-location-constraint": "3.461.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-sdk-s3": "3.461.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-ssec": "3.460.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/signature-v4-multi-region": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/signature-v4-multi-region": "3.461.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@aws-sdk/xml-builder": "3.310.0", "@smithy/config-resolver": "^2.0.18", "@smithy/eventstream-serde-browser": "^2.0.13", @@ -3434,25 +3450,25 @@ } }, "node_modules/@aws-sdk/client-ssm": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.454.0.tgz", - "integrity": "sha512-Vrf93hOzB4FAUpkGHvKywZ0yOVbghS0KbCsnlN1Mka780zmyc185YXGYSLv6B+yrI2tMj0cBvEad3M0qk69qVw==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.461.0.tgz", + "integrity": "sha512-9ChDfqWWqYMtOHz0MCAjBLgEEpdwSgAUaW6qw0JHqOUkheUvqGCYXbrQRg6B/djol9ySjXrOXb7k50pbc9z56w==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.454.0", + "@aws-sdk/client-sts": "3.461.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -3484,23 +3500,31 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-ssm/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@aws-sdk/client-sso": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.451.0.tgz", - "integrity": "sha512-KkYSke3Pdv3MfVH/5fT528+MKjMyPKlcLcd4zQb0x6/7Bl7EHrPh1JZYjzPLHelb+UY5X0qN8+cb8iSu1eiwIQ==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.460.0.tgz", + "integrity": "sha512-p5D9C8LKJs5yoBn5cCs2Wqzrp5YP5BYcP774bhGMFEu/LCIUyWzudwN3+/AObSiq8R8SSvBY2zQD4h+k3NjgTQ==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -3531,25 +3555,25 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.454.0.tgz", - "integrity": "sha512-0fDvr8WeB6IYO8BUCzcivWmahgGl/zDbaYfakzGnt4mrl5ztYaXE875WI6b7+oFcKMRvN+KLvwu5TtyFuNY+GQ==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.461.0.tgz", + "integrity": "sha512-1u+t31m23vuc9zkiUk51L4QbwuRQEuBeMArHK/thmq4V+A0VmjoAr/x2D0eQ0deOuBqG5YC62oaqUfIhj03SIw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", "@aws-sdk/core": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-sdk-sts": "3.451.0", - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-sdk-sts": "3.461.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -3593,12 +3617,12 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.454.0.tgz", - "integrity": "sha512-sRxDhZKgFasAVajNvpqJMEOCvtCUfofVcUO5vIp8jgPHNw5yrN5REZStjVjgYO5riFKXFI8qqHHtzttx+HhsZg==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.461.0.tgz", + "integrity": "sha512-D3bayvoEMxxheSpLug0VpAmGiVsDdYU4GsT8ls6389NjgQsAhPrmHd5wAxf1AtZYxghO9cT2rsZK60u0VQ1Q1w==", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.454.0", - "@aws-sdk/types": "3.451.0", + "@aws-sdk/client-cognito-identity": "3.461.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3608,11 +3632,11 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.451.0.tgz", - "integrity": "sha512-9dAav7DcRgaF7xCJEQR5ER9ErXxnu/tdnVJ+UPmb1NPeIZdESv1A3lxFDEq1Fs8c4/lzAj9BpshGyJVIZwZDKg==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.460.0.tgz", + "integrity": "sha512-WWdaRJFuYRc2Ue9NKDy2NIf8pQRNx/QRVmrsk6EkIID8uWlQIOePk3SWTVV0TZIyPrbfSEaSnJRZoShphJ6PAg==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3622,11 +3646,11 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.451.0.tgz", - "integrity": "sha512-q82kEzymqimkJ2dHmuN2RGpi9HTFSxwwoXALnzPRaRcvR/v+YY8FMgSTfwXzPkHUDf/q8J+aDz6lPcYlnsP3sQ==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.460.0.tgz", + "integrity": "sha512-tLnuLDsGcBRemj8jxt1MkerjwsQlYdwnlfQXvrYOO8qMrbFP2sEjAx165GeCbsjmY/y0w1UFQEV+xRpFg5dxUw==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/node-http-handler": "^2.1.9", "@smithy/property-provider": "^2.0.0", @@ -3641,15 +3665,15 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.451.0.tgz", - "integrity": "sha512-TySt64Ci5/ZbqFw1F9Z0FIGvYx5JSC9e6gqDnizIYd8eMnn8wFRUscRrD7pIHKfrhvVKN5h0GdYovmMO/FMCBw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.451.0", - "@aws-sdk/credential-provider-process": "3.451.0", - "@aws-sdk/credential-provider-sso": "3.451.0", - "@aws-sdk/credential-provider-web-identity": "3.451.0", - "@aws-sdk/types": "3.451.0", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.460.0.tgz", + "integrity": "sha512-1IEUmyaWzt2M3mONO8QyZtPy0f9ccaEjCo48ZQLgptWxUI+Ohga9gPK0mqu1kTJOjv4JJGACYHzLwEnnpltGlA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.460.0", + "@aws-sdk/credential-provider-process": "3.460.0", + "@aws-sdk/credential-provider-sso": "3.460.0", + "@aws-sdk/credential-provider-web-identity": "3.460.0", + "@aws-sdk/types": "3.460.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", @@ -3661,16 +3685,16 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.451.0.tgz", - "integrity": "sha512-AEwM1WPyxUdKrKyUsKyFqqRFGU70e4qlDyrtBxJnSU9NRLZI8tfEZ67bN7fHSxBUBODgDXpMSlSvJiBLh5/3pw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.451.0", - "@aws-sdk/credential-provider-ini": "3.451.0", - "@aws-sdk/credential-provider-process": "3.451.0", - "@aws-sdk/credential-provider-sso": "3.451.0", - "@aws-sdk/credential-provider-web-identity": "3.451.0", - "@aws-sdk/types": "3.451.0", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.460.0.tgz", + "integrity": "sha512-PbPo92WIgNlF6V4eWKehYGYjTqf0gU9vr09LeQUc3bTm1DJhJw1j+HU/3PfQ8LwTkBQePO7MbJ5A2n6ckMwfMg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.460.0", + "@aws-sdk/credential-provider-ini": "3.460.0", + "@aws-sdk/credential-provider-process": "3.460.0", + "@aws-sdk/credential-provider-sso": "3.460.0", + "@aws-sdk/credential-provider-web-identity": "3.460.0", + "@aws-sdk/types": "3.460.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", @@ -3682,11 +3706,11 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.451.0.tgz", - "integrity": "sha512-HQywSdKeD5PErcLLnZfSyCJO+6T+ZyzF+Lm/QgscSC+CbSUSIPi//s15qhBRVely/3KBV6AywxwNH+5eYgt4lQ==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.460.0.tgz", + "integrity": "sha512-ng+0FMc4EaxLAwdttCwf2nzNf4AgcqAHZ8pKXUf8qF/KVkoyTt3UZKW7P2FJI01zxwP+V4yAwVt95PBUKGn4YQ==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/types": "^2.5.0", @@ -3697,13 +3721,13 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.451.0.tgz", - "integrity": "sha512-Usm/N51+unOt8ID4HnQzxIjUJDrkAQ1vyTOC0gSEEJ7h64NSSPGD5yhN7il5WcErtRd3EEtT1a8/GTC5TdBctg==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.460.0.tgz", + "integrity": "sha512-KnrQieOw17+aHEzE3SwfxjeSQ5ZTe2HeAzxkaZF++GxhNul/PkVnLzjGpIuB9bn71T9a2oNfG3peDUA+m2l2kw==", "dependencies": { - "@aws-sdk/client-sso": "3.451.0", - "@aws-sdk/token-providers": "3.451.0", - "@aws-sdk/types": "3.451.0", + "@aws-sdk/client-sso": "3.460.0", + "@aws-sdk/token-providers": "3.460.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/types": "^2.5.0", @@ -3714,11 +3738,11 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.451.0.tgz", - "integrity": "sha512-Xtg3Qw65EfDjWNG7o2xD6sEmumPfsy3WDGjk2phEzVg8s7hcZGxf5wYwe6UY7RJvlEKrU0rFA+AMn6Hfj5oOzg==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.460.0.tgz", + "integrity": "sha512-7OeaZgC3HmJZGE0I0ZiKInUMF2LyA0IZiW85AYFnAZzAIfv1cXk/1UnDAoFIQhOZfnUBXivStagz892s480ryw==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3728,22 +3752,22 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.454.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.454.0.tgz", - "integrity": "sha512-y+ieaocH6T5pjGx7l2NUTb2n29URUYO3uYSvvwoWKx/KK17QJEVKMbARHBHyvDIbybeHidJTO58Jz5AY7rcTQA==", - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.454.0", - "@aws-sdk/client-sso": "3.451.0", - "@aws-sdk/client-sts": "3.454.0", - "@aws-sdk/credential-provider-cognito-identity": "3.454.0", - "@aws-sdk/credential-provider-env": "3.451.0", - "@aws-sdk/credential-provider-http": "3.451.0", - "@aws-sdk/credential-provider-ini": "3.451.0", - "@aws-sdk/credential-provider-node": "3.451.0", - "@aws-sdk/credential-provider-process": "3.451.0", - "@aws-sdk/credential-provider-sso": "3.451.0", - "@aws-sdk/credential-provider-web-identity": "3.451.0", - "@aws-sdk/types": "3.451.0", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.461.0.tgz", + "integrity": "sha512-sJjGjJxs0KajPK+WbdIRSuidWqm1xobX/Uv0x7TTQCCj1Fsuyq03pNP1aLRbJnLazKx+qyJef7rEFwQeFEAiNA==", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.461.0", + "@aws-sdk/client-sso": "3.460.0", + "@aws-sdk/client-sts": "3.461.0", + "@aws-sdk/credential-provider-cognito-identity": "3.461.0", + "@aws-sdk/credential-provider-env": "3.460.0", + "@aws-sdk/credential-provider-http": "3.460.0", + "@aws-sdk/credential-provider-ini": "3.460.0", + "@aws-sdk/credential-provider-node": "3.460.0", + "@aws-sdk/credential-provider-process": "3.460.0", + "@aws-sdk/credential-provider-sso": "3.460.0", + "@aws-sdk/credential-provider-web-identity": "3.460.0", + "@aws-sdk/types": "3.460.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", "@smithy/types": "^2.5.0", @@ -3754,11 +3778,11 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.451.0.tgz", - "integrity": "sha512-KWyZ1JGnYz2QbHuJtYTP1BVnMOfVopR8rP8dTinVb/JR5HfAYz4imICJlJUbOYRjN7wpA3PrRI8dNRjrSBjWJg==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.460.0.tgz", + "integrity": "sha512-AmrCDT/r+m7q3OogZ3UeWpVdllMeR4Wdo+3YEfefPfcZc6SilnP2uCBUHletxbw3tXhNt56bUMUzQ+SUhyuUmA==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@aws-sdk/util-arn-parser": "3.310.0", "@smithy/node-config-provider": "^2.1.5", "@smithy/protocol-http": "^3.0.9", @@ -3771,11 +3795,11 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.451.0.tgz", - "integrity": "sha512-vwG8o2Uk6biLDlOZnqXemsO4dS2HvrprUdxyouwu6hlzLFskg8nL122butn19JqXJKgcVLuSSLzT+xwqBWy2Rg==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.460.0.tgz", + "integrity": "sha512-8VxMFTR+IszcMZLUZvxVCBOO1CUBmIWmDIQKd7w/U9xyMEXmBA0cx6ZEfMOIZF9NNh9OGCzTvwK+++8OTGBwAw==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/protocol-http": "^3.0.9", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3785,13 +3809,13 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.451.0.tgz", - "integrity": "sha512-eOkpcC2zgAvqs1w7Yp5nsk9LBIj6qLU5kaZuZEBOiFbNKIrTnPo6dQuhgvDcKHD6Y5W/cUjSBiFMs/ROb5aoug==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.461.0.tgz", + "integrity": "sha512-MNY7xMl2Qzoinj6Pos23TgD+WQtC9/G/VkNW/v8Ky5faRAt7bbS+ZEkkK3KcCrjnb8x4Bl/FzYNTCZRzRoQOtA==", "dependencies": { "@aws-crypto/crc32": "3.0.0", "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/is-array-buffer": "^2.0.0", "@smithy/protocol-http": "^3.0.9", "@smithy/types": "^2.5.0", @@ -3803,11 +3827,11 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.451.0.tgz", - "integrity": "sha512-j8a5jAfhWmsK99i2k8oR8zzQgXrsJtgrLxc3js6U+525mcZytoiDndkWTmD5fjJ1byU1U2E5TaPq+QJeDip05Q==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.460.0.tgz", + "integrity": "sha512-qBeDyuJkEuHe87Xk6unvFO9Zg5j6zM8bQOOZITocTLfu9JN0u5V4GQ/yopvpv+nQHmC/MGr0G7p+kIXMrg/Q2A==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/protocol-http": "^3.0.9", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3817,11 +3841,11 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.451.0.tgz", - "integrity": "sha512-R4U2G7mybP0BMiQBJWTcB47g49F4PSXTiCsvMDp5WOEhpWvGQuO1ZIhTxCl5s5lgTSne063Os8W6KSdK2yG2TQ==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.461.0.tgz", + "integrity": "sha512-dibimciNOV2kuhBBmHbS+29X559xNw4BdZviGzjGAQPkqPx+7Adgvp5BHqSDgh7FIJpgN2+QGbrubIQ+V1Bn4A==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" }, @@ -3830,11 +3854,11 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.451.0.tgz", - "integrity": "sha512-0kHrYEyVeB2QBfP6TfbI240aRtatLZtcErJbhpiNUb+CQPgEL3crIjgVE8yYiJumZ7f0jyjo8HLPkwD1/2APaw==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.460.0.tgz", + "integrity": "sha512-w2AJ6HOJ+Ggx9+VDKuWBHk5S0ZxYEo2EY2IFh0qtCQ1RDix/ur1QEzOOL5vNjHlZKPv/dseIwhgsTCac8UHXbQ==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" }, @@ -3843,11 +3867,11 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.451.0.tgz", - "integrity": "sha512-J6jL6gJ7orjHGM70KDRcCP7so/J2SnkN4vZ9YRLTeeZY6zvBuHDjX8GCIgSqPn/nXFXckZO8XSnA7u6+3TAT0w==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.460.0.tgz", + "integrity": "sha512-wmzm1/2NzpcCVCAsGqqiTBK+xNyLmQwTOq63rcW6eeq6gYOO0cyTZROOkVRrrsKWPBigrSFFHvDrEvonOMtKAg==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/protocol-http": "^3.0.9", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3857,15 +3881,18 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.451.0.tgz", - "integrity": "sha512-XF4Cw8HrYUwGLKOqKtWs6ss1WXoxvQUcgGLACGSqn9a0p51446NiS5671x7qJUsfBuygdKlIKcOc8pPr9a+5Ow==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.461.0.tgz", + "integrity": "sha512-sOFUBWROq0xQxNoXp+3eepXrUAuMc/JPH+sI/r5QOznk7JVemYoBj99lknbTzJ4ssSK0yVrSUxxwGiGvDQb0Gg==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@aws-sdk/util-arn-parser": "3.310.0", + "@smithy/node-config-provider": "^2.1.5", "@smithy/protocol-http": "^3.0.9", + "@smithy/signature-v4": "^2.0.0", "@smithy/smithy-client": "^2.1.15", "@smithy/types": "^2.5.0", + "@smithy/util-config-provider": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -3873,12 +3900,12 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.451.0.tgz", - "integrity": "sha512-UJ6UfVUEgp0KIztxpAeelPXI5MLj9wUtUCqYeIMP7C1ZhoEMNm3G39VLkGN43dNhBf1LqjsV9jkKMZbVfYXuwg==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.461.0.tgz", + "integrity": "sha512-sgNxkwKdJ/NZm7SJZBnbYPkbspmzn3lDyRSJH7PTCvyzDBzY2PB6yS/dfnGkitR+PYwromuOYMha37W4su2SOw==", "dependencies": { - "@aws-sdk/middleware-signing": "3.451.0", - "@aws-sdk/types": "3.451.0", + "@aws-sdk/middleware-signing": "3.461.0", + "@aws-sdk/types": "3.460.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" }, @@ -3887,11 +3914,11 @@ } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.451.0.tgz", - "integrity": "sha512-s5ZlcIoLNg1Huj4Qp06iKniE8nJt/Pj1B/fjhWc6cCPCM7XJYUCejCnRh6C5ZJoBEYodjuwZBejPc1Wh3j+znA==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.461.0.tgz", + "integrity": "sha512-aM/7VupHlsgeRG1UZSAQMWJX+2Jam4GG8ZGVAbLfBr9yh9cBwnUUndpUpYI9rU7atA8n+vISr162EbR7WTiFhQ==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/property-provider": "^2.0.0", "@smithy/protocol-http": "^3.0.9", "@smithy/signature-v4": "^2.0.0", @@ -3904,11 +3931,11 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.451.0.tgz", - "integrity": "sha512-hDkeBUiRsvuDbvsPha0/uJHE680WDzjAOoE6ZnLBoWsw7ry+Bw1ULMj0sCmpBVrQ7Gpivi/6zbezhClVmt3ITw==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.460.0.tgz", + "integrity": "sha512-1PSCmkq9BRX8isxyDyf785xvjldtwhdUzI+37oZ1qfDXGmRyB+KjtRBNnz5Fz+VSiOfVzfhp3sjrc4fs4BfJ0w==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" }, @@ -3917,12 +3944,12 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.451.0.tgz", - "integrity": "sha512-8NM/0JiKLNvT9wtAQVl1DFW0cEO7OvZyLSUBLNLTHqyvOZxKaZ8YFk7d8PL6l76LeUKRxq4NMxfZQlUIRe0eSA==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.460.0.tgz", + "integrity": "sha512-0gBSOCr+RtwRUCSRLn9H3RVnj9ercvk/QKTHIr33CgfEdyZtIGpHWUSs6uqiQydPTRzjCm5SfUa6ESGhRVMM6A==", "dependencies": { - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", "@smithy/protocol-http": "^3.0.9", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -3947,11 +3974,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.451.0.tgz", - "integrity": "sha512-qQKY7/txeNUTLyRL3WxUWEwaZ5sf76EIZgu9kLaR96cAYSxwQi/qQB3ijbfD6u7sJIA8aROMxeYK0VmRsQg0CA==", + "version": "3.461.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.461.0.tgz", + "integrity": "sha512-9tsdJ5KMPZzJN1x28AZKoS9J3xfwftFwutqcU1qsXXeouck0CztLfX+wr3etO4acPQO2zU305fnR2ulSsnns4g==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/middleware-sdk-s3": "3.461.0", + "@aws-sdk/types": "3.460.0", "@smithy/protocol-http": "^3.0.9", "@smithy/signature-v4": "^2.0.0", "@smithy/types": "^2.5.0", @@ -3962,21 +3990,21 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.451.0.tgz", - "integrity": "sha512-ij1L5iUbn6CwxVOT1PG4NFjsrsKN9c4N1YEM0lkl6DwmaNOscjLKGSNyj9M118vSWsOs1ZDbTwtj++h0O/BWrQ==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.460.0.tgz", + "integrity": "sha512-EvSIPMI1gXk3gEkdtbZCW+p3Bjmt2gOR1m7ibQD7qLj4l0dKXhp4URgTqB1ExH3S4qUq0M/XSGKbGLZpvunHNg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.451.0", - "@aws-sdk/middleware-logger": "3.451.0", - "@aws-sdk/middleware-recursion-detection": "3.451.0", - "@aws-sdk/middleware-user-agent": "3.451.0", + "@aws-sdk/middleware-host-header": "3.460.0", + "@aws-sdk/middleware-logger": "3.460.0", + "@aws-sdk/middleware-recursion-detection": "3.460.0", + "@aws-sdk/middleware-user-agent": "3.460.0", "@aws-sdk/region-config-resolver": "3.451.0", - "@aws-sdk/types": "3.451.0", - "@aws-sdk/util-endpoints": "3.451.0", - "@aws-sdk/util-user-agent-browser": "3.451.0", - "@aws-sdk/util-user-agent-node": "3.451.0", + "@aws-sdk/types": "3.460.0", + "@aws-sdk/util-endpoints": "3.460.0", + "@aws-sdk/util-user-agent-browser": "3.460.0", + "@aws-sdk/util-user-agent-node": "3.460.0", "@smithy/config-resolver": "^2.0.18", "@smithy/fetch-http-handler": "^2.2.6", "@smithy/hash-node": "^2.0.15", @@ -4009,9 +4037,9 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.451.0.tgz", - "integrity": "sha512-rhK+qeYwCIs+laJfWCcrYEjay2FR/9VABZJ2NRM89jV/fKqGVQR52E5DQqrI+oEIL5JHMhhnr4N4fyECMS35lw==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.460.0.tgz", + "integrity": "sha512-MyZSWS/FV8Bnux5eD9en7KLgVxevlVrGNEP3X2D7fpnUlLhl0a7k8+OpSI2ozEQB8hIU2DLc/XXTKRerHSefxQ==", "dependencies": { "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -4032,11 +4060,11 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.451.0.tgz", - "integrity": "sha512-giqLGBTnRIcKkDqwU7+GQhKbtJ5Ku35cjGQIfMyOga6pwTBUbaK0xW1Sdd8sBQ1GhApscnChzI9o/R9x0368vw==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.460.0.tgz", + "integrity": "sha512-myH6kM5WP4IWULHDHMYf2Q+BCYVGlzqJgiBmO10kQEtJSeAGZZ49eoFFYgKW8ZAYB5VnJ+XhXVB1TRA+vR4l5A==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/util-endpoints": "^1.0.4", "tslib": "^2.5.0" }, @@ -4070,22 +4098,22 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.451.0.tgz", - "integrity": "sha512-Ws5mG3J0TQifH7OTcMrCTexo7HeSAc3cBgjfhS/ofzPUzVCtsyg0G7I6T7wl7vJJETix2Kst2cpOsxygPgPD9w==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.460.0.tgz", + "integrity": "sha512-FRCzW+TyjKnvxsargPVrjayBfp/rvObYHZyZ2OSqrVw8lkkPCb4e/WZOeIiXZuhdhhoah7wMuo6zGwtFF3bYKg==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/types": "^2.5.0", "bowser": "^2.11.0", "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.451.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.451.0.tgz", - "integrity": "sha512-TBzm6P+ql4mkGFAjPlO1CI+w3yUT+NulaiALjl/jNX/nnUp6HsJsVxJf4nVFQTG5KRV0iqMypcs7I3KIhH+LmA==", + "version": "3.460.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.460.0.tgz", + "integrity": "sha512-+kSoR9ABGpJ5Xc7v0VwpgTQbgyI4zuezC8K4pmKAGZsSsVWg4yxptoy2bDqoFL7qfRlWviMVTkQRMvR4D44WxA==", "dependencies": { - "@aws-sdk/types": "3.451.0", + "@aws-sdk/types": "3.460.0", "@smithy/node-config-provider": "^2.1.5", "@smithy/types": "^2.5.0", "tslib": "^2.5.0" @@ -4948,16 +4976,16 @@ "dev": true }, "node_modules/@changesets/apply-release-plan": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.1.4.tgz", - "integrity": "sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.0.tgz", + "integrity": "sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/config": "^2.3.1", - "@changesets/get-version-range-type": "^0.3.2", - "@changesets/git": "^2.0.0", - "@changesets/types": "^5.2.1", + "@changesets/config": "^3.0.0", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", @@ -5001,58 +5029,57 @@ } }, "node_modules/@changesets/assemble-release-plan": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.4.tgz", - "integrity": "sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.0.tgz", + "integrity": "sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/types": "^5.2.1", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.0.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "semver": "^7.5.3" } }, "node_modules/@changesets/changelog-git": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.14.tgz", - "integrity": "sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", + "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", "dev": true, "dependencies": { - "@changesets/types": "^5.2.1" + "@changesets/types": "^6.0.0" } }, "node_modules/@changesets/cli": { - "version": "2.26.2", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.26.2.tgz", - "integrity": "sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==", + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.1.tgz", + "integrity": "sha512-iJ91xlvRnnrJnELTp4eJJEOPjgpF3NOh4qeQehM6Ugiz9gJPRZ2t+TsXun6E3AMN4hScZKjqVXl0TX+C7AB3ZQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/apply-release-plan": "^6.1.4", - "@changesets/assemble-release-plan": "^5.2.4", - "@changesets/changelog-git": "^0.1.14", - "@changesets/config": "^2.3.1", - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/get-release-plan": "^3.0.17", - "@changesets/git": "^2.0.0", - "@changesets/logger": "^0.0.5", - "@changesets/pre": "^1.0.14", - "@changesets/read": "^0.5.9", - "@changesets/types": "^5.2.1", - "@changesets/write": "^0.2.3", + "@changesets/apply-release-plan": "^7.0.0", + "@changesets/assemble-release-plan": "^6.0.0", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.0", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.0.0", + "@changesets/get-release-plan": "^4.0.0", + "@changesets/git": "^3.0.0", + "@changesets/logger": "^0.1.0", + "@changesets/pre": "^2.0.0", + "@changesets/read": "^0.6.0", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.0", "@manypkg/get-packages": "^1.1.3", - "@types/is-ci": "^3.0.0", "@types/semver": "^7.5.0", "ansi-colors": "^4.1.3", "chalk": "^2.1.0", + "ci-info": "^3.7.0", "enquirer": "^2.3.0", "external-editor": "^3.1.0", "fs-extra": "^7.0.1", "human-id": "^1.0.2", - "is-ci": "^3.0.1", "meow": "^6.0.0", "outdent": "^0.5.0", "p-limit": "^2.2.0", @@ -5100,15 +5127,15 @@ } }, "node_modules/@changesets/config": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-2.3.1.tgz", - "integrity": "sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.0.tgz", + "integrity": "sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==", "dev": true, "dependencies": { - "@changesets/errors": "^0.1.4", - "@changesets/get-dependents-graph": "^1.3.6", - "@changesets/logger": "^0.0.5", - "@changesets/types": "^5.2.1", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.0.0", + "@changesets/logger": "^0.1.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1", "micromatch": "^4.0.2" @@ -5147,21 +5174,21 @@ } }, "node_modules/@changesets/errors": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.1.4.tgz", - "integrity": "sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", "dev": true, "dependencies": { "extendable-error": "^0.1.5" } }, "node_modules/@changesets/get-dependents-graph": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.6.tgz", - "integrity": "sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.0.0.tgz", + "integrity": "sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==", "dev": true, "dependencies": { - "@changesets/types": "^5.2.1", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "chalk": "^2.1.0", "fs-extra": "^7.0.1", @@ -5201,35 +5228,35 @@ } }, "node_modules/@changesets/get-release-plan": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.17.tgz", - "integrity": "sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.0.tgz", + "integrity": "sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/assemble-release-plan": "^5.2.4", - "@changesets/config": "^2.3.1", - "@changesets/pre": "^1.0.14", - "@changesets/read": "^0.5.9", - "@changesets/types": "^5.2.1", + "@changesets/assemble-release-plan": "^6.0.0", + "@changesets/config": "^3.0.0", + "@changesets/pre": "^2.0.0", + "@changesets/read": "^0.6.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3" } }, "node_modules/@changesets/get-version-range-type": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz", - "integrity": "sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", "dev": true }, "node_modules/@changesets/git": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-2.0.0.tgz", - "integrity": "sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.0.tgz", + "integrity": "sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/types": "^5.2.1", + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "is-subdir": "^1.1.1", "micromatch": "^4.0.2", @@ -5237,33 +5264,33 @@ } }, "node_modules/@changesets/logger": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.0.5.tgz", - "integrity": "sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.0.tgz", + "integrity": "sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==", "dev": true, "dependencies": { "chalk": "^2.1.0" } }, "node_modules/@changesets/parse": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.16.tgz", - "integrity": "sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", + "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", "dev": true, "dependencies": { - "@changesets/types": "^5.2.1", + "@changesets/types": "^6.0.0", "js-yaml": "^3.13.1" } }, "node_modules/@changesets/pre": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz", - "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.0.tgz", + "integrity": "sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.1.4", - "@changesets/types": "^5.2.1", + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1" } @@ -5301,16 +5328,16 @@ } }, "node_modules/@changesets/read": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz", - "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.0.tgz", + "integrity": "sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/git": "^2.0.0", - "@changesets/logger": "^0.0.5", - "@changesets/parse": "^0.3.16", - "@changesets/types": "^5.2.1", + "@changesets/git": "^3.0.0", + "@changesets/logger": "^0.1.0", + "@changesets/parse": "^0.4.0", + "@changesets/types": "^6.0.0", "chalk": "^2.1.0", "fs-extra": "^7.0.1", "p-filter": "^2.1.0" @@ -5349,19 +5376,19 @@ } }, "node_modules/@changesets/types": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz", - "integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", + "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", "dev": true }, "node_modules/@changesets/write": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.2.3.tgz", - "integrity": "sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.0.tgz", + "integrity": "sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==", "dev": true, "dependencies": { "@babel/runtime": "^7.20.1", - "@changesets/types": "^5.2.1", + "@changesets/types": "^6.0.0", "fs-extra": "^7.0.1", "human-id": "^1.0.2", "prettier": "^2.7.1" @@ -5887,9 +5914,9 @@ } }, "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/utils": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.8.tgz", - "integrity": "sha512-yjyA8ycSa1WRlJqyX/aLqXeE5DvF/H02+zXMUFnCzIDrj0UvLMUrxhmVFnMK0Q2n3bh4uuTeY3621m5za9ovXw==", + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.11.tgz", + "integrity": "sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -6162,9 +6189,9 @@ } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@graphql-tools/utils": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.8.tgz", - "integrity": "sha512-yjyA8ycSa1WRlJqyX/aLqXeE5DvF/H02+zXMUFnCzIDrj0UvLMUrxhmVFnMK0Q2n3bh4uuTeY3621m5za9ovXw==", + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.11.tgz", + "integrity": "sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -6179,11 +6206,11 @@ } }, "node_modules/@graphql-tools/merge": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.0.tgz", - "integrity": "sha512-J7/xqjkGTTwOJmaJQJ2C+VDBDOWJL3lKrHJN4yMaRLAJH3PosB7GiPRaSDZdErs0+F77sH2MKs2haMMkywzx7Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.1.tgz", + "integrity": "sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==", "dependencies": { - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.10", "tslib": "^2.4.0" }, "engines": { @@ -6194,9 +6221,9 @@ } }, "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.8.tgz", - "integrity": "sha512-yjyA8ycSa1WRlJqyX/aLqXeE5DvF/H02+zXMUFnCzIDrj0UvLMUrxhmVFnMK0Q2n3bh4uuTeY3621m5za9ovXw==", + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.11.tgz", + "integrity": "sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -6247,12 +6274,12 @@ } }, "node_modules/@graphql-tools/schema": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.0.tgz", - "integrity": "sha512-kf3qOXMFcMs2f/S8Y3A8fm/2w+GaHAkfr3Gnhh2LOug/JgpY/ywgFVxO3jOeSpSEdoYcDKLcXVjMigNbY4AdQg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.2.tgz", + "integrity": "sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==", "dependencies": { - "@graphql-tools/merge": "^9.0.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/merge": "^9.0.1", + "@graphql-tools/utils": "^10.0.10", "tslib": "^2.4.0", "value-or-promise": "^1.0.12" }, @@ -6264,9 +6291,9 @@ } }, "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.8.tgz", - "integrity": "sha512-yjyA8ycSa1WRlJqyX/aLqXeE5DvF/H02+zXMUFnCzIDrj0UvLMUrxhmVFnMK0Q2n3bh4uuTeY3621m5za9ovXw==", + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.0.11.tgz", + "integrity": "sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.0", @@ -6559,9 +6586,9 @@ } }, "node_modules/@inquirer/core/node_modules/@types/node": { - "version": "20.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.3.tgz", - "integrity": "sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==", + "version": "20.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", + "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -7856,6 +7883,36 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@pkgr/utils/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@pkgr/utils/node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@rushstack/node-core-library": { "version": "3.61.0", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", @@ -7968,16 +8025,16 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.12.0.tgz", - "integrity": "sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz", + "integrity": "sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/type-utils": "6.12.0", - "@typescript-eslint/utils": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/type-utils": "6.13.1", + "@typescript-eslint/utils": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -8003,15 +8060,15 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/parser": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.12.0.tgz", - "integrity": "sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.1.tgz", + "integrity": "sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4" }, "engines": { @@ -8031,13 +8088,13 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.12.0.tgz", - "integrity": "sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz", + "integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0" + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8048,13 +8105,13 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.12.0.tgz", - "integrity": "sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz", + "integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/utils": "6.12.0", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/utils": "6.13.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -8075,9 +8132,9 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.12.0.tgz", - "integrity": "sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz", + "integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8088,13 +8145,13 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.12.0.tgz", - "integrity": "sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz", + "integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8115,17 +8172,17 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.12.0.tgz", - "integrity": "sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz", + "integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", "semver": "^7.5.4" }, "engines": { @@ -8140,12 +8197,12 @@ } }, "node_modules/@shopify/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.12.0.tgz", - "integrity": "sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz", + "integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", + "@typescript-eslint/types": "6.13.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -8258,11 +8315,11 @@ "dev": true }, "node_modules/@smithy/abort-controller": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.13.tgz", - "integrity": "sha512-eeOPD+GF9BzF/Mjy3PICLePx4l0f3rG/nQegQHRLTloN5p1lSJJNZsyn+FzDnW8P2AduragZqJdtKNCxXozB1Q==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.14.tgz", + "integrity": "sha512-zXtteuYLWbSXnzI3O6xq3FYvigYZFW8mdytGibfarLL2lxHto9L3ILtGVnVGmFZa7SDh62l39EnU5hesLN87Fw==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8287,14 +8344,14 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.18.tgz", - "integrity": "sha512-761sJSgNbvsqcsKW6/WZbrZr4H+0Vp/QKKqwyrxCPwD8BsiPEXNHyYnqNgaeK9xRWYswjon0Uxbpe3DWQo0j/g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.19.tgz", + "integrity": "sha512-JsghnQ5zjWmjEVY8TFOulLdEOCj09SjRLugrHlkPZTIBBm7PQitCFVLThbsKPZQOP7N3ME1DU1nKUc1UaVnBog==", "dependencies": { - "@smithy/node-config-provider": "^2.1.5", - "@smithy/types": "^2.5.0", + "@smithy/node-config-provider": "^2.1.6", + "@smithy/types": "^2.6.0", "@smithy/util-config-provider": "^2.0.0", - "@smithy/util-middleware": "^2.0.6", + "@smithy/util-middleware": "^2.0.7", "tslib": "^2.5.0" }, "engines": { @@ -8302,14 +8359,14 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.1.1.tgz", - "integrity": "sha512-gw5G3FjWC6sNz8zpOJgPpH5HGKrpoVFQpToNAwLwJVyI/LJ2jDJRjSKEsM6XI25aRpYjMSE/Qptxx305gN1vHw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.1.2.tgz", + "integrity": "sha512-Y62jBWdoLPSYjr9fFvJf+KwTa1EunjVr6NryTEWCnwIY93OJxwV4t0qxjwdPl/XMsUkq79ppNJSEQN6Ohnhxjw==", "dependencies": { - "@smithy/node-config-provider": "^2.1.5", - "@smithy/property-provider": "^2.0.14", - "@smithy/types": "^2.5.0", - "@smithy/url-parser": "^2.0.13", + "@smithy/node-config-provider": "^2.1.6", + "@smithy/property-provider": "^2.0.15", + "@smithy/types": "^2.6.0", + "@smithy/url-parser": "^2.0.14", "tslib": "^2.5.0" }, "engines": { @@ -8317,23 +8374,23 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.13.tgz", - "integrity": "sha512-CExbelIYp+DxAHG8RIs0l9QL7ElqhG4ym9BNoSpkPa4ptBQfzJdep3LbOSVJIE2VUdBAeObdeL6EDB3Jo85n3g==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.14.tgz", + "integrity": "sha512-g/OU/MeWGfHDygoXgMWfG/Xb0QqDnAGcM9t2FRrVAhleXYRddGOEnfanR5cmHgB9ue52MJsyorqFjckzXsylaA==", "dependencies": { "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-hex-encoding": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.13.tgz", - "integrity": "sha512-OJ/2g/VxkzA+mYZxV102oX3CsiE+igTSmqq/ir3oEVG2kSIdRC00ryttj/lmL14W06ExNi0ysmfLxQkL8XrAZQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.14.tgz", + "integrity": "sha512-41wmYE9smDGJi1ZXp+LogH6BR7MkSsQD91wneIFISF/mupKULvoOJUkv/Nf0NMRxWlM3Bf1Vvi9FlR2oV4KU8Q==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/eventstream-serde-universal": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8341,11 +8398,11 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.13.tgz", - "integrity": "sha512-2BI1CbnYuEvAYoWSeWJtPNygbIKiWeSLxCmDLnyM6wQV32Of7VptiQlaFXPxXp4zqn/rs3ocZ/T29rxE4s4Gsg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.14.tgz", + "integrity": "sha512-43IyRIzQ82s+5X+t/3Ood00CcWtAXQdmUIUKMed2Qg9REPk8SVIHhpm3rwewLwg+3G2Nh8NOxXlEQu6DsPUcMw==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8353,12 +8410,12 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.13.tgz", - "integrity": "sha512-7NbFwPafb924elFxCBDvm48jy/DeSrpFbFQN0uN2ThuY5HrEeubikS0t7WMva4Z4EnRoivpbuT0scb9vUIJKoA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.14.tgz", + "integrity": "sha512-jVh9E2qAr6DxH5tWfCAl9HV6tI0pEQ3JVmu85JknDvYTC66djcjDdhctPV2EHuKWf2kjRiFJcMIn0eercW4THA==", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/eventstream-serde-universal": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8366,12 +8423,12 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.13.tgz", - "integrity": "sha512-j0yFd5UfftM+ia9dxLRbheJDCkCZBHpcEzCsPO8BxVOTbdcX/auVJCv6ov/yvpCKsf4Hv3mOqi0Is1YogM2g3Q==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.14.tgz", + "integrity": "sha512-Ie35+AISNn1NmEjn5b2SchIE49pvKp4Q74bE9ME5RULWI1MgXyGkQUajWd5E6OBSr/sqGcs+rD3IjPErXnCm9g==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/eventstream-codec": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8379,34 +8436,34 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.6.tgz", - "integrity": "sha512-PStY3XO1Ksjwn3wMKye5U6m6zxXpXrXZYqLy/IeCbh3nM9QB3Jgw/B0PUSLUWKdXg4U8qgEu300e3ZoBvZLsDg==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.7.tgz", + "integrity": "sha512-iSDBjxuH9TgrtMYAr7j5evjvkvgwLY3y+9D547uep+JNkZ1ZT+BaeU20j6I/bO/i26ilCWFImrlXTPsfQtZdIQ==", "dependencies": { - "@smithy/protocol-http": "^3.0.9", - "@smithy/querystring-builder": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/protocol-http": "^3.0.10", + "@smithy/querystring-builder": "^2.0.14", + "@smithy/types": "^2.6.0", "@smithy/util-base64": "^2.0.1", "tslib": "^2.5.0" } }, "node_modules/@smithy/hash-blob-browser": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.14.tgz", - "integrity": "sha512-yWdghyPJIEqLYsaE7YVgd3YhM7jN4Pv6eJQvTomnMsz5K2qRBlpjUx3T9fKlElp1qdeQ7DNc3sAat4i9CUBO7Q==", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.15.tgz", + "integrity": "sha512-HX/7GIyPUT/HDWVYe2HYQu0iRnSYpF4uZVNhAhZsObPRawk5Mv0PbyluBgIFI2DDCCKgL/tloCYYwycff1GtQg==", "dependencies": { "@smithy/chunked-blob-reader": "^2.0.0", "@smithy/chunked-blob-reader-native": "^2.0.1", - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/hash-node": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.15.tgz", - "integrity": "sha512-t/qjEJZu/G46A22PAk1k/IiJZT4ncRkG5GOCNWN9HPPy5rCcSZUbh7gwp7CGKgJJ7ATMMg+0Td7i9o1lQTwOfQ==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.16.tgz", + "integrity": "sha512-Wbi9A0PacMYUOwjAulQP90Wl3mQ6NDwnyrZQzFjDz+UzjXOSyQMgBrTkUBz+pVoYVlX3DUu24gWMZBcit+wOGg==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-utf8": "^2.0.2", "tslib": "^2.5.0" @@ -8416,11 +8473,11 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.15.tgz", - "integrity": "sha512-ZZ6kC/pHt5Dc2goXIIyC8uA7A4GUMSzdCynAabnZ3CSSaV6ctP8mlvVkqjPph0O3XzHlx/80gdLrNqi1GDPUsA==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.16.tgz", + "integrity": "sha512-4x24GFdeWos1Z49MC5sYdM1j+z32zcUr6oWM9Ggm3WudFAcRIcbG9uDQ1XgJ0Kl+ZTjpqLKniG0iuWvQb2Ud1A==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-utf8": "^2.0.2", "tslib": "^2.5.0" }, @@ -8429,11 +8486,11 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.13.tgz", - "integrity": "sha512-XsGYhVhvEikX1Yz0kyIoLssJf2Rs6E0U2w2YuKdT4jSra5A/g8V2oLROC1s56NldbgnpesTYB2z55KCHHbKyjw==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.14.tgz", + "integrity": "sha512-d8ohpwZo9RzTpGlAfsWtfm1SHBSU7+N4iuZ6MzR10xDTujJJWtmXYHK1uzcr7rggbpUTaWyHpPFgnf91q0EFqQ==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" } }, @@ -8449,22 +8506,22 @@ } }, "node_modules/@smithy/md5-js": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.15.tgz", - "integrity": "sha512-pAZaokib56XvhU0t/R9vAcr3L3bMhIakhF25X7EMSQ7LAURiLfce/tgON8I3x/dIbnZUyeRi8f2cx2azu6ATew==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.16.tgz", + "integrity": "sha512-YhWt9aKl+EMSNXyUTUo7I01WHf3HcCkPu/Hl2QmTNwrHT49eWaY7hptAMaERZuHFH0V5xHgPKgKZo2I93DFtgQ==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-utf8": "^2.0.2", "tslib": "^2.5.0" } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.15.tgz", - "integrity": "sha512-xH4kRBw01gJgWiU+/mNTrnyFXeozpZHw39gLb3JKGsFDVmSrJZ8/tRqu27tU/ki1gKkxr2wApu+dEYjI3QwV1Q==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.16.tgz", + "integrity": "sha512-9ddDia3pp1d3XzLXKcm7QebGxLq9iwKf+J1LapvlSOhpF8EM9SjMeSrMOOFgG+2TfW5K3+qz4IAJYYm7INYCng==", "dependencies": { - "@smithy/protocol-http": "^3.0.9", - "@smithy/types": "^2.5.0", + "@smithy/protocol-http": "^3.0.10", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8472,16 +8529,16 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.2.0.tgz", - "integrity": "sha512-tddRmaig5URk2106PVMiNX6mc5BnKIKajHHDxb7K0J5MLdcuQluHMGnjkv18iY9s9O0tF+gAcPd/pDXA5L9DZw==", - "dependencies": { - "@smithy/middleware-serde": "^2.0.13", - "@smithy/node-config-provider": "^2.1.5", - "@smithy/shared-ini-file-loader": "^2.2.4", - "@smithy/types": "^2.5.0", - "@smithy/url-parser": "^2.0.13", - "@smithy/util-middleware": "^2.0.6", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.2.1.tgz", + "integrity": "sha512-dVDS7HNJl/wb0lpByXor6whqDbb1YlLoaoWYoelyYzLHioXOE7y/0iDwJWtDcN36/tVCw9EPBFZ3aans84jLpg==", + "dependencies": { + "@smithy/middleware-serde": "^2.0.14", + "@smithy/node-config-provider": "^2.1.6", + "@smithy/shared-ini-file-loader": "^2.2.5", + "@smithy/types": "^2.6.0", + "@smithy/url-parser": "^2.0.14", + "@smithy/util-middleware": "^2.0.7", "tslib": "^2.5.0" }, "engines": { @@ -8489,16 +8546,16 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.20.tgz", - "integrity": "sha512-X2yrF/SHDk2WDd8LflRNS955rlzQ9daz9UWSp15wW8KtzoTXg3bhHM78HbK1cjr48/FWERSJKh9AvRUUGlIawg==", - "dependencies": { - "@smithy/node-config-provider": "^2.1.5", - "@smithy/protocol-http": "^3.0.9", - "@smithy/service-error-classification": "^2.0.6", - "@smithy/types": "^2.5.0", - "@smithy/util-middleware": "^2.0.6", - "@smithy/util-retry": "^2.0.6", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.21.tgz", + "integrity": "sha512-EZS1EXv1k6IJX6hyu/0yNQuPcPaXwG8SWljQHYueyRbOxmqYgoWMWPtfZj0xRRQ4YtLawQSpBgAeiJltq8/MPw==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.6", + "@smithy/protocol-http": "^3.0.10", + "@smithy/service-error-classification": "^2.0.7", + "@smithy/types": "^2.6.0", + "@smithy/util-middleware": "^2.0.7", + "@smithy/util-retry": "^2.0.7", "tslib": "^2.5.0", "uuid": "^8.3.2" }, @@ -8506,12 +8563,20 @@ "node": ">=14.0.0" } }, + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@smithy/middleware-serde": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.13.tgz", - "integrity": "sha512-tBGbeXw+XsE6pPr4UaXOh+UIcXARZeiA8bKJWxk2IjJcD1icVLhBSUQH9myCIZLNNzJIH36SDjUX8Wqk4xJCJg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.14.tgz", + "integrity": "sha512-hFi3FqoYWDntCYA2IGY6gJ6FKjq2gye+1tfxF2HnIJB5uW8y2DhpRNBSUMoqP+qvYzRqZ6ntv4kgbG+o3pX57g==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8519,11 +8584,11 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.7.tgz", - "integrity": "sha512-L1KLAAWkXbGx1t2jjCI/mDJ2dDNq+rp4/ifr/HcC6FHngxho5O7A5bQLpKHGlkfATH6fUnOEx0VICEVFA4sUzw==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.8.tgz", + "integrity": "sha512-7/N59j0zWqVEKExJcA14MrLDZ/IeN+d6nbkN8ucs+eURyaDUXWYlZrQmMOd/TyptcQv0+RDlgag/zSTTV62y/Q==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8531,13 +8596,13 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.5.tgz", - "integrity": "sha512-3Omb5/h4tOCuKRx4p4pkYTvEYRCYoKk52bOYbKUyz/G/8gERbagsN8jFm4FjQubkrcIqQEghTpQaUw6uk+0edw==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.6.tgz", + "integrity": "sha512-HLqTs6O78m3M3z1cPLFxddxhEPv5MkVatfPuxoVO3A+cHZanNd/H5I6btcdHy6N2CB1MJ/lihJC92h30SESsBA==", "dependencies": { - "@smithy/property-provider": "^2.0.14", - "@smithy/shared-ini-file-loader": "^2.2.4", - "@smithy/types": "^2.5.0", + "@smithy/property-provider": "^2.0.15", + "@smithy/shared-ini-file-loader": "^2.2.5", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8545,14 +8610,14 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.9.tgz", - "integrity": "sha512-+K0q3SlNcocmo9OZj+fz67gY4lwhOCvIJxVbo/xH+hfWObvaxrMTx7JEzzXcluK0thnnLz++K3Qe7Z/8MDUreA==", + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.10.tgz", + "integrity": "sha512-lkALAwtN6odygIM4nB8aHDahINM6WXXjNrZmWQAh0RSossySRT2qa31cFv0ZBuAYVWeprskRk13AFvvLmf1WLw==", "dependencies": { - "@smithy/abort-controller": "^2.0.13", - "@smithy/protocol-http": "^3.0.9", - "@smithy/querystring-builder": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/abort-controller": "^2.0.14", + "@smithy/protocol-http": "^3.0.10", + "@smithy/querystring-builder": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8560,11 +8625,11 @@ } }, "node_modules/@smithy/property-provider": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.14.tgz", - "integrity": "sha512-k3D2qp9o6imTrLaXRj6GdLYEJr1sXqS99nLhzq8fYmJjSVOeMg/G+1KVAAc7Oxpu71rlZ2f8SSZxcSxkevuR0A==", + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.15.tgz", + "integrity": "sha512-YbRFBn8oiiC3o1Kn3a4KjGa6k47rCM9++5W9cWqYn9WnkyH+hBWgfJAckuxpyA2Hq6Ys4eFrWzXq6fqHEw7iew==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8572,11 +8637,11 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.9.tgz", - "integrity": "sha512-U1wl+FhYu4/BC+rjwh1lg2gcJChQhytiNQSggREgQ9G2FzmoK9sACBZvx7thyWMvRyHQTE22mO2d5UM8gMKDBg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.10.tgz", + "integrity": "sha512-6+tjNk7rXW7YTeGo9qwxXj/2BFpJTe37kTj3EnZCoX/nH+NP/WLA7O83fz8XhkGqsaAhLUPo/bB12vvd47nsmg==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8584,11 +8649,11 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.13.tgz", - "integrity": "sha512-JhXKwp3JtsFUe96XLHy/nUPEbaXqn6r7xE4sNaH8bxEyytE5q1fwt0ew/Ke6+vIC7gP87HCHgQpJHg1X1jN2Fw==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.14.tgz", + "integrity": "sha512-lQ4pm9vTv9nIhl5jt6uVMPludr6syE2FyJmHsIJJuOD7QPIJnrf9HhUGf1iHh9KJ4CUv21tpOU3X6s0rB6uJ0g==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-uri-escape": "^2.0.0", "tslib": "^2.5.0" }, @@ -8597,11 +8662,11 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.13.tgz", - "integrity": "sha512-TEiT6o8CPZVxJ44Rly/rrsATTQsE+b/nyBVzsYn2sa75xAaZcurNxsFd8z1haoUysONiyex24JMHoJY6iCfLdA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.14.tgz", + "integrity": "sha512-+cbtXWI9tNtQjlgQg3CA+pvL3zKTAxPnG3Pj6MP89CR3vi3QMmD0SOWoq84tqZDnJCxlsusbgIXk1ngMReXo+A==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8609,22 +8674,22 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.6.tgz", - "integrity": "sha512-fCQ36frtYra2fqY2/DV8+3/z2d0VB/1D1hXbjRcM5wkxTToxq6xHbIY/NGGY6v4carskMyG8FHACxgxturJ9Pg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.7.tgz", + "integrity": "sha512-LLxgW12qGz8doYto15kZ4x1rHjtXl0BnCG6T6Wb8z2DI4PT9cJfOSvzbuLzy7+5I24PAepKgFeWHRd9GYy3Z9w==", "dependencies": { - "@smithy/types": "^2.5.0" + "@smithy/types": "^2.6.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.4.tgz", - "integrity": "sha512-9dRknGgvYlRIsoTcmMJXuoR/3ekhGwhRq4un3ns2/byre4Ql5hyUN4iS0x8eITohjU90YOnUCsbRwZRvCkbRfw==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.5.tgz", + "integrity": "sha512-LHA68Iu7SmNwfAVe8egmjDCy648/7iJR/fK1UnVw+iAOUJoEYhX2DLgVd5pWllqdDiRbQQzgaHLcRokM+UFR1w==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8632,15 +8697,15 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.15.tgz", - "integrity": "sha512-SRTEJSEhQYVlBKIIdZ9SZpqW+KFqxqcNnEcBX+8xkDdWx+DItme9VcCDkdN32yTIrICC+irUufnUdV7mmHPjoA==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.16.tgz", + "integrity": "sha512-ilLY85xS2kZZzTb83diQKYLIYALvart0KnBaKnIRnMBHAGEio5aHSlANQoxVn0VsonwmQ3CnWhnCT0sERD8uTg==", "dependencies": { - "@smithy/eventstream-codec": "^2.0.13", + "@smithy/eventstream-codec": "^2.0.14", "@smithy/is-array-buffer": "^2.0.0", - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-middleware": "^2.0.6", + "@smithy/util-middleware": "^2.0.7", "@smithy/util-uri-escape": "^2.0.0", "@smithy/util-utf8": "^2.0.2", "tslib": "^2.5.0" @@ -8650,13 +8715,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.15.tgz", - "integrity": "sha512-rngZcQu7Jvs9UbHihK1EI67RMPuzkc3CJmu4MBgB7D7yBnMGuFR86tq5rqHfL2gAkNnMelBN/8kzQVvZjNKefQ==", + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.16.tgz", + "integrity": "sha512-Lw67+yQSpLl4YkDLUzI2KgS8TXclXmbzSeOJUmRFS4ueT56B4pw3RZRF/SRzvgyxM/HxgkUan8oSHXCujPDafQ==", "dependencies": { - "@smithy/middleware-stack": "^2.0.7", - "@smithy/types": "^2.5.0", - "@smithy/util-stream": "^2.0.20", + "@smithy/middleware-stack": "^2.0.8", + "@smithy/types": "^2.6.0", + "@smithy/util-stream": "^2.0.21", "tslib": "^2.5.0" }, "engines": { @@ -8664,9 +8729,9 @@ } }, "node_modules/@smithy/types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.5.0.tgz", - "integrity": "sha512-/a31lYofrMBkJb3BuPlYJTMKDj0hUmKUP6JFZQu6YVuQVoAjubiY0A52U9S0Uysd33n/djexCUSNJ+G9bf3/aA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.6.0.tgz", + "integrity": "sha512-PgqxJq2IcdMF9iAasxcqZqqoOXBHufEfmbEUdN1pmJrJltT42b0Sc8UiYSWWzKkciIp9/mZDpzYi4qYG1qqg6g==", "dependencies": { "tslib": "^2.5.0" }, @@ -8675,12 +8740,12 @@ } }, "node_modules/@smithy/url-parser": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.13.tgz", - "integrity": "sha512-okWx2P/d9jcTsZWTVNnRMpFOE7fMkzloSFyM53fA7nLKJQObxM2T4JlZ5KitKKuXq7pxon9J6SF2kCwtdflIrA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.14.tgz", + "integrity": "sha512-kbu17Y1AFXi5lNlySdDj7ZzmvupyWKCX/0jNZ8ffquRyGdbDZb+eBh0QnWqsSmnZa/ctyWaTf7n4l/pXLExrnw==", "dependencies": { - "@smithy/querystring-parser": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/querystring-parser": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" } }, @@ -8739,13 +8804,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.19.tgz", - "integrity": "sha512-VHP8xdFR7/orpiABJwgoTB0t8Zhhwpf93gXhNfUBiwAE9O0rvsv7LwpQYjgvbOUDDO8JfIYQB2GYJNkqqGWsXw==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.20.tgz", + "integrity": "sha512-QJtnbTIl0/BbEASkx1MUFf6EaoWqWW1/IM90N++8NNscePvPf77GheYfpoPis6CBQawUWq8QepTP2QUSAdrVkw==", "dependencies": { - "@smithy/property-provider": "^2.0.14", - "@smithy/smithy-client": "^2.1.15", - "@smithy/types": "^2.5.0", + "@smithy/property-provider": "^2.0.15", + "@smithy/smithy-client": "^2.1.16", + "@smithy/types": "^2.6.0", "bowser": "^2.11.0", "tslib": "^2.5.0" }, @@ -8754,16 +8819,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.25", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.25.tgz", - "integrity": "sha512-jkmep6/JyWmn2ADw9VULDeGbugR4N/FJCKOt+gYyVswmN1BJOfzF2umaYxQ1HhQDvna3kzm1Dbo1qIfBW4iuHA==", - "dependencies": { - "@smithy/config-resolver": "^2.0.18", - "@smithy/credential-provider-imds": "^2.1.1", - "@smithy/node-config-provider": "^2.1.5", - "@smithy/property-provider": "^2.0.14", - "@smithy/smithy-client": "^2.1.15", - "@smithy/types": "^2.5.0", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.26.tgz", + "integrity": "sha512-lGFPOFCHv1ql019oegYqa54BZH7HREw6EBqjDLbAr0wquMX0BDi2sg8TJ6Eq+JGLijkZbJB73m4+aK8OFAapMg==", + "dependencies": { + "@smithy/config-resolver": "^2.0.19", + "@smithy/credential-provider-imds": "^2.1.2", + "@smithy/node-config-provider": "^2.1.6", + "@smithy/property-provider": "^2.0.15", + "@smithy/smithy-client": "^2.1.16", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8771,12 +8836,12 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.0.4.tgz", - "integrity": "sha512-FPry8j1xye5yzrdnf4xKUXVnkQErxdN7bUIaqC0OFoGsv2NfD9b2UUMuZSSt+pr9a8XWAqj0HoyVNUfPiZ/PvQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.0.5.tgz", + "integrity": "sha512-K7qNuCOD5K/90MjHvHm9kJldrfm40UxWYQxNEShMFxV/lCCCRIg8R4uu1PFAxRvPxNpIdcrh1uK6I1ISjDXZJw==", "dependencies": { - "@smithy/node-config-provider": "^2.1.5", - "@smithy/types": "^2.5.0", + "@smithy/node-config-provider": "^2.1.6", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8795,11 +8860,11 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.6.tgz", - "integrity": "sha512-7W4uuwBvSLgKoLC1x4LfeArCVcbuHdtVaC4g30kKsD1erfICyQ45+tFhhs/dZNeQg+w392fhunCm/+oCcb6BSA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.7.tgz", + "integrity": "sha512-tRINOTlf1G9B0ECarFQAtTgMhpnrMPSa+5j4ZEwEawCLfTFTavk6757sxhE4RY5RMlD/I3x+DCS8ZUiR8ho9Pw==", "dependencies": { - "@smithy/types": "^2.5.0", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8807,12 +8872,12 @@ } }, "node_modules/@smithy/util-retry": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.6.tgz", - "integrity": "sha512-PSO41FofOBmyhPQJwBQJ6mVlaD7Sp9Uff9aBbnfBJ9eqXOE/obrqQjn0PNdkfdvViiPXl49BINfnGcFtSP4kYw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.7.tgz", + "integrity": "sha512-fIe5yARaF0+xVT1XKcrdnHKTJ1Vc4+3e3tLDjCuIcE9b6fkBzzGFY7AFiX4M+vj6yM98DrwkuZeHf7/hmtVp0Q==", "dependencies": { - "@smithy/service-error-classification": "^2.0.6", - "@smithy/types": "^2.5.0", + "@smithy/service-error-classification": "^2.0.7", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -8820,13 +8885,13 @@ } }, "node_modules/@smithy/util-stream": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.20.tgz", - "integrity": "sha512-tT8VASuD8jJu0yjHEMTCPt1o5E3FVzgdsxK6FQLAjXKqVv5V8InCnc0EOsYrijgspbfDqdAJg7r0o2sySfcHVg==", + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.21.tgz", + "integrity": "sha512-0BUE16d7n1x7pi1YluXJdB33jOTyBChT0j/BlOkFa9uxfg6YqXieHxjHNuCdJRARa7AZEj32LLLEPJ1fSa4inA==", "dependencies": { - "@smithy/fetch-http-handler": "^2.2.6", - "@smithy/node-http-handler": "^2.1.9", - "@smithy/types": "^2.5.0", + "@smithy/fetch-http-handler": "^2.2.7", + "@smithy/node-http-handler": "^2.1.10", + "@smithy/types": "^2.6.0", "@smithy/util-base64": "^2.0.1", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-hex-encoding": "^2.0.0", @@ -8981,12 +9046,12 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.13.tgz", - "integrity": "sha512-YovIQatiuM7giEsRFotqJa2i3EbU2EE3PgtpXgtLgpx5rXiZMAwPxXYDFVFhuO0lbqvc/Zx4n+ZIisXOHPSqyg==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.14.tgz", + "integrity": "sha512-Q6gSz4GUNjNGhrfNg+2Mjy+7K4pEI3r82x1b/+3dSc03MQqobMiUrRVN/YK/4nHVagvBELCoXsiHAFQJNQ5BeA==", "dependencies": { - "@smithy/abort-controller": "^2.0.13", - "@smithy/types": "^2.5.0", + "@smithy/abort-controller": "^2.0.14", + "@smithy/types": "^2.6.0", "tslib": "^2.5.0" }, "engines": { @@ -9000,9 +9065,9 @@ "dev": true }, "node_modules/@types/aws-lambda": { - "version": "8.10.126", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.126.tgz", - "integrity": "sha512-5eh4ffLdGYgGYI1Xr6W5L4IVse4RR7L2ns5OVUXA52nW5GFapIcGMcCzHAIMMOdpcQs3aGVxbvFlJNZH6IpgEQ==", + "version": "8.10.129", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.129.tgz", + "integrity": "sha512-0Rl7CpTPVws5cp0Ui1gZh4Q+TXC65bXVwTOGoI2RKW45dxWzyZGbjIX0uFjFYdIJ8vnD45y584rIIqvD2vBBfQ==", "dev": true }, "node_modules/@types/debounce-promise": { @@ -9077,9 +9142,9 @@ } }, "node_modules/@types/node": { - "version": "18.18.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.11.tgz", - "integrity": "sha512-c1vku6qnTeujJneYH94/4aq73XrVcsJe35UPyAsSok1ijiKrkRzK+AxQPSpNMUnC03roWBBwJx/9I8V7lQoxmA==", + "version": "18.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", + "integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==", "dependencies": { "undici-types": "~5.26.4" } @@ -9794,9 +9859,9 @@ } }, "node_modules/@whatwg-node/node-fetch": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.0.tgz", - "integrity": "sha512-q76lDAafvHNGWedNAVHrz/EyYTS8qwRLcwne8SJQdRN5P3HydxU6XROFvJfTML6KZXQX2FDdGY4/SnaNyd7M0Q==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.1.tgz", + "integrity": "sha512-sQz/s3NyyzIZxQ7PHxDFUMM1k4kQQbi2jU8ILdTbt5+S59ME8aI7XF30O9qohRIIYdSrUvm/OwKQmVP1y6e2WQ==", "dependencies": { "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", @@ -10190,9 +10255,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.110.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.110.1.tgz", - "integrity": "sha512-/V0FOgsvD/FkFANrYnSmyb+XK56tm2oE86pUCoEggQ2tka6Zm0z9blKZQV4euMErNSkWz4ReSAKenaqk86Fr5Q==", + "version": "2.111.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.111.0.tgz", + "integrity": "sha512-2f9DCfgzSF19mb2fPFUuYaHFaUXNeN5T1Nab/4gye6rVa+pmAvBGeTXKQR4Xmckz7rGLZCB0Ym5V3P1SIWXncw==", "peer": true, "bin": { "cdk": "bin/cdk" @@ -10544,20 +10609,6 @@ "node": ">= 6" } }, - "node_modules/aws-cdk/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/aws-lambda": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/aws-lambda/-/aws-lambda-1.0.7.tgz", @@ -10580,9 +10631,9 @@ "dev": true }, "node_modules/aws-sdk": { - "version": "2.1500.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1500.0.tgz", - "integrity": "sha512-e6ISdnxgHbq+QWYYILdSMfTuTJgLSR9PLKEz4RCxaybKIe05z75jYgc2WSPt9++3rQPSdqSc4wYSlwuE0m7jjA==", + "version": "2.1506.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1506.0.tgz", + "integrity": "sha512-jSBbofvPa7HJykyM7Xph9psMcWPl6UgdiKjG2E7fHJb6psW+BZN9ZvSGOBvRIlT8Y6+JGzI0qkouS1OLK9slhg==", "dev": true, "dependencies": { "buffer": "4.9.2", @@ -11269,9 +11320,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001563", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz", - "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "funding": [ { "type": "opencollective", @@ -11407,9 +11458,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", - "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "engines": { "node": ">=6" }, @@ -12035,14 +12086,11 @@ } }, "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/define-properties": { @@ -12233,9 +12281,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.589", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.589.tgz", - "integrity": "sha512-zF6y5v/YfoFIgwf2dDfAqVlPPsyQeWNpEWXbAlDUS8Ax4Z2VoiiZpAPC0Jm9hXEkJm2vIZpwB6rc4KnLTQffbQ==" + "version": "1.4.596", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.596.tgz", + "integrity": "sha512-zW3zbZ40Icb2BCWjm47nxwcFGYlIgdXkAx85XDO7cyky9J4QQfq8t0W19/TLZqq3JPQXtlv8BPIGmfa9Jb4scg==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -13968,9 +14016,9 @@ } }, "node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -13986,15 +14034,16 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -14856,14 +14905,14 @@ } }, "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "bin": { "is-docker": "cli.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14955,6 +15004,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", @@ -15217,20 +15280,6 @@ "node": ">=8" } }, - "node_modules/is-wsl/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -16640,17 +16689,16 @@ } }, "node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", "is-wsl": "^2.2.0" }, "engines": { - "node": ">=14.16" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -16893,9 +16941,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.3.tgz", - "integrity": "sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "engines": { "node": "14 || >=16.14" } @@ -19215,6 +19263,19 @@ "fsevents": "~2.3.3" } }, + "node_modules/tsx/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/tty-table": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/tty-table/-/tty-table-4.2.3.tgz", @@ -19525,9 +19586,9 @@ } }, "node_modules/typedoc": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.3.tgz", - "integrity": "sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.4.tgz", + "integrity": "sha512-Du9ImmpBCw54bX275yJrxPVnjdIyJO/84co0/L9mwe0R3G4FSR6rQ09AlXVRvZEGMUg09+z/usc8mgygQ1aidA==", "dev": true, "dependencies": { "lunr": "^2.3.9", @@ -19542,7 +19603,7 @@ "node": ">= 16" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -19777,17 +19838,21 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-to-istanbul": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -20456,12 +20521,12 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.4.2", + "version": "0.4.3", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/plugin-types": "^0.4.2" + "@aws-amplify/plugin-types": "^0.5.0" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -20470,19 +20535,19 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.5.5", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.3.5", - "@aws-amplify/backend-data": "^0.8.2", - "@aws-amplify/backend-function": "^0.2.5", + "@aws-amplify/backend-auth": "^0.3.6", + "@aws-amplify/backend-data": "^0.8.3", + "@aws-amplify/backend-function": "^0.3.0", "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/backend-secret": "^0.3.1", - "@aws-amplify/backend-storage": "^0.3.1", + "@aws-amplify/backend-secret": "^0.3.2", + "@aws-amplify/backend-storage": "^0.3.2", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.1", - "@aws-amplify/plugin-types": "^0.4.2", + "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/plugin-types": "^0.5.0", "@aws-sdk/client-amplify": "^3.440.0" }, "devDependencies": { @@ -20496,16 +20561,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.3.5", + "version": "0.3.6", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.4.2", + "@aws-amplify/auth-construct-alpha": "^0.4.3", "@aws-amplify/backend-output-storage": "0.2.6", - "@aws-amplify/plugin-types": "^0.4.2" + "@aws-amplify/plugin-types": "^0.5.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.1" + "@aws-amplify/platform-core": "^0.3.2" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -20514,19 +20579,19 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.8.2", + "version": "0.8.3", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "0.2.6", "@aws-amplify/data-construct": "^1.4.1", "@aws-amplify/data-schema-types": "^0.6.6", - "@aws-amplify/plugin-types": "^0.4.2" + "@aws-amplify/plugin-types": "^0.5.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.1" + "@aws-amplify/platform-core": "^0.3.2" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -20535,11 +20600,11 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.3.4", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.3.1", - "@aws-amplify/plugin-types": "^0.4.2", + "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/plugin-types": "^0.5.0", "execa": "^7.2.0", "tsx": "^3.12.6" }, @@ -20550,16 +20615,16 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.2.5", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-storage": "0.2.6", - "@aws-amplify/plugin-types": "^0.4.2", + "@aws-amplify/plugin-types": "^0.5.0", "execa": "^7.1.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.1", + "@aws-amplify/platform-core": "^0.3.2", "uuid": "^9.0.1" }, "peerDependencies": { @@ -20585,7 +20650,7 @@ "version": "0.4.0", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/plugin-types": "0.4.2" + "@aws-amplify/plugin-types": "0.5.0" }, "peerDependencies": { "zod": "^3.21.4" @@ -20614,11 +20679,11 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.3.1", + "version": "0.3.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.3.0", - "@aws-amplify/plugin-types": "^0.4.0", + "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/plugin-types": "^0.5.0", "@aws-sdk/client-ssm": "^3.398.0" }, "devDependencies": { @@ -20627,16 +20692,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.3.1", + "version": "0.3.2", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/plugin-types": "^0.4.2", + "@aws-amplify/plugin-types": "^0.5.0", "@aws-amplify/storage-construct-alpha": "^0.2.3" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.1" + "@aws-amplify/platform-core": "^0.3.2" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -20645,18 +20710,18 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.9.1", + "version": "0.9.2", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", - "@aws-amplify/backend-secret": "^0.3.1", + "@aws-amplify/backend-secret": "^0.3.2", "@aws-amplify/cli-core": "^0.2.0", "@aws-amplify/client-config": "^0.4.2", - "@aws-amplify/deployed-backend-client": "^0.3.3", + "@aws-amplify/deployed-backend-client": "^0.3.4", "@aws-amplify/form-generator": "^0.6.0", "@aws-amplify/model-generator": "^0.2.3", - "@aws-amplify/platform-core": "^0.3.0", - "@aws-amplify/sandbox": "^0.3.5", + "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/sandbox": "^0.3.7", "@aws-sdk/credential-provider-ini": "^3.360.0", "@aws-sdk/credential-providers": "^3.360.0", "@aws-sdk/region-config-resolver": "^3.433.0", @@ -20691,7 +20756,8 @@ }, "packages/cli/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -20704,7 +20770,8 @@ }, "packages/cli/node_modules/cliui": { "version": "8.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -20716,7 +20783,8 @@ }, "packages/cli/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, @@ -20726,57 +20794,26 @@ }, "packages/cli/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" - }, - "packages/cli/node_modules/define-lazy-prop": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "packages/cli/node_modules/emoji-regex": { "version": "8.0.0", - "license": "MIT" - }, - "packages/cli/node_modules/is-docker": { - "version": "2.2.1", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "packages/cli/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, - "packages/cli/node_modules/open": { - "version": "8.4.2", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/cli/node_modules/string-width": { "version": "4.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20788,7 +20825,8 @@ }, "packages/cli/node_modules/wrap-ansi": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -20803,7 +20841,8 @@ }, "packages/cli/node_modules/yargs": { "version": "17.7.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -20819,7 +20858,8 @@ }, "packages/cli/node_modules/yargs-parser": { "version": "21.1.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { "node": ">=12" } @@ -20844,11 +20884,11 @@ } }, "packages/create-amplify": { - "version": "0.3.8", + "version": "0.3.9", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/platform-core": "0.3.1", + "@aws-amplify/platform-core": "0.3.2", "execa": "^7.2.0", "yargs": "^17.7.2" }, @@ -20861,7 +20901,8 @@ }, "packages/create-amplify/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -20874,7 +20915,8 @@ }, "packages/create-amplify/node_modules/cliui": { "version": "8.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -20886,7 +20928,8 @@ }, "packages/create-amplify/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, @@ -20896,22 +20939,26 @@ }, "packages/create-amplify/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "packages/create-amplify/node_modules/emoji-regex": { "version": "8.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "packages/create-amplify/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, "packages/create-amplify/node_modules/string-width": { "version": "4.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20923,7 +20970,8 @@ }, "packages/create-amplify/node_modules/wrap-ansi": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -20938,7 +20986,8 @@ }, "packages/create-amplify/node_modules/yargs": { "version": "17.7.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -20954,18 +21003,19 @@ }, "packages/create-amplify/node_modules/yargs-parser": { "version": "21.1.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { "node": ">=12" } }, "packages/deployed-backend-client": { "name": "@aws-amplify/deployed-backend-client", - "version": "0.3.3", + "version": "0.3.4", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", - "@aws-amplify/platform-core": "^0.3.0", + "@aws-amplify/platform-core": "^0.3.2", "@aws-sdk/client-amplify": "^3.329.0", "@aws-sdk/client-cloudformation": "^3.329.0", "@aws-sdk/client-s3": "^3.329.0", @@ -21007,14 +21057,14 @@ }, "packages/integration-tests": { "name": "@aws-amplify/integration-tests", - "version": "0.3.7", + "version": "0.3.8", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/backend": "^0.5.5", - "@aws-amplify/backend-secret": "^0.3.1", + "@aws-amplify/backend": "^0.6.0", + "@aws-amplify/backend-secret": "^0.3.2", "@aws-amplify/client-config": "^0.4.0", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.1", + "@aws-amplify/platform-core": "^0.3.2", "@aws-sdk/client-amplify": "^3.440.0", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/client-lambda": "^3.460.0", @@ -21403,8 +21453,9 @@ }, "packages/integration-tests/node_modules/execa": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -21425,8 +21476,9 @@ }, "packages/integration-tests/node_modules/get-stream": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "license": "MIT", "engines": { "node": ">=16" }, @@ -21436,16 +21488,18 @@ }, "packages/integration-tests/node_modules/human-signals": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "packages/integration-tests/node_modules/signal-exit": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -21488,10 +21542,10 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.3.1", + "version": "0.3.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/plugin-types": "^0.4.2", + "@aws-amplify/plugin-types": "^0.5.0", "@aws-sdk/client-sts": "3.445.0", "is-ci": "^3.0.1", "uuid": "9.0.1", @@ -21504,7 +21558,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/client-sso": { "version": "3.445.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.445.0.tgz", + "integrity": "sha512-me4LvqNnu6kxi+sW7t0AgMv1Yi64ikas0x2+5jv23o6Csg32w0S0xOjCTKQYahOA5CMFunWvlkFIfxbqs+Uo7w==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -21549,7 +21604,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/client-sts": { "version": "3.445.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.445.0.tgz", + "integrity": "sha512-ogbdqrS8x9O5BTot826iLnTQ6i4/F5BSi/74gycneCxYmAnYnyUBNOWVnynv6XZiEWyDJQCU2UtMd52aNGW1GA==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -21610,7 +21666,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-env": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.433.0.tgz", + "integrity": "sha512-Vl7Qz5qYyxBurMn6hfSiNJeUHSqfVUlMt0C1Bds3tCkl3IzecRWwyBOlxtxO3VCrgVeW3HqswLzCvhAFzPH6nQ==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", @@ -21623,7 +21680,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-ini": { "version": "3.445.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.445.0.tgz", + "integrity": "sha512-R7IYSGjNZ5KKJwQJ2HNPemjpAMWvdce91i8w+/aHfqeGfTXrmYJu99PeGRyyBTKEumBaojyjTRvmO8HzS+/l7g==", "dependencies": { "@aws-sdk/credential-provider-env": "3.433.0", "@aws-sdk/credential-provider-process": "3.433.0", @@ -21642,7 +21700,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-node": { "version": "3.445.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.445.0.tgz", + "integrity": "sha512-zI4k4foSjQRKNEsouculRcz7IbLfuqdFxypDLYwn+qPNMqJwWJ7VxOOeBSPUpHFcd7CLSfbHN2JAhQ7M02gPTA==", "dependencies": { "@aws-sdk/credential-provider-env": "3.433.0", "@aws-sdk/credential-provider-ini": "3.445.0", @@ -21662,7 +21721,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-process": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.433.0.tgz", + "integrity": "sha512-W7FcGlQjio9Y/PepcZGRyl5Bpwb0uWU7qIUCh+u4+q2mW4D5ZngXg8V/opL9/I/p4tUH9VXZLyLGwyBSkdhL+A==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", @@ -21676,7 +21736,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-sso": { "version": "3.445.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.445.0.tgz", + "integrity": "sha512-gJz7kAiDecdhtApgXnxfZsXKsww8BnifDF9MAx9Dr4X6no47qYsCCS3XPuEyRiF9VebXvHOH0H260Zp3bVyniQ==", "dependencies": { "@aws-sdk/client-sso": "3.445.0", "@aws-sdk/token-providers": "3.438.0", @@ -21692,7 +21753,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.433.0.tgz", + "integrity": "sha512-RlwjP1I5wO+aPpwyCp23Mk8nmRbRL33hqRASy73c4JA2z2YiRua+ryt6MalIxehhwQU6xvXUKulJnPG9VaMFZg==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", @@ -21705,7 +21767,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-host-header": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.433.0.tgz", + "integrity": "sha512-mBTq3UWv1UzeHG+OfUQ2MB/5GEkt5LTKFaUqzL7ESwzW8XtpBgXnjZvIwu3Vcd3sEetMwijwaGiJhY0ae/YyaA==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/protocol-http": "^3.0.8", @@ -21718,7 +21781,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-logger": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.433.0.tgz", + "integrity": "sha512-We346Fb5xGonTGVZC9Nvqtnqy74VJzYuTLLiuuftA5sbNzftBDy/22QCfvYSTOAl3bvif+dkDUzQY2ihc5PwOQ==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/types": "^2.4.0", @@ -21730,7 +21794,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.433.0.tgz", + "integrity": "sha512-HEvYC9PQlWY/ccUYtLvAlwwf1iCif2TSAmLNr3YTBRVa98x6jKL0hlCrHWYklFeqOGSKy6XhE+NGJMUII0/HaQ==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/protocol-http": "^3.0.8", @@ -21743,7 +21808,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-sdk-sts": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.433.0.tgz", + "integrity": "sha512-ORYbJnBejUyonFl5FwIqhvI3Cq6sAp9j+JpkKZtFNma9tFPdrhmYgfCeNH32H/wGTQV/tUoQ3luh0gA4cuk6DA==", "dependencies": { "@aws-sdk/middleware-signing": "3.433.0", "@aws-sdk/types": "3.433.0", @@ -21756,7 +21822,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-signing": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.433.0.tgz", + "integrity": "sha512-jxPvt59NZo/epMNLNTu47ikmP8v0q217I6bQFGJG7JVFnfl36zDktMwGw+0xZR80qiK47/2BWrNpta61Zd2FxQ==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/property-provider": "^2.0.0", @@ -21772,7 +21839,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/middleware-user-agent": { "version": "3.438.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.438.0.tgz", + "integrity": "sha512-a+xHT1wOxT6EA6YyLmrfaroKWOkwwyiktUfXKM0FsUutGzNi4fKhb5NZ2al58NsXzHgHFrasSDp+Lqbd/X2cEw==", "dependencies": { "@aws-sdk/types": "3.433.0", "@aws-sdk/util-endpoints": "3.438.0", @@ -21801,7 +21869,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/token-providers": { "version": "3.438.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.438.0.tgz", + "integrity": "sha512-G2fUfTtU6/1ayYRMu0Pd9Ln4qYSvwJOWCqJMdkDgvXSwdgcOSOLsnAIk1AHGJDAvgLikdCzuyOsdJiexr9Vnww==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", @@ -21847,7 +21916,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/types": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.433.0.tgz", + "integrity": "sha512-0jEE2mSrNDd8VGFjTc1otYrwYPIkzZJEIK90ZxisKvQ/EURGBhNzWn7ejWB9XCMFT6XumYLBR0V9qq5UPisWtA==", "dependencies": { "@smithy/types": "^2.4.0", "tslib": "^2.5.0" @@ -21858,7 +21928,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/util-endpoints": { "version": "3.438.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.438.0.tgz", + "integrity": "sha512-6VyPTq1kN3GWxwFt5DdZfOsr6cJZPLjWh0troY/0uUv3hK74C9o3Y0Xf/z8UAUvQFkVqZse12O0/BgPVMImvfA==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/util-endpoints": "^1.0.2", @@ -21870,7 +21941,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.433.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.433.0.tgz", + "integrity": "sha512-2Cf/Lwvxbt5RXvWFXrFr49vXv0IddiUwrZoAiwhDYxvsh+BMnh+NUFot+ZQaTrk/8IPZVDeLPWZRdVy00iaVXQ==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/types": "^2.4.0", @@ -21880,7 +21952,8 @@ }, "packages/platform-core/node_modules/@aws-sdk/util-user-agent-node": { "version": "3.437.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.437.0.tgz", + "integrity": "sha512-JVEcvWaniamtYVPem4UthtCNoTBCfFTwYj7Y3CrWZ2Qic4TqrwLkAfaBGtI2TGrhIClVr77uzLI6exqMTN7orA==", "dependencies": { "@aws-sdk/types": "3.433.0", "@smithy/node-config-provider": "^2.1.3", @@ -21899,20 +21972,9 @@ } } }, - "packages/platform-core/node_modules/uuid": { - "version": "9.0.1", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "packages/plugin-types": { "name": "@aws-amplify/plugin-types", - "version": "0.4.2", + "version": "0.5.0", "license": "Apache-2.0", "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21921,15 +21983,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.3.6", + "version": "0.3.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "0.3.4", - "@aws-amplify/backend-secret": "^0.3.1", + "@aws-amplify/backend-deployer": "0.4.0", + "@aws-amplify/backend-secret": "^0.3.2", "@aws-amplify/cli-core": "^0.2.0", "@aws-amplify/client-config": "0.4.2", - "@aws-amplify/deployed-backend-client": "^0.3.3", - "@aws-amplify/platform-core": "^0.3.1", + "@aws-amplify/deployed-backend-client": "^0.3.4", + "@aws-amplify/platform-core": "^0.3.2", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/credential-providers": "^3.382.0", "@aws-sdk/types": "^3.378.0", @@ -21947,6 +22009,34 @@ "aws-cdk": "^2.110.1" } }, + "packages/sandbox/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/sandbox/node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/storage-construct": { "name": "@aws-amplify/storage-construct-alpha", "version": "0.2.3", @@ -21956,7 +22046,7 @@ "@aws-amplify/backend-output-storage": "^0.2.6" }, "devDependencies": { - "@aws-amplify/plugin-types": "^0.4.2" + "@aws-amplify/plugin-types": "^0.5.0" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", diff --git a/packages/create-amplify/src/initial_project_file_generator.ts b/packages/create-amplify/src/initial_project_file_generator.ts index 81261416315..834ba522918 100644 --- a/packages/create-amplify/src/initial_project_file_generator.ts +++ b/packages/create-amplify/src/initial_project_file_generator.ts @@ -1,4 +1,5 @@ import path from 'path'; +import fs from 'fs'; import _fs from 'fs/promises'; import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_logger.js'; import { execa } from 'execa'; @@ -17,6 +18,12 @@ export class InitialProjectFileGenerator { private readonly executeWithDebugLogger = _executeWithDebugLogger ) {} + private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE + ? 'npm' + : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') + ? 'yarn' + : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. + /** * Copies the template directory to an amplify folder within the projectRoot */ @@ -35,6 +42,16 @@ export class InitialProjectFileGenerator { JSON.stringify(packageJsonContent, null, 2) ); + if (process.env.PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + fs.writeFile(path.resolve(targetDir, 'yarn.lock'), '', (err) => { + if (err) { + console.error(`Error creating ${targetDir}/${targetDir}`, err); + } else { + console.log(`${targetDir}/yarn.lock created successfully.`); + } + }); + } + await this.initializeTsConfig(targetDir); }; @@ -52,6 +69,24 @@ export class InitialProjectFileGenerator { 'es2022', ]; - await this.executeWithDebugLogger(targetDir, 'npx', tscArgs, execa); + if (this.executableName.startsWith('yarn')) { + await this.executeWithDebugLogger( + targetDir, + 'yarn', + ['add', 'typescript@^5'], + execa + ); + } + + await this.executeWithDebugLogger( + targetDir, + this.executableName === 'npm' + ? 'npx' + : this.executableName.startsWith('yarn') + ? 'yarn' + : this.executableName, + tscArgs, + execa + ); }; } diff --git a/packages/create-amplify/src/npm_package_manager_controller.ts b/packages/create-amplify/src/npm_package_manager_controller.ts index 546c581de44..a7013ec788d 100644 --- a/packages/create-amplify/src/npm_package_manager_controller.ts +++ b/packages/create-amplify/src/npm_package_manager_controller.ts @@ -18,7 +18,7 @@ export class NpmPackageManagerController implements PackageManagerController { ) {} private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE ? 'npm' - : process.env.PACKAGE_MANAGER_EXECUTABLE === 'yarn-stable' + : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') ? 'yarn' : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. @@ -29,9 +29,9 @@ export class NpmPackageManagerController implements PackageManagerController { packageNames: string[], type: DependencyType ): Promise => { - const args = [this.executableName === 'yarn' ? 'add' : 'install'].concat( - ...packageNames - ); + const args = [ + this.executableName.startsWith('yarn') ? 'add' : 'install', + ].concat(...packageNames); if (type === 'dev') { args.push('-D'); } diff --git a/packages/create-amplify/src/npm_project_initializer.ts b/packages/create-amplify/src/npm_project_initializer.ts index 2653b4a113f..072e0c90688 100644 --- a/packages/create-amplify/src/npm_project_initializer.ts +++ b/packages/create-amplify/src/npm_project_initializer.ts @@ -17,8 +17,11 @@ export class NpmProjectInitializer { private readonly execa = _execa ) {} - private readonly executableName = - process.env.PACKAGE_MANAGER_EXECUTABLE || 'npm'; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. + private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE + ? 'npm' + : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') + ? 'yarn' + : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. /** * If package.json already exists, this is a noop. Otherwise, `npm init` is executed to create a package.json file diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index 505e14ee9b0..7e113e50e75 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -8,204 +8,359 @@ import assert from 'assert'; import { glob } from 'glob'; import { testConcurrencyLevel } from './test_concurrency.js'; -void describe( - 'create-amplify script', - { concurrency: testConcurrencyLevel }, - () => { - before(async () => { - // start a local npm proxy and publish the current codebase to the proxy - await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); - await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); - - // nuke the npx cache to ensure we are installing packages from the npm proxy - const { stdout } = await execa('npm', ['config', 'get', 'cache']); - const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); - - if (existsSync(npxCacheLocation)) { - await fs.rm(npxCacheLocation, { recursive: true }); - } +type PackageManagerExecutable = 'npm' | 'yarn-classic' | 'yarn-modern' | 'pnpm'; + +const concurrency = process.env.PACKAGE_MANAGER_EXECUTABLE?.startsWith('yarn') + ? 1 + : testConcurrencyLevel; + +const packageManagerSetup = async ( + packageManagerExecutable: PackageManagerExecutable, + dir?: string +) => { + const execaOptions = { + cwd: dir || os.homedir(), + stdio: 'inherit' as const, + }; + + if (packageManagerExecutable === 'npm') { + // nuke the npx cache to ensure we are installing packages from the npm proxy + const { stdout } = await execa('npm', ['config', 'get', 'cache']); + const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); + + if (existsSync(npxCacheLocation)) { + await fs.rm(npxCacheLocation, { recursive: true }); + } + } else if (packageManagerExecutable.startsWith('yarn')) { + if (packageManagerExecutable === 'yarn-modern') { + await execa('corepack', ['enable'], execaOptions); + await execa('yarn', ['init', '-2'], execaOptions); + + await execa( + 'yarn', + ['config', 'set', 'npmRegistryServer', 'http://localhost:4873'], + execaOptions + ); + await execa( + 'yarn', + ['config', 'set', 'unsafeHttpWhitelist', 'localhost'], + execaOptions + ); + } else { + await execa( + 'yarn', + ['config', 'set', 'registry', 'http://localhost:4873'], + execaOptions + ); + await execa('yarn', ['config', 'get', 'registry'], execaOptions); + } + await execa('yarn', ['cache', 'clean'], execaOptions); + } else if (packageManagerExecutable === 'pnpm') { + await execa(packageManagerExecutable, ['--version']); + await execa(packageManagerExecutable, [ + 'config', + 'set', + 'registry', + 'http://localhost:4873', + ]); + await execa(packageManagerExecutable, ['config', 'get', 'registry']); - // Force 'create-amplify' installation in npx cache by executing help command - // before tests run. Otherwise, installing 'create-amplify' concurrently - // may lead to race conditions and corrupted npx cache. - await execa('npm', ['create', 'amplify', '--yes', '--', '--help'], { + await execa(packageManagerExecutable, ['store', 'clear']); + } +}; + +void describe('create-amplify script', { concurrency }, () => { + const { PACKAGE_MANAGER_EXECUTABLE = 'npm' } = process.env; + const packageManagerExecutable = PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE; + + before(async () => { + // start a local npm proxy and publish the current codebase to the proxy + await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); + await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); + + // install package manager + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-classic') { + await execa('npm', ['install', '-g', 'yarn'], { stdio: 'inherit' }); + } else if (PACKAGE_MANAGER_EXECUTABLE === 'pnpm') { + await execa('npm', ['install', '-g', PACKAGE_MANAGER_EXECUTABLE], { + stdio: 'inherit', + }); + } + + // nuke the npx cache to ensure we are installing packages from the npm proxy + if (PACKAGE_MANAGER_EXECUTABLE !== 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable + ); + } + + // Force 'create-amplify' installation in npx cache by executing help command + // before tests run. Otherwise, installing 'create-amplify' concurrently + // may lead to race conditions and corrupted npx cache. + await execa( + packageManagerExecutable, + [ + 'create', + 'amplify', + ...(PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern' + ? [] + : ['--yes', '--']), + '--help', + ], + { // Command must run outside of 'amplify-backend' workspace. cwd: os.homedir(), stdio: 'inherit', - }); - }); + } + ); + }); - after(async () => { - // stop the npm proxy - await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); - }); + after(async () => { + // stop the npm proxy + await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); + }); + + const initialStates = ['empty', 'module', 'commonjs'] as const; + + initialStates.forEach((initialState) => { + void describe('installs expected packages and scaffolds expected files', () => { + let tempDir: string; + beforeEach(async () => { + tempDir = await fs.mkdtemp( + path.join(os.tmpdir(), 'test-create-amplify') + ); + + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir + ); + } + }); - const initialStates = ['empty', 'module', 'commonjs'] as const; + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + }); - initialStates.forEach((initialState) => { - void describe('installs expected packages and scaffolds expected files', () => { - let tempDir: string; - beforeEach(async () => { - tempDir = await fs.mkdtemp( - path.join(os.tmpdir(), 'test-create-amplify') + void it(`starting from ${initialState} project`, async () => { + if (initialState != 'empty') { + await fs.writeFile( + path.join(tempDir, 'package.json'), + JSON.stringify( + { + name: 'test_name', + version: '0.0.1', + type: initialState, + }, + null, + 2 + ) ); + } + + await execa(packageManagerExecutable, ['create', 'amplify', '--yes'], { + cwd: tempDir, + stdio: 'inherit', }); + const packageJsonPath = path.resolve(tempDir, 'package.json'); + const packageJsonObject = JSON.parse( + await fs.readFile(packageJsonPath, 'utf-8') + ); - afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); + assert.deepStrictEqual( + Object.keys(packageJsonObject.devDependencies).sort(), + ['@aws-amplify/backend', '@aws-amplify/backend-cli', 'typescript'] + ); + + assert.deepStrictEqual( + Object.keys(packageJsonObject.dependencies).sort(), + ['aws-amplify'] + ); + + const gitIgnorePath = path.resolve(tempDir, '.gitignore'); + const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) + .split(os.EOL) + .filter((s) => s.trim()); + const expectedGitIgnoreContent = [ + '# amplify', + '.amplify', + 'amplifyconfiguration*', + 'node_modules', + ]; + + expectedGitIgnoreContent.forEach((line) => { + assert.ok(gitIgnoreContent.includes(line)); }); - void it(`starting from ${initialState} project`, async () => { - if (initialState != 'empty') { - await fs.writeFile( - path.join(tempDir, 'package.json'), - JSON.stringify( - { - name: 'test_name', - version: '0.0.1', - type: initialState, - }, - null, - 2 - ) - ); - } + const amplifyPathPrefix = path.join(tempDir, 'amplify'); - await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, + // Read tsconfig.json content, remove all comments, and make assertions + const tsConfigPath = path.resolve(amplifyPathPrefix, 'tsconfig.json'); + const tsConfigContent = ( + await fs.readFile(tsConfigPath, 'utf-8') + ).replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); + const tsConfigObject = JSON.parse(tsConfigContent); + + assert.equal(tsConfigObject.compilerOptions.module, 'node16'); + assert.equal(tsConfigObject.compilerOptions.resolveJsonModule, true); + + const pathPrefix = path.join(tempDir, 'amplify'); + + const files = await glob(path.join(amplifyPathPrefix, '**', '*'), { + // eslint-disable-next-line spellcheck/spell-checker + nodir: true, + windowsPathsNoEscape: true, + ignore: ['**/node_modules/**', '**/yarn.lock'], + }); + + const expectedAmplifyFiles = [ + path.join('auth', 'resource.ts'), + 'backend.ts', + path.join('data', 'resource.ts'), + 'package.json', + 'tsconfig.json', + ]; + + assert.deepStrictEqual( + files.sort(), + expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) + ); + + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await execa('yarn', ['config', 'set', 'nodeLinker', 'node-modules'], { + cwd: `${tempDir}/amplify`, stdio: 'inherit', }); - const packageJsonPath = path.resolve(tempDir, 'package.json'); - const packageJsonObject = JSON.parse( - await fs.readFile(packageJsonPath, 'utf-8') - ); - assert.deepStrictEqual( - Object.keys(packageJsonObject.devDependencies).sort(), - ['@aws-amplify/backend', '@aws-amplify/backend-cli', 'typescript'] + await fs.appendFile( + path.join(tempDir, '.yarnrc.yml'), + `pnpIgnorePatterns:\n - ./nm-packages/**` ); + await execa('yarn', ['install'], { + cwd: tempDir, + stdin: 'inherit', + }); + await execa('yarn', ['add', '@aws-amplify/backend'], { + cwd: `${tempDir}/amplify`, + stdio: 'inherit', + }); + } - assert.deepStrictEqual( - Object.keys(packageJsonObject.dependencies).sort(), - ['aws-amplify'] - ); + // assert that project compiles successfully + await execa( + packageManagerExecutable === 'npm' + ? 'npx' + : packageManagerExecutable.startsWith('yarn') + ? 'yarn' + : packageManagerExecutable, + [ + 'tsc', + '--noEmit', + '--skipLibCheck', + // pointing the project arg to the amplify backend directory will use the tsconfig present in that directory + '--project', + amplifyPathPrefix, + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); - const gitIgnorePath = path.resolve(tempDir, '.gitignore'); - const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) - .split(os.EOL) - .filter((s) => s.trim()); - assert.deepStrictEqual(gitIgnoreContent.sort(), [ - '# amplify', - '.amplify', - 'amplifyconfiguration*', - 'node_modules', - ]); - - const amplifyPathPrefix = path.join(tempDir, 'amplify'); - - // Read tsconfig.json content, remove all comments, and make assertions - const tsConfigPath = path.resolve(amplifyPathPrefix, 'tsconfig.json'); - const tsConfigContent = ( - await fs.readFile(tsConfigPath, 'utf-8') - ).replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); - const tsConfigObject = JSON.parse(tsConfigContent); - - assert.equal(tsConfigObject.compilerOptions.module, 'node16'); - assert.equal(tsConfigObject.compilerOptions.resolveJsonModule, true); - - const pathPrefix = path.join(tempDir, 'amplify'); - - const files = await glob(path.join(amplifyPathPrefix, '**', '*'), { - // eslint-disable-next-line spellcheck/spell-checker - nodir: true, - windowsPathsNoEscape: true, + if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { + await execa('yarn', ['add', 'aws-cdk', 'aws-cdk-lib', 'constructs'], { + cwd: tempDir, + stdio: 'inherit', }); + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await execa( + 'yarn', + [ + 'add', + '-D', + 'tsx', + 'graphql', + 'pluralize', + 'zod', + '@aws-amplify/platform-core', + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); - const expectedAmplifyFiles = [ - path.join('auth', 'resource.ts'), - 'backend.ts', - path.join('data', 'resource.ts'), - 'package.json', - 'tsconfig.json', - ]; - - assert.deepStrictEqual( - files.sort(), - expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) - ); - - // assert that project compiles successfully - await execa( - 'npx', - [ - 'tsc', - '--noEmit', - '--skipLibCheck', - // pointing the project arg to the amplify backend directory will use the tsconfig present in that directory - '--project', - amplifyPathPrefix, - ], - { + await execa('node', ['--version'], { cwd: tempDir, - stdio: 'inherit', - } - ); + }); + } + } - // assert that project synthesizes successfully - await execa( - 'npx', - [ - 'cdk', - 'synth', - '--context', - `amplify-backend-namespace=123`, - '--context', - `amplify-backend-name=sandboxName`, - '--context', - `amplify-backend-type=sandbox`, - '--app', - "'npx tsx amplify/backend.ts'", - '--quiet', - ], - { - cwd: tempDir, - stdio: 'inherit', - } - ); - }); + // assert that project synthesizes successfully + await execa( + packageManagerExecutable === 'npm' ? 'npx' : packageManagerExecutable, + [ + 'cdk', + 'synth', + '--context', + `amplify-backend-namespace=123`, + '--context', + `amplify-backend-name=sandboxName`, + '--context', + `amplify-backend-type=sandbox`, + '--app', + "'npx tsx amplify/backend.ts'", + '--quiet', + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); }); }); + }); - void describe('fails fast', () => { - let tempDir: string; - beforeEach(async () => { - tempDir = await fs.mkdtemp( - path.join(os.tmpdir(), 'test-create-amplify') + void describe('fails fast', () => { + let tempDir: string; + beforeEach(async () => { + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); + + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir ); - }); + } + }); - afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); - }); + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + }); - void it('if amplify path already exists', async () => { - const amplifyDirPath = path.join(tempDir, 'amplify'); - await fs.mkdir(amplifyDirPath, { recursive: true }); + void it('if amplify path already exists', async () => { + const amplifyDirPath = path.join(tempDir, 'amplify'); + await fs.mkdir(amplifyDirPath, { recursive: true }); - const result = await execa('npm', ['create', 'amplify', '--yes'], { + const result = await execa( + packageManagerExecutable, + ['create', 'amplify', '--yes'], + { cwd: tempDir, stdio: 'pipe', reject: false, - }); - assert.equal(result.exitCode, 1); - assert.ok( - result.stderr - .toLocaleString() - .includes( - 'If you are trying to run an Amplify (Gen 2) command inside an Amplify (Gen 1) project we recommend creating the project in another directory' - ) - ); - }); + } + ); + assert.equal(result.exitCode, 1); + assert.ok( + result.stderr + .toLocaleString() + .includes( + 'If you are trying to run an Amplify (Gen 2) command inside an Amplify (Gen 1) project we recommend creating the project in another directory' + ) + ); }); - } -); + }); +}); From 4c77c70062a84e5ad2ee242e7394b03101c8174c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Tue, 19 Dec 2023 16:34:07 -0800 Subject: [PATCH 08/30] fix(create_amplify.test): after merge main --- .../src/test-e2e/create_amplify.test.ts | 210 ++++++++++++++++-- 1 file changed, 191 insertions(+), 19 deletions(-) diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index 7d051391257..4afd860cedd 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -8,31 +8,118 @@ import assert from 'assert'; import { glob } from 'glob'; import { testConcurrencyLevel } from './test_concurrency.js'; +type PackageManagerExecutable = 'npm' | 'yarn-classic' | 'yarn-modern' | 'pnpm'; + +const concurrency = process.env.PACKAGE_MANAGER_EXECUTABLE?.startsWith('yarn') + ? 1 + : testConcurrencyLevel; + +const packageManagerSetup = async ( + packageManagerExecutable: PackageManagerExecutable, + dir?: string +) => { + const execaOptions = { + cwd: dir || os.homedir(), + stdio: 'inherit' as const, + }; + + if (packageManagerExecutable === 'npm') { + // nuke the npx cache to ensure we are installing packages from the npm proxy + const { stdout } = await execa('npm', ['config', 'get', 'cache']); + const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); + + if (existsSync(npxCacheLocation)) { + await fs.rm(npxCacheLocation, { recursive: true }); + } + } else if (packageManagerExecutable.startsWith('yarn')) { + if (packageManagerExecutable === 'yarn-modern') { + await execa('corepack', ['enable'], execaOptions); + await execa('yarn', ['init', '-2'], execaOptions); + + await execa( + 'yarn', + ['config', 'set', 'npmRegistryServer', 'http://localhost:4873'], + execaOptions + ); + await execa( + 'yarn', + ['config', 'set', 'unsafeHttpWhitelist', 'localhost'], + execaOptions + ); + } else { + await execa( + 'yarn', + ['config', 'set', 'registry', 'http://localhost:4873'], + execaOptions + ); + await execa('yarn', ['config', 'get', 'registry'], execaOptions); + } + await execa('yarn', ['cache', 'clean'], execaOptions); + } else if (packageManagerExecutable === 'pnpm') { + await execa(packageManagerExecutable, ['--version']); + await execa(packageManagerExecutable, [ + 'config', + 'set', + 'registry', + 'http://localhost:4873', + ]); + await execa(packageManagerExecutable, ['config', 'get', 'registry']); + + await execa(packageManagerExecutable, ['store', 'clear']); + } +}; + void describe( 'create-amplify script', { concurrency: testConcurrencyLevel }, () => { + const { PACKAGE_MANAGER_EXECUTABLE = 'npm' } = process.env; + const packageManagerExecutable = PACKAGE_MANAGER_EXECUTABLE.startsWith( + 'yarn' + ) + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE; + before(async () => { // start a local npm proxy and publish the current codebase to the proxy await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); - // nuke the npx cache to ensure we are installing packages from the npm proxy - const { stdout } = await execa('npm', ['config', 'get', 'cache']); - const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); + // install package manager + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-classic') { + await execa('npm', ['install', '-g', 'yarn'], { stdio: 'inherit' }); + } else if (PACKAGE_MANAGER_EXECUTABLE === 'pnpm') { + await execa('npm', ['install', '-g', PACKAGE_MANAGER_EXECUTABLE], { + stdio: 'inherit', + }); + } - if (existsSync(npxCacheLocation)) { - await fs.rm(npxCacheLocation, { recursive: true }); + // nuke the npx cache to ensure we are installing packages from the npm proxy + if (PACKAGE_MANAGER_EXECUTABLE !== 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable + ); } // Force 'create-amplify' installation in npx cache by executing help command // before tests run. Otherwise, installing 'create-amplify' concurrently // may lead to race conditions and corrupted npx cache. - await execa('npm', ['create', 'amplify', '--yes', '--', '--help'], { - // Command must run outside of 'amplify-backend' workspace. - cwd: os.homedir(), - stdio: 'inherit', - }); + await execa( + packageManagerExecutable, + [ + 'create', + 'amplify', + ...(PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern' + ? [] + : ['--yes', '--']), + '--help', + ], + { + // Command must run outside of 'amplify-backend' workspace. + cwd: os.homedir(), + stdio: 'inherit', + } + ); }); after(async () => { @@ -49,6 +136,13 @@ void describe( tempDir = await fs.mkdtemp( path.join(os.tmpdir(), 'test-create-amplify') ); + + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir + ); + } }); afterEach(async () => { @@ -94,12 +188,16 @@ void describe( const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) .split(os.EOL) .filter((s) => s.trim()); - assert.deepStrictEqual(gitIgnoreContent.sort(), [ + const expectedGitIgnoreContent = [ '# amplify', '.amplify', 'amplifyconfiguration*', 'node_modules', - ]); + ]; + + expectedGitIgnoreContent.forEach((line) => { + assert.ok(gitIgnoreContent.includes(line)); + }); const amplifyPathPrefix = path.join(tempDir, 'amplify'); @@ -138,9 +236,37 @@ void describe( expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) ); + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await execa( + 'yarn', + ['config', 'set', 'nodeLinker', 'node-modules'], + { + cwd: `${tempDir}/amplify`, + stdio: 'inherit', + } + ); + + await fs.appendFile( + path.join(tempDir, '.yarnrc.yml'), + `pnpIgnorePatterns:\n - ./nm-packages/**` + ); + await execa('yarn', ['install'], { + cwd: tempDir, + stdin: 'inherit', + }); + await execa('yarn', ['add', '@aws-amplify/backend'], { + cwd: `${tempDir}/amplify`, + stdio: 'inherit', + }); + } + // assert that project compiles successfully await execa( - 'npx', + packageManagerExecutable === 'npm' + ? 'npx' + : packageManagerExecutable.startsWith('yarn') + ? 'yarn' + : packageManagerExecutable, [ 'tsc', '--noEmit', @@ -155,9 +281,44 @@ void describe( } ); + if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { + await execa( + 'yarn', + ['add', 'aws-cdk', 'aws-cdk-lib', 'constructs'], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await execa( + 'yarn', + [ + 'add', + '-D', + 'tsx', + 'graphql', + 'pluralize', + 'zod', + '@aws-amplify/platform-core', + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + + await execa('node', ['--version'], { + cwd: tempDir, + }); + } + } + // assert that project synthesizes successfully await execa( - 'npx', + packageManagerExecutable === 'npm' + ? 'npx' + : packageManagerExecutable, [ 'cdk', 'synth', @@ -186,6 +347,13 @@ void describe( tempDir = await fs.mkdtemp( path.join(os.tmpdir(), 'test-create-amplify') ); + + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir + ); + } }); afterEach(async () => { @@ -196,11 +364,15 @@ void describe( const amplifyDirPath = path.join(tempDir, 'amplify'); await fs.mkdir(amplifyDirPath, { recursive: true }); - const result = await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, - stdio: 'pipe', - reject: false, - }); + const result = await execa( + packageManagerExecutable, + ['create', 'amplify', '--yes'], + { + cwd: tempDir, + stdio: 'pipe', + reject: false, + } + ); assert.equal(result.exitCode, 1); assert.ok( result.stderr From 0413a9ed94ea6d22d162a6d3ca740c918f04c770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Tue, 19 Dec 2023 18:50:07 -0800 Subject: [PATCH 09/30] fix the concurrency for yarn classic and modern, and fix expect --- .../src/test-e2e/create_amplify.test.ts | 525 +++++++++--------- 1 file changed, 254 insertions(+), 271 deletions(-) diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index 4afd860cedd..44515f2ea8a 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -69,319 +69,302 @@ const packageManagerSetup = async ( } }; -void describe( - 'create-amplify script', - { concurrency: testConcurrencyLevel }, - () => { - const { PACKAGE_MANAGER_EXECUTABLE = 'npm' } = process.env; - const packageManagerExecutable = PACKAGE_MANAGER_EXECUTABLE.startsWith( - 'yarn' - ) - ? 'yarn' - : PACKAGE_MANAGER_EXECUTABLE; - - before(async () => { - // start a local npm proxy and publish the current codebase to the proxy - await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); - await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); - - // install package manager - if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-classic') { - await execa('npm', ['install', '-g', 'yarn'], { stdio: 'inherit' }); - } else if (PACKAGE_MANAGER_EXECUTABLE === 'pnpm') { - await execa('npm', ['install', '-g', PACKAGE_MANAGER_EXECUTABLE], { - stdio: 'inherit', - }); - } +void describe('create-amplify script', { concurrency: concurrency }, () => { + const { PACKAGE_MANAGER_EXECUTABLE = 'npm' } = process.env; + const packageManagerExecutable = PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') + ? 'yarn' + : PACKAGE_MANAGER_EXECUTABLE; + + before(async () => { + // start a local npm proxy and publish the current codebase to the proxy + await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); + await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); + + // install package manager + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-classic') { + await execa('npm', ['install', '-g', 'yarn'], { stdio: 'inherit' }); + } else if (PACKAGE_MANAGER_EXECUTABLE === 'pnpm') { + await execa('npm', ['install', '-g', PACKAGE_MANAGER_EXECUTABLE], { + stdio: 'inherit', + }); + } - // nuke the npx cache to ensure we are installing packages from the npm proxy - if (PACKAGE_MANAGER_EXECUTABLE !== 'yarn-modern') { - await packageManagerSetup( - PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable - ); + // nuke the npx cache to ensure we are installing packages from the npm proxy + if (PACKAGE_MANAGER_EXECUTABLE !== 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable + ); + } + + // Force 'create-amplify' installation in npx cache by executing help command + // before tests run. Otherwise, installing 'create-amplify' concurrently + // may lead to race conditions and corrupted npx cache. + await execa( + packageManagerExecutable, + [ + 'create', + 'amplify', + ...(PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern' + ? [] + : ['--yes', '--']), + '--help', + ], + { + // Command must run outside of 'amplify-backend' workspace. + cwd: os.homedir(), + stdio: 'inherit', } + ); + }); - // Force 'create-amplify' installation in npx cache by executing help command - // before tests run. Otherwise, installing 'create-amplify' concurrently - // may lead to race conditions and corrupted npx cache. - await execa( - packageManagerExecutable, - [ - 'create', - 'amplify', - ...(PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern' - ? [] - : ['--yes', '--']), - '--help', - ], - { - // Command must run outside of 'amplify-backend' workspace. - cwd: os.homedir(), - stdio: 'inherit', - } - ); - }); + after(async () => { + // stop the npm proxy + await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); + }); - after(async () => { - // stop the npm proxy - await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); - }); + const initialStates = ['empty', 'module', 'commonjs'] as const; - const initialStates = ['empty', 'module', 'commonjs'] as const; + initialStates.forEach((initialState) => { + void describe('installs expected packages and scaffolds expected files', () => { + let tempDir: string; + beforeEach(async () => { + tempDir = await fs.mkdtemp( + path.join(os.tmpdir(), 'test-create-amplify') + ); - initialStates.forEach((initialState) => { - void describe('installs expected packages and scaffolds expected files', () => { - let tempDir: string; - beforeEach(async () => { - tempDir = await fs.mkdtemp( - path.join(os.tmpdir(), 'test-create-amplify') + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir ); + } + }); - if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { - await packageManagerSetup( - PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, - tempDir - ); - } - }); + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + }); + + void it(`starting from ${initialState} project`, async () => { + if (initialState != 'empty') { + await fs.writeFile( + path.join(tempDir, 'package.json'), + JSON.stringify( + { + name: 'test_name', + version: '0.0.1', + type: initialState, + }, + null, + 2 + ) + ); + } - afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); + await execa('npm', ['create', 'amplify', '--yes'], { + cwd: tempDir, + stdio: 'inherit', }); + const packageJsonPath = path.resolve(tempDir, 'package.json'); + const packageJsonObject = JSON.parse( + await fs.readFile(packageJsonPath, 'utf-8') + ); - void it(`starting from ${initialState} project`, async () => { - if (initialState != 'empty') { - await fs.writeFile( - path.join(tempDir, 'package.json'), - JSON.stringify( - { - name: 'test_name', - version: '0.0.1', - type: initialState, - }, - null, - 2 - ) - ); - } + assert.deepStrictEqual( + Object.keys(packageJsonObject.devDependencies).sort(), + ['@aws-amplify/backend', '@aws-amplify/backend-cli', 'typescript'] + ); - await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, - stdio: 'inherit', - }); - const packageJsonPath = path.resolve(tempDir, 'package.json'); - const packageJsonObject = JSON.parse( - await fs.readFile(packageJsonPath, 'utf-8') - ); + assert.deepStrictEqual( + Object.keys(packageJsonObject.dependencies).sort(), + ['aws-amplify'] + ); - assert.deepStrictEqual( - Object.keys(packageJsonObject.devDependencies).sort(), - ['@aws-amplify/backend', '@aws-amplify/backend-cli', 'typescript'] - ); + const gitIgnorePath = path.resolve(tempDir, '.gitignore'); + const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) + .split(os.EOL) + .filter((s) => s.trim()); + const expectedGitIgnoreContent = [ + '# amplify', + '.amplify', + 'amplifyconfiguration*', + 'node_modules', + ]; + + expectedGitIgnoreContent.forEach((line) => { + assert.ok(gitIgnoreContent.includes(line)); + }); - assert.deepStrictEqual( - Object.keys(packageJsonObject.dependencies).sort(), - ['aws-amplify'] - ); + const amplifyPathPrefix = path.join(tempDir, 'amplify'); - const gitIgnorePath = path.resolve(tempDir, '.gitignore'); - const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) - .split(os.EOL) - .filter((s) => s.trim()); - const expectedGitIgnoreContent = [ - '# amplify', - '.amplify', - 'amplifyconfiguration*', - 'node_modules', - ]; - - expectedGitIgnoreContent.forEach((line) => { - assert.ok(gitIgnoreContent.includes(line)); - }); + // Read tsconfig.json content, remove all comments, and make assertions + const tsConfigPath = path.resolve(amplifyPathPrefix, 'tsconfig.json'); + const tsConfigContent = ( + await fs.readFile(tsConfigPath, 'utf-8') + ).replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); + const tsConfigObject = JSON.parse(tsConfigContent); - const amplifyPathPrefix = path.join(tempDir, 'amplify'); + assert.equal(tsConfigObject.compilerOptions.module, 'es2022'); + assert.equal( + tsConfigObject.compilerOptions.moduleResolution, + 'bundler' + ); + assert.equal(tsConfigObject.compilerOptions.resolveJsonModule, true); - // Read tsconfig.json content, remove all comments, and make assertions - const tsConfigPath = path.resolve(amplifyPathPrefix, 'tsconfig.json'); - const tsConfigContent = ( - await fs.readFile(tsConfigPath, 'utf-8') - ).replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); - const tsConfigObject = JSON.parse(tsConfigContent); + const pathPrefix = path.join(tempDir, 'amplify'); - assert.equal(tsConfigObject.compilerOptions.module, 'es2022'); - assert.equal( - tsConfigObject.compilerOptions.moduleResolution, - 'bundler' - ); - assert.equal(tsConfigObject.compilerOptions.resolveJsonModule, true); + const files = await glob(path.join(amplifyPathPrefix, '**', '*'), { + // eslint-disable-next-line spellcheck/spell-checker + nodir: true, + windowsPathsNoEscape: true, + ignore: ['**/node_modules/**', '**/yarn.lock'], + }); - const pathPrefix = path.join(tempDir, 'amplify'); + const expectedAmplifyFiles = [ + path.join('auth', 'resource.ts'), + 'backend.ts', + path.join('data', 'resource.ts'), + 'package.json', + 'tsconfig.json', + ]; + + assert.deepStrictEqual( + files.sort(), + expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) + ); - const files = await glob(path.join(amplifyPathPrefix, '**', '*'), { - // eslint-disable-next-line spellcheck/spell-checker - nodir: true, - windowsPathsNoEscape: true, + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await execa('yarn', ['config', 'set', 'nodeLinker', 'node-modules'], { + cwd: `${tempDir}/amplify`, + stdio: 'inherit', }); - const expectedAmplifyFiles = [ - path.join('auth', 'resource.ts'), - 'backend.ts', - path.join('data', 'resource.ts'), - 'package.json', - 'tsconfig.json', - ]; - - assert.deepStrictEqual( - files.sort(), - expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) + await fs.appendFile( + path.join(tempDir, '.yarnrc.yml'), + `pnpIgnorePatterns:\n - ./nm-packages/**` ); + await execa('yarn', ['install'], { + cwd: tempDir, + stdin: 'inherit', + }); + await execa('yarn', ['add', '@aws-amplify/backend'], { + cwd: `${tempDir}/amplify`, + stdio: 'inherit', + }); + } + // assert that project compiles successfully + await execa( + packageManagerExecutable === 'npm' + ? 'npx' + : packageManagerExecutable.startsWith('yarn') + ? 'yarn' + : packageManagerExecutable, + [ + 'tsc', + '--noEmit', + '--skipLibCheck', + // pointing the project arg to the amplify backend directory will use the tsconfig present in that directory + '--project', + amplifyPathPrefix, + ], + { + cwd: tempDir, + stdio: 'inherit', + } + ); + + if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { + await execa('yarn', ['add', 'aws-cdk', 'aws-cdk-lib', 'constructs'], { + cwd: tempDir, + stdio: 'inherit', + }); if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { await execa( 'yarn', - ['config', 'set', 'nodeLinker', 'node-modules'], + [ + 'add', + '-D', + 'tsx', + 'graphql', + 'pluralize', + 'zod', + '@aws-amplify/platform-core', + ], { - cwd: `${tempDir}/amplify`, + cwd: tempDir, stdio: 'inherit', } ); - await fs.appendFile( - path.join(tempDir, '.yarnrc.yml'), - `pnpIgnorePatterns:\n - ./nm-packages/**` - ); - await execa('yarn', ['install'], { + await execa('node', ['--version'], { cwd: tempDir, - stdin: 'inherit', - }); - await execa('yarn', ['add', '@aws-amplify/backend'], { - cwd: `${tempDir}/amplify`, - stdio: 'inherit', }); } + } - // assert that project compiles successfully - await execa( - packageManagerExecutable === 'npm' - ? 'npx' - : packageManagerExecutable.startsWith('yarn') - ? 'yarn' - : packageManagerExecutable, - [ - 'tsc', - '--noEmit', - '--skipLibCheck', - // pointing the project arg to the amplify backend directory will use the tsconfig present in that directory - '--project', - amplifyPathPrefix, - ], - { - cwd: tempDir, - stdio: 'inherit', - } - ); - - if (PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn')) { - await execa( - 'yarn', - ['add', 'aws-cdk', 'aws-cdk-lib', 'constructs'], - { - cwd: tempDir, - stdio: 'inherit', - } - ); - if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { - await execa( - 'yarn', - [ - 'add', - '-D', - 'tsx', - 'graphql', - 'pluralize', - 'zod', - '@aws-amplify/platform-core', - ], - { - cwd: tempDir, - stdio: 'inherit', - } - ); - - await execa('node', ['--version'], { - cwd: tempDir, - }); - } + // assert that project synthesizes successfully + await execa( + packageManagerExecutable === 'npm' ? 'npx' : packageManagerExecutable, + [ + 'cdk', + 'synth', + '--context', + `amplify-backend-namespace=123`, + '--context', + `amplify-backend-name=sandboxName`, + '--context', + `amplify-backend-type=sandbox`, + '--app', + "'npx tsx amplify/backend.ts'", + '--quiet', + ], + { + cwd: tempDir, + stdio: 'inherit', } - - // assert that project synthesizes successfully - await execa( - packageManagerExecutable === 'npm' - ? 'npx' - : packageManagerExecutable, - [ - 'cdk', - 'synth', - '--context', - `amplify-backend-namespace=123`, - '--context', - `amplify-backend-name=sandboxName`, - '--context', - `amplify-backend-type=sandbox`, - '--app', - "'npx tsx amplify/backend.ts'", - '--quiet', - ], - { - cwd: tempDir, - stdio: 'inherit', - } - ); - }); + ); }); }); + }); - void describe('fails fast', () => { - let tempDir: string; - beforeEach(async () => { - tempDir = await fs.mkdtemp( - path.join(os.tmpdir(), 'test-create-amplify') - ); + void describe('fails fast', () => { + let tempDir: string; + beforeEach(async () => { + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); - if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { - await packageManagerSetup( - PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, - tempDir - ); - } - }); + if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { + await packageManagerSetup( + PACKAGE_MANAGER_EXECUTABLE as PackageManagerExecutable, + tempDir + ); + } + }); - afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); - }); + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + }); - void it('if amplify path already exists', async () => { - const amplifyDirPath = path.join(tempDir, 'amplify'); - await fs.mkdir(amplifyDirPath, { recursive: true }); + void it('if amplify path already exists', async () => { + const amplifyDirPath = path.join(tempDir, 'amplify'); + await fs.mkdir(amplifyDirPath, { recursive: true }); - const result = await execa( - packageManagerExecutable, - ['create', 'amplify', '--yes'], - { - cwd: tempDir, - stdio: 'pipe', - reject: false, - } - ); - assert.equal(result.exitCode, 1); - assert.ok( - result.stderr - .toLocaleString() - .includes( - 'If you are trying to run an Amplify (Gen 2) command inside an Amplify (Gen 1) project we recommend creating the project in another directory' - ) - ); - }); + const result = await execa( + packageManagerExecutable, + ['create', 'amplify', '--yes'], + { + cwd: tempDir, + stdio: 'pipe', + reject: false, + } + ); + assert.equal(result.exitCode, 1); + assert.ok( + result.stderr + .toLocaleString() + .includes( + 'If you are trying to run an Amplify (Gen 2) command inside an Amplify (Gen 1) project we recommend creating the project in another directory' + ) + ); }); - } -); + }); +}); From 548f9d19ab12bb4165577bcf9ac2aec4e9b5d0a9 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Wed, 27 Dec 2023 09:49:09 -0800 Subject: [PATCH 10/30] feat: package manager support create amplify (#793) * chore: update package.lock * init * feat: dynamically get package manager * chore: change workflow trigger * chore: change workflow trigger * chore: rename npm functions * chore: update output log * fix: pnpm cache clear command * chore: refactor packageManager * fix: remove pnpm store * chore: create package_manager file * chore: change workflow trigger * chore: refactor PackageManager Controller and Initializer * fix: update types * chore: refactor to use factory * chore: remove try catch from the controllers * chore: change type * chore: use abstract class * fix tests * fix: PackageManagerBase * chore: refactor PackageManagerControllerFactory * chore: refactor packageJsonExists * chore: cleanup code * fix: projectJsonExists * remove package_manager file * chore: refactor package_manager props into package manager controllers * chore: rename packageManagerControllerFactory * chore: make projectRoot, userAgent, getPackageManagerName private * chore: refactor ensureInitialized * chore: refactor PackageManagerController to extend PackageManagerControllerFactory * Revert "chore: refactor PackageManagerController to extend PackageManagerControllerFactory" This reverts commit 7ddc64f02987a7bfd3f208d9c977f3d2a87b3cbf. * chore: refactor to inject PackageManagerControllerFactory to xPackageManagerController * chore: move initialProjectFileGenerator to packageManagerController * fix: initializeAMplifyFolder * fix: generateInitialProjectFiles * fix: template path * chore: refactor getPackageManagerController yarn-modern * chore: create getWelcomeMessage * Revert "chore: refactor getPackageManagerController yarn-modern" This reverts commit 28da8a9e40911413beb566d5f730063622843eab. * chore: refactor generateInitialProjectFiles for yarn-modern * chore: cleanup code * chore: remove PackageManagerControllerFactory index * chore: remove ensureInitialized * Revert "chore: remove ensureInitialized" This reverts commit 96483ce96b6d64173fc2225cd0a4d9768cb16d30. * Revert "Revert "chore: remove ensureInitialized"" This reverts commit 7c59c80cc0b1db6cb448d01be2d845243c223f45. * temp: add initializeProject to PackageManagerController * temp: revert InitialProjectFileGenerator * fix: InitialProjectFileGenerator * test: restore initial_project_file_generator * move installDependencies and getWelcomeMessage to PackageManagerController * add addLockFile * add JSDocs and resolve some review comments * fix: create_amplify.test * chore: add addTypescript * chore: refactor generateInitialProjectFiles * Update packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts Co-authored-by: Edward Foyle * chore: refactor generateInitialProjectFiles again * chore: refactor welcomeMessage * test: add package_manager_controller_factory * test: fix test types * chore: comments update * chore: handle process.env.npm_config_user_agent undefined * chore: move addLockFile and addTypescript into initializeTsConfig * test: refactor packageManagerControllerFactory * fix: yarn initializeTsConfig * fix: yarn modern initializeTsConfig * fix: amplify_project_creator test * chore: refactor contructor * chore: update package.lock * fix: pnpm init, remove --debug, etc * test: add test for NpmPackageManagerController * fix build error * chore: refactor NpmPackageManagerController * test: add test for xPackageManagerController * chore: convert fs to fsp * fix yarn modern --------- Co-authored-by: Edward Foyle --- .eslint_dictionary.json | 1 + package-lock.json | 86 +++++----- .../src/amplify_project_creator.test.ts | 36 +++-- .../src/amplify_project_creator.ts | 31 ++-- packages/create-amplify/src/create_amplify.ts | 23 ++- .../create-amplify/src/execute_with_logger.ts | 2 +- .../initial_project_file_generator.test.ts | 1 + .../src/initial_project_file_generator.ts | 77 ++------- .../npm_package_manager_controller.test.ts | 67 -------- .../src/npm_package_manager_controller.ts | 54 ------- .../src/npm_project_initializer.test.ts | 69 -------- .../src/npm_project_initializer.ts | 66 -------- .../npm_package_manager_controller.test.ts | 138 ++++++++++++++++ .../npm_package_manager_controller.ts | 36 +++++ .../package_manager_controller.ts | 121 ++++++++++++++ ...package_manager_controller_factory.test.ts | 57 +++++++ .../package_manager_controller_factory.ts | 58 +++++++ .../pnpm_package_manager_controller.test.ts | 138 ++++++++++++++++ .../pnpm_package_manager_controller.ts | 36 +++++ ...classic_package_manager_controller.test.ts | 143 +++++++++++++++++ ...yarn_classic_package_manager_controller.ts | 53 +++++++ ..._modern_package_manager_controller.test.ts | 147 ++++++++++++++++++ .../yarn_modern_package_manager_controller.ts | 70 +++++++++ .../src/package_manager_controller.ts | 8 - .../src/project_root_validator.ts | 2 +- .../src/test-e2e/create_amplify.test.ts | 30 ++-- 26 files changed, 1122 insertions(+), 428 deletions(-) delete mode 100644 packages/create-amplify/src/npm_package_manager_controller.test.ts delete mode 100644 packages/create-amplify/src/npm_package_manager_controller.ts delete mode 100644 packages/create-amplify/src/npm_project_initializer.test.ts delete mode 100644 packages/create-amplify/src/npm_project_initializer.ts create mode 100644 packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts create mode 100644 packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts create mode 100644 packages/create-amplify/src/package-manager-controller/package_manager_controller.ts create mode 100644 packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts create mode 100644 packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts create mode 100644 packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts create mode 100644 packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts create mode 100644 packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts create mode 100644 packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts create mode 100644 packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts create mode 100644 packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts delete mode 100644 packages/create-amplify/src/package_manager_controller.ts diff --git a/.eslint_dictionary.json b/.eslint_dictionary.json index 199d3fe6136..79192b93327 100644 --- a/.eslint_dictionary.json +++ b/.eslint_dictionary.json @@ -83,6 +83,7 @@ "passthrough", "pathname", "pipelined", + "pnpm", "posix", "readdir", "readline", diff --git a/package-lock.json b/package-lock.json index 38558f3e532..06b828ac86e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21375,12 +21375,12 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.4.3", + "version": "0.4.4", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/plugin-types": "^0.6.0", "@aws-sdk/util-arn-parser": "^3.465.0" }, "peerDependencies": { @@ -21401,19 +21401,19 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.6.0", + "version": "0.7.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.3.6", - "@aws-amplify/backend-data": "^0.8.3", - "@aws-amplify/backend-function": "^0.3.0", + "@aws-amplify/backend-auth": "^0.3.7", + "@aws-amplify/backend-data": "^0.9.0", + "@aws-amplify/backend-function": "^0.4.0", "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/backend-secret": "^0.3.2", - "@aws-amplify/backend-storage": "^0.3.2", + "@aws-amplify/backend-secret": "^0.3.3", + "@aws-amplify/backend-storage": "^0.4.0", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.2", - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/platform-core": "^0.3.3", + "@aws-amplify/plugin-types": "^0.6.0", "@aws-sdk/client-amplify": "^3.440.0" }, "devDependencies": { @@ -21427,16 +21427,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.3.6", + "version": "0.3.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.4.3", + "@aws-amplify/auth-construct-alpha": "^0.4.4", "@aws-amplify/backend-output-storage": "0.2.6", - "@aws-amplify/plugin-types": "^0.5.0" + "@aws-amplify/plugin-types": "^0.6.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.2" + "@aws-amplify/platform-core": "^0.3.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21445,19 +21445,19 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.8.3", + "version": "0.9.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "0.2.6", "@aws-amplify/data-construct": "^1.4.1", "@aws-amplify/data-schema-types": "^0.6.6", - "@aws-amplify/plugin-types": "^0.5.0" + "@aws-amplify/plugin-types": "^0.6.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.2" + "@aws-amplify/platform-core": "^0.3.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21466,11 +21466,11 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.4.1", + "version": "0.4.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.3.2", - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/platform-core": "^0.3.3", + "@aws-amplify/plugin-types": "^0.6.0", "execa": "^7.2.0", "tsx": "^4.6.1" }, @@ -21481,16 +21481,16 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.3.0", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-storage": "0.2.6", - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/plugin-types": "^0.6.0", "execa": "^7.1.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/platform-core": "^0.3.3", "uuid": "^9.0.1" }, "peerDependencies": { @@ -21516,7 +21516,7 @@ "version": "0.4.0", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/plugin-types": "0.5.0" + "@aws-amplify/plugin-types": "0.6.0" }, "peerDependencies": { "zod": "^3.21.4" @@ -21545,11 +21545,11 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.3.2", + "version": "0.3.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.3.2", - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/platform-core": "^0.3.3", + "@aws-amplify/plugin-types": "^0.6.0", "@aws-sdk/client-ssm": "^3.398.0" }, "devDependencies": { @@ -21558,16 +21558,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.3.2", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.4.0", "@aws-amplify/backend-output-storage": "^0.2.6", - "@aws-amplify/plugin-types": "^0.5.0" + "@aws-amplify/plugin-types": "^0.6.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.3.2" + "@aws-amplify/platform-core": "^0.3.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21750,11 +21750,11 @@ } }, "packages/create-amplify": { - "version": "0.3.9", + "version": "0.3.10", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/platform-core": "0.3.2", + "@aws-amplify/platform-core": "0.3.3", "execa": "^7.2.0", "yargs": "^17.7.2" }, @@ -21926,12 +21926,12 @@ "version": "0.3.8", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/auth-construct-alpha": "^0.4.3", - "@aws-amplify/backend": "^0.6.0", - "@aws-amplify/backend-secret": "^0.3.2", + "@aws-amplify/auth-construct-alpha": "^0.4.4", + "@aws-amplify/backend": "^0.7.0", + "@aws-amplify/backend-secret": "^0.3.3", "@aws-amplify/client-config": "^0.4.0", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/platform-core": "^0.3.3", "@aws-sdk/client-amplify": "^3.440.0", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/client-lambda": "^3.460.0", @@ -22411,10 +22411,10 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.3.2", + "version": "0.3.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/plugin-types": "^0.5.0", + "@aws-amplify/plugin-types": "^0.6.0", "@aws-sdk/client-sts": "3.445.0", "is-ci": "^3.0.1", "uuid": "9.0.1", @@ -22843,7 +22843,7 @@ }, "packages/plugin-types": { "name": "@aws-amplify/plugin-types", - "version": "0.5.0", + "version": "0.6.0", "license": "Apache-2.0", "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -22852,15 +22852,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.3.8", + "version": "0.3.9", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "0.4.1", - "@aws-amplify/backend-secret": "^0.3.2", + "@aws-amplify/backend-deployer": "0.4.2", + "@aws-amplify/backend-secret": "^0.3.3", "@aws-amplify/cli-core": "^0.2.0", "@aws-amplify/client-config": "0.4.2", "@aws-amplify/deployed-backend-client": "^0.3.4", - "@aws-amplify/platform-core": "^0.3.2", + "@aws-amplify/platform-core": "^0.3.3", "@aws-sdk/client-cloudformation": "^3.421.0", "@aws-sdk/credential-providers": "^3.382.0", "@aws-sdk/types": "^3.378.0", diff --git a/packages/create-amplify/src/amplify_project_creator.test.ts b/packages/create-amplify/src/amplify_project_creator.test.ts index 64d23e6d6ca..3465360c0ad 100644 --- a/packages/create-amplify/src/amplify_project_creator.test.ts +++ b/packages/create-amplify/src/amplify_project_creator.test.ts @@ -11,20 +11,23 @@ void describe('AmplifyProjectCreator', () => { startAnimatingEllipsis: mock.fn(), stopAnimatingEllipsis: mock.fn(), }; - const packageManagerControllerMock = { installDependencies: mock.fn() }; + const packageManagerControllerMock = { + installDependencies: mock.fn(), + initializeProject: mock.fn(), + getWelcomeMessage: mock.fn(() => '`npx amplify help`'), + initializeTsConfig: mock.fn(), + projectRoot: '/testProjectRoot', + }; const projectRootValidatorMock = { validate: mock.fn() }; const initialProjectFileGeneratorMock = { generateInitialProjectFiles: mock.fn(), }; - const npmInitializedEnsurerMock = { ensureInitialized: mock.fn() }; const gitIgnoreInitializerMock = { ensureInitialized: mock.fn() }; const amplifyProjectCreator = new AmplifyProjectCreator( packageManagerControllerMock as never, projectRootValidatorMock as never, - initialProjectFileGeneratorMock as never, - npmInitializedEnsurerMock as never, gitIgnoreInitializerMock as never, - process.cwd() + initialProjectFileGeneratorMock as never ); mock.method(logger, 'log', logMock.log); await amplifyProjectCreator.create(); @@ -37,13 +40,9 @@ void describe('AmplifyProjectCreator', () => { initialProjectFileGeneratorMock.generateInitialProjectFiles.mock.callCount(), 1 ); - assert.equal( - npmInitializedEnsurerMock.ensureInitialized.mock.callCount(), - 1 - ); assert.equal( logMock.log.mock.calls[4].arguments[0], - 'Welcome to AWS Amplify! \nRun `npx amplify help` for a list of available commands. \nGet started by running `npx amplify sandbox`.' + "Welcome to AWS Amplify!\nNavigate to your project directory using\n'cd ./testProjectRoot'.\nThen get started with the following commands:\n\n`npx amplify help`\n" ); assert.equal( logMock.log.mock.calls[5].arguments[0], @@ -58,27 +57,30 @@ void describe('AmplifyProjectCreator', () => { startAnimatingEllipsis: mock.fn(), stopAnimatingEllipsis: mock.fn(), }; - const packageManagerControllerMock = { installDependencies: mock.fn() }; + const packageManagerControllerMock = { + installDependencies: mock.fn(), + initializeProject: mock.fn(), + getWelcomeMessage: mock.fn(() => '`npx amplify help`'), + initializeTsConfig: mock.fn(), + projectRoot: '/testProjectRoot', + }; const projectRootValidatorMock = { validate: mock.fn() }; + const gitIgnoreInitializerMock = { ensureInitialized: mock.fn() }; const initialProjectFileGeneratorMock = { generateInitialProjectFiles: mock.fn(), }; - const npmInitializedEnsurerMock = { ensureInitialized: mock.fn() }; - const gitIgnoreInitializerMock = { ensureInitialized: mock.fn() }; const amplifyProjectCreator = new AmplifyProjectCreator( packageManagerControllerMock as never, projectRootValidatorMock as never, - initialProjectFileGeneratorMock as never, - npmInitializedEnsurerMock as never, gitIgnoreInitializerMock as never, - '/project/root' + initialProjectFileGeneratorMock as never ); mock.method(logger, 'log', logMock.log); await amplifyProjectCreator.create(); assert.equal( logMock.log.mock.calls[4].arguments[0], - 'Welcome to AWS Amplify! \nRun `npx amplify help` for a list of available commands. \nGet started by running `cd ./project/root; npx amplify sandbox`.' + "Welcome to AWS Amplify!\nNavigate to your project directory using\n'cd ./testProjectRoot'.\nThen get started with the following commands:\n\n`npx amplify help`\n" ); assert.equal( logMock.log.mock.calls[5].arguments[0], diff --git a/packages/create-amplify/src/amplify_project_creator.ts b/packages/create-amplify/src/amplify_project_creator.ts index 6f2e005ae29..08fa7fd0340 100644 --- a/packages/create-amplify/src/amplify_project_creator.ts +++ b/packages/create-amplify/src/amplify_project_creator.ts @@ -1,9 +1,8 @@ -import { PackageManagerController } from './package_manager_controller.js'; +import { PackageManagerController } from './package-manager-controller/package_manager_controller.js'; import { ProjectRootValidator } from './project_root_validator.js'; -import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; -import { NpmProjectInitializer } from './npm_project_initializer.js'; import { GitIgnoreInitializer } from './gitignore_initializer.js'; import { logger } from './logger.js'; +import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; const LEARN_MORE_USAGE_DATA_TRACKING_LINK = `https://docs.amplify.aws/gen2/reference/telemetry`; @@ -26,10 +25,8 @@ export class AmplifyProjectCreator { constructor( private readonly packageManagerController: PackageManagerController, private readonly projectRootValidator: ProjectRootValidator, - private readonly initialProjectFileGenerator: InitialProjectFileGenerator, - private readonly npmInitializedEnsurer: NpmProjectInitializer, private readonly gitIgnoreInitializer: GitIgnoreInitializer, - private readonly projectRoot: string + private readonly initialProjectFileGenerator: InitialProjectFileGenerator ) {} /** @@ -39,7 +36,7 @@ export class AmplifyProjectCreator { logger.debug(`Validating current state of target directory...`); await this.projectRootValidator.validate(); - await this.npmInitializedEnsurer.ensureInitialized(); + await this.packageManagerController.initializeProject(); await logger.indicateProgress( `Installing required dependencies`, @@ -64,16 +61,18 @@ export class AmplifyProjectCreator { logger.log('Successfully created a new project!'); - const cdCommand = - process.cwd() === this.projectRoot + const cdPreamble = + process.cwd() === this.packageManagerController.projectRoot ? '' - : `cd .${this.projectRoot.replace(process.cwd(), '')}; `; - - logger.log( - `Welcome to AWS Amplify! -Run \`npx amplify help\` for a list of available commands. -Get started by running \`${cdCommand}npx amplify sandbox\`.` - ); + : `Navigate to your project directory using +'cd .${this.packageManagerController.projectRoot.replace(process.cwd(), '')}'. +Then get started with the following commands: +`; + + logger.log(`Welcome to AWS Amplify! +${cdPreamble} +${this.packageManagerController.getWelcomeMessage()} +`); logger.log( `Amplify (Gen 2) collects anonymous telemetry data about general usage of the CLI. diff --git a/packages/create-amplify/src/create_amplify.ts b/packages/create-amplify/src/create_amplify.ts index 26c28651c89..0f6ff38f8a0 100644 --- a/packages/create-amplify/src/create_amplify.ts +++ b/packages/create-amplify/src/create_amplify.ts @@ -7,23 +7,32 @@ If customers have a cached version of the create-amplify package, they might execute that cached version even after we publish features and fixes to the package on npm. */ -import { NpmPackageManagerController } from './npm_package_manager_controller.js'; import { ProjectRootValidator } from './project_root_validator.js'; import { AmplifyProjectCreator } from './amplify_project_creator.js'; -import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; -import { NpmProjectInitializer } from './npm_project_initializer.js'; +import { PackageManagerControllerFactory } from './package-manager-controller/package_manager_controller_factory.js'; import { getProjectRoot } from './get_project_root.js'; import { GitIgnoreInitializer } from './gitignore_initializer.js'; +import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; const projectRoot = await getProjectRoot(); +if (process.env.npm_config_user_agent === undefined) { + throw new Error('npm_config_user_agent is undefined'); +} + +const packageManagerControllerFactory = new PackageManagerControllerFactory( + projectRoot, + process.env.npm_config_user_agent +); + +const packageManagerController = + packageManagerControllerFactory.getPackageManagerController(); + const amplifyProjectCreator = new AmplifyProjectCreator( - new NpmPackageManagerController(projectRoot), + packageManagerController, new ProjectRootValidator(projectRoot), - new InitialProjectFileGenerator(projectRoot), - new NpmProjectInitializer(projectRoot), new GitIgnoreInitializer(projectRoot), - projectRoot + new InitialProjectFileGenerator(projectRoot, packageManagerController) ); try { diff --git a/packages/create-amplify/src/execute_with_logger.ts b/packages/create-amplify/src/execute_with_logger.ts index 46c4641b224..eee91e3d018 100644 --- a/packages/create-amplify/src/execute_with_logger.ts +++ b/packages/create-amplify/src/execute_with_logger.ts @@ -7,7 +7,7 @@ import { logger } from './logger.js'; export const executeWithDebugLogger = async ( cwd: string, executable: string, - args?: string[], + args?: Readonly, execa = _execa ) => { try { diff --git a/packages/create-amplify/src/initial_project_file_generator.test.ts b/packages/create-amplify/src/initial_project_file_generator.test.ts index e56ef782cfa..7299d77e3d4 100644 --- a/packages/create-amplify/src/initial_project_file_generator.test.ts +++ b/packages/create-amplify/src/initial_project_file_generator.test.ts @@ -48,6 +48,7 @@ void describe('InitialProjectFileGenerator', () => { executeWithDebugLoggerMock as never ); await initialProjectFileGenerator.generateInitialProjectFiles(); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); assert.deepStrictEqual( executeWithDebugLoggerMock.mock.calls[0].arguments.slice(0, 3), diff --git a/packages/create-amplify/src/initial_project_file_generator.ts b/packages/create-amplify/src/initial_project_file_generator.ts index 39d15353834..140586860b3 100644 --- a/packages/create-amplify/src/initial_project_file_generator.ts +++ b/packages/create-amplify/src/initial_project_file_generator.ts @@ -1,11 +1,10 @@ -import path from 'path'; -import fs from 'fs'; -import _fs from 'fs/promises'; +import _path from 'path'; +import _fsp from 'fs/promises'; import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_logger.js'; -import { execa } from 'execa'; +import { type PackageManagerController } from './package-manager-controller/package_manager_controller.js'; /** - * + * InitialProjectFileGenerator is responsible for copying getting started template to a new project directory */ export class InitialProjectFileGenerator { /** @@ -14,79 +13,29 @@ export class InitialProjectFileGenerator { */ constructor( private readonly projectRoot: string, - private readonly fs = _fs, - private readonly executeWithDebugLogger = _executeWithDebugLogger + private readonly packageManagerController: PackageManagerController, + private readonly fsp = _fsp, + private readonly path = _path ) {} - private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE - ? 'npm' - : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') - ? 'yarn' - : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. - /** * Copies the template directory to an amplify folder within the projectRoot */ generateInitialProjectFiles = async (): Promise => { - const targetDir = path.resolve(this.projectRoot, 'amplify'); - await this.fs.mkdir(targetDir, { recursive: true }); - await this.fs.cp( + const targetDir = this.path.resolve(this.projectRoot, 'amplify'); + await this.fsp.mkdir(targetDir, { recursive: true }); + await this.fsp.cp( new URL('../templates/basic-auth-data/amplify', import.meta.url), targetDir, { recursive: true } ); const packageJsonContent = { type: 'module' }; - await this.fs.writeFile( - path.resolve(targetDir, 'package.json'), + await this.fsp.writeFile( + this.path.resolve(targetDir, 'package.json'), JSON.stringify(packageJsonContent, null, 2) ); - if (process.env.PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { - fs.writeFile(path.resolve(targetDir, 'yarn.lock'), '', (err) => { - if (err) { - console.error(`Error creating ${targetDir}/${targetDir}`, err); - } else { - console.log(`${targetDir}/yarn.lock created successfully.`); - } - }); - } - - await this.initializeTsConfig(targetDir); - }; - - private initializeTsConfig = async (targetDir: string): Promise => { - const tscArgs = [ - 'tsc', - '--init', - '--resolveJsonModule', - 'true', - '--module', - 'es2022', - '--moduleResolution', - 'bundler', - '--target', - 'es2022', - ]; - - if (this.executableName.startsWith('yarn')) { - await this.executeWithDebugLogger( - targetDir, - 'yarn', - ['add', 'typescript@^5'], - execa - ); - } - - await this.executeWithDebugLogger( - targetDir, - this.executableName === 'npm' - ? 'npx' - : this.executableName.startsWith('yarn') - ? 'yarn' - : this.executableName, - tscArgs, - execa - ); + await this.packageManagerController.initializeTsConfig(targetDir); }; } diff --git a/packages/create-amplify/src/npm_package_manager_controller.test.ts b/packages/create-amplify/src/npm_package_manager_controller.test.ts deleted file mode 100644 index 5f6650cf5df..00000000000 --- a/packages/create-amplify/src/npm_package_manager_controller.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { describe, it, mock } from 'node:test'; -import { NpmPackageManagerController } from './npm_package_manager_controller.js'; -import assert from 'assert'; - -void describe('NpmPackageManagerController', () => { - void it('executes expected dev dependency install command', async () => { - const execaMock = mock.fn(); - const npmPackageManagerController = new NpmPackageManagerController( - 'testPath', - execaMock as never - ); - await npmPackageManagerController.installDependencies(['testDep'], 'dev'); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments, [ - 'npm', - ['install', 'testDep', '-D'], - { cwd: 'testPath', stdio: 'inherit' }, - ]); - }); - - void it('executes expected prod dependency install command', async () => { - const execaMock = mock.fn(); - const npmPackageManagerController = new NpmPackageManagerController( - 'testPath', - execaMock as never - ); - await npmPackageManagerController.installDependencies(['testDep'], 'prod'); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments, [ - 'npm', - ['install', 'testDep'], - { cwd: 'testPath', stdin: 'inherit' }, - ]); - }); - - void it('throws when installing dependencies rejects', async () => { - const execaMock = mock.fn(() => { - throw new Error('test error'); - }); - const npmPackageManagerController = new NpmPackageManagerController( - 'testPath', - execaMock as never - ); - await assert.rejects( - () => - npmPackageManagerController.installDependencies(['testDep'], 'prod'), - { - message: `\`npm install testDep\` did not exit successfully.`, - } - ); - }); - - void it('throws when installing dev dependencies rejects', async () => { - const execaMock = mock.fn(() => { - throw new Error('test error'); - }); - const npmPackageManagerController = new NpmPackageManagerController( - 'testPath', - execaMock as never - ); - await assert.rejects( - () => - npmPackageManagerController.installDependencies(['testDevDep'], 'dev'), - { - message: `\`npm install testDevDep --save-dev\` did not exit successfully.`, - } - ); - }); -}); diff --git a/packages/create-amplify/src/npm_package_manager_controller.ts b/packages/create-amplify/src/npm_package_manager_controller.ts deleted file mode 100644 index a7013ec788d..00000000000 --- a/packages/create-amplify/src/npm_package_manager_controller.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { execa as _execa } from 'execa'; -import { - DependencyType, - PackageManagerController, -} from './package_manager_controller.js'; -import { executeWithDebugLogger } from './execute_with_logger.js'; - -/** - * - */ -export class NpmPackageManagerController implements PackageManagerController { - /** - * Abstraction around npm commands that are needed to initialize a project and install dependencies - */ - constructor( - private readonly projectRoot: string, - private readonly execa = _execa - ) {} - private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE - ? 'npm' - : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') - ? 'yarn' - : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. - - /** - * Installs the given package names as devDependencies - */ - installDependencies = async ( - packageNames: string[], - type: DependencyType - ): Promise => { - const args = [ - this.executableName.startsWith('yarn') ? 'add' : 'install', - ].concat(...packageNames); - if (type === 'dev') { - args.push('-D'); - } - - try { - await executeWithDebugLogger( - this.projectRoot, - this.executableName, - args, - this.execa - ); - } catch { - throw new Error( - `\`${this.executableName} ${args.join( - ' ' - )}\` did not exit successfully.` - ); - } - }; -} diff --git a/packages/create-amplify/src/npm_project_initializer.test.ts b/packages/create-amplify/src/npm_project_initializer.test.ts deleted file mode 100644 index 8b2ad3a7724..00000000000 --- a/packages/create-amplify/src/npm_project_initializer.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { describe, it, mock } from 'node:test'; -import { NpmProjectInitializer } from './npm_project_initializer.js'; -import assert from 'assert'; - -void describe('NpmInitializedEnsurer', () => { - void it('does nothing if package.json already exists', async () => { - const existsSyncMock = mock.fn(() => true); - const execaMock = mock.fn(); - const npmInitializedEnsurer = new NpmProjectInitializer( - '/testProjectRoot', - existsSyncMock, - execaMock as never - ); - await npmInitializedEnsurer.ensureInitialized(); - assert.equal(execaMock.mock.callCount(), 0); - }); - - void it('runs `npm init` if no package.json exists', async () => { - const existsSyncMock = mock.fn( - () => true, - () => false, - { times: 1 } - ); - - const execaMock = mock.fn(); - const npmInitializedEnsurer = new NpmProjectInitializer( - '/testProjectRoot', - existsSyncMock as never, - execaMock as never - ); - await npmInitializedEnsurer.ensureInitialized(); - assert.equal(execaMock.mock.callCount(), 1); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments, [ - 'npm', - ['init', '--yes'], - { stdin: 'inherit', cwd: '/testProjectRoot' }, - ]); - }); - - void it('throws if npm init rejects', async () => { - const existsSyncMock = mock.fn(() => false); - const execaMock = mock.fn(() => { - throw new Error('test error'); - }); - const npmInitializedEnsurer = new NpmProjectInitializer( - '/testProjectRoot', - existsSyncMock, - execaMock as never - ); - await assert.rejects(() => npmInitializedEnsurer.ensureInitialized(), { - message: - '`npm init` did not exit successfully. Initialize a valid JavaScript package before continuing.', - }); - }); - - void it('throws if package.json does not exist after npm init', async () => { - const existsSyncMock = mock.fn(() => false); - const execaMock = mock.fn(); - const npmInitializedEnsurer = new NpmProjectInitializer( - '/testProjectRoot', - existsSyncMock, - execaMock as never - ); - await assert.rejects(() => npmInitializedEnsurer.ensureInitialized(), { - message: - 'package.json does not exist after running `npm init`. Initialize a valid JavaScript package before continuing.', - }); - }); -}); diff --git a/packages/create-amplify/src/npm_project_initializer.ts b/packages/create-amplify/src/npm_project_initializer.ts deleted file mode 100644 index 072e0c90688..00000000000 --- a/packages/create-amplify/src/npm_project_initializer.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { existsSync as _existsSync } from 'fs'; -import * as path from 'path'; -import { execa as _execa } from 'execa'; -import { logger } from './logger.js'; -import { executeWithDebugLogger } from './execute_with_logger.js'; - -/** - * Ensure that the current working directory is a valid JavaScript project - */ -export class NpmProjectInitializer { - /** - * injecting console and fs for testing - */ - constructor( - private readonly projectRoot: string, - private readonly existsSync = _existsSync, - private readonly execa = _execa - ) {} - - private readonly executableName = !process.env.PACKAGE_MANAGER_EXECUTABLE - ? 'npm' - : process.env.PACKAGE_MANAGER_EXECUTABLE.startsWith('yarn') - ? 'yarn' - : process.env.PACKAGE_MANAGER_EXECUTABLE; // TODO: replace `process.env.PACKAGE_MANAGER_EXECUTABLE` with `getPackageManagerName()` once the test infra is ready. - - /** - * If package.json already exists, this is a noop. Otherwise, `npm init` is executed to create a package.json file - */ - ensureInitialized = async (): Promise => { - if (this.packageJsonExists()) { - // if package.json already exists, no need to do anything - return; - } - - logger.debug( - `No package.json file found in the current directory. Running \`${this.executableName} init\`...` - ); - - try { - await executeWithDebugLogger( - this.projectRoot, - this.executableName, - this.executableName === 'pnpm' ? ['init'] : ['init', '--yes'], - this.execa - ); - } catch { - throw new Error( - `\`${this.executableName} init\` did not exit successfully. Initialize a valid JavaScript package before continuing.` - ); - } - - if (!this.packageJsonExists()) { - // this should only happen if the customer exits out of npm init before finishing - throw new Error( - `package.json does not exist after running \`${this.executableName} init\`. Initialize a valid JavaScript package before continuing.'` - ); - } - }; - - /** - * Check if a package.json file exists in projectRoot - */ - private packageJsonExists = (): boolean => { - return this.existsSync(path.resolve(this.projectRoot, 'package.json')); - }; -} diff --git a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts b/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts new file mode 100644 index 00000000000..b421f35c617 --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts @@ -0,0 +1,138 @@ +import fsp from 'fs/promises'; +import path from 'path'; +import { beforeEach, describe, it, mock } from 'node:test'; +import assert from 'assert'; +import { execa } from 'execa'; +import { NpmPackageManagerController } from './npm_package_manager_controller.js'; + +void describe('NpmPackageManagerController', () => { + const fspMock = mock.fn(() => Promise.resolve()); + const pathMock = { + resolve: mock.fn(), + }; + const execaMock = mock.fn(() => Promise.resolve()); + const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); + + beforeEach(() => { + fspMock.mock.resetCalls(); + pathMock.resolve.mock.resetCalls(); + execaMock.mock.resetCalls(); + executeWithDebugLoggerMock.mock.resetCalls(); + }); + + void describe('installDependencies', () => { + const existsSyncMock = mock.fn(() => true); + const npmPackageManagerController = new NpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + void it('runs npm install with the correct arguments', async () => { + await npmPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'dev' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'npm', + ['install', 'testPackage1', 'testPackage2', '-D'], + execaMock, + ]); + }); + + void it('runs npm install with the correct arguments for prod dependencies', async () => { + await npmPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'prod' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'npm', + ['install', 'testPackage1', 'testPackage2'], + execaMock, + ]); + }); + }); + + void describe('getWelcomeMessage', () => { + void it('returns the correct welcome message', () => { + const existsSyncMock = mock.fn(() => true); + const npmPackageManagerController = new NpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + assert.equal( + npmPackageManagerController.getWelcomeMessage(), + 'Run `npx amplify help` for a list of available commands. \nGet started by running `npx amplify sandbox`.' + ); + }); + }); + + void describe('initializeProject', () => { + void it('does nothing if package.json already exists', async () => { + let existsSyncMockValue = false; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const npmPackageManagerController = new NpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await npmPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 0); + }); + + void it('runs npm init if package.json does not exist', async () => { + let existsSyncMockValue = true; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const npmPackageManagerController = new NpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await npmPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 2); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); + + void describe('initializeTsConfig', () => { + void it('initialize tsconfig.json', async () => { + const existsSyncMock = mock.fn(() => true); + const npmPackageManagerController = new NpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + await npmPackageManagerController.initializeTsConfig('./amplify'); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); +}); diff --git a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts new file mode 100644 index 00000000000..2c90197289e --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts @@ -0,0 +1,36 @@ +import { existsSync as _existsSync } from 'fs'; +import _fsp from 'fs/promises'; +import { execa as _execa } from 'execa'; +import * as _path from 'path'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { PackageManagerController } from './package_manager_controller.js'; + +/** + * NpmPackageManagerController is an abstraction around npm commands that are needed to initialize a project and install dependencies + */ +export class NpmPackageManagerController extends PackageManagerController { + /** + * constructor + */ + constructor( + readonly projectRoot: string, + protected readonly fsp = _fsp, + protected readonly path = _path, + protected readonly execa = _execa, + protected readonly executeWithDebugLogger = _executeWithDebugLogger, + protected readonly existsSync = _existsSync + ) { + super( + projectRoot, + 'npm', + 'npx', + ['init', '--yes'], + 'install', + fsp, + path, + execa, + executeWithDebugLogger, + existsSync + ); + } +} diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts new file mode 100644 index 00000000000..7126c4cff6a --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts @@ -0,0 +1,121 @@ +import { existsSync as _existsSync } from 'fs'; +import _fsp from 'fs/promises'; +import { execa as _execa } from 'execa'; +import * as _path from 'path'; +import { logger } from '../logger.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { DependencyType } from './package_manager_controller_factory.js'; + +/** + * PackageManagerController is an abstraction around package manager commands that are needed to initialize a project and install dependencies + */ +export abstract class PackageManagerController { + /** + * constructor - sets the project root + */ + constructor( + readonly projectRoot: string, + protected executable: string, + protected binaryRunner: string, + protected initDefault: string[], + protected installCommand: string, + protected readonly fsp = _fsp, + protected readonly path = _path, + protected readonly execa = _execa, + protected readonly executeWithDebugLogger = _executeWithDebugLogger, + protected readonly existsSync = _existsSync + ) {} + + /** + * installDependencies - installs dependencies in the project root + */ + installDependencies = async ( + packageNames: string[], + type: DependencyType + ): Promise => { + const args = [`${this.installCommand}`].concat(...packageNames); + if (type === 'dev') { + args.push('-D'); + } + + await this.executeWithDebugLogger( + this.projectRoot, + this.executable, + args, + this.execa + ); + }; + + /** + * getWelcomeMessage - returns a welcome message for the customer + */ + getWelcomeMessage = () => + `Run \`${this.binaryRunner} amplify help\` for a list of available commands. +Get started by running \`${this.binaryRunner} amplify sandbox\`.`; + + /** + * initializeProject - initializes a project in the project root by checking the package.json file + */ + initializeProject = async () => { + if (this.packageJsonExists(this.projectRoot)) { + // if package.json already exists, no need to do anything + return; + } + + logger.debug( + `No package.json file found in the current directory. Running \`${this.executable} init\`...` + ); + + try { + await this.executeWithDebugLogger( + this.projectRoot, + this.executable, + this.initDefault, + this.execa + ); + } catch { + throw new Error( + `\`${this.executable} init\` did not exit successfully. Initialize a valid JavaScript package before continuing.` + ); + } + + if (!this.packageJsonExists(this.projectRoot)) { + // this should only happen if the customer exits out of npm init before finishing + throw new Error( + `package.json does not exist after running \`${this.executable} init\`. Initialize a valid JavaScript package before continuing.'` + ); + } + }; + + /** + * initializeTsConfig - initializes a tsconfig.json file in the project root + */ + async initializeTsConfig(targetDir: string) { + const tscArgs = [ + 'tsc', + '--init', + '--resolveJsonModule', + 'true', + '--module', + 'es2022', + '--moduleResolution', + 'bundler', + '--target', + 'es2022', + ]; + + await this.executeWithDebugLogger( + targetDir, + this.binaryRunner, + tscArgs, + this.execa + ); + } + + /** + * Check if a package.json file exists in projectRoot + */ + private packageJsonExists = (projectRoot: string): boolean => { + return this.existsSync(this.path.resolve(projectRoot, 'package.json')); + }; +} diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts new file mode 100644 index 00000000000..b22656e1799 --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts @@ -0,0 +1,57 @@ +import { describe, it } from 'node:test'; +import assert from 'assert'; +import { PackageManagerControllerFactory } from './package_manager_controller_factory.js'; +import { PackageManagerController } from './package_manager_controller.js'; +import { NpmPackageManagerController } from './npm_package_manager_controller.js'; + +void describe('packageManagerControllerFactory', () => { + const packageRoot = '/path/to/project'; + + void describe('getPackageManagerController', () => { + const testCases = [ + { + name: 'npm', + userAgent: 'npm/7.0.0 node/v15.0.0 darwin x64', + expectedInstanceof: NpmPackageManagerController, + }, + { + name: 'pnpm', + userAgent: 'pnpm/5.0.0 node/v15.0.0 darwin x64', + expectedInstanceof: PackageManagerController, + }, + { + name: 'yarn classic', + userAgent: 'yarn/1.22.21 node/v15.0.0 darwin x64', + expectedInstanceof: PackageManagerController, + }, + { + name: 'yarn modern', + userAgent: 'yarn/4.0.1 node/v15.0.0 darwin x64', + expectedInstanceof: PackageManagerController, + }, + ]; + + for (const testCase of testCases) { + void it(`should return the correct package manager controller for ${testCase.name}`, () => { + const packageManagerControllerFactory = + new PackageManagerControllerFactory(packageRoot, testCase.userAgent); + + const packageManagerController = + packageManagerControllerFactory.getPackageManagerController(); + assert.ok( + packageManagerController instanceof testCase.expectedInstanceof + ); + }); + } + + void it('should throw an error for unsupported package managers', () => { + const packageManagerControllerFactory = + new PackageManagerControllerFactory(packageRoot, 'unsupported'); + assert.throws( + () => packageManagerControllerFactory.getPackageManagerController(), + Error, + 'Package Manager unsupported is not supported.' + ); + }); + }); +}); diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts new file mode 100644 index 00000000000..f64cf624bd3 --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts @@ -0,0 +1,58 @@ +import { execa as _execa } from 'execa'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { NpmPackageManagerController } from './npm_package_manager_controller.js'; +import { PnpmPackageManagerController } from './pnpm_package_manager_controller.js'; +import { YarnClassicPackageManagerController } from './yarn_classic_package_manager_controller.js'; +import { YarnModernPackageManagerController } from './yarn_modern_package_manager_controller.js'; + +export type DependencyType = 'dev' | 'prod'; + +/** + * packageManagerControllerFactory is an abstraction around package manager commands that are needed to initialize a project and install dependencies + */ +export class PackageManagerControllerFactory { + /** + * constructor + * @param projectRoot - the root directory of the project + * @param userAgent - the user agent of the package manager + */ + constructor( + private readonly projectRoot: string, + private readonly userAgent: string + ) {} + + /** + * getPackageManagerName - returns the name of the package manager + */ + private getPackageManagerName() { + const packageManagerAndVersion = this.userAgent.split(' ')[0]; + const [packageManagerName, packageManagerVersion] = packageManagerAndVersion.split('/'); + + if (packageManagerName === 'yarn') { + const yarnMajorVersion = packageManagerVersion.split('.')[0]; + return `yarn-${yarnMajorVersion === '1' ? 'classic' : 'modern'}`; + } + return packageManagerName; + } + + /** + * getPackageManagerController - returns the package manager controller for each package manager + */ + getPackageManagerController() { + const packageManagerName = this.getPackageManagerName(); + switch (packageManagerName) { + case 'npm': + return new NpmPackageManagerController(this.projectRoot); + case 'pnpm': + return new PnpmPackageManagerController(this.projectRoot); + case 'yarn-classic': + return new YarnClassicPackageManagerController(this.projectRoot); + case 'yarn-modern': + return new YarnModernPackageManagerController(this.projectRoot); + default: + throw new Error( + `Package Manager ${packageManagerName} is not supported.` + ); + } + } +} diff --git a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts b/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts new file mode 100644 index 00000000000..1d1bf292b40 --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts @@ -0,0 +1,138 @@ +import fsp from 'fs/promises'; +import path from 'path'; +import { beforeEach, describe, it, mock } from 'node:test'; +import assert from 'assert'; +import { execa } from 'execa'; +import { PnpmPackageManagerController } from './pnpm_package_manager_controller.js'; + +void describe('PnpmPackageManagerController', () => { + const fspMock = mock.fn(() => Promise.resolve()); + const pathMock = { + resolve: mock.fn(), + }; + const execaMock = mock.fn(() => Promise.resolve()); + const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); + + beforeEach(() => { + fspMock.mock.resetCalls(); + pathMock.resolve.mock.resetCalls(); + execaMock.mock.resetCalls(); + executeWithDebugLoggerMock.mock.resetCalls(); + }); + + void describe('installDependencies', () => { + const existsSyncMock = mock.fn(() => true); + const pnpmPackageManagerController = new PnpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + void it('runs pnpm install with the correct arguments', async () => { + await pnpmPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'dev' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'pnpm', + ['install', 'testPackage1', 'testPackage2', '-D'], + execaMock, + ]); + }); + + void it('runs pnpm install with the correct arguments for prod dependencies', async () => { + await pnpmPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'prod' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'pnpm', + ['install', 'testPackage1', 'testPackage2'], + execaMock, + ]); + }); + }); + + void describe('getWelcomeMessage', () => { + void it('returns the correct welcome message', () => { + const existsSyncMock = mock.fn(() => true); + const pnpmPackageManagerController = new PnpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + assert.equal( + pnpmPackageManagerController.getWelcomeMessage(), + 'Run `pnpm amplify help` for a list of available commands. \nGet started by running `pnpm amplify sandbox`.' + ); + }); + }); + + void describe('initializeProject', () => { + void it('does nothing if package.json already exists', async () => { + let existsSyncMockValue = false; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const pnpmPackageManagerController = new PnpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await pnpmPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 0); + }); + + void it('runs npm init if package.json does not exist', async () => { + let existsSyncMockValue = true; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const pnpmPackageManagerController = new PnpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await pnpmPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 2); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); + + void describe('initializeTsConfig', () => { + void it('initialize tsconfig.json', async () => { + const existsSyncMock = mock.fn(() => true); + const pnpmPackageManagerController = new PnpmPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + await pnpmPackageManagerController.initializeTsConfig('./amplify'); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); +}); diff --git a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts new file mode 100644 index 00000000000..193b881ae0d --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts @@ -0,0 +1,36 @@ +import _fsp from 'fs/promises'; +import * as _path from 'path'; +import { existsSync as _existsSync } from 'fs'; +import { execa as _execa } from 'execa'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { PackageManagerController } from './package_manager_controller.js'; + +/** + * PnpmPackageManagerController is an abstraction around pnpm commands that are needed to initialize a project and install dependencies + */ +export class PnpmPackageManagerController extends PackageManagerController { + /** + * constructor + */ + constructor( + readonly projectRoot: string, + protected readonly fsp = _fsp, + protected readonly path = _path, + protected readonly execa = _execa, + protected readonly executeWithDebugLogger = _executeWithDebugLogger, + protected readonly existsSync = _existsSync + ) { + super( + projectRoot, + 'pnpm', + 'pnpm', + ['init'], + 'install', + fsp, + path, + execa, + executeWithDebugLogger, + existsSync + ); + } +} diff --git a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts new file mode 100644 index 00000000000..2aa9a282f0f --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts @@ -0,0 +1,143 @@ +import fsp from 'fs/promises'; +import path from 'path'; +import { beforeEach, describe, it, mock } from 'node:test'; +import assert from 'assert'; +import { execa } from 'execa'; +import { YarnClassicPackageManagerController } from './yarn_classic_package_manager_controller.js'; + +void describe('YarnClassicPackageManagerController', () => { + const fspMock = mock.fn(() => Promise.resolve()); + const pathMock = { + resolve: mock.fn(), + }; + const execaMock = mock.fn(() => Promise.resolve()); + const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); + + beforeEach(() => { + fspMock.mock.resetCalls(); + pathMock.resolve.mock.resetCalls(); + execaMock.mock.resetCalls(); + executeWithDebugLoggerMock.mock.resetCalls(); + }); + + void describe('installDependencies', () => { + const existsSyncMock = mock.fn(() => true); + const yarnClassicPackageManagerController = + new YarnClassicPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + void it('runs yarn add with the correct arguments', async () => { + await yarnClassicPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'dev' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'yarn', + ['add', 'testPackage1', 'testPackage2', '-D'], + execaMock, + ]); + }); + + void it('runs yarn add with the correct arguments for prod dependencies', async () => { + await yarnClassicPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'prod' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'yarn', + ['add', 'testPackage1', 'testPackage2'], + execaMock, + ]); + }); + }); + + void describe('getWelcomeMessage', () => { + void it('returns the correct welcome message', () => { + const existsSyncMock = mock.fn(() => true); + const yarnClassicPackageManagerController = + new YarnClassicPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + assert.equal( + yarnClassicPackageManagerController.getWelcomeMessage(), + 'Run `yarn amplify help` for a list of available commands. \nGet started by running `yarn amplify sandbox`.' + ); + }); + }); + + void describe('initializeProject', () => { + void it('does nothing if package.json already exists', async () => { + let existsSyncMockValue = false; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const yarnClassicPackageManagerController = + new YarnClassicPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await yarnClassicPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 0); + }); + + void it('runs yarn init if package.json does not exist', async () => { + let existsSyncMockValue = true; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const yarnClassicPackageManagerController = + new YarnClassicPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await yarnClassicPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 2); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); + + void describe('initializeTsConfig', () => { + void it('initialize tsconfig.json', async () => { + const existsSyncMock = mock.fn(() => true); + const yarnClassicPackageManagerController = + new YarnClassicPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + await yarnClassicPackageManagerController.initializeTsConfig('./amplify'); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); + }); + }); +}); diff --git a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts new file mode 100644 index 00000000000..352ed2b0a18 --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts @@ -0,0 +1,53 @@ +import { existsSync as _existsSync } from 'fs'; +import _fsp from 'fs/promises'; +import { execa as _execa } from 'execa'; +import * as _path from 'path'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { PackageManagerController } from './package_manager_controller.js'; + +/** + * YarnClassicPackageManagerController is an abstraction around yarn classic commands that are needed to initialize a project and install dependencies + */ +export class YarnClassicPackageManagerController extends PackageManagerController { + /** + * Abstraction around yarn classic commands that are needed to initialize a project and install dependencies + */ + constructor( + readonly projectRoot: string, + protected readonly fsp = _fsp, + protected readonly path = _path, + protected readonly execa = _execa, + protected readonly executeWithDebugLogger = _executeWithDebugLogger, + protected readonly existsSync = _existsSync + ) { + super( + projectRoot, + 'yarn', + 'yarn', + ['init', '--yes'], + 'add', + fsp, + path, + execa, + executeWithDebugLogger, + existsSync + ); + } + + initializeTsConfig = async (targetDir: string) => { + await this.addTypescript(targetDir); + await super.initializeTsConfig(targetDir); + }; + + /** + * initializeTsConfig - initializes a tsconfig.json file in the project root + */ + private addTypescript = async (targetDir: string) => { + await this.executeWithDebugLogger( + targetDir, + 'yarn', + ['add', 'typescript@^5'], + this.execa + ); + }; +} diff --git a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts new file mode 100644 index 00000000000..58340e6c84b --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts @@ -0,0 +1,147 @@ +import fs from 'fs'; +import fsp from 'fs/promises'; +import path from 'path'; +import { beforeEach, describe, it, mock } from 'node:test'; +import assert from 'assert'; +import { execa } from 'execa'; +import { YarnModernPackageManagerController } from './yarn_modern_package_manager_controller.js'; + +void describe('YarnModernPackageManagerController', () => { + const fspMock = mock.fn(() => Promise.resolve()); + const pathMock = { + resolve: mock.fn(() => '/testProjectRoot'), + }; + const execaMock = mock.fn(() => Promise.resolve()); + const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); + + beforeEach(() => { + fspMock.mock.resetCalls(); + pathMock.resolve.mock.resetCalls(); + execaMock.mock.resetCalls(); + executeWithDebugLoggerMock.mock.resetCalls(); + }); + + void describe('installDependencies', () => { + const existsSyncMock = mock.fn(() => true); + const yarnModernPackageManagerController = + new YarnModernPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + void it('runs yarn add with the correct arguments', async () => { + await yarnModernPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'dev' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'yarn', + ['add', 'testPackage1', 'testPackage2', '-D'], + execaMock, + ]); + }); + + void it('runs yarn add with the correct arguments for prod dependencies', async () => { + await yarnModernPackageManagerController.installDependencies( + ['testPackage1', 'testPackage2'], + 'prod' + ); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ + '/testProjectRoot', + 'yarn', + ['add', 'testPackage1', 'testPackage2'], + execaMock, + ]); + }); + }); + + void describe('getWelcomeMessage', () => { + void it('returns the correct welcome message', () => { + const existsSyncMock = mock.fn(() => true); + const yarnModernPackageManagerController = + new YarnModernPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + assert.equal( + yarnModernPackageManagerController.getWelcomeMessage(), + 'Run `yarn amplify help` for a list of available commands. \nGet started by running `yarn amplify sandbox`.' + ); + }); + }); + + void describe('initializeProject', () => { + void it('does nothing if package.json already exists', async () => { + let existsSyncMockValue = false; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const yarnModernPackageManagerController = + new YarnModernPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await yarnModernPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 0); + }); + + void it('runs yarn init if package.json does not exist', async () => { + let existsSyncMockValue = true; + const existsSyncMock = mock.fn(() => { + existsSyncMockValue = !existsSyncMockValue; + return existsSyncMockValue; + }); + const yarnModernPackageManagerController = + new YarnModernPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + + await yarnModernPackageManagerController.initializeProject(); + assert.equal(existsSyncMock.mock.callCount(), 2); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + }); + }); + + void describe('initializeTsConfig', () => { + void it('initialize tsconfig.json', async () => { + const existsSyncMock = mock.fn(() => true); + const yarnModernPackageManagerController = + new YarnModernPackageManagerController( + '/testProjectRoot', + fspMock as unknown as typeof fsp, + pathMock as unknown as typeof path, + execaMock as unknown as typeof execa, + executeWithDebugLoggerMock, + existsSyncMock + ); + const writeFileMock = mock.fn(() => Promise.resolve()); + mock.method(fs, 'writeFile', writeFileMock); + await yarnModernPackageManagerController.initializeTsConfig('./amplify'); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); + assert.equal(writeFileMock.mock.callCount(), 1); + }); + }); +}); diff --git a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts new file mode 100644 index 00000000000..45453cb850e --- /dev/null +++ b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts @@ -0,0 +1,70 @@ +import { existsSync as _existsSync } from 'fs'; +import _fsp from 'fs/promises'; +import { execa as _execa } from 'execa'; +import * as _path from 'path'; +import { logger } from '../logger.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { PackageManagerController } from './package_manager_controller.js'; + +/** + * YarnModernPackageManagerController is an abstraction around yarn modern (yarn v2+) commands that are needed to initialize a project and install dependencies + */ +export class YarnModernPackageManagerController extends PackageManagerController { + /** + * constructor + */ + constructor( + readonly projectRoot: string, + protected readonly fsp = _fsp, + protected readonly path = _path, + protected readonly execa = _execa, + protected readonly executeWithDebugLogger = _executeWithDebugLogger, + protected readonly existsSync = _existsSync + ) { + super( + projectRoot, + 'yarn', + 'yarn', + ['init', '--yes'], + 'add', + fsp, + path, + execa, + executeWithDebugLogger, + existsSync + ); + } + + initializeTsConfig = async (targetDir: string) => { + await this.addLockFile(targetDir); + await this.addTypescript(targetDir); + await super.initializeTsConfig(targetDir); + }; + + /** + * addLockFile - adds a yarn.lock file to the project root for yarn v2+ + */ + private addLockFile = async (targetDir: string) => { + try { + await this.fsp.writeFile(this.path.resolve(targetDir, 'yarn.lock'), ''); + } catch (error) { + if (typeof error === 'string') { + logger.error(`Error creating ${targetDir}/yarn.lock ${error}}`); + } else if (error instanceof Error) { + logger.error(`Error creating ${targetDir}/yarn.lock ${error.message}}`); + } + } + }; + + /** + * initializeTsConfig - initializes a tsconfig.json file in the project root + */ + private addTypescript = async (targetDir: string) => { + await this.executeWithDebugLogger( + targetDir, + 'yarn', + ['add', 'typescript@^5'], + this.execa + ); + }; +} diff --git a/packages/create-amplify/src/package_manager_controller.ts b/packages/create-amplify/src/package_manager_controller.ts deleted file mode 100644 index f80bf7b6ec3..00000000000 --- a/packages/create-amplify/src/package_manager_controller.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type DependencyType = 'dev' | 'prod'; - -export type PackageManagerController = { - installDependencies: ( - packageNames: string[], - type: DependencyType - ) => Promise; -}; diff --git a/packages/create-amplify/src/project_root_validator.ts b/packages/create-amplify/src/project_root_validator.ts index a3eae6216fa..780808a9dae 100644 --- a/packages/create-amplify/src/project_root_validator.ts +++ b/packages/create-amplify/src/project_root_validator.ts @@ -4,7 +4,7 @@ import * as path from 'path'; const amplifyLearnMoreUrl = 'https://docs.amplify.aws/gen2/how-amplify-works/'; /** - * + * ProjectRootValidator is responsible for validating that the given projectRoot path is a valid target for a new Amplify project */ export class ProjectRootValidator { /** diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index 44515f2ea8a..b030c25dc5f 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -1,5 +1,5 @@ import { execa } from 'execa'; -import * as fs from 'fs/promises'; +import * as fsp from 'fs/promises'; import { existsSync } from 'fs'; import * as path from 'path'; import * as os from 'os'; @@ -29,7 +29,7 @@ const packageManagerSetup = async ( const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); if (existsSync(npxCacheLocation)) { - await fs.rm(npxCacheLocation, { recursive: true }); + await fsp.rm(npxCacheLocation, { recursive: true }); } } else if (packageManagerExecutable.startsWith('yarn')) { if (packageManagerExecutable === 'yarn-modern') { @@ -64,8 +64,6 @@ const packageManagerSetup = async ( 'http://localhost:4873', ]); await execa(packageManagerExecutable, ['config', 'get', 'registry']); - - await execa(packageManagerExecutable, ['store', 'clear']); } }; @@ -128,7 +126,7 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { void describe('installs expected packages and scaffolds expected files', () => { let tempDir: string; beforeEach(async () => { - tempDir = await fs.mkdtemp( + tempDir = await fsp.mkdtemp( path.join(os.tmpdir(), 'test-create-amplify') ); @@ -141,12 +139,12 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { }); afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); + await fsp.rm(tempDir, { recursive: true }); }); void it(`starting from ${initialState} project`, async () => { if (initialState != 'empty') { - await fs.writeFile( + await fsp.writeFile( path.join(tempDir, 'package.json'), JSON.stringify( { @@ -160,13 +158,13 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { ); } - await execa('npm', ['create', 'amplify', '--yes'], { + await execa(packageManagerExecutable, ['create', 'amplify', '--yes'], { cwd: tempDir, stdio: 'inherit', }); const packageJsonPath = path.resolve(tempDir, 'package.json'); const packageJsonObject = JSON.parse( - await fs.readFile(packageJsonPath, 'utf-8') + await fsp.readFile(packageJsonPath, 'utf-8') ); assert.deepStrictEqual( @@ -180,7 +178,7 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { ); const gitIgnorePath = path.resolve(tempDir, '.gitignore'); - const gitIgnoreContent = (await fs.readFile(gitIgnorePath, 'utf-8')) + const gitIgnoreContent = (await fsp.readFile(gitIgnorePath, 'utf-8')) .split(os.EOL) .filter((s) => s.trim()); const expectedGitIgnoreContent = [ @@ -199,7 +197,7 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { // Read tsconfig.json content, remove all comments, and make assertions const tsConfigPath = path.resolve(amplifyPathPrefix, 'tsconfig.json'); const tsConfigContent = ( - await fs.readFile(tsConfigPath, 'utf-8') + await fsp.readFile(tsConfigPath, 'utf-8') ).replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); const tsConfigObject = JSON.parse(tsConfigContent); @@ -238,7 +236,7 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { stdio: 'inherit', }); - await fs.appendFile( + await fsp.appendFile( path.join(tempDir, '.yarnrc.yml'), `pnpIgnorePatterns:\n - ./nm-packages/**` ); @@ -330,7 +328,9 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { void describe('fails fast', () => { let tempDir: string; beforeEach(async () => { - tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); + tempDir = await fsp.mkdtemp( + path.join(os.tmpdir(), 'test-create-amplify') + ); if (PACKAGE_MANAGER_EXECUTABLE === 'yarn-modern') { await packageManagerSetup( @@ -341,12 +341,12 @@ void describe('create-amplify script', { concurrency: concurrency }, () => { }); afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); + await fsp.rm(tempDir, { recursive: true }); }); void it('if amplify path already exists', async () => { const amplifyDirPath = path.join(tempDir, 'amplify'); - await fs.mkdir(amplifyDirPath, { recursive: true }); + await fsp.mkdir(amplifyDirPath, { recursive: true }); const result = await execa( packageManagerExecutable, From f19588a8c9a0a19c0d30ffdf20f721ea3b170d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 10 Jan 2024 21:22:42 -0800 Subject: [PATCH 11/30] chore: update package-lock --- package-lock.json | 142 +++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index 065e5cc680d..a3fd7c74fd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21011,11 +21011,11 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.5.0", + "version": "0.5.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/backend-output-storage": "^0.2.8", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/backend-output-storage": "^0.2.9", "@aws-amplify/plugin-types": "^0.7.0", "@aws-sdk/util-arn-parser": "^3.465.0" }, @@ -21026,18 +21026,18 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.9.0", + "version": "0.10.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.4.1", - "@aws-amplify/backend-data": "^0.9.2", - "@aws-amplify/backend-function": "^0.6.0", - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/backend-output-storage": "^0.2.8", - "@aws-amplify/backend-secret": "^0.4.0", - "@aws-amplify/backend-storage": "^0.4.1", + "@aws-amplify/backend-auth": "^0.4.2", + "@aws-amplify/backend-data": "^0.9.3", + "@aws-amplify/backend-function": "^0.6.1", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/backend-output-storage": "^0.2.9", + "@aws-amplify/backend-secret": "^0.4.1", + "@aws-amplify/backend-storage": "^0.4.2", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-amplify/plugin-types": "^0.7.0", "@aws-sdk/client-amplify": "^3.465.0" }, @@ -21052,16 +21052,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.4.1", + "version": "0.4.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.0", - "@aws-amplify/backend-output-storage": "^0.2.8", + "@aws-amplify/auth-construct-alpha": "^0.5.1", + "@aws-amplify/backend-output-storage": "^0.2.9", "@aws-amplify/plugin-types": "^0.7.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.4.0" + "@aws-amplify/platform-core": "^0.4.1" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21070,11 +21070,11 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.9.2", + "version": "0.9.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/backend-output-storage": "^0.2.8", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/backend-output-storage": "^0.2.9", "@aws-amplify/data-construct": "^1.4.1", "@aws-amplify/data-schema-types": "^0.6.6", "@aws-amplify/plugin-types": "^0.7.0" @@ -21082,7 +21082,7 @@ "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.0" + "@aws-amplify/platform-core": "^0.4.1" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21091,10 +21091,10 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.4.4", + "version": "0.4.5", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-amplify/plugin-types": "^0.7.0", "execa": "^8.0.1", "tsx": "^4.6.1" @@ -21106,16 +21106,16 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.6.0", + "version": "0.6.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "^0.2.8", + "@aws-amplify/backend-output-storage": "^0.2.9", "@aws-amplify/plugin-types": "^0.7.0", "execa": "^8.0.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-sdk/client-ssm": "^3.465.0", "uuid": "^9.0.1" }, @@ -21139,7 +21139,7 @@ }, "packages/backend-output-schemas": { "name": "@aws-amplify/backend-output-schemas", - "version": "0.5.0", + "version": "0.5.1", "license": "Apache-2.0", "devDependencies": { "@aws-amplify/plugin-types": "^0.7.0" @@ -21150,11 +21150,11 @@ }, "packages/backend-output-storage": { "name": "@aws-amplify/backend-output-storage", - "version": "0.2.8", + "version": "0.2.9", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/platform-core": "^0.4.0" + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/platform-core": "^0.4.1" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1" @@ -21171,10 +21171,10 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.4.0", + "version": "0.4.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-amplify/plugin-types": "^0.7.0", "@aws-sdk/client-ssm": "^3.465.0" }, @@ -21184,16 +21184,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.4.1", + "version": "0.4.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/backend-output-storage": "^0.2.8", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/backend-output-storage": "^0.2.9", "@aws-amplify/plugin-types": "^0.7.0" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.1", - "@aws-amplify/platform-core": "^0.4.0" + "@aws-amplify/platform-core": "^0.4.1" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21202,18 +21202,18 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.9.4", + "version": "0.9.5", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/backend-secret": "^0.4.0", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/backend-secret": "^0.4.1", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.0", - "@aws-amplify/deployed-backend-client": "^0.3.6", - "@aws-amplify/form-generator": "^0.6.0", - "@aws-amplify/model-generator": "^0.2.4", - "@aws-amplify/platform-core": "^0.4.0", - "@aws-amplify/sandbox": "^0.3.11", + "@aws-amplify/client-config": "^0.5.1", + "@aws-amplify/deployed-backend-client": "^0.3.7", + "@aws-amplify/form-generator": "^0.6.1", + "@aws-amplify/model-generator": "^0.2.5", + "@aws-amplify/platform-core": "^0.4.1", + "@aws-amplify/sandbox": "^0.3.12", "@aws-sdk/credential-provider-ini": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@aws-sdk/region-config-resolver": "^3.465.0", @@ -21348,12 +21348,12 @@ }, "packages/client-config": { "name": "@aws-amplify/client-config", - "version": "0.5.0", + "version": "0.5.1", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/deployed-backend-client": "^0.3.6", - "@aws-amplify/model-generator": "^0.2.4", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/deployed-backend-client": "^0.3.7", + "@aws-amplify/model-generator": "^0.2.5", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-ssm": "^3.465.0", @@ -21361,16 +21361,16 @@ "zod": "^3.22.2" }, "devDependencies": { - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-sdk/types": "^3.465.0" } }, "packages/create-amplify": { - "version": "0.4.1", + "version": "0.4.2", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "execa": "^8.0.1", "yargs": "^17.7.2" }, @@ -21483,11 +21483,11 @@ }, "packages/deployed-backend-client": { "name": "@aws-amplify/deployed-backend-client", - "version": "0.3.6", + "version": "0.3.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/platform-core": "^0.4.1", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-s3": "^3.465.0", @@ -21497,7 +21497,7 @@ }, "packages/form-generator": { "name": "@aws-amplify/form-generator", - "version": "0.6.0", + "version": "0.6.1", "license": "Apache-2.0", "dependencies": { "@aws-amplify/appsync-modelgen-plugin": "^2.6.0", @@ -21529,15 +21529,15 @@ }, "packages/integration-tests": { "name": "@aws-amplify/integration-tests", - "version": "0.4.0", + "version": "0.4.1", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.0", - "@aws-amplify/backend": "^0.9.0", - "@aws-amplify/backend-secret": "^0.4.0", - "@aws-amplify/client-config": "^0.5.0", + "@aws-amplify/auth-construct-alpha": "^0.5.1", + "@aws-amplify/backend": "^0.10.0", + "@aws-amplify/backend-secret": "^0.4.1", + "@aws-amplify/client-config": "^0.5.1", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/platform-core": "^0.4.1", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-lambda": "^3.465.0", @@ -21941,11 +21941,11 @@ }, "packages/model-generator": { "name": "@aws-amplify/model-generator", - "version": "0.2.4", + "version": "0.2.5", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.0", - "@aws-amplify/deployed-backend-client": "^0.3.6", + "@aws-amplify/backend-output-schemas": "^0.5.1", + "@aws-amplify/deployed-backend-client": "^0.3.7", "@aws-amplify/graphql-generator": "^0.1.3", "@aws-amplify/graphql-types-generator": "^3.4.4", "@aws-sdk/client-appsync": "^3.465.0", @@ -21961,7 +21961,7 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.4.0", + "version": "0.4.1", "license": "Apache-2.0", "dependencies": { "@aws-amplify/plugin-types": "^0.7.0", @@ -22394,15 +22394,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.3.11", + "version": "0.3.12", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "0.4.4", - "@aws-amplify/backend-secret": "^0.4.0", + "@aws-amplify/backend-deployer": "0.4.5", + "@aws-amplify/backend-secret": "^0.4.1", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.0", - "@aws-amplify/deployed-backend-client": "^0.3.6", - "@aws-amplify/platform-core": "^0.4.0", + "@aws-amplify/client-config": "^0.5.1", + "@aws-amplify/deployed-backend-client": "^0.3.7", + "@aws-amplify/platform-core": "^0.4.1", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@aws-sdk/types": "^3.465.0", From ff9c6aa5d5493364788af2a574731895e6d355b3 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Fri, 19 Jan 2024 13:44:27 -0800 Subject: [PATCH 12/30] test: add deploy test (#901) * chore: add e2e_flow.test * add deploy test but don't work * comment out deploy test * fix: e2e test assert * chore: update package.lock * add deploy test * use before and after * change amplifyCli to execa * change test trigger * Revert "change amplifyCli to execa" This reverts commit 9f85439e7f53d5df78f2861c1229c1c588cb9407. * setupProfile * Revert "Revert "change amplifyCli to execa"" This reverts commit 4950b7d0aa581607125c0ed15d46e1875153ee9b. * remove fail test and initialStates * install @aws-amplify/backend-deployer * chore: update changeset * chore: set nodeLinker in test project * fix execaOptions syntax error * fix: npx in cdk deployer * chore: update changeset * fix: yarn modern build * chore: update package-lock * chore: remove some asserts * chore: remove synth * install packages to fix yarn * remove create-amplify help * simplify before and after * remove one packageManagerSetup * refactor packageManagerSetup * fix yarn- * move yarn add to setupPackageManager * fix type error * Revert "fix type error" and "move yarn add to setupPackageManager" This reverts commit d88ef611722dc948f6ff8c32351a83a29d52d2f8. * try fix pnpm for windows by adding @aws-sdk+credential-providers * remove the pnpm patch * add nodir to dictionary * move setupPackageManager to a new file * rename PACKAGE_MANAGER_EXECUTABLE to PACKAGE_MANAGER * refactor packageManagerSetup to use switch * refactor packageManagerSetup to initializeX * use beforeEach and afterEach * add TODO comment * temp * simplify yarn-modern treatments * misc changes * add TODO comments * exclude pnpm on windows * Revert "exclude pnpm on windows" This reverts commit dd7b4236a6c66f97668e11608ff0b1a0a741b8c1. * exclude pnpm on windows * resolve review comments * fix syntax error * address review comments * move this.packageManager logic to ctor * fix yarn-modern * add packageManagerCli and packageManagerExecutable * fix yarn * address review comments * rename package_manager_sanity_check * update workflow yml * chore: update package-lock * move npm proxy to before and after * change comments --- .changeset/eight-coats-camp.md | 5 + .changeset/friendly-windows-chew.md | 5 + .eslint_dictionary.json | 1 + .github/workflows/poc-e2e-flow-test.yml | 20 ++- package-lock.json | 140 +++++++++--------- .../backend-deployer/src/cdk_deployer.test.ts | 2 +- packages/backend-deployer/src/cdk_deployer.ts | 18 ++- .../src/cdk_deployer_singleton_factory.ts | 8 +- .../package_manager_controller.ts | 14 +- .../package_manager_controller_factory.ts | 29 ++-- ...yarn_classic_package_manager_controller.ts | 2 +- .../yarn_modern_package_manager_controller.ts | 20 ++- .../src/package_manager_sanity_checks.test.ts | 124 ++++++++++++++++ .../process-controller/process_controller.ts | 61 ++++++++ .../src/setup_package_manager.ts | 115 ++++++++++++++ .../src/test-e2e/create_amplify.test.ts | 1 - 16 files changed, 460 insertions(+), 105 deletions(-) create mode 100644 .changeset/eight-coats-camp.md create mode 100644 .changeset/friendly-windows-chew.md create mode 100644 packages/integration-tests/src/package_manager_sanity_checks.test.ts create mode 100644 packages/integration-tests/src/setup_package_manager.ts diff --git a/.changeset/eight-coats-camp.md b/.changeset/eight-coats-camp.md new file mode 100644 index 00000000000..f2875945148 --- /dev/null +++ b/.changeset/eight-coats-camp.md @@ -0,0 +1,5 @@ +--- +'@aws-amplify/backend-deployer': patch +--- + +change npx to use package manager diff --git a/.changeset/friendly-windows-chew.md b/.changeset/friendly-windows-chew.md new file mode 100644 index 00000000000..dce509637aa --- /dev/null +++ b/.changeset/friendly-windows-chew.md @@ -0,0 +1,5 @@ +--- +'@aws-amplify/backend-cli': patch +--- + +add @aws-amplify/backend-deployer as a dependency to @aws-amplify/cli diff --git a/.eslint_dictionary.json b/.eslint_dictionary.json index 9c28a90568f..95b64816e97 100644 --- a/.eslint_dictionary.json +++ b/.eslint_dictionary.json @@ -74,6 +74,7 @@ "namespace", "nodejs", "nodenext", + "nodir", "npmrc", "npx", "nullability", diff --git a/.github/workflows/poc-e2e-flow-test.yml b/.github/workflows/poc-e2e-flow-test.yml index 41ee16f2f7f..c40e5735936 100644 --- a/.github/workflows/poc-e2e-flow-test.yml +++ b/.github/workflows/poc-e2e-flow-test.yml @@ -42,8 +42,11 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] pkg-manager: [npm, yarn-classic, yarn-modern, pnpm] node-version: [20] + exclude: + - os: windows-latest + pkg-manager: pnpm env: - PACKAGE_MANAGER_EXECUTABLE: ${{ matrix.pkg-manager }} # TODO: remove PACKAGE_MANAGER_EXECUTABLE once CLI is able to getPackageManager(). + PACKAGE_MANAGER: ${{ matrix.pkg-manager }} runs-on: ${{ matrix.os }} timeout-minutes: 60 needs: @@ -61,7 +64,18 @@ jobs: node-version: ${{ matrix.node-version }} - name: Restore Build Cache uses: ./.github/actions/restore_build_cache - - name: Run E2E tests with ${{ matrix.pkg-manager }} + - name: Configure test tooling credentials + uses: ./.github/actions/setup_profile + with: + role-to-assume: ${{ secrets.E2E_TOOLING_ROLE_ARN }} + aws-region: us-west-2 + profile-name: e2e-tooling + - name: Configure test execution credentials + uses: aws-actions/configure-aws-credentials@04b98b3f9e85f563fb061be8751a0352327246b0 # version 3.0.1 + with: + role-to-assume: ${{ secrets.E2E_RUNNER_ROLE_ARN }} + aws-region: us-west-2 + - name: Run E2E flow tests with ${{ matrix.pkg-manager }} shell: bash run: | - PACKAGE_MANAGER_EXECUTABLE=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/test-e2e/create_amplify.test.ts + PACKAGE_MANAGER=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/package_manager_sanity_checks.test.ts diff --git a/package-lock.json b/package-lock.json index 49d36789079..440a364b65a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21091,11 +21091,11 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.5.2", + "version": "0.5.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/backend-output-storage": "^0.2.10", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/plugin-types": "^0.7.1", "@aws-sdk/util-arn-parser": "^3.465.0" }, @@ -21106,18 +21106,18 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.10.1", + "version": "0.10.2", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.4.3", - "@aws-amplify/backend-data": "^0.9.4", - "@aws-amplify/backend-function": "^0.6.2", - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/backend-output-storage": "^0.2.10", - "@aws-amplify/backend-secret": "^0.4.2", - "@aws-amplify/backend-storage": "^0.4.3", + "@aws-amplify/backend-auth": "^0.4.4", + "@aws-amplify/backend-data": "^0.9.5", + "@aws-amplify/backend-function": "^0.6.3", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/backend-output-storage": "^0.2.11", + "@aws-amplify/backend-secret": "^0.4.3", + "@aws-amplify/backend-storage": "^0.4.4", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-amplify/plugin-types": "^0.7.1", "@aws-sdk/client-amplify": "^3.465.0" }, @@ -21132,16 +21132,16 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.4.3", + "version": "0.4.4", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.2", - "@aws-amplify/backend-output-storage": "^0.2.10", + "@aws-amplify/auth-construct-alpha": "^0.5.3", + "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/plugin-types": "^0.7.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.2", - "@aws-amplify/platform-core": "^0.4.2" + "@aws-amplify/platform-core": "^0.4.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21150,11 +21150,11 @@ }, "packages/backend-data": { "name": "@aws-amplify/backend-data", - "version": "0.9.4", + "version": "0.9.5", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/backend-output-storage": "^0.2.10", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/data-construct": "^1.4.1", "@aws-amplify/data-schema-types": "^0.6.6", "@aws-amplify/plugin-types": "^0.7.1" @@ -21162,7 +21162,7 @@ "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.2", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.2" + "@aws-amplify/platform-core": "^0.4.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21171,10 +21171,10 @@ }, "packages/backend-deployer": { "name": "@aws-amplify/backend-deployer", - "version": "0.4.6", + "version": "0.4.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-amplify/plugin-types": "^0.7.1", "execa": "^8.0.1", "tsx": "^4.6.1" @@ -21186,16 +21186,16 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.6.2", + "version": "0.6.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-storage": "^0.2.10", + "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/plugin-types": "^0.7.1", "execa": "^8.0.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.2", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-ssm": "^3.465.0", "uuid": "^9.0.1" }, @@ -21219,7 +21219,7 @@ }, "packages/backend-output-schemas": { "name": "@aws-amplify/backend-output-schemas", - "version": "0.5.1", + "version": "0.5.2", "license": "Apache-2.0", "devDependencies": { "@aws-amplify/plugin-types": "^0.7.1" @@ -21230,11 +21230,11 @@ }, "packages/backend-output-storage": { "name": "@aws-amplify/backend-output-storage", - "version": "0.2.10", + "version": "0.2.11", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/platform-core": "^0.4.2" + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/platform-core": "^0.4.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1" @@ -21251,10 +21251,10 @@ }, "packages/backend-secret": { "name": "@aws-amplify/backend-secret", - "version": "0.4.2", + "version": "0.4.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-amplify/plugin-types": "^0.7.1", "@aws-sdk/client-ssm": "^3.465.0" }, @@ -21264,16 +21264,16 @@ }, "packages/backend-storage": { "name": "@aws-amplify/backend-storage", - "version": "0.4.3", + "version": "0.4.4", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/backend-output-storage": "^0.2.10", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/plugin-types": "^0.7.1" }, "devDependencies": { "@aws-amplify/backend-platform-test-stubs": "^0.3.2", - "@aws-amplify/platform-core": "^0.4.2" + "@aws-amplify/platform-core": "^0.4.3" }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", @@ -21282,19 +21282,19 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.9.6", + "version": "0.9.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "^0.4.6", - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/backend-secret": "^0.4.2", + "@aws-amplify/backend-deployer": "^0.4.7", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/backend-secret": "^0.4.3", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.2", - "@aws-amplify/deployed-backend-client": "^0.3.8", + "@aws-amplify/client-config": "^0.5.3", + "@aws-amplify/deployed-backend-client": "^0.3.9", "@aws-amplify/form-generator": "^0.6.1", - "@aws-amplify/model-generator": "^0.2.6", - "@aws-amplify/platform-core": "^0.4.2", - "@aws-amplify/sandbox": "^0.3.13", + "@aws-amplify/model-generator": "^0.2.7", + "@aws-amplify/platform-core": "^0.4.3", + "@aws-amplify/sandbox": "^0.3.14", "@aws-sdk/credential-provider-ini": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@aws-sdk/region-config-resolver": "^3.465.0", @@ -21429,12 +21429,12 @@ }, "packages/client-config": { "name": "@aws-amplify/client-config", - "version": "0.5.2", + "version": "0.5.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/deployed-backend-client": "^0.3.8", - "@aws-amplify/model-generator": "^0.2.6", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/deployed-backend-client": "^0.3.9", + "@aws-amplify/model-generator": "^0.2.7", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-ssm": "^3.465.0", @@ -21442,16 +21442,16 @@ "zod": "^3.22.2" }, "devDependencies": { - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/types": "^3.465.0" } }, "packages/create-amplify": { - "version": "0.4.3", + "version": "0.4.4", "license": "Apache-2.0", "dependencies": { "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "execa": "^8.0.1", "yargs": "^17.7.2" }, @@ -21564,11 +21564,11 @@ }, "packages/deployed-backend-client": { "name": "@aws-amplify/deployed-backend-client", - "version": "0.3.8", + "version": "0.3.9", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-s3": "^3.465.0", @@ -21749,15 +21749,15 @@ }, "packages/integration-tests": { "name": "@aws-amplify/integration-tests", - "version": "0.4.2", + "version": "0.4.3", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.2", - "@aws-amplify/backend": "^0.10.1", - "@aws-amplify/backend-secret": "^0.4.2", - "@aws-amplify/client-config": "^0.5.2", + "@aws-amplify/auth-construct-alpha": "^0.5.3", + "@aws-amplify/backend": "^0.10.2", + "@aws-amplify/backend-secret": "^0.4.3", + "@aws-amplify/client-config": "^0.5.3", "@aws-amplify/data-schema": "^0.12.9", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-lambda": "^3.465.0", @@ -22162,11 +22162,11 @@ }, "packages/model-generator": { "name": "@aws-amplify/model-generator", - "version": "0.2.6", + "version": "0.2.7", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-output-schemas": "^0.5.1", - "@aws-amplify/deployed-backend-client": "^0.3.8", + "@aws-amplify/backend-output-schemas": "^0.5.2", + "@aws-amplify/deployed-backend-client": "^0.3.9", "@aws-amplify/graphql-generator": "^0.1.3", "@aws-amplify/graphql-types-generator": "^3.4.4", "@aws-sdk/client-appsync": "^3.465.0", @@ -22182,7 +22182,7 @@ }, "packages/platform-core": { "name": "@aws-amplify/platform-core", - "version": "0.4.2", + "version": "0.4.3", "license": "Apache-2.0", "dependencies": { "@aws-amplify/plugin-types": "^0.7.1", @@ -22615,15 +22615,15 @@ }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.3.13", + "version": "0.3.14", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-deployer": "^0.4.6", - "@aws-amplify/backend-secret": "^0.4.2", + "@aws-amplify/backend-deployer": "^0.4.7", + "@aws-amplify/backend-secret": "^0.4.3", "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.2", - "@aws-amplify/deployed-backend-client": "^0.3.8", - "@aws-amplify/platform-core": "^0.4.2", + "@aws-amplify/client-config": "^0.5.3", + "@aws-amplify/deployed-backend-client": "^0.3.9", + "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@aws-sdk/types": "^3.465.0", diff --git a/packages/backend-deployer/src/cdk_deployer.test.ts b/packages/backend-deployer/src/cdk_deployer.test.ts index 47c45e1c376..ba0e8d9ca97 100644 --- a/packages/backend-deployer/src/cdk_deployer.test.ts +++ b/packages/backend-deployer/src/cdk_deployer.test.ts @@ -27,7 +27,7 @@ void describe('invokeCDKCommand', () => { const locateMock = mock.fn(() => 'amplify/backend.ts'); const backendLocator = { locate: locateMock } as unknown as BackendLocator; - const invoker = new CDKDeployer(new CdkErrorMapper(), backendLocator); + const invoker = new CDKDeployer(new CdkErrorMapper(), backendLocator, 'npm'); const execaMock = mock.method(invoker, 'executeChildProcess', () => Promise.resolve() ); diff --git a/packages/backend-deployer/src/cdk_deployer.ts b/packages/backend-deployer/src/cdk_deployer.ts index 9466e09eeea..088f611f6e2 100644 --- a/packages/backend-deployer/src/cdk_deployer.ts +++ b/packages/backend-deployer/src/cdk_deployer.ts @@ -33,8 +33,14 @@ export class CDKDeployer implements BackendDeployer { */ constructor( private readonly cdkErrorMapper: CdkErrorMapper, - private readonly backendLocator: BackendLocator - ) {} + private readonly backendLocator: BackendLocator, + private readonly packageManager: string + ) { + // TODO: use PackageManagerController to get the executable. + // But first, we need to move the PackageManagerController to platform-core. + this.packageManager = + this.packageManager === 'npm' ? 'npx' : this.packageManager; + } /** * Invokes cdk deploy command */ @@ -126,7 +132,7 @@ export class CDKDeployer implements BackendDeployer { } try { await this.executeChildProcess( - 'npx', + this.packageManager, [ 'tsc', '--showConfig', @@ -140,7 +146,7 @@ export class CDKDeployer implements BackendDeployer { return; } try { - await this.executeChildProcess('npx', [ + await this.executeChildProcess(this.packageManager, [ 'tsc', '--noEmit', '--skipLibCheck', @@ -195,7 +201,7 @@ export class CDKDeployer implements BackendDeployer { // See https://github.com/aws/aws-cdk/issues/7717 for more details. '--ci', '--app', - `'npx tsx ${this.backendLocator.locate()}'`, + `'${this.packageManager} tsx ${this.backendLocator.locate()}'`, '--all', '--output', '.amplify/artifacts/cdk.out', @@ -222,7 +228,7 @@ export class CDKDeployer implements BackendDeployer { cdkCommandArgs.push(...additionalArguments); } - return await this.executeChildProcess('npx', cdkCommandArgs); + return await this.executeChildProcess(this.packageManager, cdkCommandArgs); }; private populateCDKOutputFromStdout = async ( diff --git a/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts b/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts index 006394e6b97..1bc3eb021a2 100644 --- a/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts +++ b/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts @@ -43,9 +43,15 @@ export class BackendDeployerFactory { */ static getInstance = (): BackendDeployer => { if (!BackendDeployerFactory.instance) { + // TODO: once the e2e flow test is complete, we need to refactor this to detect the package manager. Similar as what we did in create-amplify. + const { PACKAGE_MANAGER = 'npm' } = process.env; + const packageManager = PACKAGE_MANAGER.startsWith('yarn') + ? 'yarn' + : PACKAGE_MANAGER; BackendDeployerFactory.instance = new CDKDeployer( new CdkErrorMapper(), - new BackendLocator() + new BackendLocator(), + packageManager ); } return BackendDeployerFactory.instance; diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts index 7126c4cff6a..f49052d5bc8 100644 --- a/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts +++ b/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts @@ -15,10 +15,10 @@ export abstract class PackageManagerController { */ constructor( readonly projectRoot: string, - protected executable: string, - protected binaryRunner: string, - protected initDefault: string[], - protected installCommand: string, + protected readonly executable: string, + protected readonly binaryRunner: string, + protected readonly initDefault: string[], + protected readonly installCommand: string, protected readonly fsp = _fsp, protected readonly path = _path, protected readonly execa = _execa, @@ -29,10 +29,10 @@ export abstract class PackageManagerController { /** * installDependencies - installs dependencies in the project root */ - installDependencies = async ( + async installDependencies( packageNames: string[], type: DependencyType - ): Promise => { + ): Promise { const args = [`${this.installCommand}`].concat(...packageNames); if (type === 'dev') { args.push('-D'); @@ -44,7 +44,7 @@ export abstract class PackageManagerController { args, this.execa ); - }; + } /** * getWelcomeMessage - returns a welcome message for the customer diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts index f64cf624bd3..2924c00552d 100644 --- a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts +++ b/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts @@ -21,20 +21,6 @@ export class PackageManagerControllerFactory { private readonly userAgent: string ) {} - /** - * getPackageManagerName - returns the name of the package manager - */ - private getPackageManagerName() { - const packageManagerAndVersion = this.userAgent.split(' ')[0]; - const [packageManagerName, packageManagerVersion] = packageManagerAndVersion.split('/'); - - if (packageManagerName === 'yarn') { - const yarnMajorVersion = packageManagerVersion.split('.')[0]; - return `yarn-${yarnMajorVersion === '1' ? 'classic' : 'modern'}`; - } - return packageManagerName; - } - /** * getPackageManagerController - returns the package manager controller for each package manager */ @@ -55,4 +41,19 @@ export class PackageManagerControllerFactory { ); } } + + /** + * getPackageManagerName - returns the name of the package manager + */ + private getPackageManagerName() { + const packageManagerAndVersion = this.userAgent.split(' ')[0]; + const [packageManagerName, packageManagerVersion] = + packageManagerAndVersion.split('/'); + + if (packageManagerName === 'yarn') { + const yarnMajorVersion = packageManagerVersion.split('.')[0]; + return `yarn-${yarnMajorVersion === '1' ? 'classic' : 'modern'}`; + } + return packageManagerName; + } } diff --git a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts index 352ed2b0a18..c438be9d1f8 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts +++ b/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts @@ -40,7 +40,7 @@ export class YarnClassicPackageManagerController extends PackageManagerControlle }; /** - * initializeTsConfig - initializes a tsconfig.json file in the project root + * addTypescript - initializes a tsconfig.json file in the project root */ private addTypescript = async (targetDir: string) => { await this.executeWithDebugLogger( diff --git a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts index 45453cb850e..2d81bed5433 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts +++ b/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts @@ -5,6 +5,7 @@ import * as _path from 'path'; import { logger } from '../logger.js'; import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; import { PackageManagerController } from './package_manager_controller.js'; +import { DependencyType } from './package_manager_controller_factory.js'; /** * YarnModernPackageManagerController is an abstraction around yarn modern (yarn v2+) commands that are needed to initialize a project and install dependencies @@ -35,6 +36,14 @@ export class YarnModernPackageManagerController extends PackageManagerController ); } + installDependencies: ( + packageNames: string[], + type: DependencyType + ) => Promise = async (packageNames, type) => { + await this.addDependencies(this.projectRoot); + await super.installDependencies(packageNames, type); + }; + initializeTsConfig = async (targetDir: string) => { await this.addLockFile(targetDir); await this.addTypescript(targetDir); @@ -57,7 +66,7 @@ export class YarnModernPackageManagerController extends PackageManagerController }; /** - * initializeTsConfig - initializes a tsconfig.json file in the project root + * addTypescript - initializes a tsconfig.json file in the project root */ private addTypescript = async (targetDir: string) => { await this.executeWithDebugLogger( @@ -67,4 +76,13 @@ export class YarnModernPackageManagerController extends PackageManagerController this.execa ); }; + + private addDependencies = async (targetDir: string) => { + await this.executeWithDebugLogger( + targetDir, + 'yarn', + ['add', '-D', 'tsx', 'esbuild'], + this.execa + ); + }; } diff --git a/packages/integration-tests/src/package_manager_sanity_checks.test.ts b/packages/integration-tests/src/package_manager_sanity_checks.test.ts new file mode 100644 index 00000000000..ad6edd147b0 --- /dev/null +++ b/packages/integration-tests/src/package_manager_sanity_checks.test.ts @@ -0,0 +1,124 @@ +import { execa } from 'execa'; +import * as fsp from 'fs/promises'; +import * as path from 'path'; +import * as os from 'os'; +import { after, afterEach, before, beforeEach, describe, it } from 'node:test'; +import assert from 'assert'; +import { glob } from 'glob'; +import { BackendIdentifier } from '@aws-amplify/plugin-types'; +import { + CloudFormationClient, + DeleteStackCommand, +} from '@aws-sdk/client-cloudformation'; +import { BackendIdentifierConversions } from '@aws-amplify/platform-core'; +import { getClientConfigPath } from '@aws-amplify/client-config'; +import { TestBranch, amplifyAppPool } from './amplify_app_pool.js'; +import { e2eToolingClientConfig } from './e2e_tooling_client_config.js'; +import { + type PackageManager, + type PackageManagerExecutable, + setupPackageManager, +} from './setup_package_manager.js'; +import { + runPackageManager, + runWithPackageManager, +} from './process-controller/process_controller.js'; + +/** + * TODO: This test will be refactored to use the test from health-checks.test.ts and run with different package managers. + */ + +void describe('getting started happy path', async () => { + let branchBackendIdentifier: BackendIdentifier; + let testBranch: TestBranch; + let cfnClient: CloudFormationClient; + let tempDir: string; + let packageManagerExecutable: PackageManagerExecutable; + let packageManager: PackageManager; + + before(async () => { + // start a local npm proxy and publish the current codebase to the proxy + await execa('npm', ['run', 'clean:npm-proxy'], { stdio: 'inherit' }); + await execa('npm', ['run', 'vend'], { stdio: 'inherit' }); + }); + + after(async () => { + // stop the npm proxy + await execa('npm', ['run', 'stop:npm-proxy'], { stdio: 'inherit' }); + }); + + beforeEach(async () => { + tempDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); + const packageManagerInfo = await setupPackageManager(tempDir); + packageManagerExecutable = packageManagerInfo.packageManagerExecutable; + packageManager = packageManagerInfo.packageManager; + + cfnClient = new CloudFormationClient(e2eToolingClientConfig); + testBranch = await amplifyAppPool.createTestBranch(); + branchBackendIdentifier = { + namespace: testBranch.appId, + name: testBranch.branchName, + type: 'branch', + }; + }); + + afterEach(async () => { + await cfnClient.send( + new DeleteStackCommand({ + StackName: BackendIdentifierConversions.toStackName( + branchBackendIdentifier + ), + }) + ); + await fsp.rm(tempDir, { recursive: true }); + }); + + void it('creates new project and deploy them without an error', async () => { + await runPackageManager( + packageManager, + ['create', 'amplify', '--yes'], + tempDir + ).run(); + + const pathPrefix = path.join(tempDir, 'amplify'); + + const files = await glob(path.join(pathPrefix, '**', '*'), { + nodir: true, + windowsPathsNoEscape: true, + ignore: ['**/node_modules/**', '**/yarn.lock'], + }); + + const expectedAmplifyFiles = [ + path.join('auth', 'resource.ts'), + 'backend.ts', + path.join('data', 'resource.ts'), + 'package.json', + 'tsconfig.json', + ]; + + assert.deepStrictEqual( + files.sort(), + expectedAmplifyFiles.map((suffix) => path.join(pathPrefix, suffix)) + ); + + await runWithPackageManager( + packageManager, + [ + 'amplify', + 'pipeline-deploy', + '--branch', + branchBackendIdentifier.name, + '--appId', + branchBackendIdentifier.namespace, + ], + tempDir, + { env: { CI: 'true' } } + ).run(); + + const clientConfigStats = await fsp.stat( + await getClientConfigPath(tempDir) + ); + + assert.ok(clientConfigStats.isFile()); + }); +}); diff --git a/packages/integration-tests/src/process-controller/process_controller.ts b/packages/integration-tests/src/process-controller/process_controller.ts index 85c2d4e8620..c8fab948120 100644 --- a/packages/integration-tests/src/process-controller/process_controller.ts +++ b/packages/integration-tests/src/process-controller/process_controller.ts @@ -3,6 +3,11 @@ import readline from 'readline'; import { PredicatedActionBuilder } from './predicated_action_queue_builder.js'; import { ActionType } from './predicated_action.js'; import { killExecaProcess } from './execa_process_killer.js'; +import { + type PackageManager, + type PackageManagerExecutable, +} from '../setup_package_manager.js'; + /** * Provides an abstractions for sending and receiving data on stdin/out of a child process * @@ -159,3 +164,59 @@ export const cdkCli = ( env: options?.env, }); }; + +/** + * runWithPackageManager - Factory function that returns a ProcessController for the specified package manager's binary runner + */ +export const runWithPackageManager = ( + packageManager: PackageManager, + args: string[] = [], + dir: string, + options?: { + env?: Record; + } +): ProcessController => { + let packageManagerBinary: PackageManagerExecutable; + switch (packageManager) { + case 'npm': + packageManagerBinary = 'npx'; + break; + + case 'pnpm': + packageManagerBinary = 'pnpm'; + break; + + case 'yarn-classic': + case 'yarn-modern': + packageManagerBinary = 'yarn'; + break; + + default: + throw new Error(`Unknown package manager: ${packageManager as string}`); + } + return new ProcessController(packageManagerBinary, args, { + cwd: dir, + env: options?.env, + }); +}; + +/** + * runPackageManager - Factory function that returns a ProcessController for the specified package manager's executable + */ +export const runPackageManager = ( + packageManager: PackageManager, + args: string[] = [], + dir: string, + options?: { + env?: Record; + } +): ProcessController => { + const packageManagerExecutable = packageManager.startsWith('yarn') + ? 'yarn' + : packageManager; + + return new ProcessController(packageManagerExecutable, args, { + cwd: dir, + env: options?.env, + }); +}; diff --git a/packages/integration-tests/src/setup_package_manager.ts b/packages/integration-tests/src/setup_package_manager.ts new file mode 100644 index 00000000000..e1b51622f0c --- /dev/null +++ b/packages/integration-tests/src/setup_package_manager.ts @@ -0,0 +1,115 @@ +import { execa } from 'execa'; +import * as fsp from 'fs/promises'; +import { existsSync } from 'fs'; +import * as path from 'path'; +import * as os from 'os'; + +const customRegistry = 'http://localhost:4873'; + +// TODO: refactor into `type PackageManagerInitializer` and have sub-types with a factory. +export type PackageManager = 'npm' | 'yarn-classic' | 'yarn-modern' | 'pnpm'; +export type PackageManagerExecutable = 'npx' | 'yarn' | 'pnpm'; + +const initializeNpm = async () => { + const { stdout } = await execa('npm', ['config', 'get', 'cache']); + const npxCacheLocation = path.join(stdout.toString().trim(), '_npx'); + if (existsSync(npxCacheLocation)) { + await fsp.rm(npxCacheLocation, { recursive: true }); + } +}; + +const initializePnpm = async () => { + const packageManager = 'pnpm'; + await execa('npm', ['install', '-g', packageManager], { + stdio: 'inherit', + }); + await execa(packageManager, ['--version']); + await execa(packageManager, ['config', 'set', 'registry', customRegistry]); + await execa(packageManager, ['config', 'get', 'registry']); +}; + +const initializeYarnClassic = async (execaOptions: { + cwd: string; + stdio: 'inherit'; +}) => { + const packageManager = 'yarn'; + await execa('npm', ['install', '-g', packageManager], { stdio: 'inherit' }); + await execa( + packageManager, + ['config', 'set', 'registry', customRegistry], + execaOptions + ); + await execa(packageManager, ['config', 'get', 'registry'], execaOptions); + await execa(packageManager, ['cache', 'clean'], execaOptions); +}; + +const initializeYarnModern = async (execaOptions: { + cwd: string; + stdio: 'inherit'; +}) => { + const packageManager = 'yarn'; + await execa('npm', ['install', '-g', packageManager], { stdio: 'inherit' }); + await execa('yarn', ['init', '-2'], execaOptions); + await execa( + packageManager, + ['config', 'set', 'npmRegistryServer', customRegistry], + execaOptions + ); + await execa( + packageManager, + ['config', 'set', 'unsafeHttpWhitelist', 'localhost'], + execaOptions + ); + await execa( + packageManager, + ['config', 'set', 'nodeLinker', 'node-modules'], + execaOptions + ); + await execa(packageManager, ['cache', 'clean'], execaOptions); +}; + +/** + * Sets up the package manager for the e2e flow + */ +export const setupPackageManager = async ( + dir: string +): Promise<{ + packageManager: PackageManager; + packageManagerExecutable: PackageManagerExecutable; +}> => { + const packageManager = (process.env.PACKAGE_MANAGER ?? + 'npm') as PackageManager; + let packageManagerExecutable: PackageManagerExecutable; + const execaOptions = { + cwd: os.homedir(), + stdio: 'inherit' as const, + }; + + switch (packageManager) { + case 'npm': + packageManagerExecutable = 'npx'; + await initializeNpm(); + break; + + case 'pnpm': + packageManagerExecutable = 'pnpm'; + await initializePnpm(); + break; + + case 'yarn-classic': + packageManagerExecutable = 'yarn'; + await initializeYarnClassic(execaOptions); + break; + + case 'yarn-modern': + packageManagerExecutable = 'yarn'; + execaOptions.cwd = dir; + await initializeYarnModern(execaOptions); + break; + + default: + throw new Error(`Unknown package manager: ${packageManager as string}`); + } + + return { packageManagerExecutable, packageManager }; +}; diff --git a/packages/integration-tests/src/test-e2e/create_amplify.test.ts b/packages/integration-tests/src/test-e2e/create_amplify.test.ts index 81b2e62a689..5a046886250 100644 --- a/packages/integration-tests/src/test-e2e/create_amplify.test.ts +++ b/packages/integration-tests/src/test-e2e/create_amplify.test.ts @@ -161,7 +161,6 @@ void describe( const pathPrefix = path.join(tempDir, 'amplify'); const files = await glob(path.join(amplifyPathPrefix, '**', '*'), { - // eslint-disable-next-line spellcheck/spell-checker nodir: true, windowsPathsNoEscape: true, }); From 8b4619f874e6ddc7c2d29ece702b3afe6c835c5a Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:24:43 -0800 Subject: [PATCH 13/30] feat(backend-deploy): use packageManagerController (#947) * fix logger * fix logLevel * change workflow trigger to include poc/pms-cli-core * move package_manager_controller to cli-core * chore: update changeset * move npm_config_user_agent to getPackageManagerName and add runWithPackageManager * fix build error * modify executeWithDebugLogger * add getPackageManagerCommandArgs * refactor cdk_deployer to use package manager * install cli-core * fix execaChildProcess type * use PackageManagerControllerFactory in cdkDeployer * fix amplify/amplify path * chore: update API.md * clean up package-manager-controller export * update API.md * add type PackageManagerController * use PackageManagerController type from plugin-types * rename PackageManagerControllerBase and use plugin-types * change workflow trigger to exclude poc/pms-cli-core * refactor BackendDeployerFactory to take PackageManagerController * clean up getPackageManagerCommandArgs * add projectRoot and rename packageManagerControllerBase file * set projectRoot default value * rename execute_with_debugger_logger * use execa Options * Revert "use execa Options" This reverts commit 30cd61ee0bb883b31eb59e104cde07a6038231e7. * rename executeChildProcessWithPackageManager to executeCommand * make BackendDeployerFactory param mandatory * make BackendDeployerFactory param mandatory * remove DependencyType * remove @aws-amplify/platform-core from cli-core * remove some default projectRoot * remove all default projectRoot * inject printer to factory * update package-lock * fix cli-core version in backend-deployer * move @aws-amplify/cli-core to devDep * add getCommand * change execa option type * change projectRoot to private * rename projectRoot to cwd * change ./ to cwd * remove @aws-amplify/cli-core from backend-deployer --- .changeset/stale-poems-visit.md | 8 + package-lock.json | 148 ++++++++++++++---- packages/backend-deployer/API.md | 4 +- .../backend-deployer/src/cdk_deployer.test.ts | 41 +++-- packages/backend-deployer/src/cdk_deployer.ts | 53 ++++--- .../src/cdk_deployer_singleton_factory.ts | 23 +-- packages/cli-core/API.md | 8 + packages/cli-core/package.json | 3 +- packages/cli-core/src/index.ts | 1 + .../execute_with_debugger_logger.test.ts} | 2 +- .../execute_with_debugger_logger.ts} | 12 +- .../npm_package_manager_controller.test.ts | 11 +- .../npm_package_manager_controller.ts | 10 +- .../package_manager_controller_base.ts} | 49 ++++-- ...package_manager_controller_factory.test.ts | 13 +- .../package_manager_controller_factory.ts | 29 ++-- .../pnpm_package_manager_controller.test.ts | 11 +- .../pnpm_package_manager_controller.ts | 10 +- ...classic_package_manager_controller.test.ts | 11 +- ...yarn_classic_package_manager_controller.ts | 10 +- ..._modern_package_manager_controller.test.ts | 18 ++- .../yarn_modern_package_manager_controller.ts | 28 ++-- packages/cli-core/src/printer.ts | 7 + .../pipeline_deploy_command.test.ts | 25 ++- .../pipeline_deploy_command_factory.ts | 11 +- packages/create-amplify/package.json | 1 + .../src/amplify_project_creator.test.ts | 14 +- .../src/amplify_project_creator.ts | 7 +- packages/create-amplify/src/create_amplify.ts | 13 +- .../initial_project_file_generator.test.ts | 6 +- .../src/initial_project_file_generator.ts | 3 +- packages/create-amplify/tsconfig.json | 6 +- packages/plugin-types/API.md | 12 ++ packages/plugin-types/package.json | 3 + packages/plugin-types/src/index.ts | 1 + .../src/package_manager_controller.ts | 22 +++ .../sandbox/src/file_watching_sandbox.test.ts | 17 +- packages/sandbox/src/sandbox_executor.test.ts | 15 +- .../sandbox/src/sandbox_singleton_factory.ts | 12 +- 39 files changed, 473 insertions(+), 205 deletions(-) create mode 100644 .changeset/stale-poems-visit.md rename packages/{create-amplify/src/execute_with_logger.test.ts => cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts} (94%) rename packages/{create-amplify/src/execute_with_logger.ts => cli-core/src/package-manager-controller/execute_with_debugger_logger.ts} (76%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/npm_package_manager_controller.test.ts (90%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/npm_package_manager_controller.ts (82%) rename packages/{create-amplify/src/package-manager-controller/package_manager_controller.ts => cli-core/src/package-manager-controller/package_manager_controller_base.ts} (73%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/package_manager_controller_factory.test.ts (78%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/package_manager_controller_factory.ts (65%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/pnpm_package_manager_controller.test.ts (90%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/pnpm_package_manager_controller.ts (82%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts (91%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/yarn_classic_package_manager_controller.ts (87%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts (86%) rename packages/{create-amplify => cli-core}/src/package-manager-controller/yarn_modern_package_manager_controller.ts (77%) create mode 100644 packages/cli-core/src/printer.ts create mode 100644 packages/plugin-types/src/package_manager_controller.ts diff --git a/.changeset/stale-poems-visit.md b/.changeset/stale-poems-visit.md new file mode 100644 index 00000000000..62404dc0e4e --- /dev/null +++ b/.changeset/stale-poems-visit.md @@ -0,0 +1,8 @@ +--- +'@aws-amplify/integration-tests': patch +'@aws-amplify/backend-deployer': patch +'create-amplify': patch +'@aws-amplify/cli-core': patch +--- + +move packageManagerController to @aws-amplify/cli-core diff --git a/package-lock.json b/package-lock.json index 5b1208aeb90..65340593c44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21091,7 +21091,7 @@ }, "packages/auth-construct": { "name": "@aws-amplify/auth-construct-alpha", - "version": "0.5.3", + "version": "0.5.4", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.5.2", @@ -21106,12 +21106,12 @@ }, "packages/backend": { "name": "@aws-amplify/backend", - "version": "0.10.2", + "version": "0.10.3", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/backend-auth": "^0.4.4", + "@aws-amplify/backend-auth": "^0.4.5", "@aws-amplify/backend-data": "^0.9.5", - "@aws-amplify/backend-function": "^0.6.3", + "@aws-amplify/backend-function": "^0.6.4", "@aws-amplify/backend-output-schemas": "^0.5.2", "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/backend-secret": "^0.4.3", @@ -21132,10 +21132,10 @@ }, "packages/backend-auth": { "name": "@aws-amplify/backend-auth", - "version": "0.4.4", + "version": "0.4.5", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.3", + "@aws-amplify/auth-construct-alpha": "^0.5.4", "@aws-amplify/backend-output-storage": "^0.2.11", "@aws-amplify/plugin-types": "^0.7.1" }, @@ -21186,7 +21186,7 @@ }, "packages/backend-function": { "name": "@aws-amplify/backend-function", - "version": "0.6.3", + "version": "0.6.4", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-storage": "^0.2.11", @@ -21282,19 +21282,19 @@ }, "packages/cli": { "name": "@aws-amplify/backend-cli", - "version": "0.9.7", + "version": "0.10.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-deployer": "^0.4.7", "@aws-amplify/backend-output-schemas": "^0.5.2", "@aws-amplify/backend-secret": "^0.4.3", - "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.3", + "@aws-amplify/cli-core": "^0.3.0", + "@aws-amplify/client-config": "^0.6.0", "@aws-amplify/deployed-backend-client": "^0.3.9", - "@aws-amplify/form-generator": "^0.6.1", - "@aws-amplify/model-generator": "^0.2.7", + "@aws-amplify/form-generator": "^0.7.0", + "@aws-amplify/model-generator": "^0.3.0", "@aws-amplify/platform-core": "^0.4.3", - "@aws-amplify/sandbox": "^0.3.14", + "@aws-amplify/sandbox": "^0.4.0", "@aws-sdk/credential-provider-ini": "^3.465.0", "@aws-sdk/credential-providers": "^3.465.0", "@aws-sdk/region-config-resolver": "^3.465.0", @@ -21321,10 +21321,11 @@ }, "packages/cli-core": { "name": "@aws-amplify/cli-core", - "version": "0.2.0", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { - "@inquirer/prompts": "^3.0.0" + "@inquirer/prompts": "^3.0.0", + "execa": "^8.0.1" } }, "packages/cli/node_modules/ansi-styles": { @@ -21429,12 +21430,12 @@ }, "packages/client-config": { "name": "@aws-amplify/client-config", - "version": "0.5.3", + "version": "0.6.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.5.2", "@aws-amplify/deployed-backend-client": "^0.3.9", - "@aws-amplify/model-generator": "^0.2.7", + "@aws-amplify/model-generator": "^0.3.0", "@aws-sdk/client-amplify": "^3.465.0", "@aws-sdk/client-cloudformation": "^3.465.0", "@aws-sdk/client-ssm": "^3.465.0", @@ -21447,11 +21448,12 @@ } }, "packages/create-amplify": { - "version": "0.4.4", + "version": "0.5.0", "license": "Apache-2.0", "dependencies": { - "@aws-amplify/cli-core": "^0.2.0", + "@aws-amplify/cli-core": "^0.3.0", "@aws-amplify/platform-core": "^0.4.3", + "@aws-amplify/plugin-types": "^0.7.1", "execa": "^8.0.1", "yargs": "^17.7.2" }, @@ -21717,7 +21719,7 @@ }, "packages/form-generator": { "name": "@aws-amplify/form-generator", - "version": "0.6.1", + "version": "0.7.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/appsync-modelgen-plugin": "^2.6.0", @@ -21752,10 +21754,10 @@ "version": "0.4.3", "license": "Apache-2.0", "devDependencies": { - "@aws-amplify/auth-construct-alpha": "^0.5.3", - "@aws-amplify/backend": "^0.10.2", + "@aws-amplify/auth-construct-alpha": "^0.5.4", + "@aws-amplify/backend": "^0.10.3", "@aws-amplify/backend-secret": "^0.4.3", - "@aws-amplify/client-config": "^0.5.3", + "@aws-amplify/client-config": "^0.6.0", "@aws-amplify/data-schema": "^0.12.9", "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-amplify": "^3.465.0", @@ -22162,7 +22164,7 @@ }, "packages/model-generator": { "name": "@aws-amplify/model-generator", - "version": "0.2.7", + "version": "0.3.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-output-schemas": "^0.5.2", @@ -22608,20 +22610,112 @@ "name": "@aws-amplify/plugin-types", "version": "0.7.1", "license": "Apache-2.0", + "devDependencies": { + "execa": "^5.1.1" + }, "peerDependencies": { "aws-cdk-lib": "^2.110.1", "constructs": "^10.0.0" } }, + "packages/plugin-types/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "packages/plugin-types/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "packages/plugin-types/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/plugin-types/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "packages/plugin-types/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "packages/plugin-types/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/plugin-types/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "packages/sandbox": { "name": "@aws-amplify/sandbox", - "version": "0.3.14", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { "@aws-amplify/backend-deployer": "^0.4.7", "@aws-amplify/backend-secret": "^0.4.3", - "@aws-amplify/cli-core": "^0.2.0", - "@aws-amplify/client-config": "^0.5.3", + "@aws-amplify/cli-core": "^0.3.0", + "@aws-amplify/client-config": "^0.6.0", "@aws-amplify/deployed-backend-client": "^0.3.9", "@aws-amplify/platform-core": "^0.4.3", "@aws-sdk/client-cloudformation": "^3.465.0", diff --git a/packages/backend-deployer/API.md b/packages/backend-deployer/API.md index d39b2b7388f..1e533a3191b 100644 --- a/packages/backend-deployer/API.md +++ b/packages/backend-deployer/API.md @@ -5,6 +5,7 @@ ```ts import { BackendIdentifier } from '@aws-amplify/plugin-types'; +import { PackageManagerController } from '@aws-amplify/plugin-types'; // @public export type BackendDeployer = { @@ -14,7 +15,8 @@ export type BackendDeployer = { // @public export class BackendDeployerFactory { - static getInstance: () => BackendDeployer; + constructor(packageManagerController: PackageManagerController); + getInstance(): BackendDeployer; } // @public (undocumented) diff --git a/packages/backend-deployer/src/cdk_deployer.test.ts b/packages/backend-deployer/src/cdk_deployer.test.ts index ba0e8d9ca97..f6457a3ce2b 100644 --- a/packages/backend-deployer/src/cdk_deployer.test.ts +++ b/packages/backend-deployer/src/cdk_deployer.test.ts @@ -26,9 +26,20 @@ void describe('invokeCDKCommand', () => { // This is needed for `getRelativeBackendEntryPoint` to ensure that backend file exists correctly const locateMock = mock.fn(() => 'amplify/backend.ts'); const backendLocator = { locate: locateMock } as unknown as BackendLocator; + const packageManagerControllerMock = { + installDependencies: mock.fn(), + initializeProject: mock.fn(), + getWelcomeMessage: mock.fn(() => '`npx amplify help`'), + initializeTsConfig: mock.fn(), + projectRoot: '/testProjectRoot', + }; - const invoker = new CDKDeployer(new CdkErrorMapper(), backendLocator, 'npm'); - const execaMock = mock.method(invoker, 'executeChildProcess', () => + const invoker = new CDKDeployer( + new CdkErrorMapper(), + backendLocator, + packageManagerControllerMock as never + ); + const execaMock = mock.method(invoker, 'executeCommand', () => Promise.resolve() ); @@ -43,7 +54,7 @@ void describe('invokeCDKCommand', () => { void it('handles options for branch deployments', async () => { await invoker.deploy(branchBackendId); assert.strictEqual(execaMock.mock.callCount(), 1); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 16); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 16); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'cdk', 'deploy', @@ -67,7 +78,7 @@ void describe('invokeCDKCommand', () => { void it('handles deployProps for sandbox', async () => { await invoker.deploy(sandboxBackendId, sandboxDeployProps); assert.strictEqual(execaMock.mock.callCount(), 1); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 18); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 18); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'cdk', 'deploy', @@ -95,7 +106,7 @@ void describe('invokeCDKCommand', () => { void it('handles options and deployProps for sandbox', async () => { await invoker.deploy(sandboxBackendId, sandboxDeployProps); assert.strictEqual(execaMock.mock.callCount(), 1); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 18); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 18); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'cdk', 'deploy', @@ -123,7 +134,7 @@ void describe('invokeCDKCommand', () => { void it('handles destroy for sandbox', async () => { await invoker.destroy(sandboxBackendId); assert.strictEqual(execaMock.mock.callCount(), 1); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 15); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 15); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'cdk', 'destroy', @@ -148,14 +159,14 @@ void describe('invokeCDKCommand', () => { validateAppSources: true, }); assert.strictEqual(execaMock.mock.callCount(), 3); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 4); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'tsc', '--showConfig', '--project', 'amplify', ]); - assert.equal(execaMock.mock.calls[1].arguments[1]?.length, 5); + assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 5); assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ 'tsc', '--noEmit', @@ -163,7 +174,7 @@ void describe('invokeCDKCommand', () => { '--project', 'amplify', ]); - assert.equal(execaMock.mock.calls[2].arguments[1]?.length, 16); + assert.equal(execaMock.mock.calls[2].arguments[0]?.length, 16); assert.deepStrictEqual(execaMock.mock.calls[2].arguments[1], [ 'cdk', 'deploy', @@ -189,14 +200,14 @@ void describe('invokeCDKCommand', () => { validateAppSources: true, }); assert.strictEqual(execaMock.mock.callCount(), 3); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 4); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'tsc', '--showConfig', '--project', 'amplify', ]); - assert.equal(execaMock.mock.calls[1].arguments[1]?.length, 5); + assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 5); assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ 'tsc', '--noEmit', @@ -204,7 +215,7 @@ void describe('invokeCDKCommand', () => { '--project', 'amplify', ]); - assert.equal(execaMock.mock.calls[2].arguments[1]?.length, 16); + assert.equal(execaMock.mock.calls[2].arguments[0]?.length, 16); assert.deepStrictEqual(execaMock.mock.calls[2].arguments[1], [ 'cdk', 'deploy', @@ -234,14 +245,14 @@ void describe('invokeCDKCommand', () => { validateAppSources: true, }); assert.strictEqual(execaMock.mock.callCount(), 2); - assert.equal(execaMock.mock.calls[0].arguments[1]?.length, 4); + assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ 'tsc', '--showConfig', '--project', 'amplify', ]); - assert.equal(execaMock.mock.calls[1].arguments[1]?.length, 16); + assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 16); assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ 'cdk', 'deploy', @@ -263,7 +274,7 @@ void describe('invokeCDKCommand', () => { }); void it('returns human readable errors', async () => { - mock.method(invoker, 'executeChildProcess', () => { + mock.method(invoker, 'executeCommand', () => { throw new Error('Access Denied'); }); diff --git a/packages/backend-deployer/src/cdk_deployer.ts b/packages/backend-deployer/src/cdk_deployer.ts index 088f611f6e2..fa6c09a9eb6 100644 --- a/packages/backend-deployer/src/cdk_deployer.ts +++ b/packages/backend-deployer/src/cdk_deployer.ts @@ -1,4 +1,3 @@ -import { execa } from 'execa'; import stream from 'stream'; import readline from 'readline'; import { @@ -8,7 +7,10 @@ import { DestroyResult, } from './cdk_deployer_singleton_factory.js'; import { CdkErrorMapper } from './cdk_error_mapper.js'; -import { BackendIdentifier } from '@aws-amplify/plugin-types'; +import { + BackendIdentifier, + type PackageManagerController, +} from '@aws-amplify/plugin-types'; import { AmplifyUserError, BackendLocator, @@ -34,13 +36,8 @@ export class CDKDeployer implements BackendDeployer { constructor( private readonly cdkErrorMapper: CdkErrorMapper, private readonly backendLocator: BackendLocator, - private readonly packageManager: string - ) { - // TODO: use PackageManagerController to get the executable. - // But first, we need to move the PackageManagerController to platform-core. - this.packageManager = - this.packageManager === 'npm' ? 'npx' : this.packageManager; - } + private readonly packageManagerController: PackageManagerController + ) {} /** * Invokes cdk deploy command */ @@ -77,8 +74,7 @@ export class CDKDeployer implements BackendDeployer { * Wrapper for the child process executor. Helps in unit testing as node:test framework * doesn't have capabilities to mock exported functions like `execa` as of right now. */ - executeChildProcess = async ( - command: string, + executeCommand = async ( commandArgs: string[], options: { printStdout: boolean } = { printStdout: true } ) => { @@ -92,17 +88,20 @@ export class CDKDeployer implements BackendDeployer { aggregatedStderr += chunk; done(); }; + const childProcess = this.packageManagerController.runWithPackageManager( + commandArgs, + process.cwd(), + { + stdin: 'inherit', + stdout: 'pipe', + stderr: 'pipe', + // Piping the output by default strips off the color. This is a workaround to + // preserve the color being piped to parent process. + extendEnv: true, + env: { FORCE_COLOR: '1' }, + } + ); - const childProcess = execa(command, commandArgs, { - stdin: 'inherit', - stdout: 'pipe', - stderr: 'pipe', - - // Piping the output by default strips off the color. This is a workaround to - // preserve the color being piped to parent process. - extendEnv: true, - env: { FORCE_COLOR: '1' }, - }); childProcess.stderr?.pipe(aggregatorStderrStream); if (options?.printStdout) { @@ -131,8 +130,7 @@ export class CDKDeployer implements BackendDeployer { return; } try { - await this.executeChildProcess( - this.packageManager, + await this.executeCommand( [ 'tsc', '--showConfig', @@ -146,7 +144,7 @@ export class CDKDeployer implements BackendDeployer { return; } try { - await this.executeChildProcess(this.packageManager, [ + await this.executeCommand([ 'tsc', '--noEmit', '--skipLibCheck', @@ -201,7 +199,10 @@ export class CDKDeployer implements BackendDeployer { // See https://github.com/aws/aws-cdk/issues/7717 for more details. '--ci', '--app', - `'${this.packageManager} tsx ${this.backendLocator.locate()}'`, + this.packageManagerController.getCommand([ + 'tsx', + this.backendLocator.locate(), + ]), '--all', '--output', '.amplify/artifacts/cdk.out', @@ -228,7 +229,7 @@ export class CDKDeployer implements BackendDeployer { cdkCommandArgs.push(...additionalArguments); } - return await this.executeChildProcess(this.packageManager, cdkCommandArgs); + return await this.executeCommand(cdkCommandArgs); }; private populateCDKOutputFromStdout = async ( diff --git a/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts b/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts index 1bc3eb021a2..5c0ede5059c 100644 --- a/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts +++ b/packages/backend-deployer/src/cdk_deployer_singleton_factory.ts @@ -1,4 +1,7 @@ -import { BackendIdentifier } from '@aws-amplify/plugin-types'; +import { + BackendIdentifier, + type PackageManagerController, +} from '@aws-amplify/plugin-types'; import { CDKDeployer } from './cdk_deployer.js'; import { CdkErrorMapper } from './cdk_error_mapper.js'; import { BackendLocator } from '@aws-amplify/platform-core'; @@ -38,22 +41,24 @@ export type BackendDeployer = { export class BackendDeployerFactory { private static instance: BackendDeployer | undefined; + /** + * constructor - sets the packageManagerController + */ + constructor( + private readonly packageManagerController: PackageManagerController + ) {} + /** * Returns a single instance of BackendDeployer */ - static getInstance = (): BackendDeployer => { + getInstance(): BackendDeployer { if (!BackendDeployerFactory.instance) { - // TODO: once the e2e flow test is complete, we need to refactor this to detect the package manager. Similar as what we did in create-amplify. - const { PACKAGE_MANAGER = 'npm' } = process.env; - const packageManager = PACKAGE_MANAGER.startsWith('yarn') - ? 'yarn' - : PACKAGE_MANAGER; BackendDeployerFactory.instance = new CDKDeployer( new CdkErrorMapper(), new BackendLocator(), - packageManager + this.packageManagerController ); } return BackendDeployerFactory.instance; - }; + } } diff --git a/packages/cli-core/API.md b/packages/cli-core/API.md index 519f9001f7d..56b39f28499 100644 --- a/packages/cli-core/API.md +++ b/packages/cli-core/API.md @@ -6,6 +6,8 @@ /// +import { PackageManagerController } from '@aws-amplify/plugin-types'; + // @public export class AmplifyPrompter { static input: (options: { @@ -35,6 +37,12 @@ export enum LogLevel { INFO = 1 } +// @public +export class PackageManagerControllerFactory { + constructor(cwd: string, printer: Printer); + getPackageManagerController(): PackageManagerController; +} + // @public export class Printer { constructor(minimumLogLevel: LogLevel, stdout?: NodeJS.WriteStream, stderr?: NodeJS.WriteStream, refreshRate?: number); diff --git a/packages/cli-core/package.json b/packages/cli-core/package.json index 01cafb5d499..cacc7342b45 100644 --- a/packages/cli-core/package.json +++ b/packages/cli-core/package.json @@ -18,6 +18,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@inquirer/prompts": "^3.0.0" + "@inquirer/prompts": "^3.0.0", + "execa": "^8.0.1" } } diff --git a/packages/cli-core/src/index.ts b/packages/cli-core/src/index.ts index 8bdb5bfd54b..ae1ac399425 100644 --- a/packages/cli-core/src/index.ts +++ b/packages/cli-core/src/index.ts @@ -1,3 +1,4 @@ export * from './prompter/amplify_prompts.js'; export { COLOR } from './colors.js'; export * from './printer/printer.js'; +export * from './package-manager-controller/package_manager_controller_factory.js'; diff --git a/packages/create-amplify/src/execute_with_logger.test.ts b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts similarity index 94% rename from packages/create-amplify/src/execute_with_logger.test.ts rename to packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts index 11607b06144..2e5a41c40d9 100644 --- a/packages/create-amplify/src/execute_with_logger.test.ts +++ b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts @@ -1,6 +1,6 @@ import assert from 'assert'; import { beforeEach, describe, it, mock } from 'node:test'; -import { executeWithDebugLogger } from './execute_with_logger.js'; +import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; const execaMock = mock.fn(); diff --git a/packages/create-amplify/src/execute_with_logger.ts b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.ts similarity index 76% rename from packages/create-amplify/src/execute_with_logger.ts rename to packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.ts index 86ebd4f2f92..7f402c8f71b 100644 --- a/packages/create-amplify/src/execute_with_logger.ts +++ b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.ts @@ -1,20 +1,22 @@ import { LogLevel } from '@aws-amplify/cli-core'; -import { execa as _execa } from 'execa'; -import { printer } from './printer.js'; +import { type Options, execa as _execa } from 'execa'; +import { printer } from '../printer.js'; /** * Abstracts the execution of a command and pipes outputs/errors to `Printer.debug` */ -export const executeWithDebugLogger = async ( +export const executeWithDebugLogger = ( cwd: string, executable: string, args?: Readonly, - execa = _execa + execa = _execa, + options?: Options<'utf8'> ) => { try { const childProcess = execa(executable, args, { stdin: 'inherit', cwd, + ...options, }); childProcess?.stdout?.on('data', (data: string) => @@ -24,7 +26,7 @@ export const executeWithDebugLogger = async ( printer.log(data, LogLevel.DEBUG) ); - await childProcess; + return childProcess; } catch { throw new Error( `\`${executable}${ diff --git a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/npm_package_manager_controller.test.ts similarity index 90% rename from packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts rename to packages/cli-core/src/package-manager-controller/npm_package_manager_controller.test.ts index b421f35c617..da42cbbf581 100644 --- a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/npm_package_manager_controller.test.ts @@ -4,6 +4,7 @@ import { beforeEach, describe, it, mock } from 'node:test'; import assert from 'assert'; import { execa } from 'execa'; import { NpmPackageManagerController } from './npm_package_manager_controller.js'; +import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; void describe('NpmPackageManagerController', () => { const fspMock = mock.fn(() => Promise.resolve()); @@ -27,7 +28,7 @@ void describe('NpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); void it('runs npm install with the correct arguments', async () => { @@ -67,7 +68,7 @@ void describe('NpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -90,7 +91,7 @@ void describe('NpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -110,7 +111,7 @@ void describe('NpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -128,7 +129,7 @@ void describe('NpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); await npmPackageManagerController.initializeTsConfig('./amplify'); diff --git a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/npm_package_manager_controller.ts similarity index 82% rename from packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts rename to packages/cli-core/src/package-manager-controller/npm_package_manager_controller.ts index 2c90197289e..124f41d1707 100644 --- a/packages/create-amplify/src/package-manager-controller/npm_package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/npm_package_manager_controller.ts @@ -2,18 +2,18 @@ import { existsSync as _existsSync } from 'fs'; import _fsp from 'fs/promises'; import { execa as _execa } from 'execa'; import * as _path from 'path'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; -import { PackageManagerController } from './package_manager_controller.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_debugger_logger.js'; +import { PackageManagerControllerBase } from './package_manager_controller_base.js'; /** * NpmPackageManagerController is an abstraction around npm commands that are needed to initialize a project and install dependencies */ -export class NpmPackageManagerController extends PackageManagerController { +export class NpmPackageManagerController extends PackageManagerControllerBase { /** * constructor */ constructor( - readonly projectRoot: string, + protected readonly cwd: string, protected readonly fsp = _fsp, protected readonly path = _path, protected readonly execa = _execa, @@ -21,7 +21,7 @@ export class NpmPackageManagerController extends PackageManagerController { protected readonly existsSync = _existsSync ) { super( - projectRoot, + cwd, 'npm', 'npx', ['init', '--yes'], diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts similarity index 73% rename from packages/create-amplify/src/package-manager-controller/package_manager_controller.ts rename to packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts index f49052d5bc8..f15ec42dcba 100644 --- a/packages/create-amplify/src/package-manager-controller/package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts @@ -1,20 +1,23 @@ import { existsSync as _existsSync } from 'fs'; import _fsp from 'fs/promises'; -import { execa as _execa } from 'execa'; +import { type ExecaChildProcess, type Options, execa as _execa } from 'execa'; import * as _path from 'path'; -import { logger } from '../logger.js'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; -import { DependencyType } from './package_manager_controller_factory.js'; +import { type PackageManagerController } from '@aws-amplify/plugin-types'; +import { LogLevel } from '../printer/printer.js'; +import { printer } from '../printer.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_debugger_logger.js'; /** * PackageManagerController is an abstraction around package manager commands that are needed to initialize a project and install dependencies */ -export abstract class PackageManagerController { +export abstract class PackageManagerControllerBase + implements PackageManagerController +{ /** * constructor - sets the project root */ constructor( - readonly projectRoot: string, + protected readonly cwd: string, protected readonly executable: string, protected readonly binaryRunner: string, protected readonly initDefault: string[], @@ -31,7 +34,7 @@ export abstract class PackageManagerController { */ async installDependencies( packageNames: string[], - type: DependencyType + type: 'dev' | 'prod' ): Promise { const args = [`${this.installCommand}`].concat(...packageNames); if (type === 'dev') { @@ -39,7 +42,7 @@ export abstract class PackageManagerController { } await this.executeWithDebugLogger( - this.projectRoot, + this.cwd, this.executable, args, this.execa @@ -57,18 +60,19 @@ Get started by running \`${this.binaryRunner} amplify sandbox\`.`; * initializeProject - initializes a project in the project root by checking the package.json file */ initializeProject = async () => { - if (this.packageJsonExists(this.projectRoot)) { + if (this.packageJsonExists(this.cwd)) { // if package.json already exists, no need to do anything return; } - logger.debug( - `No package.json file found in the current directory. Running \`${this.executable} init\`...` + printer.log( + `No package.json file found in the current directory. Running \`${this.executable} init\`...`, + LogLevel.DEBUG ); try { await this.executeWithDebugLogger( - this.projectRoot, + this.cwd, this.executable, this.initDefault, this.execa @@ -79,7 +83,7 @@ Get started by running \`${this.binaryRunner} amplify sandbox\`.`; ); } - if (!this.packageJsonExists(this.projectRoot)) { + if (!this.packageJsonExists(this.cwd)) { // this should only happen if the customer exits out of npm init before finishing throw new Error( `package.json does not exist after running \`${this.executable} init\`. Initialize a valid JavaScript package before continuing.'` @@ -112,6 +116,25 @@ Get started by running \`${this.binaryRunner} amplify sandbox\`.`; ); } + /** + * runWithPackageManager - Factory function that runs a command with the specified package manager's binary runner + */ + runWithPackageManager( + args: string[] = [], + dir: string, + options?: Options<'utf8'> + ): ExecaChildProcess { + return this.executeWithDebugLogger( + dir, + this.binaryRunner, + args, + this.execa, + options + ); + } + + getCommand = (args: string[]) => `${this.binaryRunner} ${args.join(' ')}`; + /** * Check if a package.json file exists in projectRoot */ diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts similarity index 78% rename from packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts rename to packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts index b22656e1799..9c946f2ff61 100644 --- a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.test.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts @@ -1,8 +1,9 @@ import { describe, it } from 'node:test'; import assert from 'assert'; import { PackageManagerControllerFactory } from './package_manager_controller_factory.js'; -import { PackageManagerController } from './package_manager_controller.js'; +import { PackageManagerControllerBase } from './package_manager_controller_base.js'; import { NpmPackageManagerController } from './npm_package_manager_controller.js'; +import { printer } from '../printer.js'; void describe('packageManagerControllerFactory', () => { const packageRoot = '/path/to/project'; @@ -17,24 +18,24 @@ void describe('packageManagerControllerFactory', () => { { name: 'pnpm', userAgent: 'pnpm/5.0.0 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerController, + expectedInstanceof: PackageManagerControllerBase, }, { name: 'yarn classic', userAgent: 'yarn/1.22.21 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerController, + expectedInstanceof: PackageManagerControllerBase, }, { name: 'yarn modern', userAgent: 'yarn/4.0.1 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerController, + expectedInstanceof: PackageManagerControllerBase, }, ]; for (const testCase of testCases) { void it(`should return the correct package manager controller for ${testCase.name}`, () => { const packageManagerControllerFactory = - new PackageManagerControllerFactory(packageRoot, testCase.userAgent); + new PackageManagerControllerFactory(packageRoot, printer); const packageManagerController = packageManagerControllerFactory.getPackageManagerController(); @@ -46,7 +47,7 @@ void describe('packageManagerControllerFactory', () => { void it('should throw an error for unsupported package managers', () => { const packageManagerControllerFactory = - new PackageManagerControllerFactory(packageRoot, 'unsupported'); + new PackageManagerControllerFactory(packageRoot, printer); assert.throws( () => packageManagerControllerFactory.getPackageManagerController(), Error, diff --git a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts similarity index 65% rename from packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts rename to packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts index 2924c00552d..3d882a9feff 100644 --- a/packages/create-amplify/src/package-manager-controller/package_manager_controller_factory.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts @@ -1,40 +1,37 @@ -import { execa as _execa } from 'execa'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; +import { type PackageManagerController } from '@aws-amplify/plugin-types'; +import { Printer } from '../printer/printer.js'; import { NpmPackageManagerController } from './npm_package_manager_controller.js'; import { PnpmPackageManagerController } from './pnpm_package_manager_controller.js'; import { YarnClassicPackageManagerController } from './yarn_classic_package_manager_controller.js'; import { YarnModernPackageManagerController } from './yarn_modern_package_manager_controller.js'; -export type DependencyType = 'dev' | 'prod'; - /** * packageManagerControllerFactory is an abstraction around package manager commands that are needed to initialize a project and install dependencies */ export class PackageManagerControllerFactory { /** * constructor - * @param projectRoot - the root directory of the project - * @param userAgent - the user agent of the package manager + * @param cwd - the root directory of the project */ constructor( - private readonly projectRoot: string, - private readonly userAgent: string + private readonly cwd: string, + private readonly printer: Printer ) {} /** * getPackageManagerController - returns the package manager controller for each package manager */ - getPackageManagerController() { + getPackageManagerController(): PackageManagerController { const packageManagerName = this.getPackageManagerName(); switch (packageManagerName) { case 'npm': - return new NpmPackageManagerController(this.projectRoot); + return new NpmPackageManagerController(this.cwd); case 'pnpm': - return new PnpmPackageManagerController(this.projectRoot); + return new PnpmPackageManagerController(this.cwd); case 'yarn-classic': - return new YarnClassicPackageManagerController(this.projectRoot); + return new YarnClassicPackageManagerController(this.cwd); case 'yarn-modern': - return new YarnModernPackageManagerController(this.projectRoot); + return new YarnModernPackageManagerController(this.cwd, this.printer); default: throw new Error( `Package Manager ${packageManagerName} is not supported.` @@ -46,7 +43,11 @@ export class PackageManagerControllerFactory { * getPackageManagerName - returns the name of the package manager */ private getPackageManagerName() { - const packageManagerAndVersion = this.userAgent.split(' ')[0]; + const userAgent = process.env.npm_config_user_agent; + if (userAgent === undefined) { + throw new Error('npm_config_user_agent is undefined'); + } + const packageManagerAndVersion = userAgent.split(' ')[0]; const [packageManagerName, packageManagerVersion] = packageManagerAndVersion.split('/'); diff --git a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.test.ts similarity index 90% rename from packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts rename to packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.test.ts index 1d1bf292b40..24cef9f8975 100644 --- a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.test.ts @@ -4,6 +4,7 @@ import { beforeEach, describe, it, mock } from 'node:test'; import assert from 'assert'; import { execa } from 'execa'; import { PnpmPackageManagerController } from './pnpm_package_manager_controller.js'; +import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; void describe('PnpmPackageManagerController', () => { const fspMock = mock.fn(() => Promise.resolve()); @@ -27,7 +28,7 @@ void describe('PnpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); void it('runs pnpm install with the correct arguments', async () => { @@ -67,7 +68,7 @@ void describe('PnpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -90,7 +91,7 @@ void describe('PnpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -110,7 +111,7 @@ void describe('PnpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -128,7 +129,7 @@ void describe('PnpmPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); await pnpmPackageManagerController.initializeTsConfig('./amplify'); diff --git a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.ts similarity index 82% rename from packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts rename to packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.ts index 193b881ae0d..308da76061e 100644 --- a/packages/create-amplify/src/package-manager-controller/pnpm_package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/pnpm_package_manager_controller.ts @@ -2,18 +2,18 @@ import _fsp from 'fs/promises'; import * as _path from 'path'; import { existsSync as _existsSync } from 'fs'; import { execa as _execa } from 'execa'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; -import { PackageManagerController } from './package_manager_controller.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_debugger_logger.js'; +import { PackageManagerControllerBase } from './package_manager_controller_base.js'; /** * PnpmPackageManagerController is an abstraction around pnpm commands that are needed to initialize a project and install dependencies */ -export class PnpmPackageManagerController extends PackageManagerController { +export class PnpmPackageManagerController extends PackageManagerControllerBase { /** * constructor */ constructor( - readonly projectRoot: string, + protected readonly cwd: string, protected readonly fsp = _fsp, protected readonly path = _path, protected readonly execa = _execa, @@ -21,7 +21,7 @@ export class PnpmPackageManagerController extends PackageManagerController { protected readonly existsSync = _existsSync ) { super( - projectRoot, + cwd, 'pnpm', 'pnpm', ['init'], diff --git a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts similarity index 91% rename from packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts rename to packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts index 2aa9a282f0f..b4d409aef30 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.test.ts @@ -4,6 +4,7 @@ import { beforeEach, describe, it, mock } from 'node:test'; import assert from 'assert'; import { execa } from 'execa'; import { YarnClassicPackageManagerController } from './yarn_classic_package_manager_controller.js'; +import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; void describe('YarnClassicPackageManagerController', () => { const fspMock = mock.fn(() => Promise.resolve()); @@ -28,7 +29,7 @@ void describe('YarnClassicPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); void it('runs yarn add with the correct arguments', async () => { @@ -69,7 +70,7 @@ void describe('YarnClassicPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -93,7 +94,7 @@ void describe('YarnClassicPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -114,7 +115,7 @@ void describe('YarnClassicPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -133,7 +134,7 @@ void describe('YarnClassicPackageManagerController', () => { fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); await yarnClassicPackageManagerController.initializeTsConfig('./amplify'); diff --git a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.ts similarity index 87% rename from packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts rename to packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.ts index c438be9d1f8..690d8c30534 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_classic_package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_classic_package_manager_controller.ts @@ -2,18 +2,18 @@ import { existsSync as _existsSync } from 'fs'; import _fsp from 'fs/promises'; import { execa as _execa } from 'execa'; import * as _path from 'path'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; -import { PackageManagerController } from './package_manager_controller.js'; +import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_debugger_logger.js'; +import { PackageManagerControllerBase } from './package_manager_controller_base.js'; /** * YarnClassicPackageManagerController is an abstraction around yarn classic commands that are needed to initialize a project and install dependencies */ -export class YarnClassicPackageManagerController extends PackageManagerController { +export class YarnClassicPackageManagerController extends PackageManagerControllerBase { /** * Abstraction around yarn classic commands that are needed to initialize a project and install dependencies */ constructor( - readonly projectRoot: string, + protected readonly cwd: string, protected readonly fsp = _fsp, protected readonly path = _path, protected readonly execa = _execa, @@ -21,7 +21,7 @@ export class YarnClassicPackageManagerController extends PackageManagerControlle protected readonly existsSync = _existsSync ) { super( - projectRoot, + cwd, 'yarn', 'yarn', ['init', '--yes'], diff --git a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts similarity index 86% rename from packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts rename to packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts index 58340e6c84b..a9632d3d25d 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts @@ -4,7 +4,9 @@ import path from 'path'; import { beforeEach, describe, it, mock } from 'node:test'; import assert from 'assert'; import { execa } from 'execa'; +import { Printer } from '@aws-amplify/cli-core'; import { YarnModernPackageManagerController } from './yarn_modern_package_manager_controller.js'; +import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; void describe('YarnModernPackageManagerController', () => { const fspMock = mock.fn(() => Promise.resolve()); @@ -13,6 +15,7 @@ void describe('YarnModernPackageManagerController', () => { }; const execaMock = mock.fn(() => Promise.resolve()); const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); + const printerMock = mock.fn(() => Promise.resolve()); beforeEach(() => { fspMock.mock.resetCalls(); @@ -26,10 +29,11 @@ void describe('YarnModernPackageManagerController', () => { const yarnModernPackageManagerController = new YarnModernPackageManagerController( '/testProjectRoot', + printerMock as unknown as Printer, fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); void it('runs yarn add with the correct arguments', async () => { @@ -67,10 +71,11 @@ void describe('YarnModernPackageManagerController', () => { const yarnModernPackageManagerController = new YarnModernPackageManagerController( '/testProjectRoot', + printerMock as unknown as Printer, fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -91,10 +96,11 @@ void describe('YarnModernPackageManagerController', () => { const yarnModernPackageManagerController = new YarnModernPackageManagerController( '/testProjectRoot', + printerMock as unknown as Printer, fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -112,10 +118,11 @@ void describe('YarnModernPackageManagerController', () => { const yarnModernPackageManagerController = new YarnModernPackageManagerController( '/testProjectRoot', + printerMock as unknown as Printer, fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); @@ -131,10 +138,11 @@ void describe('YarnModernPackageManagerController', () => { const yarnModernPackageManagerController = new YarnModernPackageManagerController( '/testProjectRoot', + printerMock as unknown as Printer, fspMock as unknown as typeof fsp, pathMock as unknown as typeof path, execaMock as unknown as typeof execa, - executeWithDebugLoggerMock, + executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); const writeFileMock = mock.fn(() => Promise.resolve()); diff --git a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts similarity index 77% rename from packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts rename to packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts index 2d81bed5433..dc4d219f19f 100644 --- a/packages/create-amplify/src/package-manager-controller/yarn_modern_package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts @@ -2,20 +2,20 @@ import { existsSync as _existsSync } from 'fs'; import _fsp from 'fs/promises'; import { execa as _execa } from 'execa'; import * as _path from 'path'; -import { logger } from '../logger.js'; -import { executeWithDebugLogger as _executeWithDebugLogger } from '../execute_with_logger.js'; -import { PackageManagerController } from './package_manager_controller.js'; -import { DependencyType } from './package_manager_controller_factory.js'; +import { LogLevel, Printer } from '@aws-amplify/cli-core'; +import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_debugger_logger.js'; +import { PackageManagerControllerBase } from './package_manager_controller_base.js'; /** * YarnModernPackageManagerController is an abstraction around yarn modern (yarn v2+) commands that are needed to initialize a project and install dependencies */ -export class YarnModernPackageManagerController extends PackageManagerController { +export class YarnModernPackageManagerController extends PackageManagerControllerBase { /** * constructor */ constructor( - readonly projectRoot: string, + protected readonly cwd: string, + private readonly printer: Printer, protected readonly fsp = _fsp, protected readonly path = _path, protected readonly execa = _execa, @@ -23,7 +23,7 @@ export class YarnModernPackageManagerController extends PackageManagerController protected readonly existsSync = _existsSync ) { super( - projectRoot, + cwd, 'yarn', 'yarn', ['init', '--yes'], @@ -38,9 +38,9 @@ export class YarnModernPackageManagerController extends PackageManagerController installDependencies: ( packageNames: string[], - type: DependencyType + type: 'dev' | 'prod' ) => Promise = async (packageNames, type) => { - await this.addDependencies(this.projectRoot); + await this.addDependencies(this.cwd); await super.installDependencies(packageNames, type); }; @@ -58,9 +58,15 @@ export class YarnModernPackageManagerController extends PackageManagerController await this.fsp.writeFile(this.path.resolve(targetDir, 'yarn.lock'), ''); } catch (error) { if (typeof error === 'string') { - logger.error(`Error creating ${targetDir}/yarn.lock ${error}}`); + this.printer.log( + `Error creating ${targetDir}/yarn.lock ${error}}`, + LogLevel.ERROR + ); } else if (error instanceof Error) { - logger.error(`Error creating ${targetDir}/yarn.lock ${error.message}}`); + this.printer.log( + `Error creating ${targetDir}/yarn.lock ${error.message}}`, + LogLevel.ERROR + ); } } }; diff --git a/packages/cli-core/src/printer.ts b/packages/cli-core/src/printer.ts new file mode 100644 index 00000000000..93b771431c1 --- /dev/null +++ b/packages/cli-core/src/printer.ts @@ -0,0 +1,7 @@ +import { LogLevel, Printer } from './printer/printer.js'; + +const minimumLogLevel = process.argv.includes('--debug') + ? LogLevel.DEBUG + : LogLevel.INFO; + +export const printer = new Printer(minimumLogLevel); diff --git a/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command.test.ts b/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command.test.ts index c9ca572aa8f..c2b84354311 100644 --- a/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command.test.ts +++ b/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command.test.ts @@ -11,6 +11,11 @@ import { } from './pipeline_deploy_command.js'; import { BackendDeployerFactory } from '@aws-amplify/backend-deployer'; import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; +import { + LogLevel, + PackageManagerControllerFactory, + Printer, +} from '@aws-amplify/cli-core'; import { ClientConfigGeneratorAdapter } from '../../client-config/client_config_generator_adapter.js'; void describe('deploy command', () => { @@ -23,9 +28,15 @@ void describe('deploy command', () => { 'generateClientConfigToFile', () => Promise.resolve() ); - + const packageManagerControllerFactory = new PackageManagerControllerFactory( + process.cwd(), + new Printer(LogLevel.DEBUG) + ); const getCommandRunner = (isCI = false) => { - const backendDeployer = BackendDeployerFactory.getInstance(); + const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() + ); + const backendDeployer = backendDeployerFactory.getInstance(); const deployCommand = new PipelineDeployCommand( clientConfigGenerator, backendDeployer, @@ -63,8 +74,11 @@ void describe('deploy command', () => { }); void it('executes backend deployer in CI environments', async () => { + const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() + ); const mockDeploy = mock.method( - BackendDeployerFactory.getInstance(), + backendDeployerFactory.getInstance(), 'deploy', () => Promise.resolve() ); @@ -86,8 +100,11 @@ void describe('deploy command', () => { }); void it('allows --config-out-dir argument', async () => { + const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() + ); const mockDeploy = mock.method( - BackendDeployerFactory.getInstance(), + backendDeployerFactory.getInstance(), 'deploy', () => Promise.resolve() ); diff --git a/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command_factory.ts b/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command_factory.ts index abf3b004a18..c759f37d75f 100644 --- a/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command_factory.ts +++ b/packages/cli/src/commands/pipeline-deploy/pipeline_deploy_command_factory.ts @@ -1,5 +1,6 @@ import { CommandModule } from 'yargs'; import { BackendDeployerFactory } from '@aws-amplify/backend-deployer'; +import { PackageManagerControllerFactory } from '@aws-amplify/cli-core'; import { PipelineDeployCommand, @@ -7,6 +8,7 @@ import { } from './pipeline_deploy_command.js'; import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; import { ClientConfigGeneratorAdapter } from '../../client-config/client_config_generator_adapter.js'; +import { printer } from '../../printer.js'; /** * Creates pipeline deploy command @@ -19,6 +21,13 @@ export const createPipelineDeployCommand = (): CommandModule< const clientConfigGenerator = new ClientConfigGeneratorAdapter( credentialProvider ); - const backendDeployer = BackendDeployerFactory.getInstance(); + const packageManagerControllerFactory = new PackageManagerControllerFactory( + process.cwd(), + printer + ); + const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() + ); + const backendDeployer = backendDeployerFactory.getInstance(); return new PipelineDeployCommand(clientConfigGenerator, backendDeployer); }; diff --git a/packages/create-amplify/package.json b/packages/create-amplify/package.json index 8e4ff2fc1f9..0342b91c0a2 100644 --- a/packages/create-amplify/package.json +++ b/packages/create-amplify/package.json @@ -18,6 +18,7 @@ "dependencies": { "@aws-amplify/cli-core": "^0.3.0", "@aws-amplify/platform-core": "^0.4.3", + "@aws-amplify/plugin-types": "^0.7.1", "execa": "^8.0.1", "yargs": "^17.7.2" } diff --git a/packages/create-amplify/src/amplify_project_creator.test.ts b/packages/create-amplify/src/amplify_project_creator.test.ts index ba7a0c443fa..090e7a436ee 100644 --- a/packages/create-amplify/src/amplify_project_creator.test.ts +++ b/packages/create-amplify/src/amplify_project_creator.test.ts @@ -13,12 +13,6 @@ void describe('AmplifyProjectCreator', () => { }); void it('create project if passing `--yes` or `-y` to `npm create`', async () => { - const logMock = { - log: mock.fn(), - debug: mock.fn(), - startAnimatingEllipsis: mock.fn(), - stopAnimatingEllipsis: mock.fn(), - }; const packageManagerControllerMock = { installDependencies: mock.fn(), initializeProject: mock.fn(), @@ -32,6 +26,7 @@ void describe('AmplifyProjectCreator', () => { }; const gitIgnoreInitializerMock = { ensureInitialized: mock.fn() }; const amplifyProjectCreator = new AmplifyProjectCreator( + 'testProjectRoot', packageManagerControllerMock as never, projectRootValidatorMock as never, gitIgnoreInitializerMock as never, @@ -58,12 +53,6 @@ void describe('AmplifyProjectCreator', () => { }); void it('should instruct users to use the custom project root', async () => { - const logMock = { - log: mock.fn(), - debug: mock.fn(), - startAnimatingEllipsis: mock.fn(), - stopAnimatingEllipsis: mock.fn(), - }; const packageManagerControllerMock = { installDependencies: mock.fn(), initializeProject: mock.fn(), @@ -77,6 +66,7 @@ void describe('AmplifyProjectCreator', () => { generateInitialProjectFiles: mock.fn(), }; const amplifyProjectCreator = new AmplifyProjectCreator( + 'testProjectRoot', packageManagerControllerMock as never, projectRootValidatorMock as never, gitIgnoreInitializerMock as never, diff --git a/packages/create-amplify/src/amplify_project_creator.ts b/packages/create-amplify/src/amplify_project_creator.ts index ea023211f18..5e968049ab9 100644 --- a/packages/create-amplify/src/amplify_project_creator.ts +++ b/packages/create-amplify/src/amplify_project_creator.ts @@ -1,5 +1,5 @@ -import { PackageManagerController } from './package-manager-controller/package_manager_controller.js'; import { LogLevel } from '@aws-amplify/cli-core'; +import { PackageManagerController } from '@aws-amplify/plugin-types'; import { ProjectRootValidator } from './project_root_validator.js'; import { GitIgnoreInitializer } from './gitignore_initializer.js'; import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; @@ -27,6 +27,7 @@ export class AmplifyProjectCreator { * Delegates out to other classes that handle parts of the getting started experience */ constructor( + private readonly projectRoot: string, private readonly packageManagerController: PackageManagerController, private readonly projectRootValidator: ProjectRootValidator, private readonly gitIgnoreInitializer: GitIgnoreInitializer, @@ -69,10 +70,10 @@ export class AmplifyProjectCreator { printer.log('Successfully created a new project!'); const cdPreamble = - process.cwd() === this.packageManagerController.projectRoot + process.cwd() === this.projectRoot ? '' : `Navigate to your project directory using -'cd .${this.packageManagerController.projectRoot.replace(process.cwd(), '')}'. +'cd .${this.projectRoot.replace(process.cwd(), '')}'. Then get started with the following commands: `; diff --git a/packages/create-amplify/src/create_amplify.ts b/packages/create-amplify/src/create_amplify.ts index 35dc0c7e2da..f0d36e97532 100644 --- a/packages/create-amplify/src/create_amplify.ts +++ b/packages/create-amplify/src/create_amplify.ts @@ -7,30 +7,29 @@ If customers have a cached version of the create-amplify package, they might execute that cached version even after we publish features and fixes to the package on npm. */ +import { + LogLevel, + PackageManagerControllerFactory, +} from '@aws-amplify/cli-core'; import { ProjectRootValidator } from './project_root_validator.js'; import { AmplifyProjectCreator } from './amplify_project_creator.js'; -import { PackageManagerControllerFactory } from './package-manager-controller/package_manager_controller_factory.js'; import { getProjectRoot } from './get_project_root.js'; import { GitIgnoreInitializer } from './gitignore_initializer.js'; import { InitialProjectFileGenerator } from './initial_project_file_generator.js'; -import { LogLevel } from '@aws-amplify/cli-core'; import { printer } from './printer.js'; const projectRoot = await getProjectRoot(); -if (process.env.npm_config_user_agent === undefined) { - throw new Error('npm_config_user_agent is undefined'); -} - const packageManagerControllerFactory = new PackageManagerControllerFactory( projectRoot, - process.env.npm_config_user_agent + printer ); const packageManagerController = packageManagerControllerFactory.getPackageManagerController(); const amplifyProjectCreator = new AmplifyProjectCreator( + projectRoot, packageManagerController, new ProjectRootValidator(projectRoot), new GitIgnoreInitializer(projectRoot), diff --git a/packages/create-amplify/src/initial_project_file_generator.test.ts b/packages/create-amplify/src/initial_project_file_generator.test.ts index 7299d77e3d4..0ca476d944c 100644 --- a/packages/create-amplify/src/initial_project_file_generator.test.ts +++ b/packages/create-amplify/src/initial_project_file_generator.test.ts @@ -17,8 +17,7 @@ void describe('InitialProjectFileGenerator', () => { void it('creates target directory and copies files', async () => { const initialProjectFileGenerator = new InitialProjectFileGenerator( path.join(process.cwd(), 'testDir'), - fsMock as never, - executeWithDebugLoggerMock as never + fsMock as never ); await initialProjectFileGenerator.generateInitialProjectFiles(); @@ -44,8 +43,7 @@ void describe('InitialProjectFileGenerator', () => { void it('creates default tsconfig file', async () => { const initialProjectFileGenerator = new InitialProjectFileGenerator( path.join(process.cwd(), 'testDir'), - fsMock as never, - executeWithDebugLoggerMock as never + fsMock as never ); await initialProjectFileGenerator.generateInitialProjectFiles(); diff --git a/packages/create-amplify/src/initial_project_file_generator.ts b/packages/create-amplify/src/initial_project_file_generator.ts index 140586860b3..0c782726e56 100644 --- a/packages/create-amplify/src/initial_project_file_generator.ts +++ b/packages/create-amplify/src/initial_project_file_generator.ts @@ -1,7 +1,6 @@ import _path from 'path'; import _fsp from 'fs/promises'; -import { executeWithDebugLogger as _executeWithDebugLogger } from './execute_with_logger.js'; -import { type PackageManagerController } from './package-manager-controller/package_manager_controller.js'; +import { type PackageManagerController } from '@aws-amplify/plugin-types'; /** * InitialProjectFileGenerator is responsible for copying getting started template to a new project directory diff --git a/packages/create-amplify/tsconfig.json b/packages/create-amplify/tsconfig.json index 7729e76511a..40fc5d538a7 100644 --- a/packages/create-amplify/tsconfig.json +++ b/packages/create-amplify/tsconfig.json @@ -2,5 +2,9 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "rootDir": "src", "outDir": "lib" }, "exclude": ["templates", "lib"], - "references": [{ "path": "../cli-core" }, { "path": "../platform-core" }] + "references": [ + { "path": "../cli-core" }, + { "path": "../platform-core" }, + { "path": "../plugin-types" } + ] } diff --git a/packages/plugin-types/API.md b/packages/plugin-types/API.md index 73391aa6d0e..f78b36d5086 100644 --- a/packages/plugin-types/API.md +++ b/packages/plugin-types/API.md @@ -9,10 +9,12 @@ import { CfnIdentityPoolRoleAttachment } from 'aws-cdk-lib/aws-cognito'; import { CfnUserPool } from 'aws-cdk-lib/aws-cognito'; import { CfnUserPoolClient } from 'aws-cdk-lib/aws-cognito'; import { Construct } from 'constructs'; +import { ExecaChildProcess } from 'execa'; import { IFunction } from 'aws-cdk-lib/aws-lambda'; import { IRole } from 'aws-cdk-lib/aws-iam'; import { IUserPool } from 'aws-cdk-lib/aws-cognito'; import { IUserPoolClient } from 'aws-cdk-lib/aws-cognito'; +import { Options } from 'execa'; import { SecretValue } from 'aws-cdk-lib'; import { Stack } from 'aws-cdk-lib'; @@ -135,6 +137,16 @@ export type MainStackNameResolver = { resolveMainStackName: () => Promise; }; +// @public (undocumented) +export type PackageManagerController = { + getWelcomeMessage: () => string; + initializeProject: () => Promise; + initializeTsConfig: (targetDir: string) => Promise; + installDependencies: (packageNames: string[], type: 'dev' | 'prod') => Promise; + runWithPackageManager: (args: string[] | undefined, dir: string, options?: Options<'utf8'>) => ExecaChildProcess; + getCommand: (args: string[]) => string; +}; + // @public (undocumented) export type ProjectName = string; diff --git a/packages/plugin-types/package.json b/packages/plugin-types/package.json index e8a5f0a2d0e..b4f19ff89ad 100644 --- a/packages/plugin-types/package.json +++ b/packages/plugin-types/package.json @@ -16,5 +16,8 @@ }, "imports": { "#package.json": "./package.json" + }, + "devDependencies": { + "execa": "^5.1.1" } } diff --git a/packages/plugin-types/src/index.ts b/packages/plugin-types/src/index.ts index 74757ba7f73..138441839b3 100644 --- a/packages/plugin-types/src/index.ts +++ b/packages/plugin-types/src/index.ts @@ -13,3 +13,4 @@ export * from './function_resources.js'; export * from './amplify_function.js'; export * from './backend_identifier.js'; export * from './deployment_type.js'; +export * from './package_manager_controller.js'; diff --git a/packages/plugin-types/src/package_manager_controller.ts b/packages/plugin-types/src/package_manager_controller.ts new file mode 100644 index 00000000000..65a3a655152 --- /dev/null +++ b/packages/plugin-types/src/package_manager_controller.ts @@ -0,0 +1,22 @@ +/** + * TODO: use the latest execa. + * execa v8 doesn't support commonjs, so we need to use the types from v5 + * https://github.com/sindresorhus/execa/issues/489#issuecomment-1109983390 + */ +import { type ExecaChildProcess, type Options } from 'execa'; + +export type PackageManagerController = { + getWelcomeMessage: () => string; + initializeProject: () => Promise; + initializeTsConfig: (targetDir: string) => Promise; + installDependencies: ( + packageNames: string[], + type: 'dev' | 'prod' + ) => Promise; + runWithPackageManager: ( + args: string[] | undefined, + dir: string, + options?: Options<'utf8'> + ) => ExecaChildProcess; + getCommand: (args: string[]) => string; +}; diff --git a/packages/sandbox/src/file_watching_sandbox.test.ts b/packages/sandbox/src/file_watching_sandbox.test.ts index ee96995cb9a..30985b44a0c 100644 --- a/packages/sandbox/src/file_watching_sandbox.test.ts +++ b/packages/sandbox/src/file_watching_sandbox.test.ts @@ -17,7 +17,12 @@ import _open from 'open'; import { SecretListItem, getSecretClient } from '@aws-amplify/backend-secret'; import { ClientConfigFormat } from '@aws-amplify/client-config'; import { Sandbox } from './sandbox.js'; -import { AmplifyPrompter, Printer } from '@aws-amplify/cli-core'; +import { + AmplifyPrompter, + LogLevel, + PackageManagerControllerFactory, + Printer, +} from '@aws-amplify/cli-core'; import { fileURLToPath } from 'url'; import { BackendIdentifier } from '@aws-amplify/plugin-types'; import { AmplifyUserError } from '@aws-amplify/platform-core'; @@ -27,8 +32,14 @@ const unsubscribeMockFn = mock.fn(); const subscribeMock = mock.method(watcher, 'subscribe', async () => { return { unsubscribe: unsubscribeMockFn }; }); - -const backendDeployer = BackendDeployerFactory.getInstance(); +const packageManagerControllerFactory = new PackageManagerControllerFactory( + process.cwd(), + new Printer(LogLevel.DEBUG) +); +const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() +); +const backendDeployer = backendDeployerFactory.getInstance(); const secretClient = getSecretClient(); const newlyUpdatedSecretItem: SecretListItem = { diff --git a/packages/sandbox/src/sandbox_executor.test.ts b/packages/sandbox/src/sandbox_executor.test.ts index 41d0df61077..988cc3d3cbc 100644 --- a/packages/sandbox/src/sandbox_executor.test.ts +++ b/packages/sandbox/src/sandbox_executor.test.ts @@ -2,14 +2,25 @@ import { afterEach, describe, it, mock } from 'node:test'; import assert from 'node:assert'; import { AmplifySandboxExecutor } from './sandbox_executor.js'; import { BackendDeployerFactory } from '@aws-amplify/backend-deployer'; +import { + LogLevel, + PackageManagerControllerFactory, + Printer, +} from '@aws-amplify/cli-core'; import { SecretListItem, getSecretClient } from '@aws-amplify/backend-secret'; const logMock = mock.fn(); const mockedPrinter = { log: mock.fn(), }; - -const backendDeployer = BackendDeployerFactory.getInstance(); +const packageManagerControllerFactory = new PackageManagerControllerFactory( + process.cwd(), + new Printer(LogLevel.DEBUG) +); +const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() +); +const backendDeployer = backendDeployerFactory.getInstance(); const secretClient = getSecretClient(); const sandboxExecutor = new AmplifySandboxExecutor( backendDeployer, diff --git a/packages/sandbox/src/sandbox_singleton_factory.ts b/packages/sandbox/src/sandbox_singleton_factory.ts index 158e9e84b7f..ccd7a57a8a6 100644 --- a/packages/sandbox/src/sandbox_singleton_factory.ts +++ b/packages/sandbox/src/sandbox_singleton_factory.ts @@ -1,10 +1,13 @@ +import { + PackageManagerControllerFactory, + Printer, +} from '@aws-amplify/cli-core'; import { FileWatchingSandbox } from './file_watching_sandbox.js'; import { BackendIdSandboxResolver, Sandbox } from './sandbox.js'; import { BackendDeployerFactory } from '@aws-amplify/backend-deployer'; import { AmplifySandboxExecutor } from './sandbox_executor.js'; import { CloudFormationClient } from '@aws-sdk/client-cloudformation'; import { getSecretClient } from '@aws-amplify/backend-secret'; -import { Printer } from '@aws-amplify/cli-core'; /** * Factory to create a new sandbox @@ -24,10 +27,15 @@ export class SandboxSingletonFactory { */ getInstance = async (): Promise => { if (!this.instance) { + const packageManagerControllerFactory = + new PackageManagerControllerFactory(process.cwd(), this.printer); + const backendDeployerFactory = new BackendDeployerFactory( + packageManagerControllerFactory.getPackageManagerController() + ); this.instance = new FileWatchingSandbox( this.sandboxIdResolver, new AmplifySandboxExecutor( - BackendDeployerFactory.getInstance(), + backendDeployerFactory.getInstance(), getSecretClient(), this.printer ), From 3b923b7bb298e1e4ed901e3d7512ac15280fb435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Tue, 30 Jan 2024 20:37:06 -0800 Subject: [PATCH 14/30] patch dependencies_validator for execa --- .../plugin-types/src/package_manager_controller.ts | 1 + scripts/components/dependencies_validator.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/plugin-types/src/package_manager_controller.ts b/packages/plugin-types/src/package_manager_controller.ts index 65a3a655152..4225e3163c7 100644 --- a/packages/plugin-types/src/package_manager_controller.ts +++ b/packages/plugin-types/src/package_manager_controller.ts @@ -1,5 +1,6 @@ /** * TODO: use the latest execa. + * Issue: https://github.com/aws-amplify/amplify-backend/issues/962 * execa v8 doesn't support commonjs, so we need to use the types from v5 * https://github.com/sindresorhus/execa/issues/489#issuecomment-1109983390 */ diff --git a/scripts/components/dependencies_validator.ts b/scripts/components/dependencies_validator.ts index 3d8abb447d3..d2a82c9954e 100644 --- a/scripts/components/dependencies_validator.ts +++ b/scripts/components/dependencies_validator.ts @@ -107,7 +107,15 @@ export class DependenciesValidator { const errors: Array = []; for (const dependencyName of Object.keys(dependencyVersionsUsages)) { const dependencyVersionUsage = dependencyVersionsUsages[dependencyName]; - if (dependencyVersionUsage.allVersions.size > 1) { + + /** + * TODO: This is a temporary fix for execa version inconsistency. Remove this once execa version is fixed. + * Issue: https://github.com/aws-amplify/amplify-backend/issues/962 + */ + if ( + dependencyVersionUsage.allVersions.size > 1 /* Issue-962 Start */ && + dependencyName !== 'execa' /* Issue-962 End */ + ) { errors.push( `Dependency ${dependencyName} is declared using inconsistent versions ${JSON.stringify( dependencyVersionUsage.allDeclarations From e6f143e7046f541dc0b14cf07e0a75b2d40623ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Tue, 30 Jan 2024 21:41:15 -0800 Subject: [PATCH 15/30] fix getCommand, cdk_deployer.test, amplify_project_creator.test --- .../backend-deployer/src/cdk_deployer.test.ts | 42 ++++++++++--------- .../package_manager_controller_base.ts | 2 +- .../src/amplify_project_creator.test.ts | 29 +++++++------ 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/packages/backend-deployer/src/cdk_deployer.test.ts b/packages/backend-deployer/src/cdk_deployer.test.ts index f6457a3ce2b..c8eca9bca5f 100644 --- a/packages/backend-deployer/src/cdk_deployer.test.ts +++ b/packages/backend-deployer/src/cdk_deployer.test.ts @@ -4,7 +4,10 @@ import assert from 'node:assert'; import { AmplifyError, BackendLocator } from '@aws-amplify/platform-core'; import { DeployProps } from './cdk_deployer_singleton_factory.js'; import { CdkErrorMapper } from './cdk_error_mapper.js'; -import { BackendIdentifier } from '@aws-amplify/plugin-types'; +import { + BackendIdentifier, + PackageManagerController, +} from '@aws-amplify/plugin-types'; void describe('invokeCDKCommand', () => { const branchBackendId: BackendIdentifier = { @@ -26,12 +29,13 @@ void describe('invokeCDKCommand', () => { // This is needed for `getRelativeBackendEntryPoint` to ensure that backend file exists correctly const locateMock = mock.fn(() => 'amplify/backend.ts'); const backendLocator = { locate: locateMock } as unknown as BackendLocator; - const packageManagerControllerMock = { - installDependencies: mock.fn(), - initializeProject: mock.fn(), - getWelcomeMessage: mock.fn(() => '`npx amplify help`'), - initializeTsConfig: mock.fn(), - projectRoot: '/testProjectRoot', + const packageManagerControllerMock: PackageManagerController = { + getWelcomeMessage: mock.fn(() => ''), + initializeProject: mock.fn(() => Promise.resolve()), + initializeTsConfig: mock.fn(() => Promise.resolve()), + installDependencies: mock.fn(() => Promise.resolve()), + runWithPackageManager: mock.fn(() => Promise.resolve() as never), + getCommand: (args: string[]) => `'npx ${args.join(' ')}'`, }; const invoker = new CDKDeployer( @@ -55,7 +59,7 @@ void describe('invokeCDKCommand', () => { await invoker.deploy(branchBackendId); assert.strictEqual(execaMock.mock.callCount(), 1); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 16); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'cdk', 'deploy', '--ci', @@ -79,7 +83,7 @@ void describe('invokeCDKCommand', () => { await invoker.deploy(sandboxBackendId, sandboxDeployProps); assert.strictEqual(execaMock.mock.callCount(), 1); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 18); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'cdk', 'deploy', '--ci', @@ -107,7 +111,7 @@ void describe('invokeCDKCommand', () => { await invoker.deploy(sandboxBackendId, sandboxDeployProps); assert.strictEqual(execaMock.mock.callCount(), 1); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 18); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'cdk', 'deploy', '--ci', @@ -135,7 +139,7 @@ void describe('invokeCDKCommand', () => { await invoker.destroy(sandboxBackendId); assert.strictEqual(execaMock.mock.callCount(), 1); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 15); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'cdk', 'destroy', '--ci', @@ -160,14 +164,14 @@ void describe('invokeCDKCommand', () => { }); assert.strictEqual(execaMock.mock.callCount(), 3); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'tsc', '--showConfig', '--project', 'amplify', ]); assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 5); - assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[1].arguments[0], [ 'tsc', '--noEmit', '--skipLibCheck', @@ -175,7 +179,7 @@ void describe('invokeCDKCommand', () => { 'amplify', ]); assert.equal(execaMock.mock.calls[2].arguments[0]?.length, 16); - assert.deepStrictEqual(execaMock.mock.calls[2].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[2].arguments[0], [ 'cdk', 'deploy', '--ci', @@ -201,14 +205,14 @@ void describe('invokeCDKCommand', () => { }); assert.strictEqual(execaMock.mock.callCount(), 3); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'tsc', '--showConfig', '--project', 'amplify', ]); assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 5); - assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[1].arguments[0], [ 'tsc', '--noEmit', '--skipLibCheck', @@ -216,7 +220,7 @@ void describe('invokeCDKCommand', () => { 'amplify', ]); assert.equal(execaMock.mock.calls[2].arguments[0]?.length, 16); - assert.deepStrictEqual(execaMock.mock.calls[2].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[2].arguments[0], [ 'cdk', 'deploy', '--ci', @@ -246,14 +250,14 @@ void describe('invokeCDKCommand', () => { }); assert.strictEqual(execaMock.mock.callCount(), 2); assert.equal(execaMock.mock.calls[0].arguments[0]?.length, 4); - assert.deepStrictEqual(execaMock.mock.calls[0].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[0].arguments[0], [ 'tsc', '--showConfig', '--project', 'amplify', ]); assert.equal(execaMock.mock.calls[1].arguments[0]?.length, 16); - assert.deepStrictEqual(execaMock.mock.calls[1].arguments[1], [ + assert.deepStrictEqual(execaMock.mock.calls[1].arguments[0], [ 'cdk', 'deploy', '--ci', diff --git a/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts index f15ec42dcba..15829db26ad 100644 --- a/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_base.ts @@ -133,7 +133,7 @@ Get started by running \`${this.binaryRunner} amplify sandbox\`.`; ); } - getCommand = (args: string[]) => `${this.binaryRunner} ${args.join(' ')}`; + getCommand = (args: string[]) => `'${this.binaryRunner} ${args.join(' ')}'`; /** * Check if a package.json file exists in projectRoot diff --git a/packages/create-amplify/src/amplify_project_creator.test.ts b/packages/create-amplify/src/amplify_project_creator.test.ts index 090e7a436ee..f51104d5531 100644 --- a/packages/create-amplify/src/amplify_project_creator.test.ts +++ b/packages/create-amplify/src/amplify_project_creator.test.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, it, mock } from 'node:test'; import assert from 'assert'; +import { PackageManagerController } from '@aws-amplify/plugin-types'; import { AmplifyProjectCreator } from './amplify_project_creator.js'; import { printer } from './printer.js'; @@ -14,11 +15,12 @@ void describe('AmplifyProjectCreator', () => { void it('create project if passing `--yes` or `-y` to `npm create`', async () => { const packageManagerControllerMock = { - installDependencies: mock.fn(), - initializeProject: mock.fn(), - getWelcomeMessage: mock.fn(() => '`npx amplify help`'), - initializeTsConfig: mock.fn(), - projectRoot: '/testProjectRoot', + getWelcomeMessage: mock.fn(() => ''), + initializeProject: mock.fn(() => Promise.resolve()), + initializeTsConfig: mock.fn(() => Promise.resolve()), + installDependencies: mock.fn(() => Promise.resolve()), + runWithPackageManager: mock.fn(() => Promise.resolve() as never), + getCommand: (args: string[]) => `'npx ${args.join(' ')}'`, }; const projectRootValidatorMock = { validate: mock.fn() }; const initialProjectFileGeneratorMock = { @@ -44,7 +46,7 @@ void describe('AmplifyProjectCreator', () => { ); assert.equal( logSpy.mock.calls[4].arguments[0], - "Welcome to AWS Amplify!\nNavigate to your project directory using\n'cd ./testProjectRoot'.\nThen get started with the following commands:\n\n`npx amplify help`\n" + "Welcome to AWS Amplify! \nNavigate to your project directory using\n'cd .testProjectRoot'.\nThen get started with the following commands:\n\n" ); assert.equal( logSpy.mock.calls[5].arguments[0], @@ -53,12 +55,13 @@ void describe('AmplifyProjectCreator', () => { }); void it('should instruct users to use the custom project root', async () => { - const packageManagerControllerMock = { - installDependencies: mock.fn(), - initializeProject: mock.fn(), - getWelcomeMessage: mock.fn(() => '`npx amplify help`'), - initializeTsConfig: mock.fn(), - projectRoot: '/testProjectRoot', + const packageManagerControllerMock: PackageManagerController = { + getWelcomeMessage: mock.fn(() => ''), + initializeProject: mock.fn(() => Promise.resolve()), + initializeTsConfig: mock.fn(() => Promise.resolve()), + installDependencies: mock.fn(() => Promise.resolve()), + runWithPackageManager: mock.fn(() => Promise.resolve() as never), + getCommand: (args: string[]) => `'npx ${args.join(' ')}'`, }; const projectRootValidatorMock = { validate: mock.fn() }; const gitIgnoreInitializerMock = { ensureInitialized: mock.fn() }; @@ -76,7 +79,7 @@ void describe('AmplifyProjectCreator', () => { assert.equal( logSpy.mock.calls[4].arguments[0], - "Welcome to AWS Amplify!\nNavigate to your project directory using\n'cd ./testProjectRoot'.\nThen get started with the following commands:\n\n`npx amplify help`\n" + "Welcome to AWS Amplify! \nNavigate to your project directory using\n'cd .testProjectRoot'.\nThen get started with the following commands:\n\n" ); assert.equal( logSpy.mock.calls[5].arguments[0], From 51d6dadc4ebd0565517ccf2f6f604b69cb1c1f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Tue, 30 Jan 2024 22:02:54 -0800 Subject: [PATCH 16/30] fix initial_project_file_generator.test --- .gitignore | 2 + .../initial_project_file_generator.test.ts | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 89ff13277e5..a8e9d2bd075 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ verdaccio-logs.txt cdk.out/ e2e-tests concurrent_workspace_script_cache.json + +testDir diff --git a/packages/create-amplify/src/initial_project_file_generator.test.ts b/packages/create-amplify/src/initial_project_file_generator.test.ts index 0ca476d944c..77fa2d60662 100644 --- a/packages/create-amplify/src/initial_project_file_generator.test.ts +++ b/packages/create-amplify/src/initial_project_file_generator.test.ts @@ -10,13 +10,23 @@ void describe('InitialProjectFileGenerator', () => { writeFile: mock.fn(), }; const executeWithDebugLoggerMock = mock.fn(); + const packageManagerControllerMock = { + getWelcomeMessage: mock.fn(() => ''), + initializeProject: mock.fn(() => Promise.resolve()), + initializeTsConfig: mock.fn(() => Promise.resolve()), + installDependencies: mock.fn(() => Promise.resolve()), + runWithPackageManager: mock.fn(() => Promise.resolve() as never), + getCommand: (args: string[]) => `'npx ${args.join(' ')}'`, + }; beforeEach(() => { executeWithDebugLoggerMock.mock.resetCalls(); + packageManagerControllerMock.initializeTsConfig.mock.resetCalls(); }); void it('creates target directory and copies files', async () => { const initialProjectFileGenerator = new InitialProjectFileGenerator( path.join(process.cwd(), 'testDir'), + packageManagerControllerMock, fsMock as never ); await initialProjectFileGenerator.generateInitialProjectFiles(); @@ -43,29 +53,21 @@ void describe('InitialProjectFileGenerator', () => { void it('creates default tsconfig file', async () => { const initialProjectFileGenerator = new InitialProjectFileGenerator( path.join(process.cwd(), 'testDir'), + packageManagerControllerMock, fsMock as never ); await initialProjectFileGenerator.generateInitialProjectFiles(); - assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.equal( + packageManagerControllerMock.initializeTsConfig.mock.callCount(), + 1 + ); assert.deepStrictEqual( - executeWithDebugLoggerMock.mock.calls[0].arguments.slice(0, 3), - [ - path.join(process.cwd(), 'testDir', 'amplify'), - 'npx', - [ - 'tsc', - '--init', - '--resolveJsonModule', - 'true', - '--module', - 'es2022', - '--moduleResolution', - 'bundler', - '--target', - 'es2022', - ], - ] + packageManagerControllerMock.initializeTsConfig.mock.calls[0].arguments.slice( + 0, + 3 + ), + [path.join(process.cwd(), 'testDir', 'amplify')] ); }); }); From 99c1b0bda5c82e34dccdb30e8d773ffb9079c93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 09:55:46 -0800 Subject: [PATCH 17/30] fix executeWithDebugLogger test --- .../execute_with_debugger_logger.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts index 2e5a41c40d9..2923b8990f5 100644 --- a/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts +++ b/packages/cli-core/src/package-manager-controller/execute_with_debugger_logger.test.ts @@ -42,7 +42,7 @@ void describe(() => { throw new Error('test error'); }); - await assert.rejects( + assert.throws( () => executeWithDebugLogger( '/testProjectRoot', From 4bfda616613072bbceee200e55b10d664dc5567e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 10:24:12 -0800 Subject: [PATCH 18/30] fix YarnModernPackageManagerController test --- ..._modern_package_manager_controller.test.ts | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts index a9632d3d25d..67c388d53f8 100644 --- a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts @@ -1,4 +1,3 @@ -import fs from 'fs'; import fsp from 'fs/promises'; import path from 'path'; import { beforeEach, describe, it, mock } from 'node:test'; @@ -9,16 +8,16 @@ import { YarnModernPackageManagerController } from './yarn_modern_package_manage import { executeWithDebugLogger } from './execute_with_debugger_logger.js'; void describe('YarnModernPackageManagerController', () => { - const fspMock = mock.fn(() => Promise.resolve()); + const fspMock = { writeFile: mock.fn(() => Promise.resolve()) }; const pathMock = { resolve: mock.fn(() => '/testProjectRoot'), }; const execaMock = mock.fn(() => Promise.resolve()); const executeWithDebugLoggerMock = mock.fn(() => Promise.resolve()); - const printerMock = mock.fn(() => Promise.resolve()); + const printerMock = { log: mock.fn() } as unknown as Printer; beforeEach(() => { - fspMock.mock.resetCalls(); + fspMock.writeFile.mock.resetCalls(); pathMock.resolve.mock.resetCalls(); execaMock.mock.resetCalls(); executeWithDebugLoggerMock.mock.resetCalls(); @@ -41,11 +40,11 @@ void describe('YarnModernPackageManagerController', () => { ['testPackage1', 'testPackage2'], 'dev' ); - assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ '/testProjectRoot', 'yarn', - ['add', 'testPackage1', 'testPackage2', '-D'], + ['add', '-D', 'tsx', 'esbuild'], execaMock, ]); }); @@ -55,11 +54,11 @@ void describe('YarnModernPackageManagerController', () => { ['testPackage1', 'testPackage2'], 'prod' ); - assert.equal(executeWithDebugLoggerMock.mock.callCount(), 1); + assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); assert.deepEqual(executeWithDebugLoggerMock.mock.calls[0].arguments, [ '/testProjectRoot', 'yarn', - ['add', 'testPackage1', 'testPackage2'], + ['add', '-D', 'tsx', 'esbuild'], execaMock, ]); }); @@ -145,11 +144,11 @@ void describe('YarnModernPackageManagerController', () => { executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); - const writeFileMock = mock.fn(() => Promise.resolve()); - mock.method(fs, 'writeFile', writeFileMock); + // const writeFileMock = mock.fn(() => Promise.resolve()); + // mock.method(fsp, 'writeFile', writeFileMock); await yarnModernPackageManagerController.initializeTsConfig('./amplify'); assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); - assert.equal(writeFileMock.mock.callCount(), 1); + assert.equal(fspMock.writeFile.mock.callCount(), 1); }); }); }); From 4ee0cf235c5bbf179de5aeb1dd70b751e5c35178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 10:47:03 -0800 Subject: [PATCH 19/30] fix packageManagerControllerFactory test --- ...package_manager_controller_factory.test.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts index 9c946f2ff61..06c1d717cee 100644 --- a/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.test.ts @@ -1,4 +1,4 @@ -import { describe, it } from 'node:test'; +import { afterEach, beforeEach, describe, it } from 'node:test'; import assert from 'assert'; import { PackageManagerControllerFactory } from './package_manager_controller_factory.js'; import { PackageManagerControllerBase } from './package_manager_controller_base.js'; @@ -7,28 +7,37 @@ import { printer } from '../printer.js'; void describe('packageManagerControllerFactory', () => { const packageRoot = '/path/to/project'; + let originalEnv: NodeJS.ProcessEnv; + + beforeEach(() => { + originalEnv = process.env; + }); + + afterEach(() => { + process.env = originalEnv; + }); void describe('getPackageManagerController', () => { const testCases = [ { name: 'npm', userAgent: 'npm/7.0.0 node/v15.0.0 darwin x64', - expectedInstanceof: NpmPackageManagerController, + expectedInstanceOf: NpmPackageManagerController, }, { name: 'pnpm', userAgent: 'pnpm/5.0.0 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerControllerBase, + expectedInstanceOf: PackageManagerControllerBase, }, { name: 'yarn classic', userAgent: 'yarn/1.22.21 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerControllerBase, + expectedInstanceOf: PackageManagerControllerBase, }, { name: 'yarn modern', userAgent: 'yarn/4.0.1 node/v15.0.0 darwin x64', - expectedInstanceof: PackageManagerControllerBase, + expectedInstanceOf: PackageManagerControllerBase, }, ]; @@ -40,14 +49,17 @@ void describe('packageManagerControllerFactory', () => { const packageManagerController = packageManagerControllerFactory.getPackageManagerController(); assert.ok( - packageManagerController instanceof testCase.expectedInstanceof + packageManagerController instanceof testCase.expectedInstanceOf ); }); } void it('should throw an error for unsupported package managers', () => { + const userAgent = 'unsupported/1.0.0 node/v15.0.0 darwin x64'; + process.env.npm_config_user_agent = userAgent; const packageManagerControllerFactory = new PackageManagerControllerFactory(packageRoot, printer); + assert.throws( () => packageManagerControllerFactory.getPackageManagerController(), Error, From ead586436982e4332acf60482cbc8fa02f1cc8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 11:11:22 -0800 Subject: [PATCH 20/30] fix lint error --- .eslint_dictionary.json | 1 + .prettierignore | 1 + .../src/package_manager_sanity_checks.test.ts | 4 ---- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.eslint_dictionary.json b/.eslint_dictionary.json index 95b64816e97..57f4c61df55 100644 --- a/.eslint_dictionary.json +++ b/.eslint_dictionary.json @@ -32,6 +32,7 @@ "ecma", "enum", "enums", + "esbuild", "esnext", "execa", "facebook", diff --git a/.prettierignore b/.prettierignore index 41fc948d3cd..06c9bf69194 100644 --- a/.prettierignore +++ b/.prettierignore @@ -12,3 +12,4 @@ expected-cdk-out concurrent_workspace_script_cache.json scripts/components/api-changes-validator/test-resources/working-directory test-projects +testDir diff --git a/packages/integration-tests/src/package_manager_sanity_checks.test.ts b/packages/integration-tests/src/package_manager_sanity_checks.test.ts index ad6edd147b0..239c42dc8df 100644 --- a/packages/integration-tests/src/package_manager_sanity_checks.test.ts +++ b/packages/integration-tests/src/package_manager_sanity_checks.test.ts @@ -24,10 +24,6 @@ import { runWithPackageManager, } from './process-controller/process_controller.js'; -/** - * TODO: This test will be refactored to use the test from health-checks.test.ts and run with different package managers. - */ - void describe('getting started happy path', async () => { let branchBackendIdentifier: BackendIdentifier; let testBranch: TestBranch; From c4a03adbc6a2dc7c1fb474903fcd5285c3d416d7 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:15:40 -0800 Subject: [PATCH 21/30] Update packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts Co-authored-by: Kamil Sobol --- .../package_manager_controller_factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts index 3d882a9feff..6170acbdd01 100644 --- a/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts +++ b/packages/cli-core/src/package-manager-controller/package_manager_controller_factory.ts @@ -6,7 +6,7 @@ import { YarnClassicPackageManagerController } from './yarn_classic_package_mana import { YarnModernPackageManagerController } from './yarn_modern_package_manager_controller.js'; /** - * packageManagerControllerFactory is an abstraction around package manager commands that are needed to initialize a project and install dependencies + * PackageManagerControllerFactory is a factory for an abstraction around package manager commands that are needed to initialize a project and install dependencies */ export class PackageManagerControllerFactory { /** From e344b5b22f1378118ac633878d66f290bf8c0486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 11:18:44 -0800 Subject: [PATCH 22/30] remove never used packageManagerExecutable --- .../src/package_manager_sanity_checks.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/integration-tests/src/package_manager_sanity_checks.test.ts b/packages/integration-tests/src/package_manager_sanity_checks.test.ts index 239c42dc8df..27736dbb8de 100644 --- a/packages/integration-tests/src/package_manager_sanity_checks.test.ts +++ b/packages/integration-tests/src/package_manager_sanity_checks.test.ts @@ -16,7 +16,6 @@ import { TestBranch, amplifyAppPool } from './amplify_app_pool.js'; import { e2eToolingClientConfig } from './e2e_tooling_client_config.js'; import { type PackageManager, - type PackageManagerExecutable, setupPackageManager, } from './setup_package_manager.js'; import { @@ -29,7 +28,6 @@ void describe('getting started happy path', async () => { let testBranch: TestBranch; let cfnClient: CloudFormationClient; let tempDir: string; - let packageManagerExecutable: PackageManagerExecutable; let packageManager: PackageManager; before(async () => { @@ -46,7 +44,6 @@ void describe('getting started happy path', async () => { beforeEach(async () => { tempDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-create-amplify')); const packageManagerInfo = await setupPackageManager(tempDir); - packageManagerExecutable = packageManagerInfo.packageManagerExecutable; packageManager = packageManagerInfo.packageManager; cfnClient = new CloudFormationClient(e2eToolingClientConfig); From a4011c472965a7697ff26d0a1ee3b08aecb2c2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Wed, 31 Jan 2024 16:08:01 -0800 Subject: [PATCH 23/30] update changeset --- .changeset/eight-coats-camp.md | 5 ----- .changeset/friendly-windows-chew.md | 5 ----- .changeset/itchy-pigs-switch.md | 2 -- .changeset/metal-tomatoes-check.md | 6 ------ .changeset/new-timers-warn.md | 11 +++++++++++ .changeset/small-readers-check.md | 7 ------- .changeset/stale-poems-visit.md | 8 -------- 7 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 .changeset/eight-coats-camp.md delete mode 100644 .changeset/friendly-windows-chew.md delete mode 100644 .changeset/itchy-pigs-switch.md delete mode 100644 .changeset/metal-tomatoes-check.md create mode 100644 .changeset/new-timers-warn.md delete mode 100644 .changeset/small-readers-check.md delete mode 100644 .changeset/stale-poems-visit.md diff --git a/.changeset/eight-coats-camp.md b/.changeset/eight-coats-camp.md deleted file mode 100644 index f2875945148..00000000000 --- a/.changeset/eight-coats-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@aws-amplify/backend-deployer': patch ---- - -change npx to use package manager diff --git a/.changeset/friendly-windows-chew.md b/.changeset/friendly-windows-chew.md deleted file mode 100644 index dce509637aa..00000000000 --- a/.changeset/friendly-windows-chew.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@aws-amplify/backend-cli': patch ---- - -add @aws-amplify/backend-deployer as a dependency to @aws-amplify/cli diff --git a/.changeset/itchy-pigs-switch.md b/.changeset/itchy-pigs-switch.md deleted file mode 100644 index a845151cc84..00000000000 --- a/.changeset/itchy-pigs-switch.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/metal-tomatoes-check.md b/.changeset/metal-tomatoes-check.md deleted file mode 100644 index cb02e03b2b4..00000000000 --- a/.changeset/metal-tomatoes-check.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'create-amplify': patch ---- - -1. Create Amplify (temporarily) uses environment variable for Package Manager -2. Create Amplify uses `yes` option to choose the default value for prompts diff --git a/.changeset/new-timers-warn.md b/.changeset/new-timers-warn.md new file mode 100644 index 00000000000..e2710230368 --- /dev/null +++ b/.changeset/new-timers-warn.md @@ -0,0 +1,11 @@ +--- +'@aws-amplify/integration-tests': minor +'@aws-amplify/backend-deployer': minor +'create-amplify': minor +'@aws-amplify/plugin-types': minor +'@aws-amplify/cli-core': minor +'@aws-amplify/sandbox': minor +'@aws-amplify/backend-cli': minor +--- + +Support more package managers, such as yarn (version 1 and version 2+), pnpm. diff --git a/.changeset/small-readers-check.md b/.changeset/small-readers-check.md deleted file mode 100644 index 7d3dc296122..00000000000 --- a/.changeset/small-readers-check.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@aws-amplify/integration-tests': patch -'create-amplify': patch ---- - -- Support yarn, pnpm via env var -- Add e2e test against yarn, pnpm diff --git a/.changeset/stale-poems-visit.md b/.changeset/stale-poems-visit.md deleted file mode 100644 index 62404dc0e4e..00000000000 --- a/.changeset/stale-poems-visit.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@aws-amplify/integration-tests': patch -'@aws-amplify/backend-deployer': patch -'create-amplify': patch -'@aws-amplify/cli-core': patch ---- - -move packageManagerController to @aws-amplify/cli-core From 154bdb2289bfbafd152c81c86f640ca9d42b802a Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:59:58 -0800 Subject: [PATCH 24/30] feat: add Package Manager test to health_checks (#968) * add package-manager-tests to health-checks * remove poc-e2e-flow-test * add run_package_manager_tests_tests condition * fix run_package_manager_tests_tests condition * remove amplify-backend_windows-latest_8-core * use re-usable action for run-e2e * Revert "remove amplify-backend_windows-latest_8-core" This reverts commit 547834a688f2eb7d5492a1adad080cb4c37cbf70. * Revert "use re-usable action for run-e2e" This reverts commit 3159e01dd614cdd8aadac7572cee7adb881c6b62. * revert re-usable action --- .github/workflows/health_checks.yml | 47 ++++++++++++++ .github/workflows/poc-e2e-flow-test.yml | 81 ------------------------- 2 files changed, 47 insertions(+), 81 deletions(-) delete mode 100644 .github/workflows/poc-e2e-flow-test.yml diff --git a/.github/workflows/health_checks.yml b/.github/workflows/health_checks.yml index 7c034e4effc..3c27355fb0a 100644 --- a/.github/workflows/health_checks.yml +++ b/.github/workflows/health_checks.yml @@ -164,6 +164,53 @@ jobs: aws-region: us-west-2 - name: Run E2E tests run: npm run e2e + run_package_manager_e2e_tests: + if: needs.do_include_e2e.outputs.run_e2e == 'true' + strategy: + # will finish running other test matrices even if one fails + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + pkg-manager: [npm, yarn-classic, yarn-modern, pnpm] + node-version: [20] + exclude: + - os: windows-latest + pkg-manager: pnpm + env: + PACKAGE_MANAGER: ${{ matrix.pkg-manager }} + runs-on: ${{ matrix.os }} + timeout-minutes: 25 + needs: + - build + - do_include_e2e + permissions: + # these permissions are required for the configure-aws-credentials action to get a JWT from GitHub + id-token: write + contents: read + steps: + - name: Checkout aws-amplify/amplify-cli repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Setup Node.js + uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # version 3.8.1 + with: + node-version: ${{ matrix.node-version }} + - name: Restore Build Cache + uses: ./.github/actions/restore_build_cache + - name: Configure test tooling credentials + uses: ./.github/actions/setup_profile + with: + role-to-assume: ${{ secrets.E2E_TOOLING_ROLE_ARN }} + aws-region: us-west-2 + profile-name: e2e-tooling + - name: Configure test execution credentials + uses: aws-actions/configure-aws-credentials@04b98b3f9e85f563fb061be8751a0352327246b0 # version 3.0.1 + with: + role-to-assume: ${{ secrets.E2E_RUNNER_ROLE_ARN }} + aws-region: us-west-2 + - name: Run E2E flow tests with ${{ matrix.pkg-manager }} + shell: bash + run: | + PACKAGE_MANAGER=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/package_manager_sanity_checks.test.ts lint: runs-on: ubuntu-latest needs: diff --git a/.github/workflows/poc-e2e-flow-test.yml b/.github/workflows/poc-e2e-flow-test.yml deleted file mode 100644 index c40e5735936..00000000000 --- a/.github/workflows/poc-e2e-flow-test.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Description: This workflow mimic the flow of behaviors when user using Amplify CLI; - -name: 'poc-e2e-flow-test' - -on: # TODO: need to change the trigger - push: - branches: - - poc/package-manager-support - pull_request: - branches: - - poc/package-manager-support - -jobs: - install: - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout aws-amplify/amplify-cli repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Setup Node.js - uses: ./.github/actions/setup_node - - name: Install or Restore Cache - uses: ./.github/actions/install_with_cache - build: - runs-on: ubuntu-latest - needs: - - install - steps: - - name: Checkout aws-amplify/amplify-cli repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Setup Node.js - uses: ./.github/actions/setup_node - - name: Build or Restore Build Cache - uses: ./.github/actions/build_with_cache - run_e2e_tests: - strategy: - # will finish running other test matrices even if one fails - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - pkg-manager: [npm, yarn-classic, yarn-modern, pnpm] - node-version: [20] - exclude: - - os: windows-latest - pkg-manager: pnpm - env: - PACKAGE_MANAGER: ${{ matrix.pkg-manager }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - needs: - - build - permissions: - # these permissions are required for the configure-aws-credentials action to get a JWT from GitHub - id-token: write - contents: read - steps: - - name: Checkout aws-amplify/amplify-cli repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Setup Node.js - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # version 3.8.1 - with: - node-version: ${{ matrix.node-version }} - - name: Restore Build Cache - uses: ./.github/actions/restore_build_cache - - name: Configure test tooling credentials - uses: ./.github/actions/setup_profile - with: - role-to-assume: ${{ secrets.E2E_TOOLING_ROLE_ARN }} - aws-region: us-west-2 - profile-name: e2e-tooling - - name: Configure test execution credentials - uses: aws-actions/configure-aws-credentials@04b98b3f9e85f563fb061be8751a0352327246b0 # version 3.0.1 - with: - role-to-assume: ${{ secrets.E2E_RUNNER_ROLE_ARN }} - aws-region: us-west-2 - - name: Run E2E flow tests with ${{ matrix.pkg-manager }} - shell: bash - run: | - PACKAGE_MANAGER=${{matrix.pkg-manager}} npm run test:dir packages/integration-tests/src/package_manager_sanity_checks.test.ts From 1f297f0fe605b6a61ff34a1b4fa281cb5bf1d445 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Thu, 1 Feb 2024 07:33:08 -0800 Subject: [PATCH 25/30] Update .changeset/new-timers-warn.md Co-authored-by: Kamil Sobol --- .changeset/new-timers-warn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/new-timers-warn.md b/.changeset/new-timers-warn.md index e2710230368..0cf48b999de 100644 --- a/.changeset/new-timers-warn.md +++ b/.changeset/new-timers-warn.md @@ -8,4 +8,4 @@ '@aws-amplify/backend-cli': minor --- -Support more package managers, such as yarn (version 1 and version 2+), pnpm. +Support additional package managers, such as yarn (version 1 and version 2+), pnpm. From 010277bd083805fb1e78d0fe441e122d6275e720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Thu, 1 Feb 2024 07:34:03 -0800 Subject: [PATCH 26/30] clean up commented code --- .../yarn_modern_package_manager_controller.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts index 67c388d53f8..2746de48521 100644 --- a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.test.ts @@ -144,8 +144,7 @@ void describe('YarnModernPackageManagerController', () => { executeWithDebugLoggerMock as unknown as typeof executeWithDebugLogger, existsSyncMock ); - // const writeFileMock = mock.fn(() => Promise.resolve()); - // mock.method(fsp, 'writeFile', writeFileMock); + await yarnModernPackageManagerController.initializeTsConfig('./amplify'); assert.equal(executeWithDebugLoggerMock.mock.callCount(), 2); assert.equal(fspMock.writeFile.mock.callCount(), 1); From 4f85b3d4741db815874a27911ce297a92b95984f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Thu, 1 Feb 2024 10:14:28 -0800 Subject: [PATCH 27/30] use amplify-backend_windows-latest_8-core --- .github/workflows/health_checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/health_checks.yml b/.github/workflows/health_checks.yml index 3c27355fb0a..33300bb8955 100644 --- a/.github/workflows/health_checks.yml +++ b/.github/workflows/health_checks.yml @@ -170,11 +170,11 @@ jobs: # will finish running other test matrices even if one fails fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest, amplify-backend_windows-latest_8-core] pkg-manager: [npm, yarn-classic, yarn-modern, pnpm] node-version: [20] exclude: - - os: windows-latest + - os: amplify-backend_windows-latest_8-core pkg-manager: pnpm env: PACKAGE_MANAGER: ${{ matrix.pkg-manager }} From e98d642447ab253817b202a4bf7aea70d3224c24 Mon Sep 17 00:00:00 2001 From: MJ Zhang <0618@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:11:44 -0800 Subject: [PATCH 28/30] Update .changeset/new-timers-warn.md Co-authored-by: Edward Foyle --- .changeset/new-timers-warn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/new-timers-warn.md b/.changeset/new-timers-warn.md index 0cf48b999de..90f5368b4ae 100644 --- a/.changeset/new-timers-warn.md +++ b/.changeset/new-timers-warn.md @@ -8,4 +8,4 @@ '@aws-amplify/backend-cli': minor --- -Support additional package managers, such as yarn (version 1 and version 2+), pnpm. +Support yarn 1, yarn 2+ and pnpm package managers From 223f9eb470be123688078e941018c0b9d27e3943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Thu, 1 Feb 2024 11:20:57 -0800 Subject: [PATCH 29/30] remove inaccurate JSdoc --- .../yarn_modern_package_manager_controller.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts index dc4d219f19f..10a10ad7eaa 100644 --- a/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts +++ b/packages/cli-core/src/package-manager-controller/yarn_modern_package_manager_controller.ts @@ -71,9 +71,6 @@ export class YarnModernPackageManagerController extends PackageManagerController } }; - /** - * addTypescript - initializes a tsconfig.json file in the project root - */ private addTypescript = async (targetDir: string) => { await this.executeWithDebugLogger( targetDir, From 276b82a7f1b56ba937a9ba64d64c68afb57e6456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?MJ=E2=98=94?= Date: Thu, 1 Feb 2024 11:27:54 -0800 Subject: [PATCH 30/30] remove integration-tests from changeset --- .changeset/new-timers-warn.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/new-timers-warn.md b/.changeset/new-timers-warn.md index 90f5368b4ae..a4863885add 100644 --- a/.changeset/new-timers-warn.md +++ b/.changeset/new-timers-warn.md @@ -1,5 +1,4 @@ --- -'@aws-amplify/integration-tests': minor '@aws-amplify/backend-deployer': minor 'create-amplify': minor '@aws-amplify/plugin-types': minor