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