@elench/testkit 0.1.65 → 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/graph-builder.mjs +5 -5
- package/lib/coverage/next-ir-to-graph.mjs +0 -1
- 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 +15 -2
- 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/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 +12 -9
- package/lib/coverage/fs-walk.mjs +0 -64
- package/node_modules/@elench/next-analysis/src/api-routes.mjs +0 -81
- package/node_modules/@elench/next-analysis/src/api-routes.test.mjs +0 -22
- package/node_modules/@elench/next-analysis/src/app-root.mjs +0 -7
- package/node_modules/@elench/next-analysis/src/backend-links.mjs +0 -31
- package/node_modules/@elench/next-analysis/src/index.mjs +0 -21
- package/node_modules/@elench/next-analysis/src/pages.mjs +0 -68
- package/node_modules/@elench/next-analysis/src/project.mjs +0 -94
- package/node_modules/@elench/next-analysis/src/project.test.mjs +0 -35
- package/node_modules/@elench/next-analysis/src/route-tree.mjs +0 -621
- package/node_modules/@elench/next-analysis/src/routes.mjs +0 -41
- package/node_modules/@elench/next-analysis/src/routes.test.mjs +0 -25
- package/node_modules/@elench/next-analysis/src/server-actions.mjs +0 -53
- package/node_modules/@elench/next-analysis/src/server-actions.test.mjs +0 -37
- package/node_modules/@elench/next-analysis/src/shared.mjs +0 -209
- package/node_modules/@elench/next-analysis/src/swc.mjs +0 -388
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ensureExistingPath
|
|
2
|
-
import {
|
|
1
|
+
import { ensureExistingPath } from "./paths.mjs";
|
|
2
|
+
import { validateConfiguredCollection } from "../shared/configured-steps.mjs";
|
|
3
3
|
|
|
4
4
|
export function validateConfigCoverage(configs) {
|
|
5
5
|
const names = new Set(configs.map((config) => config.name));
|
|
@@ -60,65 +60,21 @@ export function validateServiceConfig({
|
|
|
60
60
|
}
|
|
61
61
|
for (const [stageName, steps] of Object.entries(database?.template || {})) {
|
|
62
62
|
if (stageName === "inputs") continue;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
ensureExistingPath(
|
|
69
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
70
|
-
step.path,
|
|
71
|
-
`Service "${name}" database.template.${stageName} sql file`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
if (step.kind === "module") {
|
|
75
|
-
const { modulePath } = parseModuleSpecifier(step.specifier);
|
|
76
|
-
ensureExistingPath(
|
|
77
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
78
|
-
modulePath,
|
|
79
|
-
`Service "${name}" database.template.${stageName} module`
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
for (const input of step.inputs || []) {
|
|
83
|
-
ensureExistingPath(
|
|
84
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
85
|
-
input,
|
|
86
|
-
`Service "${name}" database.template.${stageName} step input`
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
for (const input of database?.template?.inputs || []) {
|
|
92
|
-
ensureExistingPath(productDir, input, `Service "${name}" database.template input`);
|
|
93
|
-
}
|
|
94
|
-
for (const step of runtime.prepare?.steps || []) {
|
|
95
|
-
if (step.cwd) {
|
|
96
|
-
ensureExistingPath(productDir, step.cwd, `Service "${name}" runtime.prepare step cwd`);
|
|
97
|
-
}
|
|
98
|
-
if (step.kind === "sql-file") {
|
|
99
|
-
ensureExistingPath(
|
|
100
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
101
|
-
step.path,
|
|
102
|
-
`Service "${name}" runtime.prepare sql file`
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
if (step.kind === "module") {
|
|
106
|
-
const { modulePath } = parseModuleSpecifier(step.specifier);
|
|
107
|
-
ensureExistingPath(
|
|
108
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
109
|
-
modulePath,
|
|
110
|
-
`Service "${name}" runtime.prepare module`
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
for (const input of step.inputs || []) {
|
|
114
|
-
ensureExistingPath(
|
|
115
|
-
resolveServiceCwd(productDir, step.cwd || "."),
|
|
116
|
-
input,
|
|
117
|
-
`Service "${name}" runtime.prepare step input`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
for (const input of runtime.prepare?.inputs || []) {
|
|
122
|
-
ensureExistingPath(productDir, input, `Service "${name}" runtime.prepare input`);
|
|
63
|
+
validateConfiguredCollection({
|
|
64
|
+
productDir,
|
|
65
|
+
label: `Service "${name}" database.template.${stageName}`,
|
|
66
|
+
steps,
|
|
67
|
+
});
|
|
123
68
|
}
|
|
69
|
+
validateConfiguredCollection({
|
|
70
|
+
productDir,
|
|
71
|
+
label: `Service "${name}" database.template`,
|
|
72
|
+
inputs: database?.template?.inputs || [],
|
|
73
|
+
});
|
|
74
|
+
validateConfiguredCollection({
|
|
75
|
+
productDir,
|
|
76
|
+
label: `Service "${name}" runtime.prepare`,
|
|
77
|
+
inputs: runtime.prepare?.inputs || [],
|
|
78
|
+
steps: runtime.prepare?.steps || [],
|
|
79
|
+
});
|
|
124
80
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import {
|
|
4
|
+
collectImports,
|
|
5
|
+
createSourceFile,
|
|
4
6
|
extractExportedFunctionBody,
|
|
5
|
-
|
|
6
|
-
extractExportedMethodBodies,
|
|
7
|
+
resolveImportToSourceFile,
|
|
7
8
|
} from "@elench/ts-analysis";
|
|
8
9
|
import {
|
|
9
|
-
dedupeBackendImports,
|
|
10
|
-
dedupeDataImports,
|
|
11
10
|
dedupeEdges,
|
|
12
11
|
dedupeNodes,
|
|
13
12
|
hasWord,
|
|
@@ -15,7 +14,6 @@ import {
|
|
|
15
14
|
isDataSpecifier,
|
|
16
15
|
modulePathKey,
|
|
17
16
|
} from "./shared.mjs";
|
|
18
|
-
import { resolveImportToSourceFile } from "./fs-walk.mjs";
|
|
19
17
|
|
|
20
18
|
export function extractBackendImports({
|
|
21
19
|
serviceName,
|
|
@@ -26,34 +24,15 @@ export function extractBackendImports({
|
|
|
26
24
|
resolveImportToSourceFile: resolveImportAlias,
|
|
27
25
|
}) {
|
|
28
26
|
const resolveImportFn = resolveImportAlias || resolveImport;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!isBackendSpecifier(specifier)) continue;
|
|
39
|
-
const resolvedFilePath = resolveImportFn(serviceRoot, filePath, specifier);
|
|
40
|
-
for (const importName of rawNames) {
|
|
41
|
-
imports.push({
|
|
42
|
-
importName,
|
|
43
|
-
node: {
|
|
44
|
-
id: `server_capability:${modulePathKey(resolvedFilePath || filePath)}#${importName}`,
|
|
45
|
-
kind: "server_capability",
|
|
46
|
-
service: serviceName,
|
|
47
|
-
label: importName,
|
|
48
|
-
filePath: resolvedFilePath || null,
|
|
49
|
-
metadata: {
|
|
50
|
-
specifier,
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return dedupeBackendImports(imports);
|
|
27
|
+
return collectCapabilityImports({
|
|
28
|
+
serviceName,
|
|
29
|
+
serviceRoot,
|
|
30
|
+
filePath,
|
|
31
|
+
content,
|
|
32
|
+
resolveImportFn,
|
|
33
|
+
matchesSpecifier: isBackendSpecifier,
|
|
34
|
+
kind: "server_capability",
|
|
35
|
+
});
|
|
57
36
|
}
|
|
58
37
|
|
|
59
38
|
export function discoverDataCapabilities({ serviceName, serviceRoot, nodes, readFile = defaultReadFile }) {
|
|
@@ -97,63 +76,67 @@ export function extractDataImports({
|
|
|
97
76
|
resolveImportToSourceFile: resolveImportAlias,
|
|
98
77
|
}) {
|
|
99
78
|
const resolveImportFn = resolveImportAlias || resolveImport;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (!isDataSpecifier(specifier)) continue;
|
|
110
|
-
const resolvedFilePath = resolveImportFn(serviceRoot, filePath, specifier);
|
|
111
|
-
for (const importName of rawNames) {
|
|
112
|
-
imports.push({
|
|
113
|
-
importName,
|
|
114
|
-
node: {
|
|
115
|
-
id: `data_capability:${modulePathKey(resolvedFilePath || filePath)}#${importName}`,
|
|
116
|
-
kind: "data_capability",
|
|
117
|
-
service: serviceName,
|
|
118
|
-
label: importName,
|
|
119
|
-
filePath: resolvedFilePath || null,
|
|
120
|
-
metadata: {
|
|
121
|
-
specifier,
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return dedupeDataImports(imports);
|
|
79
|
+
return collectCapabilityImports({
|
|
80
|
+
serviceName,
|
|
81
|
+
serviceRoot,
|
|
82
|
+
filePath,
|
|
83
|
+
content,
|
|
84
|
+
resolveImportFn,
|
|
85
|
+
matchesSpecifier: isDataSpecifier,
|
|
86
|
+
kind: "data_capability",
|
|
87
|
+
});
|
|
128
88
|
}
|
|
129
89
|
|
|
130
|
-
|
|
90
|
+
function defaultReadFile(filePath) {
|
|
91
|
+
if (!fs.existsSync(filePath)) return null;
|
|
92
|
+
return fs.readFileSync(filePath, "utf8");
|
|
93
|
+
}
|
|
131
94
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
95
|
+
function collectCapabilityImports({
|
|
96
|
+
serviceName,
|
|
97
|
+
serviceRoot,
|
|
98
|
+
filePath,
|
|
99
|
+
content,
|
|
100
|
+
resolveImportFn,
|
|
101
|
+
matchesSpecifier,
|
|
102
|
+
kind,
|
|
103
|
+
}) {
|
|
104
|
+
const sourceFile = createSourceFile(filePath, content);
|
|
105
|
+
const imports = collectImports(sourceFile, {
|
|
106
|
+
resolveImportPath: (specifier) => resolveImportFn(serviceRoot, filePath, specifier),
|
|
107
|
+
readSourceFile: () => null,
|
|
108
|
+
isServerActionFile: () => false,
|
|
109
|
+
});
|
|
137
110
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
111
|
+
const collected = [];
|
|
112
|
+
for (const [localName, imported] of imports.entries()) {
|
|
113
|
+
if (!matchesSpecifier(imported.specifier)) continue;
|
|
114
|
+
const exportName = imported.importedName === "default" ? localName : imported.importedName;
|
|
115
|
+
collected.push({
|
|
116
|
+
importName: localName,
|
|
117
|
+
node: {
|
|
118
|
+
id: `${kind}:${modulePathKey(imported.resolvedFilePath || filePath)}#${exportName}`,
|
|
119
|
+
kind,
|
|
120
|
+
service: serviceName,
|
|
121
|
+
label: exportName,
|
|
122
|
+
filePath: imported.resolvedFilePath || null,
|
|
123
|
+
metadata: {
|
|
124
|
+
specifier: imported.specifier,
|
|
125
|
+
localName,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
152
129
|
}
|
|
153
|
-
|
|
130
|
+
|
|
131
|
+
return dedupeCapabilityImports(collected);
|
|
154
132
|
}
|
|
155
133
|
|
|
156
|
-
function
|
|
157
|
-
|
|
158
|
-
return
|
|
134
|
+
function dedupeCapabilityImports(entries) {
|
|
135
|
+
const seen = new Set();
|
|
136
|
+
return entries.filter((entry) => {
|
|
137
|
+
const key = `${entry.importName}:${entry.node.id}:${entry.node.filePath || ""}`;
|
|
138
|
+
if (seen.has(key)) return false;
|
|
139
|
+
seen.add(key);
|
|
140
|
+
return true;
|
|
141
|
+
});
|
|
159
142
|
}
|
|
@@ -1,52 +1,61 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
import { extractBackendImports, extractDataImports } from "./backend-discovery.mjs";
|
|
3
|
+
|
|
4
|
+
describe("coverage backend discovery", () => {
|
|
5
|
+
it("tracks local import names while anchoring capabilities to exported names", () => {
|
|
6
|
+
const content = [
|
|
7
|
+
'import { saveSettings as persistSettings } from "@/backend/server/settings";',
|
|
8
|
+
'import { loadProjects as fetchProjects } from "@/backend/data/projects";',
|
|
9
|
+
].join("\n");
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
extractBackendImports({
|
|
13
|
+
serviceName: "web",
|
|
14
|
+
serviceRoot: "/repo",
|
|
15
|
+
filePath: "src/app/settings/actions.ts",
|
|
16
|
+
content,
|
|
17
|
+
resolveImport: () => "src/backend/server/settings.ts",
|
|
18
|
+
})
|
|
19
|
+
).toEqual([
|
|
20
|
+
{
|
|
21
|
+
importName: "persistSettings",
|
|
22
|
+
node: {
|
|
23
|
+
id: "server_capability:src/backend/server/settings#saveSettings",
|
|
24
|
+
kind: "server_capability",
|
|
25
|
+
service: "web",
|
|
26
|
+
label: "saveSettings",
|
|
27
|
+
filePath: "src/backend/server/settings.ts",
|
|
28
|
+
metadata: {
|
|
29
|
+
specifier: "@/backend/server/settings",
|
|
30
|
+
localName: "persistSettings",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
25
34
|
]);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("extracts named exported functions and their bodies", () => {
|
|
29
|
-
const content = `
|
|
30
|
-
export async function saveSettings() {
|
|
31
|
-
return updateSettings();
|
|
32
|
-
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
expect(
|
|
37
|
+
extractDataImports({
|
|
38
|
+
serviceName: "web",
|
|
39
|
+
serviceRoot: "/repo",
|
|
40
|
+
filePath: "src/backend/server/settings.ts",
|
|
41
|
+
content,
|
|
42
|
+
resolveImport: () => "src/backend/data/projects.ts",
|
|
43
|
+
})
|
|
44
|
+
).toEqual([
|
|
45
|
+
{
|
|
46
|
+
importName: "fetchProjects",
|
|
47
|
+
node: {
|
|
48
|
+
id: "data_capability:src/backend/data/projects#loadProjects",
|
|
49
|
+
kind: "data_capability",
|
|
50
|
+
service: "web",
|
|
51
|
+
label: "loadProjects",
|
|
52
|
+
filePath: "src/backend/data/projects.ts",
|
|
53
|
+
metadata: {
|
|
54
|
+
specifier: "@/backend/data/projects",
|
|
55
|
+
localName: "fetchProjects",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
42
59
|
]);
|
|
43
|
-
expect(extractExportedFunctionBody(content, "saveSettings")).toContain("updateSettings");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("reads a balanced block from a brace offset", () => {
|
|
47
|
-
const content = `before { const tpl = \`{nested}\`; return tpl; } after`;
|
|
48
|
-
const startIndex = content.indexOf("{");
|
|
49
|
-
|
|
50
|
-
expect(readBalancedBlock(content, startIndex)).toBe("{ const tpl = `{nested}`; return tpl; }");
|
|
51
60
|
});
|
|
52
61
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { discoverDataCapabilities } from "./backend-discovery.mjs";
|
|
2
2
|
import { buildEvidenceDetails, inferCoveredNodeIdsForTest } from "./evidence.mjs";
|
|
3
|
-
import { resolveServiceRoot } from "./fs-walk.mjs";
|
|
4
3
|
import { convertNextAnalysisToGraph } from "./next-ir-to-graph.mjs";
|
|
5
4
|
import {
|
|
6
5
|
appendGraph,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
toSelectionType,
|
|
12
11
|
} from "./shared.mjs";
|
|
13
12
|
import { DEFAULT_DISCOVERY_EXCLUDES, normalizeDiscoveryConfig } from "../discovery/path-policy.mjs";
|
|
13
|
+
import { resolveServiceCwd } from "../config/paths.mjs";
|
|
14
14
|
import { createNextAnalysisProject } from "@elench/next-analysis";
|
|
15
15
|
|
|
16
16
|
export function buildCoverageGraph({ productDir, repoDiscovery = {}, services = {}, discoveryFiles = [] }) {
|
|
@@ -85,10 +85,7 @@ export function buildCoverageGraph({ productDir, repoDiscovery = {}, services =
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
export function buildServiceCoverageContext(productDir, serviceName, config, repoDiscovery = {}) {
|
|
88
|
-
const serviceRoot =
|
|
89
|
-
const nextProject = createNextAnalysisProject({ rootDir: serviceRoot });
|
|
90
|
-
const nextAppRoot = nextProject.findAppRoot();
|
|
91
|
-
if (!nextAppRoot) return null;
|
|
88
|
+
const serviceRoot = resolveServiceCwd(productDir, config?.local?.cwd || ".");
|
|
92
89
|
const serviceDiscovery = normalizeDiscoveryConfig(config?.discovery, { allowRoots: true });
|
|
93
90
|
const exclude = [
|
|
94
91
|
...new Set([
|
|
@@ -97,6 +94,9 @@ export function buildServiceCoverageContext(productDir, serviceName, config, rep
|
|
|
97
94
|
...((serviceDiscovery.exclude || []).map(normalizePath)),
|
|
98
95
|
]),
|
|
99
96
|
];
|
|
97
|
+
const nextProject = createNextAnalysisProject({ rootDir: serviceRoot, exclude });
|
|
98
|
+
const nextAppRoot = nextProject.findAppRoot();
|
|
99
|
+
if (!nextAppRoot) return null;
|
|
100
100
|
|
|
101
101
|
const graph = createEmptyGraph();
|
|
102
102
|
const pages = nextProject.discoverPages();
|
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";
|