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