@elench/testkit 0.1.64 → 0.1.66
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/lib/app/browser-bridge.mjs +66 -0
- package/lib/app/configs.mjs +81 -0
- package/lib/app/configs.test.mjs +34 -0
- package/lib/cli/command-helpers.mjs +2 -10
- package/lib/cli/commands/browser/serve.mjs +3 -62
- package/lib/cli/db.mjs +3 -68
- package/lib/config/binaries.mjs +34 -0
- package/lib/config/database.mjs +9 -6
- package/lib/config/index.mjs +2 -31
- package/lib/config/runtime.mjs +24 -95
- package/lib/config/validation.mjs +18 -62
- package/lib/coverage/backend-discovery.mjs +68 -85
- package/lib/coverage/backend-discovery.test.mjs +55 -46
- package/lib/coverage/evidence.mjs +15 -3
- package/lib/coverage/evidence.test.mjs +13 -4
- package/lib/coverage/graph-builder.mjs +25 -26
- package/lib/coverage/next-ir-to-graph.mjs +239 -0
- package/lib/coverage/routing.mjs +2 -29
- package/lib/coverage/routing.test.mjs +0 -16
- package/lib/coverage/shared.mjs +22 -82
- package/lib/database/fingerprint.mjs +1 -1
- package/lib/known-failures/github-cache.mjs +159 -0
- package/lib/known-failures/github-transport.mjs +174 -0
- package/lib/known-failures/github.mjs +17 -325
- package/lib/runner/default-runtime-runner.mjs +4 -10
- package/lib/runner/execution-config.mjs +12 -83
- package/lib/runner/live-run.mjs +45 -0
- package/lib/runner/managed-processes.mjs +29 -0
- package/lib/runner/orchestrator.mjs +57 -188
- package/lib/runner/playwright-runner.mjs +4 -11
- package/lib/runner/run-finalization.mjs +132 -0
- package/lib/runner/run-guards.mjs +45 -0
- package/lib/runner/runtime-preparation.mjs +1 -1
- package/lib/runner/services.mjs +3 -4
- package/lib/runner/template-steps.mjs +8 -45
- package/lib/runner/template.mjs +7 -28
- package/lib/shared/configured-steps.mjs +178 -0
- package/lib/shared/configured-steps.test.mjs +73 -0
- package/lib/shared/execution-schema.mjs +74 -0
- package/lib/shared/execution-schema.test.mjs +26 -0
- package/node_modules/@elench/next-analysis/dist/api-routes.d.ts +7 -0
- package/node_modules/@elench/next-analysis/dist/api-routes.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/api-routes.js +66 -0
- package/node_modules/@elench/next-analysis/dist/api-routes.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/app-root.d.ts +2 -0
- package/node_modules/@elench/next-analysis/dist/app-root.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/app-root.js +7 -0
- package/node_modules/@elench/next-analysis/dist/app-root.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/backend-links.d.ts +8 -0
- package/node_modules/@elench/next-analysis/dist/backend-links.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/backend-links.js +30 -0
- package/node_modules/@elench/next-analysis/dist/backend-links.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/index.d.ts +11 -0
- package/node_modules/@elench/next-analysis/dist/index.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/index.js +10 -0
- package/node_modules/@elench/next-analysis/dist/index.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/pages.d.ts +7 -0
- package/node_modules/@elench/next-analysis/dist/pages.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/pages.js +47 -0
- package/node_modules/@elench/next-analysis/dist/pages.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/project.d.ts +3 -0
- package/node_modules/@elench/next-analysis/dist/project.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/project.js +102 -0
- package/node_modules/@elench/next-analysis/dist/project.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/route-tree.d.ts +7 -0
- package/node_modules/@elench/next-analysis/dist/route-tree.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/route-tree.js +575 -0
- package/node_modules/@elench/next-analysis/dist/route-tree.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/routes.d.ts +6 -0
- package/node_modules/@elench/next-analysis/dist/routes.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/routes.js +41 -0
- package/node_modules/@elench/next-analysis/dist/routes.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/server-actions.d.ts +7 -0
- package/node_modules/@elench/next-analysis/dist/server-actions.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/server-actions.js +37 -0
- package/node_modules/@elench/next-analysis/dist/server-actions.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/shared.d.ts +57 -0
- package/node_modules/@elench/next-analysis/dist/shared.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/shared.js +229 -0
- package/node_modules/@elench/next-analysis/dist/shared.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/swc.d.ts +53 -0
- package/node_modules/@elench/next-analysis/dist/swc.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/swc.js +387 -0
- package/node_modules/@elench/next-analysis/dist/swc.js.map +1 -0
- package/node_modules/@elench/next-analysis/dist/types.d.ts +125 -0
- package/node_modules/@elench/next-analysis/dist/types.d.ts.map +1 -0
- package/node_modules/@elench/next-analysis/dist/types.js +2 -0
- package/node_modules/@elench/next-analysis/dist/types.js.map +1 -0
- package/node_modules/@elench/next-analysis/package.json +27 -0
- package/node_modules/@elench/testkit-bridge/dist/index.d.ts +36 -0
- package/node_modules/@elench/testkit-bridge/dist/index.d.ts.map +1 -0
- package/node_modules/@elench/testkit-bridge/dist/index.js +538 -0
- package/node_modules/@elench/testkit-bridge/dist/index.js.map +1 -0
- package/node_modules/@elench/testkit-bridge/package.json +16 -5
- package/node_modules/@elench/testkit-protocol/dist/index.d.ts +190 -0
- package/node_modules/@elench/testkit-protocol/dist/index.d.ts.map +1 -0
- package/node_modules/@elench/testkit-protocol/dist/index.js +296 -0
- package/node_modules/@elench/testkit-protocol/dist/index.js.map +1 -0
- package/node_modules/@elench/testkit-protocol/package.json +14 -7
- package/node_modules/@elench/ts-analysis/dist/callables.d.ts +8 -0
- package/node_modules/@elench/ts-analysis/dist/callables.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/callables.js +126 -0
- package/node_modules/@elench/ts-analysis/dist/callables.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/exports.d.ts +6 -0
- package/node_modules/@elench/ts-analysis/dist/exports.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/exports.js +70 -0
- package/node_modules/@elench/ts-analysis/dist/exports.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/index.d.ts +10 -0
- package/node_modules/@elench/ts-analysis/dist/index.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/{src/index.mjs → dist/index.js} +9 -14
- package/node_modules/@elench/ts-analysis/dist/index.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/jsx.d.ts +9 -0
- package/node_modules/@elench/ts-analysis/dist/jsx.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/jsx.js +68 -0
- package/node_modules/@elench/ts-analysis/dist/jsx.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/project.d.ts +5 -0
- package/node_modules/@elench/ts-analysis/dist/project.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/project.js +90 -0
- package/node_modules/@elench/ts-analysis/dist/project.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/requests.d.ts +6 -0
- package/node_modules/@elench/ts-analysis/dist/requests.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/requests.js +140 -0
- package/node_modules/@elench/ts-analysis/dist/requests.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/resolution.d.ts +4 -0
- package/node_modules/@elench/ts-analysis/dist/resolution.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/resolution.js +53 -0
- package/node_modules/@elench/ts-analysis/dist/resolution.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/shared.d.ts +6 -0
- package/node_modules/@elench/ts-analysis/dist/shared.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/shared.js +31 -0
- package/node_modules/@elench/ts-analysis/dist/shared.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/syntax.d.ts +7 -0
- package/node_modules/@elench/ts-analysis/dist/syntax.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/syntax.js +27 -0
- package/node_modules/@elench/ts-analysis/dist/syntax.js.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/types.d.ts +58 -0
- package/node_modules/@elench/ts-analysis/dist/types.d.ts.map +1 -0
- package/node_modules/@elench/ts-analysis/dist/types.js +2 -0
- package/node_modules/@elench/ts-analysis/dist/types.js.map +1 -0
- package/node_modules/@elench/ts-analysis/package.json +18 -2
- package/node_modules/@next/routing/README.md +91 -0
- package/node_modules/@next/routing/dist/__tests__/captures.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/conditions.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/dynamic-after-rewrites.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/i18n-resolve-routes.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/i18n.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/middleware.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/normalize-next-data.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/redirects.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/resolve-routes.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/__tests__/rewrites.test.d.ts +1 -0
- package/node_modules/@next/routing/dist/destination.d.ts +22 -0
- package/node_modules/@next/routing/dist/i18n.d.ts +48 -0
- package/node_modules/@next/routing/dist/index.d.ts +5 -0
- package/node_modules/@next/routing/dist/index.js +1 -0
- package/node_modules/@next/routing/dist/matchers.d.ts +12 -0
- package/node_modules/@next/routing/dist/middleware.d.ts +12 -0
- package/node_modules/@next/routing/dist/next-data.d.ts +10 -0
- package/node_modules/@next/routing/dist/resolve-routes.d.ts +2 -0
- package/node_modules/@next/routing/dist/types.d.ts +97 -0
- package/node_modules/@next/routing/package.json +39 -0
- package/node_modules/@swc/core/README.md +100 -0
- package/node_modules/@swc/core/Visitor.d.ts +218 -0
- package/node_modules/@swc/core/Visitor.js +1399 -0
- package/node_modules/@swc/core/binding.d.ts +59 -0
- package/node_modules/@swc/core/binding.js +368 -0
- package/node_modules/@swc/core/index.d.ts +120 -0
- package/node_modules/@swc/core/index.js +443 -0
- package/node_modules/@swc/core/package.json +120 -0
- package/node_modules/@swc/core/postinstall.js +148 -0
- package/node_modules/@swc/core/spack.d.ts +51 -0
- package/node_modules/@swc/core/spack.js +87 -0
- package/node_modules/@swc/core/util.d.ts +1 -0
- package/node_modules/@swc/core/util.js +104 -0
- package/node_modules/@swc/core-linux-x64-gnu/README.md +3 -0
- package/node_modules/@swc/core-linux-x64-gnu/package.json +46 -0
- package/node_modules/@swc/core-linux-x64-gnu/swc.linux-x64-gnu.node +0 -0
- package/node_modules/@swc/counter/CHANGELOG.md +7 -0
- package/node_modules/@swc/counter/README.md +7 -0
- package/node_modules/@swc/counter/index.js +1 -0
- package/node_modules/@swc/counter/package.json +27 -0
- package/node_modules/@swc/types/LICENSE +201 -0
- package/node_modules/@swc/types/README.md +4 -0
- package/node_modules/@swc/types/assumptions.d.ts +92 -0
- package/node_modules/@swc/types/assumptions.js +2 -0
- package/node_modules/@swc/types/index.d.ts +2049 -0
- package/node_modules/@swc/types/index.js +2 -0
- package/node_modules/@swc/types/package.json +40 -0
- package/node_modules/typescript/LICENSE.txt +55 -0
- package/node_modules/typescript/README.md +50 -0
- package/node_modules/typescript/SECURITY.md +41 -0
- package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
- package/node_modules/typescript/bin/tsc +2 -0
- package/node_modules/typescript/bin/tsserver +2 -0
- package/node_modules/typescript/lib/_tsc.js +133818 -0
- package/node_modules/typescript/lib/_tsserver.js +659 -0
- package/node_modules/typescript/lib/_typingsInstaller.js +222 -0
- package/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/lib.d.ts +22 -0
- package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
- package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/tsc.js +8 -0
- package/node_modules/typescript/lib/tsserver.js +8 -0
- package/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/node_modules/typescript/lib/typesMap.json +497 -0
- package/node_modules/typescript/lib/typescript.d.ts +11437 -0
- package/node_modules/typescript/lib/typescript.js +200276 -0
- package/node_modules/typescript/lib/typingsInstaller.js +8 -0
- package/node_modules/typescript/lib/watchGuard.js +53 -0
- package/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
- package/node_modules/typescript/package.json +120 -0
- package/package.json +13 -8
- package/lib/coverage/fs-walk.mjs +0 -64
- package/lib/coverage/next-discovery.mjs +0 -205
- package/lib/coverage/next-static-analysis.mjs +0 -1045
- package/node_modules/@elench/testkit-bridge/src/index.mjs +0 -583
- package/node_modules/@elench/testkit-bridge/src/index.test.mjs +0 -409
- package/node_modules/@elench/testkit-protocol/src/index.d.ts +0 -231
- package/node_modules/@elench/testkit-protocol/src/index.mjs +0 -265
- package/node_modules/@elench/testkit-protocol/src/index.test.mjs +0 -242
- package/node_modules/@elench/ts-analysis/src/callables.mjs +0 -135
- package/node_modules/@elench/ts-analysis/src/callables.test.mjs +0 -55
- package/node_modules/@elench/ts-analysis/src/exports.mjs +0 -69
- package/node_modules/@elench/ts-analysis/src/exports.test.mjs +0 -50
- package/node_modules/@elench/ts-analysis/src/jsx.mjs +0 -69
- package/node_modules/@elench/ts-analysis/src/jsx.test.mjs +0 -43
- package/node_modules/@elench/ts-analysis/src/project.mjs +0 -100
- package/node_modules/@elench/ts-analysis/src/project.test.mjs +0 -54
- package/node_modules/@elench/ts-analysis/src/requests.mjs +0 -141
- package/node_modules/@elench/ts-analysis/src/requests.test.mjs +0 -35
- package/node_modules/@elench/ts-analysis/src/resolution.mjs +0 -53
- package/node_modules/@elench/ts-analysis/src/shared.mjs +0 -32
- package/node_modules/@elench/ts-analysis/src/syntax.mjs +0 -27
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pageLabelFromRoute,
|
|
3
|
+
} from "@elench/next-analysis";
|
|
4
|
+
import {
|
|
5
|
+
dedupeEdges,
|
|
6
|
+
dedupeNodes,
|
|
7
|
+
findMatchingApiRouteEntry,
|
|
8
|
+
hasWord,
|
|
9
|
+
modulePathKey,
|
|
10
|
+
} from "./shared.mjs";
|
|
11
|
+
|
|
12
|
+
export function convertNextAnalysisToGraph({ serviceName, pages = [], apiRoutes = [], serverActions = [], routeTrees = [] }) {
|
|
13
|
+
const nodes = [];
|
|
14
|
+
const edges = [];
|
|
15
|
+
const pageEntries = [];
|
|
16
|
+
const routeEntries = [];
|
|
17
|
+
const actionEntries = [];
|
|
18
|
+
|
|
19
|
+
const routeTreeByRoute = new Map(routeTrees.filter(Boolean).map((entry) => [entry.route, entry]));
|
|
20
|
+
|
|
21
|
+
for (const page of pages) {
|
|
22
|
+
const pageNode = {
|
|
23
|
+
id: `page_view:${serviceName}:${page.route}`,
|
|
24
|
+
kind: "page_view",
|
|
25
|
+
service: serviceName,
|
|
26
|
+
label: pageLabelFromRoute(page.route),
|
|
27
|
+
route: page.route,
|
|
28
|
+
filePath: page.filePath,
|
|
29
|
+
};
|
|
30
|
+
nodes.push(pageNode);
|
|
31
|
+
|
|
32
|
+
const routeTree = routeTreeByRoute.get(page.route);
|
|
33
|
+
const surfacesByTargetValue = new Map();
|
|
34
|
+
if (routeTree) {
|
|
35
|
+
for (const surface of routeTree.surfaces) {
|
|
36
|
+
const surfaceNode = {
|
|
37
|
+
id: `ui_surface:${serviceName}:${page.route}:${surface.targetHint?.value || `${surface.filePath}:${surface.tagName}:${surface.line}`}`,
|
|
38
|
+
kind: "ui_surface",
|
|
39
|
+
service: serviceName,
|
|
40
|
+
label: surface.label,
|
|
41
|
+
route: page.route,
|
|
42
|
+
filePath: surface.filePath,
|
|
43
|
+
...(surface.targetHint ? { target: surface.targetHint } : {}),
|
|
44
|
+
metadata: {
|
|
45
|
+
surfaceKind: surface.surfaceKind,
|
|
46
|
+
tagName: surface.tagName,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
nodes.push(surfaceNode);
|
|
50
|
+
edges.push({
|
|
51
|
+
id: `contains:${pageNode.id}:${surfaceNode.id}`,
|
|
52
|
+
kind: "contains",
|
|
53
|
+
from: pageNode.id,
|
|
54
|
+
to: surfaceNode.id,
|
|
55
|
+
confidence: "high",
|
|
56
|
+
});
|
|
57
|
+
if (surface.targetHint?.kind === "testId") {
|
|
58
|
+
surfacesByTargetValue.set(surface.targetHint.value, surfaceNode);
|
|
59
|
+
}
|
|
60
|
+
if (surface.actionId) {
|
|
61
|
+
const actionKey = stripActionPrefix(surface.actionId, page.route);
|
|
62
|
+
edges.push({
|
|
63
|
+
id: `triggers:${surfaceNode.id}:ui_action:${serviceName}:${page.route}:${actionKey}`,
|
|
64
|
+
kind: "triggers",
|
|
65
|
+
from: surfaceNode.id,
|
|
66
|
+
to: `ui_action:${serviceName}:${page.route}:${actionKey}`,
|
|
67
|
+
confidence: "high",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const action of routeTree.actions) {
|
|
73
|
+
const actionKey = stripActionPrefix(action.id, page.route);
|
|
74
|
+
nodes.push({
|
|
75
|
+
id: `ui_action:${serviceName}:${page.route}:${actionKey}`,
|
|
76
|
+
kind: "ui_action",
|
|
77
|
+
service: serviceName,
|
|
78
|
+
label: action.label,
|
|
79
|
+
route: page.route,
|
|
80
|
+
filePath: action.filePath,
|
|
81
|
+
metadata: {
|
|
82
|
+
bindingKind: action.bindingKind,
|
|
83
|
+
actionProp: action.actionProp,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const request of routeTree.requests) {
|
|
89
|
+
const ownerId = mapRouteTreeOwnerToGraphId(serviceName, page.route, request.ownerId);
|
|
90
|
+
const requestNode = {
|
|
91
|
+
id: `client_request:${serviceName}:${request.filePath}:${request.ownerId}:${request.method}:${request.path}`,
|
|
92
|
+
kind: "client_request",
|
|
93
|
+
service: serviceName,
|
|
94
|
+
label: `${request.method} ${request.path}`,
|
|
95
|
+
method: request.method,
|
|
96
|
+
path: request.path,
|
|
97
|
+
filePath: request.filePath,
|
|
98
|
+
};
|
|
99
|
+
nodes.push(requestNode);
|
|
100
|
+
edges.push({
|
|
101
|
+
id: `requests:${ownerId}:${requestNode.id}`,
|
|
102
|
+
kind: "requests",
|
|
103
|
+
from: ownerId,
|
|
104
|
+
to: requestNode.id,
|
|
105
|
+
confidence: request.confidence,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pageEntries.push({
|
|
110
|
+
node: pageNode,
|
|
111
|
+
route: page.route,
|
|
112
|
+
filePath: page.filePath,
|
|
113
|
+
requests: routeTree.requests.map((request) => ({
|
|
114
|
+
originNodeId: mapRouteTreeOwnerToGraphId(serviceName, page.route, request.ownerId),
|
|
115
|
+
node: {
|
|
116
|
+
id: `client_request:${serviceName}:${request.filePath}:${request.ownerId}:${request.method}:${request.path}`,
|
|
117
|
+
kind: "client_request",
|
|
118
|
+
service: serviceName,
|
|
119
|
+
label: `${request.method} ${request.path}`,
|
|
120
|
+
method: request.method,
|
|
121
|
+
path: request.path,
|
|
122
|
+
filePath: request.filePath,
|
|
123
|
+
},
|
|
124
|
+
method: request.method,
|
|
125
|
+
path: request.path,
|
|
126
|
+
})),
|
|
127
|
+
serverActionRefs: routeTree.serverActionRefs.map((ref) => ({
|
|
128
|
+
originNodeId: mapRouteTreeOwnerToGraphId(serviceName, page.route, ref.ownerId),
|
|
129
|
+
exportKey: ref.exportKey,
|
|
130
|
+
confidence: ref.confidence,
|
|
131
|
+
})),
|
|
132
|
+
surfacesByTargetValue,
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
pageEntries.push({
|
|
136
|
+
node: pageNode,
|
|
137
|
+
route: page.route,
|
|
138
|
+
filePath: page.filePath,
|
|
139
|
+
requests: [],
|
|
140
|
+
serverActionRefs: [],
|
|
141
|
+
surfacesByTargetValue,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const apiRoute of apiRoutes) {
|
|
147
|
+
const node = {
|
|
148
|
+
id: `api_route:${serviceName}:${apiRoute.method}:${apiRoute.requestPath}`,
|
|
149
|
+
kind: "api_route",
|
|
150
|
+
service: serviceName,
|
|
151
|
+
label: `${apiRoute.method} ${apiRoute.requestPath}`,
|
|
152
|
+
route: apiRoute.route,
|
|
153
|
+
method: apiRoute.method,
|
|
154
|
+
path: apiRoute.requestPath,
|
|
155
|
+
filePath: apiRoute.filePath,
|
|
156
|
+
};
|
|
157
|
+
nodes.push(node);
|
|
158
|
+
routeEntries.push({
|
|
159
|
+
node,
|
|
160
|
+
method: apiRoute.method,
|
|
161
|
+
route: apiRoute.route,
|
|
162
|
+
requestPath: apiRoute.requestPath,
|
|
163
|
+
filePath: apiRoute.filePath,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
for (const backendRef of apiRoute.backendRefs || []) {
|
|
167
|
+
const capabilityNode = createServerCapabilityNode(serviceName, backendRef);
|
|
168
|
+
nodes.push(capabilityNode);
|
|
169
|
+
edges.push({
|
|
170
|
+
id: `delegates_to:${node.id}:${capabilityNode.id}`,
|
|
171
|
+
kind: "delegates_to",
|
|
172
|
+
from: node.id,
|
|
173
|
+
to: capabilityNode.id,
|
|
174
|
+
confidence: "high",
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
for (const serverAction of serverActions) {
|
|
180
|
+
const node = {
|
|
181
|
+
id: `server_action:${serviceName}:${serverAction.filePath}#${serverAction.exportName}`,
|
|
182
|
+
kind: "server_action",
|
|
183
|
+
service: serviceName,
|
|
184
|
+
label: serverAction.exportName,
|
|
185
|
+
filePath: serverAction.filePath,
|
|
186
|
+
};
|
|
187
|
+
nodes.push(node);
|
|
188
|
+
actionEntries.push({
|
|
189
|
+
node,
|
|
190
|
+
exportName: serverAction.exportName,
|
|
191
|
+
sourceFile: serverAction.filePath,
|
|
192
|
+
});
|
|
193
|
+
for (const backendRef of serverAction.backendRefs || []) {
|
|
194
|
+
const capabilityNode = createServerCapabilityNode(serviceName, backendRef);
|
|
195
|
+
nodes.push(capabilityNode);
|
|
196
|
+
edges.push({
|
|
197
|
+
id: `delegates_to:${node.id}:${capabilityNode.id}`,
|
|
198
|
+
kind: "delegates_to",
|
|
199
|
+
from: node.id,
|
|
200
|
+
to: capabilityNode.id,
|
|
201
|
+
confidence: "high",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
nodes: dedupeNodes(nodes),
|
|
208
|
+
edges: dedupeEdges(edges),
|
|
209
|
+
pageEntries,
|
|
210
|
+
routeEntries,
|
|
211
|
+
actionEntries,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function mapRouteTreeOwnerToGraphId(serviceName, route, ownerId) {
|
|
216
|
+
if (ownerId === `page:${route}`) return `page_view:${serviceName}:${route}`;
|
|
217
|
+
if (ownerId.startsWith("action:")) {
|
|
218
|
+
return `ui_action:${serviceName}:${route}:${stripActionPrefix(ownerId, route)}`;
|
|
219
|
+
}
|
|
220
|
+
return ownerId;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function stripActionPrefix(actionId, route) {
|
|
224
|
+
const prefix = `action:${route}:`;
|
|
225
|
+
return actionId.startsWith(prefix) ? actionId.slice(prefix.length) : actionId;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function createServerCapabilityNode(serviceName, backendRef) {
|
|
229
|
+
return {
|
|
230
|
+
id: `server_capability:${modulePathKey(backendRef.modulePath)}#${backendRef.exportName}`,
|
|
231
|
+
kind: "server_capability",
|
|
232
|
+
service: serviceName,
|
|
233
|
+
label: backendRef.exportName,
|
|
234
|
+
filePath: backendRef.modulePath || null,
|
|
235
|
+
metadata: {
|
|
236
|
+
specifier: backendRef.specifier,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
package/lib/coverage/routing.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import {
|
|
2
|
+
import { normalizeRouteSegments, toApiRequestPath } from "@elench/next-analysis";
|
|
3
|
+
import { normalizePath } from "./shared.mjs";
|
|
3
4
|
|
|
4
5
|
export function inferPageRouteFromTestFile(filePath, nextAppRoot, serviceRoot) {
|
|
5
6
|
const appRelativeSegments = extractRouteOwnerSegments(filePath, nextAppRoot, serviceRoot);
|
|
@@ -47,38 +48,10 @@ export function extractRouteOwnerSegments(filePath, nextAppRoot, serviceRoot) {
|
|
|
47
48
|
return segments.slice(0, testkitIndex);
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
export function routeFromAppFile(nextAppRoot, filePath) {
|
|
51
|
-
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(nextAppRoot, filePath);
|
|
52
|
-
const relative = normalizePath(path.relative(nextAppRoot, absolutePath));
|
|
53
|
-
const segments = relative.split("/");
|
|
54
|
-
segments.pop();
|
|
55
|
-
return normalizeRouteSegments(segments);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function routeFromApiFile(nextAppRoot, filePath) {
|
|
59
|
-
const appRelative = normalizePath(path.relative(nextAppRoot, path.dirname(filePath)));
|
|
60
|
-
const segments = appRelative.split("/").filter(Boolean);
|
|
61
|
-
if (segments[0] === "api") segments.shift();
|
|
62
|
-
return normalizeRouteSegments(segments);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function normalizeRouteSegments(segments) {
|
|
66
|
-
const normalizedSegments = segments
|
|
67
|
-
.filter(Boolean)
|
|
68
|
-
.filter((segment) => !segment.startsWith("(") || !segment.endsWith(")"))
|
|
69
|
-
.filter((segment) => !segment.startsWith("@"))
|
|
70
|
-
.filter((segment) => segment !== "page" && segment !== "route");
|
|
71
|
-
return normalizeRoute(`/${normalizedSegments.join("/")}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
51
|
export function apiRouteLookupKey(method, route) {
|
|
75
52
|
return `${method}:${route}`;
|
|
76
53
|
}
|
|
77
54
|
|
|
78
|
-
export function toApiRequestPath(route) {
|
|
79
|
-
return normalizeRoute(`/api${route === "/" ? "" : route}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
55
|
export function toSelectionType(type, framework) {
|
|
83
56
|
if (framework === "playwright") return "pw";
|
|
84
57
|
if (type === "integration") return "int";
|
|
@@ -4,19 +4,10 @@ import {
|
|
|
4
4
|
inferApiRoutesFromTestFile,
|
|
5
5
|
inferOwnerDirectoryFromTestFile,
|
|
6
6
|
inferPageRouteFromTestFile,
|
|
7
|
-
normalizeRouteSegments,
|
|
8
7
|
pathMatchesOwner,
|
|
9
|
-
routeFromApiFile,
|
|
10
|
-
routeFromAppFile,
|
|
11
8
|
} from "./routing.mjs";
|
|
12
9
|
|
|
13
10
|
describe("coverage routing helpers", () => {
|
|
14
|
-
it("normalizes route segments by stripping route groups and slots", () => {
|
|
15
|
-
expect(normalizeRouteSegments(["(marketing)", "@modal", "campaigns", "[campaignId]", "page"])).toBe(
|
|
16
|
-
"/campaigns/[campaignId]"
|
|
17
|
-
);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
11
|
it("infers page ownership routes from colocated __testkit__ files", () => {
|
|
21
12
|
const serviceRoot = "/repo";
|
|
22
13
|
const nextAppRoot = path.join(serviceRoot, "src", "app");
|
|
@@ -35,13 +26,6 @@ describe("coverage routing helpers", () => {
|
|
|
35
26
|
).toEqual(["/campaigns"]);
|
|
36
27
|
});
|
|
37
28
|
|
|
38
|
-
it("derives page and API routes from Next app file paths", () => {
|
|
39
|
-
const nextAppRoot = "/repo/src/app";
|
|
40
|
-
|
|
41
|
-
expect(routeFromAppFile(nextAppRoot, "/repo/src/app/settings/page.tsx")).toBe("/settings");
|
|
42
|
-
expect(routeFromApiFile(nextAppRoot, "/repo/src/app/api/campaigns/route.ts")).toBe("/campaigns");
|
|
43
|
-
});
|
|
44
|
-
|
|
45
29
|
it("matches nested ownership directories for DAL evidence", () => {
|
|
46
30
|
expect(inferOwnerDirectoryFromTestFile("src/backend/data/campaigns/__testkit__/save.dal.testkit.ts")).toBe(
|
|
47
31
|
"src/backend/data/campaigns"
|
package/lib/coverage/shared.mjs
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { TESTKIT_COVERAGE_GRAPH_VERSION } from "@elench/testkit-protocol";
|
|
3
|
+
import {
|
|
4
|
+
DYNAMIC_SEGMENT_TOKEN,
|
|
5
|
+
HTTP_METHODS,
|
|
6
|
+
isBackendSpecifier,
|
|
7
|
+
isDataSpecifier,
|
|
8
|
+
modulePathKey,
|
|
9
|
+
normalizePath,
|
|
10
|
+
normalizeRoute,
|
|
11
|
+
pageLabelFromRoute,
|
|
12
|
+
toApiRequestPath,
|
|
13
|
+
} from "@elench/next-analysis";
|
|
14
|
+
export {
|
|
15
|
+
DYNAMIC_SEGMENT_TOKEN,
|
|
16
|
+
HTTP_METHODS,
|
|
17
|
+
isBackendSpecifier,
|
|
18
|
+
isDataSpecifier,
|
|
19
|
+
modulePathKey,
|
|
20
|
+
normalizePath,
|
|
21
|
+
normalizeRoute,
|
|
22
|
+
pageLabelFromRoute,
|
|
23
|
+
toApiRequestPath,
|
|
24
|
+
};
|
|
3
25
|
|
|
4
|
-
export const HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
5
26
|
export const HTTP_WRAPPER_METHODS = {
|
|
6
27
|
getJson: "GET",
|
|
7
28
|
postJson: "POST",
|
|
@@ -9,7 +30,6 @@ export const HTTP_WRAPPER_METHODS = {
|
|
|
9
30
|
patchJson: "PATCH",
|
|
10
31
|
deleteJson: "DELETE",
|
|
11
32
|
};
|
|
12
|
-
export const DYNAMIC_SEGMENT_TOKEN = "__TESTKIT_DYNAMIC_SEGMENT__";
|
|
13
33
|
|
|
14
34
|
export function createEmptyGraph() {
|
|
15
35
|
return {
|
|
@@ -59,51 +79,12 @@ export function apiRouteLookupKey(method, route) {
|
|
|
59
79
|
return `${method}:${route}`;
|
|
60
80
|
}
|
|
61
81
|
|
|
62
|
-
export function toApiRequestPath(route) {
|
|
63
|
-
return normalizeRoute(`/api${route === "/" ? "" : route}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
82
|
export function toSelectionType(type, framework) {
|
|
67
83
|
if (framework === "playwright") return "pw";
|
|
68
84
|
if (type === "integration") return "int";
|
|
69
85
|
return type;
|
|
70
86
|
}
|
|
71
87
|
|
|
72
|
-
export function pageLabelFromRoute(route) {
|
|
73
|
-
if (route === "/") return "Home";
|
|
74
|
-
return route
|
|
75
|
-
.split("/")
|
|
76
|
-
.filter(Boolean)
|
|
77
|
-
.map((segment) => {
|
|
78
|
-
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
79
|
-
return segment.slice(1, -1);
|
|
80
|
-
}
|
|
81
|
-
return segment;
|
|
82
|
-
})
|
|
83
|
-
.map((segment) => segment.replace(/[-_]+/gu, " "))
|
|
84
|
-
.map((segment) => segment.replace(/^\w/u, (char) => char.toUpperCase()))
|
|
85
|
-
.join(" ");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function normalizeRoute(value) {
|
|
89
|
-
const trimmed = String(value || "/").trim();
|
|
90
|
-
if (!trimmed || trimmed === "/") return "/";
|
|
91
|
-
const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
92
|
-
return withLeadingSlash.length > 1 ? withLeadingSlash.replace(/\/+$/u, "") : withLeadingSlash;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function normalizePath(filePath) {
|
|
96
|
-
return filePath.split(path.sep).join("/");
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function modulePathKey(filePath) {
|
|
100
|
-
const normalized = normalizePath(filePath);
|
|
101
|
-
const ext = path.extname(normalized);
|
|
102
|
-
if (path.basename(normalized, ext) === "index") {
|
|
103
|
-
return normalizePath(path.dirname(normalized));
|
|
104
|
-
}
|
|
105
|
-
return normalized.slice(0, normalized.length - ext.length);
|
|
106
|
-
}
|
|
107
88
|
|
|
108
89
|
export function escapeRegExp(value) {
|
|
109
90
|
return String(value).replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
@@ -114,27 +95,6 @@ export function isServerActionFile(content) {
|
|
|
114
95
|
return trimmed.startsWith('"use server"') || trimmed.startsWith("'use server'");
|
|
115
96
|
}
|
|
116
97
|
|
|
117
|
-
export function isBackendSpecifier(specifier) {
|
|
118
|
-
return (
|
|
119
|
-
specifier.startsWith("@/backend/server/") ||
|
|
120
|
-
specifier.includes("/backend/server/") ||
|
|
121
|
-
specifier.startsWith("./backend/server/") ||
|
|
122
|
-
specifier.startsWith("../backend/server/")
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function isDataSpecifier(specifier) {
|
|
127
|
-
return (
|
|
128
|
-
specifier.startsWith("@/backend/data/") ||
|
|
129
|
-
specifier.startsWith("@/backend/dal/") ||
|
|
130
|
-
specifier.includes("/backend/data/") ||
|
|
131
|
-
specifier.includes("/backend/dal/") ||
|
|
132
|
-
specifier.includes("/db/") ||
|
|
133
|
-
specifier.includes("/repository/") ||
|
|
134
|
-
specifier.includes("/repositories/")
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
98
|
export function hasWord(content, word) {
|
|
139
99
|
if (!content || !word) return false;
|
|
140
100
|
return new RegExp(`\\b${escapeRegExp(word)}\\b`, "u").test(content);
|
|
@@ -178,26 +138,6 @@ export function dedupeTargets(targets) {
|
|
|
178
138
|
});
|
|
179
139
|
}
|
|
180
140
|
|
|
181
|
-
export function dedupeBackendImports(entries) {
|
|
182
|
-
const seen = new Set();
|
|
183
|
-
return entries.filter((entry) => {
|
|
184
|
-
const key = `${entry.importName}:${entry.node.filePath || ""}:${entry.node.label}`;
|
|
185
|
-
if (seen.has(key)) return false;
|
|
186
|
-
seen.add(key);
|
|
187
|
-
return true;
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export function dedupeDataImports(entries) {
|
|
192
|
-
const seen = new Set();
|
|
193
|
-
return entries.filter((entry) => {
|
|
194
|
-
const key = `${entry.importName}:${entry.node.filePath || ""}:${entry.node.label}`;
|
|
195
|
-
if (seen.has(key)) return false;
|
|
196
|
-
seen.add(key);
|
|
197
|
-
return true;
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
141
|
export function findMatchingApiRouteEntry(method, candidatePath, routeEntries = []) {
|
|
202
142
|
const normalizedMethod = String(method || "").trim().toUpperCase();
|
|
203
143
|
const normalizedCandidate = normalizeRequestPathCandidate(candidatePath);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { resolveServiceCwd } from "../config/
|
|
4
|
+
import { resolveServiceCwd } from "../config/paths.mjs";
|
|
5
5
|
import { collectTemplateInputs } from "./template-steps.mjs";
|
|
6
6
|
|
|
7
7
|
const LOCAL_IMAGE = "pgvector/pgvector:pg16";
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
export function loadIssueCache(productDir, cachePath, schemaVersion) {
|
|
5
|
+
const filePath = path.join(productDir, ...cachePath);
|
|
6
|
+
if (!fs.existsSync(filePath)) {
|
|
7
|
+
return {
|
|
8
|
+
schemaVersion,
|
|
9
|
+
entries: {},
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
15
|
+
if (parsed?.schemaVersion !== schemaVersion || typeof parsed.entries !== "object") {
|
|
16
|
+
return {
|
|
17
|
+
schemaVersion,
|
|
18
|
+
entries: {},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return parsed;
|
|
22
|
+
} catch {
|
|
23
|
+
return {
|
|
24
|
+
schemaVersion,
|
|
25
|
+
entries: {},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function resolveIssueCache(cache, issueNumbersByRepo, config, now) {
|
|
31
|
+
const issuesByRepo = new Map();
|
|
32
|
+
const missingByRepo = new Map();
|
|
33
|
+
const staleByRepo = new Map();
|
|
34
|
+
const ttlMs = config.cacheTtlSeconds * 1000;
|
|
35
|
+
|
|
36
|
+
for (const [repo, numbers] of issueNumbersByRepo.entries()) {
|
|
37
|
+
const cachedIssues = new Map();
|
|
38
|
+
const missing = [];
|
|
39
|
+
const stale = [];
|
|
40
|
+
|
|
41
|
+
for (const number of numbers) {
|
|
42
|
+
const key = buildIssueCacheKey(repo, number);
|
|
43
|
+
const cached = cache.entries[key];
|
|
44
|
+
if (!cached) {
|
|
45
|
+
missing.push(number);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const checkedAt = Date.parse(cached.checkedAt);
|
|
50
|
+
const normalized = {
|
|
51
|
+
repo,
|
|
52
|
+
number,
|
|
53
|
+
exists: Boolean(cached.exists),
|
|
54
|
+
title: normalizeOptionalString(cached.title),
|
|
55
|
+
state: normalizeOptionalString(cached.state),
|
|
56
|
+
url: normalizeOptionalString(cached.url),
|
|
57
|
+
checkedAt: cached.checkedAt || null,
|
|
58
|
+
source: "cache",
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (!Number.isFinite(checkedAt) || now - checkedAt > ttlMs) {
|
|
62
|
+
stale.push(number);
|
|
63
|
+
cachedIssues.set(number, normalized);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
cachedIssues.set(number, normalized);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
issuesByRepo.set(repo, cachedIssues);
|
|
71
|
+
if (missing.length > 0 || stale.length > 0) {
|
|
72
|
+
missingByRepo.set(repo, [...new Set([...missing, ...stale])].sort((a, b) => a - b));
|
|
73
|
+
}
|
|
74
|
+
if (stale.length > 0) {
|
|
75
|
+
staleByRepo.set(repo, stale.sort((a, b) => a - b));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
issuesByRepo,
|
|
81
|
+
missingByRepo,
|
|
82
|
+
staleByRepo,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function updateIssueCache(cache, issuesByRepo, now, schemaVersion) {
|
|
87
|
+
cache.schemaVersion = schemaVersion;
|
|
88
|
+
cache.entries = cache.entries || {};
|
|
89
|
+
const checkedAt = new Date(now).toISOString();
|
|
90
|
+
|
|
91
|
+
for (const [repo, issues] of issuesByRepo.entries()) {
|
|
92
|
+
for (const [number, issue] of issues.entries()) {
|
|
93
|
+
issue.checkedAt = checkedAt;
|
|
94
|
+
cache.entries[buildIssueCacheKey(repo, number)] = {
|
|
95
|
+
exists: issue.exists,
|
|
96
|
+
title: issue.title,
|
|
97
|
+
state: issue.state,
|
|
98
|
+
url: issue.url,
|
|
99
|
+
checkedAt,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function writeIssueCache(productDir, cachePath, cache) {
|
|
106
|
+
const filePath = path.join(productDir, ...cachePath);
|
|
107
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
108
|
+
fs.writeFileSync(filePath, `${JSON.stringify(cache, null, 2)}\n`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function applyStaleCacheFallback(issuesByRepo, staleByRepo, findings) {
|
|
112
|
+
let usedStale = false;
|
|
113
|
+
for (const [repo, numbers] of staleByRepo.entries()) {
|
|
114
|
+
const issues = issuesByRepo.get(repo);
|
|
115
|
+
if (!issues) continue;
|
|
116
|
+
for (const number of numbers) {
|
|
117
|
+
if (issues.has(number)) {
|
|
118
|
+
usedStale = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (usedStale) {
|
|
123
|
+
findings.push({
|
|
124
|
+
code: "used_stale_cache",
|
|
125
|
+
severity: "warning",
|
|
126
|
+
message: "Used stale cached GitHub issue metadata because fresh validation failed",
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return issuesByRepo;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function mergeIssuesByRepo(left, right) {
|
|
133
|
+
const merged = new Map();
|
|
134
|
+
for (const [repo, issues] of left.entries()) {
|
|
135
|
+
merged.set(repo, new Map(issues.entries()));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (const [repo, issues] of right.entries()) {
|
|
139
|
+
if (!merged.has(repo)) {
|
|
140
|
+
merged.set(repo, new Map());
|
|
141
|
+
}
|
|
142
|
+
const mergedIssues = merged.get(repo);
|
|
143
|
+
for (const [number, issue] of issues.entries()) {
|
|
144
|
+
mergedIssues.set(number, issue);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return merged;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function buildIssueCacheKey(repo, number) {
|
|
152
|
+
return `${repo}#${number}`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function normalizeOptionalString(value) {
|
|
156
|
+
if (typeof value !== "string") return null;
|
|
157
|
+
const normalized = value.trim();
|
|
158
|
+
return normalized.length > 0 ? normalized : null;
|
|
159
|
+
}
|