@ykdz/template 0.0.36 → 0.0.37
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/dist/application.d.ts +129 -13
- package/dist/application.js +286 -174
- package/dist/command-result.d.ts +9 -0
- package/dist/command-result.js +231 -0
- package/dist/main.d.ts +4 -1
- package/dist/main.js +319 -51
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +122 -22
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +2093 -416
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +18 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +29 -5
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +16 -15
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.d.ts +8 -6
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.js +3 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +6 -4
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +8 -6
- package/node_modules/@ykdz/template-builtin-presets/dist/src/template-sources.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/template-sources.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +34 -8
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +7 -7
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.d.ts +28 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +168 -148
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.d.ts +2 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +3 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.d.ts +2 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +22 -23
- package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/bin/semver.js +0 -0
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/README.md +1 -1
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/dist/index.cjs +427 -504
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/dist/index.d.cts +427 -32
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/dist/index.d.mts +427 -32
- package/node_modules/@ykdz/template-builtin-presets/node_modules/valibot/dist/index.min.cjs +2 -0
- package/node_modules/@ykdz/template-builtin-presets/node_modules/valibot/dist/index.min.mjs +2 -0
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/dist/index.mjs +418 -504
- package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/package.json +7 -2
- package/node_modules/@ykdz/template-builtin-presets/package.json +23 -10
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +5 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +4 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-diagnostics.yml +4 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check.yml +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/AGENTS.md.template +11 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/devcontainer.json +1 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.dynamic.txt +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/pnpm-workspace.yaml +5 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/check-toolchain-versions.ts +556 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.json +4 -6
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.packing-hook.json +2 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/turbo.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/rust-bin/turbo.json +19 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/devcontainer/node-pnpm.Dockerfile +4 -6
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/oxc/tsconfig.config.json +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.app.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/vue/tsconfig.node.json +2 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +26 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/root-tsconfig.json +2 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.json +2 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/tsconfig.build.json +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-lib/tsconfig.json +2 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/scripts/reset.ts +3 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/src/db.ts +3 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/src/readiness.ts +6 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/src/storage.ts +93 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/tsconfig.build.json +8 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/tsconfig.json +3 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/turbo.json +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/drizzle.config.ts +5 -5
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/tsconfig.build.json +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/tsconfig.json +2 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/.env.example +2 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/Dockerfile +25 -17
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/Dockerfile.dockerignore +4 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/playwright.config.ts +5 -25
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/scripts/check-standalone-deployment.ts +17 -15
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/test/playwright-teardown.ts +6 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.app.json +1 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.json +0 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.node.json +2 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/tsconfig.test.json +0 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/turbo.json +0 -8
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/vite.config.ts +3 -39
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/api/tsconfig.json +7 -2
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/root/playwright.config.ts +34 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/{web → root}/test/e2e/app.spec.ts +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/root/test/e2e/fixtures.ts +15 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/root/tsconfig.json +3 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/src/api.ts +1 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/turbo.json +0 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/vite.config.ts +2 -0
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/ci-diagnostic-artifact.js +10 -5
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +1 -1
- package/node_modules/@ykdz/template-core/dist/module-graph.js +7 -5
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +34 -10
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +1 -1
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +10 -9
- package/node_modules/@ykdz/template-core/dist/preset-definition.d.ts +11 -0
- package/node_modules/@ykdz/template-core/dist/project-github.d.ts +6 -4
- package/node_modules/@ykdz/template-core/dist/project-github.js +4 -4
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.js +12 -6
- package/node_modules/@ykdz/template-core/dist/project-projection.d.ts +27 -0
- package/node_modules/@ykdz/template-core/dist/project-projection.js +394 -9
- package/node_modules/@ykdz/template-core/dist/release-toolchain-snapshot.d.ts +10 -0
- package/node_modules/@ykdz/template-core/dist/release-toolchain-snapshot.js +9 -0
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +15 -9
- package/node_modules/@ykdz/template-core/node_modules/valibot/LICENSE.md +9 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/README.md +94 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.cjs +7897 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.d.cts +16579 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.d.mts +16579 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.min.cjs +2 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.min.mjs +2 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/dist/index.mjs +7577 -0
- package/node_modules/@ykdz/template-core/node_modules/valibot/package.json +84 -0
- package/node_modules/@ykdz/template-core/package.json +0 -2
- package/node_modules/hosted-git-info/LICENSE +13 -0
- package/node_modules/hosted-git-info/README.md +138 -0
- package/node_modules/hosted-git-info/lib/from-url.js +122 -0
- package/node_modules/hosted-git-info/lib/hosts.js +229 -0
- package/node_modules/hosted-git-info/lib/index.js +227 -0
- package/node_modules/hosted-git-info/lib/parse-url.js +79 -0
- package/node_modules/hosted-git-info/package.json +57 -0
- package/node_modules/jsonc-parser/CHANGELOG.md +76 -0
- package/node_modules/jsonc-parser/LICENSE.md +21 -0
- package/node_modules/jsonc-parser/README.md +364 -0
- package/node_modules/jsonc-parser/SECURITY.md +41 -0
- package/node_modules/jsonc-parser/lib/esm/impl/edit.js +185 -0
- package/node_modules/jsonc-parser/lib/esm/impl/format.js +261 -0
- package/node_modules/jsonc-parser/lib/esm/impl/parser.js +659 -0
- package/node_modules/jsonc-parser/lib/esm/impl/scanner.js +443 -0
- package/node_modules/jsonc-parser/lib/esm/impl/string-intern.js +29 -0
- package/node_modules/jsonc-parser/lib/esm/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/esm/main.js +178 -0
- package/node_modules/jsonc-parser/lib/umd/impl/edit.js +201 -0
- package/node_modules/jsonc-parser/lib/umd/impl/format.js +275 -0
- package/node_modules/jsonc-parser/lib/umd/impl/parser.js +682 -0
- package/node_modules/jsonc-parser/lib/umd/impl/scanner.js +456 -0
- package/node_modules/jsonc-parser/lib/umd/impl/string-intern.js +42 -0
- package/node_modules/jsonc-parser/lib/umd/main.d.ts +351 -0
- package/node_modules/jsonc-parser/lib/umd/main.js +194 -0
- package/node_modules/jsonc-parser/package.json +37 -0
- package/node_modules/lru-cache/LICENSE.md +55 -0
- package/node_modules/lru-cache/README.md +469 -0
- package/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.js +1733 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/lru-cache/dist/commonjs/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/index.js +1733 -0
- package/node_modules/lru-cache/dist/commonjs/index.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/index.min.js +2 -0
- package/node_modules/lru-cache/dist/commonjs/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.js +1733 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/package.json +3 -0
- package/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel-react-native.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel-react-native.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/diagnostics-channel.js +7 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/index.js +1733 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/index.js.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/perf.js +10 -0
- package/node_modules/lru-cache/dist/commonjs/react-native/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/index.js +1729 -0
- package/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
- package/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/lru-cache/dist/esm/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/index.js +1729 -0
- package/node_modules/lru-cache/dist/esm/index.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/index.min.js +2 -0
- package/node_modules/lru-cache/dist/esm/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/node/index.js +1729 -0
- package/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
- package/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/package.json +3 -0
- package/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel-react-native.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel-react-native.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel.d.ts +5 -0
- package/node_modules/lru-cache/dist/esm/react-native/diagnostics-channel.js +4 -0
- package/node_modules/lru-cache/dist/esm/react-native/index.d.ts +1400 -0
- package/node_modules/lru-cache/dist/esm/react-native/index.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/index.js +1729 -0
- package/node_modules/lru-cache/dist/esm/react-native/index.js.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/perf.d.ts +12 -0
- package/node_modules/lru-cache/dist/esm/react-native/perf.d.ts.map +1 -0
- package/node_modules/lru-cache/dist/esm/react-native/perf.js +7 -0
- package/node_modules/lru-cache/dist/esm/react-native/perf.js.map +1 -0
- package/node_modules/lru-cache/package.json +180 -0
- package/node_modules/npm-package-arg/LICENSE +15 -0
- package/node_modules/npm-package-arg/README.md +104 -0
- package/node_modules/npm-package-arg/lib/npa.js +479 -0
- package/node_modules/npm-package-arg/node_modules/semver/LICENSE +15 -0
- package/node_modules/npm-package-arg/node_modules/semver/README.md +680 -0
- package/node_modules/npm-package-arg/node_modules/semver/bin/semver.js +195 -0
- package/node_modules/npm-package-arg/node_modules/semver/classes/comparator.js +143 -0
- package/node_modules/npm-package-arg/node_modules/semver/classes/index.js +7 -0
- package/node_modules/npm-package-arg/node_modules/semver/classes/range.js +577 -0
- package/node_modules/npm-package-arg/node_modules/semver/classes/semver.js +350 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/clean.js +8 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/cmp.js +54 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/coerce.js +62 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/compare-build.js +9 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/compare-loose.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/compare.js +7 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/diff.js +60 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/eq.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/gt.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/gte.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/inc.js +21 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/lt.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/lte.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/major.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/minor.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/neq.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/parse.js +18 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/patch.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/prerelease.js +8 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/rcompare.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/rsort.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/satisfies.js +12 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/sort.js +5 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/truncate.js +48 -0
- package/node_modules/npm-package-arg/node_modules/semver/functions/valid.js +8 -0
- package/node_modules/npm-package-arg/node_modules/semver/index.js +93 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/constants.js +37 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/debug.js +11 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/identifiers.js +29 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/lrucache.js +42 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/parse-options.js +17 -0
- package/node_modules/npm-package-arg/node_modules/semver/internal/re.js +223 -0
- package/node_modules/npm-package-arg/node_modules/semver/package.json +78 -0
- package/node_modules/npm-package-arg/node_modules/semver/preload.js +4 -0
- package/node_modules/npm-package-arg/node_modules/semver/range.bnf +17 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/gtr.js +6 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/intersects.js +9 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/ltr.js +6 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/max-satisfying.js +27 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/min-satisfying.js +26 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/min-version.js +63 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/outside.js +82 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/simplify.js +49 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/subset.js +249 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/to-comparators.js +10 -0
- package/node_modules/npm-package-arg/node_modules/semver/ranges/valid.js +13 -0
- package/node_modules/npm-package-arg/package.json +60 -0
- package/node_modules/picomatch/LICENSE +21 -0
- package/node_modules/picomatch/README.md +743 -0
- package/node_modules/picomatch/index.js +17 -0
- package/node_modules/picomatch/lib/constants.js +184 -0
- package/node_modules/picomatch/lib/parse.js +1425 -0
- package/node_modules/picomatch/lib/picomatch.js +361 -0
- package/node_modules/picomatch/lib/scan.js +403 -0
- package/node_modules/picomatch/lib/utils.js +72 -0
- package/node_modules/picomatch/package.json +83 -0
- package/node_modules/picomatch/posix.js +3 -0
- package/node_modules/proc-log/LICENSE +15 -0
- package/node_modules/proc-log/README.md +226 -0
- package/node_modules/proc-log/lib/index.js +158 -0
- package/node_modules/proc-log/package.json +46 -0
- package/node_modules/smol-toml/LICENSE +24 -0
- package/node_modules/smol-toml/README.md +605 -0
- package/node_modules/smol-toml/dist/date.d.ts +41 -0
- package/node_modules/smol-toml/dist/date.js +156 -0
- package/node_modules/smol-toml/dist/error.d.ts +37 -0
- package/node_modules/smol-toml/dist/error.js +67 -0
- package/node_modules/smol-toml/dist/extract.js +289 -0
- package/node_modules/smol-toml/dist/index.cjs +770 -0
- package/node_modules/smol-toml/dist/index.d.ts +44 -0
- package/node_modules/smol-toml/dist/index.js +34 -0
- package/node_modules/smol-toml/dist/parse.d.ts +73 -0
- package/node_modules/smol-toml/dist/parse.js +164 -0
- package/node_modules/smol-toml/dist/primitive.js +151 -0
- package/node_modules/smol-toml/dist/stringify.d.ts +32 -0
- package/node_modules/smol-toml/dist/stringify.js +219 -0
- package/node_modules/smol-toml/dist/struct.js +156 -0
- package/node_modules/smol-toml/dist/util.d.ts +43 -0
- package/node_modules/smol-toml/dist/util.js +57 -0
- package/node_modules/smol-toml/package.json +68 -0
- package/node_modules/typescript/bin/tsc +0 -0
- package/node_modules/typescript/bin/tsserver +0 -0
- package/node_modules/unbash/LICENSE +15 -0
- package/node_modules/unbash/README.md +289 -0
- package/node_modules/unbash/dist/ansi-c.d.ts +5 -0
- package/node_modules/unbash/dist/ansi-c.js +130 -0
- package/node_modules/unbash/dist/arithmetic.d.ts +11 -0
- package/node_modules/unbash/dist/arithmetic.js +530 -0
- package/node_modules/unbash/dist/assignment.d.ts +15 -0
- package/node_modules/unbash/dist/assignment.js +118 -0
- package/node_modules/unbash/dist/chars.d.ts +41 -0
- package/node_modules/unbash/dist/chars.js +41 -0
- package/node_modules/unbash/dist/command.d.ts +14 -0
- package/node_modules/unbash/dist/command.js +41 -0
- package/node_modules/unbash/dist/heredoc.d.ts +18 -0
- package/node_modules/unbash/dist/heredoc.js +25 -0
- package/node_modules/unbash/dist/internal-types.d.ts +87 -0
- package/node_modules/unbash/dist/internal-types.js +1 -0
- package/node_modules/unbash/dist/lexer.d.ts +202 -0
- package/node_modules/unbash/dist/lexer.js +3930 -0
- package/node_modules/unbash/dist/parser.d.ts +4 -0
- package/node_modules/unbash/dist/parser.js +1295 -0
- package/node_modules/unbash/dist/parts.d.ts +17 -0
- package/node_modules/unbash/dist/parts.js +82 -0
- package/node_modules/unbash/dist/printer.d.ts +2 -0
- package/node_modules/unbash/dist/printer.js +536 -0
- package/node_modules/unbash/dist/types.d.ts +494 -0
- package/node_modules/unbash/dist/types.js +1 -0
- package/node_modules/unbash/dist/word.d.ts +22 -0
- package/node_modules/unbash/dist/word.js +102 -0
- package/node_modules/unbash/package.json +80 -0
- package/node_modules/validate-npm-package-name/LICENSE +6 -0
- package/node_modules/validate-npm-package-name/README.md +120 -0
- package/node_modules/validate-npm-package-name/lib/builtin-modules.json +1 -0
- package/node_modules/validate-npm-package-name/lib/index.js +114 -0
- package/node_modules/validate-npm-package-name/package.json +59 -0
- package/node_modules/yaml/LICENSE +13 -0
- package/node_modules/yaml/README.md +172 -0
- package/node_modules/yaml/bin.mjs +11 -0
- package/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
- package/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
- package/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
- package/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
- package/node_modules/yaml/browser/dist/compose/composer.js +219 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
- package/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +226 -0
- package/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
- package/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
- package/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
- package/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
- package/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
- package/node_modules/yaml/browser/dist/doc/Document.js +335 -0
- package/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
- package/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
- package/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
- package/node_modules/yaml/browser/dist/doc/directives.js +176 -0
- package/node_modules/yaml/browser/dist/errors.js +57 -0
- package/node_modules/yaml/browser/dist/index.js +17 -0
- package/node_modules/yaml/browser/dist/log.js +11 -0
- package/node_modules/yaml/browser/dist/nodes/Alias.js +118 -0
- package/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
- package/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
- package/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
- package/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
- package/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
- package/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
- package/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
- package/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
- package/node_modules/yaml/browser/dist/parse/cst.js +98 -0
- package/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
- package/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
- package/node_modules/yaml/browser/dist/parse/parser.js +975 -0
- package/node_modules/yaml/browser/dist/public-api.js +102 -0
- package/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
- package/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
- package/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
- package/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
- package/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
- package/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
- package/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
- package/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
- package/node_modules/yaml/browser/dist/schema/tags.js +96 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
- package/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
- package/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
- package/node_modules/yaml/browser/dist/util.js +11 -0
- package/node_modules/yaml/browser/dist/visit.js +233 -0
- package/node_modules/yaml/browser/index.js +5 -0
- package/node_modules/yaml/browser/package.json +3 -0
- package/node_modules/yaml/dist/cli.d.ts +8 -0
- package/node_modules/yaml/dist/cli.mjs +201 -0
- package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
- package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
- package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
- package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
- package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
- package/node_modules/yaml/dist/compose/compose-node.js +112 -0
- package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
- package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
- package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
- package/node_modules/yaml/dist/compose/composer.js +224 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
- package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +228 -0
- package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
- package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
- package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
- package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
- package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
- package/node_modules/yaml/dist/doc/Document.js +337 -0
- package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
- package/node_modules/yaml/dist/doc/anchors.js +76 -0
- package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
- package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
- package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
- package/node_modules/yaml/dist/doc/createNode.js +90 -0
- package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
- package/node_modules/yaml/dist/doc/directives.js +178 -0
- package/node_modules/yaml/dist/errors.d.ts +21 -0
- package/node_modules/yaml/dist/errors.js +62 -0
- package/node_modules/yaml/dist/index.d.ts +25 -0
- package/node_modules/yaml/dist/index.js +50 -0
- package/node_modules/yaml/dist/log.d.ts +3 -0
- package/node_modules/yaml/dist/log.js +19 -0
- package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/Alias.js +120 -0
- package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
- package/node_modules/yaml/dist/nodes/Collection.js +151 -0
- package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/Node.js +40 -0
- package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
- package/node_modules/yaml/dist/nodes/Pair.js +39 -0
- package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
- package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
- package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
- package/node_modules/yaml/dist/nodes/identity.js +53 -0
- package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/toJS.js +39 -0
- package/node_modules/yaml/dist/options.d.ts +350 -0
- package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
- package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
- package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
- package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
- package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
- package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
- package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
- package/node_modules/yaml/dist/parse/cst.js +112 -0
- package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
- package/node_modules/yaml/dist/parse/lexer.js +723 -0
- package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
- package/node_modules/yaml/dist/parse/line-counter.js +41 -0
- package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
- package/node_modules/yaml/dist/parse/parser.js +980 -0
- package/node_modules/yaml/dist/public-api.d.ts +44 -0
- package/node_modules/yaml/dist/public-api.js +107 -0
- package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
- package/node_modules/yaml/dist/schema/Schema.js +39 -0
- package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/map.js +19 -0
- package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
- package/node_modules/yaml/dist/schema/common/null.js +17 -0
- package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/seq.js +19 -0
- package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/string.js +16 -0
- package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/bool.js +21 -0
- package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/float.js +47 -0
- package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/int.js +42 -0
- package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/core/schema.js +25 -0
- package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
- package/node_modules/yaml/dist/schema/json/schema.js +64 -0
- package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
- package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
- package/node_modules/yaml/dist/schema/tags.js +99 -0
- package/node_modules/yaml/dist/schema/types.d.ts +92 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
- package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
- package/node_modules/yaml/dist/stringify/stringify.js +132 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
- package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
- package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
- package/node_modules/yaml/dist/test-events.d.ts +4 -0
- package/node_modules/yaml/dist/test-events.js +134 -0
- package/node_modules/yaml/dist/util.d.ts +16 -0
- package/node_modules/yaml/dist/util.js +28 -0
- package/node_modules/yaml/dist/visit.d.ts +102 -0
- package/node_modules/yaml/dist/visit.js +236 -0
- package/node_modules/yaml/package.json +97 -0
- package/node_modules/yaml/util.js +2 -0
- package/package.json +21 -19
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/check-boundaries.ts +0 -12
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/scripts/run-root-owned-task.ts +0 -69
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/test/global-setup.ts +0 -21
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/vitest.config.ts +0 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/playwright.config.ts +0 -90
- package/node_modules/@ykdz/template-core/dist/toolchain-baseline-update.d.ts +0 -45
- package/node_modules/@ykdz/template-core/dist/toolchain-baseline-update.js +0 -27
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.d.ts +0 -37
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +0 -195
- package/node_modules/valibot/dist/index.min.cjs +0 -2
- package/node_modules/valibot/dist/index.min.mjs +0 -2
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/LICENSE +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/README.md +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/classes/comparator.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/classes/index.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/classes/range.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/classes/semver.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/clean.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/cmp.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/coerce.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/compare-build.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/compare-loose.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/compare.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/diff.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/eq.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/gt.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/gte.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/inc.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/lt.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/lte.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/major.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/minor.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/neq.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/parse.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/patch.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/prerelease.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/rcompare.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/rsort.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/satisfies.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/sort.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/truncate.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/functions/valid.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/index.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/constants.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/debug.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/identifiers.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/lrucache.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/parse-options.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/internal/re.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/package.json +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/preload.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/range.bnf +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/gtr.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/intersects.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/ltr.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/max-satisfying.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/min-satisfying.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/min-version.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/outside.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/simplify.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/subset.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/to-comparators.js +0 -0
- /package/node_modules/{semver → @ykdz/template-builtin-presets/node_modules/semver}/ranges/valid.js +0 -0
- /package/node_modules/{valibot → @ykdz/template-builtin-presets/node_modules/valibot}/LICENSE.md +0 -0
- /package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/src/{types.d.ts → types.ts} +0 -0
|
@@ -2,17 +2,21 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
5
|
+
import { isDeepStrictEqual } from "node:util";
|
|
6
|
+
import { composeCiDiagnosticArtifacts } from "@ykdz/template-core/ci-diagnostic-artifact";
|
|
7
|
+
import { collectGeneratedManifestCatalogReferences, selectTemplateDependencyCatalogEntries, } from "@ykdz/template-core/dependency-catalog";
|
|
8
|
+
import { planDevelopmentContainerToolLayersSync, } from "@ykdz/template-core/development-container-tool-layer";
|
|
9
|
+
import { editorCustomizationForCapabilities, loadEditorCustomizationDeclarations, } from "@ykdz/template-core/editor-customization";
|
|
10
|
+
import { normalizeEnvironmentNeeds, parseEnvironmentNeedsMetadata, playwrightBrowserAssetsEnvironmentNeed, renderDeploymentCheckCommand, renderFixCommand, renderRootCheckCommand, renderTurboRunCommand, shellCheckEnvironmentNeed, } from "@ykdz/template-core/module-graph";
|
|
11
|
+
import { assertPackageContribution, assertPackageContributionCommandNames, } from "@ykdz/template-core/package-contribution";
|
|
12
|
+
import { assertProjectBlueprint, assertProjectBlueprintDraft, isValidNewNpmPackageName, validateNewPackagePath, validateProjectBlueprint as validateCoreProjectBlueprint, } from "@ykdz/template-core/project-blueprint";
|
|
13
|
+
import { projectCheckWorkflowTemplateSource, projectCheckWorkflowTemplateReplacements, projectDependabotTemplateReplacements, } from "@ykdz/template-core/project-github";
|
|
14
|
+
import { canConsumeNodePackageNameImport, canLinkNodePackageRoles, canProvideSourceConditionPackageNameImport, planExplicitProjectLinks, } from "@ykdz/template-core/project-linking-v2";
|
|
15
|
+
import { validateProjectProjectionPlan } from "@ykdz/template-core/project-projection";
|
|
16
|
+
import { releaseToolchainSnapshot } from "@ykdz/template-core/release-toolchain-snapshot";
|
|
17
|
+
import { resolveTemplateSource, } from "@ykdz/template-core/renderer";
|
|
18
|
+
import { parse as parseToml } from "smol-toml";
|
|
19
|
+
import ts from "typescript";
|
|
16
20
|
import { isValidDefaultPackageScope, parseGenerationRecord, } from "./generation-record.js";
|
|
17
21
|
import { rustBinDefinition } from "./rust-bin/definition.js";
|
|
18
22
|
import { githubCliDevelopmentContainerToolLayer } from "./shared/development-container.js";
|
|
@@ -25,6 +29,20 @@ import { vikeAppDefinition } from "./vike-app/definition.js";
|
|
|
25
29
|
import { vueAppDefinition } from "./vue-app/definition.js";
|
|
26
30
|
import { vueHonoAppDefinition } from "./vue-hono-app/definition.js";
|
|
27
31
|
const localTemplateMetadataStateKey = Symbol("localTemplateMetadataState");
|
|
32
|
+
export class PackageAdditionBusinessConflict extends Error {
|
|
33
|
+
kind;
|
|
34
|
+
existing;
|
|
35
|
+
requested;
|
|
36
|
+
missingLink;
|
|
37
|
+
constructor(kind, existing, requested, missingLink) {
|
|
38
|
+
super("Package Addition business conflict");
|
|
39
|
+
this.kind = kind;
|
|
40
|
+
this.existing = existing;
|
|
41
|
+
this.requested = requested;
|
|
42
|
+
if (missingLink !== undefined)
|
|
43
|
+
this.missingLink = missingLink;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
28
46
|
const environmentNeedsPath = ".template/environment-needs.json";
|
|
29
47
|
const packageManifestKeyOrder = [
|
|
30
48
|
"name",
|
|
@@ -157,12 +175,123 @@ function readGenerationRecord(options) {
|
|
|
157
175
|
const generationPath = path.join(options.repositoryRoot, ".template/generation.json");
|
|
158
176
|
return parseGenerationRecord(readJsonFile(generationPath, "Generation Record facts"));
|
|
159
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Package Addition 的目标根 package.json 允许两种 Node 声明:旧仓库的纯大版本
|
|
180
|
+
* ("24")与精确版本("24.16.0"),两者都能派生大版本;范围表达式与两段版本拒绝。
|
|
181
|
+
*/
|
|
182
|
+
const nodeMajorOrExactVersionPattern = /^(\d+)(?:\.(\d+)\.(\d+))?$/u;
|
|
183
|
+
/** 与 npm packageManager 字段一致的精确 pnpm pin(可带预发布或构建元数据)。 */
|
|
184
|
+
const exactPnpmPinPattern = /^pnpm@\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u;
|
|
185
|
+
/**
|
|
186
|
+
* 目标根现行版本声明缺失或形状错误时的显式带形状内部失败:点名文件与字段、实际值与修正动作,
|
|
187
|
+
* 由 Package Addition 准备边界传递给命令层;其他 metadata 错误保持通用。
|
|
188
|
+
*/
|
|
189
|
+
class PackageAdditionTargetDeclarationFailure extends Error {
|
|
190
|
+
field;
|
|
191
|
+
suggestion;
|
|
192
|
+
constructor(file, field, requirement, actualDeclaration, suggestion) {
|
|
193
|
+
super(`加包需要目标仓库根 ${file} 的 ${field} ${requirement},实际收到 ${actualDeclaration}。${suggestion}`);
|
|
194
|
+
this.field = field;
|
|
195
|
+
this.suggestion = suggestion;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Package Addition 的版本上下文来自目标仓库根 package.json 的当前声明,因此升级过
|
|
200
|
+
* Node 或 pnpm 的仓库会继续按自身版本加包;Generation Record 的 toolchain 只保留为
|
|
201
|
+
* 初始化历史。
|
|
202
|
+
*/
|
|
203
|
+
function readPackageAdditionVersionFacts(repositoryRoot) {
|
|
204
|
+
const manifest = readRepositoryJsonRecord({
|
|
205
|
+
repositoryRoot,
|
|
206
|
+
relativePath: "package.json",
|
|
207
|
+
label: "root Manifest",
|
|
208
|
+
});
|
|
209
|
+
const nodeDeclaration = isRecord(manifest.engines)
|
|
210
|
+
? manifest.engines.node
|
|
211
|
+
: undefined;
|
|
212
|
+
const nodeDeclarationMatch = typeof nodeDeclaration === "string"
|
|
213
|
+
? nodeMajorOrExactVersionPattern.exec(nodeDeclaration)
|
|
214
|
+
: undefined;
|
|
215
|
+
const nodeLtsMajor = nodeDeclarationMatch?.[1];
|
|
216
|
+
if (nodeLtsMajor === undefined || typeof nodeDeclaration !== "string") {
|
|
217
|
+
throw new PackageAdditionTargetDeclarationFailure("package.json", "engines.node", '声明单个 Node 大版本("24")或精确 Node 版本("24.16.0")', JSON.stringify(nodeDeclaration ?? null), "请先修改根 package.json 的 engines.node 声明再加包。");
|
|
218
|
+
}
|
|
219
|
+
const packageManagerDeclaration = manifest.packageManager;
|
|
220
|
+
if (typeof packageManagerDeclaration !== "string" ||
|
|
221
|
+
!exactPnpmPinPattern.test(packageManagerDeclaration)) {
|
|
222
|
+
throw new PackageAdditionTargetDeclarationFailure("package.json", "packageManager", '声明精确 pnpm 版本("pnpm@11.21.0")', JSON.stringify(packageManagerDeclaration ?? null), "请先修改根 package.json 的 packageManager 声明再加包。");
|
|
223
|
+
}
|
|
224
|
+
// 根只声明大版本时没有诚实的精确 patch 可传,保持缺省而不伪造。
|
|
225
|
+
return {
|
|
226
|
+
toolchain: {
|
|
227
|
+
nodeLtsMajor,
|
|
228
|
+
packageManagerPin: packageManagerDeclaration,
|
|
229
|
+
...(nodeDeclarationMatch?.[2] === undefined
|
|
230
|
+
? {}
|
|
231
|
+
: { nodeVersion: nodeDeclaration }),
|
|
232
|
+
},
|
|
233
|
+
rootNodeDeclaration: nodeDeclaration,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/** 生成仓库根 Rust 声明的唯一文件名;所有权判定与投影保留都只经这个接缝引用它。 */
|
|
237
|
+
const rootRustDeclarationFileName = "rust-toolchain.toml";
|
|
238
|
+
/**
|
|
239
|
+
* 已选用 Rust 的目标仓库由根 rust-toolchain.toml 的 channel 拥有后续 Rust 版本选择,因此加包
|
|
240
|
+
* 按该现行声明重放根投影与开发容器初值。声明缺失、非法 TOML 或 channel 形状错误时在此失败,
|
|
241
|
+
* 不回退 CLI 发版快照、Generation Record 历史或 ambient 环境。
|
|
242
|
+
*/
|
|
243
|
+
function readPackageAdditionTargetRustChannel(repositoryRoot) {
|
|
244
|
+
const relativePath = rootRustDeclarationFileName;
|
|
245
|
+
const filePath = path.join(repositoryRoot, relativePath);
|
|
246
|
+
if (!existsSync(filePath)) {
|
|
247
|
+
throw new PackageAdditionTargetDeclarationFailure(relativePath, "[toolchain].channel", "存在", "文件不存在", `请先创建根 ${relativePath},在 [toolchain] 表内声明 channel 再加包。`);
|
|
248
|
+
}
|
|
249
|
+
let declaration;
|
|
250
|
+
try {
|
|
251
|
+
declaration = parseToml(readFileSync(filePath, "utf8"));
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
throw new PackageAdditionTargetDeclarationFailure(relativePath, "[toolchain].channel", "是有效 TOML 声明", `无法解析:${error instanceof Error ? error.message : String(error)}`, `请先修正根 ${relativePath} 的 TOML 语法,使 [toolchain] 表内声明 channel 再加包。`);
|
|
255
|
+
}
|
|
256
|
+
const toolchain = isRecord(declaration) ? declaration.toolchain : undefined;
|
|
257
|
+
const channel = isRecord(toolchain) ? toolchain.channel : undefined;
|
|
258
|
+
if (typeof channel !== "string" || channel.trim().length === 0) {
|
|
259
|
+
throw new PackageAdditionTargetDeclarationFailure(relativePath, "[toolchain].channel", "为非空字符串", JSON.stringify(channel ?? null), `请先在根 ${relativePath} 的 [toolchain] 表内写入 channel 再加包。`);
|
|
260
|
+
}
|
|
261
|
+
return channel;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Root Rust 来源的最小接缝:从 rust-toolchain.toml 正文结构化读出 `[toolchain].channel`。
|
|
265
|
+
* 复用加包路径同一 smol-toml 真源,供模板仓投影值门核对 M5;不引入第二套版本或文件名表。
|
|
266
|
+
* 正文非法 TOML 或缺少非空 channel 时返回不可解释,由调用方按缺失/漂移分类,不静默跳过。
|
|
267
|
+
*/
|
|
268
|
+
export function readRustToolchainChannelFromToml(contents) {
|
|
269
|
+
let declaration;
|
|
270
|
+
try {
|
|
271
|
+
declaration = parseToml(contents);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
return {
|
|
275
|
+
reason: `不是有效 TOML 声明:${error instanceof Error ? error.message : String(error)}`,
|
|
276
|
+
status: "unreadable",
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const toolchain = isRecord(declaration) ? declaration.toolchain : undefined;
|
|
280
|
+
const channel = isRecord(toolchain) ? toolchain.channel : undefined;
|
|
281
|
+
if (typeof channel !== "string" || channel.trim().length === 0) {
|
|
282
|
+
return {
|
|
283
|
+
reason: `[toolchain].channel 必须是非空字符串,实际为 ${JSON.stringify(channel ?? null)}`,
|
|
284
|
+
status: "unreadable",
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return { channel, status: "explained" };
|
|
288
|
+
}
|
|
160
289
|
function readJsonFile(filePath, label) {
|
|
161
290
|
try {
|
|
162
291
|
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
163
292
|
}
|
|
164
293
|
catch (error) {
|
|
165
|
-
throw new Error(`Package Addition requires valid ${label}: ${error instanceof Error ? error.message : String(error)}
|
|
294
|
+
throw new Error(`Package Addition requires valid ${label}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
166
295
|
}
|
|
167
296
|
}
|
|
168
297
|
function barePackageDefinition(definition) {
|
|
@@ -309,7 +438,8 @@ export function loadLocalTemplateMetadata(repositoryRoot) {
|
|
|
309
438
|
blueprint,
|
|
310
439
|
generationRecord,
|
|
311
440
|
});
|
|
312
|
-
const
|
|
441
|
+
const rootVersions = readPackageAdditionVersionFacts(resolvedRoot);
|
|
442
|
+
const nodeFactsContext = {
|
|
313
443
|
targetDir: resolvedRoot,
|
|
314
444
|
repositoryName: generationRecord.repositoryName,
|
|
315
445
|
defaultPackageScope: generationRecord.defaultPackageScope,
|
|
@@ -318,16 +448,37 @@ export function loadLocalTemplateMetadata(repositoryRoot) {
|
|
|
318
448
|
name: preflight.foundationPackage.definition.name,
|
|
319
449
|
},
|
|
320
450
|
},
|
|
321
|
-
toolchain:
|
|
451
|
+
toolchain: rootVersions.toolchain,
|
|
322
452
|
};
|
|
323
|
-
|
|
324
|
-
|
|
453
|
+
let context = nodeFactsContext;
|
|
454
|
+
let planningState = replayLocalTemplateMetadata({
|
|
455
|
+
context: nodeFactsContext,
|
|
325
456
|
preflight,
|
|
326
457
|
});
|
|
458
|
+
// 已有 Rust 能力事实的目标仓库由自己的根 rust-toolchain.toml 拥有后续版本选择:读出该现行
|
|
459
|
+
// channel 后重放,使根声明与开发容器初值来自同一个目标根事实;首次引入 Rust 的仓库还没有
|
|
460
|
+
// 该声明,保持缺省上下文交由建源路径处理。
|
|
461
|
+
if (normalizeRustToolchain([
|
|
462
|
+
planningState.foundationContribution,
|
|
463
|
+
...planningState.packageContributions,
|
|
464
|
+
]) !== undefined) {
|
|
465
|
+
context = {
|
|
466
|
+
...nodeFactsContext,
|
|
467
|
+
toolchain: {
|
|
468
|
+
...nodeFactsContext.toolchain,
|
|
469
|
+
rustVersion: readPackageAdditionTargetRustChannel(resolvedRoot),
|
|
470
|
+
},
|
|
471
|
+
};
|
|
472
|
+
planningState = replayLocalTemplateMetadata({ context, preflight });
|
|
473
|
+
}
|
|
327
474
|
return {
|
|
328
475
|
blueprint,
|
|
329
476
|
context,
|
|
330
|
-
[localTemplateMetadataStateKey]: {
|
|
477
|
+
[localTemplateMetadataStateKey]: {
|
|
478
|
+
generationRecord,
|
|
479
|
+
rootNodeDeclaration: rootVersions.rootNodeDeclaration,
|
|
480
|
+
...planningState,
|
|
481
|
+
},
|
|
331
482
|
};
|
|
332
483
|
}
|
|
333
484
|
function requireReplayAdapter(options) {
|
|
@@ -405,7 +556,7 @@ function readPersistedEnvironmentNeeds(targetDir) {
|
|
|
405
556
|
value = JSON.parse(readFileSync(filePath, "utf8"));
|
|
406
557
|
}
|
|
407
558
|
catch (error) {
|
|
408
|
-
throw new Error(`Package Addition requires valid Check Environment Need facts: ${error instanceof Error ? error.message : String(error)}
|
|
559
|
+
throw new Error(`Package Addition requires valid Check Environment Need facts: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
409
560
|
}
|
|
410
561
|
try {
|
|
411
562
|
return parseEnvironmentNeedsMetadata(value);
|
|
@@ -419,8 +570,38 @@ function readExistingPackageAdditionState(options) {
|
|
|
419
570
|
const state = options.localTemplateMetadata[localTemplateMetadataStateKey];
|
|
420
571
|
const { foundationContribution, generationRecord, packageContributions: contributions, } = state;
|
|
421
572
|
const persistedEnvironmentNeeds = readPersistedEnvironmentNeeds(context.targetDir);
|
|
573
|
+
const allContributions = [foundationContribution, ...contributions];
|
|
574
|
+
const deploymentCheck = normalizeDeploymentCheck(allContributions);
|
|
575
|
+
const vueHonoJointE2e = normalizeVueHonoJointE2e(allContributions);
|
|
576
|
+
const databasePreparation = normalizeDatabasePreparation(allContributions);
|
|
422
577
|
const manifestTruthByPackagePath = new Map();
|
|
423
578
|
const requiredManifestTruthPackagePaths = new Set(options.requiredManifestTruthPackagePaths ?? []);
|
|
579
|
+
const packageByName = new Map(allContributions.map((contribution) => [
|
|
580
|
+
contribution.definition.name,
|
|
581
|
+
contribution,
|
|
582
|
+
]));
|
|
583
|
+
const capabilityPackageNames = [
|
|
584
|
+
...(databasePreparation === undefined
|
|
585
|
+
? []
|
|
586
|
+
: [
|
|
587
|
+
databasePreparation.databasePackageName,
|
|
588
|
+
databasePreparation.migrationPackageName,
|
|
589
|
+
...Object.values(databasePreparation.consumers),
|
|
590
|
+
]),
|
|
591
|
+
...(deploymentCheck === undefined
|
|
592
|
+
? []
|
|
593
|
+
: [
|
|
594
|
+
deploymentCheck.applicationPackageName,
|
|
595
|
+
deploymentCheck.databasePackageName,
|
|
596
|
+
deploymentCheck.migrationPackageName,
|
|
597
|
+
]),
|
|
598
|
+
];
|
|
599
|
+
for (const packageName of capabilityPackageNames) {
|
|
600
|
+
const contribution = packageByName.get(packageName);
|
|
601
|
+
if (contribution !== undefined) {
|
|
602
|
+
requiredManifestTruthPackagePaths.add(contribution.definition.path);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
424
605
|
for (const packagePath of requiredManifestTruthPackagePaths) {
|
|
425
606
|
if (!blueprint.packages.some((definition) => definition.path === packagePath)) {
|
|
426
607
|
throw new Error(`Package Addition requires manifest truth for unknown Package Path ${packagePath}`);
|
|
@@ -437,16 +618,26 @@ function readExistingPackageAdditionState(options) {
|
|
|
437
618
|
manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
438
619
|
}
|
|
439
620
|
catch (error) {
|
|
440
|
-
throw new Error(`Package Addition requires manifest truth for ${expectedDefinition.path}: ${error instanceof Error ? error.message : String(error)}
|
|
621
|
+
throw new Error(`Package Addition requires manifest truth for ${expectedDefinition.path}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
441
622
|
}
|
|
442
623
|
if (!isRecord(manifest) || manifest.name !== expectedDefinition.name) {
|
|
443
624
|
throw new Error(`Package Addition requires manifest truth for ${expectedDefinition.path}: expected name ${expectedDefinition.name}`);
|
|
444
625
|
}
|
|
445
626
|
manifestTruthByPackagePath.set(expectedDefinition.path, manifest);
|
|
446
627
|
}
|
|
628
|
+
assertCapabilityRepositoryTruth({
|
|
629
|
+
repositoryRoot: context.targetDir,
|
|
630
|
+
blueprint,
|
|
631
|
+
contributions: allContributions,
|
|
632
|
+
packageByName,
|
|
633
|
+
manifestTruthByPackagePath,
|
|
634
|
+
databasePreparation,
|
|
635
|
+
deploymentCheck,
|
|
636
|
+
vueHonoJointE2e,
|
|
637
|
+
});
|
|
447
638
|
const reconstructedEnvironmentNeeds = normalizeEnvironmentNeeds({
|
|
448
|
-
check:
|
|
449
|
-
deployment:
|
|
639
|
+
check: foundationCheckEnvironmentNeeds(allContributions, deploymentCheck, vueHonoJointE2e),
|
|
640
|
+
deployment: deploymentCheck?.environmentNeeds ?? [],
|
|
450
641
|
});
|
|
451
642
|
if (JSON.stringify(reconstructedEnvironmentNeeds) !==
|
|
452
643
|
JSON.stringify(persistedEnvironmentNeeds)) {
|
|
@@ -456,7 +647,6 @@ function readExistingPackageAdditionState(options) {
|
|
|
456
647
|
foundationContribution,
|
|
457
648
|
contributions,
|
|
458
649
|
manifestTruthByPackagePath,
|
|
459
|
-
deploymentEnvironmentNeeds: persistedEnvironmentNeeds.deployment,
|
|
460
650
|
generationRecord,
|
|
461
651
|
};
|
|
462
652
|
}
|
|
@@ -504,13 +694,14 @@ function contributedDevcontainerComposition(options) {
|
|
|
504
694
|
buildArguments: [
|
|
505
695
|
{
|
|
506
696
|
name: "NODE_VERSION",
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
{
|
|
510
|
-
name: "PACKAGE_MANAGER_PIN",
|
|
511
|
-
value: options.context.toolchain.packageManagerPin,
|
|
697
|
+
// 根 Node 声明原文是 M1 槽位唯一来源;major 与快照字段不得另作真源。
|
|
698
|
+
value: options.rootNodeDeclaration,
|
|
512
699
|
},
|
|
513
700
|
],
|
|
701
|
+
probes: [
|
|
702
|
+
{ identity: "procps", command: "ps", args: ["--version"] },
|
|
703
|
+
{ identity: "bubblewrap", command: "bwrap", args: ["--version"] },
|
|
704
|
+
],
|
|
514
705
|
mounts: [
|
|
515
706
|
{
|
|
516
707
|
identity: "pnpm-store",
|
|
@@ -531,8 +722,7 @@ function contributedDevcontainerComposition(options) {
|
|
|
531
722
|
to: ".devcontainer/devcontainer.json",
|
|
532
723
|
replacements: {
|
|
533
724
|
PROJECT_NAME: options.context.repositoryName,
|
|
534
|
-
|
|
535
|
-
PACKAGE_MANAGER_PIN: options.context.toolchain.packageManagerPin,
|
|
725
|
+
NODE_VERSION: options.rootNodeDeclaration,
|
|
536
726
|
},
|
|
537
727
|
},
|
|
538
728
|
{
|
|
@@ -576,191 +766,1094 @@ function contributedDevcontainerComposition(options) {
|
|
|
576
766
|
probes: layerPlan.probes,
|
|
577
767
|
};
|
|
578
768
|
}
|
|
579
|
-
function
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
if (
|
|
585
|
-
|
|
586
|
-
source: resolveTemplateSource(previous.source, previous.from),
|
|
587
|
-
from: previous.from,
|
|
588
|
-
to: previous.to,
|
|
589
|
-
replacements: previous.replacements ?? {},
|
|
590
|
-
});
|
|
591
|
-
const fingerprint = JSON.stringify({
|
|
592
|
-
source: resolveTemplateSource(file.source, file.from),
|
|
593
|
-
from: file.from,
|
|
594
|
-
to: file.to,
|
|
595
|
-
replacements: file.replacements ?? {},
|
|
596
|
-
});
|
|
597
|
-
if (fingerprint !== previousFingerprint) {
|
|
598
|
-
throw new Error(`Foundation Template File identity ${file.identity} has conflicting descriptors`);
|
|
599
|
-
}
|
|
600
|
-
continue;
|
|
769
|
+
function normalizeDatabasePreparation(contributions) {
|
|
770
|
+
const declarations = contributions.flatMap((contribution) => {
|
|
771
|
+
const capability = contribution.foundation.databasePreparation;
|
|
772
|
+
if (capability === undefined)
|
|
773
|
+
return [];
|
|
774
|
+
if (capability.kind !== "sqlite-database-preparation") {
|
|
775
|
+
throw new Error("Database Preparation has an unsupported capability kind");
|
|
601
776
|
}
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
777
|
+
const consumers = Object.fromEntries(capability.consumers.map((consumer) => [
|
|
778
|
+
consumer.kind,
|
|
779
|
+
consumer.packageName,
|
|
780
|
+
]));
|
|
781
|
+
if (capability.consumers.length !== 3 ||
|
|
782
|
+
new Set(capability.consumers.map((consumer) => consumer.kind)).size !==
|
|
783
|
+
3 ||
|
|
784
|
+
consumers["application-dev"] === undefined ||
|
|
785
|
+
consumers["database-test"] === undefined ||
|
|
786
|
+
consumers["application-e2e"] === undefined) {
|
|
787
|
+
throw new Error("Database Preparation must declare application-dev, database-test, and application-e2e consumers exactly once");
|
|
605
788
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
const rust = contribution.foundation.toolchains.rust;
|
|
622
|
-
return rust === undefined
|
|
623
|
-
? []
|
|
624
|
-
: [
|
|
625
|
-
JSON.stringify({
|
|
626
|
-
toolchain: rust.toolchain,
|
|
627
|
-
components: [...new Set(rust.components)].toSorted(),
|
|
789
|
+
const normalizedConsumers = {
|
|
790
|
+
"application-dev": consumers["application-dev"],
|
|
791
|
+
"database-test": consumers["database-test"],
|
|
792
|
+
"application-e2e": consumers["application-e2e"],
|
|
793
|
+
};
|
|
794
|
+
return [
|
|
795
|
+
{
|
|
796
|
+
databasePackageName: contribution.definition.name,
|
|
797
|
+
migrationPackageName: capability.migrationPackageName,
|
|
798
|
+
consumers: normalizedConsumers,
|
|
799
|
+
fingerprint: JSON.stringify({
|
|
800
|
+
databasePackageName: contribution.definition.name,
|
|
801
|
+
migrationPackageName: capability.migrationPackageName,
|
|
802
|
+
consumers: normalizedConsumers,
|
|
803
|
+
profiles: ["dev", "test", "e2e"],
|
|
628
804
|
}),
|
|
629
|
-
|
|
805
|
+
},
|
|
806
|
+
];
|
|
630
807
|
});
|
|
631
|
-
|
|
632
|
-
|
|
808
|
+
const first = declarations.at(0);
|
|
809
|
+
if (first === undefined)
|
|
810
|
+
return undefined;
|
|
811
|
+
if (declarations.some((item) => item.fingerprint !== first.fingerprint)) {
|
|
812
|
+
throw new Error("Database Preparation has conflicting capability declarations");
|
|
633
813
|
}
|
|
814
|
+
return first;
|
|
634
815
|
}
|
|
635
|
-
function
|
|
636
|
-
const
|
|
637
|
-
|
|
816
|
+
function databasePreparationCommands(preparation) {
|
|
817
|
+
const run = (profile, packageName, task) => `DATABASE_PROFILE=${profile} pnpm --filter ${packageName} run ${task}`;
|
|
818
|
+
return {
|
|
819
|
+
"database:prepare:dev": [
|
|
820
|
+
run("dev", preparation.migrationPackageName, "db:push"),
|
|
821
|
+
run("dev", preparation.databasePackageName, "db:seed:example"),
|
|
822
|
+
].join(" && "),
|
|
823
|
+
"database:prepare:test": [
|
|
824
|
+
run("test", preparation.databasePackageName, "db:reset"),
|
|
825
|
+
run("test", preparation.migrationPackageName, "db:push"),
|
|
826
|
+
run("test", preparation.databasePackageName, "db:seed:example"),
|
|
827
|
+
].join(" && "),
|
|
828
|
+
"database:prepare:e2e": [
|
|
829
|
+
run("e2e", preparation.databasePackageName, "db:reset"),
|
|
830
|
+
run("e2e", preparation.migrationPackageName, "db:push"),
|
|
831
|
+
run("e2e", preparation.databasePackageName, "db:seed:example"),
|
|
832
|
+
].join(" && "),
|
|
833
|
+
dev: `pnpm run database:prepare:dev && turbo watch dev --filter=${preparation.consumers["application-dev"]}`,
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
function databasePreparationTurboTasks(preparation) {
|
|
837
|
+
return {
|
|
838
|
+
"//#database:prepare:dev": { cache: false },
|
|
839
|
+
"//#database:prepare:test": { cache: false },
|
|
840
|
+
"//#database:prepare:e2e": { cache: false },
|
|
841
|
+
[`${preparation.databasePackageName}#test`]: {
|
|
842
|
+
dependsOn: ["//#database:prepare:test"],
|
|
843
|
+
},
|
|
844
|
+
[`${preparation.migrationPackageName}#typecheck`]: {
|
|
845
|
+
dependsOn: [`${preparation.databasePackageName}#build`],
|
|
846
|
+
},
|
|
847
|
+
[`${preparation.consumers["application-dev"]}#typecheck`]: {
|
|
848
|
+
dependsOn: [`${preparation.databasePackageName}#build`],
|
|
849
|
+
},
|
|
850
|
+
[`${preparation.consumers["application-dev"]}#dev`]: {
|
|
851
|
+
dependsOn: [`${preparation.databasePackageName}#build`],
|
|
852
|
+
cache: false,
|
|
853
|
+
persistent: true,
|
|
854
|
+
},
|
|
855
|
+
[`${preparation.consumers["application-e2e"]}#test:e2e`]: {
|
|
856
|
+
dependsOn: [
|
|
857
|
+
"//#database:prepare:e2e",
|
|
858
|
+
`${preparation.databasePackageName}#build`,
|
|
859
|
+
"build",
|
|
860
|
+
],
|
|
861
|
+
cache: false,
|
|
862
|
+
},
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
function deploymentTurboTasks(deploymentCheck) {
|
|
866
|
+
return {
|
|
867
|
+
"//#deployment": {
|
|
868
|
+
dependsOn: [
|
|
869
|
+
`${deploymentCheck.applicationPackageName}#build`,
|
|
870
|
+
`${deploymentCheck.databasePackageName}#build`,
|
|
871
|
+
`${deploymentCheck.migrationPackageName}#build`,
|
|
872
|
+
],
|
|
873
|
+
cache: false,
|
|
874
|
+
},
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
function vueHonoJointE2eTurboTasks(e2e) {
|
|
878
|
+
return {
|
|
879
|
+
"//#test:e2e": {
|
|
880
|
+
dependsOn: [`${e2e.apiPackageName}#build`, `${e2e.webPackageName}#build`],
|
|
881
|
+
cache: false,
|
|
882
|
+
},
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
function assertDatabasePreparationManifestTruth(options) {
|
|
886
|
+
const { preparation, packageByName, manifestTruthByPackagePath } = options;
|
|
887
|
+
if (preparation === undefined || manifestTruthByPackagePath === undefined) {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
const expectedTasks = [
|
|
891
|
+
[preparation.databasePackageName, "build"],
|
|
892
|
+
[preparation.databasePackageName, "db:reset"],
|
|
893
|
+
[preparation.databasePackageName, "db:seed:example"],
|
|
894
|
+
[preparation.databasePackageName, "test"],
|
|
895
|
+
[preparation.migrationPackageName, "db:push"],
|
|
896
|
+
[preparation.migrationPackageName, "typecheck"],
|
|
897
|
+
[preparation.consumers["application-dev"], "dev"],
|
|
898
|
+
[preparation.consumers["application-dev"], "typecheck"],
|
|
899
|
+
[preparation.consumers["application-e2e"], "build"],
|
|
900
|
+
[preparation.consumers["application-e2e"], "test:e2e"],
|
|
638
901
|
];
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
902
|
+
for (const [packageName, taskName] of expectedTasks) {
|
|
903
|
+
const contribution = requireContributionByName(packageByName, packageName, "Database Preparation");
|
|
904
|
+
const manifest = requireManifestTruth(manifestTruthByPackagePath, contribution, "Database Preparation");
|
|
905
|
+
const actualScripts = manifest.scripts;
|
|
906
|
+
const expectedScripts = contribution.manifest.scripts;
|
|
907
|
+
const actual = isRecord(actualScripts)
|
|
908
|
+
? actualScripts[taskName]
|
|
909
|
+
: undefined;
|
|
910
|
+
const expected = isRecord(expectedScripts)
|
|
911
|
+
? expectedScripts[taskName]
|
|
912
|
+
: undefined;
|
|
913
|
+
if (actual !== expected) {
|
|
914
|
+
throw new Error(`Database Preparation requires exact ${packageName} script ${taskName}`);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
function normalizeDeploymentCheck(contributions) {
|
|
919
|
+
const declarations = contributions.flatMap((contribution) => {
|
|
920
|
+
const check = contribution.foundation.deploymentCheck;
|
|
921
|
+
if (check === undefined)
|
|
922
|
+
return [];
|
|
923
|
+
if (check.kind !== "application-container-with-database-migrations") {
|
|
924
|
+
throw new Error("Deployment Check has an unsupported capability kind");
|
|
925
|
+
}
|
|
926
|
+
return [{ ...check, declaringPackagePath: contribution.definition.path }];
|
|
927
|
+
});
|
|
928
|
+
if (declarations.length > 1) {
|
|
929
|
+
throw new Error("Deployment Check has multiple capability declarations");
|
|
930
|
+
}
|
|
931
|
+
return declarations.at(0);
|
|
932
|
+
}
|
|
933
|
+
function normalizeVueHonoJointE2e(contributions) {
|
|
934
|
+
const declarations = contributions.flatMap((contribution) => {
|
|
935
|
+
const e2e = contribution.foundation.vueHonoJointE2e;
|
|
936
|
+
if (e2e === undefined)
|
|
937
|
+
return [];
|
|
938
|
+
if (e2e.kind !== "vue-hono-joint-e2e") {
|
|
939
|
+
throw new Error("Vue-Hono joint E2E has an unsupported capability kind");
|
|
940
|
+
}
|
|
941
|
+
return [
|
|
942
|
+
{
|
|
943
|
+
...e2e,
|
|
944
|
+
webPackageName: contribution.definition.name,
|
|
945
|
+
declaringPackagePath: contribution.definition.path,
|
|
946
|
+
},
|
|
651
947
|
];
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
if (extra.length > 0)
|
|
656
|
-
extraDirectories[ecosystem] = extra;
|
|
948
|
+
});
|
|
949
|
+
if (declarations.length > 1) {
|
|
950
|
+
throw new Error("Vue-Hono joint E2E has multiple capability declarations");
|
|
657
951
|
}
|
|
658
|
-
return
|
|
659
|
-
ecosystems,
|
|
660
|
-
...(Object.keys(directories).length === 0 ? {} : { directories }),
|
|
661
|
-
...(Object.keys(extraDirectories).length === 0 ? {} : { extraDirectories }),
|
|
662
|
-
interval: "weekly",
|
|
663
|
-
};
|
|
952
|
+
return declarations.at(0);
|
|
664
953
|
}
|
|
665
|
-
function
|
|
666
|
-
const
|
|
667
|
-
if (
|
|
668
|
-
throw new Error(
|
|
954
|
+
function requireContributionByName(packageByName, packageName, capability) {
|
|
955
|
+
const contribution = packageByName.get(packageName);
|
|
956
|
+
if (contribution === undefined) {
|
|
957
|
+
throw new Error(`${capability} references unknown Package ${packageName}`);
|
|
669
958
|
}
|
|
670
|
-
return
|
|
959
|
+
return contribution;
|
|
671
960
|
}
|
|
672
|
-
function
|
|
673
|
-
const
|
|
674
|
-
if (
|
|
675
|
-
throw new Error(
|
|
961
|
+
function requireManifestTruth(manifestTruthByPackagePath, contribution, capability) {
|
|
962
|
+
const manifest = manifestTruthByPackagePath.get(contribution.definition.path);
|
|
963
|
+
if (manifest === undefined) {
|
|
964
|
+
throw new Error(`${capability} requires manifest truth for ${contribution.definition.path}`);
|
|
676
965
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
966
|
+
return manifest;
|
|
967
|
+
}
|
|
968
|
+
function assertExpectedRecordMembers(options) {
|
|
969
|
+
if (!isRecord(options.expected)) {
|
|
970
|
+
throw new Error(`${options.label} replay did not provide object truth`);
|
|
971
|
+
}
|
|
972
|
+
if (!isRecord(options.actual)) {
|
|
973
|
+
throw new Error(`${options.label} must be an object`);
|
|
974
|
+
}
|
|
975
|
+
for (const [key, expectedValue] of Object.entries(options.expected)) {
|
|
976
|
+
if (!isDeepStrictEqual(options.actual[key], expectedValue)) {
|
|
977
|
+
throw new Error(`${options.label} must preserve replayed member ${key}`);
|
|
978
|
+
}
|
|
680
979
|
}
|
|
681
|
-
return candidate;
|
|
682
980
|
}
|
|
683
|
-
function
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
981
|
+
function assertArtifactConditionOrder(options) {
|
|
982
|
+
if (!isRecord(options.expected) || !isRecord(options.actual))
|
|
983
|
+
return;
|
|
984
|
+
const conditionNames = ["source", "types", "default"];
|
|
985
|
+
const expectedConditions = Object.keys(options.expected).filter((name) => conditionNames.includes(name));
|
|
986
|
+
if (!expectedConditions.includes("source") ||
|
|
987
|
+
!expectedConditions.some((name) => name === "types" || name === "default")) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
const actualConditions = Object.keys(options.actual).filter((name) => expectedConditions.includes(name));
|
|
991
|
+
if (!isDeepStrictEqual(actualConditions, expectedConditions)) {
|
|
992
|
+
throw new Error(`${options.label} must preserve replayed condition order`);
|
|
993
|
+
}
|
|
689
994
|
}
|
|
690
|
-
function
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
-
|
|
995
|
+
function assertDatabaseArtifactConditionTruth(options) {
|
|
996
|
+
if (!isRecord(options.actual) || !isRecord(options.expected))
|
|
997
|
+
return;
|
|
998
|
+
for (const [memberName, expectedMember] of Object.entries(options.expected)) {
|
|
999
|
+
assertArtifactConditionOrder({
|
|
1000
|
+
actual: options.actual[memberName],
|
|
1001
|
+
expected: expectedMember,
|
|
1002
|
+
label: `${options.label} ${memberName}`,
|
|
1003
|
+
});
|
|
696
1004
|
}
|
|
697
|
-
|
|
1005
|
+
}
|
|
1006
|
+
function assertDatabaseArtifactManifestTruth(options) {
|
|
1007
|
+
if (options.preparation === undefined)
|
|
1008
|
+
return;
|
|
1009
|
+
const database = requireContributionByName(options.packageByName, options.preparation.databasePackageName, "Database Preparation");
|
|
1010
|
+
const actual = requireManifestTruth(options.manifestTruthByPackagePath, database, "Database Preparation");
|
|
1011
|
+
const expected = database.manifest;
|
|
1012
|
+
if (actual.type !== expected.type || expected.type !== "module") {
|
|
1013
|
+
throw new Error(`Database Preparation requires ${database.definition.name} manifest type module`);
|
|
1014
|
+
}
|
|
1015
|
+
if (!Array.isArray(expected.files)) {
|
|
1016
|
+
throw new Error(`Database Preparation replay for ${database.definition.name} did not provide files truth`);
|
|
1017
|
+
}
|
|
1018
|
+
const actualFiles = actual.files;
|
|
1019
|
+
if (!Array.isArray(actualFiles) ||
|
|
1020
|
+
expected.files.some((expectedFile) => !actualFiles.some((actualFile) => isDeepStrictEqual(actualFile, expectedFile)))) {
|
|
1021
|
+
throw new Error(`Database Preparation requires ${database.definition.name} public build files`);
|
|
1022
|
+
}
|
|
1023
|
+
assertExpectedRecordMembers({
|
|
1024
|
+
actual: actual.exports,
|
|
1025
|
+
expected: expected.exports,
|
|
1026
|
+
label: `Database Preparation ${database.definition.name} exports`,
|
|
1027
|
+
});
|
|
1028
|
+
assertDatabaseArtifactConditionTruth({
|
|
1029
|
+
actual: actual.exports,
|
|
1030
|
+
expected: expected.exports,
|
|
1031
|
+
label: `Database Preparation ${database.definition.name} exports`,
|
|
1032
|
+
});
|
|
1033
|
+
assertExpectedRecordMembers({
|
|
1034
|
+
actual: actual.imports,
|
|
1035
|
+
expected: expected.imports,
|
|
1036
|
+
label: `Database Preparation ${database.definition.name} imports`,
|
|
1037
|
+
});
|
|
1038
|
+
assertDatabaseArtifactConditionTruth({
|
|
1039
|
+
actual: actual.imports,
|
|
1040
|
+
expected: expected.imports,
|
|
1041
|
+
label: `Database Preparation ${database.definition.name} imports`,
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
function assertDatabaseProjectLinkManifestTruth(options) {
|
|
1045
|
+
if (options.preparation === undefined)
|
|
1046
|
+
return;
|
|
1047
|
+
const database = requireContributionByName(options.packageByName, options.preparation.databasePackageName, "Database Preparation");
|
|
1048
|
+
const expectedLinks = planExplicitProjectLinks({
|
|
698
1049
|
blueprint: options.blueprint,
|
|
699
1050
|
contributions: options.contributions,
|
|
700
|
-
|
|
1051
|
+
});
|
|
1052
|
+
for (const intent of options.blueprint.packageLinkIntents ?? []) {
|
|
1053
|
+
if (intent.providerPackagePath !== database.definition.path)
|
|
1054
|
+
continue;
|
|
1055
|
+
const consumer = options.contributions.find((candidate) => candidate.definition.path === intent.consumerPackagePath);
|
|
1056
|
+
if (consumer === undefined) {
|
|
1057
|
+
throw new Error(`Database Preparation Project Link references unknown consumer ${intent.consumerPackagePath}`);
|
|
1058
|
+
}
|
|
1059
|
+
const actual = requireManifestTruth(options.manifestTruthByPackagePath, consumer, "Database Preparation Project Link");
|
|
1060
|
+
if (!isRecord(actual.dependencies) ||
|
|
1061
|
+
actual.dependencies[database.definition.name] !== "workspace:*") {
|
|
1062
|
+
throw new Error(`Database Preparation requires ${consumer.definition.name} to depend on ${database.definition.name} through workspace:*`);
|
|
1063
|
+
}
|
|
1064
|
+
const expectedMetadata = expectedLinks.manifestPatchesByPackagePath.get(consumer.definition.path)?.dependenciesMeta?.[database.definition.name];
|
|
1065
|
+
if (actual.dependenciesMeta !== undefined &&
|
|
1066
|
+
!isRecord(actual.dependenciesMeta)) {
|
|
1067
|
+
throw new Error(`Database Preparation requires valid dependency metadata in ${consumer.definition.name}`);
|
|
1068
|
+
}
|
|
1069
|
+
const actualMetadata = isRecord(actual.dependenciesMeta)
|
|
1070
|
+
? actual.dependenciesMeta[database.definition.name]
|
|
1071
|
+
: undefined;
|
|
1072
|
+
if (!isDeepStrictEqual(actualMetadata, expectedMetadata)) {
|
|
1073
|
+
throw new Error(`Database Preparation requires replayed Project Link metadata for ${consumer.definition.name} -> ${database.definition.name}`);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function assertDeploymentBuildManifestTruth(options) {
|
|
1078
|
+
if (options.deploymentCheck === undefined)
|
|
1079
|
+
return;
|
|
1080
|
+
for (const packageName of [
|
|
1081
|
+
options.deploymentCheck.applicationPackageName,
|
|
1082
|
+
options.deploymentCheck.databasePackageName,
|
|
1083
|
+
options.deploymentCheck.migrationPackageName,
|
|
1084
|
+
]) {
|
|
1085
|
+
const contribution = requireContributionByName(options.packageByName, packageName, "Deployment Check");
|
|
1086
|
+
const actual = requireManifestTruth(options.manifestTruthByPackagePath, contribution, "Deployment Check");
|
|
1087
|
+
const actualBuild = isRecord(actual.scripts)
|
|
1088
|
+
? actual.scripts.build
|
|
1089
|
+
: undefined;
|
|
1090
|
+
const expectedBuild = isRecord(contribution.manifest.scripts)
|
|
1091
|
+
? contribution.manifest.scripts.build
|
|
1092
|
+
: undefined;
|
|
1093
|
+
if (typeof expectedBuild !== "string" || actualBuild !== expectedBuild) {
|
|
1094
|
+
throw new Error(`Deployment Check requires exact ${packageName} manifest script build`);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
function assertVueHonoJointE2eManifestTruth(options) {
|
|
1099
|
+
if (options.e2e === undefined)
|
|
1100
|
+
return;
|
|
1101
|
+
if (options.e2e.apiPackageName === options.e2e.webPackageName) {
|
|
1102
|
+
throw new Error("Vue-Hono joint E2E requires distinct API and web Packages");
|
|
1103
|
+
}
|
|
1104
|
+
const expectedTasks = [
|
|
1105
|
+
[options.e2e.apiPackageName, "build"],
|
|
1106
|
+
[options.e2e.apiPackageName, "start"],
|
|
1107
|
+
[options.e2e.webPackageName, "build"],
|
|
1108
|
+
[options.e2e.webPackageName, "preview"],
|
|
1109
|
+
];
|
|
1110
|
+
for (const [packageName, taskName] of expectedTasks) {
|
|
1111
|
+
const contribution = requireContributionByName(options.packageByName, packageName, "Vue-Hono joint E2E");
|
|
1112
|
+
const actual = requireManifestTruth(options.manifestTruthByPackagePath, contribution, "Vue-Hono joint E2E");
|
|
1113
|
+
const expected = isRecord(contribution.manifest.scripts)
|
|
1114
|
+
? contribution.manifest.scripts[taskName]
|
|
1115
|
+
: undefined;
|
|
1116
|
+
const actualScript = isRecord(actual.scripts)
|
|
1117
|
+
? actual.scripts[taskName]
|
|
1118
|
+
: undefined;
|
|
1119
|
+
if (typeof expected !== "string" || actualScript !== expected) {
|
|
1120
|
+
throw new Error(`Vue-Hono joint E2E requires exact ${packageName} manifest script ${taskName}`);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
function readRepositoryJsonRecord(options) {
|
|
1125
|
+
const value = readJsonFile(path.join(options.repositoryRoot, options.relativePath), `${options.label} in ${options.relativePath}`);
|
|
1126
|
+
if (!isRecord(value)) {
|
|
1127
|
+
throw new Error(`Package Addition requires ${options.label} in ${options.relativePath} to be an object`);
|
|
1128
|
+
}
|
|
1129
|
+
return value;
|
|
1130
|
+
}
|
|
1131
|
+
function assertRootCapabilityManifestTruth(options) {
|
|
1132
|
+
if (options.databasePreparation === undefined &&
|
|
1133
|
+
options.deploymentCheck === undefined &&
|
|
1134
|
+
options.vueHonoJointE2e === undefined) {
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
const manifest = readRepositoryJsonRecord({
|
|
1138
|
+
repositoryRoot: options.repositoryRoot,
|
|
1139
|
+
relativePath: "package.json",
|
|
1140
|
+
label: "root Manifest Truth",
|
|
1141
|
+
});
|
|
1142
|
+
if (!isRecord(manifest.scripts)) {
|
|
1143
|
+
throw new Error("Package Addition requires root manifest scripts truth");
|
|
1144
|
+
}
|
|
1145
|
+
const expectedScripts = {
|
|
1146
|
+
...(options.databasePreparation === undefined
|
|
1147
|
+
? {}
|
|
1148
|
+
: databasePreparationCommands(options.databasePreparation)),
|
|
1149
|
+
...(options.deploymentCheck === undefined
|
|
701
1150
|
? {}
|
|
702
1151
|
: {
|
|
703
|
-
|
|
1152
|
+
deployment: "node --conditions=source scripts/check-standalone-deployment.ts",
|
|
1153
|
+
"check:deployment": renderDeploymentCheckCommand(),
|
|
704
1154
|
}),
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
|
|
1155
|
+
...(options.vueHonoJointE2e === undefined
|
|
1156
|
+
? {}
|
|
1157
|
+
: { "test:e2e": "playwright test" }),
|
|
1158
|
+
};
|
|
1159
|
+
for (const [scriptName, expectedCommand] of Object.entries(expectedScripts)) {
|
|
1160
|
+
if (manifest.scripts[scriptName] !== expectedCommand) {
|
|
1161
|
+
throw new Error(`Package Addition requires exact root manifest script ${scriptName}`);
|
|
1162
|
+
}
|
|
712
1163
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
1164
|
+
}
|
|
1165
|
+
function assertTurboTaskTruth(options) {
|
|
1166
|
+
if (!isRecord(options.config.tasks)) {
|
|
1167
|
+
throw new Error(`${options.label} requires Turbo tasks truth`);
|
|
1168
|
+
}
|
|
1169
|
+
for (const [taskName, expectedTask] of Object.entries(options.expectedTasks)) {
|
|
1170
|
+
const actualTask = options.config.tasks[taskName];
|
|
1171
|
+
if (!isRecord(actualTask)) {
|
|
1172
|
+
throw new Error(`${options.label} requires Turbo task ${taskName}`);
|
|
717
1173
|
}
|
|
718
|
-
const
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1174
|
+
for (const [field, expectedValue] of Object.entries(expectedTask)) {
|
|
1175
|
+
const actualValue = actualTask[field];
|
|
1176
|
+
if (Array.isArray(expectedValue)) {
|
|
1177
|
+
if (!Array.isArray(actualValue) ||
|
|
1178
|
+
expectedValue.some((expectedMember) => !actualValue.includes(expectedMember))) {
|
|
1179
|
+
throw new Error(`${options.label} requires Turbo task ${taskName} ${field}`);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
else if (!isDeepStrictEqual(actualValue, expectedValue)) {
|
|
1183
|
+
throw new Error(`${options.label} requires Turbo task ${taskName} ${field}`);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
function assertCapabilityPackageTurboInheritanceTruth(options) {
|
|
1189
|
+
if (!Array.isArray(options.config.extends) ||
|
|
1190
|
+
options.config.extends.length !== 1 ||
|
|
1191
|
+
options.config.extends[0] !== "//") {
|
|
1192
|
+
throw new Error(`${options.label} requires exact Turbo extends truth`);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
function effectiveCapabilityTaskDependencies(options) {
|
|
1196
|
+
if (options.localTask === undefined) {
|
|
1197
|
+
if (!isRecord(options.inheritedTask)) {
|
|
1198
|
+
throw new Error(`${options.label} requires Turbo task ${options.taskName}`);
|
|
1199
|
+
}
|
|
1200
|
+
return options.inheritedTask.dependsOn;
|
|
1201
|
+
}
|
|
1202
|
+
if (!isRecord(options.localTask)) {
|
|
1203
|
+
throw new Error(`${options.label} requires Turbo task ${options.taskName}`);
|
|
1204
|
+
}
|
|
1205
|
+
const extendsValue = options.localTask.extends;
|
|
1206
|
+
if (extendsValue !== undefined && typeof extendsValue !== "boolean") {
|
|
1207
|
+
throw new Error(`${options.label} requires Turbo task ${options.taskName} extends truth`);
|
|
1208
|
+
}
|
|
1209
|
+
if (extendsValue === false || options.localTask.dependsOn !== undefined) {
|
|
1210
|
+
return options.localTask.dependsOn;
|
|
1211
|
+
}
|
|
1212
|
+
if (!isRecord(options.inheritedTask)) {
|
|
1213
|
+
throw new Error(`${options.label} requires Turbo task ${options.taskName}`);
|
|
1214
|
+
}
|
|
1215
|
+
return options.inheritedTask.dependsOn;
|
|
1216
|
+
}
|
|
1217
|
+
function assertCapabilityConsumerTurboTruth(options) {
|
|
1218
|
+
const turboByPackagePath = new Map();
|
|
1219
|
+
for (const [qualifiedTaskName, expectedTask] of Object.entries(options.expectedTasks)) {
|
|
1220
|
+
if (expectedTask.dependsOn === undefined)
|
|
1221
|
+
continue;
|
|
1222
|
+
const separator = qualifiedTaskName.lastIndexOf("#");
|
|
1223
|
+
if (separator <= 0)
|
|
1224
|
+
continue;
|
|
1225
|
+
const packageName = qualifiedTaskName.slice(0, separator);
|
|
1226
|
+
const taskName = qualifiedTaskName.slice(separator + 1);
|
|
1227
|
+
const contribution = requireContributionByName(options.packageByName, packageName, "Database Preparation");
|
|
1228
|
+
const packageTurbo = turboByPackagePath.get(contribution.definition.path) ??
|
|
1229
|
+
readRepositoryJsonRecord({
|
|
1230
|
+
repositoryRoot: options.repositoryRoot,
|
|
1231
|
+
relativePath: `${contribution.definition.path}/turbo.json`,
|
|
1232
|
+
label: `${contribution.definition.name} Turbo Truth`,
|
|
1233
|
+
});
|
|
1234
|
+
turboByPackagePath.set(contribution.definition.path, packageTurbo);
|
|
1235
|
+
if (!isRecord(packageTurbo.tasks)) {
|
|
1236
|
+
throw new Error(`Package Addition ${contribution.definition.name} Turbo Truth requires Turbo tasks truth`);
|
|
1237
|
+
}
|
|
1238
|
+
assertCapabilityPackageTurboInheritanceTruth({
|
|
1239
|
+
config: packageTurbo,
|
|
1240
|
+
label: `Package Addition ${contribution.definition.name} Turbo Truth`,
|
|
1241
|
+
});
|
|
1242
|
+
const localTask = packageTurbo.tasks[taskName];
|
|
1243
|
+
const localDependencies = effectiveCapabilityTaskDependencies({
|
|
1244
|
+
localTask,
|
|
1245
|
+
inheritedTask: expectedTask,
|
|
1246
|
+
label: `Package Addition ${contribution.definition.name} Turbo Truth`,
|
|
1247
|
+
taskName,
|
|
1248
|
+
});
|
|
1249
|
+
if (!Array.isArray(localDependencies) ||
|
|
1250
|
+
expectedTask.dependsOn.some((expectedDependency) => !localDependencies.includes(expectedDependency))) {
|
|
1251
|
+
throw new Error(`Package Addition ${contribution.definition.name} Turbo Truth requires Turbo task ${taskName} dependsOn`);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
for (const packageName of options.buildConsumerPackageNames) {
|
|
1255
|
+
const contribution = requireContributionByName(options.packageByName, packageName, "Database Preparation");
|
|
1256
|
+
const packageTurbo = turboByPackagePath.get(contribution.definition.path) ??
|
|
1257
|
+
readRepositoryJsonRecord({
|
|
1258
|
+
repositoryRoot: options.repositoryRoot,
|
|
1259
|
+
relativePath: `${contribution.definition.path}/turbo.json`,
|
|
1260
|
+
label: `${contribution.definition.name} Turbo Truth`,
|
|
1261
|
+
});
|
|
1262
|
+
turboByPackagePath.set(contribution.definition.path, packageTurbo);
|
|
1263
|
+
if (!isRecord(packageTurbo.tasks)) {
|
|
1264
|
+
throw new Error(`Package Addition ${contribution.definition.name} Turbo Truth requires Turbo tasks truth`);
|
|
1265
|
+
}
|
|
1266
|
+
assertCapabilityPackageTurboInheritanceTruth({
|
|
1267
|
+
config: packageTurbo,
|
|
1268
|
+
label: `Package Addition ${contribution.definition.name} Turbo Truth`,
|
|
1269
|
+
});
|
|
1270
|
+
const localBuild = packageTurbo.tasks.build;
|
|
1271
|
+
const qualifiedBuild = isRecord(options.rootTurbo.tasks)
|
|
1272
|
+
? options.rootTurbo.tasks[`${packageName}#build`]
|
|
1273
|
+
: undefined;
|
|
1274
|
+
const genericBuild = isRecord(options.rootTurbo.tasks)
|
|
1275
|
+
? options.rootTurbo.tasks.build
|
|
1276
|
+
: undefined;
|
|
1277
|
+
const dependencies = effectiveCapabilityTaskDependencies({
|
|
1278
|
+
localTask: localBuild,
|
|
1279
|
+
inheritedTask: qualifiedBuild === undefined ? genericBuild : qualifiedBuild,
|
|
1280
|
+
label: `Package Addition ${contribution.definition.name} Turbo Truth`,
|
|
1281
|
+
taskName: "build",
|
|
1282
|
+
});
|
|
1283
|
+
if (!Array.isArray(dependencies) ||
|
|
1284
|
+
!dependencies.some((dependency) => dependency === "^build" ||
|
|
1285
|
+
dependency === `${options.databasePackageName}#build`)) {
|
|
1286
|
+
throw new Error(`Package Addition ${contribution.definition.name} Turbo Truth requires Turbo task build dependsOn`);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
function assertCapabilityTurboTruth(options) {
|
|
1291
|
+
if (options.databasePreparation === undefined &&
|
|
1292
|
+
options.deploymentCheck === undefined &&
|
|
1293
|
+
options.vueHonoJointE2e === undefined) {
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
const rootTurbo = readRepositoryJsonRecord({
|
|
1297
|
+
repositoryRoot: options.repositoryRoot,
|
|
1298
|
+
relativePath: "turbo.json",
|
|
1299
|
+
label: "root Turbo Truth",
|
|
1300
|
+
});
|
|
1301
|
+
assertTurboTaskTruth({
|
|
1302
|
+
config: rootTurbo,
|
|
1303
|
+
expectedTasks: {
|
|
1304
|
+
...(options.databasePreparation === undefined
|
|
1305
|
+
? {}
|
|
1306
|
+
: databasePreparationTurboTasks(options.databasePreparation)),
|
|
1307
|
+
...(options.deploymentCheck === undefined
|
|
1308
|
+
? {}
|
|
1309
|
+
: deploymentTurboTasks(options.deploymentCheck)),
|
|
1310
|
+
...(options.vueHonoJointE2e === undefined
|
|
1311
|
+
? {}
|
|
1312
|
+
: vueHonoJointE2eTurboTasks(options.vueHonoJointE2e)),
|
|
1313
|
+
},
|
|
1314
|
+
label: "Package Addition root Turbo Truth",
|
|
1315
|
+
});
|
|
1316
|
+
if (options.databasePreparation === undefined)
|
|
1317
|
+
return;
|
|
1318
|
+
const database = requireContributionByName(options.packageByName, options.databasePreparation.databasePackageName, "Database Preparation");
|
|
1319
|
+
const databaseTurbo = readRepositoryJsonRecord({
|
|
1320
|
+
repositoryRoot: options.repositoryRoot,
|
|
1321
|
+
relativePath: `${database.definition.path}/turbo.json`,
|
|
1322
|
+
label: `${database.definition.name} Turbo Truth`,
|
|
1323
|
+
});
|
|
1324
|
+
assertTurboTaskTruth({
|
|
1325
|
+
config: databaseTurbo,
|
|
1326
|
+
expectedTasks: { build: { outputs: ["dist/**"] } },
|
|
1327
|
+
label: `Package Addition ${database.definition.name} Turbo Truth`,
|
|
1328
|
+
});
|
|
1329
|
+
assertCapabilityConsumerTurboTruth({
|
|
1330
|
+
repositoryRoot: options.repositoryRoot,
|
|
1331
|
+
rootTurbo,
|
|
1332
|
+
expectedTasks: databasePreparationTurboTasks(options.databasePreparation),
|
|
1333
|
+
buildConsumerPackageNames: [
|
|
1334
|
+
options.databasePreparation.migrationPackageName,
|
|
1335
|
+
...new Set(Object.values(options.databasePreparation.consumers)),
|
|
1336
|
+
],
|
|
1337
|
+
databasePackageName: options.databasePreparation.databasePackageName,
|
|
1338
|
+
packageByName: options.packageByName,
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
function unwrapTypeScriptExpression(expression) {
|
|
1342
|
+
return ts.isParenthesizedExpression(expression) ||
|
|
1343
|
+
ts.isAsExpression(expression) ||
|
|
1344
|
+
ts.isSatisfiesExpression(expression) ||
|
|
1345
|
+
ts.isTypeAssertionExpression(expression)
|
|
1346
|
+
? unwrapTypeScriptExpression(expression.expression)
|
|
1347
|
+
: expression;
|
|
1348
|
+
}
|
|
1349
|
+
function typeScriptPropertyName(name) {
|
|
1350
|
+
return ts.isIdentifier(name) || ts.isStringLiteralLike(name)
|
|
1351
|
+
? name.text
|
|
1352
|
+
: undefined;
|
|
1353
|
+
}
|
|
1354
|
+
function finalObjectLiteralPropertyValue(expression, propertyName) {
|
|
1355
|
+
let hasUnverifiableOverride = false;
|
|
1356
|
+
for (const property of [...expression.properties].reverse()) {
|
|
1357
|
+
if (ts.isSpreadAssignment(property)) {
|
|
1358
|
+
hasUnverifiableOverride = true;
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
const name = typeScriptPropertyName(property.name);
|
|
1362
|
+
if (name === propertyName) {
|
|
1363
|
+
if (!ts.isPropertyAssignment(property) || hasUnverifiableOverride) {
|
|
1364
|
+
return undefined;
|
|
1365
|
+
}
|
|
1366
|
+
return property.initializer;
|
|
1367
|
+
}
|
|
1368
|
+
if (name === undefined) {
|
|
1369
|
+
hasUnverifiableOverride = true;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return undefined;
|
|
1373
|
+
}
|
|
1374
|
+
function assertDatabaseViteRuntimeTruth(options) {
|
|
1375
|
+
if (options.deploymentCheck === undefined)
|
|
1376
|
+
return;
|
|
1377
|
+
const application = requireContributionByName(options.packageByName, options.deploymentCheck.applicationPackageName, "Deployment Check");
|
|
1378
|
+
const configPath = `${application.definition.path}/vite.config.ts`;
|
|
1379
|
+
let sourceText;
|
|
1380
|
+
try {
|
|
1381
|
+
sourceText = readFileSync(path.join(options.repositoryRoot, configPath), "utf8");
|
|
1382
|
+
}
|
|
1383
|
+
catch (error) {
|
|
1384
|
+
throw new Error(`Package Addition requires Vite runtime truth in ${configPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
1385
|
+
}
|
|
1386
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
1387
|
+
if ((sourceFile.parseDiagnostics ?? []).length > 0) {
|
|
1388
|
+
throw new Error(`Package Addition requires valid Vite runtime truth in ${configPath}`);
|
|
1389
|
+
}
|
|
1390
|
+
const exportAssignment = sourceFile.statements.find((statement) => ts.isExportAssignment(statement) && !statement.isExportEquals);
|
|
1391
|
+
const exported = exportAssignment === undefined
|
|
1392
|
+
? undefined
|
|
1393
|
+
: unwrapTypeScriptExpression(exportAssignment.expression);
|
|
1394
|
+
const configCall = exported !== undefined &&
|
|
1395
|
+
ts.isCallExpression(exported) &&
|
|
1396
|
+
ts.isIdentifier(exported.expression) &&
|
|
1397
|
+
exported.expression.text === "defineConfig"
|
|
1398
|
+
? exported
|
|
1399
|
+
: undefined;
|
|
1400
|
+
const configArgument = configCall?.arguments[0];
|
|
1401
|
+
const config = configArgument === undefined
|
|
1402
|
+
? undefined
|
|
1403
|
+
: unwrapTypeScriptExpression(configArgument);
|
|
1404
|
+
const ssrValue = config !== undefined && ts.isObjectLiteralExpression(config)
|
|
1405
|
+
? finalObjectLiteralPropertyValue(config, "ssr")
|
|
1406
|
+
: undefined;
|
|
1407
|
+
const ssr = ssrValue === undefined ? undefined : unwrapTypeScriptExpression(ssrValue);
|
|
1408
|
+
const externalValue = ssr !== undefined && ts.isObjectLiteralExpression(ssr)
|
|
1409
|
+
? finalObjectLiteralPropertyValue(ssr, "external")
|
|
1410
|
+
: undefined;
|
|
1411
|
+
const external = externalValue === undefined
|
|
1412
|
+
? undefined
|
|
1413
|
+
: unwrapTypeScriptExpression(externalValue);
|
|
1414
|
+
const expectedPackageName = options.deploymentCheck.databasePackageName;
|
|
1415
|
+
const externalPackageNames = external !== undefined && ts.isArrayLiteralExpression(external)
|
|
1416
|
+
? external.elements.flatMap((element) => ts.isStringLiteralLike(element) ? [element.text] : [])
|
|
1417
|
+
: external !== undefined && ts.isStringLiteralLike(external)
|
|
1418
|
+
? [external.text]
|
|
1419
|
+
: [];
|
|
1420
|
+
if (!externalPackageNames.includes(expectedPackageName)) {
|
|
1421
|
+
throw new Error(`Package Addition requires ${configPath} to externalize ${expectedPackageName} through Vite SSR`);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
function assertVueHonoJointE2ePlaywrightTruth(options) {
|
|
1425
|
+
if (options.e2e === undefined)
|
|
1426
|
+
return;
|
|
1427
|
+
const configPath = "playwright.config.ts";
|
|
1428
|
+
let sourceText;
|
|
1429
|
+
try {
|
|
1430
|
+
sourceText = readFileSync(path.join(options.repositoryRoot, configPath), "utf8");
|
|
1431
|
+
}
|
|
1432
|
+
catch (error) {
|
|
1433
|
+
throw new Error(`Package Addition requires Vue-Hono joint E2E root Playwright truth in ${configPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
1434
|
+
}
|
|
1435
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
1436
|
+
if ((sourceFile.parseDiagnostics ?? []).length > 0) {
|
|
1437
|
+
throw new Error(`Package Addition requires valid Vue-Hono joint E2E root Playwright truth in ${configPath}`);
|
|
1438
|
+
}
|
|
1439
|
+
const exportAssignment = sourceFile.statements.find((statement) => ts.isExportAssignment(statement) && !statement.isExportEquals);
|
|
1440
|
+
const exported = exportAssignment === undefined
|
|
1441
|
+
? undefined
|
|
1442
|
+
: unwrapTypeScriptExpression(exportAssignment.expression);
|
|
1443
|
+
const configCall = exported !== undefined &&
|
|
1444
|
+
ts.isCallExpression(exported) &&
|
|
1445
|
+
ts.isIdentifier(exported.expression) &&
|
|
1446
|
+
exported.expression.text === "defineConfig"
|
|
1447
|
+
? exported
|
|
1448
|
+
: undefined;
|
|
1449
|
+
const configArgument = configCall?.arguments[0];
|
|
1450
|
+
const config = configArgument === undefined
|
|
1451
|
+
? undefined
|
|
1452
|
+
: unwrapTypeScriptExpression(configArgument);
|
|
1453
|
+
const webServerValue = config !== undefined && ts.isObjectLiteralExpression(config)
|
|
1454
|
+
? finalObjectLiteralPropertyValue(config, "webServer")
|
|
1455
|
+
: undefined;
|
|
1456
|
+
const webServers = webServerValue === undefined
|
|
1457
|
+
? undefined
|
|
1458
|
+
: unwrapTypeScriptExpression(webServerValue);
|
|
1459
|
+
if (webServers === undefined ||
|
|
1460
|
+
!ts.isArrayLiteralExpression(webServers) ||
|
|
1461
|
+
webServers.elements.length !== 2) {
|
|
1462
|
+
throw new Error(`Package Addition requires two static Vue-Hono joint E2E web servers in ${configPath}`);
|
|
1463
|
+
}
|
|
1464
|
+
const expectedServers = [
|
|
1465
|
+
{
|
|
1466
|
+
command: `pnpm --filter ${options.e2e.apiPackageName} --fail-if-no-match run start`,
|
|
1467
|
+
portEnvironment: "PORT",
|
|
1468
|
+
portVariable: "apiPort",
|
|
1469
|
+
portInput: "PLAYWRIGHT_API_PORT",
|
|
1470
|
+
stdout: "/Hono API listening on (?<VITE_API_BASE_URL>http:\\/\\/localhost:\\d+)/",
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
command: `pnpm --filter ${options.e2e.webPackageName} --fail-if-no-match run preview --host 127.0.0.1 --strictPort`,
|
|
1474
|
+
portEnvironment: "PLAYWRIGHT_WEB_PORT",
|
|
1475
|
+
portVariable: "webPort",
|
|
1476
|
+
portInput: "PLAYWRIGHT_WEB_PORT",
|
|
1477
|
+
stdout: "/Local:\\s+(?<PLAYWRIGHT_WEB_URL>http:\\/\\/127\\.0\\.0\\.1:\\d+)/",
|
|
1478
|
+
},
|
|
1479
|
+
];
|
|
1480
|
+
for (const [index, expected] of expectedServers.entries()) {
|
|
1481
|
+
const server = unwrapTypeScriptExpression(webServers.elements[index]);
|
|
1482
|
+
if (!ts.isObjectLiteralExpression(server)) {
|
|
1483
|
+
throw new Error(`Package Addition requires static Vue-Hono joint E2E web server ${index + 1} in ${configPath}`);
|
|
1484
|
+
}
|
|
1485
|
+
const command = finalObjectLiteralPropertyValue(server, "command");
|
|
1486
|
+
if (command === undefined ||
|
|
1487
|
+
!ts.isStringLiteralLike(command) ||
|
|
1488
|
+
command.text !== expected.command) {
|
|
1489
|
+
throw new Error(`Package Addition requires exact Vue-Hono joint E2E web server ${index + 1} command in ${configPath}`);
|
|
1490
|
+
}
|
|
1491
|
+
const environmentValue = finalObjectLiteralPropertyValue(server, "env");
|
|
1492
|
+
const environment = environmentValue === undefined
|
|
1493
|
+
? undefined
|
|
1494
|
+
: unwrapTypeScriptExpression(environmentValue);
|
|
1495
|
+
const environmentProperty = environment !== undefined && ts.isObjectLiteralExpression(environment)
|
|
1496
|
+
? environment.properties[0]
|
|
1497
|
+
: undefined;
|
|
1498
|
+
const portValue = environmentProperty !== undefined &&
|
|
1499
|
+
ts.isPropertyAssignment(environmentProperty) &&
|
|
1500
|
+
!ts.isComputedPropertyName(environmentProperty.name) &&
|
|
1501
|
+
(ts.isIdentifier(environmentProperty.name) ||
|
|
1502
|
+
ts.isStringLiteral(environmentProperty.name)) &&
|
|
1503
|
+
environmentProperty.name.text === expected.portEnvironment
|
|
1504
|
+
? unwrapTypeScriptExpression(environmentProperty.initializer)
|
|
1505
|
+
: undefined;
|
|
1506
|
+
if (environment === undefined ||
|
|
1507
|
+
!ts.isObjectLiteralExpression(environment) ||
|
|
1508
|
+
environment.properties.length !== 1 ||
|
|
1509
|
+
portValue === undefined ||
|
|
1510
|
+
!ts.isIdentifier(portValue) ||
|
|
1511
|
+
portValue.text !== expected.portVariable) {
|
|
1512
|
+
throw new Error(`Package Addition requires Vue-Hono joint E2E web server ${index + 1} ${expected.portEnvironment} environment in ${configPath}`);
|
|
1513
|
+
}
|
|
1514
|
+
const waitValue = finalObjectLiteralPropertyValue(server, "wait");
|
|
1515
|
+
const wait = waitValue === undefined
|
|
1516
|
+
? undefined
|
|
1517
|
+
: unwrapTypeScriptExpression(waitValue);
|
|
1518
|
+
const stdout = wait !== undefined && ts.isObjectLiteralExpression(wait)
|
|
1519
|
+
? finalObjectLiteralPropertyValue(wait, "stdout")
|
|
1520
|
+
: undefined;
|
|
1521
|
+
if (stdout === undefined ||
|
|
1522
|
+
!ts.isRegularExpressionLiteral(stdout) ||
|
|
1523
|
+
stdout.text !== expected.stdout) {
|
|
1524
|
+
throw new Error(`Package Addition requires static Vue-Hono joint E2E web server ${index + 1} stdout capture in ${configPath}`);
|
|
1525
|
+
}
|
|
1526
|
+
const reuseExistingServer = finalObjectLiteralPropertyValue(server, "reuseExistingServer");
|
|
1527
|
+
if (reuseExistingServer?.kind !== ts.SyntaxKind.FalseKeyword) {
|
|
1528
|
+
throw new Error(`Package Addition requires Vue-Hono joint E2E web server ${index + 1} native cleanup in ${configPath}`);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
const expectedPortInputs = expectedServers.map(({ portVariable, portInput }) => ({ portVariable, portInput }));
|
|
1532
|
+
for (const expected of expectedPortInputs) {
|
|
1533
|
+
const declarations = sourceFile.statements
|
|
1534
|
+
.filter(ts.isVariableStatement)
|
|
1535
|
+
.flatMap((statement) => statement.declarationList.declarations.map((declaration) => ({
|
|
1536
|
+
declaration,
|
|
1537
|
+
declarationList: statement.declarationList,
|
|
1538
|
+
})))
|
|
1539
|
+
.filter(({ declaration }) => ts.isIdentifier(declaration.name) &&
|
|
1540
|
+
declaration.name.text === expected.portVariable);
|
|
1541
|
+
const declaration = declarations[0];
|
|
1542
|
+
if (declarations.length !== 1 ||
|
|
1543
|
+
declaration === undefined ||
|
|
1544
|
+
(declaration.declarationList.flags & ts.NodeFlags.Const) === 0) {
|
|
1545
|
+
throw new Error(`Package Addition requires one top-level const Vue-Hono joint E2E ${expected.portVariable} in ${configPath}`);
|
|
1546
|
+
}
|
|
1547
|
+
const initializer = declaration.declaration.initializer;
|
|
1548
|
+
const left = initializer !== undefined &&
|
|
1549
|
+
ts.isBinaryExpression(initializer) &&
|
|
1550
|
+
initializer.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken
|
|
1551
|
+
? initializer.left
|
|
1552
|
+
: undefined;
|
|
1553
|
+
const right = initializer !== undefined &&
|
|
1554
|
+
ts.isBinaryExpression(initializer) &&
|
|
1555
|
+
initializer.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken
|
|
1556
|
+
? initializer.right
|
|
1557
|
+
: undefined;
|
|
1558
|
+
const environmentInput = left !== undefined &&
|
|
1559
|
+
ts.isPropertyAccessExpression(left) &&
|
|
1560
|
+
ts.isPropertyAccessExpression(left.expression) &&
|
|
1561
|
+
ts.isIdentifier(left.expression.expression) &&
|
|
1562
|
+
left.expression.expression.text === "process" &&
|
|
1563
|
+
left.expression.name.text === "env"
|
|
1564
|
+
? left.name.text
|
|
1565
|
+
: undefined;
|
|
1566
|
+
if (environmentInput !== expected.portInput ||
|
|
1567
|
+
right === undefined ||
|
|
1568
|
+
!ts.isStringLiteralLike(right) ||
|
|
1569
|
+
right.text !== "0") {
|
|
1570
|
+
throw new Error(`Package Addition requires Vue-Hono joint E2E ${expected.portVariable} to read ${expected.portInput} or static port 0 in ${configPath}`);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
function assertCapabilityRepositoryTruth(options) {
|
|
1575
|
+
assertDatabasePreparationManifestTruth({
|
|
1576
|
+
preparation: options.databasePreparation,
|
|
1577
|
+
packageByName: options.packageByName,
|
|
1578
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1579
|
+
});
|
|
1580
|
+
assertDatabaseArtifactManifestTruth({
|
|
1581
|
+
preparation: options.databasePreparation,
|
|
1582
|
+
packageByName: options.packageByName,
|
|
1583
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1584
|
+
});
|
|
1585
|
+
assertDatabaseProjectLinkManifestTruth({
|
|
1586
|
+
blueprint: options.blueprint,
|
|
1587
|
+
contributions: options.contributions,
|
|
1588
|
+
preparation: options.databasePreparation,
|
|
1589
|
+
packageByName: options.packageByName,
|
|
1590
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1591
|
+
});
|
|
1592
|
+
assertDeploymentBuildManifestTruth({
|
|
1593
|
+
deploymentCheck: options.deploymentCheck,
|
|
1594
|
+
packageByName: options.packageByName,
|
|
1595
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1596
|
+
});
|
|
1597
|
+
assertVueHonoJointE2eManifestTruth({
|
|
1598
|
+
e2e: options.vueHonoJointE2e,
|
|
1599
|
+
packageByName: options.packageByName,
|
|
1600
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1601
|
+
});
|
|
1602
|
+
assertVueHonoJointE2ePlaywrightTruth({
|
|
1603
|
+
repositoryRoot: options.repositoryRoot,
|
|
1604
|
+
e2e: options.vueHonoJointE2e,
|
|
1605
|
+
});
|
|
1606
|
+
assertRootCapabilityManifestTruth(options);
|
|
1607
|
+
assertCapabilityTurboTruth(options);
|
|
1608
|
+
assertDatabaseViteRuntimeTruth(options);
|
|
1609
|
+
}
|
|
1610
|
+
function foundationCheckEnvironmentNeeds(contributions, deploymentCheck, vueHonoJointE2e) {
|
|
1611
|
+
return [
|
|
1612
|
+
...contributions.flatMap((contribution) => contribution.environmentNeeds),
|
|
1613
|
+
...(vueHonoJointE2e === undefined
|
|
1614
|
+
? []
|
|
1615
|
+
: [
|
|
1616
|
+
playwrightBrowserAssetsEnvironmentNeed({
|
|
1617
|
+
browser: "chromium",
|
|
1618
|
+
owner: { kind: "workspace-orchestration", path: "." },
|
|
1619
|
+
}),
|
|
1620
|
+
]),
|
|
1621
|
+
...(deploymentCheck === undefined
|
|
1622
|
+
? []
|
|
1623
|
+
: [
|
|
1624
|
+
shellCheckEnvironmentNeed({
|
|
1625
|
+
kind: "workspace-orchestration",
|
|
1626
|
+
path: ".",
|
|
1627
|
+
}),
|
|
1628
|
+
]),
|
|
1629
|
+
];
|
|
1630
|
+
}
|
|
1631
|
+
function deploymentCheckDevelopmentContainerToolLayers(deploymentCheck) {
|
|
1632
|
+
if (deploymentCheck === undefined)
|
|
1633
|
+
return [];
|
|
1634
|
+
return [
|
|
1635
|
+
{
|
|
1636
|
+
identity: "shellcheck",
|
|
1637
|
+
dockerfile: deploymentCheck.sources.shellCheckDockerfile,
|
|
1638
|
+
requires: ["node-pnpm"],
|
|
1639
|
+
probes: [
|
|
1640
|
+
{
|
|
1641
|
+
identity: "shellcheck",
|
|
1642
|
+
command: "shellcheck",
|
|
1643
|
+
args: ["--version"],
|
|
1644
|
+
},
|
|
1645
|
+
],
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
identity: "docker-client",
|
|
1649
|
+
dockerfile: deploymentCheck.sources.dockerClientToolLayer,
|
|
1650
|
+
requires: ["node-pnpm"],
|
|
1651
|
+
mounts: [
|
|
1652
|
+
{
|
|
1653
|
+
identity: "docker-socket",
|
|
1654
|
+
type: "bind",
|
|
1655
|
+
source: "/var/run/docker.sock",
|
|
1656
|
+
target: "/var/run/docker.sock",
|
|
1657
|
+
},
|
|
1658
|
+
],
|
|
1659
|
+
probes: [
|
|
1660
|
+
{
|
|
1661
|
+
identity: "docker-cli",
|
|
1662
|
+
command: "docker",
|
|
1663
|
+
args: ["--version"],
|
|
1664
|
+
failureMessage: "Docker CLI is unavailable; rebuild the Development Container to install the Docker Client Tool Layer.",
|
|
1665
|
+
},
|
|
1666
|
+
{
|
|
1667
|
+
identity: "docker-daemon",
|
|
1668
|
+
command: "docker",
|
|
1669
|
+
args: ["version"],
|
|
1670
|
+
failureMessage: "Docker daemon is inaccessible through /var/run/docker.sock; verify the host daemon is running and the standard socket is accessible.",
|
|
1671
|
+
},
|
|
1672
|
+
],
|
|
1673
|
+
},
|
|
1674
|
+
];
|
|
1675
|
+
}
|
|
1676
|
+
function normalizeRustToolchain(contributions) {
|
|
1677
|
+
const declarations = contributions.flatMap((contribution) => {
|
|
1678
|
+
const rust = contribution.foundation.toolchains.rust;
|
|
1679
|
+
return rust === undefined
|
|
1680
|
+
? []
|
|
1681
|
+
: [
|
|
1682
|
+
{
|
|
1683
|
+
...rust,
|
|
1684
|
+
components: [...new Set(rust.components)].toSorted(),
|
|
1685
|
+
},
|
|
1686
|
+
];
|
|
1687
|
+
});
|
|
1688
|
+
const fingerprints = declarations.map((rust) => JSON.stringify({
|
|
1689
|
+
toolchain: rust.toolchain,
|
|
1690
|
+
components: rust.components,
|
|
1691
|
+
configurationSource: resolveTemplateSource(rust.configurationSource.source, rust.configurationSource.from),
|
|
1692
|
+
}));
|
|
1693
|
+
if (new Set(fingerprints).size > 1) {
|
|
1694
|
+
throw new Error("Foundation requires compatible Rust toolchain facts");
|
|
1695
|
+
}
|
|
1696
|
+
return declarations.at(0);
|
|
1697
|
+
}
|
|
1698
|
+
function composeDependencyMaintenancePolicy(contributions, deploymentCheck) {
|
|
1699
|
+
const ecosystems = [
|
|
1700
|
+
...new Set([
|
|
1701
|
+
...contributions.flatMap((contribution) => contribution.foundation.dependencyMaintenance.ecosystems),
|
|
1702
|
+
...(deploymentCheck === undefined ? [] : ["docker"]),
|
|
1703
|
+
]),
|
|
1704
|
+
];
|
|
1705
|
+
const directories = {};
|
|
1706
|
+
const extraDirectories = {};
|
|
1707
|
+
for (const ecosystem of ecosystems) {
|
|
1708
|
+
const candidates = [
|
|
1709
|
+
...new Set([
|
|
1710
|
+
...contributions.flatMap((contribution) => {
|
|
1711
|
+
const policy = contribution.foundation.dependencyMaintenance;
|
|
1712
|
+
const primary = policy.directories?.[ecosystem];
|
|
1713
|
+
return [
|
|
1714
|
+
...(primary === undefined ? [] : [primary]),
|
|
1715
|
+
...(policy.extraDirectories?.[ecosystem] ?? []),
|
|
1716
|
+
];
|
|
1717
|
+
}),
|
|
1718
|
+
...(ecosystem === "docker" && deploymentCheck !== undefined
|
|
1719
|
+
? ["/"]
|
|
1720
|
+
: []),
|
|
1721
|
+
]),
|
|
1722
|
+
];
|
|
1723
|
+
const [primary, ...extra] = candidates;
|
|
1724
|
+
if (primary !== undefined)
|
|
1725
|
+
directories[ecosystem] = primary;
|
|
1726
|
+
if (extra.length > 0)
|
|
1727
|
+
extraDirectories[ecosystem] = extra;
|
|
1728
|
+
}
|
|
1729
|
+
return {
|
|
1730
|
+
ecosystems,
|
|
1731
|
+
...(Object.keys(directories).length === 0 ? {} : { directories }),
|
|
1732
|
+
...(Object.keys(extraDirectories).length === 0 ? {} : { extraDirectories }),
|
|
1733
|
+
interval: "weekly",
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
function localTypescriptConfigurationSpecifier(options) {
|
|
1737
|
+
const relativePackagePath = path.posix.relative(options.consumerPackagePath, options.configurationPackagePath);
|
|
1738
|
+
if (relativePackagePath.length === 0) {
|
|
1739
|
+
throw new Error("TypeScript Configuration Package must have a distinct Package Path");
|
|
1740
|
+
}
|
|
1741
|
+
return `link:${relativePackagePath}`;
|
|
1742
|
+
}
|
|
1743
|
+
function publicCliCandidate(contributions) {
|
|
1744
|
+
const candidates = contributions.filter((contribution) => contribution.foundation.npmPublication?.kind === "public-cli-candidate");
|
|
1745
|
+
if (candidates.length > 1) {
|
|
1746
|
+
throw new Error(`Generated Repository Plan supports at most one public CLI candidate; found ${candidates.map((candidate) => `${candidate.definition.name} at ${candidate.definition.path}`).join(", ")}`);
|
|
1747
|
+
}
|
|
1748
|
+
const candidate = candidates[0];
|
|
1749
|
+
if (candidate !== undefined && candidate.definition.role !== "cli-tool") {
|
|
1750
|
+
throw new Error(`Public CLI candidate ${candidate.definition.name} must use the cli-tool Package role`);
|
|
1751
|
+
}
|
|
1752
|
+
return candidate;
|
|
1753
|
+
}
|
|
1754
|
+
function renderPublicationRootCheckCommand(candidatePackagePath) {
|
|
1755
|
+
return [
|
|
1756
|
+
"pnpm run boundaries",
|
|
1757
|
+
renderTurboRunCommand(["format:check", "lint", "typecheck", "test"], [], {
|
|
1758
|
+
continueAfterFailure: true,
|
|
1759
|
+
taskPrefix: true,
|
|
1760
|
+
}),
|
|
1761
|
+
renderTurboRunCommand(["build", "test:e2e"], [`--filter=!./${candidatePackagePath}`], { continueAfterFailure: true, taskPrefix: true }),
|
|
1762
|
+
"pnpm run publication:artifact",
|
|
1763
|
+
].join(" && ");
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1766
|
+
* 票 26 清单单源:把 plan 声明的镜像槽位集合投影成生成检查器携带的清单文本。
|
|
1767
|
+
* 转义 `$` 是必要的:清单文本注入模板字面量,未转义的 `$` 会被当成 TypeScript 插值。
|
|
1768
|
+
*/
|
|
1769
|
+
function renderToolchainMirrorSlotManifest(reconciliation) {
|
|
1770
|
+
const slots = reconciliation.flatMap((policy) => policy.driver === "canonical"
|
|
1771
|
+
? []
|
|
1772
|
+
: (policy.mirrorSlots ?? []).map((slot) => ({
|
|
1773
|
+
id: slot.id,
|
|
1774
|
+
path: policy.path,
|
|
1775
|
+
location: slot.location,
|
|
1776
|
+
})));
|
|
1777
|
+
return JSON.stringify(slots, null, 2).replaceAll("$", String.raw `\$`);
|
|
1778
|
+
}
|
|
1779
|
+
function foundationPlan(options) {
|
|
1780
|
+
assertProjectBlueprint(options.blueprint);
|
|
1781
|
+
const configContribution = options.foundationContribution;
|
|
1782
|
+
const configDefinition = configContribution.definition;
|
|
1783
|
+
if (!options.blueprint.packages.some((definition) => packageDefinitionsEqual(definition, configDefinition))) {
|
|
1784
|
+
throw new Error("Project Blueprint must contain the Foundation TypeScript configuration Package Definition");
|
|
1785
|
+
}
|
|
1786
|
+
const initialProjectLinkPlan = planExplicitProjectLinks({
|
|
1787
|
+
blueprint: options.blueprint,
|
|
1788
|
+
contributions: options.contributions,
|
|
1789
|
+
...(options.manifestTruthByPackagePath === undefined
|
|
1790
|
+
? {}
|
|
1791
|
+
: {
|
|
1792
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1793
|
+
}),
|
|
1794
|
+
});
|
|
1795
|
+
const injectedProviderNames = new Set([...initialProjectLinkPlan.manifestPatchesByPackagePath.values()].flatMap((patch) => Object.entries(patch.dependenciesMeta ?? {})
|
|
1796
|
+
.filter(([, metadata]) => metadata.injected)
|
|
1797
|
+
.map(([name]) => name)));
|
|
1798
|
+
const configPackageName = options.context.foundationPackages.typescriptConfiguration.name;
|
|
1799
|
+
if (configDefinition.name !== configPackageName) {
|
|
1800
|
+
throw new Error(`Generation Context TypeScript Configuration Package ${configPackageName} conflicts with Blueprint Package Definition ${configDefinition.name}`);
|
|
1801
|
+
}
|
|
1802
|
+
const publicationCandidate = publicCliCandidate(options.contributions);
|
|
1803
|
+
const packageContributions = options.contributions.map((contribution) => {
|
|
1804
|
+
if (contribution.foundation.typescriptConfigurationPackage === undefined) {
|
|
1805
|
+
return contribution;
|
|
1806
|
+
}
|
|
1807
|
+
const dependencyField = injectedProviderNames.has(contribution.definition.name)
|
|
1808
|
+
? "dependencies"
|
|
1809
|
+
: "devDependencies";
|
|
1810
|
+
const dependencySpecifier = dependencyField === "devDependencies" &&
|
|
1811
|
+
(contribution.manifest.private !== true ||
|
|
1812
|
+
publicationCandidate?.definition.path === contribution.definition.path)
|
|
1813
|
+
? localTypescriptConfigurationSpecifier({
|
|
1814
|
+
consumerPackagePath: contribution.definition.path,
|
|
1815
|
+
configurationPackagePath: configDefinition.path,
|
|
1816
|
+
})
|
|
1817
|
+
: "workspace:*";
|
|
1818
|
+
const existingDependencies = contribution.manifest[dependencyField];
|
|
1819
|
+
return {
|
|
1820
|
+
...contribution,
|
|
1821
|
+
manifest: {
|
|
1822
|
+
...contribution.manifest,
|
|
1823
|
+
[dependencyField]: {
|
|
1824
|
+
...(isRecord(existingDependencies) ? existingDependencies : {}),
|
|
1825
|
+
[configPackageName]: dependencySpecifier,
|
|
1826
|
+
},
|
|
1827
|
+
},
|
|
1828
|
+
};
|
|
1829
|
+
});
|
|
1830
|
+
const requiresPackingHook = packageContributions.some((contribution) => {
|
|
1831
|
+
const developmentDependencies = contribution.manifest.devDependencies;
|
|
1832
|
+
return (isRecord(developmentDependencies) &&
|
|
1833
|
+
typeof developmentDependencies[configPackageName] === "string" &&
|
|
1834
|
+
developmentDependencies[configPackageName].startsWith("link:"));
|
|
1835
|
+
});
|
|
1836
|
+
const contributions = [configContribution, ...packageContributions];
|
|
1837
|
+
assertPackageContributionCommandNames(contributions.map((contribution) => {
|
|
1838
|
+
const manifest = options.manifestTruthByPackagePath?.get(contribution.definition.path);
|
|
1839
|
+
return manifest === undefined
|
|
1840
|
+
? contribution
|
|
1841
|
+
: { ...contribution, manifest };
|
|
1842
|
+
}));
|
|
1843
|
+
const candidateRecord = options.generationRecord ?? {
|
|
1844
|
+
schemaVersion: 2,
|
|
1845
|
+
repositoryName: options.context.repositoryName,
|
|
1846
|
+
defaultPackageScope: options.context.defaultPackageScope,
|
|
1847
|
+
preset: options.definition.metadata.name,
|
|
1848
|
+
templateVersion: "0.0.0",
|
|
1849
|
+
// 显式只投影 v2 的两个历史字段,上下文里的精确 Node 事实不得进入持久记录。
|
|
1850
|
+
toolchain: {
|
|
1851
|
+
nodeLtsMajor: options.context.toolchain.nodeLtsMajor,
|
|
1852
|
+
packageManagerPin: options.context.toolchain.packageManagerPin,
|
|
1853
|
+
},
|
|
1854
|
+
packages: [
|
|
1855
|
+
...options.contributions.map((contribution) => {
|
|
1856
|
+
const planningContribution = options.mode === "initialization"
|
|
764
1857
|
? "planInitialization"
|
|
765
1858
|
: "planPackageAddition";
|
|
766
1859
|
return {
|
|
@@ -785,21 +1878,82 @@ function foundationPlan(options) {
|
|
|
785
1878
|
],
|
|
786
1879
|
};
|
|
787
1880
|
const generationRecord = parseGenerationRecord(candidateRecord);
|
|
1881
|
+
const deploymentCheck = normalizeDeploymentCheck(contributions);
|
|
1882
|
+
const vueHonoJointE2e = normalizeVueHonoJointE2e(contributions);
|
|
1883
|
+
const databasePreparation = normalizeDatabasePreparation(contributions);
|
|
1884
|
+
const rustToolchain = normalizeRustToolchain(contributions);
|
|
1885
|
+
const packageByName = new Map(contributions.map((contribution) => [
|
|
1886
|
+
contribution.definition.name,
|
|
1887
|
+
contribution,
|
|
1888
|
+
]));
|
|
1889
|
+
const deploymentPackages = deploymentCheck === undefined
|
|
1890
|
+
? undefined
|
|
1891
|
+
: {
|
|
1892
|
+
application: requireContributionByName(packageByName, deploymentCheck.applicationPackageName, "Deployment Check"),
|
|
1893
|
+
database: requireContributionByName(packageByName, deploymentCheck.databasePackageName, "Deployment Check"),
|
|
1894
|
+
migration: requireContributionByName(packageByName, deploymentCheck.migrationPackageName, "Deployment Check"),
|
|
1895
|
+
};
|
|
1896
|
+
if (databasePreparation !== undefined) {
|
|
1897
|
+
const migration = packageByName.get(databasePreparation.migrationPackageName);
|
|
1898
|
+
if (migration === undefined) {
|
|
1899
|
+
throw new Error("Database Preparation references an unknown migration Package");
|
|
1900
|
+
}
|
|
1901
|
+
for (const packageName of Object.values(databasePreparation.consumers)) {
|
|
1902
|
+
if (!packageByName.has(packageName)) {
|
|
1903
|
+
throw new Error("Database Preparation references an unknown consumer Package");
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
if (databasePreparation.consumers["database-test"] !==
|
|
1907
|
+
databasePreparation.databasePackageName) {
|
|
1908
|
+
throw new Error("Database Preparation database-test consumer must be its owner");
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
assertDatabasePreparationManifestTruth({
|
|
1912
|
+
preparation: databasePreparation,
|
|
1913
|
+
packageByName,
|
|
1914
|
+
manifestTruthByPackagePath: options.manifestTruthByPackagePath,
|
|
1915
|
+
});
|
|
1916
|
+
if (deploymentCheck !== undefined) {
|
|
1917
|
+
const deploymentPackageNames = [
|
|
1918
|
+
deploymentCheck.applicationPackageName,
|
|
1919
|
+
deploymentCheck.databasePackageName,
|
|
1920
|
+
deploymentCheck.migrationPackageName,
|
|
1921
|
+
];
|
|
1922
|
+
if (new Set(deploymentPackageNames).size !== 3) {
|
|
1923
|
+
throw new Error("Deployment Check requires three distinct Packages");
|
|
1924
|
+
}
|
|
1925
|
+
if (deploymentPackages?.application.definition.path !==
|
|
1926
|
+
deploymentCheck.declaringPackagePath) {
|
|
1927
|
+
throw new Error("Deployment Check must be declared by its application Package");
|
|
1928
|
+
}
|
|
1929
|
+
if (databasePreparation !== undefined &&
|
|
1930
|
+
(databasePreparation.databasePackageName !==
|
|
1931
|
+
deploymentCheck.databasePackageName ||
|
|
1932
|
+
databasePreparation.migrationPackageName !==
|
|
1933
|
+
deploymentCheck.migrationPackageName)) {
|
|
1934
|
+
throw new Error("Deployment Check must use the Database Preparation Packages");
|
|
1935
|
+
}
|
|
1936
|
+
for (const packageName of deploymentPackageNames) {
|
|
1937
|
+
const contribution = requireContributionByName(packageByName, packageName, "Deployment Check");
|
|
1938
|
+
const manifest = options.manifestTruthByPackagePath?.get(contribution.definition.path) ??
|
|
1939
|
+
contribution.manifest;
|
|
1940
|
+
const expectedBuild = isRecord(contribution.manifest.scripts)
|
|
1941
|
+
? contribution.manifest.scripts.build
|
|
1942
|
+
: undefined;
|
|
1943
|
+
const actualBuild = isRecord(manifest.scripts)
|
|
1944
|
+
? manifest.scripts.build
|
|
1945
|
+
: undefined;
|
|
1946
|
+
if (typeof expectedBuild !== "string" || actualBuild !== expectedBuild) {
|
|
1947
|
+
throw new Error(`Deployment Check requires exact ${packageName} manifest script build`);
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
788
1951
|
const persistedEnvironmentNeeds = normalizeEnvironmentNeeds({
|
|
789
|
-
check: contributions
|
|
790
|
-
deployment: [
|
|
791
|
-
...(options.existingDeploymentEnvironmentNeeds ?? []),
|
|
792
|
-
...contributions.flatMap((item) => item.deploymentEnvironmentNeeds ?? []),
|
|
793
|
-
],
|
|
1952
|
+
check: foundationCheckEnvironmentNeeds(contributions, deploymentCheck, vueHonoJointE2e),
|
|
1953
|
+
deployment: deploymentCheck?.environmentNeeds ?? [],
|
|
794
1954
|
});
|
|
795
1955
|
const environmentNeeds = persistedEnvironmentNeeds.check;
|
|
796
1956
|
const deploymentEnvironmentNeeds = persistedEnvironmentNeeds.deployment;
|
|
797
|
-
const hasDeploymentTask = contributions.some((contribution) => {
|
|
798
|
-
const scripts = contribution.manifest.scripts;
|
|
799
|
-
return (typeof scripts === "object" &&
|
|
800
|
-
scripts !== null &&
|
|
801
|
-
typeof scripts.deployment === "string");
|
|
802
|
-
});
|
|
803
1957
|
const contributionPackagePaths = contributions.map((contribution) => contribution.definition.path);
|
|
804
1958
|
if (new Set(contributionPackagePaths).size !== contributionPackagePaths.length)
|
|
805
1959
|
throw new Error("Package Contributions must have unique Package Paths");
|
|
@@ -814,13 +1968,26 @@ function foundationPlan(options) {
|
|
|
814
1968
|
const ciDiagnosticArtifactDeclarations = contributions.flatMap((contribution) => contribution.ciDiagnosticArtifacts ?? []);
|
|
815
1969
|
const ciDiagnosticArtifacts = composeCiDiagnosticArtifacts({
|
|
816
1970
|
packagePaths: blueprintPackagePaths,
|
|
817
|
-
declarations:
|
|
1971
|
+
declarations: [
|
|
1972
|
+
...ciDiagnosticArtifactDeclarations,
|
|
1973
|
+
...(vueHonoJointE2e === undefined
|
|
1974
|
+
? []
|
|
1975
|
+
: [
|
|
1976
|
+
{
|
|
1977
|
+
kind: "playwright",
|
|
1978
|
+
owner: { kind: "workspace-orchestration", path: "." },
|
|
1979
|
+
},
|
|
1980
|
+
]),
|
|
1981
|
+
],
|
|
818
1982
|
});
|
|
819
|
-
assertCompatibleRustToolchainFacts(contributions);
|
|
820
1983
|
const contributedToolLayers = contributions.flatMap((contribution) => contribution.foundation.developmentContainerToolLayers ?? []);
|
|
821
1984
|
const developmentContainer = contributedDevcontainerComposition({
|
|
822
1985
|
context: options.context,
|
|
823
|
-
|
|
1986
|
+
rootNodeDeclaration: options.rootNodeDeclaration,
|
|
1987
|
+
layers: [
|
|
1988
|
+
...contributedToolLayers,
|
|
1989
|
+
...deploymentCheckDevelopmentContainerToolLayers(deploymentCheck),
|
|
1990
|
+
],
|
|
824
1991
|
});
|
|
825
1992
|
const workspacePackageGlobs = [
|
|
826
1993
|
"apps/*",
|
|
@@ -835,7 +2002,9 @@ function foundationPlan(options) {
|
|
|
835
2002
|
]),
|
|
836
2003
|
];
|
|
837
2004
|
const editorCustomization = editorCustomizationForCapabilities(contributions.flatMap((contribution) => contribution.foundation.editorCapabilities), loadEditorCustomizationDeclarations(resolveTemplateSource(templateSources.editorCustomization, "capabilities.json")));
|
|
838
|
-
const dependencyMaintenancePolicy = composeDependencyMaintenancePolicy(contributions);
|
|
2005
|
+
const dependencyMaintenancePolicy = composeDependencyMaintenancePolicy(contributions, deploymentCheck);
|
|
2006
|
+
const rootOwnedE2e = vueHonoJointE2e !== undefined;
|
|
2007
|
+
const rootAutomationPaths = rootOwnedE2e ? "scripts test" : "scripts";
|
|
839
2008
|
const rootManifest = {
|
|
840
2009
|
name: options.context.repositoryName,
|
|
841
2010
|
private: true,
|
|
@@ -851,25 +2020,39 @@ function foundationPlan(options) {
|
|
|
851
2020
|
check: publicationCandidate === undefined
|
|
852
2021
|
? renderRootCheckCommand()
|
|
853
2022
|
: renderPublicationRootCheckCommand(publicationCandidate.definition.path),
|
|
854
|
-
|
|
2023
|
+
// Cargo 会在首次代理调用时按根 rust-toolchain.toml 安装版本与组件;先经唯一根任务完成解析,再并行运行各 Rust 包的 Cargo 检查。
|
|
2024
|
+
...(rustToolchain === undefined
|
|
2025
|
+
? {}
|
|
2026
|
+
: { "toolchain:prepare": "cargo --version" }),
|
|
2027
|
+
boundaries: "turbo boundaries --no-color && node --conditions=source scripts/check-toolchain-versions.ts",
|
|
2028
|
+
...(databasePreparation === undefined
|
|
2029
|
+
? {}
|
|
2030
|
+
: databasePreparationCommands(databasePreparation)),
|
|
855
2031
|
...(publicationCandidate === undefined
|
|
856
2032
|
? {}
|
|
857
2033
|
: {
|
|
858
2034
|
"publication:readiness": "node --conditions=source scripts/npm-publication/check-readiness.ts",
|
|
859
2035
|
"publication:artifact": "node --conditions=source scripts/npm-publication/check-artifact.ts",
|
|
860
2036
|
}),
|
|
861
|
-
...(
|
|
862
|
-
? {
|
|
863
|
-
: {
|
|
2037
|
+
...(deploymentCheck === undefined
|
|
2038
|
+
? {}
|
|
2039
|
+
: {
|
|
2040
|
+
deployment: "node --conditions=source scripts/check-standalone-deployment.ts",
|
|
2041
|
+
"check:deployment": renderDeploymentCheckCommand(),
|
|
2042
|
+
}),
|
|
2043
|
+
...(rootOwnedE2e ? { "test:e2e": "playwright test" } : {}),
|
|
864
2044
|
fix: renderFixCommand(),
|
|
865
|
-
"format:check":
|
|
866
|
-
"format:write":
|
|
867
|
-
lint:
|
|
868
|
-
|
|
2045
|
+
"format:check": `oxfmt --list-different --no-error-on-unmatched-pattern package.json pnpm-workspace.yaml pnpm-lock.yaml turbo.json tsconfig.json tsconfig.config.json *.config.ts .pnpmfile.mjs .gitignore .dockerignore Dockerfile TODO.md rust-toolchain.toml .vscode .github .devcontainer ${rootAutomationPaths}`,
|
|
2046
|
+
"format:write": `oxfmt --write --no-error-on-unmatched-pattern package.json pnpm-workspace.yaml pnpm-lock.yaml turbo.json tsconfig.json tsconfig.config.json *.config.ts .pnpmfile.mjs .gitignore .dockerignore Dockerfile TODO.md rust-toolchain.toml .vscode .github .devcontainer ${rootAutomationPaths}`,
|
|
2047
|
+
lint: deploymentCheck === undefined
|
|
2048
|
+
? `oxlint --quiet --format=unix --no-error-on-unmatched-pattern *.config.ts .pnpmfile.mjs ${rootAutomationPaths}`
|
|
2049
|
+
: `shellcheck scripts/container-entrypoint.sh && oxlint --quiet --format=unix --no-error-on-unmatched-pattern *.config.ts .pnpmfile.mjs ${rootAutomationPaths}`,
|
|
2050
|
+
"lint:fix": `oxlint --format=unix --no-error-on-unmatched-pattern *.config.ts .pnpmfile.mjs ${rootAutomationPaths} --fix`,
|
|
869
2051
|
typecheck: "tsc -p tsconfig.json --noEmit --pretty false",
|
|
870
2052
|
},
|
|
871
2053
|
devDependencies: {
|
|
872
2054
|
"@types/node": "catalog:",
|
|
2055
|
+
...(rootOwnedE2e ? { "@playwright/test": "catalog:" } : {}),
|
|
873
2056
|
...(publicationCandidate === undefined
|
|
874
2057
|
? {}
|
|
875
2058
|
: {
|
|
@@ -879,6 +2062,7 @@ function foundationPlan(options) {
|
|
|
879
2062
|
oxfmt: "catalog:",
|
|
880
2063
|
oxlint: "catalog:",
|
|
881
2064
|
"oxlint-tsgolint": "catalog:",
|
|
2065
|
+
"smol-toml": "catalog:",
|
|
882
2066
|
...(publicationCandidate === undefined
|
|
883
2067
|
? {}
|
|
884
2068
|
: {
|
|
@@ -890,7 +2074,7 @@ function foundationPlan(options) {
|
|
|
890
2074
|
turbo: "catalog:",
|
|
891
2075
|
"typescript-7": "catalog:",
|
|
892
2076
|
},
|
|
893
|
-
engines: { node: options.
|
|
2077
|
+
engines: { node: options.rootNodeDeclaration },
|
|
894
2078
|
packageManager: options.context.toolchain.packageManagerPin,
|
|
895
2079
|
};
|
|
896
2080
|
const dependencyCatalog = selectTemplateDependencyCatalogEntries(collectGeneratedManifestCatalogReferences([
|
|
@@ -930,8 +2114,7 @@ function foundationPlan(options) {
|
|
|
930
2114
|
};
|
|
931
2115
|
const workflowTemplateSource = projectCheckWorkflowTemplateSource({
|
|
932
2116
|
packagePaths: blueprintPackagePaths,
|
|
933
|
-
|
|
934
|
-
hasDeploymentTask,
|
|
2117
|
+
deploymentCheck,
|
|
935
2118
|
diagnosticArtifacts: ciDiagnosticArtifacts,
|
|
936
2119
|
});
|
|
937
2120
|
const workflowOperation = ciDiagnosticArtifacts.length === 0
|
|
@@ -973,6 +2156,70 @@ function foundationPlan(options) {
|
|
|
973
2156
|
];
|
|
974
2157
|
const projectLinkPlan = initialProjectLinkPlan;
|
|
975
2158
|
const turboBoundaryTags = turboBoundaryTagsForContributions(contributions);
|
|
2159
|
+
const reconciliation = [
|
|
2160
|
+
{ path: "tsconfig.json", driver: "structured" },
|
|
2161
|
+
{ path: "turbo.json", driver: "structured" },
|
|
2162
|
+
{
|
|
2163
|
+
path: ".devcontainer/devcontainer.json",
|
|
2164
|
+
driver: "structured",
|
|
2165
|
+
identitySets: [developmentContainer.mountIdentitySet],
|
|
2166
|
+
// M1:根 engines.node 原文拥有的静态镜像槽位;Core 只见位置,不见文件语义。
|
|
2167
|
+
// 设计写作 /build.args/NODE_VERSION;RFC 6901 下点号不是分隔符,取同位置的标准形。
|
|
2168
|
+
mirrorSlots: [
|
|
2169
|
+
{
|
|
2170
|
+
id: "node-version-build-arg",
|
|
2171
|
+
location: {
|
|
2172
|
+
kind: "json-pointer",
|
|
2173
|
+
pointer: "/build/args/NODE_VERSION",
|
|
2174
|
+
},
|
|
2175
|
+
},
|
|
2176
|
+
// M5:仅当本 plan 选用 Rust 时接入同一机制,值由根 rust-toolchain.toml channel 拥有。
|
|
2177
|
+
// 声明只给位置、不含版本值,故已含 Rust 的目标在加包时 Before/After 清单逐字节相同,
|
|
2178
|
+
// reconciliationPoliciesCompatible 不因 M5 扩展把合法加包变成策略不兼容。
|
|
2179
|
+
...(rustToolchain === undefined
|
|
2180
|
+
? []
|
|
2181
|
+
: [
|
|
2182
|
+
{
|
|
2183
|
+
id: "rust-toolchain-build-arg",
|
|
2184
|
+
location: {
|
|
2185
|
+
kind: "json-pointer",
|
|
2186
|
+
pointer: "/build/args/RUST_TOOLCHAIN",
|
|
2187
|
+
},
|
|
2188
|
+
},
|
|
2189
|
+
]),
|
|
2190
|
+
],
|
|
2191
|
+
},
|
|
2192
|
+
...(deploymentCheck === undefined || deploymentPackages === undefined
|
|
2193
|
+
? []
|
|
2194
|
+
: [
|
|
2195
|
+
{
|
|
2196
|
+
path: "Dockerfile",
|
|
2197
|
+
driver: "text",
|
|
2198
|
+
// M2:同一 rootNodeDeclaration 投影的锚定 ARG 默认值。
|
|
2199
|
+
mirrorSlots: [
|
|
2200
|
+
{
|
|
2201
|
+
id: "node-version-deployment-arg",
|
|
2202
|
+
location: { kind: "text-anchor", name: "NODE_VERSION" },
|
|
2203
|
+
},
|
|
2204
|
+
],
|
|
2205
|
+
},
|
|
2206
|
+
]),
|
|
2207
|
+
{
|
|
2208
|
+
path: ".vscode/extensions.json",
|
|
2209
|
+
driver: "structured",
|
|
2210
|
+
identitySets: [
|
|
2211
|
+
{
|
|
2212
|
+
location: "/recommendations",
|
|
2213
|
+
identity: { kind: "self" },
|
|
2214
|
+
},
|
|
2215
|
+
],
|
|
2216
|
+
},
|
|
2217
|
+
{ path: ".template/blueprint.json", driver: "canonical" },
|
|
2218
|
+
{ path: environmentNeedsPath, driver: "canonical" },
|
|
2219
|
+
{ path: ".template/generation.json", driver: "canonical" },
|
|
2220
|
+
];
|
|
2221
|
+
// 票 26 清单单源:生成检查器携带的槽位清单是上面声明的投影,不是第二份真源。
|
|
2222
|
+
const toolchainMirrorSlotManifest = renderToolchainMirrorSlotManifest(reconciliation);
|
|
976
2223
|
const initializationFoundationOperations = [
|
|
977
2224
|
{
|
|
978
2225
|
kind: "writeJson",
|
|
@@ -998,12 +2245,57 @@ function foundationPlan(options) {
|
|
|
998
2245
|
from: "gitignore",
|
|
999
2246
|
to: ".gitignore",
|
|
1000
2247
|
},
|
|
2248
|
+
{
|
|
2249
|
+
kind: "copyFile",
|
|
2250
|
+
source: templateSources.foundation,
|
|
2251
|
+
from: "AGENTS.md.template",
|
|
2252
|
+
to: "AGENTS.md",
|
|
2253
|
+
},
|
|
1001
2254
|
{
|
|
1002
2255
|
kind: "copyFile",
|
|
1003
2256
|
source: templateSources.foundation,
|
|
1004
2257
|
from: "turbo.json",
|
|
1005
2258
|
to: "turbo.json",
|
|
1006
2259
|
},
|
|
2260
|
+
...(vueHonoJointE2e === undefined
|
|
2261
|
+
? []
|
|
2262
|
+
: [
|
|
2263
|
+
{
|
|
2264
|
+
kind: "mergeJson",
|
|
2265
|
+
to: "turbo.json",
|
|
2266
|
+
value: { tasks: vueHonoJointE2eTurboTasks(vueHonoJointE2e) },
|
|
2267
|
+
multilineArrays: ["tasks.//#test:e2e.dependsOn"],
|
|
2268
|
+
},
|
|
2269
|
+
]),
|
|
2270
|
+
...(deploymentCheck === undefined
|
|
2271
|
+
? []
|
|
2272
|
+
: [
|
|
2273
|
+
{
|
|
2274
|
+
kind: "mergeJson",
|
|
2275
|
+
to: "turbo.json",
|
|
2276
|
+
value: {
|
|
2277
|
+
tasks: deploymentTurboTasks(deploymentCheck),
|
|
2278
|
+
},
|
|
2279
|
+
multilineArrays: ["tasks.//#deployment.dependsOn"],
|
|
2280
|
+
},
|
|
2281
|
+
]),
|
|
2282
|
+
...(databasePreparation === undefined
|
|
2283
|
+
? []
|
|
2284
|
+
: [
|
|
2285
|
+
{
|
|
2286
|
+
kind: "mergeJson",
|
|
2287
|
+
to: "turbo.json",
|
|
2288
|
+
value: {
|
|
2289
|
+
tasks: databasePreparationTurboTasks(databasePreparation),
|
|
2290
|
+
},
|
|
2291
|
+
multilineArrays: [
|
|
2292
|
+
`tasks.${databasePreparation.migrationPackageName}#typecheck.dependsOn`,
|
|
2293
|
+
`tasks.${databasePreparation.consumers["application-dev"]}#typecheck.dependsOn`,
|
|
2294
|
+
`tasks.${databasePreparation.consumers["application-dev"]}#dev.dependsOn`,
|
|
2295
|
+
`tasks.${databasePreparation.consumers["application-e2e"]}#test:e2e.dependsOn`,
|
|
2296
|
+
],
|
|
2297
|
+
},
|
|
2298
|
+
]),
|
|
1007
2299
|
...(publicationCandidate === undefined
|
|
1008
2300
|
? []
|
|
1009
2301
|
: [
|
|
@@ -1019,18 +2311,16 @@ function foundationPlan(options) {
|
|
|
1019
2311
|
source: templateSources.foundation,
|
|
1020
2312
|
from: `turbo-boundary-tags/${tag}.json`,
|
|
1021
2313
|
to: "turbo.json",
|
|
2314
|
+
multilineArrays: deploymentCheck === undefined ? [] : ["tasks.//#deployment.dependsOn"],
|
|
1022
2315
|
})),
|
|
1023
2316
|
{
|
|
1024
|
-
kind: "
|
|
1025
|
-
source: templateSources.foundation,
|
|
1026
|
-
from: "scripts/check-boundaries.ts",
|
|
1027
|
-
to: "scripts/check-boundaries.ts",
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
kind: "copyFile",
|
|
2317
|
+
kind: "writeTextTemplate",
|
|
1031
2318
|
source: templateSources.foundation,
|
|
1032
|
-
from: "scripts/
|
|
1033
|
-
to: "scripts/
|
|
2319
|
+
from: "scripts/check-toolchain-versions.ts",
|
|
2320
|
+
to: "scripts/check-toolchain-versions.ts",
|
|
2321
|
+
replacements: {
|
|
2322
|
+
TOOLCHAIN_MIRROR_SLOT_MANIFEST: toolchainMirrorSlotManifest,
|
|
2323
|
+
},
|
|
1034
2324
|
},
|
|
1035
2325
|
{
|
|
1036
2326
|
kind: "copyFile",
|
|
@@ -1038,6 +2328,38 @@ function foundationPlan(options) {
|
|
|
1038
2328
|
from: "tsconfig.json",
|
|
1039
2329
|
to: "tsconfig.json",
|
|
1040
2330
|
},
|
|
2331
|
+
...(vueHonoJointE2e === undefined
|
|
2332
|
+
? []
|
|
2333
|
+
: [
|
|
2334
|
+
{
|
|
2335
|
+
kind: "mergeJsonTemplate",
|
|
2336
|
+
source: templateSources.vueHonoApp,
|
|
2337
|
+
from: "root/tsconfig.json",
|
|
2338
|
+
to: "tsconfig.json",
|
|
2339
|
+
},
|
|
2340
|
+
{
|
|
2341
|
+
kind: "writeTextTemplate",
|
|
2342
|
+
source: templateSources.vueHonoApp,
|
|
2343
|
+
from: "root/playwright.config.ts",
|
|
2344
|
+
to: "playwright.config.ts",
|
|
2345
|
+
replacements: {
|
|
2346
|
+
API_PACKAGE_NAME: vueHonoJointE2e.apiPackageName,
|
|
2347
|
+
WEB_PACKAGE_NAME: vueHonoJointE2e.webPackageName,
|
|
2348
|
+
},
|
|
2349
|
+
},
|
|
2350
|
+
{
|
|
2351
|
+
kind: "copyFile",
|
|
2352
|
+
source: templateSources.vueHonoApp,
|
|
2353
|
+
from: "root/test/e2e/fixtures.ts",
|
|
2354
|
+
to: "test/e2e/fixtures.ts",
|
|
2355
|
+
},
|
|
2356
|
+
{
|
|
2357
|
+
kind: "copyFile",
|
|
2358
|
+
source: templateSources.vueHonoApp,
|
|
2359
|
+
from: "root/test/e2e/app.spec.ts",
|
|
2360
|
+
to: "test/e2e/app.spec.ts",
|
|
2361
|
+
},
|
|
2362
|
+
]),
|
|
1041
2363
|
...(publicationCandidate === undefined
|
|
1042
2364
|
? []
|
|
1043
2365
|
: [
|
|
@@ -1046,7 +2368,6 @@ function foundationPlan(options) {
|
|
|
1046
2368
|
source: templateSources.tsCli,
|
|
1047
2369
|
from: "publication/root-tsconfig.json",
|
|
1048
2370
|
to: "tsconfig.json",
|
|
1049
|
-
multilineArrays: ["include"],
|
|
1050
2371
|
},
|
|
1051
2372
|
]),
|
|
1052
2373
|
...(requiresPackingHook && publicationCandidate === undefined
|
|
@@ -1220,7 +2541,67 @@ function foundationPlan(options) {
|
|
|
1220
2541
|
value: editorCustomization.settings,
|
|
1221
2542
|
},
|
|
1222
2543
|
...developmentContainer.operations,
|
|
1223
|
-
...
|
|
2544
|
+
...(rustToolchain === undefined
|
|
2545
|
+
? []
|
|
2546
|
+
: [
|
|
2547
|
+
{
|
|
2548
|
+
kind: "writeTextTemplate",
|
|
2549
|
+
source: rustToolchain.configurationSource.source,
|
|
2550
|
+
from: rustToolchain.configurationSource.from,
|
|
2551
|
+
to: "rust-toolchain.toml",
|
|
2552
|
+
replacements: { RUST_TOOLCHAIN: rustToolchain.toolchain },
|
|
2553
|
+
},
|
|
2554
|
+
]),
|
|
2555
|
+
...(deploymentCheck === undefined || deploymentPackages === undefined
|
|
2556
|
+
? []
|
|
2557
|
+
: [
|
|
2558
|
+
{
|
|
2559
|
+
kind: "writeTextTemplate",
|
|
2560
|
+
source: deploymentCheck.sources.dockerfile.source,
|
|
2561
|
+
from: deploymentCheck.sources.dockerfile.from,
|
|
2562
|
+
to: "Dockerfile",
|
|
2563
|
+
replacements: {
|
|
2564
|
+
NODE_VERSION: options.rootNodeDeclaration,
|
|
2565
|
+
APPLICATION_PACKAGE_NAME: deploymentPackages.application.definition.name,
|
|
2566
|
+
APPLICATION_PACKAGE_PATH: deploymentPackages.application.definition.path,
|
|
2567
|
+
DATABASE_PACKAGE_NAME: deploymentPackages.database.definition.name,
|
|
2568
|
+
DATABASE_PACKAGE_PATH: deploymentPackages.database.definition.path,
|
|
2569
|
+
MIGRATION_PACKAGE_NAME: deploymentPackages.migration.definition.name,
|
|
2570
|
+
MIGRATION_PACKAGE_PATH: deploymentPackages.migration.definition.path,
|
|
2571
|
+
TYPESCRIPT_CONFIG_PACKAGE_PATH: configDefinition.path,
|
|
2572
|
+
},
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
kind: "writeTextTemplate",
|
|
2576
|
+
source: deploymentCheck.sources.dockerIgnore.source,
|
|
2577
|
+
from: deploymentCheck.sources.dockerIgnore.from,
|
|
2578
|
+
to: ".dockerignore",
|
|
2579
|
+
replacements: {
|
|
2580
|
+
APPLICATION_PACKAGE_PATH: deploymentPackages.application.definition.path,
|
|
2581
|
+
DATABASE_PACKAGE_PATH: deploymentPackages.database.definition.path,
|
|
2582
|
+
},
|
|
2583
|
+
},
|
|
2584
|
+
{
|
|
2585
|
+
kind: "writeTextTemplate",
|
|
2586
|
+
source: deploymentCheck.sources.checker.source,
|
|
2587
|
+
from: deploymentCheck.sources.checker.from,
|
|
2588
|
+
to: "scripts/check-standalone-deployment.ts",
|
|
2589
|
+
replacements: {
|
|
2590
|
+
APPLICATION_PACKAGE_NAME: deploymentPackages.application.definition.name,
|
|
2591
|
+
},
|
|
2592
|
+
},
|
|
2593
|
+
{
|
|
2594
|
+
kind: "copyFile",
|
|
2595
|
+
source: deploymentCheck.sources.controlScript.source,
|
|
2596
|
+
from: deploymentCheck.sources.controlScript.from,
|
|
2597
|
+
to: "scripts/container-entrypoint.sh",
|
|
2598
|
+
},
|
|
2599
|
+
{
|
|
2600
|
+
kind: "setExecutable",
|
|
2601
|
+
path: "scripts/container-entrypoint.sh",
|
|
2602
|
+
executable: true,
|
|
2603
|
+
},
|
|
2604
|
+
]),
|
|
1224
2605
|
...workflowOperations,
|
|
1225
2606
|
{
|
|
1226
2607
|
kind: "writeJson",
|
|
@@ -1293,60 +2674,173 @@ function foundationPlan(options) {
|
|
|
1293
2674
|
...plannedFoundationOperations.map((operation) => withProvenance(operation, foundationProvenance)),
|
|
1294
2675
|
...linkOperations.map((operation) => withProvenance(operation, foundationProvenance)),
|
|
1295
2676
|
];
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
2677
|
+
return {
|
|
2678
|
+
definitionName: options.definition.metadata.name,
|
|
2679
|
+
plannerSourceFile: options.definition.plannerSourceFile,
|
|
2680
|
+
planningContribution: options.mode === "addition"
|
|
2681
|
+
? "planPackageAddition"
|
|
2682
|
+
: "planInitialization",
|
|
2683
|
+
blueprint: options.blueprint,
|
|
2684
|
+
generationRecord,
|
|
2685
|
+
packageContributions,
|
|
2686
|
+
operations,
|
|
2687
|
+
reconciliation,
|
|
2688
|
+
developmentContainer: {
|
|
2689
|
+
toolLayers: developmentContainer.toolLayers,
|
|
2690
|
+
buildArguments: developmentContainer.buildArguments,
|
|
2691
|
+
mounts: developmentContainer.mounts,
|
|
2692
|
+
probes: developmentContainer.probes,
|
|
1303
2693
|
},
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
2694
|
+
environmentNeeds,
|
|
2695
|
+
deploymentCheck: deploymentCheck === undefined
|
|
2696
|
+
? undefined
|
|
2697
|
+
: {
|
|
2698
|
+
kind: deploymentCheck.kind,
|
|
2699
|
+
applicationPackageName: deploymentCheck.applicationPackageName,
|
|
2700
|
+
databasePackageName: deploymentCheck.databasePackageName,
|
|
2701
|
+
migrationPackageName: deploymentCheck.migrationPackageName,
|
|
2702
|
+
environmentNeeds: deploymentCheck.environmentNeeds,
|
|
2703
|
+
},
|
|
2704
|
+
vueHonoJointE2e: vueHonoJointE2e === undefined
|
|
2705
|
+
? undefined
|
|
2706
|
+
: {
|
|
2707
|
+
kind: vueHonoJointE2e.kind,
|
|
2708
|
+
apiPackageName: vueHonoJointE2e.apiPackageName,
|
|
2709
|
+
},
|
|
2710
|
+
deploymentEnvironmentNeeds,
|
|
2711
|
+
ciDiagnosticArtifacts,
|
|
2712
|
+
manifests: [...contributions.map((item) => item.manifest), rootManifest],
|
|
2713
|
+
dependencyCatalog,
|
|
2714
|
+
dependencyMaintenancePolicy,
|
|
2715
|
+
nextStepInstructions: [
|
|
2716
|
+
{ display: "pnpm install" },
|
|
2717
|
+
{ display: "pnpm run fix" },
|
|
2718
|
+
{ display: "pnpm run check" },
|
|
2719
|
+
],
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
function hasConfigurablePrimaryPackage(definition) {
|
|
2723
|
+
return definition.initialPrimaryPackage !== undefined;
|
|
2724
|
+
}
|
|
2725
|
+
function deduplicateInitializationInputIssues(issues) {
|
|
2726
|
+
return issues.filter((issue, index) => issues.findIndex((candidate) => candidate.code === issue.code) === index);
|
|
2727
|
+
}
|
|
2728
|
+
function collectInitializationInput(options) {
|
|
2729
|
+
const issues = [];
|
|
2730
|
+
const definition = options.definition ??
|
|
2731
|
+
(options.preset === undefined
|
|
2732
|
+
? undefined
|
|
2733
|
+
: builtInPresetRegistry
|
|
2734
|
+
.all()
|
|
2735
|
+
.find((candidate) => candidate.metadata.name === options.preset));
|
|
2736
|
+
if (definition === undefined) {
|
|
2737
|
+
return {
|
|
2738
|
+
status: "input-invalid",
|
|
2739
|
+
issues: [{ code: "PRESET_UNKNOWN" }],
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2742
|
+
const scopeOverride = options.overrides?.scope;
|
|
2743
|
+
const normalizedScope = scopeOverride?.startsWith("@") === true
|
|
2744
|
+
? scopeOverride.slice(1)
|
|
2745
|
+
: scopeOverride;
|
|
2746
|
+
const nameOverride = options.overrides?.name;
|
|
2747
|
+
const pathOverride = options.overrides?.path;
|
|
2748
|
+
const repositoryName = path.basename(path.resolve(options.targetDir));
|
|
2749
|
+
const configurablePrimaryPackage = definition.initialPrimaryPackage !== undefined;
|
|
2750
|
+
if (!configurablePrimaryPackage &&
|
|
2751
|
+
(nameOverride !== undefined || pathOverride !== undefined)) {
|
|
2752
|
+
issues.push({ code: "FIXED_TOPOLOGY_OVERRIDE" });
|
|
2753
|
+
}
|
|
2754
|
+
let validNameOverride = nameOverride !== undefined &&
|
|
2755
|
+
isValidNewNpmPackageName(`@x/${nameOverride}`);
|
|
2756
|
+
if (nameOverride !== undefined && !validNameOverride) {
|
|
2757
|
+
issues.push({ code: "INVALID_PACKAGE_NAME" });
|
|
2758
|
+
}
|
|
2759
|
+
if (pathOverride !== undefined) {
|
|
2760
|
+
const pathValidation = validateNewPackagePath(pathOverride);
|
|
2761
|
+
if (!pathValidation.hasValidShape) {
|
|
2762
|
+
issues.push({ code: "INVALID_PACKAGE_PATH" });
|
|
2763
|
+
}
|
|
2764
|
+
if (pathValidation.reservedWorkspaceCollection !== undefined) {
|
|
2765
|
+
issues.push({ code: "RESERVED_PACKAGE_PATH" });
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
let validScopeOverride = normalizedScope !== undefined &&
|
|
2769
|
+
scopeOverride === scopeOverride?.trim() &&
|
|
2770
|
+
isValidDefaultPackageScope(normalizedScope) &&
|
|
2771
|
+
isValidNewNpmPackageName(`@${normalizedScope}/typescript-config`);
|
|
2772
|
+
if (normalizedScope !== undefined && !validScopeOverride) {
|
|
2773
|
+
issues.push({ code: "INVALID_PACKAGE_SCOPE" });
|
|
2774
|
+
}
|
|
2775
|
+
let validRepositoryScope = isValidDefaultPackageScope(repositoryName) &&
|
|
2776
|
+
isValidNewNpmPackageName(`@${repositoryName}/typescript-config`);
|
|
2777
|
+
if (normalizedScope === undefined && !validRepositoryScope) {
|
|
2778
|
+
issues.push({ code: "INVALID_REPOSITORY_SCOPE" });
|
|
2779
|
+
}
|
|
2780
|
+
const resolvedScope = validScopeOverride
|
|
2781
|
+
? (normalizedScope ?? "repository")
|
|
2782
|
+
: validRepositoryScope
|
|
2783
|
+
? repositoryName
|
|
2784
|
+
: "repository";
|
|
2785
|
+
const resolvedLeaf = configurablePrimaryPackage &&
|
|
2786
|
+
nameOverride !== undefined &&
|
|
2787
|
+
validNameOverride
|
|
2788
|
+
? nameOverride
|
|
2789
|
+
: configurablePrimaryPackage
|
|
2790
|
+
? definition.initialPrimaryPackage?.defaultLeafName
|
|
2791
|
+
: undefined;
|
|
2792
|
+
if (resolvedLeaf !== undefined &&
|
|
2793
|
+
!isValidNewNpmPackageName(`@${resolvedScope}/${resolvedLeaf}`)) {
|
|
2794
|
+
if (nameOverride !== undefined) {
|
|
2795
|
+
validNameOverride = false;
|
|
2796
|
+
issues.push({ code: "INVALID_PACKAGE_NAME" });
|
|
2797
|
+
}
|
|
2798
|
+
else if (scopeOverride !== undefined) {
|
|
2799
|
+
validScopeOverride = false;
|
|
2800
|
+
issues.push({ code: "INVALID_PACKAGE_SCOPE" });
|
|
2801
|
+
}
|
|
2802
|
+
else {
|
|
2803
|
+
validRepositoryScope = false;
|
|
2804
|
+
issues.push({ code: "INVALID_REPOSITORY_SCOPE" });
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
const initialPrimaryPackage = definition.initialPrimaryPackage;
|
|
2808
|
+
const foundationDefinition = typescriptConfigPackageDefinition({
|
|
2809
|
+
foundationPackages: {
|
|
2810
|
+
typescriptConfiguration: {
|
|
2811
|
+
name: `@${resolvedScope}/typescript-config`,
|
|
2812
|
+
},
|
|
1313
2813
|
},
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
{
|
|
1317
|
-
|
|
2814
|
+
});
|
|
2815
|
+
if ((nameOverride !== undefined &&
|
|
2816
|
+
`@${resolvedScope}/${nameOverride}` === foundationDefinition.name) ||
|
|
2817
|
+
pathOverride === foundationDefinition.path) {
|
|
2818
|
+
issues.push({ code: "CONFLICTING_PACKAGE_IDENTITY" });
|
|
2819
|
+
}
|
|
2820
|
+
if (issues.length > 0) {
|
|
2821
|
+
return {
|
|
2822
|
+
status: "input-invalid",
|
|
2823
|
+
issues: deduplicateInitializationInputIssues(issues),
|
|
2824
|
+
};
|
|
2825
|
+
}
|
|
1318
2826
|
return {
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
buildArguments: developmentContainer.buildArguments,
|
|
1332
|
-
mounts: developmentContainer.mounts,
|
|
1333
|
-
probes: developmentContainer.probes,
|
|
1334
|
-
},
|
|
1335
|
-
environmentNeeds,
|
|
1336
|
-
deploymentEnvironmentNeeds,
|
|
1337
|
-
ciDiagnosticArtifacts,
|
|
1338
|
-
manifests: [...contributions.map((item) => item.manifest), rootManifest],
|
|
1339
|
-
dependencyCatalog,
|
|
1340
|
-
dependencyMaintenancePolicy,
|
|
1341
|
-
nextStepInstructions: [
|
|
1342
|
-
{ display: "pnpm install" },
|
|
1343
|
-
{ display: "pnpm run fix" },
|
|
1344
|
-
{ display: "pnpm run check" },
|
|
1345
|
-
],
|
|
2827
|
+
status: "valid",
|
|
2828
|
+
definition,
|
|
2829
|
+
normalizedScope,
|
|
2830
|
+
nameOverride,
|
|
2831
|
+
pathOverride,
|
|
2832
|
+
repositoryName,
|
|
2833
|
+
configurablePrimaryPackage,
|
|
2834
|
+
validScopeOverride,
|
|
2835
|
+
validRepositoryScope,
|
|
2836
|
+
resolvedScope,
|
|
2837
|
+
initialPrimaryPackage,
|
|
2838
|
+
foundationDefinition,
|
|
1346
2839
|
};
|
|
1347
2840
|
}
|
|
1348
|
-
function
|
|
1349
|
-
|
|
2841
|
+
export function validateGeneratedRepositoryInitializationInput(options) {
|
|
2842
|
+
const input = collectInitializationInput(options);
|
|
2843
|
+
return input.status === "input-invalid" ? input : { status: "valid" };
|
|
1350
2844
|
}
|
|
1351
2845
|
function errorDiagnostics(error) {
|
|
1352
2846
|
return (error instanceof Error ? error.message : String(error))
|
|
@@ -1476,6 +2970,7 @@ function planPreparedRepositoryInitialization(options) {
|
|
|
1476
2970
|
foundationContribution: typescriptConfigReplayAdapter.identify(typescriptConfigContribution(options.context, configDefinition)),
|
|
1477
2971
|
contributions,
|
|
1478
2972
|
mode: "initialization",
|
|
2973
|
+
rootNodeDeclaration: options.rootNodeDeclaration,
|
|
1479
2974
|
});
|
|
1480
2975
|
}
|
|
1481
2976
|
function assertPreflightedInitializationPlan(plan) {
|
|
@@ -1488,6 +2983,28 @@ function assertPreflightedInitializationPlan(plan) {
|
|
|
1488
2983
|
}
|
|
1489
2984
|
return plan;
|
|
1490
2985
|
}
|
|
2986
|
+
/** 精确 Node 事实必须是有三段补丁号的版本,不接受纯大版本或两段形式。 */
|
|
2987
|
+
const exactNodeVersionPattern = /^\d+\.\d+\.\d+$/u;
|
|
2988
|
+
/**
|
|
2989
|
+
* 私有根的 Node 声明:上下文带已知精确值时沿用该精确值,并校验其大版本与 nodeLtsMajor 一致;
|
|
2990
|
+
* 缺省时沿用原有大版本声明。这条缺省路径不作为新生成公开包范围的推导来源。
|
|
2991
|
+
*/
|
|
2992
|
+
function resolvePrivateRootNodeDeclaration(toolchain) {
|
|
2993
|
+
const { nodeLtsMajor, nodeVersion } = toolchain;
|
|
2994
|
+
if (nodeVersion === undefined)
|
|
2995
|
+
return nodeLtsMajor;
|
|
2996
|
+
if (!exactNodeVersionPattern.test(nodeVersion)) {
|
|
2997
|
+
throw new Error(`Generation Context 的 toolchain.nodeVersion 必须是精确三段 Node 版本("24.16.0"),实际收到 ${JSON.stringify(nodeVersion)}。`);
|
|
2998
|
+
}
|
|
2999
|
+
if (nodeVersion.slice(0, nodeVersion.indexOf(".")) !== nodeLtsMajor) {
|
|
3000
|
+
throw new Error(`Generation Context 的 toolchain.nodeVersion ${nodeVersion} 与 nodeLtsMajor ${nodeLtsMajor} 大版本不一致。`);
|
|
3001
|
+
}
|
|
3002
|
+
return nodeVersion;
|
|
3003
|
+
}
|
|
3004
|
+
/**
|
|
3005
|
+
* 直接规划接缝:调用方自带 Generation Context,私有根沿用其 Node 声明;上下文带精确事实时
|
|
3006
|
+
* 私有根得到精确版本。生产初始化由 prepareGeneratedRepositoryInitialization 投影 CLI 发版快照。
|
|
3007
|
+
*/
|
|
1491
3008
|
export function planGeneratedRepositoryInitialization(options) {
|
|
1492
3009
|
const prepared = preparePresetInitialization(options);
|
|
1493
3010
|
return assertPreflightedInitializationPlan(planPreparedRepositoryInitialization({
|
|
@@ -1495,79 +3012,46 @@ export function planGeneratedRepositoryInitialization(options) {
|
|
|
1495
3012
|
context: options.context,
|
|
1496
3013
|
presetBlueprint: prepared.presetBlueprint,
|
|
1497
3014
|
contributions: prepared.contributions,
|
|
3015
|
+
rootNodeDeclaration: resolvePrivateRootNodeDeclaration(options.context.toolchain),
|
|
1498
3016
|
}));
|
|
1499
3017
|
}
|
|
3018
|
+
/**
|
|
3019
|
+
* 初始化只消费随 CLI 发版的不可变工具链快照:私有根得到精确 Node 与 pnpm pin,
|
|
3020
|
+
* 选用 Rust 的仓库根 toolchain 声明得到快照的精确 Rust 版本,Generation Record 与容器等
|
|
3021
|
+
* 消费者继续得到派生的大版本。不读在线版本源,也不接受调用方版本。
|
|
3022
|
+
*/
|
|
3023
|
+
const initializationSnapshotToolchain = {
|
|
3024
|
+
nodeLtsMajor: releaseToolchainSnapshot.nodeVersion.slice(0, releaseToolchainSnapshot.nodeVersion.indexOf(".")),
|
|
3025
|
+
packageManagerPin: releaseToolchainSnapshot.packageManagerPin,
|
|
3026
|
+
nodeVersion: releaseToolchainSnapshot.nodeVersion,
|
|
3027
|
+
rustVersion: releaseToolchainSnapshot.rustVersion,
|
|
3028
|
+
};
|
|
1500
3029
|
export function prepareGeneratedRepositoryInitialization(options) {
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
};
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
const repositoryName = path.basename(path.resolve(options.targetDir));
|
|
1512
|
-
const configurablePrimaryPackage = options.definition.initialPrimaryPackage !== undefined;
|
|
1513
|
-
if (!configurablePrimaryPackage &&
|
|
1514
|
-
(nameOverride !== undefined || pathOverride !== undefined)) {
|
|
1515
|
-
diagnostics.push(`Built-in Preset ${options.definition.metadata.name} has fixed initial package topology and does not accept --name or --path`);
|
|
1516
|
-
}
|
|
1517
|
-
let validNameOverride = nameOverride !== undefined &&
|
|
1518
|
-
isValidNewNpmPackageName(`@x/${nameOverride}`);
|
|
1519
|
-
if (nameOverride !== undefined && !validNameOverride) {
|
|
1520
|
-
diagnostics.push("--name must be an unscoped package leaf name");
|
|
1521
|
-
}
|
|
1522
|
-
let validPathOverride = pathOverride !== undefined;
|
|
1523
|
-
if (pathOverride !== undefined) {
|
|
1524
|
-
const pathValidation = validateNewPackagePath(pathOverride);
|
|
1525
|
-
if (!pathValidation.hasValidShape) {
|
|
1526
|
-
diagnostics.push("--path must be exactly two safe path segments");
|
|
1527
|
-
validPathOverride = false;
|
|
1528
|
-
}
|
|
1529
|
-
if (pathValidation.reservedWorkspaceCollection !== undefined) {
|
|
1530
|
-
diagnostics.push(`--path ${pathOverride} uses reserved workspace collection ${pathValidation.reservedWorkspaceCollection}`);
|
|
1531
|
-
validPathOverride = false;
|
|
3030
|
+
const input = collectInitializationInput(options);
|
|
3031
|
+
if (input.status === "input-invalid")
|
|
3032
|
+
return input;
|
|
3033
|
+
const { definition, normalizedScope, nameOverride, pathOverride, repositoryName, configurablePrimaryPackage, validScopeOverride, validRepositoryScope, resolvedScope, initialPrimaryPackage, foundationDefinition, } = input;
|
|
3034
|
+
let derivedPackagePath;
|
|
3035
|
+
if (initialPrimaryPackage !== undefined) {
|
|
3036
|
+
try {
|
|
3037
|
+
derivedPackagePath = initialPrimaryPackage.defaultPackagePath({
|
|
3038
|
+
packageLeafName: nameOverride ?? initialPrimaryPackage.defaultLeafName,
|
|
3039
|
+
});
|
|
1532
3040
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
scopeOverride === scopeOverride?.trim() &&
|
|
1536
|
-
isValidDefaultPackageScope(normalizedScope) &&
|
|
1537
|
-
isValidNewNpmPackageName(`@${normalizedScope}/typescript-config`);
|
|
1538
|
-
if (normalizedScope !== undefined && !validScopeOverride) {
|
|
1539
|
-
diagnostics.push("--scope must be a valid npm scope without whitespace");
|
|
1540
|
-
}
|
|
1541
|
-
let validRepositoryScope = isValidDefaultPackageScope(repositoryName) &&
|
|
1542
|
-
isValidNewNpmPackageName(`@${repositoryName}/typescript-config`);
|
|
1543
|
-
if (normalizedScope === undefined && !validRepositoryScope) {
|
|
1544
|
-
diagnostics.push(`Repository Identity ${repositoryName} is not a valid default package scope; pass --scope with a valid npm scope`);
|
|
1545
|
-
}
|
|
1546
|
-
const resolvedScope = validScopeOverride
|
|
1547
|
-
? (normalizedScope ?? "repository")
|
|
1548
|
-
: validRepositoryScope
|
|
1549
|
-
? repositoryName
|
|
1550
|
-
: "repository";
|
|
1551
|
-
const resolvedLeaf = configurablePrimaryPackage &&
|
|
1552
|
-
nameOverride !== undefined &&
|
|
1553
|
-
validNameOverride
|
|
1554
|
-
? nameOverride
|
|
1555
|
-
: configurablePrimaryPackage
|
|
1556
|
-
? options.definition.initialPrimaryPackage?.defaultLeafName
|
|
1557
|
-
: undefined;
|
|
1558
|
-
if (resolvedLeaf !== undefined &&
|
|
1559
|
-
!isValidNewNpmPackageName(`@${resolvedScope}/${resolvedLeaf}`)) {
|
|
1560
|
-
if (nameOverride !== undefined) {
|
|
1561
|
-
validNameOverride = false;
|
|
1562
|
-
diagnostics.push("--name must be an unscoped package leaf name");
|
|
3041
|
+
catch {
|
|
3042
|
+
return { status: "operation-failure", phase: "preset" };
|
|
1563
3043
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
3044
|
+
const derivedPathValidation = validateNewPackagePath(derivedPackagePath);
|
|
3045
|
+
if (!derivedPathValidation.hasValidShape ||
|
|
3046
|
+
derivedPathValidation.reservedWorkspaceCollection !== undefined) {
|
|
3047
|
+
return { status: "operation-failure", phase: "preset" };
|
|
1567
3048
|
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
3049
|
+
if ((nameOverride === undefined &&
|
|
3050
|
+
`@${resolvedScope}/${initialPrimaryPackage.defaultLeafName}` ===
|
|
3051
|
+
foundationDefinition.name) ||
|
|
3052
|
+
(pathOverride === undefined &&
|
|
3053
|
+
derivedPackagePath === foundationDefinition.path)) {
|
|
3054
|
+
return { status: "operation-failure", phase: "preset" };
|
|
1571
3055
|
}
|
|
1572
3056
|
}
|
|
1573
3057
|
const context = createGenerationContext({
|
|
@@ -1577,77 +3061,56 @@ export function prepareGeneratedRepositoryInitialization(options) {
|
|
|
1577
3061
|
: validRepositoryScope
|
|
1578
3062
|
? repositoryName
|
|
1579
3063
|
: "repository",
|
|
1580
|
-
toolchain:
|
|
3064
|
+
toolchain: initializationSnapshotToolchain,
|
|
1581
3065
|
});
|
|
1582
|
-
const safeNameOverride = configurablePrimaryPackage && nameOverride !== undefined
|
|
1583
|
-
? validNameOverride
|
|
1584
|
-
? nameOverride
|
|
1585
|
-
: "x"
|
|
1586
|
-
: undefined;
|
|
1587
|
-
let safeDerivedPathOverride;
|
|
1588
|
-
const initialPrimaryPackage = options.definition.initialPrimaryPackage;
|
|
1589
|
-
if (initialPrimaryPackage !== undefined && pathOverride === undefined) {
|
|
1590
|
-
const safeLeafName = safeNameOverride ?? initialPrimaryPackage.defaultLeafName;
|
|
1591
|
-
const derivedPackagePath = initialPrimaryPackage.defaultPackagePath({
|
|
1592
|
-
packageLeafName: safeLeafName,
|
|
1593
|
-
});
|
|
1594
|
-
const derivedPathValidation = validateNewPackagePath(derivedPackagePath);
|
|
1595
|
-
if (!derivedPathValidation.hasValidShape ||
|
|
1596
|
-
derivedPathValidation.reservedWorkspaceCollection !== undefined) {
|
|
1597
|
-
diagnostics.push(`Preset-derived Package Path ${derivedPackagePath} is unsafe; pass --path with exactly two safe path segments`);
|
|
1598
|
-
safeDerivedPathOverride = "packages/invalid";
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
3066
|
const safeIdentityOverrides = {
|
|
1602
|
-
...(
|
|
3067
|
+
...(configurablePrimaryPackage && nameOverride !== undefined
|
|
3068
|
+
? { name: nameOverride }
|
|
3069
|
+
: {}),
|
|
1603
3070
|
...(configurablePrimaryPackage && pathOverride !== undefined
|
|
1604
|
-
? { path:
|
|
1605
|
-
:
|
|
3071
|
+
? { path: pathOverride }
|
|
3072
|
+
: derivedPackagePath === undefined
|
|
1606
3073
|
? {}
|
|
1607
|
-
: { path:
|
|
3074
|
+
: { path: derivedPackagePath }),
|
|
1608
3075
|
};
|
|
1609
3076
|
let prepared;
|
|
1610
3077
|
try {
|
|
1611
3078
|
prepared = preparePresetInitialization({
|
|
1612
|
-
definition
|
|
3079
|
+
definition,
|
|
1613
3080
|
context,
|
|
1614
3081
|
...(Object.keys(safeIdentityOverrides).length === 0
|
|
1615
3082
|
? {}
|
|
1616
3083
|
: { overrides: safeIdentityOverrides }),
|
|
1617
3084
|
});
|
|
1618
3085
|
}
|
|
1619
|
-
catch
|
|
1620
|
-
|
|
3086
|
+
catch {
|
|
3087
|
+
return { status: "operation-failure", phase: "preset" };
|
|
1621
3088
|
}
|
|
1622
3089
|
let plan;
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
appendDiagnostics(error);
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
if (plan !== undefined) {
|
|
1637
|
-
diagnostics.push(...validateProjectProjectionPlan({
|
|
3090
|
+
try {
|
|
3091
|
+
plan = planPreparedRepositoryInitialization({
|
|
3092
|
+
definition,
|
|
3093
|
+
context,
|
|
3094
|
+
presetBlueprint: prepared.presetBlueprint,
|
|
3095
|
+
contributions: prepared.contributions,
|
|
3096
|
+
// 私有根与上下文共用同一精确 Node 事实的推导点,避免根声明与上下文出现两个来源。
|
|
3097
|
+
rootNodeDeclaration: resolvePrivateRootNodeDeclaration(context.toolchain),
|
|
3098
|
+
});
|
|
3099
|
+
if (validateProjectProjectionPlan({
|
|
1638
3100
|
operations: plan.operations,
|
|
1639
3101
|
reconciliation: plan.reconciliation,
|
|
1640
|
-
}))
|
|
3102
|
+
}).length > 0) {
|
|
3103
|
+
return { status: "operation-failure", phase: "preflight" };
|
|
3104
|
+
}
|
|
1641
3105
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
if (prepared === undefined || plan === undefined) {
|
|
1645
|
-
throw new Error("Initialization preparation did not produce a plan");
|
|
3106
|
+
catch {
|
|
3107
|
+
return { status: "operation-failure", phase: "planning" };
|
|
1646
3108
|
}
|
|
1647
3109
|
return {
|
|
3110
|
+
status: "ready",
|
|
1648
3111
|
context,
|
|
1649
3112
|
resolved: {
|
|
1650
|
-
preset:
|
|
3113
|
+
preset: definition.metadata.name,
|
|
1651
3114
|
topology: prepared.resolvedPackageIdentity === undefined
|
|
1652
3115
|
? "fixed"
|
|
1653
3116
|
: "configurable-primary-package",
|
|
@@ -1666,24 +3129,11 @@ export function prepareGeneratedRepositoryInitialization(options) {
|
|
|
1666
3129
|
: { command: "./scripts/npm-publication-setup/setup.sh" },
|
|
1667
3130
|
};
|
|
1668
3131
|
}
|
|
1669
|
-
|
|
3132
|
+
function planGeneratedRepositoryPackageAdditionFromPreparedContribution(options) {
|
|
1670
3133
|
const { blueprint: persistedBlueprint, context } = options.localTemplateMetadata;
|
|
3134
|
+
const { rootNodeDeclaration } = options.localTemplateMetadata[localTemplateMetadataStateKey];
|
|
1671
3135
|
assertProjectBlueprint(persistedBlueprint);
|
|
1672
|
-
|
|
1673
|
-
throw new Error(`Built-in Preset ${options.definition.metadata.name} does not support Package Addition`);
|
|
1674
|
-
const packagePath = options.packagePath ??
|
|
1675
|
-
options.definition.defaultPackagePath?.({
|
|
1676
|
-
context,
|
|
1677
|
-
packageLeafName: options.packageLeafName,
|
|
1678
|
-
});
|
|
1679
|
-
if (packagePath === undefined) {
|
|
1680
|
-
throw new Error(`Built-in Preset ${options.definition.metadata.name} must own a default Package Path or receive an explicit Package Path`);
|
|
1681
|
-
}
|
|
1682
|
-
const contribution = options.definition.planPackageAddition({
|
|
1683
|
-
context,
|
|
1684
|
-
packageLeafName: options.packageLeafName,
|
|
1685
|
-
packagePath,
|
|
1686
|
-
});
|
|
3136
|
+
const contribution = options.contribution;
|
|
1687
3137
|
const requestedPackageLinkIntents = [...new Set(options.linkFrom ?? [])].map((consumerPackagePath) => ({
|
|
1688
3138
|
consumerPackagePath,
|
|
1689
3139
|
providerPackagePath: contribution.definition.path,
|
|
@@ -1703,10 +3153,10 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1703
3153
|
foundationContribution: existing.foundationContribution,
|
|
1704
3154
|
contributions: existing.contributions,
|
|
1705
3155
|
renderContributions: [],
|
|
1706
|
-
existingDeploymentEnvironmentNeeds: existing.deploymentEnvironmentNeeds,
|
|
1707
3156
|
manifestTruthByPackagePath: existing.manifestTruthByPackagePath,
|
|
1708
3157
|
generationRecord: existing.generationRecord,
|
|
1709
3158
|
mode: "addition",
|
|
3159
|
+
rootNodeDeclaration,
|
|
1710
3160
|
});
|
|
1711
3161
|
const currentProjection = foundationPlan({
|
|
1712
3162
|
definition: options.definition,
|
|
@@ -1714,9 +3164,9 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1714
3164
|
blueprint: persistedBlueprint,
|
|
1715
3165
|
foundationContribution: existing.foundationContribution,
|
|
1716
3166
|
contributions: existing.contributions,
|
|
1717
|
-
existingDeploymentEnvironmentNeeds: existing.deploymentEnvironmentNeeds,
|
|
1718
3167
|
generationRecord: existing.generationRecord,
|
|
1719
3168
|
mode: "initialization",
|
|
3169
|
+
rootNodeDeclaration,
|
|
1720
3170
|
});
|
|
1721
3171
|
return {
|
|
1722
3172
|
...plan,
|
|
@@ -1735,9 +3185,9 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1735
3185
|
};
|
|
1736
3186
|
}
|
|
1737
3187
|
if (isExactPackageDefinition) {
|
|
1738
|
-
throw new
|
|
3188
|
+
throw new PackageAdditionBusinessConflict("missing-link", conflictingPackage, contribution.definition, missingPackageLinkIntent);
|
|
1739
3189
|
}
|
|
1740
|
-
throw new
|
|
3190
|
+
throw new PackageAdditionBusinessConflict("identity", conflictingPackage, contribution.definition);
|
|
1741
3191
|
}
|
|
1742
3192
|
const contributionIdentity = requireReplayAdapter({
|
|
1743
3193
|
owner: options.definition.metadata.name,
|
|
@@ -1798,9 +3248,9 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1798
3248
|
blueprint: persistedBlueprint,
|
|
1799
3249
|
foundationContribution: existing.foundationContribution,
|
|
1800
3250
|
contributions: existing.contributions,
|
|
1801
|
-
existingDeploymentEnvironmentNeeds: existing.deploymentEnvironmentNeeds,
|
|
1802
3251
|
generationRecord: existing.generationRecord,
|
|
1803
3252
|
mode: "initialization",
|
|
3253
|
+
rootNodeDeclaration,
|
|
1804
3254
|
});
|
|
1805
3255
|
const afterProjection = foundationPlan({
|
|
1806
3256
|
definition: options.definition,
|
|
@@ -1808,10 +3258,10 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1808
3258
|
blueprint,
|
|
1809
3259
|
foundationContribution: existing.foundationContribution,
|
|
1810
3260
|
contributions: [...existing.contributions, contribution],
|
|
1811
|
-
existingDeploymentEnvironmentNeeds: existing.deploymentEnvironmentNeeds,
|
|
1812
3261
|
manifestTruthByPackagePath: existing.manifestTruthByPackagePath,
|
|
1813
3262
|
generationRecord,
|
|
1814
3263
|
mode: "initialization",
|
|
3264
|
+
rootNodeDeclaration,
|
|
1815
3265
|
});
|
|
1816
3266
|
const plan = foundationPlan({
|
|
1817
3267
|
definition: options.definition,
|
|
@@ -1820,20 +3270,35 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1820
3270
|
foundationContribution: existing.foundationContribution,
|
|
1821
3271
|
contributions: [...existing.contributions, contribution],
|
|
1822
3272
|
renderContributions: [contribution],
|
|
1823
|
-
existingDeploymentEnvironmentNeeds: existing.deploymentEnvironmentNeeds,
|
|
1824
3273
|
manifestTruthByPackagePath: existing.manifestTruthByPackagePath,
|
|
1825
3274
|
generationRecord,
|
|
1826
3275
|
mode: "addition",
|
|
3276
|
+
rootNodeDeclaration,
|
|
1827
3277
|
});
|
|
3278
|
+
let beforeOperations = beforeProjection.operations;
|
|
3279
|
+
let afterOperations = afterProjection.operations;
|
|
3280
|
+
if (options.existingRootRustDeclaration !== undefined) {
|
|
3281
|
+
const preserveOperation = {
|
|
3282
|
+
kind: "writeText",
|
|
3283
|
+
to: rootRustDeclarationFileName,
|
|
3284
|
+
text: options.existingRootRustDeclaration,
|
|
3285
|
+
};
|
|
3286
|
+
beforeOperations = [...beforeProjection.operations, preserveOperation];
|
|
3287
|
+
afterOperations = afterProjection.operations.map((operation) => operation.kind === "writeTextTemplate" &&
|
|
3288
|
+
"to" in operation &&
|
|
3289
|
+
operation.to === rootRustDeclarationFileName
|
|
3290
|
+
? preserveOperation
|
|
3291
|
+
: operation);
|
|
3292
|
+
}
|
|
1828
3293
|
return {
|
|
1829
3294
|
...plan,
|
|
1830
3295
|
projectProjections: {
|
|
1831
3296
|
before: {
|
|
1832
|
-
operations:
|
|
3297
|
+
operations: beforeOperations,
|
|
1833
3298
|
reconciliation: beforeProjection.reconciliation,
|
|
1834
3299
|
},
|
|
1835
3300
|
after: {
|
|
1836
|
-
operations:
|
|
3301
|
+
operations: afterOperations,
|
|
1837
3302
|
reconciliation: afterProjection.reconciliation,
|
|
1838
3303
|
},
|
|
1839
3304
|
preconditions: [
|
|
@@ -1846,3 +3311,215 @@ export function planGeneratedRepositoryPackageAddition(options) {
|
|
|
1846
3311
|
},
|
|
1847
3312
|
};
|
|
1848
3313
|
}
|
|
3314
|
+
export function planGeneratedRepositoryPackageAddition(options) {
|
|
3315
|
+
const { context } = options.localTemplateMetadata;
|
|
3316
|
+
if (options.definition.planPackageAddition === undefined) {
|
|
3317
|
+
throw new Error(`Built-in Preset ${options.definition.metadata.name} does not support Package Addition`);
|
|
3318
|
+
}
|
|
3319
|
+
const packagePath = options.packagePath ??
|
|
3320
|
+
options.definition.defaultPackagePath?.({
|
|
3321
|
+
context,
|
|
3322
|
+
packageLeafName: options.packageLeafName,
|
|
3323
|
+
});
|
|
3324
|
+
if (packagePath === undefined) {
|
|
3325
|
+
throw new Error(`Built-in Preset ${options.definition.metadata.name} must own a default Package Path or receive an explicit Package Path`);
|
|
3326
|
+
}
|
|
3327
|
+
const contribution = options.definition.planPackageAddition({
|
|
3328
|
+
context,
|
|
3329
|
+
packageLeafName: options.packageLeafName,
|
|
3330
|
+
packagePath,
|
|
3331
|
+
});
|
|
3332
|
+
return planGeneratedRepositoryPackageAdditionFromPreparedContribution({
|
|
3333
|
+
...options,
|
|
3334
|
+
packagePath,
|
|
3335
|
+
contribution,
|
|
3336
|
+
});
|
|
3337
|
+
}
|
|
3338
|
+
function collectPackageAdditionInput(options) {
|
|
3339
|
+
const issues = [];
|
|
3340
|
+
const definition = builtInPresetRegistry
|
|
3341
|
+
.all()
|
|
3342
|
+
.find((candidate) => candidate.metadata.name === options.preset);
|
|
3343
|
+
if (definition === undefined)
|
|
3344
|
+
issues.push({ code: "PRESET_UNKNOWN" });
|
|
3345
|
+
else if (definition.planPackageAddition === undefined)
|
|
3346
|
+
issues.push({ code: "PRESET_NOT_ADDABLE" });
|
|
3347
|
+
if (!isValidNewNpmPackageName(`@x/${options.packageLeafName}`)) {
|
|
3348
|
+
issues.push({ code: "INVALID_PACKAGE_NAME" });
|
|
3349
|
+
}
|
|
3350
|
+
if (options.packagePath !== undefined) {
|
|
3351
|
+
const validation = validateNewPackagePath(options.packagePath);
|
|
3352
|
+
if (!validation.hasValidShape)
|
|
3353
|
+
issues.push({ code: "INVALID_PACKAGE_PATH" });
|
|
3354
|
+
if (validation.reservedWorkspaceCollection !== undefined) {
|
|
3355
|
+
issues.push({ code: "RESERVED_PACKAGE_PATH" });
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
const linkFrom = [...new Set(options.linkFrom ?? [])];
|
|
3359
|
+
for (const consumerPackagePath of linkFrom) {
|
|
3360
|
+
const validation = validateNewPackagePath(consumerPackagePath);
|
|
3361
|
+
if (!validation.hasValidShape) {
|
|
3362
|
+
issues.push({ code: "INVALID_LINK_FROM" });
|
|
3363
|
+
}
|
|
3364
|
+
if (validation.reservedWorkspaceCollection !== undefined)
|
|
3365
|
+
issues.push({ code: "RESERVED_LINK_FROM" });
|
|
3366
|
+
}
|
|
3367
|
+
if (issues.length > 0 || definition === undefined) {
|
|
3368
|
+
return { status: "input-invalid", issues };
|
|
3369
|
+
}
|
|
3370
|
+
return { status: "valid", definition, linkFrom };
|
|
3371
|
+
}
|
|
3372
|
+
/**
|
|
3373
|
+
* Command-owned preparation: user input is checked before local metadata or any
|
|
3374
|
+
* Preset default/planner work; all remaining failures are deliberately bounded.
|
|
3375
|
+
*/
|
|
3376
|
+
export function prepareGeneratedRepositoryPackageAddition(options) {
|
|
3377
|
+
const input = collectPackageAdditionInput(options);
|
|
3378
|
+
if (input.status === "input-invalid")
|
|
3379
|
+
return input;
|
|
3380
|
+
let localTemplateMetadata;
|
|
3381
|
+
try {
|
|
3382
|
+
localTemplateMetadata = loadLocalTemplateMetadata(options.repositoryRoot);
|
|
3383
|
+
}
|
|
3384
|
+
catch (error) {
|
|
3385
|
+
if (error instanceof PackageAdditionTargetDeclarationFailure) {
|
|
3386
|
+
return {
|
|
3387
|
+
status: "operation-failure",
|
|
3388
|
+
phase: "metadata",
|
|
3389
|
+
diagnostic: { message: error.message, suggestion: error.suggestion },
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
return { status: "operation-failure", phase: "metadata" };
|
|
3393
|
+
}
|
|
3394
|
+
if (input.linkFrom.some((consumerPackagePath) => !localTemplateMetadata.blueprint.packages.some((candidate) => candidate.path === consumerPackagePath))) {
|
|
3395
|
+
return {
|
|
3396
|
+
status: "input-invalid",
|
|
3397
|
+
issues: [{ code: "UNKNOWN_LINK_FROM" }],
|
|
3398
|
+
};
|
|
3399
|
+
}
|
|
3400
|
+
let packagePath = options.packagePath;
|
|
3401
|
+
if (packagePath === undefined) {
|
|
3402
|
+
try {
|
|
3403
|
+
packagePath = input.definition.defaultPackagePath?.({
|
|
3404
|
+
context: localTemplateMetadata.context,
|
|
3405
|
+
packageLeafName: options.packageLeafName,
|
|
3406
|
+
});
|
|
3407
|
+
}
|
|
3408
|
+
catch {
|
|
3409
|
+
return { status: "operation-failure", phase: "default" };
|
|
3410
|
+
}
|
|
3411
|
+
const defaultPathValidation = packagePath === undefined
|
|
3412
|
+
? undefined
|
|
3413
|
+
: validateNewPackagePath(packagePath);
|
|
3414
|
+
if (defaultPathValidation === undefined ||
|
|
3415
|
+
!defaultPathValidation.hasValidShape ||
|
|
3416
|
+
defaultPathValidation.reservedWorkspaceCollection !== undefined) {
|
|
3417
|
+
return { status: "operation-failure", phase: "default" };
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
if (packagePath === undefined) {
|
|
3421
|
+
return { status: "operation-failure", phase: "default" };
|
|
3422
|
+
}
|
|
3423
|
+
let provider;
|
|
3424
|
+
try {
|
|
3425
|
+
provider = input.definition.planPackageAddition({
|
|
3426
|
+
context: localTemplateMetadata.context,
|
|
3427
|
+
packageLeafName: options.packageLeafName,
|
|
3428
|
+
packagePath,
|
|
3429
|
+
});
|
|
3430
|
+
}
|
|
3431
|
+
catch {
|
|
3432
|
+
return { status: "operation-failure", phase: "planning" };
|
|
3433
|
+
}
|
|
3434
|
+
// 首次引入 Rust 的加包按目标事实二选一:已有合法根声明由该声明拥有版本并原正文保留;
|
|
3435
|
+
// 没有根声明才以当前 CLI 已验证快照建源。已有 Rust 能力的仓库在 loadLocalTemplateMetadata
|
|
3436
|
+
// 已由根 channel 重放(缺真源在那里失败),不进入这条路径;不可解释的声明在此可行动失败,
|
|
3437
|
+
// 不用快照掩盖。非 Rust 加包不读无关根文件。
|
|
3438
|
+
let additionMetadata = localTemplateMetadata;
|
|
3439
|
+
let preservedRootRustDeclaration;
|
|
3440
|
+
if (provider.foundation.toolchains.rust !== undefined &&
|
|
3441
|
+
localTemplateMetadata.context.toolchain.rustVersion === undefined) {
|
|
3442
|
+
const repositoryRoot = localTemplateMetadata.context.targetDir;
|
|
3443
|
+
const rootDeclarationPath = path.join(repositoryRoot, rootRustDeclarationFileName);
|
|
3444
|
+
const existingDeclaration = existsSync(rootDeclarationPath)
|
|
3445
|
+
? readFileSync(rootDeclarationPath, "utf8")
|
|
3446
|
+
: undefined;
|
|
3447
|
+
let rustVersion;
|
|
3448
|
+
try {
|
|
3449
|
+
if (existingDeclaration === undefined) {
|
|
3450
|
+
rustVersion = releaseToolchainSnapshot.rustVersion;
|
|
3451
|
+
}
|
|
3452
|
+
else {
|
|
3453
|
+
rustVersion = readPackageAdditionTargetRustChannel(repositoryRoot);
|
|
3454
|
+
preservedRootRustDeclaration = existingDeclaration;
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
catch (error) {
|
|
3458
|
+
if (error instanceof PackageAdditionTargetDeclarationFailure) {
|
|
3459
|
+
return {
|
|
3460
|
+
status: "operation-failure",
|
|
3461
|
+
phase: "metadata",
|
|
3462
|
+
diagnostic: { message: error.message, suggestion: error.suggestion },
|
|
3463
|
+
};
|
|
3464
|
+
}
|
|
3465
|
+
return { status: "operation-failure", phase: "metadata" };
|
|
3466
|
+
}
|
|
3467
|
+
additionMetadata = {
|
|
3468
|
+
...localTemplateMetadata,
|
|
3469
|
+
context: {
|
|
3470
|
+
...localTemplateMetadata.context,
|
|
3471
|
+
toolchain: {
|
|
3472
|
+
...localTemplateMetadata.context.toolchain,
|
|
3473
|
+
rustVersion,
|
|
3474
|
+
},
|
|
3475
|
+
},
|
|
3476
|
+
};
|
|
3477
|
+
try {
|
|
3478
|
+
provider = input.definition.planPackageAddition({
|
|
3479
|
+
context: additionMetadata.context,
|
|
3480
|
+
packageLeafName: options.packageLeafName,
|
|
3481
|
+
packagePath,
|
|
3482
|
+
});
|
|
3483
|
+
}
|
|
3484
|
+
catch {
|
|
3485
|
+
return { status: "operation-failure", phase: "planning" };
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
const contributionsByPath = new Map(localTemplateMetadata[localTemplateMetadataStateKey].packageContributions.map((contribution) => [
|
|
3489
|
+
contribution.definition.path,
|
|
3490
|
+
contribution,
|
|
3491
|
+
]));
|
|
3492
|
+
if (input.linkFrom.length > 0 &&
|
|
3493
|
+
(!canProvideSourceConditionPackageNameImport(provider) ||
|
|
3494
|
+
input.linkFrom.some((consumerPackagePath) => {
|
|
3495
|
+
const consumer = contributionsByPath.get(consumerPackagePath);
|
|
3496
|
+
return (consumer === undefined ||
|
|
3497
|
+
!canConsumeNodePackageNameImport(consumer) ||
|
|
3498
|
+
!canLinkNodePackageRoles(consumer.definition.role, provider.definition.role));
|
|
3499
|
+
}))) {
|
|
3500
|
+
return { status: "input-invalid", issues: [{ code: "UNSUPPORTED_LINK" }] };
|
|
3501
|
+
}
|
|
3502
|
+
try {
|
|
3503
|
+
return {
|
|
3504
|
+
status: "ready",
|
|
3505
|
+
definition: input.definition,
|
|
3506
|
+
plan: planGeneratedRepositoryPackageAdditionFromPreparedContribution({
|
|
3507
|
+
definition: input.definition,
|
|
3508
|
+
localTemplateMetadata: additionMetadata,
|
|
3509
|
+
packageLeafName: options.packageLeafName,
|
|
3510
|
+
packagePath,
|
|
3511
|
+
contribution: provider,
|
|
3512
|
+
...(input.linkFrom.length === 0 ? {} : { linkFrom: input.linkFrom }),
|
|
3513
|
+
...(preservedRootRustDeclaration === undefined
|
|
3514
|
+
? {}
|
|
3515
|
+
: { existingRootRustDeclaration: preservedRootRustDeclaration }),
|
|
3516
|
+
}),
|
|
3517
|
+
};
|
|
3518
|
+
}
|
|
3519
|
+
catch (error) {
|
|
3520
|
+
if (error instanceof PackageAdditionBusinessConflict) {
|
|
3521
|
+
return { status: "conflict", conflict: error };
|
|
3522
|
+
}
|
|
3523
|
+
return { status: "operation-failure", phase: "planning" };
|
|
3524
|
+
}
|
|
3525
|
+
}
|