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