@hyperfrontend/project-scope 0.2.1 → 0.2.2
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/CHANGELOG.md +7 -1
- package/README.md +3 -4
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js +7 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js +5 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.cjs.js +13 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.esm.js +8 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.cjs.js +10 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.esm.js +8 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js +6 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js +5 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js +7 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.esm.js +5 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js +6 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js +5 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js +9 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js +6 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.cjs.js +7 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.esm.js +7 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js +15 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js +9 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js +6 -0
- package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js +5 -0
- package/_dependencies/@hyperfrontend/logging/index.cjs.js +191 -0
- package/_dependencies/@hyperfrontend/logging/index.d.ts +151 -0
- package/_dependencies/@hyperfrontend/logging/index.esm.js +186 -0
- package/_shared/core/cache/index.cjs.js +135 -0
- package/_shared/core/cache/index.esm.js +128 -0
- package/_shared/core/errors/structured-errors/index.cjs.js +28 -0
- package/_shared/core/errors/structured-errors/index.esm.js +23 -0
- package/_shared/core/fs/stat/index.cjs.js +46 -0
- package/_shared/core/fs/stat/index.esm.js +40 -0
- package/_shared/core/path/join/index.cjs.js +13 -0
- package/_shared/core/path/join/index.esm.js +10 -0
- package/_shared/core/path/normalize/index.cjs.js +37 -0
- package/_shared/core/path/normalize/index.esm.js +31 -0
- package/_shared/core/path/resolve/index.cjs.js +47 -0
- package/_shared/core/path/resolve/index.esm.js +41 -0
- package/_shared/core/path/segments/index.cjs.js +38 -0
- package/_shared/core/path/segments/index.esm.js +31 -0
- package/_shared/core/patterns/glob/index.cjs.js +145 -0
- package/_shared/core/patterns/glob/index.esm.js +136 -0
- package/_shared/core/platform/detect/index.cjs.js +103 -0
- package/_shared/core/platform/detect/index.esm.js +95 -0
- package/_shared/core/platform/line-endings/index.cjs.js +52 -0
- package/_shared/core/platform/line-endings/index.esm.js +44 -0
- package/_shared/project/config/patterns/index.cjs.js +172 -0
- package/_shared/project/config/patterns/index.esm.js +169 -0
- package/_shared/tech/monorepo/pnpm-workspaces/index.cjs.js +33 -0
- package/_shared/tech/monorepo/pnpm-workspaces/index.esm.js +31 -0
- package/_shared/tech/shared-utils/detector-helpers/index.cjs.js +48 -0
- package/_shared/tech/shared-utils/detector-helpers/index.esm.js +43 -0
- package/_shared/vfs/types/index.cjs.js +14 -0
- package/_shared/vfs/types/index.esm.js +12 -0
- package/cli/index.cjs.js +1702 -1910
- package/cli/index.d.ts +273 -7
- package/cli/index.d.ts.map +1 -1
- package/cli/index.esm.js +1586 -1794
- package/core/encoding/index.cjs.js +86 -401
- package/core/encoding/index.d.ts +186 -3
- package/core/encoding/index.d.ts.map +1 -1
- package/core/encoding/index.esm.js +78 -392
- package/core/fs/index.cjs.js +231 -581
- package/core/fs/index.d.ts +479 -6
- package/core/fs/index.d.ts.map +1 -1
- package/core/fs/index.esm.js +221 -571
- package/core/index.cjs.js +518 -1748
- package/core/index.d.ts +486 -9
- package/core/index.d.ts.map +1 -1
- package/core/index.esm.js +501 -1728
- package/core/path/index.cjs.js +6 -234
- package/core/path/index.d.ts +306 -5
- package/core/path/index.d.ts.map +1 -1
- package/core/path/index.esm.js +4 -232
- package/core/platform/index.cjs.js +5 -216
- package/core/platform/index.d.ts +185 -3
- package/core/platform/index.d.ts.map +1 -1
- package/core/platform/index.esm.js +3 -212
- package/heuristics/dependencies/index.cjs.js +95 -492
- package/heuristics/dependencies/index.d.ts +99 -2
- package/heuristics/dependencies/index.d.ts.map +1 -1
- package/heuristics/dependencies/index.esm.js +69 -466
- package/heuristics/entry-points/index.cjs.js +91 -795
- package/heuristics/entry-points/index.d.ts +123 -2
- package/heuristics/entry-points/index.d.ts.map +1 -1
- package/heuristics/entry-points/index.esm.js +72 -776
- package/heuristics/framework/index.cjs.js +1481 -1410
- package/heuristics/framework/index.d.ts +104 -2
- package/heuristics/framework/index.d.ts.map +1 -1
- package/heuristics/framework/index.esm.js +1417 -1346
- package/heuristics/index.cjs.js +3206 -3301
- package/heuristics/index.d.ts +4 -5
- package/heuristics/index.d.ts.map +1 -1
- package/heuristics/index.esm.js +3231 -3326
- package/heuristics/project-type/index.cjs.js +1487 -1437
- package/heuristics/project-type/index.d.ts +64 -2
- package/heuristics/project-type/index.d.ts.map +1 -1
- package/heuristics/project-type/index.esm.js +1416 -1366
- package/index.cjs.js +3044 -3533
- package/index.d.ts +44 -10
- package/index.d.ts.map +1 -1
- package/index.esm.js +2900 -3377
- package/models/index.cjs.js +0 -1
- package/models/index.d.ts +20 -14
- package/models/index.d.ts.map +1 -1
- package/models/index.esm.js +0 -1
- package/nx/index.cjs.js +163 -577
- package/nx/index.d.ts +279 -4
- package/nx/index.d.ts.map +1 -1
- package/nx/index.esm.js +145 -554
- package/package.json +13 -12
- package/project/config/index.cjs.js +122 -1062
- package/project/config/index.d.ts +202 -4
- package/project/config/index.d.ts.map +1 -1
- package/project/config/index.esm.js +105 -1043
- package/project/index.cjs.js +323 -1100
- package/project/index.d.ts +4 -5
- package/project/index.d.ts.map +1 -1
- package/project/index.esm.js +302 -1076
- package/project/package/index.cjs.js +191 -472
- package/project/package/index.d.ts +280 -3
- package/project/package/index.d.ts.map +1 -1
- package/project/package/index.esm.js +178 -458
- package/project/root/index.cjs.js +107 -416
- package/project/root/index.d.ts +83 -2
- package/project/root/index.d.ts.map +1 -1
- package/project/root/index.esm.js +96 -405
- package/project/traversal/index.cjs.js +94 -621
- package/project/traversal/index.d.ts +165 -3
- package/project/traversal/index.d.ts.map +1 -1
- package/project/traversal/index.esm.js +80 -607
- package/tech/backend/index.cjs.js +221 -507
- package/tech/backend/index.d.ts +205 -8
- package/tech/backend/index.d.ts.map +1 -1
- package/tech/backend/index.esm.js +200 -486
- package/tech/build/index.cjs.js +348 -635
- package/tech/build/index.d.ts +276 -10
- package/tech/build/index.d.ts.map +1 -1
- package/tech/build/index.esm.js +326 -613
- package/tech/frontend/index.cjs.js +505 -684
- package/tech/frontend/index.d.ts +379 -15
- package/tech/frontend/index.d.ts.map +1 -1
- package/tech/frontend/index.esm.js +481 -660
- package/tech/index.cjs.js +1580 -1420
- package/tech/index.d.ts +55 -32
- package/tech/index.d.ts.map +1 -1
- package/tech/index.esm.js +1513 -1353
- package/tech/legacy/index.cjs.js +97 -448
- package/tech/legacy/index.d.ts +125 -7
- package/tech/legacy/index.d.ts.map +1 -1
- package/tech/legacy/index.esm.js +79 -430
- package/tech/linting/index.cjs.js +136 -522
- package/tech/linting/index.d.ts +129 -7
- package/tech/linting/index.d.ts.map +1 -1
- package/tech/linting/index.esm.js +116 -502
- package/tech/monorepo/index.cjs.js +244 -572
- package/tech/monorepo/index.d.ts +241 -10
- package/tech/monorepo/index.d.ts.map +1 -1
- package/tech/monorepo/index.esm.js +224 -552
- package/tech/testing/index.cjs.js +214 -570
- package/tech/testing/index.d.ts +176 -8
- package/tech/testing/index.d.ts.map +1 -1
- package/tech/testing/index.esm.js +196 -552
- package/tech/types/index.cjs.js +121 -505
- package/tech/types/index.d.ts +120 -2
- package/tech/types/index.d.ts.map +1 -1
- package/tech/types/index.esm.js +99 -483
- package/vfs/index.cjs.js +647 -1142
- package/vfs/index.d.ts +360 -6
- package/vfs/index.d.ts.map +1 -1
- package/vfs/index.esm.js +672 -1167
- package/ARCHITECTURE.md +0 -370
- package/analyze.d.ts +0 -33
- package/analyze.d.ts.map +0 -1
- package/cli/commands/analyze.d.ts +0 -28
- package/cli/commands/analyze.d.ts.map +0 -1
- package/cli/commands/config.d.ts +0 -27
- package/cli/commands/config.d.ts.map +0 -1
- package/cli/commands/deps.d.ts +0 -24
- package/cli/commands/deps.d.ts.map +0 -1
- package/cli/commands/tree.d.ts +0 -36
- package/cli/commands/tree.d.ts.map +0 -1
- package/cli/index.cjs.js.map +0 -1
- package/cli/index.esm.js.map +0 -1
- package/cli/run.d.ts +0 -25
- package/cli/run.d.ts.map +0 -1
- package/cli/types.d.ts +0 -55
- package/cli/types.d.ts.map +0 -1
- package/core/cache.d.ts +0 -158
- package/core/cache.d.ts.map +0 -1
- package/core/encoding/convert.d.ts +0 -32
- package/core/encoding/convert.d.ts.map +0 -1
- package/core/encoding/detect.d.ts +0 -91
- package/core/encoding/detect.d.ts.map +0 -1
- package/core/encoding/index.cjs.js.map +0 -1
- package/core/encoding/index.esm.js.map +0 -1
- package/core/errors/structured-errors.d.ts +0 -66
- package/core/errors/structured-errors.d.ts.map +0 -1
- package/core/fs/directory.d.ts +0 -91
- package/core/fs/directory.d.ts.map +0 -1
- package/core/fs/index.cjs.js.map +0 -1
- package/core/fs/index.esm.js.map +0 -1
- package/core/fs/read.d.ts +0 -94
- package/core/fs/read.d.ts.map +0 -1
- package/core/fs/stat.d.ts +0 -58
- package/core/fs/stat.d.ts.map +0 -1
- package/core/fs/traversal.d.ts +0 -26
- package/core/fs/traversal.d.ts.map +0 -1
- package/core/fs/write.d.ts +0 -75
- package/core/fs/write.d.ts.map +0 -1
- package/core/index.cjs.js.map +0 -1
- package/core/index.esm.js.map +0 -1
- package/core/logger.d.ts +0 -111
- package/core/logger.d.ts.map +0 -1
- package/core/path/index.cjs.js.map +0 -1
- package/core/path/index.esm.js.map +0 -1
- package/core/path/join.d.ts +0 -17
- package/core/path/join.d.ts.map +0 -1
- package/core/path/normalize.d.ts +0 -37
- package/core/path/normalize.d.ts.map +0 -1
- package/core/path/resolve.d.ts +0 -52
- package/core/path/resolve.d.ts.map +0 -1
- package/core/path/segments.d.ts +0 -59
- package/core/path/segments.d.ts.map +0 -1
- package/core/patterns/glob.d.ts +0 -42
- package/core/patterns/glob.d.ts.map +0 -1
- package/core/platform/detect.d.ts +0 -66
- package/core/platform/detect.d.ts.map +0 -1
- package/core/platform/index.cjs.js.map +0 -1
- package/core/platform/index.esm.js.map +0 -1
- package/core/platform/line-endings.d.ts +0 -48
- package/core/platform/line-endings.d.ts.map +0 -1
- package/heuristics/dependencies/analyze.d.ts +0 -77
- package/heuristics/dependencies/analyze.d.ts.map +0 -1
- package/heuristics/dependencies/index.cjs.js.map +0 -1
- package/heuristics/dependencies/index.esm.js.map +0 -1
- package/heuristics/entry-points/discover.d.ts +0 -113
- package/heuristics/entry-points/discover.d.ts.map +0 -1
- package/heuristics/entry-points/index.cjs.js.map +0 -1
- package/heuristics/entry-points/index.esm.js.map +0 -1
- package/heuristics/framework/identify.d.ts +0 -84
- package/heuristics/framework/identify.d.ts.map +0 -1
- package/heuristics/framework/index.cjs.js.map +0 -1
- package/heuristics/framework/index.esm.js.map +0 -1
- package/heuristics/index.cjs.js.map +0 -1
- package/heuristics/index.esm.js.map +0 -1
- package/heuristics/project-type/detect.d.ts +0 -61
- package/heuristics/project-type/detect.d.ts.map +0 -1
- package/heuristics/project-type/index.cjs.js.map +0 -1
- package/heuristics/project-type/index.esm.js.map +0 -1
- package/index.cjs.js.map +0 -1
- package/index.esm.js.map +0 -1
- package/models/index.cjs.js.map +0 -1
- package/models/index.esm.js.map +0 -1
- package/nx/detect.d.ts +0 -105
- package/nx/detect.d.ts.map +0 -1
- package/nx/devkit-loader.d.ts +0 -62
- package/nx/devkit-loader.d.ts.map +0 -1
- package/nx/index.cjs.js.map +0 -1
- package/nx/index.esm.js.map +0 -1
- package/nx/project-config.d.ts +0 -111
- package/nx/project-config.d.ts.map +0 -1
- package/project/config/detect.d.ts +0 -77
- package/project/config/detect.d.ts.map +0 -1
- package/project/config/index.cjs.js.map +0 -1
- package/project/config/index.esm.js.map +0 -1
- package/project/config/parse.d.ts +0 -53
- package/project/config/parse.d.ts.map +0 -1
- package/project/config/patterns.d.ts +0 -31
- package/project/config/patterns.d.ts.map +0 -1
- package/project/index.cjs.js.map +0 -1
- package/project/index.esm.js.map +0 -1
- package/project/package/dependencies.d.ts +0 -101
- package/project/package/dependencies.d.ts.map +0 -1
- package/project/package/index.cjs.js.map +0 -1
- package/project/package/index.esm.js.map +0 -1
- package/project/package/read.d.ts +0 -67
- package/project/package/read.d.ts.map +0 -1
- package/project/root/detect.d.ts +0 -65
- package/project/root/detect.d.ts.map +0 -1
- package/project/root/index.cjs.js.map +0 -1
- package/project/root/index.esm.js.map +0 -1
- package/project/traversal/index.cjs.js.map +0 -1
- package/project/traversal/index.esm.js.map +0 -1
- package/project/traversal/search.d.ts +0 -59
- package/project/traversal/search.d.ts.map +0 -1
- package/project/traversal/walk.d.ts +0 -63
- package/project/traversal/walk.d.ts.map +0 -1
- package/tech/backend/detect-all.d.ts +0 -13
- package/tech/backend/detect-all.d.ts.map +0 -1
- package/tech/backend/express.d.ts +0 -11
- package/tech/backend/express.d.ts.map +0 -1
- package/tech/backend/fastify.d.ts +0 -11
- package/tech/backend/fastify.d.ts.map +0 -1
- package/tech/backend/hono.d.ts +0 -11
- package/tech/backend/hono.d.ts.map +0 -1
- package/tech/backend/index.cjs.js.map +0 -1
- package/tech/backend/index.esm.js.map +0 -1
- package/tech/backend/koa.d.ts +0 -11
- package/tech/backend/koa.d.ts.map +0 -1
- package/tech/backend/nestjs.d.ts +0 -11
- package/tech/backend/nestjs.d.ts.map +0 -1
- package/tech/backend/types.d.ts +0 -31
- package/tech/backend/types.d.ts.map +0 -1
- package/tech/build/babel.d.ts +0 -13
- package/tech/build/babel.d.ts.map +0 -1
- package/tech/build/detect-all.d.ts +0 -13
- package/tech/build/detect-all.d.ts.map +0 -1
- package/tech/build/esbuild.d.ts +0 -11
- package/tech/build/esbuild.d.ts.map +0 -1
- package/tech/build/index.cjs.js.map +0 -1
- package/tech/build/index.esm.js.map +0 -1
- package/tech/build/parcel.d.ts +0 -13
- package/tech/build/parcel.d.ts.map +0 -1
- package/tech/build/rollup.d.ts +0 -13
- package/tech/build/rollup.d.ts.map +0 -1
- package/tech/build/swc.d.ts +0 -13
- package/tech/build/swc.d.ts.map +0 -1
- package/tech/build/types.d.ts +0 -31
- package/tech/build/types.d.ts.map +0 -1
- package/tech/build/vite.d.ts +0 -13
- package/tech/build/vite.d.ts.map +0 -1
- package/tech/build/webpack.d.ts +0 -13
- package/tech/build/webpack.d.ts.map +0 -1
- package/tech/frontend/angular.d.ts +0 -11
- package/tech/frontend/angular.d.ts.map +0 -1
- package/tech/frontend/astro.d.ts +0 -11
- package/tech/frontend/astro.d.ts.map +0 -1
- package/tech/frontend/detect-all.d.ts +0 -13
- package/tech/frontend/detect-all.d.ts.map +0 -1
- package/tech/frontend/gatsby.d.ts +0 -11
- package/tech/frontend/gatsby.d.ts.map +0 -1
- package/tech/frontend/index.cjs.js.map +0 -1
- package/tech/frontend/index.esm.js.map +0 -1
- package/tech/frontend/nextjs.d.ts +0 -11
- package/tech/frontend/nextjs.d.ts.map +0 -1
- package/tech/frontend/nuxt.d.ts +0 -11
- package/tech/frontend/nuxt.d.ts.map +0 -1
- package/tech/frontend/qwik.d.ts +0 -11
- package/tech/frontend/qwik.d.ts.map +0 -1
- package/tech/frontend/react.d.ts +0 -11
- package/tech/frontend/react.d.ts.map +0 -1
- package/tech/frontend/remix.d.ts +0 -11
- package/tech/frontend/remix.d.ts.map +0 -1
- package/tech/frontend/solid.d.ts +0 -11
- package/tech/frontend/solid.d.ts.map +0 -1
- package/tech/frontend/svelte.d.ts +0 -11
- package/tech/frontend/svelte.d.ts.map +0 -1
- package/tech/frontend/sveltekit.d.ts +0 -11
- package/tech/frontend/sveltekit.d.ts.map +0 -1
- package/tech/frontend/types.d.ts +0 -35
- package/tech/frontend/types.d.ts.map +0 -1
- package/tech/frontend/vue.d.ts +0 -11
- package/tech/frontend/vue.d.ts.map +0 -1
- package/tech/index.cjs.js.map +0 -1
- package/tech/index.esm.js.map +0 -1
- package/tech/legacy/angularjs.d.ts +0 -12
- package/tech/legacy/angularjs.d.ts.map +0 -1
- package/tech/legacy/backbone.d.ts +0 -11
- package/tech/legacy/backbone.d.ts.map +0 -1
- package/tech/legacy/detect-all.d.ts +0 -13
- package/tech/legacy/detect-all.d.ts.map +0 -1
- package/tech/legacy/ember.d.ts +0 -11
- package/tech/legacy/ember.d.ts.map +0 -1
- package/tech/legacy/index.cjs.js.map +0 -1
- package/tech/legacy/index.esm.js.map +0 -1
- package/tech/legacy/jquery.d.ts +0 -11
- package/tech/legacy/jquery.d.ts.map +0 -1
- package/tech/legacy/types.d.ts +0 -33
- package/tech/legacy/types.d.ts.map +0 -1
- package/tech/linting/biome.d.ts +0 -11
- package/tech/linting/biome.d.ts.map +0 -1
- package/tech/linting/detect-all.d.ts +0 -13
- package/tech/linting/detect-all.d.ts.map +0 -1
- package/tech/linting/eslint.d.ts +0 -13
- package/tech/linting/eslint.d.ts.map +0 -1
- package/tech/linting/index.cjs.js.map +0 -1
- package/tech/linting/index.esm.js.map +0 -1
- package/tech/linting/prettier.d.ts +0 -13
- package/tech/linting/prettier.d.ts.map +0 -1
- package/tech/linting/stylelint.d.ts +0 -13
- package/tech/linting/stylelint.d.ts.map +0 -1
- package/tech/linting/types.d.ts +0 -31
- package/tech/linting/types.d.ts.map +0 -1
- package/tech/monorepo/detect-all.d.ts +0 -13
- package/tech/monorepo/detect-all.d.ts.map +0 -1
- package/tech/monorepo/index.cjs.js.map +0 -1
- package/tech/monorepo/index.esm.js.map +0 -1
- package/tech/monorepo/lerna.d.ts +0 -11
- package/tech/monorepo/lerna.d.ts.map +0 -1
- package/tech/monorepo/npm-workspaces.d.ts +0 -11
- package/tech/monorepo/npm-workspaces.d.ts.map +0 -1
- package/tech/monorepo/nx.d.ts +0 -11
- package/tech/monorepo/nx.d.ts.map +0 -1
- package/tech/monorepo/pnpm-workspaces.d.ts +0 -9
- package/tech/monorepo/pnpm-workspaces.d.ts.map +0 -1
- package/tech/monorepo/rush.d.ts +0 -11
- package/tech/monorepo/rush.d.ts.map +0 -1
- package/tech/monorepo/turborepo.d.ts +0 -11
- package/tech/monorepo/turborepo.d.ts.map +0 -1
- package/tech/monorepo/types.d.ts +0 -39
- package/tech/monorepo/types.d.ts.map +0 -1
- package/tech/monorepo/yarn-workspaces.d.ts +0 -11
- package/tech/monorepo/yarn-workspaces.d.ts.map +0 -1
- package/tech/shared-utils/detector-helpers.d.ts +0 -52
- package/tech/shared-utils/detector-helpers.d.ts.map +0 -1
- package/tech/shared-utils/types.d.ts +0 -41
- package/tech/shared-utils/types.d.ts.map +0 -1
- package/tech/testing/cypress.d.ts +0 -13
- package/tech/testing/cypress.d.ts.map +0 -1
- package/tech/testing/detect-all.d.ts +0 -13
- package/tech/testing/detect-all.d.ts.map +0 -1
- package/tech/testing/index.cjs.js.map +0 -1
- package/tech/testing/index.esm.js.map +0 -1
- package/tech/testing/jest.d.ts +0 -13
- package/tech/testing/jest.d.ts.map +0 -1
- package/tech/testing/mocha.d.ts +0 -13
- package/tech/testing/mocha.d.ts.map +0 -1
- package/tech/testing/playwright.d.ts +0 -13
- package/tech/testing/playwright.d.ts.map +0 -1
- package/tech/testing/types.d.ts +0 -35
- package/tech/testing/types.d.ts.map +0 -1
- package/tech/testing/vitest.d.ts +0 -13
- package/tech/testing/vitest.d.ts.map +0 -1
- package/tech/types/detectors.d.ts +0 -67
- package/tech/types/detectors.d.ts.map +0 -1
- package/tech/types/index.cjs.js.map +0 -1
- package/tech/types/index.esm.js.map +0 -1
- package/vfs/commit.d.ts +0 -32
- package/vfs/commit.d.ts.map +0 -1
- package/vfs/diff.d.ts +0 -73
- package/vfs/diff.d.ts.map +0 -1
- package/vfs/factory.d.ts +0 -37
- package/vfs/factory.d.ts.map +0 -1
- package/vfs/fs-tree.d.ts +0 -13
- package/vfs/fs-tree.d.ts.map +0 -1
- package/vfs/index.cjs.js.map +0 -1
- package/vfs/index.esm.js.map +0 -1
- package/vfs/types.d.ts +0 -179
- package/vfs/types.d.ts.map +0 -1
|
@@ -1,547 +1,19 @@
|
|
|
1
|
+
import { createMap } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js';
|
|
2
|
+
import { freeze, entries, keys, defineProperties, values } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js';
|
|
3
|
+
import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
|
|
4
|
+
import { isArray } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
|
|
5
|
+
import { error, warn, log, info, debug } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.esm.js';
|
|
6
|
+
import { stringify, parse } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.esm.js';
|
|
7
|
+
import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
|
|
1
8
|
import { join as join$1 } from 'node:path';
|
|
9
|
+
import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
|
|
2
10
|
import { existsSync, readFileSync, statSync, lstatSync, readdirSync } from 'node:fs';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
* These references are captured at module initialization time to protect against
|
|
11
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
12
|
-
*
|
|
13
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/map
|
|
14
|
-
*/
|
|
15
|
-
const _Map = globalThis.Map;
|
|
16
|
-
const _Reflect$2 = globalThis.Reflect;
|
|
17
|
-
/**
|
|
18
|
-
* (Safe copy) Creates a new Map using the captured Map constructor.
|
|
19
|
-
* Use this instead of `new Map()`.
|
|
20
|
-
*
|
|
21
|
-
* @param iterable - Optional iterable of key-value pairs.
|
|
22
|
-
* @returns A new Map instance.
|
|
23
|
-
*/
|
|
24
|
-
const createMap = (iterable) => _Reflect$2.construct(_Map, iterable ? [iterable] : []);
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Safe copies of Object built-in methods.
|
|
28
|
-
*
|
|
29
|
-
* These references are captured at module initialization time to protect against
|
|
30
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
31
|
-
*
|
|
32
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/object
|
|
33
|
-
*/
|
|
34
|
-
const _Object = globalThis.Object;
|
|
35
|
-
/**
|
|
36
|
-
* (Safe copy) Prevents modification of existing property attributes and values,
|
|
37
|
-
* and prevents the addition of new properties.
|
|
38
|
-
*/
|
|
39
|
-
const freeze = _Object.freeze;
|
|
40
|
-
/**
|
|
41
|
-
* (Safe copy) Returns the names of the enumerable string properties and methods of an object.
|
|
42
|
-
*/
|
|
43
|
-
const keys = _Object.keys;
|
|
44
|
-
/**
|
|
45
|
-
* (Safe copy) Returns an array of key/values of the enumerable own properties of an object.
|
|
46
|
-
*/
|
|
47
|
-
const entries = _Object.entries;
|
|
48
|
-
/**
|
|
49
|
-
* (Safe copy) Returns an array of values of the enumerable own properties of an object.
|
|
50
|
-
*/
|
|
51
|
-
const values = _Object.values;
|
|
52
|
-
/**
|
|
53
|
-
* (Safe copy) Adds one or more properties to an object, and/or modifies attributes of existing properties.
|
|
54
|
-
*/
|
|
55
|
-
const defineProperties = _Object.defineProperties;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Safe copies of Set built-in via factory function.
|
|
59
|
-
*
|
|
60
|
-
* Since constructors cannot be safely captured via Object.assign, this module
|
|
61
|
-
* provides a factory function that uses Reflect.construct internally.
|
|
62
|
-
*
|
|
63
|
-
* These references are captured at module initialization time to protect against
|
|
64
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
65
|
-
*
|
|
66
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/set
|
|
67
|
-
*/
|
|
68
|
-
const _Set = globalThis.Set;
|
|
69
|
-
const _Reflect$1 = globalThis.Reflect;
|
|
70
|
-
/**
|
|
71
|
-
* (Safe copy) Creates a new Set using the captured Set constructor.
|
|
72
|
-
* Use this instead of `new Set()`.
|
|
73
|
-
*
|
|
74
|
-
* @param iterable - Optional iterable of values.
|
|
75
|
-
* @returns A new Set instance.
|
|
76
|
-
*/
|
|
77
|
-
const createSet = (iterable) => _Reflect$1.construct(_Set, iterable ? [iterable] : []);
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Global registry of all caches for bulk operations.
|
|
81
|
-
*/
|
|
82
|
-
const cacheRegistry = createSet();
|
|
83
|
-
/**
|
|
84
|
-
* Create a cache with optional TTL and size limits.
|
|
85
|
-
*
|
|
86
|
-
* The cache provides a simple key-value store with:
|
|
87
|
-
* - Optional TTL (time-to-live) for automatic expiration
|
|
88
|
-
* - Optional maxSize for limiting cache size with FIFO eviction
|
|
89
|
-
* - Lazy expiration (entries are checked on access)
|
|
90
|
-
*
|
|
91
|
-
* @param options - Cache configuration options
|
|
92
|
-
* @returns Cache instance
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```typescript
|
|
96
|
-
* // Basic cache
|
|
97
|
-
* const cache = createCache<string, number>()
|
|
98
|
-
* cache.set('answer', 42)
|
|
99
|
-
* cache.get('answer') // 42
|
|
100
|
-
*
|
|
101
|
-
* // Cache with TTL (expires after 60 seconds)
|
|
102
|
-
* const ttlCache = createCache<string, object>({ ttl: 60000 })
|
|
103
|
-
*
|
|
104
|
-
* // Cache with max size (evicts oldest when full)
|
|
105
|
-
* const lruCache = createCache<string, object>({ maxSize: 100 })
|
|
106
|
-
*
|
|
107
|
-
* // Combined options
|
|
108
|
-
* const configCache = createCache<string, object>({
|
|
109
|
-
* ttl: 30000,
|
|
110
|
-
* maxSize: 50
|
|
111
|
-
* })
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
function createCache(options) {
|
|
115
|
-
const { ttl, maxSize } = options ?? {};
|
|
116
|
-
const store = createMap();
|
|
117
|
-
const insertionOrder = [];
|
|
118
|
-
/**
|
|
119
|
-
* Check if an entry is expired.
|
|
120
|
-
*
|
|
121
|
-
* @param entry - Cache entry to check
|
|
122
|
-
* @returns True if entry is expired
|
|
123
|
-
*/
|
|
124
|
-
function isExpired(entry) {
|
|
125
|
-
if (ttl === undefined)
|
|
126
|
-
return false;
|
|
127
|
-
// eslint-disable-next-line workspace/no-unsafe-builtin-methods -- Date.now() is needed for Jest fake timers compatibility
|
|
128
|
-
return Date.now() - entry.timestamp > ttl;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Evict oldest entries to make room for new ones.
|
|
132
|
-
*/
|
|
133
|
-
function evictIfNeeded() {
|
|
134
|
-
if (maxSize === undefined)
|
|
135
|
-
return;
|
|
136
|
-
while (store.size >= maxSize && insertionOrder.length > 0) {
|
|
137
|
-
const oldestKey = insertionOrder.shift();
|
|
138
|
-
if (oldestKey !== undefined) {
|
|
139
|
-
store.delete(oldestKey);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Remove key from insertion order tracking.
|
|
145
|
-
*
|
|
146
|
-
* @param key - Key to remove from order tracking
|
|
147
|
-
*/
|
|
148
|
-
function removeFromOrder(key) {
|
|
149
|
-
const index = insertionOrder.indexOf(key);
|
|
150
|
-
if (index !== -1) {
|
|
151
|
-
insertionOrder.splice(index, 1);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
const cache = {
|
|
155
|
-
get(key) {
|
|
156
|
-
const entry = store.get(key);
|
|
157
|
-
if (!entry)
|
|
158
|
-
return undefined;
|
|
159
|
-
if (isExpired(entry)) {
|
|
160
|
-
store.delete(key);
|
|
161
|
-
removeFromOrder(key);
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
return entry.value;
|
|
165
|
-
},
|
|
166
|
-
set(key, value) {
|
|
167
|
-
if (store.has(key)) {
|
|
168
|
-
removeFromOrder(key);
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
evictIfNeeded();
|
|
172
|
-
}
|
|
173
|
-
// eslint-disable-next-line workspace/no-unsafe-builtin-methods -- Date.now() is needed for Jest fake timers compatibility
|
|
174
|
-
store.set(key, { value, timestamp: Date.now() });
|
|
175
|
-
insertionOrder.push(key);
|
|
176
|
-
},
|
|
177
|
-
has(key) {
|
|
178
|
-
const entry = store.get(key);
|
|
179
|
-
if (!entry)
|
|
180
|
-
return false;
|
|
181
|
-
if (isExpired(entry)) {
|
|
182
|
-
store.delete(key);
|
|
183
|
-
removeFromOrder(key);
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
return true;
|
|
187
|
-
},
|
|
188
|
-
delete(key) {
|
|
189
|
-
removeFromOrder(key);
|
|
190
|
-
return store.delete(key);
|
|
191
|
-
},
|
|
192
|
-
clear() {
|
|
193
|
-
store.clear();
|
|
194
|
-
insertionOrder.length = 0;
|
|
195
|
-
},
|
|
196
|
-
size() {
|
|
197
|
-
return store.size;
|
|
198
|
-
},
|
|
199
|
-
keys() {
|
|
200
|
-
return [...insertionOrder];
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
cacheRegistry.add(cache);
|
|
204
|
-
return freeze(cache);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Safe copies of Array built-in static methods.
|
|
209
|
-
*
|
|
210
|
-
* These references are captured at module initialization time to protect against
|
|
211
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
212
|
-
*
|
|
213
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/array
|
|
214
|
-
*/
|
|
215
|
-
const _Array = globalThis.Array;
|
|
216
|
-
/**
|
|
217
|
-
* (Safe copy) Determines whether the passed value is an Array.
|
|
218
|
-
*/
|
|
219
|
-
const isArray = _Array.isArray;
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Safe copies of Console built-in methods.
|
|
223
|
-
*
|
|
224
|
-
* These references are captured at module initialization time to protect against
|
|
225
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
226
|
-
*
|
|
227
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/console
|
|
228
|
-
*/
|
|
229
|
-
const _console = globalThis.console;
|
|
230
|
-
/**
|
|
231
|
-
* (Safe copy) Outputs a message to the console.
|
|
232
|
-
*/
|
|
233
|
-
const log = _console.log.bind(_console);
|
|
234
|
-
/**
|
|
235
|
-
* (Safe copy) Outputs a warning message to the console.
|
|
236
|
-
*/
|
|
237
|
-
const warn = _console.warn.bind(_console);
|
|
238
|
-
/**
|
|
239
|
-
* (Safe copy) Outputs an error message to the console.
|
|
240
|
-
*/
|
|
241
|
-
const error = _console.error.bind(_console);
|
|
242
|
-
/**
|
|
243
|
-
* (Safe copy) Outputs an informational message to the console.
|
|
244
|
-
*/
|
|
245
|
-
const info = _console.info.bind(_console);
|
|
246
|
-
/**
|
|
247
|
-
* (Safe copy) Outputs a debug message to the console.
|
|
248
|
-
*/
|
|
249
|
-
const debug = _console.debug.bind(_console);
|
|
250
|
-
/**
|
|
251
|
-
* (Safe copy) Outputs a stack trace to the console.
|
|
252
|
-
*/
|
|
253
|
-
_console.trace.bind(_console);
|
|
254
|
-
/**
|
|
255
|
-
* (Safe copy) Displays an interactive listing of the properties of a specified object.
|
|
256
|
-
*/
|
|
257
|
-
_console.dir.bind(_console);
|
|
258
|
-
/**
|
|
259
|
-
* (Safe copy) Displays tabular data as a table.
|
|
260
|
-
*/
|
|
261
|
-
_console.table.bind(_console);
|
|
262
|
-
/**
|
|
263
|
-
* (Safe copy) Writes an error message to the console if the assertion is false.
|
|
264
|
-
*/
|
|
265
|
-
_console.assert.bind(_console);
|
|
266
|
-
/**
|
|
267
|
-
* (Safe copy) Clears the console.
|
|
268
|
-
*/
|
|
269
|
-
_console.clear.bind(_console);
|
|
270
|
-
/**
|
|
271
|
-
* (Safe copy) Logs the number of times that this particular call to count() has been called.
|
|
272
|
-
*/
|
|
273
|
-
_console.count.bind(_console);
|
|
274
|
-
/**
|
|
275
|
-
* (Safe copy) Resets the counter used with console.count().
|
|
276
|
-
*/
|
|
277
|
-
_console.countReset.bind(_console);
|
|
278
|
-
/**
|
|
279
|
-
* (Safe copy) Creates a new inline group in the console.
|
|
280
|
-
*/
|
|
281
|
-
_console.group.bind(_console);
|
|
282
|
-
/**
|
|
283
|
-
* (Safe copy) Creates a new inline group in the console that is initially collapsed.
|
|
284
|
-
*/
|
|
285
|
-
_console.groupCollapsed.bind(_console);
|
|
286
|
-
/**
|
|
287
|
-
* (Safe copy) Exits the current inline group.
|
|
288
|
-
*/
|
|
289
|
-
_console.groupEnd.bind(_console);
|
|
290
|
-
/**
|
|
291
|
-
* (Safe copy) Starts a timer with a name specified as an input parameter.
|
|
292
|
-
*/
|
|
293
|
-
_console.time.bind(_console);
|
|
294
|
-
/**
|
|
295
|
-
* (Safe copy) Stops a timer that was previously started.
|
|
296
|
-
*/
|
|
297
|
-
_console.timeEnd.bind(_console);
|
|
298
|
-
/**
|
|
299
|
-
* (Safe copy) Logs the current value of a timer that was previously started.
|
|
300
|
-
*/
|
|
301
|
-
_console.timeLog.bind(_console);
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Safe copies of JSON built-in methods.
|
|
305
|
-
*
|
|
306
|
-
* These references are captured at module initialization time to protect against
|
|
307
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
308
|
-
*
|
|
309
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/json
|
|
310
|
-
*/
|
|
311
|
-
const _JSON = globalThis.JSON;
|
|
312
|
-
/**
|
|
313
|
-
* (Safe copy) Converts a JavaScript Object Notation (JSON) string into an object.
|
|
314
|
-
*/
|
|
315
|
-
const parse = _JSON.parse;
|
|
316
|
-
/**
|
|
317
|
-
* (Safe copy) Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
|
|
318
|
-
*/
|
|
319
|
-
const stringify = _JSON.stringify;
|
|
320
|
-
|
|
321
|
-
const registeredClasses = [];
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Returns the data type of the target.
|
|
325
|
-
* Uses native `typeof` operator, however, makes distinction between `null`, `array`, and `object`.
|
|
326
|
-
* Also, when classes are registered via `registerClass`, it checks if objects are instance of any known registered class.
|
|
327
|
-
*
|
|
328
|
-
* @param target - The target to get the data type of.
|
|
329
|
-
* @returns The data type of the target.
|
|
330
|
-
*/
|
|
331
|
-
const getType = (target) => {
|
|
332
|
-
if (target === null)
|
|
333
|
-
return 'null';
|
|
334
|
-
const nativeDataType = typeof target;
|
|
335
|
-
if (nativeDataType === 'object') {
|
|
336
|
-
if (isArray(target))
|
|
337
|
-
return 'array';
|
|
338
|
-
for (const registeredClass of registeredClasses) {
|
|
339
|
-
if (target instanceof registeredClass)
|
|
340
|
-
return registeredClass.name;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return nativeDataType;
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Safe copies of Error built-ins via factory functions.
|
|
348
|
-
*
|
|
349
|
-
* Since constructors cannot be safely captured via Object.assign, this module
|
|
350
|
-
* provides factory functions that use Reflect.construct internally.
|
|
351
|
-
*
|
|
352
|
-
* These references are captured at module initialization time to protect against
|
|
353
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
354
|
-
*
|
|
355
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/error
|
|
356
|
-
*/
|
|
357
|
-
const _Error = globalThis.Error;
|
|
358
|
-
const _Reflect = globalThis.Reflect;
|
|
359
|
-
/**
|
|
360
|
-
* (Safe copy) Creates a new Error using the captured Error constructor.
|
|
361
|
-
* Use this instead of `new Error()`.
|
|
362
|
-
*
|
|
363
|
-
* @param message - Optional error message.
|
|
364
|
-
* @param options - Optional error options.
|
|
365
|
-
* @returns A new Error instance.
|
|
366
|
-
*/
|
|
367
|
-
const createError = (message, options) => _Reflect.construct(_Error, [message, options]);
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Safe copies of Math built-in methods.
|
|
371
|
-
*
|
|
372
|
-
* These references are captured at module initialization time to protect against
|
|
373
|
-
* prototype pollution attacks. Import only what you need for tree-shaking.
|
|
374
|
-
*
|
|
375
|
-
* @module @hyperfrontend/immutable-api-utils/built-in-copy/math
|
|
376
|
-
*/
|
|
377
|
-
const _Math = globalThis.Math;
|
|
378
|
-
/**
|
|
379
|
-
* (Safe copy) Returns the smaller of zero or more numbers.
|
|
380
|
-
*/
|
|
381
|
-
const min = _Math.min;
|
|
382
|
-
|
|
383
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
384
|
-
/**
|
|
385
|
-
* Creates a wrapper function that only executes the wrapped function if the condition function returns true.
|
|
386
|
-
*
|
|
387
|
-
* @param func - The function to be conditionally executed.
|
|
388
|
-
* @param conditionFunc - A function that returns a boolean, determining if `func` should be executed.
|
|
389
|
-
* @returns A wrapped version of `func` that executes conditionally.
|
|
390
|
-
*/
|
|
391
|
-
function createConditionalExecutionFunction(func, conditionFunc) {
|
|
392
|
-
return function (...args) {
|
|
393
|
-
if (conditionFunc()) {
|
|
394
|
-
return func(...args);
|
|
395
|
-
}
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
400
|
-
/**
|
|
401
|
-
* Creates a wrapper function that silently ignores any errors thrown by the wrapped void function.
|
|
402
|
-
* This function is specifically for wrapping functions that do not return a value (void functions).
|
|
403
|
-
* Exceptions are swallowed without any logging or handling.
|
|
404
|
-
*
|
|
405
|
-
* @param func - The void function to be wrapped.
|
|
406
|
-
* @returns A wrapped version of the input function that ignores errors.
|
|
407
|
-
*/
|
|
408
|
-
function createErrorIgnoringFunction(func) {
|
|
409
|
-
return function (...args) {
|
|
410
|
-
try {
|
|
411
|
-
func(...args);
|
|
412
|
-
}
|
|
413
|
-
catch {
|
|
414
|
-
// Deliberately swallowing/ignoring the exception
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
420
|
-
/**
|
|
421
|
-
* A no-operation function (noop) that does nothing regardless of the arguments passed.
|
|
422
|
-
* It is designed to be as permissive as possible in its typing without using the `Function` keyword.
|
|
423
|
-
*
|
|
424
|
-
* @param args - Any arguments passed to the function (ignored)
|
|
425
|
-
*/
|
|
426
|
-
const noop = (...args) => {
|
|
427
|
-
// Intentionally does nothing
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
const logLevels = ['none', 'error', 'warn', 'log', 'info', 'debug'];
|
|
431
|
-
const priority = {
|
|
432
|
-
error: 4,
|
|
433
|
-
warn: 3,
|
|
434
|
-
log: 2,
|
|
435
|
-
info: 1,
|
|
436
|
-
debug: 0,
|
|
437
|
-
};
|
|
438
|
-
/**
|
|
439
|
-
* Validates whether a given string is a valid log level.
|
|
440
|
-
*
|
|
441
|
-
* @param level - The log level to validate
|
|
442
|
-
* @returns True if the level is valid, false otherwise
|
|
443
|
-
*/
|
|
444
|
-
function isValidLogLevel(level) {
|
|
445
|
-
return logLevels.includes(level);
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Creates a log level configuration manager for controlling logging behavior.
|
|
449
|
-
* Provides methods to get, set, and evaluate log levels based on priority.
|
|
450
|
-
*
|
|
451
|
-
* @param level - The initial log level (defaults to 'error')
|
|
452
|
-
* @returns A configuration object with log level management methods
|
|
453
|
-
* @throws {Error} When the provided level is not a valid log level
|
|
454
|
-
*/
|
|
455
|
-
function createLogLevelConfig(level = 'error') {
|
|
456
|
-
if (!isValidLogLevel(level)) {
|
|
457
|
-
throw createError('Cannot create log level configuration with a valid default log level');
|
|
458
|
-
}
|
|
459
|
-
const state = { level };
|
|
460
|
-
const getLogLevel = () => state.level;
|
|
461
|
-
const setLogLevel = (level) => {
|
|
462
|
-
if (!isValidLogLevel(level)) {
|
|
463
|
-
throw createError(`Cannot set value '${level}' level. Expected levels are ${logLevels}.`);
|
|
464
|
-
}
|
|
465
|
-
state.level = level;
|
|
466
|
-
};
|
|
467
|
-
const shouldLog = (level) => {
|
|
468
|
-
if (state.level === 'none' || level === 'none' || !isValidLogLevel(level)) {
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
|
-
return priority[level] >= priority[state.level];
|
|
472
|
-
};
|
|
473
|
-
return freeze({
|
|
474
|
-
getLogLevel,
|
|
475
|
-
setLogLevel,
|
|
476
|
-
shouldLog,
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Creates a logger instance with configurable log level filtering.
|
|
482
|
-
* Each log function is wrapped to respect the current log level setting.
|
|
483
|
-
*
|
|
484
|
-
* @param error - Function to handle error-level logs (required)
|
|
485
|
-
* @param warn - Function to handle warning-level logs (optional, defaults to noop)
|
|
486
|
-
* @param log - Function to handle standard logs (optional, defaults to noop)
|
|
487
|
-
* @param info - Function to handle info-level logs (optional, defaults to noop)
|
|
488
|
-
* @param debug - Function to handle debug-level logs (optional, defaults to noop)
|
|
489
|
-
* @returns A frozen logger object with log methods and level control
|
|
490
|
-
* @throws {ErrorLevelFn} When any provided log function is invalid
|
|
491
|
-
*/
|
|
492
|
-
function createLogger(error, warn = noop, log = noop, info = noop, debug = noop) {
|
|
493
|
-
if (notValidLogFn(error)) {
|
|
494
|
-
throw createError(notFnMsg('error'));
|
|
495
|
-
}
|
|
496
|
-
if (notValidLogFn(warn)) {
|
|
497
|
-
throw createError(notFnMsg('warn'));
|
|
498
|
-
}
|
|
499
|
-
if (notValidLogFn(log)) {
|
|
500
|
-
throw createError(notFnMsg('log'));
|
|
501
|
-
}
|
|
502
|
-
if (notValidLogFn(info)) {
|
|
503
|
-
throw createError(notFnMsg('info'));
|
|
504
|
-
}
|
|
505
|
-
if (notValidLogFn(debug)) {
|
|
506
|
-
throw createError(notFnMsg('debug'));
|
|
507
|
-
}
|
|
508
|
-
const { setLogLevel, getLogLevel, shouldLog } = createLogLevelConfig();
|
|
509
|
-
const wrapLogFn = (fn, level) => {
|
|
510
|
-
if (fn === noop)
|
|
511
|
-
return fn;
|
|
512
|
-
const condition = () => shouldLog(level);
|
|
513
|
-
return createConditionalExecutionFunction(createErrorIgnoringFunction(fn), condition);
|
|
514
|
-
};
|
|
515
|
-
return freeze({
|
|
516
|
-
error: wrapLogFn(error, 'error'),
|
|
517
|
-
warn: wrapLogFn(warn, 'warn'),
|
|
518
|
-
log: wrapLogFn(log, 'log'),
|
|
519
|
-
info: wrapLogFn(info, 'info'),
|
|
520
|
-
debug: wrapLogFn(debug, 'debug'),
|
|
521
|
-
setLogLevel,
|
|
522
|
-
getLogLevel,
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Validates whether a given value is a valid log function.
|
|
527
|
-
*
|
|
528
|
-
* @param fn - The value to validate
|
|
529
|
-
* @returns True if the value is not a function (invalid), false if it is valid
|
|
530
|
-
*/
|
|
531
|
-
function notValidLogFn(fn) {
|
|
532
|
-
return getType(fn) !== 'function' && fn !== noop;
|
|
533
|
-
}
|
|
534
|
-
/**
|
|
535
|
-
* Generates an error message for invalid log function parameters.
|
|
536
|
-
*
|
|
537
|
-
* @param label - The name of the log function that failed validation
|
|
538
|
-
* @returns A formatted error message string
|
|
539
|
-
*/
|
|
540
|
-
function notFnMsg(label) {
|
|
541
|
-
return `Cannot create a logger when ${label} is not a function`;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
createLogger(error, warn, log, info, debug);
|
|
11
|
+
import { min } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js';
|
|
12
|
+
import { isDirectory, exists } from '../../_shared/core/fs/stat/index.esm.js';
|
|
13
|
+
import { join } from '../../_shared/core/path/join/index.esm.js';
|
|
14
|
+
import { createCache } from '../../_shared/core/cache/index.esm.js';
|
|
15
|
+
import { collectAllDependencies, parseVersionString, locateConfigFile, filterScriptsByCommand } from '../../_shared/tech/shared-utils/detector-helpers/index.esm.js';
|
|
16
|
+
import { pnpmWorkspacesDetector } from '../../_shared/tech/monorepo/pnpm-workspaces/index.esm.js';
|
|
545
17
|
|
|
546
18
|
/**
|
|
547
19
|
* Global log level registry.
|
|
@@ -581,6 +53,13 @@ function isSensitiveKey(key) {
|
|
|
581
53
|
*
|
|
582
54
|
* @param obj - Object to sanitize
|
|
583
55
|
* @returns New object with sensitive values redacted
|
|
56
|
+
*
|
|
57
|
+
* @example Sanitizing sensitive data
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const config = { apiKey: 'secret123', endpoint: 'https://api.example.com' }
|
|
60
|
+
* const safe = sanitize(config)
|
|
61
|
+
* // => { apiKey: '[REDACTED]', endpoint: 'https://api.example.com' }
|
|
62
|
+
* ```
|
|
584
63
|
*/
|
|
585
64
|
function sanitize(obj) {
|
|
586
65
|
if (obj === null || obj === undefined) {
|
|
@@ -631,7 +110,7 @@ function formatMessage(namespace, message, meta) {
|
|
|
631
110
|
* @param options - Logger configuration options
|
|
632
111
|
* @returns A configured scoped logger instance
|
|
633
112
|
*
|
|
634
|
-
* @example
|
|
113
|
+
* @example Creating a scoped logger
|
|
635
114
|
* ```typescript
|
|
636
115
|
* const logger = createScopedLogger('project-scope')
|
|
637
116
|
* logger.setLogLevel('debug')
|
|
@@ -668,7 +147,7 @@ function createScopedLogger(namespace, options = {}) {
|
|
|
668
147
|
* Default logger instance for the project-scope library.
|
|
669
148
|
* Use this for general logging within the library.
|
|
670
149
|
*
|
|
671
|
-
* @example
|
|
150
|
+
* @example Using the default logger
|
|
672
151
|
* ```typescript
|
|
673
152
|
* import { logger } from '@hyperfrontend/project-scope/core'
|
|
674
153
|
*
|
|
@@ -686,6 +165,15 @@ createScopedLogger('project-scope:fs');
|
|
|
686
165
|
* @param code - The category code for this type of filesystem failure
|
|
687
166
|
* @param context - Additional context including path, operation, and cause
|
|
688
167
|
* @returns A configured Error object with code and context properties
|
|
168
|
+
*
|
|
169
|
+
* @example Creating a file system error
|
|
170
|
+
* ```typescript
|
|
171
|
+
* throw createFileSystemError(
|
|
172
|
+
* 'Cannot read file',
|
|
173
|
+
* 'FS_READ_ERROR',
|
|
174
|
+
* { path: './missing.txt', operation: 'read' }
|
|
175
|
+
* )
|
|
176
|
+
* ```
|
|
689
177
|
*/
|
|
690
178
|
function createFileSystemError(message, code, context) {
|
|
691
179
|
const error = createError(message);
|
|
@@ -701,6 +189,14 @@ function createFileSystemError(message, code, context) {
|
|
|
701
189
|
* @param filePath - Path to file
|
|
702
190
|
* @param encoding - File encoding (default: utf-8)
|
|
703
191
|
* @returns File contents or null if file doesn't exist
|
|
192
|
+
*
|
|
193
|
+
* @example Reading file if it exists
|
|
194
|
+
* ```typescript
|
|
195
|
+
* const content = readFileIfExists('./optional-config.json')
|
|
196
|
+
* if (content) {
|
|
197
|
+
* // File existed, use content
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
704
200
|
*/
|
|
705
201
|
function readFileIfExists(filePath, encoding = 'utf-8') {
|
|
706
202
|
if (!existsSync(filePath)) {
|
|
@@ -714,56 +210,6 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
|
|
|
714
210
|
}
|
|
715
211
|
}
|
|
716
212
|
|
|
717
|
-
createScopedLogger('project-scope:fs:write');
|
|
718
|
-
|
|
719
|
-
/**
|
|
720
|
-
* Get file stats with error handling.
|
|
721
|
-
*
|
|
722
|
-
* @param filePath - Path to file
|
|
723
|
-
* @param followSymlinks - Whether to follow symlinks (default: true)
|
|
724
|
-
* @returns File stats or null if path doesn't exist
|
|
725
|
-
*/
|
|
726
|
-
function getFileStat(filePath, followSymlinks = true) {
|
|
727
|
-
if (!existsSync(filePath)) {
|
|
728
|
-
return null;
|
|
729
|
-
}
|
|
730
|
-
try {
|
|
731
|
-
const stat = followSymlinks ? statSync(filePath) : lstatSync(filePath);
|
|
732
|
-
return {
|
|
733
|
-
isFile: stat.isFile(),
|
|
734
|
-
isDirectory: stat.isDirectory(),
|
|
735
|
-
isSymlink: stat.isSymbolicLink(),
|
|
736
|
-
size: stat.size,
|
|
737
|
-
created: stat.birthtime,
|
|
738
|
-
modified: stat.mtime,
|
|
739
|
-
accessed: stat.atime,
|
|
740
|
-
mode: stat.mode,
|
|
741
|
-
};
|
|
742
|
-
}
|
|
743
|
-
catch {
|
|
744
|
-
return null;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Check if path is a directory.
|
|
749
|
-
*
|
|
750
|
-
* @param dirPath - Path to check
|
|
751
|
-
* @returns True if path is a directory
|
|
752
|
-
*/
|
|
753
|
-
function isDirectory(dirPath) {
|
|
754
|
-
const stats = getFileStat(dirPath);
|
|
755
|
-
return stats?.isDirectory ?? false;
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Check if path exists.
|
|
759
|
-
*
|
|
760
|
-
* @param filePath - Path to check
|
|
761
|
-
* @returns True if path exists
|
|
762
|
-
*/
|
|
763
|
-
function exists(filePath) {
|
|
764
|
-
return existsSync(filePath);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
213
|
const fsDirLogger = createScopedLogger('project-scope:fs:dir');
|
|
768
214
|
/**
|
|
769
215
|
* List immediate contents of a directory.
|
|
@@ -772,7 +218,7 @@ const fsDirLogger = createScopedLogger('project-scope:fs:dir');
|
|
|
772
218
|
* @returns Array of entries with metadata for each file/directory
|
|
773
219
|
* @throws {Error} If directory doesn't exist or isn't a directory
|
|
774
220
|
*
|
|
775
|
-
* @example
|
|
221
|
+
* @example Listing directory contents
|
|
776
222
|
* ```typescript
|
|
777
223
|
* import { readDirectory } from '@hyperfrontend/project-scope'
|
|
778
224
|
*
|
|
@@ -813,19 +259,10 @@ function readDirectory(dirPath) {
|
|
|
813
259
|
}
|
|
814
260
|
}
|
|
815
261
|
|
|
816
|
-
/**
|
|
817
|
-
* Join path segments.
|
|
818
|
-
* Uses platform-specific separators (e.g., / or \).
|
|
819
|
-
*
|
|
820
|
-
* @param paths - Path segments to join
|
|
821
|
-
* @returns Joined path
|
|
822
|
-
*/
|
|
823
|
-
function join(...paths) {
|
|
824
|
-
return join$1(...paths);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
262
|
createScopedLogger('project-scope:fs:traversal');
|
|
828
263
|
|
|
264
|
+
createScopedLogger('project-scope:fs:write');
|
|
265
|
+
|
|
829
266
|
const packageLogger = createScopedLogger('project-scope:project:package');
|
|
830
267
|
/**
|
|
831
268
|
* Verifies that a value is an object with only string values,
|
|
@@ -895,6 +332,16 @@ function validatePackageJson(data) {
|
|
|
895
332
|
*
|
|
896
333
|
* @param projectPath - Project directory path or path to package.json
|
|
897
334
|
* @returns Parsed package.json or null if not found
|
|
335
|
+
*
|
|
336
|
+
* @example Reading package.json if it exists
|
|
337
|
+
* ```typescript
|
|
338
|
+
* import { readPackageJsonIfExists } from '@hyperfrontend/project-scope'
|
|
339
|
+
*
|
|
340
|
+
* const pkg = readPackageJsonIfExists('/path/to/project')
|
|
341
|
+
* if (pkg) {
|
|
342
|
+
* console.log('Found:', pkg.name)
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
898
345
|
*/
|
|
899
346
|
function readPackageJsonIfExists(projectPath) {
|
|
900
347
|
const packageJsonPath = projectPath.endsWith('package.json') ? projectPath : join$1(projectPath, 'package.json');
|
|
@@ -915,79 +362,31 @@ function readPackageJsonIfExists(projectPath) {
|
|
|
915
362
|
}
|
|
916
363
|
|
|
917
364
|
/**
|
|
918
|
-
*
|
|
919
|
-
* Merges dependencies, devDependencies, peerDependencies, and optionalDependencies.
|
|
365
|
+
* Detect Express in project.
|
|
920
366
|
*
|
|
921
|
-
* @param
|
|
922
|
-
* @
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Extract clean version from dependency version string.
|
|
934
|
-
* Removes semver prefixes like ^, ~, >=, etc.
|
|
935
|
-
* Uses character-by-character parsing to avoid ReDoS vulnerabilities.
|
|
367
|
+
* @param projectPath - Project directory path
|
|
368
|
+
* @param packageJson - Optional pre-loaded package.json
|
|
369
|
+
* @returns Detection result or null if not detected
|
|
370
|
+
* @example Detecting Express framework
|
|
371
|
+
* ```typescript
|
|
372
|
+
* const pkg = {
|
|
373
|
+
* dependencies: { express: '^4.18.2', cors: '^2.8.5' },
|
|
374
|
+
* devDependencies: { '@types/express': '^4.17.17' },
|
|
375
|
+
* }
|
|
936
376
|
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
}
|
|
951
|
-
return versionString.slice(start);
|
|
952
|
-
}
|
|
953
|
-
/**
|
|
954
|
-
* Find first matching config file in project.
|
|
955
|
-
* Note: Name avoids similarity to fs.readFile/fs.readFileSync.
|
|
956
|
-
*
|
|
957
|
-
* @param projectPath - The project directory path
|
|
958
|
-
* @param patterns - Array of config file patterns to search for
|
|
959
|
-
* @returns The first matching config file path or undefined
|
|
960
|
-
*/
|
|
961
|
-
function locateConfigFile(projectPath, patterns) {
|
|
962
|
-
for (const pattern of patterns) {
|
|
963
|
-
const fullPath = join(projectPath, pattern);
|
|
964
|
-
if (exists(fullPath)) {
|
|
965
|
-
return pattern;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
return undefined;
|
|
969
|
-
}
|
|
970
|
-
/**
|
|
971
|
-
* Find scripts containing a specific command.
|
|
972
|
-
*
|
|
973
|
-
* @param scripts - The scripts object from package.json
|
|
974
|
-
* @param command - The command string to search for
|
|
975
|
-
* @returns Array of script names that contain the command
|
|
976
|
-
*/
|
|
977
|
-
function filterScriptsByCommand(scripts, command) {
|
|
978
|
-
if (!scripts)
|
|
979
|
-
return [];
|
|
980
|
-
return entries(scripts)
|
|
981
|
-
.filter(([, script]) => script.includes(command))
|
|
982
|
-
.map(([name]) => name);
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
/**
|
|
986
|
-
* Detect Express in project.
|
|
987
|
-
*
|
|
988
|
-
* @param projectPath - Project directory path
|
|
989
|
-
* @param packageJson - Optional pre-loaded package.json
|
|
990
|
-
* @returns Detection result or null if not detected
|
|
377
|
+
* const result = expressDetector('/path/to/project', pkg)
|
|
378
|
+
* // => {
|
|
379
|
+
* // id: 'express',
|
|
380
|
+
* // name: 'Express',
|
|
381
|
+
* // version: '4.18.2',
|
|
382
|
+
* // confidence: 100,
|
|
383
|
+
* // detectedFrom: [
|
|
384
|
+
* // { type: 'package.json', field: 'dependencies.express' },
|
|
385
|
+
* // { type: 'package.json', field: 'dependencies.@types/express' },
|
|
386
|
+
* // { type: 'package.json', field: 'dependencies (express middleware)' },
|
|
387
|
+
* // ],
|
|
388
|
+
* // }
|
|
389
|
+
* ```
|
|
991
390
|
*/
|
|
992
391
|
function expressDetector(projectPath, packageJson) {
|
|
993
392
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -1022,84 +421,109 @@ function expressDetector(projectPath, packageJson) {
|
|
|
1022
421
|
}
|
|
1023
422
|
|
|
1024
423
|
/**
|
|
1025
|
-
* Detect
|
|
424
|
+
* Detect Fastify in project.
|
|
1026
425
|
*
|
|
1027
426
|
* @param projectPath - Project directory path
|
|
1028
427
|
* @param packageJson - Optional pre-loaded package.json
|
|
1029
428
|
* @returns Detection result or null if not detected
|
|
429
|
+
* @example Detecting Fastify framework
|
|
430
|
+
* ```typescript
|
|
431
|
+
* const pkg = {
|
|
432
|
+
* dependencies: { fastify: '^4.24.0', '@fastify/cors': '^8.4.0' },
|
|
433
|
+
* }
|
|
434
|
+
*
|
|
435
|
+
* const result = fastifyDetector('/path/to/project', pkg)
|
|
436
|
+
* // => {
|
|
437
|
+
* // id: 'fastify',
|
|
438
|
+
* // name: 'Fastify',
|
|
439
|
+
* // version: '4.24.0',
|
|
440
|
+
* // confidence: 95,
|
|
441
|
+
* // detectedFrom: [
|
|
442
|
+
* // { type: 'package.json', field: 'dependencies.fastify' },
|
|
443
|
+
* // { type: 'package.json', field: 'dependencies (fastify plugins)' },
|
|
444
|
+
* // ],
|
|
445
|
+
* // }
|
|
446
|
+
* ```
|
|
1030
447
|
*/
|
|
1031
|
-
function
|
|
448
|
+
function fastifyDetector(projectPath, packageJson) {
|
|
1032
449
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1033
450
|
const sources = [];
|
|
1034
451
|
let confidence = 0;
|
|
1035
452
|
let version;
|
|
1036
|
-
let configPath;
|
|
1037
453
|
const deps = collectAllDependencies(pkg);
|
|
1038
|
-
if (deps['
|
|
1039
|
-
confidence +=
|
|
1040
|
-
version = parseVersionString(deps['
|
|
1041
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1042
|
-
}
|
|
1043
|
-
if (deps['@nestjs/common']) {
|
|
1044
|
-
confidence += 15;
|
|
1045
|
-
sources.push({ type: 'package.json', field: 'dependencies.@nestjs/common' });
|
|
454
|
+
if (deps['fastify']) {
|
|
455
|
+
confidence += 80;
|
|
456
|
+
version = parseVersionString(deps['fastify']);
|
|
457
|
+
sources.push({ type: 'package.json', field: 'dependencies.fastify' });
|
|
1046
458
|
}
|
|
1047
|
-
|
|
459
|
+
const fastifyPlugins = keys(deps).filter((d) => d.startsWith('@fastify/') || d.startsWith('fastify-'));
|
|
460
|
+
if (fastifyPlugins.length > 0) {
|
|
1048
461
|
confidence += 15;
|
|
1049
|
-
|
|
1050
|
-
sources.push({ type: 'config-file', path: 'nest-cli.json' });
|
|
462
|
+
sources.push({ type: 'package.json', field: 'dependencies (fastify plugins)' });
|
|
1051
463
|
}
|
|
1052
|
-
|
|
1053
|
-
if (nestPackages.length > 2) {
|
|
464
|
+
if (deps['@types/fastify']) {
|
|
1054
465
|
confidence += 5;
|
|
1055
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
466
|
+
sources.push({ type: 'package.json', field: 'dependencies.@types/fastify' });
|
|
1056
467
|
}
|
|
1057
468
|
if (confidence === 0) {
|
|
1058
469
|
return null;
|
|
1059
470
|
}
|
|
1060
471
|
return {
|
|
1061
|
-
id: '
|
|
1062
|
-
name: '
|
|
472
|
+
id: 'fastify',
|
|
473
|
+
name: 'Fastify',
|
|
1063
474
|
version,
|
|
1064
|
-
configPath,
|
|
1065
475
|
confidence: min(confidence, 100),
|
|
1066
476
|
detectedFrom: sources,
|
|
1067
477
|
};
|
|
1068
478
|
}
|
|
1069
479
|
|
|
1070
480
|
/**
|
|
1071
|
-
* Detect
|
|
481
|
+
* Detect Hono in project.
|
|
1072
482
|
*
|
|
1073
483
|
* @param projectPath - Project directory path
|
|
1074
484
|
* @param packageJson - Optional pre-loaded package.json
|
|
1075
485
|
* @returns Detection result or null if not detected
|
|
486
|
+
* @example Detecting Hono framework
|
|
487
|
+
* ```typescript
|
|
488
|
+
* const pkg = {
|
|
489
|
+
* dependencies: { hono: '^3.11.0', '@hono/node-server': '^1.3.0' },
|
|
490
|
+
* }
|
|
491
|
+
*
|
|
492
|
+
* const result = honoDetector('/path/to/project', pkg)
|
|
493
|
+
* // => {
|
|
494
|
+
* // id: 'hono',
|
|
495
|
+
* // name: 'Hono',
|
|
496
|
+
* // version: '3.11.0',
|
|
497
|
+
* // confidence: 100,
|
|
498
|
+
* // detectedFrom: [
|
|
499
|
+
* // { type: 'package.json', field: 'dependencies.hono' },
|
|
500
|
+
* // { type: 'package.json', field: 'dependencies (@hono adapters)' },
|
|
501
|
+
* // ],
|
|
502
|
+
* // }
|
|
503
|
+
* ```
|
|
1076
504
|
*/
|
|
1077
|
-
function
|
|
505
|
+
function honoDetector(projectPath, packageJson) {
|
|
1078
506
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1079
507
|
const sources = [];
|
|
1080
508
|
let confidence = 0;
|
|
1081
509
|
let version;
|
|
1082
510
|
const deps = collectAllDependencies(pkg);
|
|
1083
|
-
if (deps['
|
|
1084
|
-
confidence +=
|
|
1085
|
-
version = parseVersionString(deps['
|
|
1086
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
511
|
+
if (deps['hono']) {
|
|
512
|
+
confidence += 85;
|
|
513
|
+
version = parseVersionString(deps['hono']);
|
|
514
|
+
sources.push({ type: 'package.json', field: 'dependencies.hono' });
|
|
1087
515
|
}
|
|
1088
|
-
const
|
|
1089
|
-
if (
|
|
516
|
+
const honoAdapters = keys(deps).filter((d) => d.startsWith('@hono/'));
|
|
517
|
+
if (honoAdapters.length > 0) {
|
|
1090
518
|
confidence += 15;
|
|
1091
|
-
sources.push({ type: 'package.json', field: 'dependencies (
|
|
1092
|
-
}
|
|
1093
|
-
if (deps['@types/fastify']) {
|
|
1094
|
-
confidence += 5;
|
|
1095
|
-
sources.push({ type: 'package.json', field: 'dependencies.@types/fastify' });
|
|
519
|
+
sources.push({ type: 'package.json', field: 'dependencies (@hono adapters)' });
|
|
1096
520
|
}
|
|
1097
521
|
if (confidence === 0) {
|
|
1098
522
|
return null;
|
|
1099
523
|
}
|
|
1100
524
|
return {
|
|
1101
|
-
id: '
|
|
1102
|
-
name: '
|
|
525
|
+
id: 'hono',
|
|
526
|
+
name: 'Hono',
|
|
1103
527
|
version,
|
|
1104
528
|
confidence: min(confidence, 100),
|
|
1105
529
|
detectedFrom: sources,
|
|
@@ -1112,6 +536,26 @@ function fastifyDetector(projectPath, packageJson) {
|
|
|
1112
536
|
* @param projectPath - Project directory path
|
|
1113
537
|
* @param packageJson - Optional pre-loaded package.json
|
|
1114
538
|
* @returns Detection result or null if not detected
|
|
539
|
+
* @example Detecting Koa framework
|
|
540
|
+
* ```typescript
|
|
541
|
+
* const pkg = {
|
|
542
|
+
* dependencies: { koa: '^2.14.2', 'koa-router': '^12.0.0' },
|
|
543
|
+
* devDependencies: { '@types/koa': '^2.13.9' },
|
|
544
|
+
* }
|
|
545
|
+
*
|
|
546
|
+
* const result = koaDetector('/path/to/project', pkg)
|
|
547
|
+
* // => {
|
|
548
|
+
* // id: 'koa',
|
|
549
|
+
* // name: 'Koa',
|
|
550
|
+
* // version: '2.14.2',
|
|
551
|
+
* // confidence: 100,
|
|
552
|
+
* // detectedFrom: [
|
|
553
|
+
* // { type: 'package.json', field: 'dependencies.koa' },
|
|
554
|
+
* // { type: 'package.json', field: 'dependencies.@types/koa' },
|
|
555
|
+
* // { type: 'package.json', field: 'dependencies (koa middleware)' },
|
|
556
|
+
* // ],
|
|
557
|
+
* // }
|
|
558
|
+
* ```
|
|
1115
559
|
*/
|
|
1116
560
|
function koaDetector(projectPath, packageJson) {
|
|
1117
561
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -1146,35 +590,72 @@ function koaDetector(projectPath, packageJson) {
|
|
|
1146
590
|
}
|
|
1147
591
|
|
|
1148
592
|
/**
|
|
1149
|
-
* Detect
|
|
593
|
+
* Detect NestJS in project.
|
|
1150
594
|
*
|
|
1151
595
|
* @param projectPath - Project directory path
|
|
1152
596
|
* @param packageJson - Optional pre-loaded package.json
|
|
1153
597
|
* @returns Detection result or null if not detected
|
|
598
|
+
* @example Detecting NestJS framework
|
|
599
|
+
* ```typescript
|
|
600
|
+
* // Project with nest-cli.json and NestJS packages
|
|
601
|
+
* const pkg = {
|
|
602
|
+
* dependencies: {
|
|
603
|
+
* '@nestjs/core': '^10.2.0',
|
|
604
|
+
* '@nestjs/common': '^10.2.0',
|
|
605
|
+
* '@nestjs/platform-express': '^10.2.0',
|
|
606
|
+
* },
|
|
607
|
+
* }
|
|
608
|
+
*
|
|
609
|
+
* const result = nestDetector('/path/to/nest-project', pkg)
|
|
610
|
+
* // => {
|
|
611
|
+
* // id: 'nestjs',
|
|
612
|
+
* // name: 'NestJS',
|
|
613
|
+
* // version: '10.2.0',
|
|
614
|
+
* // configPath: 'nest-cli.json', // if present
|
|
615
|
+
* // confidence: 100,
|
|
616
|
+
* // detectedFrom: [
|
|
617
|
+
* // { type: 'package.json', field: 'dependencies.@nestjs/core' },
|
|
618
|
+
* // { type: 'package.json', field: 'dependencies.@nestjs/common' },
|
|
619
|
+
* // { type: 'config-file', path: 'nest-cli.json' },
|
|
620
|
+
* // { type: 'package.json', field: 'dependencies (@nestjs packages)' },
|
|
621
|
+
* // ],
|
|
622
|
+
* // }
|
|
623
|
+
* ```
|
|
1154
624
|
*/
|
|
1155
|
-
function
|
|
625
|
+
function nestDetector(projectPath, packageJson) {
|
|
1156
626
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1157
627
|
const sources = [];
|
|
1158
628
|
let confidence = 0;
|
|
1159
629
|
let version;
|
|
630
|
+
let configPath;
|
|
1160
631
|
const deps = collectAllDependencies(pkg);
|
|
1161
|
-
if (deps['
|
|
1162
|
-
confidence +=
|
|
1163
|
-
version = parseVersionString(deps['
|
|
1164
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
632
|
+
if (deps['@nestjs/core']) {
|
|
633
|
+
confidence += 70;
|
|
634
|
+
version = parseVersionString(deps['@nestjs/core']);
|
|
635
|
+
sources.push({ type: 'package.json', field: 'dependencies.@nestjs/core' });
|
|
1165
636
|
}
|
|
1166
|
-
|
|
1167
|
-
if (honoAdapters.length > 0) {
|
|
637
|
+
if (deps['@nestjs/common']) {
|
|
1168
638
|
confidence += 15;
|
|
1169
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
639
|
+
sources.push({ type: 'package.json', field: 'dependencies.@nestjs/common' });
|
|
640
|
+
}
|
|
641
|
+
if (exists(join$1(projectPath, 'nest-cli.json'))) {
|
|
642
|
+
confidence += 15;
|
|
643
|
+
configPath = 'nest-cli.json';
|
|
644
|
+
sources.push({ type: 'config-file', path: 'nest-cli.json' });
|
|
645
|
+
}
|
|
646
|
+
const nestPackages = keys(deps).filter((d) => d.startsWith('@nestjs/'));
|
|
647
|
+
if (nestPackages.length > 2) {
|
|
648
|
+
confidence += 5;
|
|
649
|
+
sources.push({ type: 'package.json', field: 'dependencies (@nestjs packages)' });
|
|
1170
650
|
}
|
|
1171
651
|
if (confidence === 0) {
|
|
1172
652
|
return null;
|
|
1173
653
|
}
|
|
1174
654
|
return {
|
|
1175
|
-
id: '
|
|
1176
|
-
name: '
|
|
655
|
+
id: 'nestjs',
|
|
656
|
+
name: 'NestJS',
|
|
1177
657
|
version,
|
|
658
|
+
configPath,
|
|
1178
659
|
confidence: min(confidence, 100),
|
|
1179
660
|
detectedFrom: sources,
|
|
1180
661
|
};
|
|
@@ -1189,52 +670,64 @@ const backendDetectors = [
|
|
|
1189
670
|
{ id: 'hono', name: 'Hono', detect: honoDetector },
|
|
1190
671
|
];
|
|
1191
672
|
|
|
1192
|
-
/** Config patterns for
|
|
1193
|
-
const
|
|
1194
|
-
'webpack.config.js',
|
|
1195
|
-
'webpack.config.ts',
|
|
1196
|
-
'webpack.config.cjs',
|
|
1197
|
-
'webpack.config.mjs',
|
|
1198
|
-
'webpack.config.babel.js',
|
|
1199
|
-
];
|
|
673
|
+
/** Config patterns for Babel */
|
|
674
|
+
const BABEL_CONFIG_PATTERNS = ['babel.config.js', 'babel.config.cjs', 'babel.config.mjs', 'babel.config.json', '.babelrc', '.babelrc.json', '.babelrc.js'];
|
|
1200
675
|
/**
|
|
1201
|
-
* Detect
|
|
676
|
+
* Detect Babel in project.
|
|
1202
677
|
*
|
|
1203
678
|
* @param projectPath - Project directory path
|
|
1204
679
|
* @param packageJson - Optional pre-loaded package.json
|
|
1205
680
|
* @returns Detection result or null if not detected
|
|
681
|
+
*
|
|
682
|
+
* @example Detecting Babel compiler
|
|
683
|
+
* ```typescript
|
|
684
|
+
* const result = babelDetector('/path/to/project', {
|
|
685
|
+
* name: 'my-app',
|
|
686
|
+
* devDependencies: { '@babel/core': '^7.23.0', '@babel/preset-env': '^7.23.0' }
|
|
687
|
+
* })
|
|
688
|
+
* // => {
|
|
689
|
+
* // id: 'babel',
|
|
690
|
+
* // name: 'Babel',
|
|
691
|
+
* // version: '7.23.0',
|
|
692
|
+
* // confidence: 60,
|
|
693
|
+
* // detectedFrom: [
|
|
694
|
+
* // { type: 'package.json', field: 'dependencies.@babel/core' },
|
|
695
|
+
* // { type: 'package.json', field: 'dependencies (@babel packages)' }
|
|
696
|
+
* // ]
|
|
697
|
+
* // }
|
|
698
|
+
* ```
|
|
1206
699
|
*/
|
|
1207
|
-
function
|
|
700
|
+
function babelDetector(projectPath, packageJson) {
|
|
1208
701
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1209
702
|
const sources = [];
|
|
1210
703
|
let confidence = 0;
|
|
1211
704
|
let version;
|
|
1212
705
|
const deps = collectAllDependencies(pkg);
|
|
1213
|
-
if (deps['
|
|
706
|
+
if (deps['@babel/core']) {
|
|
1214
707
|
confidence += 50;
|
|
1215
|
-
version = parseVersionString(deps['
|
|
1216
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
708
|
+
version = parseVersionString(deps['@babel/core']);
|
|
709
|
+
sources.push({ type: 'package.json', field: 'dependencies.@babel/core' });
|
|
1217
710
|
}
|
|
1218
|
-
const configPath = locateConfigFile(projectPath,
|
|
711
|
+
const configPath = locateConfigFile(projectPath, BABEL_CONFIG_PATTERNS);
|
|
1219
712
|
if (configPath) {
|
|
1220
713
|
confidence += 40;
|
|
1221
714
|
sources.push({ type: 'config-file', path: configPath });
|
|
1222
715
|
}
|
|
1223
|
-
if (
|
|
1224
|
-
confidence +=
|
|
1225
|
-
sources.push({ type: 'package.json', field: '
|
|
716
|
+
if (pkg && 'babel' in pkg) {
|
|
717
|
+
confidence += 30;
|
|
718
|
+
sources.push({ type: 'package.json', field: 'babel' });
|
|
1226
719
|
}
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
confidence
|
|
1230
|
-
sources.push({ type: 'package.json', field:
|
|
720
|
+
const babelPackages = keys(deps).filter((d) => d.startsWith('@babel/'));
|
|
721
|
+
if (babelPackages.length > 1) {
|
|
722
|
+
confidence += 10;
|
|
723
|
+
sources.push({ type: 'package.json', field: 'dependencies (@babel packages)' });
|
|
1231
724
|
}
|
|
1232
725
|
if (confidence === 0) {
|
|
1233
726
|
return null;
|
|
1234
727
|
}
|
|
1235
728
|
return {
|
|
1236
|
-
id: '
|
|
1237
|
-
name: '
|
|
729
|
+
id: 'babel',
|
|
730
|
+
name: 'Babel',
|
|
1238
731
|
version,
|
|
1239
732
|
configPath,
|
|
1240
733
|
confidence: min(confidence, 100),
|
|
@@ -1242,94 +735,126 @@ function webpackDetector(projectPath, packageJson) {
|
|
|
1242
735
|
};
|
|
1243
736
|
}
|
|
1244
737
|
|
|
1245
|
-
/** Config patterns for Vite */
|
|
1246
|
-
const VITE_CONFIG_PATTERNS = ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.cjs'];
|
|
1247
738
|
/**
|
|
1248
|
-
* Detect
|
|
739
|
+
* Detect esbuild in project.
|
|
1249
740
|
*
|
|
1250
741
|
* @param projectPath - Project directory path
|
|
1251
742
|
* @param packageJson - Optional pre-loaded package.json
|
|
1252
743
|
* @returns Detection result or null if not detected
|
|
744
|
+
*
|
|
745
|
+
* @example Detecting esbuild bundler
|
|
746
|
+
* ```typescript
|
|
747
|
+
* const result = esbuildDetector('/path/to/project', {
|
|
748
|
+
* name: 'my-lib',
|
|
749
|
+
* devDependencies: { 'esbuild': '^0.19.0' },
|
|
750
|
+
* scripts: { 'build': 'esbuild src/index.ts --bundle --outfile=dist/index.js' }
|
|
751
|
+
* })
|
|
752
|
+
* // => {
|
|
753
|
+
* // id: 'esbuild',
|
|
754
|
+
* // name: 'esbuild',
|
|
755
|
+
* // version: '0.19.0',
|
|
756
|
+
* // confidence: 80,
|
|
757
|
+
* // detectedFrom: [
|
|
758
|
+
* // { type: 'package.json', field: 'dependencies.esbuild' },
|
|
759
|
+
* // { type: 'package.json', field: 'scripts.build' }
|
|
760
|
+
* // ]
|
|
761
|
+
* // }
|
|
762
|
+
* ```
|
|
1253
763
|
*/
|
|
1254
|
-
function
|
|
764
|
+
function esbuildDetector(projectPath, packageJson) {
|
|
1255
765
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1256
766
|
const sources = [];
|
|
1257
767
|
let confidence = 0;
|
|
1258
768
|
let version;
|
|
1259
769
|
const deps = collectAllDependencies(pkg);
|
|
1260
|
-
if (deps['
|
|
1261
|
-
confidence +=
|
|
1262
|
-
version = parseVersionString(deps['
|
|
1263
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
1264
|
-
}
|
|
1265
|
-
const configPath = locateConfigFile(projectPath, VITE_CONFIG_PATTERNS);
|
|
1266
|
-
if (configPath) {
|
|
1267
|
-
confidence += 35;
|
|
1268
|
-
sources.push({ type: 'config-file', path: configPath });
|
|
770
|
+
if (deps['esbuild']) {
|
|
771
|
+
confidence += 70;
|
|
772
|
+
version = parseVersionString(deps['esbuild']);
|
|
773
|
+
sources.push({ type: 'package.json', field: 'dependencies.esbuild' });
|
|
1269
774
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
775
|
+
const esbuildPlugins = keys(deps).filter((d) => d.includes('esbuild-plugin') || d.includes('esbuild-'));
|
|
776
|
+
if (esbuildPlugins.length > 0) {
|
|
777
|
+
confidence += 15;
|
|
778
|
+
sources.push({ type: 'package.json', field: 'dependencies (esbuild plugins)' });
|
|
1273
779
|
}
|
|
1274
|
-
const
|
|
1275
|
-
|
|
1276
|
-
confidence
|
|
1277
|
-
sources.push({ type: 'package.json', field:
|
|
780
|
+
const scriptMatches = filterScriptsByCommand(pkg?.scripts, 'esbuild');
|
|
781
|
+
for (const name of scriptMatches) {
|
|
782
|
+
confidence = min(confidence + 10, 100);
|
|
783
|
+
sources.push({ type: 'package.json', field: `scripts.${name}` });
|
|
1278
784
|
}
|
|
1279
785
|
if (confidence === 0) {
|
|
1280
786
|
return null;
|
|
1281
787
|
}
|
|
1282
788
|
return {
|
|
1283
|
-
id: '
|
|
1284
|
-
name: '
|
|
789
|
+
id: 'esbuild',
|
|
790
|
+
name: 'esbuild',
|
|
1285
791
|
version,
|
|
1286
|
-
configPath,
|
|
1287
792
|
confidence: min(confidence, 100),
|
|
1288
793
|
detectedFrom: sources,
|
|
1289
794
|
};
|
|
1290
795
|
}
|
|
1291
796
|
|
|
1292
|
-
/** Config patterns for
|
|
1293
|
-
const
|
|
797
|
+
/** Config patterns for Parcel */
|
|
798
|
+
const PARCEL_CONFIG_PATTERNS = ['.parcelrc'];
|
|
1294
799
|
/**
|
|
1295
|
-
* Detect
|
|
800
|
+
* Detect Parcel in project.
|
|
1296
801
|
*
|
|
1297
802
|
* @param projectPath - Project directory path
|
|
1298
803
|
* @param packageJson - Optional pre-loaded package.json
|
|
1299
804
|
* @returns Detection result or null if not detected
|
|
805
|
+
*
|
|
806
|
+
* @example Detecting Parcel bundler
|
|
807
|
+
* ```typescript
|
|
808
|
+
* const result = parcelDetector('/path/to/project', {
|
|
809
|
+
* name: 'my-app',
|
|
810
|
+
* devDependencies: { 'parcel': '^2.10.0' },
|
|
811
|
+
* scripts: { 'dev': 'parcel src/index.html', 'build': 'parcel build src/index.html' }
|
|
812
|
+
* })
|
|
813
|
+
* // => {
|
|
814
|
+
* // id: 'parcel',
|
|
815
|
+
* // name: 'Parcel',
|
|
816
|
+
* // version: '2.10.0',
|
|
817
|
+
* // confidence: 80,
|
|
818
|
+
* // detectedFrom: [
|
|
819
|
+
* // { type: 'package.json', field: 'dependencies.parcel' },
|
|
820
|
+
* // { type: 'package.json', field: 'scripts.dev' },
|
|
821
|
+
* // { type: 'package.json', field: 'scripts.build' }
|
|
822
|
+
* // ]
|
|
823
|
+
* // }
|
|
824
|
+
* ```
|
|
1300
825
|
*/
|
|
1301
|
-
function
|
|
826
|
+
function parcelDetector(projectPath, packageJson) {
|
|
1302
827
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1303
828
|
const sources = [];
|
|
1304
829
|
let confidence = 0;
|
|
1305
830
|
let version;
|
|
1306
831
|
const deps = collectAllDependencies(pkg);
|
|
1307
|
-
if (deps['
|
|
1308
|
-
confidence +=
|
|
1309
|
-
version = parseVersionString(deps['
|
|
1310
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
832
|
+
if (deps['parcel']) {
|
|
833
|
+
confidence += 60;
|
|
834
|
+
version = parseVersionString(deps['parcel']);
|
|
835
|
+
sources.push({ type: 'package.json', field: 'dependencies.parcel' });
|
|
1311
836
|
}
|
|
1312
|
-
|
|
837
|
+
if (deps['parcel-bundler']) {
|
|
838
|
+
confidence += 60;
|
|
839
|
+
version = parseVersionString(deps['parcel-bundler']);
|
|
840
|
+
sources.push({ type: 'package.json', field: 'dependencies.parcel-bundler' });
|
|
841
|
+
}
|
|
842
|
+
const configPath = locateConfigFile(projectPath, PARCEL_CONFIG_PATTERNS);
|
|
1313
843
|
if (configPath) {
|
|
1314
|
-
confidence +=
|
|
844
|
+
confidence += 30;
|
|
1315
845
|
sources.push({ type: 'config-file', path: configPath });
|
|
1316
846
|
}
|
|
1317
|
-
const
|
|
1318
|
-
if (rollupPlugins.length > 0) {
|
|
1319
|
-
confidence += 10;
|
|
1320
|
-
sources.push({ type: 'package.json', field: 'dependencies (rollup plugins)' });
|
|
1321
|
-
}
|
|
1322
|
-
const scriptMatches = filterScriptsByCommand(pkg?.scripts, 'rollup');
|
|
847
|
+
const scriptMatches = filterScriptsByCommand(pkg?.scripts, 'parcel');
|
|
1323
848
|
for (const name of scriptMatches) {
|
|
1324
|
-
confidence = min(confidence +
|
|
849
|
+
confidence = min(confidence + 10, 100);
|
|
1325
850
|
sources.push({ type: 'package.json', field: `scripts.${name}` });
|
|
1326
851
|
}
|
|
1327
852
|
if (confidence === 0) {
|
|
1328
853
|
return null;
|
|
1329
854
|
}
|
|
1330
855
|
return {
|
|
1331
|
-
id: '
|
|
1332
|
-
name: '
|
|
856
|
+
id: 'parcel',
|
|
857
|
+
name: 'Parcel',
|
|
1333
858
|
version,
|
|
1334
859
|
configPath,
|
|
1335
860
|
confidence: min(confidence, 100),
|
|
@@ -1337,86 +862,134 @@ function rollupDetector(projectPath, packageJson) {
|
|
|
1337
862
|
};
|
|
1338
863
|
}
|
|
1339
864
|
|
|
865
|
+
/** Config patterns for Rollup */
|
|
866
|
+
const ROLLUP_CONFIG_PATTERNS = ['rollup.config.js', 'rollup.config.ts', 'rollup.config.mjs', 'rollup.config.cjs'];
|
|
1340
867
|
/**
|
|
1341
|
-
* Detect
|
|
868
|
+
* Detect Rollup in project.
|
|
1342
869
|
*
|
|
1343
870
|
* @param projectPath - Project directory path
|
|
1344
871
|
* @param packageJson - Optional pre-loaded package.json
|
|
1345
872
|
* @returns Detection result or null if not detected
|
|
873
|
+
*
|
|
874
|
+
* @example Detecting Rollup bundler
|
|
875
|
+
* ```typescript
|
|
876
|
+
* const result = rollupDetector('/path/to/project', {
|
|
877
|
+
* name: 'my-lib',
|
|
878
|
+
* devDependencies: {
|
|
879
|
+
* 'rollup': '^4.0.0',
|
|
880
|
+
* '@rollup/plugin-node-resolve': '^15.0.0',
|
|
881
|
+
* '@rollup/plugin-commonjs': '^25.0.0'
|
|
882
|
+
* }
|
|
883
|
+
* })
|
|
884
|
+
* // => {
|
|
885
|
+
* // id: 'rollup',
|
|
886
|
+
* // name: 'Rollup',
|
|
887
|
+
* // version: '4.0.0',
|
|
888
|
+
* // confidence: 65,
|
|
889
|
+
* // detectedFrom: [
|
|
890
|
+
* // { type: 'package.json', field: 'dependencies.rollup' },
|
|
891
|
+
* // { type: 'package.json', field: 'dependencies (rollup plugins)' }
|
|
892
|
+
* // ]
|
|
893
|
+
* // }
|
|
894
|
+
* ```
|
|
1346
895
|
*/
|
|
1347
|
-
function
|
|
896
|
+
function rollupDetector(projectPath, packageJson) {
|
|
1348
897
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1349
898
|
const sources = [];
|
|
1350
899
|
let confidence = 0;
|
|
1351
900
|
let version;
|
|
1352
901
|
const deps = collectAllDependencies(pkg);
|
|
1353
|
-
if (deps['
|
|
1354
|
-
confidence +=
|
|
1355
|
-
version = parseVersionString(deps['
|
|
1356
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
902
|
+
if (deps['rollup']) {
|
|
903
|
+
confidence += 55;
|
|
904
|
+
version = parseVersionString(deps['rollup']);
|
|
905
|
+
sources.push({ type: 'package.json', field: 'dependencies.rollup' });
|
|
1357
906
|
}
|
|
1358
|
-
const
|
|
1359
|
-
if (
|
|
1360
|
-
confidence +=
|
|
1361
|
-
sources.push({ type: '
|
|
907
|
+
const configPath = locateConfigFile(projectPath, ROLLUP_CONFIG_PATTERNS);
|
|
908
|
+
if (configPath) {
|
|
909
|
+
confidence += 40;
|
|
910
|
+
sources.push({ type: 'config-file', path: configPath });
|
|
1362
911
|
}
|
|
1363
|
-
const
|
|
912
|
+
const rollupPlugins = keys(deps).filter((d) => d.startsWith('@rollup/') || d.startsWith('rollup-plugin-'));
|
|
913
|
+
if (rollupPlugins.length > 0) {
|
|
914
|
+
confidence += 10;
|
|
915
|
+
sources.push({ type: 'package.json', field: 'dependencies (rollup plugins)' });
|
|
916
|
+
}
|
|
917
|
+
const scriptMatches = filterScriptsByCommand(pkg?.scripts, 'rollup');
|
|
1364
918
|
for (const name of scriptMatches) {
|
|
1365
|
-
confidence = min(confidence +
|
|
919
|
+
confidence = min(confidence + 5, 100);
|
|
1366
920
|
sources.push({ type: 'package.json', field: `scripts.${name}` });
|
|
1367
921
|
}
|
|
1368
922
|
if (confidence === 0) {
|
|
1369
923
|
return null;
|
|
1370
924
|
}
|
|
1371
925
|
return {
|
|
1372
|
-
id: '
|
|
1373
|
-
name: '
|
|
926
|
+
id: 'rollup',
|
|
927
|
+
name: 'Rollup',
|
|
1374
928
|
version,
|
|
929
|
+
configPath,
|
|
1375
930
|
confidence: min(confidence, 100),
|
|
1376
931
|
detectedFrom: sources,
|
|
1377
932
|
};
|
|
1378
933
|
}
|
|
1379
934
|
|
|
1380
|
-
/** Config patterns for
|
|
1381
|
-
const
|
|
935
|
+
/** Config patterns for SWC */
|
|
936
|
+
const SWC_CONFIG_PATTERNS = ['.swcrc', 'swc.config.js'];
|
|
1382
937
|
/**
|
|
1383
|
-
* Detect
|
|
938
|
+
* Detect SWC in project.
|
|
1384
939
|
*
|
|
1385
940
|
* @param projectPath - Project directory path
|
|
1386
941
|
* @param packageJson - Optional pre-loaded package.json
|
|
1387
942
|
* @returns Detection result or null if not detected
|
|
943
|
+
*
|
|
944
|
+
* @example Detecting SWC compiler
|
|
945
|
+
* ```typescript
|
|
946
|
+
* const result = swcDetector('/path/to/project', {
|
|
947
|
+
* name: 'my-app',
|
|
948
|
+
* devDependencies: { '@swc/core': '^1.3.0', '@swc/cli': '^0.1.0' }
|
|
949
|
+
* })
|
|
950
|
+
* // => {
|
|
951
|
+
* // id: 'swc',
|
|
952
|
+
* // name: 'SWC',
|
|
953
|
+
* // version: '1.3.0',
|
|
954
|
+
* // confidence: 70,
|
|
955
|
+
* // detectedFrom: [
|
|
956
|
+
* // { type: 'package.json', field: 'dependencies.@swc/core' },
|
|
957
|
+
* // { type: 'package.json', field: 'dependencies.@swc/cli' }
|
|
958
|
+
* // ]
|
|
959
|
+
* // }
|
|
960
|
+
* ```
|
|
1388
961
|
*/
|
|
1389
|
-
function
|
|
962
|
+
function swcDetector(projectPath, packageJson) {
|
|
1390
963
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1391
964
|
const sources = [];
|
|
1392
965
|
let confidence = 0;
|
|
1393
966
|
let version;
|
|
1394
967
|
const deps = collectAllDependencies(pkg);
|
|
1395
|
-
if (deps['@
|
|
1396
|
-
confidence +=
|
|
1397
|
-
version = parseVersionString(deps['@
|
|
1398
|
-
sources.push({ type: 'package.json', field: 'dependencies.@
|
|
968
|
+
if (deps['@swc/core']) {
|
|
969
|
+
confidence += 60;
|
|
970
|
+
version = parseVersionString(deps['@swc/core']);
|
|
971
|
+
sources.push({ type: 'package.json', field: 'dependencies.@swc/core' });
|
|
1399
972
|
}
|
|
1400
|
-
const configPath = locateConfigFile(projectPath,
|
|
973
|
+
const configPath = locateConfigFile(projectPath, SWC_CONFIG_PATTERNS);
|
|
1401
974
|
if (configPath) {
|
|
1402
|
-
confidence +=
|
|
975
|
+
confidence += 35;
|
|
1403
976
|
sources.push({ type: 'config-file', path: configPath });
|
|
1404
977
|
}
|
|
1405
|
-
if (
|
|
1406
|
-
confidence += 30;
|
|
1407
|
-
sources.push({ type: 'package.json', field: 'babel' });
|
|
1408
|
-
}
|
|
1409
|
-
const babelPackages = keys(deps).filter((d) => d.startsWith('@babel/'));
|
|
1410
|
-
if (babelPackages.length > 1) {
|
|
978
|
+
if (deps['@swc/cli']) {
|
|
1411
979
|
confidence += 10;
|
|
1412
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
980
|
+
sources.push({ type: 'package.json', field: 'dependencies.@swc/cli' });
|
|
981
|
+
}
|
|
982
|
+
const swcPlugins = keys(deps).filter((d) => d.startsWith('@swc/') || d.includes('swc-plugin'));
|
|
983
|
+
if (swcPlugins.length > 1) {
|
|
984
|
+
confidence += 5;
|
|
985
|
+
sources.push({ type: 'package.json', field: 'dependencies (@swc packages)' });
|
|
1413
986
|
}
|
|
1414
987
|
if (confidence === 0) {
|
|
1415
988
|
return null;
|
|
1416
989
|
}
|
|
1417
990
|
return {
|
|
1418
|
-
id: '
|
|
1419
|
-
name: '
|
|
991
|
+
id: 'swc',
|
|
992
|
+
name: 'SWC',
|
|
1420
993
|
version,
|
|
1421
994
|
configPath,
|
|
1422
995
|
confidence: min(confidence, 100),
|
|
@@ -1424,46 +997,69 @@ function babelDetector(projectPath, packageJson) {
|
|
|
1424
997
|
};
|
|
1425
998
|
}
|
|
1426
999
|
|
|
1427
|
-
/** Config patterns for
|
|
1428
|
-
const
|
|
1000
|
+
/** Config patterns for Vite */
|
|
1001
|
+
const VITE_CONFIG_PATTERNS = ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.cjs'];
|
|
1429
1002
|
/**
|
|
1430
|
-
* Detect
|
|
1003
|
+
* Detect Vite in project.
|
|
1431
1004
|
*
|
|
1432
1005
|
* @param projectPath - Project directory path
|
|
1433
1006
|
* @param packageJson - Optional pre-loaded package.json
|
|
1434
1007
|
* @returns Detection result or null if not detected
|
|
1008
|
+
*
|
|
1009
|
+
* @example Detecting Vite build tool
|
|
1010
|
+
* ```typescript
|
|
1011
|
+
* const result = viteDetector('/path/to/project', {
|
|
1012
|
+
* name: 'my-app',
|
|
1013
|
+
* devDependencies: {
|
|
1014
|
+
* 'vite': '^5.0.0',
|
|
1015
|
+
* '@vitejs/plugin-react': '^4.0.0',
|
|
1016
|
+
* 'vitest': '^1.0.0'
|
|
1017
|
+
* }
|
|
1018
|
+
* })
|
|
1019
|
+
* // => {
|
|
1020
|
+
* // id: 'vite',
|
|
1021
|
+
* // name: 'Vite',
|
|
1022
|
+
* // version: '5.0.0',
|
|
1023
|
+
* // confidence: 80,
|
|
1024
|
+
* // detectedFrom: [
|
|
1025
|
+
* // { type: 'package.json', field: 'dependencies.vite' },
|
|
1026
|
+
* // { type: 'package.json', field: 'dependencies.vitest' },
|
|
1027
|
+
* // { type: 'package.json', field: 'dependencies (vite plugins)' }
|
|
1028
|
+
* // ]
|
|
1029
|
+
* // }
|
|
1030
|
+
* ```
|
|
1435
1031
|
*/
|
|
1436
|
-
function
|
|
1032
|
+
function viteDetector(projectPath, packageJson) {
|
|
1437
1033
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1438
1034
|
const sources = [];
|
|
1439
1035
|
let confidence = 0;
|
|
1440
1036
|
let version;
|
|
1441
1037
|
const deps = collectAllDependencies(pkg);
|
|
1442
|
-
if (deps['
|
|
1038
|
+
if (deps['vite']) {
|
|
1443
1039
|
confidence += 60;
|
|
1444
|
-
version = parseVersionString(deps['
|
|
1445
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1040
|
+
version = parseVersionString(deps['vite']);
|
|
1041
|
+
sources.push({ type: 'package.json', field: 'dependencies.vite' });
|
|
1446
1042
|
}
|
|
1447
|
-
const configPath = locateConfigFile(projectPath,
|
|
1043
|
+
const configPath = locateConfigFile(projectPath, VITE_CONFIG_PATTERNS);
|
|
1448
1044
|
if (configPath) {
|
|
1449
1045
|
confidence += 35;
|
|
1450
1046
|
sources.push({ type: 'config-file', path: configPath });
|
|
1451
1047
|
}
|
|
1452
|
-
if (deps['
|
|
1048
|
+
if (deps['vitest']) {
|
|
1453
1049
|
confidence += 10;
|
|
1454
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1050
|
+
sources.push({ type: 'package.json', field: 'dependencies.vitest' });
|
|
1455
1051
|
}
|
|
1456
|
-
const
|
|
1457
|
-
if (
|
|
1458
|
-
confidence +=
|
|
1459
|
-
sources.push({ type: 'package.json', field: 'dependencies (
|
|
1052
|
+
const vitePlugins = keys(deps).filter((d) => d.startsWith('vite-plugin-') || d.startsWith('@vitejs/'));
|
|
1053
|
+
if (vitePlugins.length > 0) {
|
|
1054
|
+
confidence += 10;
|
|
1055
|
+
sources.push({ type: 'package.json', field: 'dependencies (vite plugins)' });
|
|
1460
1056
|
}
|
|
1461
1057
|
if (confidence === 0) {
|
|
1462
1058
|
return null;
|
|
1463
1059
|
}
|
|
1464
1060
|
return {
|
|
1465
|
-
id: '
|
|
1466
|
-
name: '
|
|
1061
|
+
id: 'vite',
|
|
1062
|
+
name: 'Vite',
|
|
1467
1063
|
version,
|
|
1468
1064
|
configPath,
|
|
1469
1065
|
confidence: min(confidence, 100),
|
|
@@ -1471,47 +1067,72 @@ function swcDetector(projectPath, packageJson) {
|
|
|
1471
1067
|
};
|
|
1472
1068
|
}
|
|
1473
1069
|
|
|
1474
|
-
/** Config patterns for
|
|
1475
|
-
const
|
|
1070
|
+
/** Config patterns for Webpack */
|
|
1071
|
+
const WEBPACK_CONFIG_PATTERNS = [
|
|
1072
|
+
'webpack.config.js',
|
|
1073
|
+
'webpack.config.ts',
|
|
1074
|
+
'webpack.config.cjs',
|
|
1075
|
+
'webpack.config.mjs',
|
|
1076
|
+
'webpack.config.babel.js',
|
|
1077
|
+
];
|
|
1476
1078
|
/**
|
|
1477
|
-
* Detect
|
|
1079
|
+
* Detect Webpack in project.
|
|
1478
1080
|
*
|
|
1479
1081
|
* @param projectPath - Project directory path
|
|
1480
1082
|
* @param packageJson - Optional pre-loaded package.json
|
|
1481
1083
|
* @returns Detection result or null if not detected
|
|
1084
|
+
*
|
|
1085
|
+
* @example Detecting Webpack bundler
|
|
1086
|
+
* ```typescript
|
|
1087
|
+
* const result = webpackDetector('/path/to/project', {
|
|
1088
|
+
* name: 'my-app',
|
|
1089
|
+
* devDependencies: { 'webpack': '^5.89.0', 'webpack-cli': '^5.1.0' },
|
|
1090
|
+
* scripts: { 'build': 'webpack --mode production' }
|
|
1091
|
+
* })
|
|
1092
|
+
* // => {
|
|
1093
|
+
* // id: 'webpack',
|
|
1094
|
+
* // name: 'Webpack',
|
|
1095
|
+
* // version: '5.89.0',
|
|
1096
|
+
* // confidence: 65,
|
|
1097
|
+
* // detectedFrom: [
|
|
1098
|
+
* // { type: 'package.json', field: 'dependencies.webpack' },
|
|
1099
|
+
* // { type: 'package.json', field: 'dependencies.webpack-cli' },
|
|
1100
|
+
* // { type: 'package.json', field: 'scripts.build' }
|
|
1101
|
+
* // ]
|
|
1102
|
+
* // }
|
|
1103
|
+
* ```
|
|
1482
1104
|
*/
|
|
1483
|
-
function
|
|
1105
|
+
function webpackDetector(projectPath, packageJson) {
|
|
1484
1106
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1485
1107
|
const sources = [];
|
|
1486
1108
|
let confidence = 0;
|
|
1487
1109
|
let version;
|
|
1488
1110
|
const deps = collectAllDependencies(pkg);
|
|
1489
|
-
if (deps['
|
|
1490
|
-
confidence +=
|
|
1491
|
-
version = parseVersionString(deps['
|
|
1492
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
1493
|
-
}
|
|
1494
|
-
if (deps['parcel-bundler']) {
|
|
1495
|
-
confidence += 60;
|
|
1496
|
-
version = parseVersionString(deps['parcel-bundler']);
|
|
1497
|
-
sources.push({ type: 'package.json', field: 'dependencies.parcel-bundler' });
|
|
1111
|
+
if (deps['webpack']) {
|
|
1112
|
+
confidence += 50;
|
|
1113
|
+
version = parseVersionString(deps['webpack']);
|
|
1114
|
+
sources.push({ type: 'package.json', field: 'dependencies.webpack' });
|
|
1498
1115
|
}
|
|
1499
|
-
const configPath = locateConfigFile(projectPath,
|
|
1116
|
+
const configPath = locateConfigFile(projectPath, WEBPACK_CONFIG_PATTERNS);
|
|
1500
1117
|
if (configPath) {
|
|
1501
|
-
confidence +=
|
|
1118
|
+
confidence += 40;
|
|
1502
1119
|
sources.push({ type: 'config-file', path: configPath });
|
|
1503
1120
|
}
|
|
1504
|
-
|
|
1121
|
+
if (deps['webpack-cli']) {
|
|
1122
|
+
confidence += 10;
|
|
1123
|
+
sources.push({ type: 'package.json', field: 'dependencies.webpack-cli' });
|
|
1124
|
+
}
|
|
1125
|
+
const scriptMatches = filterScriptsByCommand(pkg?.scripts, 'webpack');
|
|
1505
1126
|
for (const name of scriptMatches) {
|
|
1506
|
-
confidence = min(confidence +
|
|
1127
|
+
confidence = min(confidence + 5, 100);
|
|
1507
1128
|
sources.push({ type: 'package.json', field: `scripts.${name}` });
|
|
1508
1129
|
}
|
|
1509
1130
|
if (confidence === 0) {
|
|
1510
1131
|
return null;
|
|
1511
1132
|
}
|
|
1512
1133
|
return {
|
|
1513
|
-
id: '
|
|
1514
|
-
name: '
|
|
1134
|
+
id: 'webpack',
|
|
1135
|
+
name: 'Webpack',
|
|
1515
1136
|
version,
|
|
1516
1137
|
configPath,
|
|
1517
1138
|
confidence: min(confidence, 100),
|
|
@@ -1531,81 +1152,187 @@ const buildToolDetectors = [
|
|
|
1531
1152
|
];
|
|
1532
1153
|
|
|
1533
1154
|
/**
|
|
1534
|
-
* Detect
|
|
1155
|
+
* Detect Angular in project.
|
|
1535
1156
|
*
|
|
1536
1157
|
* @param projectPath - Project directory path
|
|
1537
1158
|
* @param packageJson - Optional pre-loaded package.json
|
|
1538
1159
|
* @returns Detection result or null if not detected
|
|
1160
|
+
*
|
|
1161
|
+
* @example Detecting Angular framework
|
|
1162
|
+
* ```typescript
|
|
1163
|
+
* const result = angularDetector('/path/to/angular-app', {
|
|
1164
|
+
* dependencies: { '@angular/core': '^17.0.0', '@angular/cli': '^17.0.0' }
|
|
1165
|
+
* })
|
|
1166
|
+
* // => {
|
|
1167
|
+
* // id: 'angular',
|
|
1168
|
+
* // name: 'Angular',
|
|
1169
|
+
* // category: 'frontend',
|
|
1170
|
+
* // version: '17.0.0',
|
|
1171
|
+
* // confidence: 85,
|
|
1172
|
+
* // detectedFrom: [
|
|
1173
|
+
* // { type: 'package.json', field: 'dependencies.@angular/core' },
|
|
1174
|
+
* // { type: 'package.json', field: 'dependencies.@angular/cli' }
|
|
1175
|
+
* // ]
|
|
1176
|
+
* // }
|
|
1177
|
+
* ```
|
|
1539
1178
|
*/
|
|
1540
|
-
function
|
|
1179
|
+
function angularDetector(projectPath, packageJson) {
|
|
1541
1180
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1542
1181
|
const sources = [];
|
|
1543
1182
|
let confidence = 0;
|
|
1544
1183
|
let version;
|
|
1545
|
-
const metaFrameworks = [];
|
|
1546
1184
|
const deps = collectAllDependencies(pkg);
|
|
1547
|
-
if (deps['
|
|
1548
|
-
confidence +=
|
|
1549
|
-
version = parseVersionString(deps['
|
|
1550
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1185
|
+
if (deps['@angular/core']) {
|
|
1186
|
+
confidence += 70;
|
|
1187
|
+
version = parseVersionString(deps['@angular/core']);
|
|
1188
|
+
sources.push({ type: 'package.json', field: 'dependencies.@angular/core' });
|
|
1551
1189
|
}
|
|
1552
|
-
if (deps['
|
|
1553
|
-
confidence +=
|
|
1554
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1190
|
+
if (deps['@angular/cli']) {
|
|
1191
|
+
confidence += 15;
|
|
1192
|
+
sources.push({ type: 'package.json', field: 'dependencies.@angular/cli' });
|
|
1555
1193
|
}
|
|
1556
|
-
if (
|
|
1557
|
-
confidence +=
|
|
1558
|
-
sources.push({ type: '
|
|
1194
|
+
if (exists(join$1(projectPath, 'angular.json'))) {
|
|
1195
|
+
confidence += 15;
|
|
1196
|
+
sources.push({ type: 'config-file', path: 'angular.json' });
|
|
1559
1197
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1198
|
+
if (deps['angular'] && !deps['@angular/core']) {
|
|
1199
|
+
return {
|
|
1200
|
+
id: 'angularjs',
|
|
1201
|
+
name: 'AngularJS (Legacy)',
|
|
1202
|
+
category: 'frontend',
|
|
1203
|
+
version: parseVersionString(deps['angular']),
|
|
1204
|
+
confidence: 80,
|
|
1205
|
+
detectedFrom: [{ type: 'package.json', field: 'dependencies.angular' }],
|
|
1206
|
+
};
|
|
1567
1207
|
}
|
|
1568
|
-
if (
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1208
|
+
if (confidence === 0) {
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
return {
|
|
1212
|
+
id: 'angular',
|
|
1213
|
+
name: 'Angular',
|
|
1214
|
+
category: 'frontend',
|
|
1215
|
+
version,
|
|
1216
|
+
confidence: min(confidence, 100),
|
|
1217
|
+
detectedFrom: sources,
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Detect Astro in project.
|
|
1223
|
+
*
|
|
1224
|
+
* @param projectPath - Project directory path
|
|
1225
|
+
* @param packageJson - Optional pre-loaded package.json
|
|
1226
|
+
* @returns Detection result or null if not detected
|
|
1227
|
+
*
|
|
1228
|
+
* @example Detecting Astro framework
|
|
1229
|
+
* ```typescript
|
|
1230
|
+
* const result = astroDetector('/path/to/astro-project', {
|
|
1231
|
+
* dependencies: { 'astro': '^4.0.0' }
|
|
1232
|
+
* })
|
|
1233
|
+
* // => {
|
|
1234
|
+
* // id: 'astro',
|
|
1235
|
+
* // name: 'Astro',
|
|
1236
|
+
* // category: 'meta-framework',
|
|
1237
|
+
* // version: '4.0.0',
|
|
1238
|
+
* // confidence: 70,
|
|
1239
|
+
* // detectedFrom: [{ type: 'package.json', field: 'dependencies.astro' }]
|
|
1240
|
+
* // }
|
|
1241
|
+
* ```
|
|
1242
|
+
*/
|
|
1243
|
+
function astroDetector(projectPath, packageJson) {
|
|
1244
|
+
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1245
|
+
const sources = [];
|
|
1246
|
+
let confidence = 0;
|
|
1247
|
+
let version;
|
|
1248
|
+
const deps = collectAllDependencies(pkg);
|
|
1249
|
+
if (deps['astro']) {
|
|
1250
|
+
confidence += 70;
|
|
1251
|
+
version = parseVersionString(deps['astro']);
|
|
1252
|
+
sources.push({ type: 'package.json', field: 'dependencies.astro' });
|
|
1253
|
+
}
|
|
1254
|
+
if (exists(join$1(projectPath, 'astro.config.mjs')) ||
|
|
1255
|
+
exists(join$1(projectPath, 'astro.config.ts')) ||
|
|
1256
|
+
exists(join$1(projectPath, 'astro.config.js'))) {
|
|
1257
|
+
confidence += 25;
|
|
1258
|
+
sources.push({ type: 'config-file', path: 'astro.config.*' });
|
|
1259
|
+
}
|
|
1260
|
+
if (exists(join$1(projectPath, 'src', 'pages'))) {
|
|
1261
|
+
confidence += 5;
|
|
1262
|
+
sources.push({ type: 'directory', path: 'src/pages/' });
|
|
1263
|
+
}
|
|
1264
|
+
if (confidence === 0) {
|
|
1265
|
+
return null;
|
|
1577
1266
|
}
|
|
1267
|
+
return {
|
|
1268
|
+
id: 'astro',
|
|
1269
|
+
name: 'Astro',
|
|
1270
|
+
category: 'meta-framework',
|
|
1271
|
+
version,
|
|
1272
|
+
confidence: min(confidence, 100),
|
|
1273
|
+
detectedFrom: sources,
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* Detect Gatsby in project.
|
|
1279
|
+
*
|
|
1280
|
+
* @param projectPath - Project directory path
|
|
1281
|
+
* @param packageJson - Optional pre-loaded package.json
|
|
1282
|
+
* @returns Detection result or null if not detected
|
|
1283
|
+
*
|
|
1284
|
+
* @example Detecting Gatsby framework
|
|
1285
|
+
* ```typescript
|
|
1286
|
+
* const result = gatsbyDetector('/path/to/gatsby-blog', {
|
|
1287
|
+
* dependencies: {
|
|
1288
|
+
* 'gatsby': '^5.0.0',
|
|
1289
|
+
* 'gatsby-plugin-image': '^3.0.0',
|
|
1290
|
+
* 'gatsby-source-filesystem': '^5.0.0'
|
|
1291
|
+
* }
|
|
1292
|
+
* })
|
|
1293
|
+
* // => {
|
|
1294
|
+
* // id: 'gatsby',
|
|
1295
|
+
* // name: 'Gatsby',
|
|
1296
|
+
* // category: 'meta-framework',
|
|
1297
|
+
* // version: '5.0.0',
|
|
1298
|
+
* // confidence: 75,
|
|
1299
|
+
* // detectedFrom: [
|
|
1300
|
+
* // { type: 'package.json', field: 'dependencies.gatsby' },
|
|
1301
|
+
* // { type: 'package.json', field: 'dependencies (gatsby plugins)' }
|
|
1302
|
+
* // ]
|
|
1303
|
+
* // }
|
|
1304
|
+
* ```
|
|
1305
|
+
*/
|
|
1306
|
+
function gatsbyDetector(projectPath, packageJson) {
|
|
1307
|
+
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1308
|
+
const sources = [];
|
|
1309
|
+
let confidence = 0;
|
|
1310
|
+
let version;
|
|
1311
|
+
const deps = collectAllDependencies(pkg);
|
|
1578
1312
|
if (deps['gatsby']) {
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
category: 'meta-framework',
|
|
1583
|
-
version: parseVersionString(deps['gatsby']),
|
|
1584
|
-
confidence: 90,
|
|
1585
|
-
detectedFrom: [{ type: 'package.json', field: 'dependencies.gatsby' }],
|
|
1586
|
-
});
|
|
1313
|
+
confidence += 70;
|
|
1314
|
+
version = parseVersionString(deps['gatsby']);
|
|
1315
|
+
sources.push({ type: 'package.json', field: 'dependencies.gatsby' });
|
|
1587
1316
|
}
|
|
1588
|
-
if (
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
});
|
|
1317
|
+
if (exists(join$1(projectPath, 'gatsby-config.js')) || exists(join$1(projectPath, 'gatsby-config.ts'))) {
|
|
1318
|
+
confidence += 25;
|
|
1319
|
+
sources.push({ type: 'config-file', path: 'gatsby-config.*' });
|
|
1320
|
+
}
|
|
1321
|
+
const gatsbyPlugins = keys(deps).filter((d) => d.startsWith('gatsby-plugin-') || d.startsWith('gatsby-source-'));
|
|
1322
|
+
if (gatsbyPlugins.length > 0) {
|
|
1323
|
+
confidence += 5;
|
|
1324
|
+
sources.push({ type: 'package.json', field: 'dependencies (gatsby plugins)' });
|
|
1597
1325
|
}
|
|
1598
1326
|
if (confidence === 0) {
|
|
1599
1327
|
return null;
|
|
1600
1328
|
}
|
|
1601
1329
|
return {
|
|
1602
|
-
id: '
|
|
1603
|
-
name: '
|
|
1604
|
-
category: '
|
|
1330
|
+
id: 'gatsby',
|
|
1331
|
+
name: 'Gatsby',
|
|
1332
|
+
category: 'meta-framework',
|
|
1605
1333
|
version,
|
|
1606
1334
|
confidence: min(confidence, 100),
|
|
1607
1335
|
detectedFrom: sources,
|
|
1608
|
-
metaFrameworks: metaFrameworks.length > 0 ? metaFrameworks : undefined,
|
|
1609
1336
|
};
|
|
1610
1337
|
}
|
|
1611
1338
|
|
|
@@ -1615,6 +1342,21 @@ function reactDetector(projectPath, packageJson) {
|
|
|
1615
1342
|
* @param projectPath - Project directory path
|
|
1616
1343
|
* @param packageJson - Optional pre-loaded package.json
|
|
1617
1344
|
* @returns Detection result or null if not detected
|
|
1345
|
+
*
|
|
1346
|
+
* @example Detecting Next.js framework
|
|
1347
|
+
* ```typescript
|
|
1348
|
+
* const result = nextjsDetector('/path/to/nextjs-app', {
|
|
1349
|
+
* dependencies: { 'next': '^14.0.0', 'react': '^18.0.0' }
|
|
1350
|
+
* })
|
|
1351
|
+
* // => {
|
|
1352
|
+
* // id: 'nextjs',
|
|
1353
|
+
* // name: 'Next.js',
|
|
1354
|
+
* // category: 'meta-framework',
|
|
1355
|
+
* // version: '14.0.0',
|
|
1356
|
+
* // confidence: 70,
|
|
1357
|
+
* // detectedFrom: [{ type: 'package.json', field: 'dependencies.next' }]
|
|
1358
|
+
* // }
|
|
1359
|
+
* ```
|
|
1618
1360
|
*/
|
|
1619
1361
|
function nextjsDetector(projectPath, packageJson) {
|
|
1620
1362
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -1654,37 +1396,52 @@ function nextjsDetector(projectPath, packageJson) {
|
|
|
1654
1396
|
}
|
|
1655
1397
|
|
|
1656
1398
|
/**
|
|
1657
|
-
* Detect
|
|
1399
|
+
* Detect Nuxt in project.
|
|
1658
1400
|
*
|
|
1659
1401
|
* @param projectPath - Project directory path
|
|
1660
1402
|
* @param packageJson - Optional pre-loaded package.json
|
|
1661
1403
|
* @returns Detection result or null if not detected
|
|
1404
|
+
*
|
|
1405
|
+
* @example Detecting Nuxt framework
|
|
1406
|
+
* ```typescript
|
|
1407
|
+
* const result = nuxtDetector('/path/to/nuxt-app', {
|
|
1408
|
+
* dependencies: { 'nuxt': '^3.0.0', 'vue': '^3.0.0' }
|
|
1409
|
+
* })
|
|
1410
|
+
* // => {
|
|
1411
|
+
* // id: 'nuxt',
|
|
1412
|
+
* // name: 'Nuxt',
|
|
1413
|
+
* // category: 'meta-framework',
|
|
1414
|
+
* // version: '3.0.0',
|
|
1415
|
+
* // confidence: 70,
|
|
1416
|
+
* // detectedFrom: [{ type: 'package.json', field: 'dependencies.nuxt' }]
|
|
1417
|
+
* // }
|
|
1418
|
+
* ```
|
|
1662
1419
|
*/
|
|
1663
|
-
function
|
|
1420
|
+
function nuxtDetector(projectPath, packageJson) {
|
|
1664
1421
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1665
1422
|
const sources = [];
|
|
1666
1423
|
let confidence = 0;
|
|
1667
1424
|
let version;
|
|
1668
1425
|
const deps = collectAllDependencies(pkg);
|
|
1669
|
-
if (deps['
|
|
1426
|
+
if (deps['nuxt'] || deps['nuxt3']) {
|
|
1670
1427
|
confidence += 70;
|
|
1671
|
-
version = parseVersionString(deps['
|
|
1672
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1428
|
+
version = parseVersionString(deps['nuxt'] ?? deps['nuxt3']);
|
|
1429
|
+
sources.push({ type: 'package.json', field: 'dependencies.nuxt' });
|
|
1673
1430
|
}
|
|
1674
|
-
if (
|
|
1675
|
-
confidence +=
|
|
1676
|
-
sources.push({ type: '
|
|
1431
|
+
if (exists(join$1(projectPath, 'nuxt.config.js')) || exists(join$1(projectPath, 'nuxt.config.ts'))) {
|
|
1432
|
+
confidence += 25;
|
|
1433
|
+
sources.push({ type: 'config-file', path: 'nuxt.config.*' });
|
|
1677
1434
|
}
|
|
1678
|
-
if (exists(join$1(projectPath, '
|
|
1679
|
-
confidence +=
|
|
1680
|
-
sources.push({ type: '
|
|
1435
|
+
if (exists(join$1(projectPath, 'pages'))) {
|
|
1436
|
+
confidence += 5;
|
|
1437
|
+
sources.push({ type: 'directory', path: 'pages/' });
|
|
1681
1438
|
}
|
|
1682
1439
|
if (confidence === 0) {
|
|
1683
1440
|
return null;
|
|
1684
1441
|
}
|
|
1685
1442
|
return {
|
|
1686
|
-
id: '
|
|
1687
|
-
name: '
|
|
1443
|
+
id: 'nuxt',
|
|
1444
|
+
name: 'Nuxt',
|
|
1688
1445
|
category: 'meta-framework',
|
|
1689
1446
|
version,
|
|
1690
1447
|
confidence: min(confidence, 100),
|
|
@@ -1693,39 +1450,59 @@ function remixDetector(projectPath, packageJson) {
|
|
|
1693
1450
|
}
|
|
1694
1451
|
|
|
1695
1452
|
/**
|
|
1696
|
-
* Detect
|
|
1453
|
+
* Detect Qwik in project.
|
|
1697
1454
|
*
|
|
1698
1455
|
* @param projectPath - Project directory path
|
|
1699
1456
|
* @param packageJson - Optional pre-loaded package.json
|
|
1700
1457
|
* @returns Detection result or null if not detected
|
|
1458
|
+
*
|
|
1459
|
+
* @example Detecting Qwik framework
|
|
1460
|
+
* ```typescript
|
|
1461
|
+
* const result = qwikDetector('/path/to/qwik-app', {
|
|
1462
|
+
* dependencies: {
|
|
1463
|
+
* '@builder.io/qwik': '^1.0.0',
|
|
1464
|
+
* '@builder.io/qwik-city': '^1.0.0'
|
|
1465
|
+
* }
|
|
1466
|
+
* })
|
|
1467
|
+
* // => {
|
|
1468
|
+
* // id: 'qwik',
|
|
1469
|
+
* // name: 'Qwik',
|
|
1470
|
+
* // category: 'frontend',
|
|
1471
|
+
* // version: '1.0.0',
|
|
1472
|
+
* // confidence: 90,
|
|
1473
|
+
* // detectedFrom: [
|
|
1474
|
+
* // { type: 'package.json', field: 'dependencies.@builder.io/qwik' },
|
|
1475
|
+
* // { type: 'package.json', field: 'dependencies.@builder.io/qwik-city' }
|
|
1476
|
+
* // ]
|
|
1477
|
+
* // }
|
|
1478
|
+
* ```
|
|
1701
1479
|
*/
|
|
1702
|
-
function
|
|
1480
|
+
function qwikDetector(projectPath, packageJson) {
|
|
1703
1481
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1704
1482
|
const sources = [];
|
|
1705
1483
|
let confidence = 0;
|
|
1706
1484
|
let version;
|
|
1707
1485
|
const deps = collectAllDependencies(pkg);
|
|
1708
|
-
if (deps['
|
|
1486
|
+
if (deps['@builder.io/qwik']) {
|
|
1709
1487
|
confidence += 70;
|
|
1710
|
-
version = parseVersionString(deps['
|
|
1711
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
1488
|
+
version = parseVersionString(deps['@builder.io/qwik']);
|
|
1489
|
+
sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik' });
|
|
1712
1490
|
}
|
|
1713
|
-
if (
|
|
1714
|
-
confidence +=
|
|
1715
|
-
sources.push({ type: '
|
|
1491
|
+
if (deps['@builder.io/qwik-city']) {
|
|
1492
|
+
confidence += 20;
|
|
1493
|
+
sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik-city' });
|
|
1716
1494
|
}
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
sources.push({ type: 'package.json', field: 'dependencies (gatsby plugins)' });
|
|
1495
|
+
if (exists(join$1(projectPath, 'qwik.config.ts')) || exists(join$1(projectPath, 'qwik.config.js'))) {
|
|
1496
|
+
confidence += 10;
|
|
1497
|
+
sources.push({ type: 'config-file', path: 'qwik.config.*' });
|
|
1721
1498
|
}
|
|
1722
1499
|
if (confidence === 0) {
|
|
1723
1500
|
return null;
|
|
1724
1501
|
}
|
|
1725
1502
|
return {
|
|
1726
|
-
id: '
|
|
1727
|
-
name: '
|
|
1728
|
-
category: '
|
|
1503
|
+
id: 'qwik',
|
|
1504
|
+
name: 'Qwik',
|
|
1505
|
+
category: 'frontend',
|
|
1729
1506
|
version,
|
|
1730
1507
|
confidence: min(confidence, 100),
|
|
1731
1508
|
detectedFrom: sources,
|
|
@@ -1733,53 +1510,94 @@ function gatsbyDetector(projectPath, packageJson) {
|
|
|
1733
1510
|
}
|
|
1734
1511
|
|
|
1735
1512
|
/**
|
|
1736
|
-
* Detect
|
|
1513
|
+
* Detect React in project.
|
|
1737
1514
|
*
|
|
1738
1515
|
* @param projectPath - Project directory path
|
|
1739
1516
|
* @param packageJson - Optional pre-loaded package.json
|
|
1740
1517
|
* @returns Detection result or null if not detected
|
|
1518
|
+
*
|
|
1519
|
+
* @example Detecting React library
|
|
1520
|
+
* ```typescript
|
|
1521
|
+
* const result = reactDetector('/path/to/react-app', {
|
|
1522
|
+
* dependencies: { 'react': '^18.0.0', 'react-dom': '^18.0.0' }
|
|
1523
|
+
* })
|
|
1524
|
+
* // => {
|
|
1525
|
+
* // id: 'react',
|
|
1526
|
+
* // name: 'React',
|
|
1527
|
+
* // category: 'frontend',
|
|
1528
|
+
* // version: '18.0.0',
|
|
1529
|
+
* // confidence: 80,
|
|
1530
|
+
* // detectedFrom: [
|
|
1531
|
+
* // { type: 'package.json', field: 'dependencies.react' },
|
|
1532
|
+
* // { type: 'package.json', field: 'dependencies.react-dom' }
|
|
1533
|
+
* // ]
|
|
1534
|
+
* // }
|
|
1535
|
+
* ```
|
|
1741
1536
|
*/
|
|
1742
|
-
function
|
|
1537
|
+
function reactDetector(projectPath, packageJson) {
|
|
1743
1538
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1744
1539
|
const sources = [];
|
|
1745
1540
|
let confidence = 0;
|
|
1746
1541
|
let version;
|
|
1747
1542
|
const metaFrameworks = [];
|
|
1748
1543
|
const deps = collectAllDependencies(pkg);
|
|
1749
|
-
if (deps['
|
|
1750
|
-
confidence +=
|
|
1751
|
-
version = parseVersionString(deps['
|
|
1752
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
1544
|
+
if (deps['react']) {
|
|
1545
|
+
confidence += 60;
|
|
1546
|
+
version = parseVersionString(deps['react']);
|
|
1547
|
+
sources.push({ type: 'package.json', field: 'dependencies.react' });
|
|
1753
1548
|
}
|
|
1754
|
-
if (deps['
|
|
1755
|
-
confidence +=
|
|
1756
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1549
|
+
if (deps['react-dom']) {
|
|
1550
|
+
confidence += 20;
|
|
1551
|
+
sources.push({ type: 'package.json', field: 'dependencies.react-dom' });
|
|
1757
1552
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1553
|
+
if (deps['react-native']) {
|
|
1554
|
+
confidence += 20;
|
|
1555
|
+
sources.push({ type: 'package.json', field: 'dependencies.react-native' });
|
|
1556
|
+
}
|
|
1557
|
+
const hasJsxFiles = exists(join$1(projectPath, 'src', 'App.tsx')) ||
|
|
1558
|
+
exists(join$1(projectPath, 'src', 'App.jsx')) ||
|
|
1559
|
+
exists(join$1(projectPath, 'src', 'index.tsx')) ||
|
|
1560
|
+
exists(join$1(projectPath, 'src', 'index.jsx'));
|
|
1561
|
+
if (hasJsxFiles) {
|
|
1760
1562
|
confidence += 10;
|
|
1761
|
-
sources.push({ type: 'directory', path: 'src/*.
|
|
1563
|
+
sources.push({ type: 'directory', path: 'src/*.tsx or src/*.jsx' });
|
|
1762
1564
|
}
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
|
|
1565
|
+
if (deps['next']) {
|
|
1566
|
+
metaFrameworks.push({
|
|
1567
|
+
id: 'nextjs',
|
|
1568
|
+
name: 'Next.js',
|
|
1569
|
+
category: 'meta-framework',
|
|
1570
|
+
version: parseVersionString(deps['next']),
|
|
1571
|
+
confidence: 90,
|
|
1572
|
+
detectedFrom: [{ type: 'package.json', field: 'dependencies.next' }],
|
|
1573
|
+
});
|
|
1766
1574
|
}
|
|
1767
|
-
if (deps['
|
|
1575
|
+
if (deps['gatsby']) {
|
|
1768
1576
|
metaFrameworks.push({
|
|
1769
|
-
id: '
|
|
1770
|
-
name: '
|
|
1577
|
+
id: 'gatsby',
|
|
1578
|
+
name: 'Gatsby',
|
|
1771
1579
|
category: 'meta-framework',
|
|
1772
|
-
version: parseVersionString(deps['
|
|
1580
|
+
version: parseVersionString(deps['gatsby']),
|
|
1773
1581
|
confidence: 90,
|
|
1774
|
-
detectedFrom: [{ type: 'package.json', field: 'dependencies.
|
|
1582
|
+
detectedFrom: [{ type: 'package.json', field: 'dependencies.gatsby' }],
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
if (deps['@remix-run/react'] || deps['remix']) {
|
|
1586
|
+
metaFrameworks.push({
|
|
1587
|
+
id: 'remix',
|
|
1588
|
+
name: 'Remix',
|
|
1589
|
+
category: 'meta-framework',
|
|
1590
|
+
version: parseVersionString(deps['@remix-run/react'] ?? deps['remix']),
|
|
1591
|
+
confidence: 90,
|
|
1592
|
+
detectedFrom: [{ type: 'package.json', field: 'dependencies.@remix-run/react' }],
|
|
1775
1593
|
});
|
|
1776
1594
|
}
|
|
1777
1595
|
if (confidence === 0) {
|
|
1778
1596
|
return null;
|
|
1779
1597
|
}
|
|
1780
1598
|
return {
|
|
1781
|
-
id: '
|
|
1782
|
-
name: '
|
|
1599
|
+
id: 'react',
|
|
1600
|
+
name: 'React',
|
|
1783
1601
|
category: 'frontend',
|
|
1784
1602
|
version,
|
|
1785
1603
|
confidence: min(confidence, 100),
|
|
@@ -1789,37 +1607,58 @@ function vueDetector(projectPath, packageJson) {
|
|
|
1789
1607
|
}
|
|
1790
1608
|
|
|
1791
1609
|
/**
|
|
1792
|
-
* Detect
|
|
1610
|
+
* Detect Remix in project.
|
|
1793
1611
|
*
|
|
1794
1612
|
* @param projectPath - Project directory path
|
|
1795
1613
|
* @param packageJson - Optional pre-loaded package.json
|
|
1796
1614
|
* @returns Detection result or null if not detected
|
|
1615
|
+
*
|
|
1616
|
+
* @example Detecting Remix framework
|
|
1617
|
+
* ```typescript
|
|
1618
|
+
* const result = remixDetector('/path/to/remix-app', {
|
|
1619
|
+
* dependencies: {
|
|
1620
|
+
* '@remix-run/react': '^2.0.0',
|
|
1621
|
+
* '@remix-run/node': '^2.0.0'
|
|
1622
|
+
* }
|
|
1623
|
+
* })
|
|
1624
|
+
* // => {
|
|
1625
|
+
* // id: 'remix',
|
|
1626
|
+
* // name: 'Remix',
|
|
1627
|
+
* // category: 'meta-framework',
|
|
1628
|
+
* // version: '2.0.0',
|
|
1629
|
+
* // confidence: 90,
|
|
1630
|
+
* // detectedFrom: [
|
|
1631
|
+
* // { type: 'package.json', field: 'dependencies.@remix-run/react' },
|
|
1632
|
+
* // { type: 'package.json', field: 'dependencies.@remix-run/*' }
|
|
1633
|
+
* // ]
|
|
1634
|
+
* // }
|
|
1635
|
+
* ```
|
|
1797
1636
|
*/
|
|
1798
|
-
function
|
|
1637
|
+
function remixDetector(projectPath, packageJson) {
|
|
1799
1638
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1800
1639
|
const sources = [];
|
|
1801
1640
|
let confidence = 0;
|
|
1802
1641
|
let version;
|
|
1803
1642
|
const deps = collectAllDependencies(pkg);
|
|
1804
|
-
if (deps['
|
|
1643
|
+
if (deps['@remix-run/react']) {
|
|
1805
1644
|
confidence += 70;
|
|
1806
|
-
version = parseVersionString(deps['
|
|
1807
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1645
|
+
version = parseVersionString(deps['@remix-run/react']);
|
|
1646
|
+
sources.push({ type: 'package.json', field: 'dependencies.@remix-run/react' });
|
|
1808
1647
|
}
|
|
1809
|
-
if (
|
|
1810
|
-
confidence +=
|
|
1811
|
-
sources.push({ type: '
|
|
1648
|
+
if (deps['@remix-run/node'] || deps['@remix-run/cloudflare'] || deps['@remix-run/deno']) {
|
|
1649
|
+
confidence += 20;
|
|
1650
|
+
sources.push({ type: 'package.json', field: 'dependencies.@remix-run/*' });
|
|
1812
1651
|
}
|
|
1813
|
-
if (exists(join$1(projectPath, '
|
|
1814
|
-
confidence +=
|
|
1815
|
-
sources.push({ type: '
|
|
1652
|
+
if (exists(join$1(projectPath, 'remix.config.js')) || exists(join$1(projectPath, 'remix.config.ts'))) {
|
|
1653
|
+
confidence += 10;
|
|
1654
|
+
sources.push({ type: 'config-file', path: 'remix.config.*' });
|
|
1816
1655
|
}
|
|
1817
1656
|
if (confidence === 0) {
|
|
1818
1657
|
return null;
|
|
1819
1658
|
}
|
|
1820
1659
|
return {
|
|
1821
|
-
id: '
|
|
1822
|
-
name: '
|
|
1660
|
+
id: 'remix',
|
|
1661
|
+
name: 'Remix',
|
|
1823
1662
|
category: 'meta-framework',
|
|
1824
1663
|
version,
|
|
1825
1664
|
confidence: min(confidence, 100),
|
|
@@ -1828,47 +1667,55 @@ function nuxtDetector(projectPath, packageJson) {
|
|
|
1828
1667
|
}
|
|
1829
1668
|
|
|
1830
1669
|
/**
|
|
1831
|
-
* Detect
|
|
1670
|
+
* Detect Solid in project.
|
|
1832
1671
|
*
|
|
1833
1672
|
* @param projectPath - Project directory path
|
|
1834
1673
|
* @param packageJson - Optional pre-loaded package.json
|
|
1835
1674
|
* @returns Detection result or null if not detected
|
|
1675
|
+
*
|
|
1676
|
+
* @example Detecting Solid.js framework
|
|
1677
|
+
* ```typescript
|
|
1678
|
+
* const result = solidDetector('/path/to/solid-app', {
|
|
1679
|
+
* dependencies: { 'solid-js': '^1.8.0', 'vite-plugin-solid': '^2.0.0' }
|
|
1680
|
+
* })
|
|
1681
|
+
* // => {
|
|
1682
|
+
* // id: 'solid',
|
|
1683
|
+
* // name: 'Solid',
|
|
1684
|
+
* // category: 'frontend',
|
|
1685
|
+
* // version: '1.8.0',
|
|
1686
|
+
* // confidence: 90,
|
|
1687
|
+
* // detectedFrom: [
|
|
1688
|
+
* // { type: 'package.json', field: 'dependencies.solid-js' },
|
|
1689
|
+
* // { type: 'package.json', field: 'dependencies.vite-plugin-solid' }
|
|
1690
|
+
* // ]
|
|
1691
|
+
* // }
|
|
1692
|
+
* ```
|
|
1836
1693
|
*/
|
|
1837
|
-
function
|
|
1694
|
+
function solidDetector(projectPath, packageJson) {
|
|
1838
1695
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1839
1696
|
const sources = [];
|
|
1840
1697
|
let confidence = 0;
|
|
1841
1698
|
let version;
|
|
1842
1699
|
const deps = collectAllDependencies(pkg);
|
|
1843
|
-
if (deps['
|
|
1700
|
+
if (deps['solid-js']) {
|
|
1844
1701
|
confidence += 70;
|
|
1845
|
-
version = parseVersionString(deps['
|
|
1846
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1847
|
-
}
|
|
1848
|
-
if (deps['@angular/cli']) {
|
|
1849
|
-
confidence += 15;
|
|
1850
|
-
sources.push({ type: 'package.json', field: 'dependencies.@angular/cli' });
|
|
1702
|
+
version = parseVersionString(deps['solid-js']);
|
|
1703
|
+
sources.push({ type: 'package.json', field: 'dependencies.solid-js' });
|
|
1851
1704
|
}
|
|
1852
|
-
if (
|
|
1853
|
-
confidence +=
|
|
1854
|
-
sources.push({ type: '
|
|
1705
|
+
if (deps['vite-plugin-solid']) {
|
|
1706
|
+
confidence += 20;
|
|
1707
|
+
sources.push({ type: 'package.json', field: 'dependencies.vite-plugin-solid' });
|
|
1855
1708
|
}
|
|
1856
|
-
if (deps['
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
name: 'AngularJS (Legacy)',
|
|
1860
|
-
category: 'frontend',
|
|
1861
|
-
version: parseVersionString(deps['angular']),
|
|
1862
|
-
confidence: 80,
|
|
1863
|
-
detectedFrom: [{ type: 'package.json', field: 'dependencies.angular' }],
|
|
1864
|
-
};
|
|
1709
|
+
if (deps['solid-start'] || deps['@solidjs/start']) {
|
|
1710
|
+
confidence += 10;
|
|
1711
|
+
sources.push({ type: 'package.json', field: 'dependencies.solid-start' });
|
|
1865
1712
|
}
|
|
1866
1713
|
if (confidence === 0) {
|
|
1867
1714
|
return null;
|
|
1868
1715
|
}
|
|
1869
1716
|
return {
|
|
1870
|
-
id: '
|
|
1871
|
-
name: '
|
|
1717
|
+
id: 'solid',
|
|
1718
|
+
name: 'Solid',
|
|
1872
1719
|
category: 'frontend',
|
|
1873
1720
|
version,
|
|
1874
1721
|
confidence: min(confidence, 100),
|
|
@@ -1882,6 +1729,21 @@ function angularDetector(projectPath, packageJson) {
|
|
|
1882
1729
|
* @param projectPath - Project directory path
|
|
1883
1730
|
* @param packageJson - Optional pre-loaded package.json
|
|
1884
1731
|
* @returns Detection result or null if not detected
|
|
1732
|
+
*
|
|
1733
|
+
* @example Detecting Svelte framework
|
|
1734
|
+
* ```typescript
|
|
1735
|
+
* const result = svelteDetector('/path/to/svelte-app', {
|
|
1736
|
+
* devDependencies: { 'svelte': '^4.0.0' }
|
|
1737
|
+
* })
|
|
1738
|
+
* // => {
|
|
1739
|
+
* // id: 'svelte',
|
|
1740
|
+
* // name: 'Svelte',
|
|
1741
|
+
* // category: 'frontend',
|
|
1742
|
+
* // version: '4.0.0',
|
|
1743
|
+
* // confidence: 70,
|
|
1744
|
+
* // detectedFrom: [{ type: 'package.json', field: 'dependencies.svelte' }]
|
|
1745
|
+
* // }
|
|
1746
|
+
* ```
|
|
1885
1747
|
*/
|
|
1886
1748
|
function svelteDetector(projectPath, packageJson) {
|
|
1887
1749
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -1934,6 +1796,21 @@ function svelteDetector(projectPath, packageJson) {
|
|
|
1934
1796
|
* @param projectPath - Project directory path
|
|
1935
1797
|
* @param packageJson - Optional pre-loaded package.json
|
|
1936
1798
|
* @returns Detection result or null if not detected
|
|
1799
|
+
*
|
|
1800
|
+
* @example Detecting SvelteKit framework
|
|
1801
|
+
* ```typescript
|
|
1802
|
+
* const result = sveltekitDetector('/path/to/sveltekit-app', {
|
|
1803
|
+
* devDependencies: { '@sveltejs/kit': '^2.0.0', 'svelte': '^4.0.0' }
|
|
1804
|
+
* })
|
|
1805
|
+
* // => {
|
|
1806
|
+
* // id: 'sveltekit',
|
|
1807
|
+
* // name: 'SvelteKit',
|
|
1808
|
+
* // category: 'meta-framework',
|
|
1809
|
+
* // version: '2.0.0',
|
|
1810
|
+
* // confidence: 70,
|
|
1811
|
+
* // detectedFrom: [{ type: 'package.json', field: 'dependencies.@sveltejs/kit' }]
|
|
1812
|
+
* // }
|
|
1813
|
+
* ```
|
|
1937
1814
|
*/
|
|
1938
1815
|
function sveltekitDetector(projectPath, packageJson) {
|
|
1939
1816
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -1968,121 +1845,76 @@ function sveltekitDetector(projectPath, packageJson) {
|
|
|
1968
1845
|
}
|
|
1969
1846
|
|
|
1970
1847
|
/**
|
|
1971
|
-
* Detect
|
|
1848
|
+
* Detect Vue in project.
|
|
1972
1849
|
*
|
|
1973
1850
|
* @param projectPath - Project directory path
|
|
1974
1851
|
* @param packageJson - Optional pre-loaded package.json
|
|
1975
1852
|
* @returns Detection result or null if not detected
|
|
1976
|
-
*/
|
|
1977
|
-
function solidDetector(projectPath, packageJson) {
|
|
1978
|
-
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
1979
|
-
const sources = [];
|
|
1980
|
-
let confidence = 0;
|
|
1981
|
-
let version;
|
|
1982
|
-
const deps = collectAllDependencies(pkg);
|
|
1983
|
-
if (deps['solid-js']) {
|
|
1984
|
-
confidence += 70;
|
|
1985
|
-
version = parseVersionString(deps['solid-js']);
|
|
1986
|
-
sources.push({ type: 'package.json', field: 'dependencies.solid-js' });
|
|
1987
|
-
}
|
|
1988
|
-
if (deps['vite-plugin-solid']) {
|
|
1989
|
-
confidence += 20;
|
|
1990
|
-
sources.push({ type: 'package.json', field: 'dependencies.vite-plugin-solid' });
|
|
1991
|
-
}
|
|
1992
|
-
if (deps['solid-start'] || deps['@solidjs/start']) {
|
|
1993
|
-
confidence += 10;
|
|
1994
|
-
sources.push({ type: 'package.json', field: 'dependencies.solid-start' });
|
|
1995
|
-
}
|
|
1996
|
-
if (confidence === 0) {
|
|
1997
|
-
return null;
|
|
1998
|
-
}
|
|
1999
|
-
return {
|
|
2000
|
-
id: 'solid',
|
|
2001
|
-
name: 'Solid',
|
|
2002
|
-
category: 'frontend',
|
|
2003
|
-
version,
|
|
2004
|
-
confidence: min(confidence, 100),
|
|
2005
|
-
detectedFrom: sources,
|
|
2006
|
-
};
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
|
-
/**
|
|
2010
|
-
* Detect Qwik in project.
|
|
2011
1853
|
*
|
|
2012
|
-
* @
|
|
2013
|
-
*
|
|
2014
|
-
*
|
|
1854
|
+
* @example Detecting Vue.js framework
|
|
1855
|
+
* ```typescript
|
|
1856
|
+
* const result = vueDetector('/path/to/vue-app', {
|
|
1857
|
+
* dependencies: { 'vue': '^3.0.0', '@vue/cli-service': '^5.0.0' }
|
|
1858
|
+
* })
|
|
1859
|
+
* // => {
|
|
1860
|
+
* // id: 'vue',
|
|
1861
|
+
* // name: 'Vue',
|
|
1862
|
+
* // category: 'frontend',
|
|
1863
|
+
* // version: '3.0.0',
|
|
1864
|
+
* // confidence: 85,
|
|
1865
|
+
* // detectedFrom: [
|
|
1866
|
+
* // { type: 'package.json', field: 'dependencies.vue' },
|
|
1867
|
+
* // { type: 'package.json', field: 'dependencies.@vue/cli-service' }
|
|
1868
|
+
* // ]
|
|
1869
|
+
* // }
|
|
1870
|
+
* ```
|
|
2015
1871
|
*/
|
|
2016
|
-
function
|
|
1872
|
+
function vueDetector(projectPath, packageJson) {
|
|
2017
1873
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2018
1874
|
const sources = [];
|
|
2019
1875
|
let confidence = 0;
|
|
2020
1876
|
let version;
|
|
1877
|
+
const metaFrameworks = [];
|
|
2021
1878
|
const deps = collectAllDependencies(pkg);
|
|
2022
|
-
if (deps['
|
|
1879
|
+
if (deps['vue']) {
|
|
2023
1880
|
confidence += 70;
|
|
2024
|
-
version = parseVersionString(deps['
|
|
2025
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
1881
|
+
version = parseVersionString(deps['vue']);
|
|
1882
|
+
sources.push({ type: 'package.json', field: 'dependencies.vue' });
|
|
2026
1883
|
}
|
|
2027
|
-
if (deps['@
|
|
2028
|
-
confidence +=
|
|
2029
|
-
sources.push({ type: 'package.json', field: 'dependencies.@
|
|
1884
|
+
if (deps['@vue/cli-service']) {
|
|
1885
|
+
confidence += 15;
|
|
1886
|
+
sources.push({ type: 'package.json', field: 'dependencies.@vue/cli-service' });
|
|
2030
1887
|
}
|
|
2031
|
-
|
|
1888
|
+
const hasVueFiles = exists(join$1(projectPath, 'src', 'App.vue')) || exists(join$1(projectPath, 'src', 'main.vue'));
|
|
1889
|
+
if (hasVueFiles) {
|
|
2032
1890
|
confidence += 10;
|
|
2033
|
-
sources.push({ type: '
|
|
2034
|
-
}
|
|
2035
|
-
if (confidence === 0) {
|
|
2036
|
-
return null;
|
|
2037
|
-
}
|
|
2038
|
-
return {
|
|
2039
|
-
id: 'qwik',
|
|
2040
|
-
name: 'Qwik',
|
|
2041
|
-
category: 'frontend',
|
|
2042
|
-
version,
|
|
2043
|
-
confidence: min(confidence, 100),
|
|
2044
|
-
detectedFrom: sources,
|
|
2045
|
-
};
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
/**
|
|
2049
|
-
* Detect Astro in project.
|
|
2050
|
-
*
|
|
2051
|
-
* @param projectPath - Project directory path
|
|
2052
|
-
* @param packageJson - Optional pre-loaded package.json
|
|
2053
|
-
* @returns Detection result or null if not detected
|
|
2054
|
-
*/
|
|
2055
|
-
function astroDetector(projectPath, packageJson) {
|
|
2056
|
-
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2057
|
-
const sources = [];
|
|
2058
|
-
let confidence = 0;
|
|
2059
|
-
let version;
|
|
2060
|
-
const deps = collectAllDependencies(pkg);
|
|
2061
|
-
if (deps['astro']) {
|
|
2062
|
-
confidence += 70;
|
|
2063
|
-
version = parseVersionString(deps['astro']);
|
|
2064
|
-
sources.push({ type: 'package.json', field: 'dependencies.astro' });
|
|
2065
|
-
}
|
|
2066
|
-
if (exists(join$1(projectPath, 'astro.config.mjs')) ||
|
|
2067
|
-
exists(join$1(projectPath, 'astro.config.ts')) ||
|
|
2068
|
-
exists(join$1(projectPath, 'astro.config.js'))) {
|
|
2069
|
-
confidence += 25;
|
|
2070
|
-
sources.push({ type: 'config-file', path: 'astro.config.*' });
|
|
1891
|
+
sources.push({ type: 'directory', path: 'src/*.vue' });
|
|
2071
1892
|
}
|
|
2072
|
-
if (exists(join$1(projectPath, '
|
|
1893
|
+
if (exists(join$1(projectPath, 'vue.config.js'))) {
|
|
2073
1894
|
confidence += 5;
|
|
2074
|
-
sources.push({ type: '
|
|
1895
|
+
sources.push({ type: 'config-file', path: 'vue.config.js' });
|
|
1896
|
+
}
|
|
1897
|
+
if (deps['nuxt'] || deps['nuxt3']) {
|
|
1898
|
+
metaFrameworks.push({
|
|
1899
|
+
id: 'nuxt',
|
|
1900
|
+
name: 'Nuxt',
|
|
1901
|
+
category: 'meta-framework',
|
|
1902
|
+
version: parseVersionString(deps['nuxt'] ?? deps['nuxt3']),
|
|
1903
|
+
confidence: 90,
|
|
1904
|
+
detectedFrom: [{ type: 'package.json', field: 'dependencies.nuxt' }],
|
|
1905
|
+
});
|
|
2075
1906
|
}
|
|
2076
1907
|
if (confidence === 0) {
|
|
2077
1908
|
return null;
|
|
2078
1909
|
}
|
|
2079
1910
|
return {
|
|
2080
|
-
id: '
|
|
2081
|
-
name: '
|
|
2082
|
-
category: '
|
|
1911
|
+
id: 'vue',
|
|
1912
|
+
name: 'Vue',
|
|
1913
|
+
category: 'frontend',
|
|
2083
1914
|
version,
|
|
2084
1915
|
confidence: min(confidence, 100),
|
|
2085
1916
|
detectedFrom: sources,
|
|
1917
|
+
metaFrameworks: metaFrameworks.length > 0 ? metaFrameworks : undefined,
|
|
2086
1918
|
};
|
|
2087
1919
|
}
|
|
2088
1920
|
|
|
@@ -2109,6 +1941,14 @@ const frameworkDetectors = [
|
|
|
2109
1941
|
* @param projectPath - Project directory path
|
|
2110
1942
|
* @param packageJson - Optional pre-loaded package.json
|
|
2111
1943
|
* @returns Detection result or null if not detected
|
|
1944
|
+
*
|
|
1945
|
+
* @example Detecting AngularJS framework
|
|
1946
|
+
* ```typescript
|
|
1947
|
+
* const result = angularJSDetector('/path/to/project', {
|
|
1948
|
+
* dependencies: { angular: '^1.8.0', 'angular-route': '^1.8.0' },
|
|
1949
|
+
* })
|
|
1950
|
+
* // => { id: 'angularjs', name: 'AngularJS', confidence: 85, version: '1.8.0', ... }
|
|
1951
|
+
* ```
|
|
2112
1952
|
*/
|
|
2113
1953
|
function angularJSDetector(projectPath, packageJson) {
|
|
2114
1954
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2152,6 +1992,14 @@ function angularJSDetector(projectPath, packageJson) {
|
|
|
2152
1992
|
* @param projectPath - Project directory path
|
|
2153
1993
|
* @param packageJson - Optional pre-loaded package.json
|
|
2154
1994
|
* @returns Detection result or null if not detected
|
|
1995
|
+
*
|
|
1996
|
+
* @example Detecting Backbone.js framework
|
|
1997
|
+
* ```typescript
|
|
1998
|
+
* const result = backboneDetector('/path/to/project', {
|
|
1999
|
+
* dependencies: { backbone: '^1.4.0', underscore: '^1.13.0' },
|
|
2000
|
+
* })
|
|
2001
|
+
* // => { id: 'backbone', name: 'Backbone.js', confidence: 85, version: '1.4.0', ... }
|
|
2002
|
+
* ```
|
|
2155
2003
|
*/
|
|
2156
2004
|
function backboneDetector(projectPath, packageJson) {
|
|
2157
2005
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2195,6 +2043,15 @@ function backboneDetector(projectPath, packageJson) {
|
|
|
2195
2043
|
* @param projectPath - Project directory path
|
|
2196
2044
|
* @param packageJson - Optional pre-loaded package.json
|
|
2197
2045
|
* @returns Detection result or null if not detected
|
|
2046
|
+
*
|
|
2047
|
+
* @example Detecting Ember.js framework
|
|
2048
|
+
* ```typescript
|
|
2049
|
+
* const result = emberDetector('/path/to/project', {
|
|
2050
|
+
* dependencies: { 'ember-source': '^4.0.0' },
|
|
2051
|
+
* devDependencies: { 'ember-cli': '^4.0.0' },
|
|
2052
|
+
* })
|
|
2053
|
+
* // => { id: 'ember', name: 'Ember.js', confidence: 90, version: '4.0.0', ... }
|
|
2054
|
+
* ```
|
|
2198
2055
|
*/
|
|
2199
2056
|
function emberDetector(projectPath, packageJson) {
|
|
2200
2057
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2234,47 +2091,105 @@ function emberDetector(projectPath, packageJson) {
|
|
|
2234
2091
|
* @param projectPath - Project directory path
|
|
2235
2092
|
* @param packageJson - Optional pre-loaded package.json
|
|
2236
2093
|
* @returns Detection result or null if not detected
|
|
2094
|
+
*
|
|
2095
|
+
* @example Detecting jQuery library
|
|
2096
|
+
* ```typescript
|
|
2097
|
+
* const result = jqueryDetector('/path/to/project', {
|
|
2098
|
+
* dependencies: { jquery: '^3.6.0', 'jquery-ui': '^1.13.0' },
|
|
2099
|
+
* })
|
|
2100
|
+
* // => { id: 'jquery', name: 'jQuery', confidence: 90, version: '3.6.0', ... }
|
|
2101
|
+
* ```
|
|
2102
|
+
*/
|
|
2103
|
+
function jqueryDetector(projectPath, packageJson) {
|
|
2104
|
+
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2105
|
+
const sources = [];
|
|
2106
|
+
let confidence = 0;
|
|
2107
|
+
let version;
|
|
2108
|
+
const deps = collectAllDependencies(pkg);
|
|
2109
|
+
if (deps['jquery']) {
|
|
2110
|
+
confidence += 80;
|
|
2111
|
+
version = parseVersionString(deps['jquery']);
|
|
2112
|
+
sources.push({ type: 'package.json', field: 'dependencies.jquery' });
|
|
2113
|
+
}
|
|
2114
|
+
if (deps['jquery-ui']) {
|
|
2115
|
+
confidence += 10;
|
|
2116
|
+
sources.push({ type: 'package.json', field: 'dependencies.jquery-ui' });
|
|
2117
|
+
}
|
|
2118
|
+
if (deps['jquery-validation']) {
|
|
2119
|
+
confidence += 5;
|
|
2120
|
+
sources.push({ type: 'package.json', field: 'dependencies.jquery-validation' });
|
|
2121
|
+
}
|
|
2122
|
+
if (confidence === 0) {
|
|
2123
|
+
return null;
|
|
2124
|
+
}
|
|
2125
|
+
return {
|
|
2126
|
+
id: 'jquery',
|
|
2127
|
+
name: 'jQuery',
|
|
2128
|
+
category: 'legacy-frontend',
|
|
2129
|
+
version,
|
|
2130
|
+
confidence: min(confidence, 100),
|
|
2131
|
+
detectedFrom: sources,
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
/** All legacy framework detectors */
|
|
2136
|
+
const legacyDetectors = [
|
|
2137
|
+
{ id: 'angularjs', name: 'AngularJS', category: 'legacy-frontend', detect: angularJSDetector },
|
|
2138
|
+
{ id: 'backbone', name: 'Backbone.js', category: 'legacy-frontend', detect: backboneDetector },
|
|
2139
|
+
{ id: 'ember', name: 'Ember.js', category: 'legacy-frontend', detect: emberDetector },
|
|
2140
|
+
{ id: 'jquery', name: 'jQuery', category: 'legacy-frontend', detect: jqueryDetector },
|
|
2141
|
+
];
|
|
2142
|
+
|
|
2143
|
+
/**
|
|
2144
|
+
* Detect Biome in project.
|
|
2145
|
+
*
|
|
2146
|
+
* @param projectPath - Project directory path
|
|
2147
|
+
* @param packageJson - Optional pre-loaded package.json
|
|
2148
|
+
* @returns Detection result or null if not detected
|
|
2149
|
+
*
|
|
2150
|
+
* @example Detecting Biome linter
|
|
2151
|
+
* ```typescript
|
|
2152
|
+
* const result = biomeDetector('/path/to/project', {
|
|
2153
|
+
* devDependencies: { '@biomejs/biome': '^1.5.0' },
|
|
2154
|
+
* })
|
|
2155
|
+
* // => { id: 'biome', name: 'Biome', confidence: 70, version: '1.5.0', ... }
|
|
2156
|
+
* ```
|
|
2237
2157
|
*/
|
|
2238
|
-
function
|
|
2158
|
+
function biomeDetector(projectPath, packageJson) {
|
|
2239
2159
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2240
2160
|
const sources = [];
|
|
2241
2161
|
let confidence = 0;
|
|
2162
|
+
let configPath;
|
|
2242
2163
|
let version;
|
|
2243
2164
|
const deps = collectAllDependencies(pkg);
|
|
2244
|
-
if (deps['
|
|
2245
|
-
confidence +=
|
|
2246
|
-
version = parseVersionString(deps['
|
|
2247
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
2165
|
+
if (deps['@biomejs/biome']) {
|
|
2166
|
+
confidence += 70;
|
|
2167
|
+
version = parseVersionString(deps['@biomejs/biome']);
|
|
2168
|
+
sources.push({ type: 'package.json', field: 'dependencies.@biomejs/biome' });
|
|
2248
2169
|
}
|
|
2249
|
-
if (
|
|
2250
|
-
confidence +=
|
|
2251
|
-
|
|
2170
|
+
if (exists(join$1(projectPath, 'biome.json'))) {
|
|
2171
|
+
confidence += 30;
|
|
2172
|
+
configPath = 'biome.json';
|
|
2173
|
+
sources.push({ type: 'config-file', path: 'biome.json' });
|
|
2252
2174
|
}
|
|
2253
|
-
if (
|
|
2254
|
-
confidence +=
|
|
2255
|
-
|
|
2175
|
+
if (!configPath && exists(join$1(projectPath, 'biome.jsonc'))) {
|
|
2176
|
+
confidence += 30;
|
|
2177
|
+
configPath = 'biome.jsonc';
|
|
2178
|
+
sources.push({ type: 'config-file', path: 'biome.jsonc' });
|
|
2256
2179
|
}
|
|
2257
2180
|
if (confidence === 0) {
|
|
2258
2181
|
return null;
|
|
2259
2182
|
}
|
|
2260
2183
|
return {
|
|
2261
|
-
id: '
|
|
2262
|
-
name: '
|
|
2263
|
-
category: 'legacy-frontend',
|
|
2184
|
+
id: 'biome',
|
|
2185
|
+
name: 'Biome',
|
|
2264
2186
|
version,
|
|
2187
|
+
configPath,
|
|
2265
2188
|
confidence: min(confidence, 100),
|
|
2266
2189
|
detectedFrom: sources,
|
|
2267
2190
|
};
|
|
2268
2191
|
}
|
|
2269
2192
|
|
|
2270
|
-
/** All legacy framework detectors */
|
|
2271
|
-
const legacyDetectors = [
|
|
2272
|
-
{ id: 'angularjs', name: 'AngularJS', category: 'legacy-frontend', detect: angularJSDetector },
|
|
2273
|
-
{ id: 'backbone', name: 'Backbone.js', category: 'legacy-frontend', detect: backboneDetector },
|
|
2274
|
-
{ id: 'ember', name: 'Ember.js', category: 'legacy-frontend', detect: emberDetector },
|
|
2275
|
-
{ id: 'jquery', name: 'jQuery', category: 'legacy-frontend', detect: jqueryDetector },
|
|
2276
|
-
];
|
|
2277
|
-
|
|
2278
2193
|
/** Config patterns for ESLint */
|
|
2279
2194
|
const ESLINT_CONFIG_PATTERNS = [
|
|
2280
2195
|
'eslint.config.js',
|
|
@@ -2294,6 +2209,15 @@ const ESLINT_CONFIG_PATTERNS = [
|
|
|
2294
2209
|
* @param projectPath - Project directory path
|
|
2295
2210
|
* @param packageJson - Optional pre-loaded package.json
|
|
2296
2211
|
* @returns Detection result or null if not detected
|
|
2212
|
+
*
|
|
2213
|
+
* @example Detecting ESLint linter
|
|
2214
|
+
* ```typescript
|
|
2215
|
+
* const result = eslintDetector('/path/to/project', {
|
|
2216
|
+
* devDependencies: { eslint: '^8.50.0', '@typescript-eslint/parser': '^6.0.0' },
|
|
2217
|
+
* scripts: { lint: 'eslint src/' },
|
|
2218
|
+
* })
|
|
2219
|
+
* // => { id: 'eslint', name: 'ESLint', confidence: 65, version: '8.50.0', ... }
|
|
2220
|
+
* ```
|
|
2297
2221
|
*/
|
|
2298
2222
|
function eslintDetector(projectPath, packageJson) {
|
|
2299
2223
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2357,6 +2281,15 @@ const PRETTIER_CONFIG_PATTERNS = [
|
|
|
2357
2281
|
* @param projectPath - Project directory path
|
|
2358
2282
|
* @param packageJson - Optional pre-loaded package.json
|
|
2359
2283
|
* @returns Detection result or null if not detected
|
|
2284
|
+
*
|
|
2285
|
+
* @example Detecting Prettier formatter
|
|
2286
|
+
* ```typescript
|
|
2287
|
+
* const result = prettierDetector('/path/to/project', {
|
|
2288
|
+
* devDependencies: { prettier: '^3.0.0' },
|
|
2289
|
+
* scripts: { format: 'prettier --write .' },
|
|
2290
|
+
* })
|
|
2291
|
+
* // => { id: 'prettier', name: 'Prettier', confidence: 55, version: '3.0.0', ... }
|
|
2292
|
+
* ```
|
|
2360
2293
|
*/
|
|
2361
2294
|
function prettierDetector(projectPath, packageJson) {
|
|
2362
2295
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2419,6 +2352,14 @@ const STYLELINT_CONFIG_PATTERNS = [
|
|
|
2419
2352
|
* @param projectPath - Project directory path
|
|
2420
2353
|
* @param packageJson - Optional pre-loaded package.json
|
|
2421
2354
|
* @returns Detection result or null if not detected
|
|
2355
|
+
*
|
|
2356
|
+
* @example Detecting Stylelint linter
|
|
2357
|
+
* ```typescript
|
|
2358
|
+
* const result = stylelintDetector('/path/to/project', {
|
|
2359
|
+
* devDependencies: { stylelint: '^15.0.0', 'stylelint-config-standard': '^30.0.0' },
|
|
2360
|
+
* })
|
|
2361
|
+
* // => { id: 'stylelint', name: 'Stylelint', confidence: 65, version: '15.0.0', ... }
|
|
2362
|
+
* ```
|
|
2422
2363
|
*/
|
|
2423
2364
|
function stylelintDetector(projectPath, packageJson) {
|
|
2424
2365
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2458,48 +2399,6 @@ function stylelintDetector(projectPath, packageJson) {
|
|
|
2458
2399
|
};
|
|
2459
2400
|
}
|
|
2460
2401
|
|
|
2461
|
-
/**
|
|
2462
|
-
* Detect Biome in project.
|
|
2463
|
-
*
|
|
2464
|
-
* @param projectPath - Project directory path
|
|
2465
|
-
* @param packageJson - Optional pre-loaded package.json
|
|
2466
|
-
* @returns Detection result or null if not detected
|
|
2467
|
-
*/
|
|
2468
|
-
function biomeDetector(projectPath, packageJson) {
|
|
2469
|
-
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2470
|
-
const sources = [];
|
|
2471
|
-
let confidence = 0;
|
|
2472
|
-
let configPath;
|
|
2473
|
-
let version;
|
|
2474
|
-
const deps = collectAllDependencies(pkg);
|
|
2475
|
-
if (deps['@biomejs/biome']) {
|
|
2476
|
-
confidence += 70;
|
|
2477
|
-
version = parseVersionString(deps['@biomejs/biome']);
|
|
2478
|
-
sources.push({ type: 'package.json', field: 'dependencies.@biomejs/biome' });
|
|
2479
|
-
}
|
|
2480
|
-
if (exists(join$1(projectPath, 'biome.json'))) {
|
|
2481
|
-
confidence += 30;
|
|
2482
|
-
configPath = 'biome.json';
|
|
2483
|
-
sources.push({ type: 'config-file', path: 'biome.json' });
|
|
2484
|
-
}
|
|
2485
|
-
if (!configPath && exists(join$1(projectPath, 'biome.jsonc'))) {
|
|
2486
|
-
confidence += 30;
|
|
2487
|
-
configPath = 'biome.jsonc';
|
|
2488
|
-
sources.push({ type: 'config-file', path: 'biome.jsonc' });
|
|
2489
|
-
}
|
|
2490
|
-
if (confidence === 0) {
|
|
2491
|
-
return null;
|
|
2492
|
-
}
|
|
2493
|
-
return {
|
|
2494
|
-
id: 'biome',
|
|
2495
|
-
name: 'Biome',
|
|
2496
|
-
version,
|
|
2497
|
-
configPath,
|
|
2498
|
-
confidence: min(confidence, 100),
|
|
2499
|
-
detectedFrom: sources,
|
|
2500
|
-
};
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
2402
|
/** All linting tool detectors */
|
|
2504
2403
|
const lintingDetectors = [
|
|
2505
2404
|
{ id: 'eslint', name: 'ESLint', detect: eslintDetector },
|
|
@@ -2509,140 +2408,179 @@ const lintingDetectors = [
|
|
|
2509
2408
|
];
|
|
2510
2409
|
|
|
2511
2410
|
/**
|
|
2512
|
-
* Detect
|
|
2411
|
+
* Detect Lerna in project.
|
|
2513
2412
|
*
|
|
2514
2413
|
* @param workspacePath - Workspace directory path
|
|
2515
2414
|
* @param packageJson - Optional pre-loaded package.json
|
|
2516
2415
|
* @returns Detection result or null if not detected
|
|
2416
|
+
*
|
|
2417
|
+
* @example Detecting Lerna monorepo
|
|
2418
|
+
* ```typescript
|
|
2419
|
+
* // Project with lerna.json config file
|
|
2420
|
+
* const result = lernaDetector('/path/to/lerna-project')
|
|
2421
|
+
* // => {
|
|
2422
|
+
* // id: 'lerna',
|
|
2423
|
+
* // name: 'Lerna',
|
|
2424
|
+
* // confidence: 80,
|
|
2425
|
+
* // configPath: 'lerna.json',
|
|
2426
|
+
* // detectedFrom: [{ type: 'config-file', path: 'lerna.json' }]
|
|
2427
|
+
* // }
|
|
2428
|
+
* ```
|
|
2517
2429
|
*/
|
|
2518
|
-
function
|
|
2430
|
+
function lernaDetector(workspacePath, packageJson) {
|
|
2519
2431
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
2520
2432
|
const sources = [];
|
|
2521
2433
|
let confidence = 0;
|
|
2522
2434
|
let version;
|
|
2523
|
-
let
|
|
2524
|
-
const
|
|
2525
|
-
if (exists(
|
|
2526
|
-
confidence +=
|
|
2527
|
-
|
|
2435
|
+
let configPath;
|
|
2436
|
+
const lernaJsonPath = join$1(workspacePath, 'lerna.json');
|
|
2437
|
+
if (exists(lernaJsonPath)) {
|
|
2438
|
+
confidence += 80;
|
|
2439
|
+
configPath = 'lerna.json';
|
|
2440
|
+
sources.push({ type: 'config-file', path: 'lerna.json' });
|
|
2528
2441
|
}
|
|
2529
2442
|
const deps = collectAllDependencies(pkg);
|
|
2530
|
-
if (deps['
|
|
2531
|
-
confidence +=
|
|
2532
|
-
version = parseVersionString(deps['
|
|
2533
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
2534
|
-
}
|
|
2535
|
-
const hasApps = exists(join$1(workspacePath, 'apps'));
|
|
2536
|
-
const hasLibs = exists(join$1(workspacePath, 'libs'));
|
|
2537
|
-
if (hasApps || hasLibs) {
|
|
2538
|
-
confidence += 10;
|
|
2539
|
-
sources.push({ type: 'directory', path: 'apps/ or libs/' });
|
|
2540
|
-
workspaceLayout = {
|
|
2541
|
-
appsDir: hasApps ? 'apps' : '',
|
|
2542
|
-
libsDir: hasLibs ? 'libs' : '',
|
|
2543
|
-
};
|
|
2443
|
+
if (deps['lerna']) {
|
|
2444
|
+
confidence += 15;
|
|
2445
|
+
version = parseVersionString(deps['lerna']);
|
|
2446
|
+
sources.push({ type: 'package.json', field: 'dependencies.lerna' });
|
|
2544
2447
|
}
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
sources.push({ type: 'package.json', field: '@nx/* packages' });
|
|
2448
|
+
if (exists(join$1(workspacePath, 'packages'))) {
|
|
2449
|
+
confidence += 5;
|
|
2450
|
+
sources.push({ type: 'directory', path: 'packages/' });
|
|
2549
2451
|
}
|
|
2550
2452
|
if (confidence === 0) {
|
|
2551
2453
|
return null;
|
|
2552
2454
|
}
|
|
2553
2455
|
return {
|
|
2554
|
-
id: '
|
|
2555
|
-
name: '
|
|
2456
|
+
id: 'lerna',
|
|
2457
|
+
name: 'Lerna',
|
|
2556
2458
|
version,
|
|
2557
|
-
configPath
|
|
2459
|
+
configPath,
|
|
2558
2460
|
confidence: min(confidence, 100),
|
|
2559
2461
|
detectedFrom: sources,
|
|
2560
|
-
workspaceLayout,
|
|
2561
2462
|
};
|
|
2562
2463
|
}
|
|
2563
2464
|
|
|
2564
2465
|
/**
|
|
2565
|
-
* Detect
|
|
2466
|
+
* Detect npm workspaces in project.
|
|
2566
2467
|
*
|
|
2567
2468
|
* @param workspacePath - Workspace directory path
|
|
2568
2469
|
* @param packageJson - Optional pre-loaded package.json
|
|
2569
2470
|
* @returns Detection result or null if not detected
|
|
2471
|
+
*
|
|
2472
|
+
* @example Detecting npm workspaces
|
|
2473
|
+
* ```typescript
|
|
2474
|
+
* // Project with workspaces in package.json and package-lock.json
|
|
2475
|
+
* const result = npmWorkspacesDetector('/path/to/npm-project')
|
|
2476
|
+
* // => {
|
|
2477
|
+
* // id: 'npm-workspaces',
|
|
2478
|
+
* // name: 'npm Workspaces',
|
|
2479
|
+
* // confidence: 90,
|
|
2480
|
+
* // configPath: 'package.json',
|
|
2481
|
+
* // detectedFrom: [
|
|
2482
|
+
* // { type: 'package.json', field: 'workspaces' },
|
|
2483
|
+
* // { type: 'lockfile', path: 'package-lock.json' }
|
|
2484
|
+
* // ]
|
|
2485
|
+
* // }
|
|
2486
|
+
* ```
|
|
2570
2487
|
*/
|
|
2571
|
-
function
|
|
2488
|
+
function npmWorkspacesDetector(workspacePath, packageJson) {
|
|
2572
2489
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
2573
2490
|
const sources = [];
|
|
2574
2491
|
let confidence = 0;
|
|
2575
|
-
|
|
2576
|
-
let configPath;
|
|
2577
|
-
const turboJsonPath = join$1(workspacePath, 'turbo.json');
|
|
2578
|
-
if (exists(turboJsonPath)) {
|
|
2492
|
+
if (pkg?.workspaces) {
|
|
2579
2493
|
confidence += 80;
|
|
2580
|
-
|
|
2581
|
-
sources.push({ type: 'config-file', path: 'turbo.json' });
|
|
2494
|
+
sources.push({ type: 'package.json', field: 'workspaces' });
|
|
2582
2495
|
}
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
version = parseVersionString(deps['turbo']);
|
|
2587
|
-
sources.push({ type: 'package.json', field: 'dependencies.turbo' });
|
|
2496
|
+
if (exists(join$1(workspacePath, 'package-lock.json'))) {
|
|
2497
|
+
confidence += 10;
|
|
2498
|
+
sources.push({ type: 'lockfile', path: 'package-lock.json' });
|
|
2588
2499
|
}
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
confidence += 5;
|
|
2592
|
-
sources.push({ type: 'package.json', field: 'scripts (turbo commands)' });
|
|
2500
|
+
if (exists(join$1(workspacePath, 'yarn.lock'))) {
|
|
2501
|
+
return null;
|
|
2593
2502
|
}
|
|
2594
2503
|
if (confidence === 0) {
|
|
2595
2504
|
return null;
|
|
2596
2505
|
}
|
|
2597
2506
|
return {
|
|
2598
|
-
id: '
|
|
2599
|
-
name: '
|
|
2600
|
-
|
|
2601
|
-
configPath,
|
|
2507
|
+
id: 'npm-workspaces',
|
|
2508
|
+
name: 'npm Workspaces',
|
|
2509
|
+
configPath: 'package.json',
|
|
2602
2510
|
confidence: min(confidence, 100),
|
|
2603
2511
|
detectedFrom: sources,
|
|
2604
2512
|
};
|
|
2605
2513
|
}
|
|
2606
2514
|
|
|
2607
2515
|
/**
|
|
2608
|
-
* Detect
|
|
2516
|
+
* Detect NX in project.
|
|
2609
2517
|
*
|
|
2610
2518
|
* @param workspacePath - Workspace directory path
|
|
2611
2519
|
* @param packageJson - Optional pre-loaded package.json
|
|
2612
2520
|
* @returns Detection result or null if not detected
|
|
2521
|
+
*
|
|
2522
|
+
* @example Detecting NX workspace
|
|
2523
|
+
* ```typescript
|
|
2524
|
+
* // Project with nx.json and apps/libs directories
|
|
2525
|
+
* const result = nxDetector('/path/to/nx-workspace')
|
|
2526
|
+
* // => {
|
|
2527
|
+
* // id: 'nx',
|
|
2528
|
+
* // name: 'NX',
|
|
2529
|
+
* // confidence: 100,
|
|
2530
|
+
* // configPath: 'nx.json',
|
|
2531
|
+
* // version: '17.0.0',
|
|
2532
|
+
* // workspaceLayout: { appsDir: 'apps', libsDir: 'libs' },
|
|
2533
|
+
* // detectedFrom: [
|
|
2534
|
+
* // { type: 'config-file', path: 'nx.json' },
|
|
2535
|
+
* // { type: 'package.json', field: 'dependencies.nx' },
|
|
2536
|
+
* // { type: 'directory', path: 'apps/ or libs/' }
|
|
2537
|
+
* // ]
|
|
2538
|
+
* // }
|
|
2539
|
+
* ```
|
|
2613
2540
|
*/
|
|
2614
|
-
function
|
|
2541
|
+
function nxDetector(workspacePath, packageJson) {
|
|
2615
2542
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
2616
2543
|
const sources = [];
|
|
2617
2544
|
let confidence = 0;
|
|
2618
2545
|
let version;
|
|
2619
|
-
let
|
|
2620
|
-
const
|
|
2621
|
-
if (exists(
|
|
2622
|
-
confidence +=
|
|
2623
|
-
|
|
2624
|
-
sources.push({ type: 'config-file', path: 'lerna.json' });
|
|
2546
|
+
let workspaceLayout;
|
|
2547
|
+
const nxJsonPath = join$1(workspacePath, 'nx.json');
|
|
2548
|
+
if (exists(nxJsonPath)) {
|
|
2549
|
+
confidence += 70;
|
|
2550
|
+
sources.push({ type: 'config-file', path: 'nx.json' });
|
|
2625
2551
|
}
|
|
2626
2552
|
const deps = collectAllDependencies(pkg);
|
|
2627
|
-
if (deps['
|
|
2628
|
-
confidence +=
|
|
2629
|
-
version = parseVersionString(deps['
|
|
2630
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
2553
|
+
if (deps['nx']) {
|
|
2554
|
+
confidence += 20;
|
|
2555
|
+
version = parseVersionString(deps['nx']);
|
|
2556
|
+
sources.push({ type: 'package.json', field: 'dependencies.nx' });
|
|
2631
2557
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2558
|
+
const hasApps = exists(join$1(workspacePath, 'apps'));
|
|
2559
|
+
const hasLibs = exists(join$1(workspacePath, 'libs'));
|
|
2560
|
+
if (hasApps || hasLibs) {
|
|
2561
|
+
confidence += 10;
|
|
2562
|
+
sources.push({ type: 'directory', path: 'apps/ or libs/' });
|
|
2563
|
+
workspaceLayout = {
|
|
2564
|
+
appsDir: hasApps ? 'apps' : '',
|
|
2565
|
+
libsDir: hasLibs ? 'libs' : '',
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
const nxPackages = keys(deps).filter((d) => d.startsWith('@nx/') || d.startsWith('@nrwl/'));
|
|
2569
|
+
if (nxPackages.length > 0) {
|
|
2570
|
+
confidence += 10;
|
|
2571
|
+
sources.push({ type: 'package.json', field: '@nx/* packages' });
|
|
2635
2572
|
}
|
|
2636
2573
|
if (confidence === 0) {
|
|
2637
2574
|
return null;
|
|
2638
2575
|
}
|
|
2639
2576
|
return {
|
|
2640
|
-
id: '
|
|
2641
|
-
name: '
|
|
2577
|
+
id: 'nx',
|
|
2578
|
+
name: 'NX',
|
|
2642
2579
|
version,
|
|
2643
|
-
configPath,
|
|
2580
|
+
configPath: exists(nxJsonPath) ? 'nx.json' : undefined,
|
|
2644
2581
|
confidence: min(confidence, 100),
|
|
2645
2582
|
detectedFrom: sources,
|
|
2583
|
+
workspaceLayout,
|
|
2646
2584
|
};
|
|
2647
2585
|
}
|
|
2648
2586
|
|
|
@@ -2652,6 +2590,19 @@ function lernaDetector(workspacePath, packageJson) {
|
|
|
2652
2590
|
* @param workspacePath - Workspace directory path
|
|
2653
2591
|
* @param packageJson - Optional pre-loaded package.json
|
|
2654
2592
|
* @returns Detection result or null if not detected
|
|
2593
|
+
*
|
|
2594
|
+
* @example Detecting Rush monorepo
|
|
2595
|
+
* ```typescript
|
|
2596
|
+
* // Project with rush.json config file
|
|
2597
|
+
* const result = rushDetector('/path/to/rush-project')
|
|
2598
|
+
* // => {
|
|
2599
|
+
* // id: 'rush',
|
|
2600
|
+
* // name: 'Rush',
|
|
2601
|
+
* // confidence: 90,
|
|
2602
|
+
* // configPath: 'rush.json',
|
|
2603
|
+
* // detectedFrom: [{ type: 'config-file', path: 'rush.json' }]
|
|
2604
|
+
* // }
|
|
2605
|
+
* ```
|
|
2655
2606
|
*/
|
|
2656
2607
|
function rushDetector(workspacePath, packageJson) {
|
|
2657
2608
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
@@ -2681,39 +2632,7 @@ function rushDetector(workspacePath, packageJson) {
|
|
|
2681
2632
|
return {
|
|
2682
2633
|
id: 'rush',
|
|
2683
2634
|
name: 'Rush',
|
|
2684
|
-
version,
|
|
2685
|
-
configPath,
|
|
2686
|
-
confidence: min(confidence, 100),
|
|
2687
|
-
detectedFrom: sources,
|
|
2688
|
-
};
|
|
2689
|
-
}
|
|
2690
|
-
|
|
2691
|
-
/**
|
|
2692
|
-
* Detect pnpm workspaces in project.
|
|
2693
|
-
*
|
|
2694
|
-
* @param workspacePath - Workspace directory path
|
|
2695
|
-
* @returns Detection result or null if not detected
|
|
2696
|
-
*/
|
|
2697
|
-
function pnpmWorkspacesDetector(workspacePath) {
|
|
2698
|
-
const sources = [];
|
|
2699
|
-
let confidence = 0;
|
|
2700
|
-
let configPath;
|
|
2701
|
-
const pnpmWorkspacePath = join$1(workspacePath, 'pnpm-workspace.yaml');
|
|
2702
|
-
if (exists(pnpmWorkspacePath)) {
|
|
2703
|
-
confidence += 90;
|
|
2704
|
-
configPath = 'pnpm-workspace.yaml';
|
|
2705
|
-
sources.push({ type: 'config-file', path: 'pnpm-workspace.yaml' });
|
|
2706
|
-
}
|
|
2707
|
-
if (exists(join$1(workspacePath, 'pnpm-lock.yaml'))) {
|
|
2708
|
-
confidence += 10;
|
|
2709
|
-
sources.push({ type: 'lockfile', path: 'pnpm-lock.yaml' });
|
|
2710
|
-
}
|
|
2711
|
-
if (confidence === 0) {
|
|
2712
|
-
return null;
|
|
2713
|
-
}
|
|
2714
|
-
return {
|
|
2715
|
-
id: 'pnpm-workspaces',
|
|
2716
|
-
name: 'pnpm Workspaces',
|
|
2635
|
+
version,
|
|
2717
2636
|
configPath,
|
|
2718
2637
|
confidence: min(confidence, 100),
|
|
2719
2638
|
detectedFrom: sources,
|
|
@@ -2721,34 +2640,60 @@ function pnpmWorkspacesDetector(workspacePath) {
|
|
|
2721
2640
|
}
|
|
2722
2641
|
|
|
2723
2642
|
/**
|
|
2724
|
-
* Detect
|
|
2643
|
+
* Detect Turborepo in project.
|
|
2725
2644
|
*
|
|
2726
2645
|
* @param workspacePath - Workspace directory path
|
|
2727
2646
|
* @param packageJson - Optional pre-loaded package.json
|
|
2728
2647
|
* @returns Detection result or null if not detected
|
|
2648
|
+
*
|
|
2649
|
+
* @example Detecting Turborepo monorepo
|
|
2650
|
+
* ```typescript
|
|
2651
|
+
* // Project with turbo.json and turbo dependency
|
|
2652
|
+
* const result = turborepoDetector('/path/to/turbo-project')
|
|
2653
|
+
* // => {
|
|
2654
|
+
* // id: 'turborepo',
|
|
2655
|
+
* // name: 'Turborepo',
|
|
2656
|
+
* // confidence: 95,
|
|
2657
|
+
* // configPath: 'turbo.json',
|
|
2658
|
+
* // version: '2.0.0',
|
|
2659
|
+
* // detectedFrom: [
|
|
2660
|
+
* // { type: 'config-file', path: 'turbo.json' },
|
|
2661
|
+
* // { type: 'package.json', field: 'dependencies.turbo' }
|
|
2662
|
+
* // ]
|
|
2663
|
+
* // }
|
|
2664
|
+
* ```
|
|
2729
2665
|
*/
|
|
2730
|
-
function
|
|
2666
|
+
function turborepoDetector(workspacePath, packageJson) {
|
|
2731
2667
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
2732
2668
|
const sources = [];
|
|
2733
2669
|
let confidence = 0;
|
|
2734
|
-
|
|
2670
|
+
let version;
|
|
2671
|
+
let configPath;
|
|
2672
|
+
const turboJsonPath = join$1(workspacePath, 'turbo.json');
|
|
2673
|
+
if (exists(turboJsonPath)) {
|
|
2735
2674
|
confidence += 80;
|
|
2736
|
-
|
|
2675
|
+
configPath = 'turbo.json';
|
|
2676
|
+
sources.push({ type: 'config-file', path: 'turbo.json' });
|
|
2737
2677
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2678
|
+
const deps = collectAllDependencies(pkg);
|
|
2679
|
+
if (deps['turbo']) {
|
|
2680
|
+
confidence += 15;
|
|
2681
|
+
version = parseVersionString(deps['turbo']);
|
|
2682
|
+
sources.push({ type: 'package.json', field: 'dependencies.turbo' });
|
|
2741
2683
|
}
|
|
2742
|
-
|
|
2743
|
-
|
|
2684
|
+
const scripts = pkg?.scripts ?? {};
|
|
2685
|
+
if (values(scripts).some((s) => s?.includes('turbo'))) {
|
|
2686
|
+
confidence += 5;
|
|
2687
|
+
sources.push({ type: 'package.json', field: 'scripts (turbo commands)' });
|
|
2744
2688
|
}
|
|
2745
2689
|
if (confidence === 0) {
|
|
2746
2690
|
return null;
|
|
2747
2691
|
}
|
|
2748
2692
|
return {
|
|
2749
|
-
id: '
|
|
2750
|
-
name: '
|
|
2751
|
-
|
|
2693
|
+
id: 'turborepo',
|
|
2694
|
+
name: 'Turborepo',
|
|
2695
|
+
version,
|
|
2696
|
+
configPath,
|
|
2752
2697
|
confidence: min(confidence, 100),
|
|
2753
2698
|
detectedFrom: sources,
|
|
2754
2699
|
};
|
|
@@ -2760,6 +2705,23 @@ function npmWorkspacesDetector(workspacePath, packageJson) {
|
|
|
2760
2705
|
* @param workspacePath - Workspace directory path
|
|
2761
2706
|
* @param packageJson - Optional pre-loaded package.json
|
|
2762
2707
|
* @returns Detection result or null if not detected
|
|
2708
|
+
*
|
|
2709
|
+
* @example Detecting yarn workspaces
|
|
2710
|
+
* ```typescript
|
|
2711
|
+
* // Project with workspaces in package.json and yarn.lock
|
|
2712
|
+
* const result = yarnWorkspacesDetector('/path/to/yarn-project')
|
|
2713
|
+
* // => {
|
|
2714
|
+
* // id: 'yarn-workspaces',
|
|
2715
|
+
* // name: 'Yarn Workspaces',
|
|
2716
|
+
* // confidence: 100,
|
|
2717
|
+
* // configPath: 'package.json',
|
|
2718
|
+
* // detectedFrom: [
|
|
2719
|
+
* // { type: 'package.json', field: 'workspaces' },
|
|
2720
|
+
* // { type: 'lockfile', path: 'yarn.lock' },
|
|
2721
|
+
* // { type: 'config-file', path: '.yarnrc.yml' }
|
|
2722
|
+
* // ]
|
|
2723
|
+
* // }
|
|
2724
|
+
* ```
|
|
2763
2725
|
*/
|
|
2764
2726
|
function yarnWorkspacesDetector(workspacePath, packageJson) {
|
|
2765
2727
|
const pkg = packageJson ?? readPackageJsonIfExists(workspacePath);
|
|
@@ -2800,55 +2762,58 @@ const monorepoDetectors = [
|
|
|
2800
2762
|
{ id: 'yarn-workspaces', name: 'Yarn Workspaces', detect: yarnWorkspacesDetector },
|
|
2801
2763
|
];
|
|
2802
2764
|
|
|
2803
|
-
/** Config patterns for
|
|
2804
|
-
const
|
|
2765
|
+
/** Config patterns for Cypress */
|
|
2766
|
+
const CYPRESS_CONFIG_PATTERNS = ['cypress.config.js', 'cypress.config.ts', 'cypress.config.mjs', 'cypress.json'];
|
|
2805
2767
|
/**
|
|
2806
|
-
* Detect
|
|
2768
|
+
* Detect Cypress in project.
|
|
2807
2769
|
*
|
|
2808
2770
|
* @param projectPath - Project directory path
|
|
2809
2771
|
* @param packageJson - Optional pre-loaded package.json
|
|
2810
2772
|
* @returns Detection result or null if not detected
|
|
2773
|
+
*
|
|
2774
|
+
* @example Detecting Cypress testing framework
|
|
2775
|
+
* ```typescript
|
|
2776
|
+
* import { cypressDetector } from '@hyperfrontend/project-scope'
|
|
2777
|
+
*
|
|
2778
|
+
* const result = cypressDetector('./my-project')
|
|
2779
|
+
* if (result) {
|
|
2780
|
+
* console.log(`Cypress ${result.version} detected (${result.confidence}% confidence)`)
|
|
2781
|
+
* // => "Cypress 13.6.0 detected (95% confidence)"
|
|
2782
|
+
* }
|
|
2783
|
+
* ```
|
|
2811
2784
|
*/
|
|
2812
|
-
function
|
|
2785
|
+
function cypressDetector(projectPath, packageJson) {
|
|
2813
2786
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2814
2787
|
const sources = [];
|
|
2815
2788
|
let confidence = 0;
|
|
2816
2789
|
let version;
|
|
2817
2790
|
const deps = collectAllDependencies(pkg);
|
|
2818
|
-
if (deps['
|
|
2791
|
+
if (deps['cypress']) {
|
|
2819
2792
|
confidence += 60;
|
|
2820
|
-
version = parseVersionString(deps['
|
|
2821
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
2793
|
+
version = parseVersionString(deps['cypress']);
|
|
2794
|
+
sources.push({ type: 'package.json', field: 'dependencies.cypress' });
|
|
2822
2795
|
}
|
|
2823
|
-
const configPath = locateConfigFile(projectPath,
|
|
2796
|
+
const configPath = locateConfigFile(projectPath, CYPRESS_CONFIG_PATTERNS);
|
|
2824
2797
|
if (configPath) {
|
|
2825
2798
|
confidence += 30;
|
|
2826
2799
|
sources.push({ type: 'config-file', path: configPath });
|
|
2827
2800
|
}
|
|
2828
|
-
if (
|
|
2829
|
-
confidence += 20;
|
|
2830
|
-
sources.push({ type: 'package.json', field: 'jest' });
|
|
2831
|
-
}
|
|
2832
|
-
const testScript = pkg?.scripts?.['test'] ?? '';
|
|
2833
|
-
if (testScript.includes('jest')) {
|
|
2801
|
+
if (exists(join$1(projectPath, 'cypress'))) {
|
|
2834
2802
|
confidence += 10;
|
|
2835
|
-
sources.push({ type: '
|
|
2836
|
-
}
|
|
2837
|
-
if (deps['@types/jest']) {
|
|
2838
|
-
confidence += 5;
|
|
2839
|
-
sources.push({ type: 'package.json', field: 'dependencies.@types/jest' });
|
|
2803
|
+
sources.push({ type: 'directory', path: 'cypress/' });
|
|
2840
2804
|
}
|
|
2841
|
-
|
|
2805
|
+
const e2eScript = pkg?.scripts?.['e2e'] ?? pkg?.scripts?.['test:e2e'] ?? '';
|
|
2806
|
+
if (e2eScript.includes('cypress')) {
|
|
2842
2807
|
confidence += 5;
|
|
2843
|
-
sources.push({ type: 'package.json', field: '
|
|
2808
|
+
sources.push({ type: 'package.json', field: 'scripts.e2e or scripts.test:e2e' });
|
|
2844
2809
|
}
|
|
2845
2810
|
if (confidence === 0) {
|
|
2846
2811
|
return null;
|
|
2847
2812
|
}
|
|
2848
2813
|
return {
|
|
2849
|
-
id: '
|
|
2850
|
-
name: '
|
|
2851
|
-
type: '
|
|
2814
|
+
id: 'cypress',
|
|
2815
|
+
name: 'Cypress',
|
|
2816
|
+
type: 'e2e',
|
|
2852
2817
|
version,
|
|
2853
2818
|
configPath,
|
|
2854
2819
|
confidence: min(confidence, 100),
|
|
@@ -2856,51 +2821,66 @@ function jestDetector(projectPath, packageJson) {
|
|
|
2856
2821
|
};
|
|
2857
2822
|
}
|
|
2858
2823
|
|
|
2859
|
-
/** Config patterns for
|
|
2860
|
-
const
|
|
2824
|
+
/** Config patterns for Jest */
|
|
2825
|
+
const JEST_CONFIG_PATTERNS = ['jest.config.js', 'jest.config.ts', 'jest.config.mjs', 'jest.config.cjs', 'jest.config.json'];
|
|
2861
2826
|
/**
|
|
2862
|
-
* Detect
|
|
2827
|
+
* Detect Jest in project.
|
|
2863
2828
|
*
|
|
2864
2829
|
* @param projectPath - Project directory path
|
|
2865
2830
|
* @param packageJson - Optional pre-loaded package.json
|
|
2866
2831
|
* @returns Detection result or null if not detected
|
|
2832
|
+
*
|
|
2833
|
+
* @example Detecting Jest testing framework
|
|
2834
|
+
* ```typescript
|
|
2835
|
+
* import { jestDetector } from '@hyperfrontend/project-scope'
|
|
2836
|
+
*
|
|
2837
|
+
* const result = jestDetector('./my-project')
|
|
2838
|
+
* if (result) {
|
|
2839
|
+
* console.log(`Jest ${result.version} detected`)
|
|
2840
|
+
* console.log('Sources:', result.detectedFrom.map(s => s.type))
|
|
2841
|
+
* // => "Sources: ['package.json', 'config-file']"
|
|
2842
|
+
* }
|
|
2843
|
+
* ```
|
|
2867
2844
|
*/
|
|
2868
|
-
function
|
|
2845
|
+
function jestDetector(projectPath, packageJson) {
|
|
2869
2846
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2870
2847
|
const sources = [];
|
|
2871
2848
|
let confidence = 0;
|
|
2872
2849
|
let version;
|
|
2873
2850
|
const deps = collectAllDependencies(pkg);
|
|
2874
|
-
if (deps['
|
|
2875
|
-
confidence +=
|
|
2876
|
-
version = parseVersionString(deps['
|
|
2877
|
-
sources.push({ type: 'package.json', field: 'dependencies.
|
|
2851
|
+
if (deps['jest']) {
|
|
2852
|
+
confidence += 60;
|
|
2853
|
+
version = parseVersionString(deps['jest']);
|
|
2854
|
+
sources.push({ type: 'package.json', field: 'dependencies.jest' });
|
|
2878
2855
|
}
|
|
2879
|
-
const configPath = locateConfigFile(projectPath,
|
|
2856
|
+
const configPath = locateConfigFile(projectPath, JEST_CONFIG_PATTERNS);
|
|
2880
2857
|
if (configPath) {
|
|
2881
|
-
confidence +=
|
|
2858
|
+
confidence += 30;
|
|
2882
2859
|
sources.push({ type: 'config-file', path: configPath });
|
|
2883
2860
|
}
|
|
2884
|
-
if (
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
exists(join$1(projectPath, 'vite.config.mjs'));
|
|
2888
|
-
if (viteConfig && deps['vitest']) {
|
|
2889
|
-
confidence += 5;
|
|
2890
|
-
sources.push({ type: 'config-file', path: 'vite.config.*' });
|
|
2891
|
-
}
|
|
2861
|
+
if (pkg && 'jest' in pkg) {
|
|
2862
|
+
confidence += 20;
|
|
2863
|
+
sources.push({ type: 'package.json', field: 'jest' });
|
|
2892
2864
|
}
|
|
2893
2865
|
const testScript = pkg?.scripts?.['test'] ?? '';
|
|
2894
|
-
if (testScript.includes('
|
|
2866
|
+
if (testScript.includes('jest')) {
|
|
2895
2867
|
confidence += 10;
|
|
2896
2868
|
sources.push({ type: 'package.json', field: 'scripts.test' });
|
|
2897
2869
|
}
|
|
2870
|
+
if (deps['@types/jest']) {
|
|
2871
|
+
confidence += 5;
|
|
2872
|
+
sources.push({ type: 'package.json', field: 'dependencies.@types/jest' });
|
|
2873
|
+
}
|
|
2874
|
+
if (deps['ts-jest']) {
|
|
2875
|
+
confidence += 5;
|
|
2876
|
+
sources.push({ type: 'package.json', field: 'dependencies.ts-jest' });
|
|
2877
|
+
}
|
|
2898
2878
|
if (confidence === 0) {
|
|
2899
2879
|
return null;
|
|
2900
2880
|
}
|
|
2901
2881
|
return {
|
|
2902
|
-
id: '
|
|
2903
|
-
name: '
|
|
2882
|
+
id: 'jest',
|
|
2883
|
+
name: 'Jest',
|
|
2904
2884
|
type: 'unit',
|
|
2905
2885
|
version,
|
|
2906
2886
|
configPath,
|
|
@@ -2917,6 +2897,17 @@ const MOCHA_CONFIG_PATTERNS = ['.mocharc.js', '.mocharc.json', '.mocharc.yaml',
|
|
|
2917
2897
|
* @param projectPath - Project directory path
|
|
2918
2898
|
* @param packageJson - Optional pre-loaded package.json
|
|
2919
2899
|
* @returns Detection result or null if not detected
|
|
2900
|
+
*
|
|
2901
|
+
* @example Detecting Mocha testing framework
|
|
2902
|
+
* ```typescript
|
|
2903
|
+
* import { mochaDetector } from '@hyperfrontend/project-scope'
|
|
2904
|
+
*
|
|
2905
|
+
* const result = mochaDetector('./my-project')
|
|
2906
|
+
* if (result) {
|
|
2907
|
+
* console.log(`Mocha ${result.version} detected (${result.confidence}%)`)
|
|
2908
|
+
* // => "Mocha 10.2.0 detected (95%)"
|
|
2909
|
+
* }
|
|
2910
|
+
* ```
|
|
2920
2911
|
*/
|
|
2921
2912
|
function mochaDetector(projectPath, packageJson) {
|
|
2922
2913
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -2961,37 +2952,53 @@ function mochaDetector(projectPath, packageJson) {
|
|
|
2961
2952
|
};
|
|
2962
2953
|
}
|
|
2963
2954
|
|
|
2964
|
-
/** Config patterns for
|
|
2965
|
-
const
|
|
2955
|
+
/** Config patterns for Playwright */
|
|
2956
|
+
const PLAYWRIGHT_CONFIG_PATTERNS = ['playwright.config.js', 'playwright.config.ts', 'playwright.config.mjs'];
|
|
2966
2957
|
/**
|
|
2967
|
-
* Detect
|
|
2958
|
+
* Detect Playwright in project.
|
|
2968
2959
|
*
|
|
2969
2960
|
* @param projectPath - Project directory path
|
|
2970
2961
|
* @param packageJson - Optional pre-loaded package.json
|
|
2971
2962
|
* @returns Detection result or null if not detected
|
|
2963
|
+
*
|
|
2964
|
+
* @example Detecting Playwright testing framework
|
|
2965
|
+
* ```typescript
|
|
2966
|
+
* import { playwrightDetector } from '@hyperfrontend/project-scope'
|
|
2967
|
+
*
|
|
2968
|
+
* const result = playwrightDetector('./my-project')
|
|
2969
|
+
* if (result) {
|
|
2970
|
+
* console.log(`Playwright ${result.version} (${result.type} tests)`)
|
|
2971
|
+
* // => "Playwright 1.42.0 (e2e tests)"
|
|
2972
|
+
* }
|
|
2973
|
+
* ```
|
|
2972
2974
|
*/
|
|
2973
|
-
function
|
|
2975
|
+
function playwrightDetector(projectPath, packageJson) {
|
|
2974
2976
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
2975
2977
|
const sources = [];
|
|
2976
2978
|
let confidence = 0;
|
|
2977
2979
|
let version;
|
|
2978
2980
|
const deps = collectAllDependencies(pkg);
|
|
2979
|
-
if (deps['
|
|
2980
|
-
confidence +=
|
|
2981
|
-
version = parseVersionString(deps['
|
|
2982
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
2981
|
+
if (deps['@playwright/test']) {
|
|
2982
|
+
confidence += 70;
|
|
2983
|
+
version = parseVersionString(deps['@playwright/test']);
|
|
2984
|
+
sources.push({ type: 'package.json', field: 'dependencies.@playwright/test' });
|
|
2983
2985
|
}
|
|
2984
|
-
|
|
2986
|
+
if (deps['playwright']) {
|
|
2987
|
+
confidence += 50;
|
|
2988
|
+
version = version ?? parseVersionString(deps['playwright']);
|
|
2989
|
+
sources.push({ type: 'package.json', field: 'dependencies.playwright' });
|
|
2990
|
+
}
|
|
2991
|
+
const configPath = locateConfigFile(projectPath, PLAYWRIGHT_CONFIG_PATTERNS);
|
|
2985
2992
|
if (configPath) {
|
|
2986
|
-
confidence +=
|
|
2993
|
+
confidence += 25;
|
|
2987
2994
|
sources.push({ type: 'config-file', path: configPath });
|
|
2988
2995
|
}
|
|
2989
|
-
if (exists(join$1(projectPath, '
|
|
2990
|
-
confidence +=
|
|
2991
|
-
sources.push({ type: 'directory', path: '
|
|
2996
|
+
if (exists(join$1(projectPath, 'e2e')) || exists(join$1(projectPath, 'tests'))) {
|
|
2997
|
+
confidence += 5;
|
|
2998
|
+
sources.push({ type: 'directory', path: 'e2e/ or tests/' });
|
|
2992
2999
|
}
|
|
2993
3000
|
const e2eScript = pkg?.scripts?.['e2e'] ?? pkg?.scripts?.['test:e2e'] ?? '';
|
|
2994
|
-
if (e2eScript.includes('
|
|
3001
|
+
if (e2eScript.includes('playwright')) {
|
|
2995
3002
|
confidence += 5;
|
|
2996
3003
|
sources.push({ type: 'package.json', field: 'scripts.e2e or scripts.test:e2e' });
|
|
2997
3004
|
}
|
|
@@ -2999,8 +3006,8 @@ function cypressDetector(projectPath, packageJson) {
|
|
|
2999
3006
|
return null;
|
|
3000
3007
|
}
|
|
3001
3008
|
return {
|
|
3002
|
-
id: '
|
|
3003
|
-
name: '
|
|
3009
|
+
id: 'playwright',
|
|
3010
|
+
name: 'Playwright',
|
|
3004
3011
|
type: 'e2e',
|
|
3005
3012
|
version,
|
|
3006
3013
|
configPath,
|
|
@@ -3009,52 +3016,64 @@ function cypressDetector(projectPath, packageJson) {
|
|
|
3009
3016
|
};
|
|
3010
3017
|
}
|
|
3011
3018
|
|
|
3012
|
-
/** Config patterns for
|
|
3013
|
-
const
|
|
3019
|
+
/** Config patterns for Vitest */
|
|
3020
|
+
const VITEST_CONFIG_PATTERNS = ['vitest.config.js', 'vitest.config.ts', 'vitest.config.mjs'];
|
|
3014
3021
|
/**
|
|
3015
|
-
* Detect
|
|
3022
|
+
* Detect Vitest in project.
|
|
3016
3023
|
*
|
|
3017
3024
|
* @param projectPath - Project directory path
|
|
3018
3025
|
* @param packageJson - Optional pre-loaded package.json
|
|
3019
3026
|
* @returns Detection result or null if not detected
|
|
3027
|
+
*
|
|
3028
|
+
* @example Detecting Vitest testing framework
|
|
3029
|
+
* ```typescript
|
|
3030
|
+
* import { vitestDetector } from '@hyperfrontend/project-scope'
|
|
3031
|
+
*
|
|
3032
|
+
* const result = vitestDetector('./my-project')
|
|
3033
|
+
* if (result) {
|
|
3034
|
+
* console.log(`Vitest ${result.version} detected`)
|
|
3035
|
+
* console.log('Config:', result.configPath)
|
|
3036
|
+
* // => "Config: vitest.config.ts"
|
|
3037
|
+
* }
|
|
3038
|
+
* ```
|
|
3020
3039
|
*/
|
|
3021
|
-
function
|
|
3040
|
+
function vitestDetector(projectPath, packageJson) {
|
|
3022
3041
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
3023
3042
|
const sources = [];
|
|
3024
3043
|
let confidence = 0;
|
|
3025
3044
|
let version;
|
|
3026
3045
|
const deps = collectAllDependencies(pkg);
|
|
3027
|
-
if (deps['
|
|
3046
|
+
if (deps['vitest']) {
|
|
3028
3047
|
confidence += 70;
|
|
3029
|
-
version = parseVersionString(deps['
|
|
3030
|
-
sources.push({ type: 'package.json', field: 'dependencies
|
|
3031
|
-
}
|
|
3032
|
-
if (deps['playwright']) {
|
|
3033
|
-
confidence += 50;
|
|
3034
|
-
version = version ?? parseVersionString(deps['playwright']);
|
|
3035
|
-
sources.push({ type: 'package.json', field: 'dependencies.playwright' });
|
|
3048
|
+
version = parseVersionString(deps['vitest']);
|
|
3049
|
+
sources.push({ type: 'package.json', field: 'dependencies.vitest' });
|
|
3036
3050
|
}
|
|
3037
|
-
const configPath = locateConfigFile(projectPath,
|
|
3051
|
+
const configPath = locateConfigFile(projectPath, VITEST_CONFIG_PATTERNS);
|
|
3038
3052
|
if (configPath) {
|
|
3039
3053
|
confidence += 25;
|
|
3040
3054
|
sources.push({ type: 'config-file', path: configPath });
|
|
3041
3055
|
}
|
|
3042
|
-
if (
|
|
3043
|
-
|
|
3044
|
-
|
|
3056
|
+
if (!configPath) {
|
|
3057
|
+
const viteConfig = exists(join$1(projectPath, 'vite.config.ts')) ||
|
|
3058
|
+
exists(join$1(projectPath, 'vite.config.js')) ||
|
|
3059
|
+
exists(join$1(projectPath, 'vite.config.mjs'));
|
|
3060
|
+
if (viteConfig && deps['vitest']) {
|
|
3061
|
+
confidence += 5;
|
|
3062
|
+
sources.push({ type: 'config-file', path: 'vite.config.*' });
|
|
3063
|
+
}
|
|
3045
3064
|
}
|
|
3046
|
-
const
|
|
3047
|
-
if (
|
|
3048
|
-
confidence +=
|
|
3049
|
-
sources.push({ type: 'package.json', field: 'scripts.
|
|
3065
|
+
const testScript = pkg?.scripts?.['test'] ?? '';
|
|
3066
|
+
if (testScript.includes('vitest')) {
|
|
3067
|
+
confidence += 10;
|
|
3068
|
+
sources.push({ type: 'package.json', field: 'scripts.test' });
|
|
3050
3069
|
}
|
|
3051
3070
|
if (confidence === 0) {
|
|
3052
3071
|
return null;
|
|
3053
3072
|
}
|
|
3054
3073
|
return {
|
|
3055
|
-
id: '
|
|
3056
|
-
name: '
|
|
3057
|
-
type: '
|
|
3074
|
+
id: 'vitest',
|
|
3075
|
+
name: 'Vitest',
|
|
3076
|
+
type: 'unit',
|
|
3058
3077
|
version,
|
|
3059
3078
|
configPath,
|
|
3060
3079
|
confidence: min(confidence, 100),
|
|
@@ -3097,6 +3116,19 @@ function checkTsConfigStrict(projectPath) {
|
|
|
3097
3116
|
* @param projectPath - Project directory path
|
|
3098
3117
|
* @param packageJson - Optional pre-loaded package.json
|
|
3099
3118
|
* @returns Detection result or null if not detected
|
|
3119
|
+
*
|
|
3120
|
+
* @example Detecting TypeScript
|
|
3121
|
+
* ```typescript
|
|
3122
|
+
* import { typescriptDetector } from '@hyperfrontend/project-scope'
|
|
3123
|
+
*
|
|
3124
|
+
* const result = typescriptDetector('./my-project')
|
|
3125
|
+
* if (result) {
|
|
3126
|
+
* console.log(`TypeScript ${result.version}`)
|
|
3127
|
+
* console.log(`Strict mode: ${result.strictMode ?? 'unknown'}`)
|
|
3128
|
+
* // => "TypeScript 5.3.0"
|
|
3129
|
+
* // => "Strict mode: true"
|
|
3130
|
+
* }
|
|
3131
|
+
* ```
|
|
3100
3132
|
*/
|
|
3101
3133
|
function typescriptDetector(projectPath, packageJson) {
|
|
3102
3134
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -3148,6 +3180,17 @@ function typescriptDetector(projectPath, packageJson) {
|
|
|
3148
3180
|
* @param projectPath - Project directory path
|
|
3149
3181
|
* @param packageJson - Optional pre-loaded package.json
|
|
3150
3182
|
* @returns Detection result or null if not detected
|
|
3183
|
+
*
|
|
3184
|
+
* @example Detecting Flow type system
|
|
3185
|
+
* ```typescript
|
|
3186
|
+
* import { flowDetector } from '@hyperfrontend/project-scope'
|
|
3187
|
+
*
|
|
3188
|
+
* const result = flowDetector('./my-project')
|
|
3189
|
+
* if (result) {
|
|
3190
|
+
* console.log(`Flow ${result.version} with config: ${result.configPath}`)
|
|
3191
|
+
* // => "Flow 0.232.0 with config: .flowconfig"
|
|
3192
|
+
* }
|
|
3193
|
+
* ```
|
|
3151
3194
|
*/
|
|
3152
3195
|
function flowDetector(projectPath, packageJson) {
|
|
3153
3196
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -3205,6 +3248,18 @@ function hasJsDocTypes(content) {
|
|
|
3205
3248
|
* @param projectPath - Project directory path
|
|
3206
3249
|
* @param packageJson - Optional pre-loaded package.json
|
|
3207
3250
|
* @returns Detection result or null if not detected
|
|
3251
|
+
*
|
|
3252
|
+
* @example Detecting JSDoc type annotations
|
|
3253
|
+
* ```typescript
|
|
3254
|
+
* import { jsdocDetector } from '@hyperfrontend/project-scope'
|
|
3255
|
+
*
|
|
3256
|
+
* const result = jsdocDetector('./my-project')
|
|
3257
|
+
* if (result) {
|
|
3258
|
+
* console.log('JSDoc types detected')
|
|
3259
|
+
* console.log('Sources:', result.detectedFrom.map(s => s.path ?? s.field))
|
|
3260
|
+
* // => "Sources: ['jsconfig.json', 'src/utils.js (JSDoc annotations)']"
|
|
3261
|
+
* }
|
|
3262
|
+
* ```
|
|
3208
3263
|
*/
|
|
3209
3264
|
function jsdocDetector(projectPath, packageJson) {
|
|
3210
3265
|
const pkg = packageJson ?? readPackageJsonIfExists(projectPath);
|
|
@@ -3298,7 +3353,7 @@ function isDetectAllOptions(value) {
|
|
|
3298
3353
|
* @param packageJsonOrOptions - Optional pre-loaded package.json or options object
|
|
3299
3354
|
* @returns All detection results organized by category
|
|
3300
3355
|
*
|
|
3301
|
-
* @example
|
|
3356
|
+
* @example Running all tech detectors
|
|
3302
3357
|
* ```typescript
|
|
3303
3358
|
* import { detectAll } from '@hyperfrontend/project-scope'
|
|
3304
3359
|
*
|
|
@@ -3415,7 +3470,7 @@ function buildSummary(frontend, backend, testing) {
|
|
|
3415
3470
|
* @param options - Identification options
|
|
3416
3471
|
* @returns Framework identification result
|
|
3417
3472
|
*
|
|
3418
|
-
* @example
|
|
3473
|
+
* @example Identifying all frameworks in project
|
|
3419
3474
|
* ```typescript
|
|
3420
3475
|
* import { identifyFrameworks } from '@hyperfrontend/project-scope'
|
|
3421
3476
|
*
|
|
@@ -3530,6 +3585,14 @@ function identifyFrameworks(projectPath, options) {
|
|
|
3530
3585
|
* Clear the framework identification cache.
|
|
3531
3586
|
*
|
|
3532
3587
|
* Useful for testing or when the project files have changed.
|
|
3588
|
+
*
|
|
3589
|
+
* @example Clearing the framework cache
|
|
3590
|
+
* ```typescript
|
|
3591
|
+
* import { clearFrameworkIdentificationCache } from '@hyperfrontend/project-scope'
|
|
3592
|
+
*
|
|
3593
|
+
* // Reset cache before re-identifying frameworks
|
|
3594
|
+
* clearFrameworkIdentificationCache()
|
|
3595
|
+
* ```
|
|
3533
3596
|
*/
|
|
3534
3597
|
function clearFrameworkIdentificationCache() {
|
|
3535
3598
|
frameworkIdCache.clear();
|
|
@@ -3541,6 +3604,15 @@ function clearFrameworkIdentificationCache() {
|
|
|
3541
3604
|
* @param frameworkId - Framework identifier to check
|
|
3542
3605
|
* @param minConfidence - Minimum confidence threshold (default: 50)
|
|
3543
3606
|
* @returns True if the framework is detected with sufficient confidence
|
|
3607
|
+
*
|
|
3608
|
+
* @example Checking for a specific framework
|
|
3609
|
+
* ```typescript
|
|
3610
|
+
* import { usesFramework } from '@hyperfrontend/project-scope'
|
|
3611
|
+
*
|
|
3612
|
+
* if (usesFramework('/path/to/project', 'react', 70)) {
|
|
3613
|
+
* console.log('Project uses React with high confidence')
|
|
3614
|
+
* }
|
|
3615
|
+
* ```
|
|
3544
3616
|
*/
|
|
3545
3617
|
function usesFramework(projectPath, frameworkId, minConfidence = 50) {
|
|
3546
3618
|
const identification = identifyFrameworks(projectPath, { minConfidence });
|
|
@@ -3549,4 +3621,3 @@ function usesFramework(projectPath, frameworkId, minConfidence = 50) {
|
|
|
3549
3621
|
}
|
|
3550
3622
|
|
|
3551
3623
|
export { clearFrameworkIdentificationCache, identifyFrameworks, usesFramework };
|
|
3552
|
-
//# sourceMappingURL=index.esm.js.map
|