@aws/nx-plugin 1.0.0-rc.97 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +9 -9
- package/migrations.json +125 -115
- package/package.json +3 -3
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/infra/app/generator.js +5 -2
- package/src/infra/app/generator.js.map +1 -1
- package/src/internal/test-matrix/generator.js +2 -2
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/license/sync/generator.d.ts +10 -0
- package/src/license/sync/generator.js +1 -1
- package/src/license/sync/generator.js.map +1 -1
- package/src/migrations/latest/sandbox-pattern-nested-stacks/metadata.json +3 -0
- package/src/migrations/latest/sandbox-pattern-nested-stacks/migration.js +68 -0
- package/src/migrations/latest/sandbox-pattern-nested-stacks/migration.js.map +1 -0
- package/src/migrations/latest/shadcn-cn-package/metadata.json +3 -0
- package/src/migrations/latest/shadcn-cn-package/migration.js +114 -0
- package/src/migrations/latest/shadcn-cn-package/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0001-dev-target-depends-on-pull-image/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0002-open-api-codegen-executor/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0003-terraform-provider-plugin-cache/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0004-python-test-input-scoping/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0005-vitest-coverage-output-dir/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0006-add-assemble-target/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0007-docker-target-cache-soundness/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0008-declare-cacheable-target-inputs/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.90/0009-terraform-fmt-check/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.92/0001-react-website-unique-dev-ports/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.94/0001-infra-deploy-express-mode/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.94/0002-shx-fs-commands/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.94/0003-agent-core-vendor-target/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.95/0001-rolldown-config-bundle-transient/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.95/0002-agent-connection-pin-strands-peers/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.95/0003-ignore-package-manager-temp-files/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.95/0004-shadcn-package-imports-exports/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0001-gateway-url-accessor/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0002-checkov-scan-cache-inputs/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0003-terraform-validate-without-backend/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0004-py-lambda-powertools-context/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.97/0004-py-lambda-powertools-context/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0005-smithy-extension-trait-aliases/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.97/0006-script-project-quality-gates/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.97/0006-script-project-quality-gates/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +4 -4
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +4 -4
- package/src/py/agent/a2a-connection/generator.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +1 -7
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +12 -12
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +5 -5
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +8 -8
- package/src/terraform/project/schema.d.js +0 -3
- package/src/terraform/project/schema.d.js.map +1 -1
- package/src/terraform/project/schema.d.ts +0 -4
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +12 -12
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/agent/react-connection/generator.d.ts +1 -9
- package/src/ts/astro-docs/files/translation/scripts/translate.ts.template +47 -2
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/ts/mcp-server/files/app/http.ts.template +1 -1
- package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/nx-generator/files/local/generator.spec.ts.template +2 -2
- package/src/ts/nx-migration/generator.js +3 -1
- package/src/ts/nx-migration/generator.js.map +1 -1
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +1 -25
- package/src/ts/nx-plugin/generator.js +19 -17
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.d.ts +21 -0
- package/src/ts/nx-plugin/utils.js +41 -1
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +10 -10
- package/src/ts/react-website/agui/generator.d.ts +1 -5
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +26 -26
- package/src/ts/react-website/app/generator.d.ts +1 -5
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +2 -2
- package/src/utils/ast.js +55 -16
- package/src/utils/ast.js.map +1 -1
- package/src/utils/dependencies.d.ts +10 -0
- package/src/utils/dependencies.js +93 -1
- package/src/utils/dependencies.js.map +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/alert.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/avatar.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/breadcrumb.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/button.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/card.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/input.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/separator.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/sheet.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/sidebar.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/skeleton.tsx.template +1 -1
- package/src/utils/files/common/shadcn/src/components/ui/spinner.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/textarea.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/components/ui/tooltip.tsx.template +1 -2
- package/src/utils/files/common/shadcn/src/lib/utils.ts.template +1 -6
- package/src/utils/shared-shadcn.d.ts +1 -3
- package/src/utils/shared-shadcn.js +1 -4
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/versions.d.ts +52 -53
- package/src/utils/versions.js +51 -52
- package/src/utils/versions.js.map +1 -1
- package/src/migrations/latest/add-assemble-target/migration.js.map +0 -1
- package/src/migrations/latest/agent-connection-pin-strands-peers/migration.js.map +0 -1
- package/src/migrations/latest/agent-core-vendor-target/migration.js.map +0 -1
- package/src/migrations/latest/checkov-scan-cache-inputs/migration.js.map +0 -1
- package/src/migrations/latest/declare-cacheable-target-inputs/migration.js.map +0 -1
- package/src/migrations/latest/dev-target-depends-on-pull-image/migration.js.map +0 -1
- package/src/migrations/latest/docker-target-cache-soundness/migration.js.map +0 -1
- package/src/migrations/latest/gateway-url-accessor/migration.js.map +0 -1
- package/src/migrations/latest/ignore-package-manager-temp-files/migration.js.map +0 -1
- package/src/migrations/latest/infra-deploy-express-mode/migration.js.map +0 -1
- package/src/migrations/latest/open-api-codegen-executor/migration.js.map +0 -1
- package/src/migrations/latest/py-lambda-powertools-context/migration.js.map +0 -1
- package/src/migrations/latest/python-test-input-scoping/migration.js.map +0 -1
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js.map +0 -1
- package/src/migrations/latest/rolldown-config-bundle-transient/migration.js.map +0 -1
- package/src/migrations/latest/script-project-quality-gates/migration.js.map +0 -1
- package/src/migrations/latest/shadcn-package-imports-exports/migration.js.map +0 -1
- package/src/migrations/latest/shx-fs-commands/migration.js.map +0 -1
- package/src/migrations/latest/smithy-extension-trait-aliases/migration.js.map +0 -1
- package/src/migrations/latest/terraform-fmt-check/migration.js.map +0 -1
- package/src/migrations/latest/terraform-provider-plugin-cache/migration.js.map +0 -1
- package/src/migrations/latest/terraform-validate-without-backend/migration.js.map +0 -1
- package/src/migrations/latest/vitest-coverage-output-dir/migration.js.map +0 -1
- /package/src/migrations/latest/{add-assemble-target → sandbox-pattern-nested-stacks}/migration.d.ts +0 -0
- /package/src/migrations/latest/{agent-core-vendor-target → shadcn-cn-package}/migration.d.ts +0 -0
- /package/src/migrations/{latest/dev-target-depends-on-pull-image → v1.0.0-rc.90/0001-dev-target-depends-on-pull-image}/metadata.json +0 -0
- /package/src/migrations/{latest/checkov-scan-cache-inputs → v1.0.0-rc.90/0001-dev-target-depends-on-pull-image}/migration.d.ts +0 -0
- /package/src/migrations/{latest/dev-target-depends-on-pull-image → v1.0.0-rc.90/0001-dev-target-depends-on-pull-image}/migration.js +0 -0
- /package/src/migrations/{latest/open-api-codegen-executor → v1.0.0-rc.90/0002-open-api-codegen-executor}/metadata.json +0 -0
- /package/src/migrations/{latest/declare-cacheable-target-inputs → v1.0.0-rc.90/0002-open-api-codegen-executor}/migration.d.ts +0 -0
- /package/src/migrations/{latest/open-api-codegen-executor → v1.0.0-rc.90/0002-open-api-codegen-executor}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-provider-plugin-cache → v1.0.0-rc.90/0003-terraform-provider-plugin-cache}/metadata.json +0 -0
- /package/src/migrations/{latest/dev-target-depends-on-pull-image → v1.0.0-rc.90/0003-terraform-provider-plugin-cache}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-provider-plugin-cache → v1.0.0-rc.90/0003-terraform-provider-plugin-cache}/migration.js +0 -0
- /package/src/migrations/{latest/python-test-input-scoping → v1.0.0-rc.90/0004-python-test-input-scoping}/metadata.json +0 -0
- /package/src/migrations/{latest/docker-target-cache-soundness → v1.0.0-rc.90/0004-python-test-input-scoping}/migration.d.ts +0 -0
- /package/src/migrations/{latest/python-test-input-scoping → v1.0.0-rc.90/0004-python-test-input-scoping}/migration.js +0 -0
- /package/src/migrations/{latest/vitest-coverage-output-dir → v1.0.0-rc.90/0005-vitest-coverage-output-dir}/metadata.json +0 -0
- /package/src/migrations/{latest/infra-deploy-express-mode → v1.0.0-rc.90/0005-vitest-coverage-output-dir}/migration.d.ts +0 -0
- /package/src/migrations/{latest/vitest-coverage-output-dir → v1.0.0-rc.90/0005-vitest-coverage-output-dir}/migration.js +0 -0
- /package/src/migrations/{latest/add-assemble-target → v1.0.0-rc.90/0006-add-assemble-target}/metadata.json +0 -0
- /package/src/migrations/{latest/open-api-codegen-executor → v1.0.0-rc.90/0006-add-assemble-target}/migration.d.ts +0 -0
- /package/src/migrations/{latest/add-assemble-target → v1.0.0-rc.90/0006-add-assemble-target}/migration.js +0 -0
- /package/src/migrations/{latest/docker-target-cache-soundness → v1.0.0-rc.90/0007-docker-target-cache-soundness}/metadata.json +0 -0
- /package/src/migrations/{latest/py-lambda-powertools-context → v1.0.0-rc.90/0007-docker-target-cache-soundness}/migration.d.ts +0 -0
- /package/src/migrations/{latest/docker-target-cache-soundness → v1.0.0-rc.90/0007-docker-target-cache-soundness}/migration.js +0 -0
- /package/src/migrations/{latest/declare-cacheable-target-inputs → v1.0.0-rc.90/0008-declare-cacheable-target-inputs}/metadata.json +0 -0
- /package/src/migrations/{latest/python-test-input-scoping → v1.0.0-rc.90/0008-declare-cacheable-target-inputs}/migration.d.ts +0 -0
- /package/src/migrations/{latest/declare-cacheable-target-inputs → v1.0.0-rc.90/0008-declare-cacheable-target-inputs}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-fmt-check → v1.0.0-rc.90/0009-terraform-fmt-check}/metadata.json +0 -0
- /package/src/migrations/{latest/react-website-unique-dev-ports → v1.0.0-rc.90/0009-terraform-fmt-check}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-fmt-check → v1.0.0-rc.90/0009-terraform-fmt-check}/migration.js +0 -0
- /package/src/migrations/{latest/react-website-unique-dev-ports → v1.0.0-rc.92/0001-react-website-unique-dev-ports}/metadata.json +0 -0
- /package/src/migrations/{latest/rolldown-config-bundle-transient → v1.0.0-rc.92/0001-react-website-unique-dev-ports}/migration.d.ts +0 -0
- /package/src/migrations/{latest/react-website-unique-dev-ports → v1.0.0-rc.92/0001-react-website-unique-dev-ports}/migration.js +0 -0
- /package/src/migrations/{latest/infra-deploy-express-mode → v1.0.0-rc.94/0001-infra-deploy-express-mode}/metadata.json +0 -0
- /package/src/migrations/{latest/script-project-quality-gates → v1.0.0-rc.94/0001-infra-deploy-express-mode}/migration.d.ts +0 -0
- /package/src/migrations/{latest/infra-deploy-express-mode → v1.0.0-rc.94/0001-infra-deploy-express-mode}/migration.js +0 -0
- /package/src/migrations/{latest/shx-fs-commands → v1.0.0-rc.94/0002-shx-fs-commands}/metadata.json +0 -0
- /package/src/migrations/{latest/shadcn-package-imports-exports → v1.0.0-rc.94/0002-shx-fs-commands}/migration.d.ts +0 -0
- /package/src/migrations/{latest/shx-fs-commands → v1.0.0-rc.94/0002-shx-fs-commands}/migration.js +0 -0
- /package/src/migrations/{latest/agent-core-vendor-target → v1.0.0-rc.94/0003-agent-core-vendor-target}/metadata.json +0 -0
- /package/src/migrations/{latest/shx-fs-commands → v1.0.0-rc.94/0003-agent-core-vendor-target}/migration.d.ts +0 -0
- /package/src/migrations/{latest/agent-core-vendor-target → v1.0.0-rc.94/0003-agent-core-vendor-target}/migration.js +0 -0
- /package/src/migrations/{latest/rolldown-config-bundle-transient → v1.0.0-rc.95/0001-rolldown-config-bundle-transient}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-fmt-check → v1.0.0-rc.95/0001-rolldown-config-bundle-transient}/migration.d.ts +0 -0
- /package/src/migrations/{latest/rolldown-config-bundle-transient → v1.0.0-rc.95/0001-rolldown-config-bundle-transient}/migration.js +0 -0
- /package/src/migrations/{latest/agent-connection-pin-strands-peers → v1.0.0-rc.95/0002-agent-connection-pin-strands-peers}/metadata.json +0 -0
- /package/src/migrations/{latest/agent-connection-pin-strands-peers → v1.0.0-rc.95/0002-agent-connection-pin-strands-peers}/migration.d.ts +0 -0
- /package/src/migrations/{latest/agent-connection-pin-strands-peers → v1.0.0-rc.95/0002-agent-connection-pin-strands-peers}/migration.js +0 -0
- /package/src/migrations/{latest/ignore-package-manager-temp-files → v1.0.0-rc.95/0003-ignore-package-manager-temp-files}/metadata.json +0 -0
- /package/src/migrations/{latest/ignore-package-manager-temp-files → v1.0.0-rc.95/0003-ignore-package-manager-temp-files}/migration.d.ts +0 -0
- /package/src/migrations/{latest/ignore-package-manager-temp-files → v1.0.0-rc.95/0003-ignore-package-manager-temp-files}/migration.js +0 -0
- /package/src/migrations/{latest/shadcn-package-imports-exports → v1.0.0-rc.95/0004-shadcn-package-imports-exports}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-provider-plugin-cache → v1.0.0-rc.95/0004-shadcn-package-imports-exports}/migration.d.ts +0 -0
- /package/src/migrations/{latest/shadcn-package-imports-exports → v1.0.0-rc.95/0004-shadcn-package-imports-exports}/migration.js +0 -0
- /package/src/migrations/{latest/gateway-url-accessor → v1.0.0-rc.97/0001-gateway-url-accessor}/__snapshots__/migration.spec.ts.snap +0 -0
- /package/src/migrations/{latest/gateway-url-accessor → v1.0.0-rc.97/0001-gateway-url-accessor}/metadata.json +0 -0
- /package/src/migrations/{latest/gateway-url-accessor → v1.0.0-rc.97/0001-gateway-url-accessor}/migration.d.ts +0 -0
- /package/src/migrations/{latest/gateway-url-accessor → v1.0.0-rc.97/0001-gateway-url-accessor}/migration.js +0 -0
- /package/src/migrations/{latest/checkov-scan-cache-inputs → v1.0.0-rc.97/0002-checkov-scan-cache-inputs}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-validate-without-backend → v1.0.0-rc.97/0002-checkov-scan-cache-inputs}/migration.d.ts +0 -0
- /package/src/migrations/{latest/checkov-scan-cache-inputs → v1.0.0-rc.97/0002-checkov-scan-cache-inputs}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-validate-without-backend → v1.0.0-rc.97/0003-terraform-validate-without-backend}/metadata.json +0 -0
- /package/src/migrations/{latest/vitest-coverage-output-dir → v1.0.0-rc.97/0003-terraform-validate-without-backend}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-validate-without-backend → v1.0.0-rc.97/0003-terraform-validate-without-backend}/migration.js +0 -0
- /package/src/migrations/{latest/py-lambda-powertools-context → v1.0.0-rc.97/0004-py-lambda-powertools-context}/metadata.json +0 -0
- /package/src/migrations/{latest/py-lambda-powertools-context → v1.0.0-rc.97/0004-py-lambda-powertools-context}/migration.js +0 -0
- /package/src/migrations/{latest/smithy-extension-trait-aliases → v1.0.0-rc.97/0005-smithy-extension-trait-aliases}/__snapshots__/migration.spec.ts.snap +0 -0
- /package/src/migrations/{latest/smithy-extension-trait-aliases → v1.0.0-rc.97/0005-smithy-extension-trait-aliases}/metadata.json +0 -0
- /package/src/migrations/{latest/smithy-extension-trait-aliases → v1.0.0-rc.97/0005-smithy-extension-trait-aliases}/migration.d.ts +0 -0
- /package/src/migrations/{latest/smithy-extension-trait-aliases → v1.0.0-rc.97/0005-smithy-extension-trait-aliases}/migration.js +0 -0
- /package/src/migrations/{latest/script-project-quality-gates → v1.0.0-rc.97/0006-script-project-quality-gates}/metadata.json +0 -0
- /package/src/migrations/{latest/script-project-quality-gates → v1.0.0-rc.97/0006-script-project-quality-gates}/migration.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/internal/test-matrix/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { GeneratorCallback, Tree } from '@nx/devkit';\nimport { agentcoreGatewayGenerator } from '../../sdk/agentcore-gateway.js';\nimport { agentcoreHarnessGenerator } from '../../sdk/agentcore-harness.js';\nimport {\n type ConnectionGeneratorSchema,\n connectionGenerator,\n} from '../../sdk/connection.js';\nimport { licenseGenerator } from '../../sdk/license.js';\nimport {\n type PyAgentGeneratorSchema,\n type PyApiGeneratorSchema,\n type PyRdbGeneratorSchema,\n pyAgentGenerator,\n pyApiGenerator,\n pyDynamoDBGenerator,\n pyLambdaFunctionGenerator,\n pyMcpServerGenerator,\n pyProjectGenerator,\n pyRdbGenerator,\n} from '../../sdk/py.js';\nimport { smithyProjectGenerator } from '../../sdk/smithy.js';\nimport { terraformProjectGenerator } from '../../sdk/terraform.js';\nimport {\n type TsAgentGeneratorSchema,\n type TsApiGeneratorSchema,\n type TsNxMigrationGeneratorSchema,\n type TsRdbGeneratorSchema,\n tsAgentGenerator,\n tsApiGenerator,\n tsAstroDocsGenerator,\n tsDcrProxyGenerator,\n tsDynamoDBGenerator,\n tsInfraGenerator,\n tsLambdaFunctionGenerator,\n tsMcpServerGenerator,\n tsNxGeneratorGenerator,\n tsNxMigrationGenerator,\n tsNxPluginGenerator,\n tsProjectGenerator,\n tsRdbGenerator,\n tsWebsiteAuthGenerator,\n tsWebsiteGenerator,\n} from '../../sdk/ts.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope, getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport type { InternalTestMatrixGeneratorSchema } from './schema';\n\n/**\n * Scaffolds every generator, component and connection permutation the e2e tests\n * cover, by composing the generators in-process on a single tree.\n *\n * This ships with the plugin so each released version carries the matrix of the\n * generators *it* had. A test upgrading an old workspace scaffolds with the\n * released version's own matrix and never has to reason about which generators\n * existed when — driving the CLI from the test repo instead would couple the\n * test to a generator list that only describes today's plugin.\n *\n * Hidden and undocumented: it exists for the e2e suite, not for users.\n *\n * Options are typed against each generator's schema, so adding a required option\n * or changing an enum breaks the build here rather than silently reducing\n * coverage.\n *\n * Projects are generated with `preferInstallDependencies: false` by default and\n * the returned callback installs once. Nothing composed here reads the project\n * graph (only `ts#sync` does, which is not part of the matrix), so no\n * intermediate install is needed.\n */\nexport const internalTestMatrixGenerator = async (\n tree: Tree,\n options: InternalTestMatrixGeneratorSchema = {},\n): Promise<GeneratorCallback> => {\n const preferInstallDependencies = options.preferInstallDependencies ?? false;\n const defaults = { preferInstallDependencies };\n const projectDefaults = { ...defaults, directory: 'packages' };\n // Fully-qualified project names, which differ per language: TypeScript\n // projects are scope-prefixed, Python ones are dotted snake_case. Derived from\n // the workspace rather than hardcoded, so the matrix works in any workspace.\n const ts = (name: string) => `${getNpmScopePrefix(tree)}${name}`;\n const py = (name: string) =>\n `${toSnakeCase(getNpmScope(tree))}.${toSnakeCase(name)}`;\n\n // The infrastructure project every other generator deploys into. Which\n // generator owns it depends on the workspace's IaC provider, so the caller\n // asks for the one matching the workspace it created.\n if (options.infra === 'terraform') {\n await terraformProjectGenerator(tree, {\n name: 'infra',\n type: 'application',\n ...projectDefaults,\n });\n } else {\n await tsInfraGenerator(tree, { name: 'infra', ...projectDefaults });\n // A second CDK app with stage config, which only ts#infra offers.\n await tsInfraGenerator(tree, {\n name: 'infra-with-stages',\n stageConfig: true,\n ...projectDefaults,\n });\n }\n\n // Websites (with and without TanStack Router), a docs site, and auth on each.\n await tsWebsiteGenerator(tree, {\n name: 'website',\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsWebsiteGenerator(tree, {\n name: 'website-no-router',\n tanstackRouter: false,\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsAstroDocsGenerator(tree, { name: 'docs-site', ...defaults });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website'),\n cognitoDomain: 'test',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website-no-router'),\n cognitoDomain: 'test-no-router',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n\n // tRPC APIs — REST + HTTP, with Cognito and custom auth.\n const tsApis: TsApiGeneratorSchema[] = [\n { name: 'my-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'my-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n // The APIs above take the default `isolated` integration pattern; these\n // cover `shared`.\n {\n name: 'my-api-shared',\n infra: 'rest-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-shared-http',\n infra: 'http-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-smithy-api',\n framework: 'smithy',\n infra: 'rest-lambda',\n auth: 'iam',\n iac: 'inherit',\n },\n ];\n for (const api of tsApis) {\n await tsApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // A Smithy shape library; `my-smithy-api` covers consuming one.\n await smithyProjectGenerator(tree, {\n name: 'my-shapes',\n type: 'shapes',\n ...projectDefaults,\n });\n\n // Python FastAPI — REST + HTTP, with Cognito and custom auth.\n const pyApis: PyApiGeneratorSchema[] = [\n { name: 'py-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'py-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n {\n name: 'py-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'py-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n ];\n for (const api of pyApis) {\n await pyApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // Library projects hosting the components below, each with a lambda function.\n await pyProjectGenerator(tree, {\n name: 'py-project',\n type: 'application',\n ...projectDefaults,\n });\n await tsProjectGenerator(tree, { name: 'ts-project', ...projectDefaults });\n await pyLambdaFunctionGenerator(tree, {\n project: py('py-project'),\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n await tsLambdaFunctionGenerator(tree, {\n project: 'ts-project',\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n\n // MCP servers — uninfra'd and hosted on AgentCore.\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'my-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'my-mcp-server',\n infra: 'none',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'hosted-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n // Container-packaged variants, so both packagings are covered and a workspace\n // mixing them vends one copy of the shared runtime module.\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'ecr-mcp-server',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n ...defaults,\n });\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'ecr-mcp-server',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n ...defaults,\n });\n\n // OAuth DCR proxy for Cognito-authenticated MCP servers.\n await tsDcrProxyGenerator(tree, {\n name: 'my-dcr-proxy',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // TypeScript agents across every protocol and auth permutation. The unnamed\n // one takes the generator's default name, which the connections below use.\n const tsAgents: TsAgentGeneratorSchema[] = [\n {\n project: 'ts-project',\n name: 'my-ts-agent',\n infra: 'none',\n iac: 'inherit',\n },\n { project: 'ts-project', infra: 'agentcore', iac: 'inherit' },\n {\n project: 'ts-project',\n name: 'my-ts-ecr-agent',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of tsAgents) {\n await tsAgentGenerator(tree, { ...agent, ...defaults });\n }\n\n // Python agents: Strands across every protocol, plus LangChain in its own\n // project — langchain's dependency closure would push the zip-bundled Lambda\n // in py-project past its unzipped size limit.\n const pyAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_project',\n name: 'my-agent',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-ecr-agent',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of pyAgents) {\n await pyAgentGenerator(tree, { ...agent, ...defaults });\n }\n await pyProjectGenerator(tree, {\n name: 'py-langchain-project',\n type: 'application',\n ...projectDefaults,\n });\n const langchainAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-agent',\n protocol: 'ag-ui',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-http-agent',\n protocol: 'http',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-a2a-agent',\n protocol: 'a2a',\n iac: 'inherit',\n },\n ];\n for (const agent of langchainAgents) {\n await pyAgentGenerator(tree, {\n ...agent,\n framework: 'langchain',\n infra: 'agentcore',\n ...defaults,\n });\n }\n\n // AgentCore gateways, including a parent fronting the first (chained), and\n // an http-protocol gateway fronting agent runtime targets.\n await agentcoreGatewayGenerator(tree, {\n name: 'my-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'parent-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'agent-gateway',\n protocol: 'http',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // AgentCore Harness — a standalone invocation project.\n await agentcoreHarnessGenerator(tree, {\n name: 'my-harness',\n infra: 'agentcore',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // Databases — DynamoDB, plus Aurora across both engines and ORMs.\n await tsDynamoDBGenerator(tree, {\n name: 'my-table',\n framework: 'electrodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n await pyDynamoDBGenerator(tree, {\n name: 'my-py-table',\n framework: 'pynamodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n const tsRdbs: TsRdbGeneratorSchema[] = [\n {\n name: 'postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'prisma',\n iac: 'inherit',\n },\n {\n name: 'my-sql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'prisma',\n iac: 'inherit',\n },\n ];\n for (const rdb of tsRdbs) {\n await tsRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n const pyRdbs: PyRdbGeneratorSchema[] = [\n {\n name: 'py-postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n {\n name: 'py-mysql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n ];\n for (const rdb of pyRdbs) {\n await pyRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n\n // Every connection edge the matrix covers.\n const connections: ConnectionGeneratorSchema[] = [\n // Website -> API\n { sourceProject: ts('website'), targetProject: ts('my-api') },\n { sourceProject: ts('website-no-router'), targetProject: ts('my-api') },\n { sourceProject: 'website', targetProject: 'py_api' },\n { sourceProject: 'website', targetProject: 'my-smithy-api' },\n // Agent -> MCP server\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agui-agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n // HTTP agent <-> A2A agent\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n // Agent -> gateway, gateway -> MCP server, gateway -> gateway\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n { sourceProject: ts('parent-gateway'), targetProject: ts('my-gateway') },\n // Gateway -> agent (http gateway fronting agent runtime targets: every\n // supported protocol permutation), then website -> gateway.\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: ts('website-no-router'),\n targetProject: ts('agent-gateway'),\n },\n // Website -> agent\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-http-agent',\n },\n // DynamoDB\n { sourceProject: 'my-api', targetProject: ts('my-table') },\n { sourceProject: 'my-smithy-api', targetProject: ts('my-table') },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agent',\n targetProject: ts('my-table'),\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-mcp-server',\n targetProject: ts('my-table'),\n },\n { sourceProject: 'py_api', targetProject: 'my_py_table' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-http-agent',\n targetProject: 'my_py_table',\n },\n // Relational databases\n { sourceProject: 'py_api', targetProject: 'py_postgres_db' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_postgres_db',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'py_postgres_db',\n },\n ];\n for (const connection of connections) {\n await connectionGenerator(tree, { ...connection, ...defaults });\n }\n\n // Licensing, then an Nx plugin with a custom generator.\n await licenseGenerator(tree, {\n license: 'Apache-2.0',\n copyrightHolder: 'Amazon.com, Inc. or its affiliates',\n ...defaults,\n });\n await tsNxPluginGenerator(tree, {\n ...projectDefaults,\n name: 'plugin',\n directory: 'tools',\n });\n await tsNxGeneratorGenerator(tree, {\n project: ts('plugin'),\n name: 'my#generator',\n ...defaults,\n });\n\n // A migration of each kind, so the scaffolded codemods compile and the\n // plugin's migrations.json (created by the first run) registers all three.\n const migrations: Omit<TsNxMigrationGeneratorSchema, 'project'>[] = [\n {\n name: 'rename-foo-target',\n description: 'Rename the foo target to bar',\n },\n {\n name: 'migrate-custom-handlers',\n description: 'Update custom handlers for the new API',\n kind: 'agentic',\n },\n {\n name: 'upgrade-framework',\n description: 'Upgrade the framework and reconcile call sites',\n kind: 'hybrid',\n },\n ];\n for (const migration of migrations) {\n await tsNxMigrationGenerator(tree, {\n ...migration,\n project: ts('plugin'),\n ...defaults,\n });\n }\n\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default internalTestMatrixGenerator;\n"],"names":["agentcoreGatewayGenerator","agentcoreHarnessGenerator","connectionGenerator","licenseGenerator","pyAgentGenerator","pyApiGenerator","pyDynamoDBGenerator","pyLambdaFunctionGenerator","pyMcpServerGenerator","pyProjectGenerator","pyRdbGenerator","smithyProjectGenerator","terraformProjectGenerator","tsAgentGenerator","tsApiGenerator","tsAstroDocsGenerator","tsDcrProxyGenerator","tsDynamoDBGenerator","tsInfraGenerator","tsLambdaFunctionGenerator","tsMcpServerGenerator","tsNxGeneratorGenerator","tsNxMigrationGenerator","tsNxPluginGenerator","tsProjectGenerator","tsRdbGenerator","tsWebsiteAuthGenerator","tsWebsiteGenerator","installDependencies","toSnakeCase","getNpmScope","getNpmScopePrefix","internalTestMatrixGenerator","tree","options","preferInstallDependencies","defaults","projectDefaults","directory","ts","name","py","infra","type","stageConfig","iac","tanstackRouter","project","cognitoDomain","allowSignup","tsApis","auth","integrationPattern","framework","api","pyApis","event","tsAgents","protocol","agent","pyAgents","langchainAgents","tsRdbs","engine","rdb","pyRdbs","connections","sourceProject","targetProject","sourceComponent","targetComponent","connection","license","copyrightHolder","migrations","description","kind","migration","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/internal/test-matrix/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { GeneratorCallback, Tree } from '@nx/devkit';\nimport { agentcoreGatewayGenerator } from '../../sdk/agentcore-gateway.js';\nimport { agentcoreHarnessGenerator } from '../../sdk/agentcore-harness.js';\nimport {\n type ConnectionGeneratorSchema,\n connectionGenerator,\n} from '../../sdk/connection.js';\nimport { licenseGenerator } from '../../sdk/license.js';\nimport {\n type PyAgentGeneratorSchema,\n type PyApiGeneratorSchema,\n type PyRdbGeneratorSchema,\n pyAgentGenerator,\n pyApiGenerator,\n pyDynamoDBGenerator,\n pyLambdaFunctionGenerator,\n pyMcpServerGenerator,\n pyProjectGenerator,\n pyRdbGenerator,\n} from '../../sdk/py.js';\nimport { smithyProjectGenerator } from '../../sdk/smithy.js';\nimport { terraformProjectGenerator } from '../../sdk/terraform.js';\nimport {\n type TsAgentGeneratorSchema,\n type TsApiGeneratorSchema,\n type TsNxMigrationGeneratorSchema,\n type TsRdbGeneratorSchema,\n tsAgentGenerator,\n tsApiGenerator,\n tsDcrProxyGenerator,\n tsDocsGenerator,\n tsDynamoDBGenerator,\n tsInfraGenerator,\n tsLambdaFunctionGenerator,\n tsMcpServerGenerator,\n tsNxGeneratorGenerator,\n tsNxMigrationGenerator,\n tsNxPluginGenerator,\n tsProjectGenerator,\n tsRdbGenerator,\n tsWebsiteAuthGenerator,\n tsWebsiteGenerator,\n} from '../../sdk/ts.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope, getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport type { InternalTestMatrixGeneratorSchema } from './schema';\n\n/**\n * Scaffolds every generator, component and connection permutation the e2e tests\n * cover, by composing the generators in-process on a single tree.\n *\n * This ships with the plugin so each released version carries the matrix of the\n * generators *it* had. A test upgrading an old workspace scaffolds with the\n * released version's own matrix and never has to reason about which generators\n * existed when — driving the CLI from the test repo instead would couple the\n * test to a generator list that only describes today's plugin.\n *\n * Hidden and undocumented: it exists for the e2e suite, not for users.\n *\n * Options are typed against each generator's schema, so adding a required option\n * or changing an enum breaks the build here rather than silently reducing\n * coverage.\n *\n * Projects are generated with `preferInstallDependencies: false` by default and\n * the returned callback installs once. Nothing composed here reads the project\n * graph (only `ts#sync` does, which is not part of the matrix), so no\n * intermediate install is needed.\n */\nexport const internalTestMatrixGenerator = async (\n tree: Tree,\n options: InternalTestMatrixGeneratorSchema = {},\n): Promise<GeneratorCallback> => {\n const preferInstallDependencies = options.preferInstallDependencies ?? false;\n const defaults = { preferInstallDependencies };\n const projectDefaults = { ...defaults, directory: 'packages' };\n // Fully-qualified project names, which differ per language: TypeScript\n // projects are scope-prefixed, Python ones are dotted snake_case. Derived from\n // the workspace rather than hardcoded, so the matrix works in any workspace.\n const ts = (name: string) => `${getNpmScopePrefix(tree)}${name}`;\n const py = (name: string) =>\n `${toSnakeCase(getNpmScope(tree))}.${toSnakeCase(name)}`;\n\n // The infrastructure project every other generator deploys into. Which\n // generator owns it depends on the workspace's IaC provider, so the caller\n // asks for the one matching the workspace it created.\n if (options.infra === 'terraform') {\n await terraformProjectGenerator(tree, {\n name: 'infra',\n type: 'application',\n ...projectDefaults,\n });\n } else {\n await tsInfraGenerator(tree, { name: 'infra', ...projectDefaults });\n // A second CDK app with stage config, which only ts#infra offers.\n await tsInfraGenerator(tree, {\n name: 'infra-with-stages',\n stageConfig: true,\n ...projectDefaults,\n });\n }\n\n // Websites (with and without TanStack Router), a docs site, and auth on each.\n await tsWebsiteGenerator(tree, {\n name: 'website',\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsWebsiteGenerator(tree, {\n name: 'website-no-router',\n tanstackRouter: false,\n iac: 'inherit',\n ...projectDefaults,\n });\n await tsDocsGenerator(tree, { name: 'docs-site', ...defaults });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website'),\n cognitoDomain: 'test',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n await tsWebsiteAuthGenerator(tree, {\n project: ts('website-no-router'),\n cognitoDomain: 'test-no-router',\n allowSignup: true,\n iac: 'inherit',\n ...defaults,\n });\n\n // tRPC APIs — REST + HTTP, with Cognito and custom auth.\n const tsApis: TsApiGeneratorSchema[] = [\n { name: 'my-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'my-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n // The APIs above take the default `isolated` integration pattern; these\n // cover `shared`.\n {\n name: 'my-api-shared',\n infra: 'rest-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-shared-http',\n infra: 'http-lambda',\n auth: 'iam',\n integrationPattern: 'shared',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'my-smithy-api',\n framework: 'smithy',\n infra: 'rest-lambda',\n auth: 'iam',\n iac: 'inherit',\n },\n ];\n for (const api of tsApis) {\n await tsApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // A Smithy shape library; `my-smithy-api` covers consuming one.\n await smithyProjectGenerator(tree, {\n name: 'my-shapes',\n type: 'shapes',\n ...projectDefaults,\n });\n\n // Python FastAPI — REST + HTTP, with Cognito and custom auth.\n const pyApis: PyApiGeneratorSchema[] = [\n { name: 'py-api', infra: 'rest-lambda', auth: 'iam', iac: 'inherit' },\n { name: 'py-api-http', infra: 'http-lambda', auth: 'iam', iac: 'inherit' },\n {\n name: 'py-api-custom',\n infra: 'rest-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n {\n name: 'py-api-custom-http',\n infra: 'http-lambda',\n auth: 'custom',\n iac: 'inherit',\n },\n ];\n for (const api of pyApis) {\n await pyApiGenerator(tree, { ...api, ...projectDefaults });\n }\n\n // Library projects hosting the components below, each with a lambda function.\n await pyProjectGenerator(tree, {\n name: 'py-project',\n type: 'application',\n ...projectDefaults,\n });\n await tsProjectGenerator(tree, { name: 'ts-project', ...projectDefaults });\n await pyLambdaFunctionGenerator(tree, {\n project: py('py-project'),\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n await tsLambdaFunctionGenerator(tree, {\n project: 'ts-project',\n name: 'my-function',\n event: 'Any',\n iac: 'inherit',\n ...defaults,\n });\n\n // MCP servers — uninfra'd and hosted on AgentCore.\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'my-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'my-mcp-server',\n infra: 'none',\n iac: 'inherit',\n ...defaults,\n });\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'hosted-mcp-server',\n infra: 'agentcore',\n iac: 'inherit',\n ...defaults,\n });\n // Container-packaged variants, so both packagings are covered and a workspace\n // mixing them vends one copy of the shared runtime module.\n await tsMcpServerGenerator(tree, {\n project: 'ts-project',\n name: 'ecr-mcp-server',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n ...defaults,\n });\n await pyMcpServerGenerator(tree, {\n project: 'py_project',\n name: 'ecr-mcp-server',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n ...defaults,\n });\n\n // OAuth DCR proxy for Cognito-authenticated MCP servers.\n await tsDcrProxyGenerator(tree, {\n name: 'my-dcr-proxy',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // TypeScript agents across every protocol and auth permutation. The unnamed\n // one takes the generator's default name, which the connections below use.\n const tsAgents: TsAgentGeneratorSchema[] = [\n {\n project: 'ts-project',\n name: 'my-ts-agent',\n infra: 'none',\n iac: 'inherit',\n },\n { project: 'ts-project', infra: 'agentcore', iac: 'inherit' },\n {\n project: 'ts-project',\n name: 'my-ts-ecr-agent',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'ts-project',\n name: 'my-ts-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of tsAgents) {\n await tsAgentGenerator(tree, { ...agent, ...defaults });\n }\n\n // Python agents: Strands across every protocol, plus LangChain in its own\n // project — langchain's dependency closure would push the zip-bundled Lambda\n // in py-project past its unzipped size limit.\n const pyAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_project',\n name: 'my-agent',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-ecr-agent',\n infra: 'agentcore-ecr',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent',\n protocol: 'a2a',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-a2a-agent-cognito',\n protocol: 'a2a',\n auth: 'cognito',\n infra: 'agentcore',\n iac: 'inherit',\n },\n {\n project: 'py_project',\n name: 'my-py-agui-agent',\n protocol: 'ag-ui',\n infra: 'agentcore',\n iac: 'inherit',\n },\n ];\n for (const agent of pyAgents) {\n await pyAgentGenerator(tree, { ...agent, ...defaults });\n }\n await pyProjectGenerator(tree, {\n name: 'py-langchain-project',\n type: 'application',\n ...projectDefaults,\n });\n const langchainAgents: PyAgentGeneratorSchema[] = [\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-agent',\n protocol: 'ag-ui',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-http-agent',\n protocol: 'http',\n iac: 'inherit',\n },\n {\n project: 'py_langchain_project',\n name: 'my-py-langchain-a2a-agent',\n protocol: 'a2a',\n iac: 'inherit',\n },\n ];\n for (const agent of langchainAgents) {\n await pyAgentGenerator(tree, {\n ...agent,\n framework: 'langchain',\n infra: 'agentcore',\n ...defaults,\n });\n }\n\n // AgentCore gateways, including a parent fronting the first (chained), and\n // an http-protocol gateway fronting agent runtime targets.\n await agentcoreGatewayGenerator(tree, {\n name: 'my-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'parent-gateway',\n iac: 'inherit',\n ...projectDefaults,\n });\n await agentcoreGatewayGenerator(tree, {\n name: 'agent-gateway',\n protocol: 'http',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // AgentCore Harness — a standalone invocation project.\n await agentcoreHarnessGenerator(tree, {\n name: 'my-harness',\n infra: 'agentcore',\n iac: 'inherit',\n ...projectDefaults,\n });\n\n // Databases — DynamoDB, plus Aurora across both engines and ORMs.\n await tsDynamoDBGenerator(tree, {\n name: 'my-table',\n framework: 'electrodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n await pyDynamoDBGenerator(tree, {\n name: 'my-py-table',\n framework: 'pynamodb',\n infra: 'dynamodb',\n iac: 'inherit',\n ...projectDefaults,\n });\n const tsRdbs: TsRdbGeneratorSchema[] = [\n {\n name: 'postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'prisma',\n iac: 'inherit',\n },\n {\n name: 'my-sql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'prisma',\n iac: 'inherit',\n },\n ];\n for (const rdb of tsRdbs) {\n await tsRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n const pyRdbs: PyRdbGeneratorSchema[] = [\n {\n name: 'py-postgres-db',\n infra: 'aurora',\n engine: 'postgres',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n {\n name: 'py-mysql-db',\n infra: 'aurora',\n engine: 'mysql',\n framework: 'sqlmodel',\n iac: 'inherit',\n },\n ];\n for (const rdb of pyRdbs) {\n await pyRdbGenerator(tree, { ...rdb, ...projectDefaults });\n }\n\n // Every connection edge the matrix covers.\n const connections: ConnectionGeneratorSchema[] = [\n // Website -> API\n { sourceProject: ts('website'), targetProject: ts('my-api') },\n { sourceProject: ts('website-no-router'), targetProject: ts('my-api') },\n { sourceProject: 'website', targetProject: 'py_api' },\n { sourceProject: 'website', targetProject: 'my-smithy-api' },\n // Agent -> MCP server\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agui-agent',\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n // HTTP agent <-> A2A agent\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n // Agent -> gateway, gateway -> MCP server, gateway -> gateway\n {\n sourceProject: 'ts-project',\n sourceComponent: 'agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-agent',\n targetProject: ts('my-gateway'),\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'hosted-mcp-server',\n },\n {\n sourceProject: ts('my-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-mcp-server',\n },\n { sourceProject: ts('parent-gateway'), targetProject: ts('my-gateway') },\n // Gateway -> agent (http gateway fronting agent runtime targets: every\n // supported protocol permutation), then website -> gateway.\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-a2a-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('agent-gateway'),\n targetProject: 'py_project',\n targetComponent: 'my-py-a2a-agent',\n },\n {\n sourceProject: ts('website-no-router'),\n targetProject: ts('agent-gateway'),\n },\n // Website -> agent\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'ts-project',\n targetComponent: 'my-ts-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_project',\n targetComponent: 'my-py-agui-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-agent',\n },\n {\n sourceProject: ts('website'),\n targetProject: 'py_langchain_project',\n targetComponent: 'my-py-langchain-http-agent',\n },\n // DynamoDB\n { sourceProject: 'my-api', targetProject: ts('my-table') },\n { sourceProject: 'my-smithy-api', targetProject: ts('my-table') },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-ts-agent',\n targetProject: ts('my-table'),\n },\n {\n sourceProject: 'ts-project',\n sourceComponent: 'my-mcp-server',\n targetProject: ts('my-table'),\n },\n { sourceProject: 'py_api', targetProject: 'my_py_table' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'my_py_table',\n },\n {\n sourceProject: 'py_langchain_project',\n sourceComponent: 'my-py-langchain-http-agent',\n targetProject: 'my_py_table',\n },\n // Relational databases\n { sourceProject: 'py_api', targetProject: 'py_postgres_db' },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-agent',\n targetProject: 'py_postgres_db',\n },\n {\n sourceProject: 'py_project',\n sourceComponent: 'my-mcp-server',\n targetProject: 'py_postgres_db',\n },\n ];\n for (const connection of connections) {\n await connectionGenerator(tree, { ...connection, ...defaults });\n }\n\n // Licensing, then an Nx plugin with a custom generator.\n await licenseGenerator(tree, {\n license: 'Apache-2.0',\n copyrightHolder: 'Amazon.com, Inc. or its affiliates',\n ...defaults,\n });\n await tsNxPluginGenerator(tree, {\n ...projectDefaults,\n name: 'plugin',\n directory: 'tools',\n });\n await tsNxGeneratorGenerator(tree, {\n project: ts('plugin'),\n name: 'my#generator',\n ...defaults,\n });\n\n // A migration of each kind, so the scaffolded codemods compile and the\n // plugin's migrations.json (created by the first run) registers all three.\n const migrations: Omit<TsNxMigrationGeneratorSchema, 'project'>[] = [\n {\n name: 'rename-foo-target',\n description: 'Rename the foo target to bar',\n },\n {\n name: 'migrate-custom-handlers',\n description: 'Update custom handlers for the new API',\n kind: 'agentic',\n },\n {\n name: 'upgrade-framework',\n description: 'Upgrade the framework and reconcile call sites',\n kind: 'hybrid',\n },\n ];\n for (const migration of migrations) {\n await tsNxMigrationGenerator(tree, {\n ...migration,\n project: ts('plugin'),\n ...defaults,\n });\n }\n\n return () =>\n installDependencies(tree, preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default internalTestMatrixGenerator;\n"],"names":["agentcoreGatewayGenerator","agentcoreHarnessGenerator","connectionGenerator","licenseGenerator","pyAgentGenerator","pyApiGenerator","pyDynamoDBGenerator","pyLambdaFunctionGenerator","pyMcpServerGenerator","pyProjectGenerator","pyRdbGenerator","smithyProjectGenerator","terraformProjectGenerator","tsAgentGenerator","tsApiGenerator","tsDcrProxyGenerator","tsDocsGenerator","tsDynamoDBGenerator","tsInfraGenerator","tsLambdaFunctionGenerator","tsMcpServerGenerator","tsNxGeneratorGenerator","tsNxMigrationGenerator","tsNxPluginGenerator","tsProjectGenerator","tsRdbGenerator","tsWebsiteAuthGenerator","tsWebsiteGenerator","installDependencies","toSnakeCase","getNpmScope","getNpmScopePrefix","internalTestMatrixGenerator","tree","options","preferInstallDependencies","defaults","projectDefaults","directory","ts","name","py","infra","type","stageConfig","iac","tanstackRouter","project","cognitoDomain","allowSignup","tsApis","auth","integrationPattern","framework","api","pyApis","event","tsAgents","protocol","agent","pyAgents","langchainAgents","tsRdbs","engine","rdb","pyRdbs","connections","sourceProject","targetProject","sourceComponent","targetComponent","connection","license","copyrightHolder","migrations","description","kind","migration","languages"],"mappings":"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"}
|
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type Tree } from '@nx/devkit';
|
|
6
6
|
import type { SyncGeneratorResult } from 'nx/src/utils/sync-generators';
|
|
7
|
+
import type { CommentSyntax } from '../config-types.js';
|
|
7
8
|
export declare const SYNC_GENERATOR_NAME: string;
|
|
8
9
|
export declare function licenseSyncGenerator(tree: Tree): Promise<SyncGeneratorResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Parse the hashbang, header and body from a file.
|
|
12
|
+
* The header is the first block comment, or consecutive series of line comments found in the file, after the hashbang
|
|
13
|
+
*/
|
|
14
|
+
export declare const parseFile: (content: string, syntax: CommentSyntax) => {
|
|
15
|
+
hashbang: string;
|
|
16
|
+
header: string;
|
|
17
|
+
body: string;
|
|
18
|
+
};
|
|
9
19
|
export default licenseSyncGenerator;
|
|
@@ -178,7 +178,7 @@ export async function licenseSyncGenerator(tree) {
|
|
|
178
178
|
/**
|
|
179
179
|
* Parse the hashbang, header and body from a file.
|
|
180
180
|
* The header is the first block comment, or consecutive series of line comments found in the file, after the hashbang
|
|
181
|
-
*/ const parseFile = (content, syntax)=>{
|
|
181
|
+
*/ export const parseFile = (content, syntax)=>{
|
|
182
182
|
const lines = content.split('\n');
|
|
183
183
|
let i = 0;
|
|
184
184
|
// Hashbangs must always go first, so extract this if it exists
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/license/sync/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n globAsync,\n joinPathFragments,\n type Tree,\n} from '@nx/devkit';\nimport fastGlob from 'fast-glob';\nimport { minimatch } from 'minimatch';\nimport type { SyncGeneratorResult } from 'nx/src/utils/sync-generators';\nimport { basename } from 'path';\nimport PackageJson from '../../../package.json' with { type: 'json' };\nimport { AWS_NX_PLUGIN_CONFIG_FILE_NAME } from '../../utils/config/utils.js';\nimport { getGitIncludedFiles, isWithinGitRepo } from '../../utils/git.js';\nimport { getGeneratorInfo } from '../../utils/nx.js';\nimport { LANGUAGE_COMMENT_SYNTAX, readLicenseConfig } from '../config.js';\nimport type {\n CommentSyntax,\n LicenseHeaderConfig,\n LicenseHeaderFormat,\n} from '../config-types.js';\nimport {\n PROJECT_FILES_TO_SYNC,\n type ProjectFileToSync,\n syncProjectFile,\n} from './project-file-sync.js';\n\nexport const SYNC_GENERATOR_NAME = `${PackageJson.name}:${getGeneratorInfo(import.meta.filename).id}`;\n\ninterface ProjectFile {\n name: ProjectFileToSync;\n path: string;\n}\n\nexport async function licenseSyncGenerator(\n tree: Tree,\n): Promise<SyncGeneratorResult> {\n const source = (await readLicenseConfig(tree))?.source;\n\n if (!source) {\n // Nothing to do when source licensing (headers + LICENSE files) isn't configured\n return {};\n }\n\n const licenseHeadersUpdated: string[] = [];\n\n if (source.header) {\n // Get all candidate project files for header\n const candidateProjectFiles = await getCandidateProjectFilesForHeader(\n tree,\n source.header,\n );\n\n const headerContentLines = loadHeaderContentLines(tree, source.header);\n\n // Add headers to project files which match the include pattern\n for (const [includePattern, format] of Object.entries(\n source.header.format,\n )) {\n const files = minimatch.match(candidateProjectFiles, includePattern);\n\n files.forEach((file) => {\n const didAdd = addHeader(\n tree,\n file,\n headerContentLines,\n source.header,\n format,\n );\n if (didAdd) {\n licenseHeadersUpdated.push(file);\n }\n });\n }\n }\n\n const projectFilesUpdated: ProjectFile[] = [];\n\n // Helper to check whether a file should be included in the sync based on file exclude configuration\n const isFileIncludedInSync = (path: string): boolean =>\n !(source.files?.exclude ?? []).some((excludePattern) =>\n minimatch(path, excludePattern),\n );\n\n // Sync files in the root, and all projects\n const projectRoots = [\n '.',\n ...[...getProjects(tree).values()].map((p) => p.root),\n ];\n\n // Sync subproject license files and project files\n for (const projectRoot of projectRoots) {\n // Check that this project should have files synced - allows users to specify a project path\n // to exclude from all file syncs\n if (isFileIncludedInSync(projectRoot)) {\n PROJECT_FILES_TO_SYNC.forEach((projectFile) => {\n const projectFilePath = joinPathFragments(projectRoot, projectFile);\n // Check that the specific project file should be synced - allows users to be more granular to\n // decide to eg omit LICENSE file sync but keep package.json sync\n if (isFileIncludedInSync(projectFilePath)) {\n const prevContent = tree.read(projectFilePath, 'utf-8');\n\n syncProjectFile(tree, projectRoot, projectFile, source);\n\n const newContent = tree.read(projectFilePath, 'utf-8');\n\n if (prevContent !== newContent) {\n projectFilesUpdated.push({\n path: projectFilePath,\n name: projectFile,\n });\n }\n }\n });\n }\n }\n\n return {\n outOfSyncMessage: buildOutOfSyncMessage({\n licenseHeadersUpdated,\n projectFilesUpdated,\n }),\n };\n}\n\n/**\n * Build the message to display when the sync generator would make changes to the tree\n */\nconst buildOutOfSyncMessage = (updates: {\n projectFilesUpdated: ProjectFile[];\n licenseHeadersUpdated: string[];\n}): string => {\n let outOfSyncMessage = '';\n\n const pathsByName: { [key: string]: string[] } =\n updates.projectFilesUpdated.reduce(\n (prev, { name, path }) => ({\n ...prev,\n [name]: [...(prev[name] ?? []), path],\n }),\n {},\n );\n Object.entries(pathsByName).forEach(([name, files]) => {\n outOfSyncMessage += `Project ${name} files are out of sync:\\n${files.map((p) => `- ${p}`).join('\\n')}\\n\\n`;\n });\n\n if (updates.licenseHeadersUpdated.length > 0) {\n outOfSyncMessage += `License headers are out of sync in the following source files:\\n${updates.licenseHeadersUpdated.map((p) => `- ${p}`).join('\\n')}\\n\\n`;\n }\n\n return outOfSyncMessage.trim();\n};\n\n/**\n * Load the license header content lines\n */\nconst loadHeaderContentLines = (\n tree: Tree,\n config: LicenseHeaderConfig,\n): string[] => {\n // Load the license header content\n let headerContentLines = [];\n if ('lines' in config.content) {\n headerContentLines = config.content.lines;\n } else {\n if (!tree.exists(config.content.filePath)) {\n throw new Error(\n `Could not find license header content file ${config.content.filePath}`,\n );\n }\n headerContentLines = tree\n .read(config.content.filePath, 'utf-8')\n .split('\\n');\n }\n return headerContentLines;\n};\n\n/**\n * Returns all files in the given tree - both in-memory only and in the filesystem under the tree root\n */\nconst getAllFilesInTree = async (tree: Tree): Promise<string[]> => {\n return [\n ...new Set([\n // Get all files in memory in the tree\n ...(await globAsync(tree, ['*', '**/*'])),\n // Find all files on the filesystem that may not be in memory in the tree\n ...(await fastGlob(['*', '**/*'], { cwd: tree.root, dot: true })),\n ]),\n ].filter((f) => tree.exists(f));\n};\n\n/**\n * Returns the list of project files\n */\nconst getCandidateProjectFilesForHeader = async (\n tree: Tree,\n config: LicenseHeaderConfig,\n): Promise<string[]> => {\n // Prefer, if possible, to treat all non gitignored files as our candidate set such that we honour users .gitignore files\n // If we're not in a git repo, fall back to everything and rely on the user configuring exclusions below\n const projectFiles = isWithinGitRepo(tree)\n ? getGitIncludedFiles(tree)\n : await getAllFilesInTree(tree);\n\n // Remove any files that were excluded in the config\n const ignoredProjectFiles = new Set(\n (config.exclude ?? []).flatMap((pattern) =>\n minimatch.match(projectFiles, pattern),\n ),\n );\n return projectFiles.filter((file) => !ignoredProjectFiles.has(file));\n};\n\n/**\n * Renders a header with the given format\n */\nconst renderHeader = (\n contentLines: string[],\n format: LicenseHeaderFormat,\n): string => {\n return `${format.blockStart ? `${format.blockStart}\\n` : ''}${contentLines.map((line) => `${format.lineStart ?? ''}${line}${format.lineEnd ?? ''}`).join('\\n')}${format.blockEnd ? `\\n${format.blockEnd}` : ''}`;\n};\n\n/**\n * Validates header format to ensure it produces a valid comment\n */\nconst validateFormat = (\n fileExtension: string,\n syntax: CommentSyntax,\n format: LicenseHeaderFormat,\n contentLines: string[],\n): void => {\n const blockStartOpensBlockComment =\n format.blockStart &&\n syntax.block &&\n format.blockStart.startsWith(syntax.block.start);\n const blockEndClosesBlockComment =\n format.blockEnd &&\n syntax.block &&\n format.blockEnd.endsWith(syntax.block.end);\n\n // Block start must start with the block start or line comment\n const validBlockStart =\n !format.blockStart ||\n blockStartOpensBlockComment ||\n (syntax.line && format.blockStart.startsWith(syntax.line));\n // Block end must end with the block end, or begin with the line comment\n const validBlockEnd =\n !format.blockEnd ||\n blockEndClosesBlockComment ||\n (syntax.line && format.blockEnd.startsWith(syntax.line));\n\n // Lines must start with the line comment syntax, unless within a block comment\n const validLineStart =\n !format.lineStart ||\n (syntax.line && format.lineStart.startsWith(syntax.line)) ||\n (blockStartOpensBlockComment && blockEndClosesBlockComment);\n\n if (!validLineStart || !validBlockStart || !validBlockEnd) {\n throw new Error(\n `Provided format for ${fileExtension} file would generate invalid comment syntax. Configured syntax for ${fileExtension} is ${JSON.stringify(syntax, null, 2)}.`,\n );\n }\n\n if (blockStartOpensBlockComment && !blockEndClosesBlockComment) {\n throw new Error(\n `Provided format for ${fileExtension} file opens a block comment with \"${syntax.block.start}\" in blockStart but does not close it with \"${syntax.block.end}\" in blockEnd`,\n );\n }\n\n if (\n blockStartOpensBlockComment &&\n contentLines.some((line) => line.includes(syntax.block.end))\n ) {\n throw new Error(\n `Provided license content would close a block comment early and cause a syntax error! Please remove \"${syntax.block.end}\" from your license text.`,\n );\n }\n\n if (blockStartOpensBlockComment && blockEndClosesBlockComment) {\n if (\n format.blockEnd.lastIndexOf(syntax.block.end) !==\n format.blockEnd.indexOf(syntax.block.end)\n ) {\n throw new Error(\n `Provided format for ${fileExtension} file may cause syntax errors due to closing a block comment multiple times with \"${syntax.block.end}\" in blockEnd`,\n );\n }\n if (format.blockStart.includes(syntax.block.end)) {\n throw new Error(\n `Provided format for ${fileExtension} file may cause syntax errors since it closes the block comment with \"${syntax.block.end}\" in blockStart`,\n );\n }\n }\n};\n\n/**\n * Parse the hashbang, header and body from a file.\n * The header is the first block comment, or consecutive series of line comments found in the file, after the hashbang\n */\nconst parseFile = (\n content: string,\n syntax: CommentSyntax,\n): { hashbang: string; header: string; body: string } => {\n const lines = content.split('\\n');\n let i = 0;\n\n // Hashbangs must always go first, so extract this if it exists\n const hashbangLines = [];\n for (; i < lines.length; i++) {\n if (hashbangLines.length === 0) {\n if (lines[i].startsWith('#!')) {\n hashbangLines.push(lines[i]);\n } else {\n break;\n }\n } else {\n if (lines[i].trim().length === 0) {\n // Preserve any empty lines following the hashbang\n hashbangLines.push(lines[i]);\n } else {\n break;\n }\n }\n }\n\n // After the hashbang, consume the next comment which follows.\n // This could either be all lines of a block comment, or all consecutive line comments until a non line-comment is seen\n const headerLines = [];\n let withinBlockComment = false;\n let withinLineCommentSeries = false;\n for (; i < lines.length; i++) {\n const trimmedLine = lines[i].trim();\n if (\n syntax.block &&\n trimmedLine.endsWith(syntax.block.end) &&\n !withinLineCommentSeries &&\n (withinBlockComment || trimmedLine.startsWith(syntax.block.start))\n ) {\n // Comment ends with the block end, so we've completed the header and therefore break out of the loop\n headerLines.push(lines[i]);\n i++; // Increment here to ensure we point to the next line for the body\n break;\n } else if (\n syntax.block &&\n trimmedLine.startsWith(syntax.block.start) &&\n !withinLineCommentSeries\n ) {\n // Line begins a comment block (without also ending it on the same line), so start consuming the block\n withinBlockComment = true;\n headerLines.push(lines[i]);\n } else if (withinBlockComment) {\n // We haven't yet closed the block comment, so consume this line\n headerLines.push(lines[i]);\n } else if (syntax.line && trimmedLine.startsWith(syntax.line)) {\n // Line starts with the line comment syntax, so consume it\n withinLineCommentSeries = true;\n headerLines.push(lines[i]);\n } else {\n break;\n }\n }\n\n // Body of the file is the rest\n const bodyLines = lines.slice(i);\n\n return {\n hashbang: hashbangLines.join('\\n'),\n header: headerLines.join('\\n'),\n body: bodyLines.join('\\n'),\n };\n};\n\n/**\n * Add a header to the given file according to the header content and license config\n * Returns true if the header was added/updated, and false otherwise.\n */\nconst addHeader = (\n tree: Tree,\n file: string,\n contentLines: string[],\n config: LicenseHeaderConfig,\n format: LicenseHeaderFormat,\n): boolean => {\n const fileName = basename(file);\n const fileNameParts = fileName.split('.');\n const fileExtension = fileNameParts[fileNameParts.length - 1];\n\n const syntax =\n (config.commentSyntax ?? {})[fileExtension] ??\n LANGUAGE_COMMENT_SYNTAX[fileExtension];\n if (!syntax) {\n throw new Error(`Unknown file extension ${fileExtension}. Please configure commentSyntax in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME}, eg:\n\nexport default {\n license: {\n header: {\n ...\n commentSyntax: {\n ${fileExtension}: {\n line: \"//\",\n block: { start: \"/*\", end: \"*/\" }\n }\n }\n }\n }\n} satisfies AwsNxPluginConfig;\n`);\n }\n\n // Check that we would render a valid comment\n validateFormat(fileExtension, syntax, format, contentLines);\n\n const existingContent = tree.read(file, 'utf-8');\n\n const { hashbang, body } = parseFile(existingContent, syntax);\n\n const newContent = [\n ...(hashbang ? [hashbang] : []),\n renderHeader(contentLines, format),\n body,\n ].join('\\n');\n\n // Sanity check that we wouldn't edit the hashbang or body, only the header\n const { hashbang: newHashbang, body: newBody } = parseFile(\n newContent,\n syntax,\n );\n if (hashbang !== newHashbang || body !== newBody) {\n throw new Error(\n `The license header content, or format for ${fileExtension} files would produce a header that cannot be safely replaced in ${file}. Please revise license content and format in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME}`,\n );\n }\n\n if (newContent !== existingContent) {\n tree.write(file, newContent);\n return true;\n }\n\n return false;\n};\n\nexport default licenseSyncGenerator;\n"],"names":["getProjects","globAsync","joinPathFragments","fastGlob","minimatch","basename","PackageJson","type","AWS_NX_PLUGIN_CONFIG_FILE_NAME","getGitIncludedFiles","isWithinGitRepo","getGeneratorInfo","LANGUAGE_COMMENT_SYNTAX","readLicenseConfig","PROJECT_FILES_TO_SYNC","syncProjectFile","SYNC_GENERATOR_NAME","name","filename","id","licenseSyncGenerator","tree","source","licenseHeadersUpdated","header","candidateProjectFiles","getCandidateProjectFilesForHeader","headerContentLines","loadHeaderContentLines","includePattern","format","Object","entries","files","match","forEach","file","didAdd","addHeader","push","projectFilesUpdated","isFileIncludedInSync","path","exclude","some","excludePattern","projectRoots","values","map","p","root","projectRoot","projectFile","projectFilePath","prevContent","read","newContent","outOfSyncMessage","buildOutOfSyncMessage","updates","pathsByName","reduce","prev","join","length","trim","config","content","lines","exists","filePath","Error","split","getAllFilesInTree","Set","cwd","dot","filter","f","projectFiles","ignoredProjectFiles","flatMap","pattern","has","renderHeader","contentLines","blockStart","line","lineStart","lineEnd","blockEnd","validateFormat","fileExtension","syntax","blockStartOpensBlockComment","block","startsWith","start","blockEndClosesBlockComment","endsWith","end","validBlockStart","validBlockEnd","validLineStart","JSON","stringify","includes","lastIndexOf","indexOf","parseFile","i","hashbangLines","headerLines","withinBlockComment","withinLineCommentSeries","trimmedLine","bodyLines","slice","hashbang","body","fileName","fileNameParts","commentSyntax","existingContent","newHashbang","newBody","write"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/license/sync/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n globAsync,\n joinPathFragments,\n type Tree,\n} from '@nx/devkit';\nimport fastGlob from 'fast-glob';\nimport { minimatch } from 'minimatch';\nimport type { SyncGeneratorResult } from 'nx/src/utils/sync-generators';\nimport { basename } from 'path';\nimport PackageJson from '../../../package.json' with { type: 'json' };\nimport { AWS_NX_PLUGIN_CONFIG_FILE_NAME } from '../../utils/config/utils.js';\nimport { getGitIncludedFiles, isWithinGitRepo } from '../../utils/git.js';\nimport { getGeneratorInfo } from '../../utils/nx.js';\nimport { LANGUAGE_COMMENT_SYNTAX, readLicenseConfig } from '../config.js';\nimport type {\n CommentSyntax,\n LicenseHeaderConfig,\n LicenseHeaderFormat,\n} from '../config-types.js';\nimport {\n PROJECT_FILES_TO_SYNC,\n type ProjectFileToSync,\n syncProjectFile,\n} from './project-file-sync.js';\n\nexport const SYNC_GENERATOR_NAME = `${PackageJson.name}:${getGeneratorInfo(import.meta.filename).id}`;\n\ninterface ProjectFile {\n name: ProjectFileToSync;\n path: string;\n}\n\nexport async function licenseSyncGenerator(\n tree: Tree,\n): Promise<SyncGeneratorResult> {\n const source = (await readLicenseConfig(tree))?.source;\n\n if (!source) {\n // Nothing to do when source licensing (headers + LICENSE files) isn't configured\n return {};\n }\n\n const licenseHeadersUpdated: string[] = [];\n\n if (source.header) {\n // Get all candidate project files for header\n const candidateProjectFiles = await getCandidateProjectFilesForHeader(\n tree,\n source.header,\n );\n\n const headerContentLines = loadHeaderContentLines(tree, source.header);\n\n // Add headers to project files which match the include pattern\n for (const [includePattern, format] of Object.entries(\n source.header.format,\n )) {\n const files = minimatch.match(candidateProjectFiles, includePattern);\n\n files.forEach((file) => {\n const didAdd = addHeader(\n tree,\n file,\n headerContentLines,\n source.header,\n format,\n );\n if (didAdd) {\n licenseHeadersUpdated.push(file);\n }\n });\n }\n }\n\n const projectFilesUpdated: ProjectFile[] = [];\n\n // Helper to check whether a file should be included in the sync based on file exclude configuration\n const isFileIncludedInSync = (path: string): boolean =>\n !(source.files?.exclude ?? []).some((excludePattern) =>\n minimatch(path, excludePattern),\n );\n\n // Sync files in the root, and all projects\n const projectRoots = [\n '.',\n ...[...getProjects(tree).values()].map((p) => p.root),\n ];\n\n // Sync subproject license files and project files\n for (const projectRoot of projectRoots) {\n // Check that this project should have files synced - allows users to specify a project path\n // to exclude from all file syncs\n if (isFileIncludedInSync(projectRoot)) {\n PROJECT_FILES_TO_SYNC.forEach((projectFile) => {\n const projectFilePath = joinPathFragments(projectRoot, projectFile);\n // Check that the specific project file should be synced - allows users to be more granular to\n // decide to eg omit LICENSE file sync but keep package.json sync\n if (isFileIncludedInSync(projectFilePath)) {\n const prevContent = tree.read(projectFilePath, 'utf-8');\n\n syncProjectFile(tree, projectRoot, projectFile, source);\n\n const newContent = tree.read(projectFilePath, 'utf-8');\n\n if (prevContent !== newContent) {\n projectFilesUpdated.push({\n path: projectFilePath,\n name: projectFile,\n });\n }\n }\n });\n }\n }\n\n return {\n outOfSyncMessage: buildOutOfSyncMessage({\n licenseHeadersUpdated,\n projectFilesUpdated,\n }),\n };\n}\n\n/**\n * Build the message to display when the sync generator would make changes to the tree\n */\nconst buildOutOfSyncMessage = (updates: {\n projectFilesUpdated: ProjectFile[];\n licenseHeadersUpdated: string[];\n}): string => {\n let outOfSyncMessage = '';\n\n const pathsByName: { [key: string]: string[] } =\n updates.projectFilesUpdated.reduce(\n (prev, { name, path }) => ({\n ...prev,\n [name]: [...(prev[name] ?? []), path],\n }),\n {},\n );\n Object.entries(pathsByName).forEach(([name, files]) => {\n outOfSyncMessage += `Project ${name} files are out of sync:\\n${files.map((p) => `- ${p}`).join('\\n')}\\n\\n`;\n });\n\n if (updates.licenseHeadersUpdated.length > 0) {\n outOfSyncMessage += `License headers are out of sync in the following source files:\\n${updates.licenseHeadersUpdated.map((p) => `- ${p}`).join('\\n')}\\n\\n`;\n }\n\n return outOfSyncMessage.trim();\n};\n\n/**\n * Load the license header content lines\n */\nconst loadHeaderContentLines = (\n tree: Tree,\n config: LicenseHeaderConfig,\n): string[] => {\n // Load the license header content\n let headerContentLines = [];\n if ('lines' in config.content) {\n headerContentLines = config.content.lines;\n } else {\n if (!tree.exists(config.content.filePath)) {\n throw new Error(\n `Could not find license header content file ${config.content.filePath}`,\n );\n }\n headerContentLines = tree\n .read(config.content.filePath, 'utf-8')\n .split('\\n');\n }\n return headerContentLines;\n};\n\n/**\n * Returns all files in the given tree - both in-memory only and in the filesystem under the tree root\n */\nconst getAllFilesInTree = async (tree: Tree): Promise<string[]> => {\n return [\n ...new Set([\n // Get all files in memory in the tree\n ...(await globAsync(tree, ['*', '**/*'])),\n // Find all files on the filesystem that may not be in memory in the tree\n ...(await fastGlob(['*', '**/*'], { cwd: tree.root, dot: true })),\n ]),\n ].filter((f) => tree.exists(f));\n};\n\n/**\n * Returns the list of project files\n */\nconst getCandidateProjectFilesForHeader = async (\n tree: Tree,\n config: LicenseHeaderConfig,\n): Promise<string[]> => {\n // Prefer, if possible, to treat all non gitignored files as our candidate set such that we honour users .gitignore files\n // If we're not in a git repo, fall back to everything and rely on the user configuring exclusions below\n const projectFiles = isWithinGitRepo(tree)\n ? getGitIncludedFiles(tree)\n : await getAllFilesInTree(tree);\n\n // Remove any files that were excluded in the config\n const ignoredProjectFiles = new Set(\n (config.exclude ?? []).flatMap((pattern) =>\n minimatch.match(projectFiles, pattern),\n ),\n );\n return projectFiles.filter((file) => !ignoredProjectFiles.has(file));\n};\n\n/**\n * Renders a header with the given format\n */\nconst renderHeader = (\n contentLines: string[],\n format: LicenseHeaderFormat,\n): string => {\n return `${format.blockStart ? `${format.blockStart}\\n` : ''}${contentLines.map((line) => `${format.lineStart ?? ''}${line}${format.lineEnd ?? ''}`).join('\\n')}${format.blockEnd ? `\\n${format.blockEnd}` : ''}`;\n};\n\n/**\n * Validates header format to ensure it produces a valid comment\n */\nconst validateFormat = (\n fileExtension: string,\n syntax: CommentSyntax,\n format: LicenseHeaderFormat,\n contentLines: string[],\n): void => {\n const blockStartOpensBlockComment =\n format.blockStart &&\n syntax.block &&\n format.blockStart.startsWith(syntax.block.start);\n const blockEndClosesBlockComment =\n format.blockEnd &&\n syntax.block &&\n format.blockEnd.endsWith(syntax.block.end);\n\n // Block start must start with the block start or line comment\n const validBlockStart =\n !format.blockStart ||\n blockStartOpensBlockComment ||\n (syntax.line && format.blockStart.startsWith(syntax.line));\n // Block end must end with the block end, or begin with the line comment\n const validBlockEnd =\n !format.blockEnd ||\n blockEndClosesBlockComment ||\n (syntax.line && format.blockEnd.startsWith(syntax.line));\n\n // Lines must start with the line comment syntax, unless within a block comment\n const validLineStart =\n !format.lineStart ||\n (syntax.line && format.lineStart.startsWith(syntax.line)) ||\n (blockStartOpensBlockComment && blockEndClosesBlockComment);\n\n if (!validLineStart || !validBlockStart || !validBlockEnd) {\n throw new Error(\n `Provided format for ${fileExtension} file would generate invalid comment syntax. Configured syntax for ${fileExtension} is ${JSON.stringify(syntax, null, 2)}.`,\n );\n }\n\n if (blockStartOpensBlockComment && !blockEndClosesBlockComment) {\n throw new Error(\n `Provided format for ${fileExtension} file opens a block comment with \"${syntax.block.start}\" in blockStart but does not close it with \"${syntax.block.end}\" in blockEnd`,\n );\n }\n\n if (\n blockStartOpensBlockComment &&\n contentLines.some((line) => line.includes(syntax.block.end))\n ) {\n throw new Error(\n `Provided license content would close a block comment early and cause a syntax error! Please remove \"${syntax.block.end}\" from your license text.`,\n );\n }\n\n if (blockStartOpensBlockComment && blockEndClosesBlockComment) {\n if (\n format.blockEnd.lastIndexOf(syntax.block.end) !==\n format.blockEnd.indexOf(syntax.block.end)\n ) {\n throw new Error(\n `Provided format for ${fileExtension} file may cause syntax errors due to closing a block comment multiple times with \"${syntax.block.end}\" in blockEnd`,\n );\n }\n if (format.blockStart.includes(syntax.block.end)) {\n throw new Error(\n `Provided format for ${fileExtension} file may cause syntax errors since it closes the block comment with \"${syntax.block.end}\" in blockStart`,\n );\n }\n }\n};\n\n/**\n * Parse the hashbang, header and body from a file.\n * The header is the first block comment, or consecutive series of line comments found in the file, after the hashbang\n */\nexport const parseFile = (\n content: string,\n syntax: CommentSyntax,\n): { hashbang: string; header: string; body: string } => {\n const lines = content.split('\\n');\n let i = 0;\n\n // Hashbangs must always go first, so extract this if it exists\n const hashbangLines = [];\n for (; i < lines.length; i++) {\n if (hashbangLines.length === 0) {\n if (lines[i].startsWith('#!')) {\n hashbangLines.push(lines[i]);\n } else {\n break;\n }\n } else {\n if (lines[i].trim().length === 0) {\n // Preserve any empty lines following the hashbang\n hashbangLines.push(lines[i]);\n } else {\n break;\n }\n }\n }\n\n // After the hashbang, consume the next comment which follows.\n // This could either be all lines of a block comment, or all consecutive line comments until a non line-comment is seen\n const headerLines = [];\n let withinBlockComment = false;\n let withinLineCommentSeries = false;\n for (; i < lines.length; i++) {\n const trimmedLine = lines[i].trim();\n if (\n syntax.block &&\n trimmedLine.endsWith(syntax.block.end) &&\n !withinLineCommentSeries &&\n (withinBlockComment || trimmedLine.startsWith(syntax.block.start))\n ) {\n // Comment ends with the block end, so we've completed the header and therefore break out of the loop\n headerLines.push(lines[i]);\n i++; // Increment here to ensure we point to the next line for the body\n break;\n } else if (\n syntax.block &&\n trimmedLine.startsWith(syntax.block.start) &&\n !withinLineCommentSeries\n ) {\n // Line begins a comment block (without also ending it on the same line), so start consuming the block\n withinBlockComment = true;\n headerLines.push(lines[i]);\n } else if (withinBlockComment) {\n // We haven't yet closed the block comment, so consume this line\n headerLines.push(lines[i]);\n } else if (syntax.line && trimmedLine.startsWith(syntax.line)) {\n // Line starts with the line comment syntax, so consume it\n withinLineCommentSeries = true;\n headerLines.push(lines[i]);\n } else {\n break;\n }\n }\n\n // Body of the file is the rest\n const bodyLines = lines.slice(i);\n\n return {\n hashbang: hashbangLines.join('\\n'),\n header: headerLines.join('\\n'),\n body: bodyLines.join('\\n'),\n };\n};\n\n/**\n * Add a header to the given file according to the header content and license config\n * Returns true if the header was added/updated, and false otherwise.\n */\nconst addHeader = (\n tree: Tree,\n file: string,\n contentLines: string[],\n config: LicenseHeaderConfig,\n format: LicenseHeaderFormat,\n): boolean => {\n const fileName = basename(file);\n const fileNameParts = fileName.split('.');\n const fileExtension = fileNameParts[fileNameParts.length - 1];\n\n const syntax =\n (config.commentSyntax ?? {})[fileExtension] ??\n LANGUAGE_COMMENT_SYNTAX[fileExtension];\n if (!syntax) {\n throw new Error(`Unknown file extension ${fileExtension}. Please configure commentSyntax in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME}, eg:\n\nexport default {\n license: {\n header: {\n ...\n commentSyntax: {\n ${fileExtension}: {\n line: \"//\",\n block: { start: \"/*\", end: \"*/\" }\n }\n }\n }\n }\n} satisfies AwsNxPluginConfig;\n`);\n }\n\n // Check that we would render a valid comment\n validateFormat(fileExtension, syntax, format, contentLines);\n\n const existingContent = tree.read(file, 'utf-8');\n\n const { hashbang, body } = parseFile(existingContent, syntax);\n\n const newContent = [\n ...(hashbang ? [hashbang] : []),\n renderHeader(contentLines, format),\n body,\n ].join('\\n');\n\n // Sanity check that we wouldn't edit the hashbang or body, only the header\n const { hashbang: newHashbang, body: newBody } = parseFile(\n newContent,\n syntax,\n );\n if (hashbang !== newHashbang || body !== newBody) {\n throw new Error(\n `The license header content, or format for ${fileExtension} files would produce a header that cannot be safely replaced in ${file}. Please revise license content and format in ${AWS_NX_PLUGIN_CONFIG_FILE_NAME}`,\n );\n }\n\n if (newContent !== existingContent) {\n tree.write(file, newContent);\n return true;\n }\n\n return false;\n};\n\nexport default licenseSyncGenerator;\n"],"names":["getProjects","globAsync","joinPathFragments","fastGlob","minimatch","basename","PackageJson","type","AWS_NX_PLUGIN_CONFIG_FILE_NAME","getGitIncludedFiles","isWithinGitRepo","getGeneratorInfo","LANGUAGE_COMMENT_SYNTAX","readLicenseConfig","PROJECT_FILES_TO_SYNC","syncProjectFile","SYNC_GENERATOR_NAME","name","filename","id","licenseSyncGenerator","tree","source","licenseHeadersUpdated","header","candidateProjectFiles","getCandidateProjectFilesForHeader","headerContentLines","loadHeaderContentLines","includePattern","format","Object","entries","files","match","forEach","file","didAdd","addHeader","push","projectFilesUpdated","isFileIncludedInSync","path","exclude","some","excludePattern","projectRoots","values","map","p","root","projectRoot","projectFile","projectFilePath","prevContent","read","newContent","outOfSyncMessage","buildOutOfSyncMessage","updates","pathsByName","reduce","prev","join","length","trim","config","content","lines","exists","filePath","Error","split","getAllFilesInTree","Set","cwd","dot","filter","f","projectFiles","ignoredProjectFiles","flatMap","pattern","has","renderHeader","contentLines","blockStart","line","lineStart","lineEnd","blockEnd","validateFormat","fileExtension","syntax","blockStartOpensBlockComment","block","startsWith","start","blockEndClosesBlockComment","endsWith","end","validBlockStart","validBlockEnd","validLineStart","JSON","stringify","includes","lastIndexOf","indexOf","parseFile","i","hashbangLines","headerLines","withinBlockComment","withinLineCommentSeries","trimmedLine","bodyLines","slice","hashbang","body","fileName","fileNameParts","commentSyntax","existingContent","newHashbang","newBody","write"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { getProjects, updateProjectConfiguration } from "@nx/devkit";
|
|
5
|
+
import { INFRA_APP_GENERATOR_INFO } from "../../../infra/app/generator.js";
|
|
6
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
7
|
+
/**
|
|
8
|
+
* Widen the stage pattern of the sandbox targets of ts#infra projects from
|
|
9
|
+
* `<stage>/*` to `<stage>/**`.
|
|
10
|
+
*
|
|
11
|
+
* A single `*` matches the stage's own stacks but nothing below them, so it
|
|
12
|
+
* misses stacks a construct creates inside a stack - such as the `us-east-1`
|
|
13
|
+
* WebACL stack a website creates for its CloudFront distribution.
|
|
14
|
+
* `cdk destroy` only deletes the stacks its pattern selects, so
|
|
15
|
+
* `destroy-sandbox` left that stack, and the WebACL it bills for, deployed.
|
|
16
|
+
*/ const SANDBOX_TARGETS = [
|
|
17
|
+
'deploy-sandbox',
|
|
18
|
+
'destroy-sandbox'
|
|
19
|
+
];
|
|
20
|
+
/** A quoted or bare stage pattern ending in a single `*`, ie `"my-sandbox/*"`. */ const SINGLE_STAR_PATTERN = /^("?)\S+\/\*\1$/;
|
|
21
|
+
const widen = (token)=>token.replace(/\/\*("?)$/, '/**$1');
|
|
22
|
+
/**
|
|
23
|
+
* Whether the command is one of the deploy/destroy commands this generator
|
|
24
|
+
* vends - either a direct `cdk deploy`/`cdk destroy`, or the stage-config
|
|
25
|
+
* script that wraps it. Anything else has been hand-written and is reported
|
|
26
|
+
* rather than rewritten.
|
|
27
|
+
*/ const isGeneratedCommand = (command)=>/(^|\s)cdk\s+(deploy|destroy)(\s|$)/.test(command) || command.includes('infra-deploy.ts') || command.includes('infra-destroy.ts');
|
|
28
|
+
export default async function migration(tree) {
|
|
29
|
+
const nextSteps = [];
|
|
30
|
+
let migrated = false;
|
|
31
|
+
for (const [name, project] of getProjects(tree)){
|
|
32
|
+
if (project.metadata?.generator !== INFRA_APP_GENERATOR_INFO.id) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
let projectChanged = false;
|
|
36
|
+
for (const targetName of SANDBOX_TARGETS){
|
|
37
|
+
const target = project.targets?.[targetName];
|
|
38
|
+
const command = target?.options?.command;
|
|
39
|
+
if (!target || typeof command !== 'string') {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const args = command.split(/\s+/);
|
|
43
|
+
// Nothing to widen: already `/**`, or the pattern has been removed. Keeps
|
|
44
|
+
// re-runs - and a project generated after this change - a no-op.
|
|
45
|
+
if (!args.some((arg)=>SINGLE_STAR_PATTERN.test(arg))) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (!isGeneratedCommand(command)) {
|
|
49
|
+
nextSteps.push(`${name}: its ${targetName} target has been customised, so it was left as it is. Widen its stage pattern from "<stage>/*" to "<stage>/**" so it also matches stacks nested below the stage's stacks, such as a website's WebACL stack.`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
target.options.command = args.map((arg)=>SINGLE_STAR_PATTERN.test(arg) ? widen(arg) : arg).join(' ');
|
|
53
|
+
projectChanged = true;
|
|
54
|
+
}
|
|
55
|
+
if (projectChanged) {
|
|
56
|
+
updateProjectConfiguration(tree, name, project);
|
|
57
|
+
migrated = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (migrated) {
|
|
61
|
+
await formatFilesInSubtree(tree);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
nextSteps
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/sandbox-pattern-nested-stacks/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type TargetConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { INFRA_APP_GENERATOR_INFO } from '../../../infra/app/generator.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\n\n/**\n * Widen the stage pattern of the sandbox targets of ts#infra projects from\n * `<stage>/*` to `<stage>/**`.\n *\n * A single `*` matches the stage's own stacks but nothing below them, so it\n * misses stacks a construct creates inside a stack - such as the `us-east-1`\n * WebACL stack a website creates for its CloudFront distribution.\n * `cdk destroy` only deletes the stacks its pattern selects, so\n * `destroy-sandbox` left that stack, and the WebACL it bills for, deployed.\n */\n\nconst SANDBOX_TARGETS = ['deploy-sandbox', 'destroy-sandbox'];\n\n/** A quoted or bare stage pattern ending in a single `*`, ie `\"my-sandbox/*\"`. */\nconst SINGLE_STAR_PATTERN = /^(\"?)\\S+\\/\\*\\1$/;\n\nconst widen = (token: string): string => token.replace(/\\/\\*(\"?)$/, '/**$1');\n\n/**\n * Whether the command is one of the deploy/destroy commands this generator\n * vends - either a direct `cdk deploy`/`cdk destroy`, or the stage-config\n * script that wraps it. Anything else has been hand-written and is reported\n * rather than rewritten.\n */\nconst isGeneratedCommand = (command: string): boolean =>\n /(^|\\s)cdk\\s+(deploy|destroy)(\\s|$)/.test(command) ||\n command.includes('infra-deploy.ts') ||\n command.includes('infra-destroy.ts');\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let migrated = false;\n\n for (const [name, project] of getProjects(tree)) {\n if (\n (project.metadata as { generator?: string } | undefined)?.generator !==\n INFRA_APP_GENERATOR_INFO.id\n ) {\n continue;\n }\n\n let projectChanged = false;\n\n for (const targetName of SANDBOX_TARGETS) {\n const target: TargetConfiguration | undefined =\n project.targets?.[targetName];\n const command = target?.options?.command;\n if (!target || typeof command !== 'string') {\n continue;\n }\n\n const args = command.split(/\\s+/);\n // Nothing to widen: already `/**`, or the pattern has been removed. Keeps\n // re-runs - and a project generated after this change - a no-op.\n if (!args.some((arg) => SINGLE_STAR_PATTERN.test(arg))) {\n continue;\n }\n\n if (!isGeneratedCommand(command)) {\n nextSteps.push(\n `${name}: its ${targetName} target has been customised, so it was left as it is. Widen its stage pattern from \"<stage>/*\" to \"<stage>/**\" so it also matches stacks nested below the stage's stacks, such as a website's WebACL stack.`,\n );\n continue;\n }\n\n target.options.command = args\n .map((arg) => (SINGLE_STAR_PATTERN.test(arg) ? widen(arg) : arg))\n .join(' ');\n projectChanged = true;\n }\n\n if (projectChanged) {\n updateProjectConfiguration(tree, name, project);\n migrated = true;\n }\n }\n\n if (migrated) {\n await formatFilesInSubtree(tree);\n }\n\n return { nextSteps };\n}\n"],"names":["getProjects","updateProjectConfiguration","INFRA_APP_GENERATOR_INFO","formatFilesInSubtree","SANDBOX_TARGETS","SINGLE_STAR_PATTERN","widen","token","replace","isGeneratedCommand","command","test","includes","migration","tree","nextSteps","migrated","name","project","metadata","generator","id","projectChanged","targetName","target","targets","options","args","split","some","arg","push","map","join"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EAIXC,0BAA0B,QACrB,aAAa;AACpB,SAASC,wBAAwB,QAAQ,kCAAkC;AAC3E,SAASC,oBAAoB,QAAQ,2BAA2B;AAEhE;;;;;;;;;CASC,GAED,MAAMC,kBAAkB;IAAC;IAAkB;CAAkB;AAE7D,gFAAgF,GAChF,MAAMC,sBAAsB;AAE5B,MAAMC,QAAQ,CAACC,QAA0BA,MAAMC,OAAO,CAAC,aAAa;AAEpE;;;;;CAKC,GACD,MAAMC,qBAAqB,CAACC,UAC1B,qCAAqCC,IAAI,CAACD,YAC1CA,QAAQE,QAAQ,CAAC,sBACjBF,QAAQE,QAAQ,CAAC;AAEnB,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAC9B,IAAIC,WAAW;IAEf,KAAK,MAAM,CAACC,MAAMC,QAAQ,IAAIlB,YAAYc,MAAO;QAC/C,IACE,AAACI,QAAQC,QAAQ,EAAyCC,cAC1DlB,yBAAyBmB,EAAE,EAC3B;YACA;QACF;QAEA,IAAIC,iBAAiB;QAErB,KAAK,MAAMC,cAAcnB,gBAAiB;YACxC,MAAMoB,SACJN,QAAQO,OAAO,EAAE,CAACF,WAAW;YAC/B,MAAMb,UAAUc,QAAQE,SAAShB;YACjC,IAAI,CAACc,UAAU,OAAOd,YAAY,UAAU;gBAC1C;YACF;YAEA,MAAMiB,OAAOjB,QAAQkB,KAAK,CAAC;YAC3B,0EAA0E;YAC1E,iEAAiE;YACjE,IAAI,CAACD,KAAKE,IAAI,CAAC,CAACC,MAAQzB,oBAAoBM,IAAI,CAACmB,OAAO;gBACtD;YACF;YAEA,IAAI,CAACrB,mBAAmBC,UAAU;gBAChCK,UAAUgB,IAAI,CACZ,GAAGd,KAAK,MAAM,EAAEM,WAAW,2MAA2M,CAAC;gBAEzO;YACF;YAEAC,OAAOE,OAAO,CAAChB,OAAO,GAAGiB,KACtBK,GAAG,CAAC,CAACF,MAASzB,oBAAoBM,IAAI,CAACmB,OAAOxB,MAAMwB,OAAOA,KAC3DG,IAAI,CAAC;YACRX,iBAAiB;QACnB;QAEA,IAAIA,gBAAgB;YAClBrB,2BAA2Ba,MAAMG,MAAMC;YACvCF,WAAW;QACb;IACF;IAEA,IAAIA,UAAU;QACZ,MAAMb,qBAAqBW;IAC7B;IAEA,OAAO;QAAEC;IAAU;AACrB"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments, readJson } from "@nx/devkit";
|
|
5
|
+
import { applyGritQL, matchGritQL } from "../../../utils/ast.js";
|
|
6
|
+
import { addDependenciesToPackageJson, removeDependenciesFromPackageJson } from "../../../utils/dependencies.js";
|
|
7
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
8
|
+
import { PACKAGES_DIR, SHARED_SHADCN_DIR } from "../../../utils/shared-constructs-constants.js";
|
|
9
|
+
import { TS_VERSIONS } from "../../../utils/versions.js";
|
|
10
|
+
/**
|
|
11
|
+
* Move the shared shadcn package onto the `cn` package.
|
|
12
|
+
*
|
|
13
|
+
* The shadcn registry now serves components importing `cn` from the `cn`
|
|
14
|
+
* package and declares it as a registry dependency, so a component added by
|
|
15
|
+
* `shadcn add` no longer resolves the package's own `#lib/utils` helper. This
|
|
16
|
+
* carries an existing workspace onto that shape: the components import `cn`,
|
|
17
|
+
* `src/lib/utils.ts` becomes the single-line re-export shadcn's own install
|
|
18
|
+
* guide prescribes, which keeps every consumer importing `cn` through
|
|
19
|
+
* `<scope>common-shadcn/lib/utils` working, and clsx / tailwind-merge are
|
|
20
|
+
* dropped now that nothing imports them.
|
|
21
|
+
*
|
|
22
|
+
* How to write a migration:
|
|
23
|
+
* - https://nx.dev/docs/kb/migration-generators
|
|
24
|
+
* - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject
|
|
25
|
+
*
|
|
26
|
+
* Guardrails:
|
|
27
|
+
* - Only touches a `packages/common/shadcn` this plugin's generators produced,
|
|
28
|
+
* guarded by `components.json`'s aliases still matching the generated shape.
|
|
29
|
+
* - An import is only rewritten when `cn` is its sole binding, so a file also
|
|
30
|
+
* pulling a user's own helper out of `#lib/utils` keeps resolving through the
|
|
31
|
+
* re-export.
|
|
32
|
+
* - `src/lib/utils.ts` is only rewritten while it still holds the generated
|
|
33
|
+
* `twMerge(clsx(...))` helper; a customised one is reported instead.
|
|
34
|
+
* - clsx / tailwind-merge are only dropped once nothing under `src` imports
|
|
35
|
+
* them.
|
|
36
|
+
* - Idempotent: every write is guarded by the old shape still being present.
|
|
37
|
+
*/ const libraryRoot = joinPathFragments(PACKAGES_DIR, SHARED_SHADCN_DIR);
|
|
38
|
+
const componentsJsonPath = joinPathFragments(libraryRoot, 'components.json');
|
|
39
|
+
const packageJsonPath = joinPathFragments(libraryRoot, 'package.json');
|
|
40
|
+
const srcRoot = joinPathFragments(libraryRoot, 'src');
|
|
41
|
+
const utilsPath = joinPathFragments(srcRoot, 'lib', 'utils.ts');
|
|
42
|
+
/** The aliases today's generators write, which this migration leaves in place. */ const generatedAliases = {
|
|
43
|
+
components: '#components',
|
|
44
|
+
utils: '#lib/utils',
|
|
45
|
+
hooks: '#hooks',
|
|
46
|
+
lib: '#lib',
|
|
47
|
+
ui: '#components/ui'
|
|
48
|
+
};
|
|
49
|
+
const CN_IMPORT_REWRITE = `\`import { cn } from '#lib/utils'\` => \`import { cn } from 'cn'\``;
|
|
50
|
+
/** The generated helper, whichever way the user's formatter has laid it out. */ const GENERATED_CN_HELPER = `\`twMerge(clsx($_))\``;
|
|
51
|
+
const importsPackage = (name)=>`\`import $_ from '${name}'\``;
|
|
52
|
+
const REEXPORT_UTILS = `export { cn } from 'cn';\n`;
|
|
53
|
+
const DROPPED_PACKAGES = [
|
|
54
|
+
'clsx',
|
|
55
|
+
'tailwind-merge'
|
|
56
|
+
];
|
|
57
|
+
/** Every `.ts`/`.tsx` file in the package's source tree. */ const sourceFiles = (tree, dir)=>{
|
|
58
|
+
if (!tree.exists(dir)) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
return tree.children(dir).flatMap((entry)=>{
|
|
62
|
+
const path = joinPathFragments(dir, entry);
|
|
63
|
+
if (!tree.isFile(path)) {
|
|
64
|
+
return sourceFiles(tree, path);
|
|
65
|
+
}
|
|
66
|
+
return path.endsWith('.ts') || path.endsWith('.tsx') ? [
|
|
67
|
+
path
|
|
68
|
+
] : [];
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
export default async function migration(tree) {
|
|
72
|
+
const nextSteps = [];
|
|
73
|
+
if (!tree.exists(componentsJsonPath) || !tree.exists(packageJsonPath)) {
|
|
74
|
+
return {
|
|
75
|
+
nextSteps
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const aliases = readJson(tree, componentsJsonPath).aliases ?? {};
|
|
79
|
+
if (Object.entries(generatedAliases).some(([k, v])=>aliases[k] !== v)) {
|
|
80
|
+
return {
|
|
81
|
+
nextSteps
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const files = sourceFiles(tree, srcRoot);
|
|
85
|
+
for (const file of files){
|
|
86
|
+
await applyGritQL(tree, file, CN_IMPORT_REWRITE);
|
|
87
|
+
}
|
|
88
|
+
if (tree.exists(utilsPath)) {
|
|
89
|
+
if (await matchGritQL(tree, utilsPath, GENERATED_CN_HELPER)) {
|
|
90
|
+
tree.write(utilsPath, REEXPORT_UTILS);
|
|
91
|
+
} else if (tree.read(utilsPath, 'utf-8') !== REEXPORT_UTILS) {
|
|
92
|
+
nextSteps.push(`${utilsPath}: no longer holds the generated cn helper - left untouched. Re-export cn from the 'cn' package by hand so consumers importing it from here keep working.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
addDependenciesToPackageJson(tree, {
|
|
96
|
+
cn: TS_VERSIONS.cn
|
|
97
|
+
}, {}, packageJsonPath);
|
|
98
|
+
const stillImported = new Set();
|
|
99
|
+
for (const file of sourceFiles(tree, srcRoot)){
|
|
100
|
+
for (const name of DROPPED_PACKAGES){
|
|
101
|
+
if (await matchGritQL(tree, file, importsPackage(name))) {
|
|
102
|
+
stillImported.add(name);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const dropped = DROPPED_PACKAGES.filter((name)=>!stillImported.has(name));
|
|
107
|
+
removeDependenciesFromPackageJson(tree, dropped, dropped, packageJsonPath);
|
|
108
|
+
await formatFilesInSubtree(tree);
|
|
109
|
+
return {
|
|
110
|
+
nextSteps
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/shadcn-cn-package/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n readJson,\n type Tree,\n} from '@nx/devkit';\nimport { applyGritQL, matchGritQL } from '../../../utils/ast.js';\nimport {\n addDependenciesToPackageJson,\n removeDependenciesFromPackageJson,\n} from '../../../utils/dependencies.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_SHADCN_DIR,\n} from '../../../utils/shared-constructs-constants.js';\nimport { TS_VERSIONS } from '../../../utils/versions.js';\n\n/**\n * Move the shared shadcn package onto the `cn` package.\n *\n * The shadcn registry now serves components importing `cn` from the `cn`\n * package and declares it as a registry dependency, so a component added by\n * `shadcn add` no longer resolves the package's own `#lib/utils` helper. This\n * carries an existing workspace onto that shape: the components import `cn`,\n * `src/lib/utils.ts` becomes the single-line re-export shadcn's own install\n * guide prescribes, which keeps every consumer importing `cn` through\n * `<scope>common-shadcn/lib/utils` working, and clsx / tailwind-merge are\n * dropped now that nothing imports them.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n *\n * Guardrails:\n * - Only touches a `packages/common/shadcn` this plugin's generators produced,\n * guarded by `components.json`'s aliases still matching the generated shape.\n * - An import is only rewritten when `cn` is its sole binding, so a file also\n * pulling a user's own helper out of `#lib/utils` keeps resolving through the\n * re-export.\n * - `src/lib/utils.ts` is only rewritten while it still holds the generated\n * `twMerge(clsx(...))` helper; a customised one is reported instead.\n * - clsx / tailwind-merge are only dropped once nothing under `src` imports\n * them.\n * - Idempotent: every write is guarded by the old shape still being present.\n */\n\nconst libraryRoot = joinPathFragments(PACKAGES_DIR, SHARED_SHADCN_DIR);\nconst componentsJsonPath = joinPathFragments(libraryRoot, 'components.json');\nconst packageJsonPath = joinPathFragments(libraryRoot, 'package.json');\nconst srcRoot = joinPathFragments(libraryRoot, 'src');\nconst utilsPath = joinPathFragments(srcRoot, 'lib', 'utils.ts');\n\n/** The aliases today's generators write, which this migration leaves in place. */\nconst generatedAliases: Record<string, string> = {\n components: '#components',\n utils: '#lib/utils',\n hooks: '#hooks',\n lib: '#lib',\n ui: '#components/ui',\n};\n\nconst CN_IMPORT_REWRITE = `\\`import { cn } from '#lib/utils'\\` => \\`import { cn } from 'cn'\\``;\n\n/** The generated helper, whichever way the user's formatter has laid it out. */\nconst GENERATED_CN_HELPER = `\\`twMerge(clsx($_))\\``;\n\nconst importsPackage = (name: string): string => `\\`import $_ from '${name}'\\``;\n\nconst REEXPORT_UTILS = `export { cn } from 'cn';\\n`;\n\nconst DROPPED_PACKAGES = ['clsx', 'tailwind-merge'] as const;\n\n/** Every `.ts`/`.tsx` file in the package's source tree. */\nconst sourceFiles = (tree: Tree, dir: string): string[] => {\n if (!tree.exists(dir)) {\n return [];\n }\n return tree.children(dir).flatMap((entry) => {\n const path = joinPathFragments(dir, entry);\n if (!tree.isFile(path)) {\n return sourceFiles(tree, path);\n }\n return path.endsWith('.ts') || path.endsWith('.tsx') ? [path] : [];\n });\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(componentsJsonPath) || !tree.exists(packageJsonPath)) {\n return { nextSteps };\n }\n\n const aliases =\n readJson<{ aliases?: Record<string, string> }>(tree, componentsJsonPath)\n .aliases ?? {};\n if (Object.entries(generatedAliases).some(([k, v]) => aliases[k] !== v)) {\n return { nextSteps };\n }\n\n const files = sourceFiles(tree, srcRoot);\n\n for (const file of files) {\n await applyGritQL(tree, file, CN_IMPORT_REWRITE);\n }\n\n if (tree.exists(utilsPath)) {\n if (await matchGritQL(tree, utilsPath, GENERATED_CN_HELPER)) {\n tree.write(utilsPath, REEXPORT_UTILS);\n } else if (tree.read(utilsPath, 'utf-8') !== REEXPORT_UTILS) {\n nextSteps.push(\n `${utilsPath}: no longer holds the generated cn helper - left untouched. Re-export cn from the 'cn' package by hand so consumers importing it from here keep working.`,\n );\n }\n }\n\n addDependenciesToPackageJson(\n tree,\n { cn: TS_VERSIONS.cn },\n {},\n packageJsonPath,\n );\n\n const stillImported = new Set<string>();\n for (const file of sourceFiles(tree, srcRoot)) {\n for (const name of DROPPED_PACKAGES) {\n if (await matchGritQL(tree, file, importsPackage(name))) {\n stillImported.add(name);\n }\n }\n }\n\n const dropped = DROPPED_PACKAGES.filter((name) => !stillImported.has(name));\n removeDependenciesFromPackageJson(tree, dropped, dropped, packageJsonPath);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","readJson","applyGritQL","matchGritQL","addDependenciesToPackageJson","removeDependenciesFromPackageJson","formatFilesInSubtree","PACKAGES_DIR","SHARED_SHADCN_DIR","TS_VERSIONS","libraryRoot","componentsJsonPath","packageJsonPath","srcRoot","utilsPath","generatedAliases","components","utils","hooks","lib","ui","CN_IMPORT_REWRITE","GENERATED_CN_HELPER","importsPackage","name","REEXPORT_UTILS","DROPPED_PACKAGES","sourceFiles","tree","dir","exists","children","flatMap","entry","path","isFile","endsWith","migration","nextSteps","aliases","Object","entries","some","k","v","files","file","write","read","push","cn","stillImported","Set","add","dropped","filter","has"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.90/0001-dev-target-depends-on-pull-image/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { TS_DYNAMODB_GENERATOR_INFO } from '../../../ts/dynamodb/generator.js';\nimport { TS_RDB_GENERATOR_INFO } from '../../../ts/rdb/generator.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { addDependencyToTargetIfNotPresent } from '../../../utils/nx.js';\n\n/**\n * Make the dev target of ts#dynamodb and ts#rdb projects depend on pull-image\n *\n * Without it, `nx dev` starts the container (and, for DynamoDB, creates the\n * local table) while the image is still being fetched, so a first run on a\n * machine without the image races the pull.\n */\n\nconst GENERATOR_IDS = [TS_DYNAMODB_GENERATOR_INFO.id, TS_RDB_GENERATOR_INFO.id];\n\nconst PULL_IMAGE_TARGET = 'pull-image';\n\nconst startsGeneratedContainer = (project: ProjectConfiguration): boolean => {\n const { command, commands } = project.targets?.dev?.options ?? {};\n return [...(commands ?? []), ...(command ? [command] : [])].some(\n (c: string) => typeof c === 'string' && c.includes('start-container.ts'),\n );\n};\n\nconst divergedNextStep = (projectName: string): string =>\n `${projectName}: its dev target has been customised, so it was left as it is. Add \"${PULL_IMAGE_TARGET}\" to the target's dependsOn so the container image is fetched before the container starts.`;\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n let migrated = false;\n\n for (const [name, project] of getProjects(tree)) {\n if (!GENERATOR_IDS.includes((project.metadata as any)?.generator)) {\n continue;\n }\n\n const dev = project.targets?.dev;\n if (!dev || !project.targets?.[PULL_IMAGE_TARGET]) {\n continue;\n }\n\n // Nx requires an array here. Anything else is hand-written and is reported\n // rather than rewritten, so a malformed value is never spread or clobbered.\n if (dev.dependsOn !== undefined && !Array.isArray(dev.dependsOn)) {\n nextSteps.push(divergedNextStep(name));\n continue;\n }\n\n const alreadyDependsOnPullImage = (dev.dependsOn ?? []).some(\n (dependency) =>\n dependency === PULL_IMAGE_TARGET ||\n (typeof dependency === 'object' &&\n dependency !== null &&\n dependency.target === PULL_IMAGE_TARGET &&\n dependency.projects === undefined),\n );\n if (alreadyDependsOnPullImage) {\n continue;\n }\n\n if (!startsGeneratedContainer(project)) {\n nextSteps.push(divergedNextStep(name));\n continue;\n }\n\n addDependencyToTargetIfNotPresent(project, 'dev', PULL_IMAGE_TARGET);\n updateProjectConfiguration(tree, name, project);\n migrated = true;\n }\n\n if (migrated) {\n await formatFilesInSubtree(tree);\n }\n\n return { nextSteps };\n}\n"],"names":["getProjects","updateProjectConfiguration","TS_DYNAMODB_GENERATOR_INFO","TS_RDB_GENERATOR_INFO","formatFilesInSubtree","addDependencyToTargetIfNotPresent","GENERATOR_IDS","id","PULL_IMAGE_TARGET","startsGeneratedContainer","project","command","commands","targets","dev","options","some","c","includes","divergedNextStep","projectName","migration","tree","nextSteps","migrated","name","metadata","generator","dependsOn","undefined","Array","isArray","push","alreadyDependsOnPullImage","dependency","target","projects"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EAIXC,0BAA0B,QACrB,aAAa;AACpB,SAASC,0BAA0B,QAAQ,oCAAoC;AAC/E,SAASC,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SAASC,iCAAiC,QAAQ,uBAAuB;AAEzE;;;;;;CAMC,GAED,MAAMC,gBAAgB;IAACJ,2BAA2BK,EAAE;IAAEJ,sBAAsBI,EAAE;CAAC;AAE/E,MAAMC,oBAAoB;AAE1B,MAAMC,2BAA2B,CAACC;IAChC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGF,QAAQG,OAAO,EAAEC,KAAKC,WAAW,CAAC;IAChE,OAAO;WAAKH,YAAY,EAAE;WAAOD,UAAU;YAACA;SAAQ,GAAG,EAAE;KAAE,CAACK,IAAI,CAC9D,CAACC,IAAc,OAAOA,MAAM,YAAYA,EAAEC,QAAQ,CAAC;AAEvD;AAEA,MAAMC,mBAAmB,CAACC,cACxB,GAAGA,YAAY,oEAAoE,EAAEZ,kBAAkB,0FAA0F,CAAC;AAEpM,eAAe,eAAea,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAC9B,IAAIC,WAAW;IAEf,KAAK,MAAM,CAACC,MAAMf,QAAQ,IAAIV,YAAYsB,MAAO;QAC/C,IAAI,CAAChB,cAAcY,QAAQ,CAAER,QAAQgB,QAAQ,EAAUC,YAAY;YACjE;QACF;QAEA,MAAMb,MAAMJ,QAAQG,OAAO,EAAEC;QAC7B,IAAI,CAACA,OAAO,CAACJ,QAAQG,OAAO,EAAE,CAACL,kBAAkB,EAAE;YACjD;QACF;QAEA,2EAA2E;QAC3E,4EAA4E;QAC5E,IAAIM,IAAIc,SAAS,KAAKC,aAAa,CAACC,MAAMC,OAAO,CAACjB,IAAIc,SAAS,GAAG;YAChEL,UAAUS,IAAI,CAACb,iBAAiBM;YAChC;QACF;QAEA,MAAMQ,4BAA4B,AAACnB,CAAAA,IAAIc,SAAS,IAAI,EAAE,AAAD,EAAGZ,IAAI,CAC1D,CAACkB,aACCA,eAAe1B,qBACd,OAAO0B,eAAe,YACrBA,eAAe,QACfA,WAAWC,MAAM,KAAK3B,qBACtB0B,WAAWE,QAAQ,KAAKP;QAE9B,IAAII,2BAA2B;YAC7B;QACF;QAEA,IAAI,CAACxB,yBAAyBC,UAAU;YACtCa,UAAUS,IAAI,CAACb,iBAAiBM;YAChC;QACF;QAEApB,kCAAkCK,SAAS,OAAOF;QAClDP,2BAA2BqB,MAAMG,MAAMf;QACvCc,WAAW;IACb;IAEA,IAAIA,UAAU;QACZ,MAAMpB,qBAAqBkB;IAC7B;IAEA,OAAO;QAAEC;IAAU;AACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/v1.0.0-rc.90/0002-open-api-codegen-executor/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n getProjects,\n type MigrationReturnObject,\n type TargetConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport type { OpenApiCodegenTarget } from '../../../open-api/codegen/executor-schema';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { normalizeTargetKeyOrder } from '../../../utils/nx.js';\nimport { OPEN_API_CODEGEN_EXECUTOR } from '../../../utils/open-api-codegen-target.js';\n\n/**\n * Codegen targets ran `nx g @aws/nx-plugin:open-api#<generator>` through\n * `nx:run-commands`, paying a second full Nx bootstrap — project graph, plugin\n * resolution and schema validation — for every codegen step. They now use the\n * `open-api-codegen` executor, which runs the same generator in the Nx process\n * that is already running.\n *\n * Only the command shape the generators produced is rewritten. A target that has\n * been customised — an extra flag, a chained command, options beyond `commands` —\n * is the user's, so it is left as it is and reported.\n *\n * How to write a migration:\n * - https://nx.dev/docs/kb/migration-generators\n * - What `nextSteps` means: https://nx.dev/docs/reference/devkit/MigrationReturnObject\n */\n\n/** The generators the executor can run, by the collection name they had. */\nconst GENERATORS: Record<string, OpenApiCodegenTarget> = {\n 'open-api#ts-client': 'ts-client',\n 'open-api#ts-hooks': 'ts-hooks',\n 'open-api#ts-metadata': 'ts-metadata',\n 'open-api#json-metadata': 'json-metadata',\n};\n\n/**\n * Matches a whole generated codegen command, binding the generator name and its\n * two paths. Anchored, so a command carrying anything else does not match and is\n * reported instead of rewritten.\n */\nconst CODEGEN_COMMAND =\n /^nx g @aws\\/nx-plugin:(?<generator>[\\w#-]+) --openApiSpecPath=\"(?<specPath>[^\"]+)\" --outputPath=\"(?<outputPath>[^\"]+)\" --no-interactive$/;\n\ninterface CodegenOptions {\n readonly generator: OpenApiCodegenTarget;\n readonly openApiSpecPath: string;\n readonly outputPath: string;\n}\n\n/**\n * The command a target runs, when it is a single-command `nx:run-commands` — the\n * shape the generators produced. A target carrying several commands, or options\n * beyond `commands`, has diverged.\n */\nconst singleCommand = (target: TargetConfiguration): string | undefined => {\n if (target.executor !== 'nx:run-commands') return undefined;\n const options = target.options as Record<string, unknown> | undefined;\n if (!options || Object.keys(options).length !== 1) return undefined;\n const commands = options.commands;\n if (!Array.isArray(commands) || commands.length !== 1) return undefined;\n return typeof commands[0] === 'string' ? commands[0] : undefined;\n};\n\n/** Parses a generated codegen command, or undefined if it is not one. */\nconst parseCodegenCommand = (command: string): CodegenOptions | undefined => {\n const groups = CODEGEN_COMMAND.exec(command)?.groups;\n if (!groups) return undefined;\n const generator = GENERATORS[groups.generator];\n if (!generator) return undefined;\n return {\n generator,\n openApiSpecPath: groups.specPath,\n outputPath: groups.outputPath,\n };\n};\n\n/**\n * Whether a target invokes an OpenAPI generator without being the shape the\n * generators produced, so it must be reported rather than rewritten.\n *\n * Continuous targets are excluded. The vended `watch-generate:<api>-client`\n * wraps `nx watch -- nx run <project>:<codegen target>`, which references the\n * codegen target rather than the generator, so it never matches here anyway. But\n * a watch target rewritten to invoke the generator directly would, and telling\n * its owner to switch to the executor would be wrong advice: `nx watch` runs\n * until interrupted, which a single executor invocation cannot express.\n *\n * `continuous` is the property that makes that true, so it is what is checked —\n * rather than the `watch-` name prefix, which is only a convention.\n */\nconst hasCustomisedCodegenCommand = (target: TargetConfiguration): boolean =>\n target.executor === 'nx:run-commands' &&\n !target.continuous &&\n JSON.stringify(target.options ?? {}).includes('@aws/nx-plugin:open-api#');\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const [projectName, project] of getProjects(tree)) {\n let changed = false;\n\n for (const [targetName, target] of Object.entries(project.targets ?? {})) {\n const command = singleCommand(target);\n const options = command ? parseCodegenCommand(command) : undefined;\n\n if (!options) {\n if (hasCustomisedCodegenCommand(target)) {\n nextSteps.push(\n `${projectName}:${targetName} has diverged from the generated shape — left untouched. Switch it to the '${OPEN_API_CODEGEN_EXECUTOR}' executor to avoid a nested Nx invocation.`,\n );\n }\n continue;\n }\n\n project.targets[targetName] = normalizeTargetKeyOrder({\n ...target,\n executor: OPEN_API_CODEGEN_EXECUTOR,\n options,\n });\n changed = true;\n }\n\n if (changed) {\n updateProjectConfiguration(tree, projectName, project);\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["getProjects","updateProjectConfiguration","formatFilesInSubtree","normalizeTargetKeyOrder","OPEN_API_CODEGEN_EXECUTOR","GENERATORS","CODEGEN_COMMAND","singleCommand","target","executor","undefined","options","Object","keys","length","commands","Array","isArray","parseCodegenCommand","command","groups","exec","generator","openApiSpecPath","specPath","outputPath","hasCustomisedCodegenCommand","continuous","JSON","stringify","includes","migration","tree","nextSteps","projectName","project","changed","targetName","entries","targets","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,WAAW,EAIXC,0BAA0B,QACrB,aAAa;AAEpB,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SAASC,uBAAuB,QAAQ,uBAAuB;AAC/D,SAASC,yBAAyB,QAAQ,4CAA4C;AAEtF;;;;;;;;;;;;;;CAcC,GAED,0EAA0E,GAC1E,MAAMC,aAAmD;IACvD,sBAAsB;IACtB,qBAAqB;IACrB,wBAAwB;IACxB,0BAA0B;AAC5B;AAEA;;;;CAIC,GACD,MAAMC,kBACJ;AAQF;;;;CAIC,GACD,MAAMC,gBAAgB,CAACC;IACrB,IAAIA,OAAOC,QAAQ,KAAK,mBAAmB,OAAOC;IAClD,MAAMC,UAAUH,OAAOG,OAAO;IAC9B,IAAI,CAACA,WAAWC,OAAOC,IAAI,CAACF,SAASG,MAAM,KAAK,GAAG,OAAOJ;IAC1D,MAAMK,WAAWJ,QAAQI,QAAQ;IACjC,IAAI,CAACC,MAAMC,OAAO,CAACF,aAAaA,SAASD,MAAM,KAAK,GAAG,OAAOJ;IAC9D,OAAO,OAAOK,QAAQ,CAAC,EAAE,KAAK,WAAWA,QAAQ,CAAC,EAAE,GAAGL;AACzD;AAEA,uEAAuE,GACvE,MAAMQ,sBAAsB,CAACC;IAC3B,MAAMC,SAASd,gBAAgBe,IAAI,CAACF,UAAUC;IAC9C,IAAI,CAACA,QAAQ,OAAOV;IACpB,MAAMY,YAAYjB,UAAU,CAACe,OAAOE,SAAS,CAAC;IAC9C,IAAI,CAACA,WAAW,OAAOZ;IACvB,OAAO;QACLY;QACAC,iBAAiBH,OAAOI,QAAQ;QAChCC,YAAYL,OAAOK,UAAU;IAC/B;AACF;AAEA;;;;;;;;;;;;;CAaC,GACD,MAAMC,8BAA8B,CAAClB,SACnCA,OAAOC,QAAQ,KAAK,qBACpB,CAACD,OAAOmB,UAAU,IAClBC,KAAKC,SAAS,CAACrB,OAAOG,OAAO,IAAI,CAAC,GAAGmB,QAAQ,CAAC;AAEhD,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,KAAK,MAAM,CAACC,aAAaC,QAAQ,IAAInC,YAAYgC,MAAO;QACtD,IAAII,UAAU;QAEd,KAAK,MAAM,CAACC,YAAY7B,OAAO,IAAII,OAAO0B,OAAO,CAACH,QAAQI,OAAO,IAAI,CAAC,GAAI;YACxE,MAAMpB,UAAUZ,cAAcC;YAC9B,MAAMG,UAAUQ,UAAUD,oBAAoBC,WAAWT;YAEzD,IAAI,CAACC,SAAS;gBACZ,IAAIe,4BAA4BlB,SAAS;oBACvCyB,UAAUO,IAAI,CACZ,GAAGN,YAAY,CAAC,EAAEG,WAAW,2EAA2E,EAAEjC,0BAA0B,2CAA2C,CAAC;gBAEpL;gBACA;YACF;YAEA+B,QAAQI,OAAO,CAACF,WAAW,GAAGlC,wBAAwB;gBACpD,GAAGK,MAAM;gBACTC,UAAUL;gBACVO;YACF;YACAyB,UAAU;QACZ;QAEA,IAAIA,SAAS;YACXnC,2BAA2B+B,MAAME,aAAaC;QAChD;IACF;IAEA,MAAMjC,qBAAqB8B;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
|