@hyperfrontend/project-scope 0.1.0 → 0.2.1
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 +15 -3
- package/README.md +2 -0
- package/analyze.d.ts.map +1 -1
- package/cli/commands/analyze.d.ts +8 -0
- package/cli/commands/analyze.d.ts.map +1 -1
- package/cli/commands/config.d.ts +7 -0
- package/cli/commands/config.d.ts.map +1 -1
- package/cli/commands/deps.d.ts +6 -0
- package/cli/commands/deps.d.ts.map +1 -1
- package/cli/commands/tree.d.ts +12 -0
- package/cli/commands/tree.d.ts.map +1 -1
- package/cli/index.cjs.js +73 -206
- package/cli/index.cjs.js.map +1 -1
- package/cli/index.esm.js +73 -206
- package/cli/index.esm.js.map +1 -1
- package/cli/run.d.ts.map +1 -1
- package/core/cache.d.ts +1 -0
- package/core/cache.d.ts.map +1 -1
- package/core/encoding/convert.d.ts.map +1 -1
- package/core/encoding/detect.d.ts +5 -0
- package/core/encoding/detect.d.ts.map +1 -1
- package/core/encoding/index.cjs.js +2 -23
- package/core/encoding/index.cjs.js.map +1 -1
- package/core/encoding/index.esm.js +2 -23
- package/core/encoding/index.esm.js.map +1 -1
- package/core/errors/structured-errors.d.ts +2 -0
- package/core/errors/structured-errors.d.ts.map +1 -1
- package/core/fs/directory.d.ts +3 -0
- package/core/fs/directory.d.ts.map +1 -1
- package/core/fs/index.cjs.js +0 -14
- package/core/fs/index.cjs.js.map +1 -1
- package/core/fs/index.esm.js +0 -14
- package/core/fs/index.esm.js.map +1 -1
- package/core/fs/read.d.ts +11 -3
- package/core/fs/read.d.ts.map +1 -1
- package/core/fs/traversal.d.ts.map +1 -1
- package/core/index.cjs.js +11 -63
- package/core/index.cjs.js.map +1 -1
- package/core/index.esm.js +11 -63
- package/core/index.esm.js.map +1 -1
- package/core/logger.d.ts.map +1 -1
- package/core/path/index.cjs.js +5 -2
- package/core/path/index.cjs.js.map +1 -1
- package/core/path/index.esm.js +5 -2
- package/core/path/index.esm.js.map +1 -1
- package/core/path/normalize.d.ts.map +1 -1
- package/core/patterns/glob.d.ts +0 -4
- package/core/patterns/glob.d.ts.map +1 -1
- package/core/platform/detect.d.ts.map +1 -1
- package/core/platform/index.cjs.js +0 -10
- package/core/platform/index.cjs.js.map +1 -1
- package/core/platform/index.esm.js +0 -10
- package/core/platform/index.esm.js.map +1 -1
- package/core/platform/line-endings.d.ts.map +1 -1
- package/heuristics/dependencies/analyze.d.ts.map +1 -1
- package/heuristics/dependencies/index.cjs.js +0 -17
- package/heuristics/dependencies/index.cjs.js.map +1 -1
- package/heuristics/dependencies/index.esm.js +0 -17
- package/heuristics/dependencies/index.esm.js.map +1 -1
- package/heuristics/entry-points/discover.d.ts +34 -7
- package/heuristics/entry-points/discover.d.ts.map +1 -1
- package/heuristics/entry-points/index.cjs.js +6 -34
- package/heuristics/entry-points/index.cjs.js.map +1 -1
- package/heuristics/entry-points/index.esm.js +6 -34
- package/heuristics/entry-points/index.esm.js.map +1 -1
- package/heuristics/framework/index.cjs.js +1 -63
- package/heuristics/framework/index.cjs.js.map +1 -1
- package/heuristics/framework/index.esm.js +1 -63
- package/heuristics/framework/index.esm.js.map +1 -1
- package/heuristics/index.cjs.js +7 -88
- package/heuristics/index.cjs.js.map +1 -1
- package/heuristics/index.esm.js +7 -88
- package/heuristics/index.esm.js.map +1 -1
- package/heuristics/project-type/index.cjs.js +1 -63
- package/heuristics/project-type/index.cjs.js.map +1 -1
- package/heuristics/project-type/index.esm.js +1 -63
- package/heuristics/project-type/index.esm.js.map +1 -1
- package/index.cjs.js +86 -294
- package/index.cjs.js.map +1 -1
- package/index.esm.js +86 -294
- package/index.esm.js.map +1 -1
- package/nx/detect.d.ts.map +1 -1
- package/nx/devkit-loader.d.ts.map +1 -1
- package/nx/index.cjs.js +0 -29
- package/nx/index.cjs.js.map +1 -1
- package/nx/index.esm.js +0 -29
- package/nx/index.esm.js.map +1 -1
- package/nx/project-config.d.ts +2 -0
- package/nx/project-config.d.ts.map +1 -1
- package/package.json +9 -9
- package/project/config/index.cjs.js +4 -46
- package/project/config/index.cjs.js.map +1 -1
- package/project/config/index.esm.js +4 -46
- package/project/config/index.esm.js.map +1 -1
- package/project/config/patterns.d.ts.map +1 -1
- package/project/index.cjs.js +4 -47
- package/project/index.cjs.js.map +1 -1
- package/project/index.esm.js +4 -47
- package/project/index.esm.js.map +1 -1
- package/project/package/index.cjs.js +0 -11
- package/project/package/index.cjs.js.map +1 -1
- package/project/package/index.esm.js +0 -11
- package/project/package/index.esm.js.map +1 -1
- package/project/package/read.d.ts +1 -0
- package/project/package/read.d.ts.map +1 -1
- package/project/root/index.cjs.js +0 -11
- package/project/root/index.cjs.js.map +1 -1
- package/project/root/index.esm.js +0 -11
- package/project/root/index.esm.js.map +1 -1
- package/project/traversal/index.cjs.js +4 -28
- package/project/traversal/index.cjs.js.map +1 -1
- package/project/traversal/index.esm.js +4 -28
- package/project/traversal/index.esm.js.map +1 -1
- package/tech/backend/express.d.ts.map +1 -1
- package/tech/backend/fastify.d.ts.map +1 -1
- package/tech/backend/index.cjs.js +0 -17
- package/tech/backend/index.cjs.js.map +1 -1
- package/tech/backend/index.esm.js +0 -17
- package/tech/backend/index.esm.js.map +1 -1
- package/tech/backend/koa.d.ts.map +1 -1
- package/tech/backend/nestjs.d.ts.map +1 -1
- package/tech/build/index.cjs.js +0 -12
- package/tech/build/index.cjs.js.map +1 -1
- package/tech/build/index.esm.js +0 -12
- package/tech/build/index.esm.js.map +1 -1
- package/tech/frontend/index.cjs.js +0 -16
- package/tech/frontend/index.cjs.js.map +1 -1
- package/tech/frontend/index.esm.js +0 -16
- package/tech/frontend/index.esm.js.map +1 -1
- package/tech/frontend/qwik.d.ts.map +1 -1
- package/tech/frontend/remix.d.ts.map +1 -1
- package/tech/frontend/sveltekit.d.ts.map +1 -1
- package/tech/index.cjs.js +1 -63
- package/tech/index.cjs.js.map +1 -1
- package/tech/index.d.ts.map +1 -1
- package/tech/index.esm.js +1 -63
- package/tech/index.esm.js.map +1 -1
- package/tech/legacy/angularjs.d.ts.map +1 -1
- package/tech/legacy/backbone.d.ts.map +1 -1
- package/tech/legacy/ember.d.ts.map +1 -1
- package/tech/legacy/index.cjs.js +0 -26
- package/tech/legacy/index.cjs.js.map +1 -1
- package/tech/legacy/index.esm.js +0 -26
- package/tech/legacy/index.esm.js.map +1 -1
- package/tech/legacy/jquery.d.ts.map +1 -1
- package/tech/linting/biome.d.ts.map +1 -1
- package/tech/linting/index.cjs.js +0 -14
- package/tech/linting/index.cjs.js.map +1 -1
- package/tech/linting/index.esm.js +0 -14
- package/tech/linting/index.esm.js.map +1 -1
- package/tech/linting/prettier.d.ts.map +1 -1
- package/tech/monorepo/index.cjs.js +1 -13
- package/tech/monorepo/index.cjs.js.map +1 -1
- package/tech/monorepo/index.esm.js +1 -13
- package/tech/monorepo/index.esm.js.map +1 -1
- package/tech/monorepo/types.d.ts +1 -1
- package/tech/monorepo/types.d.ts.map +1 -1
- package/tech/shared-utils/detector-helpers.d.ts.map +1 -1
- package/tech/testing/index.cjs.js +0 -12
- package/tech/testing/index.cjs.js.map +1 -1
- package/tech/testing/index.esm.js +0 -12
- package/tech/testing/index.esm.js.map +1 -1
- package/tech/types/detectors.d.ts.map +1 -1
- package/tech/types/index.cjs.js +0 -27
- package/tech/types/index.cjs.js.map +1 -1
- package/tech/types/index.esm.js +0 -27
- package/tech/types/index.esm.js.map +1 -1
- package/vfs/commit.d.ts.map +1 -1
- package/vfs/diff.d.ts.map +1 -1
- package/vfs/factory.d.ts.map +1 -1
- package/vfs/fs-tree.d.ts.map +1 -1
- package/vfs/index.cjs.js +5 -46
- package/vfs/index.cjs.js.map +1 -1
- package/vfs/index.esm.js +5 -46
- package/vfs/index.esm.js.map +1 -1
- package/vfs/types.d.ts +1 -0
- package/vfs/types.d.ts.map +1 -1
package/heuristics/index.cjs.js
CHANGED
|
@@ -11,7 +11,6 @@ var node_fs = require('node:fs');
|
|
|
11
11
|
*
|
|
12
12
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/json
|
|
13
13
|
*/
|
|
14
|
-
// Capture references at module initialization time
|
|
15
14
|
const _JSON = globalThis.JSON;
|
|
16
15
|
/**
|
|
17
16
|
* (Safe copy) Converts a JavaScript Object Notation (JSON) string into an object.
|
|
@@ -30,7 +29,6 @@ const stringify = _JSON.stringify;
|
|
|
30
29
|
*
|
|
31
30
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/math
|
|
32
31
|
*/
|
|
33
|
-
// Capture references at module initialization time
|
|
34
32
|
const _Math = globalThis.Math;
|
|
35
33
|
/**
|
|
36
34
|
* (Safe copy) Returns the value of a number rounded to the nearest integer.
|
|
@@ -49,7 +47,6 @@ const min = _Math.min;
|
|
|
49
47
|
*
|
|
50
48
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/object
|
|
51
49
|
*/
|
|
52
|
-
// Capture references at module initialization time
|
|
53
50
|
const _Object = globalThis.Object;
|
|
54
51
|
/**
|
|
55
52
|
* (Safe copy) Prevents modification of existing property attributes and values,
|
|
@@ -84,7 +81,6 @@ const defineProperties = _Object.defineProperties;
|
|
|
84
81
|
*
|
|
85
82
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/error
|
|
86
83
|
*/
|
|
87
|
-
// Capture references at module initialization time
|
|
88
84
|
const _Error = globalThis.Error;
|
|
89
85
|
const _Reflect$2 = globalThis.Reflect;
|
|
90
86
|
/**
|
|
@@ -105,7 +101,6 @@ const createError = (message, options) => _Reflect$2.construct(_Error, [message,
|
|
|
105
101
|
*
|
|
106
102
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/array
|
|
107
103
|
*/
|
|
108
|
-
// Capture references at module initialization time
|
|
109
104
|
const _Array = globalThis.Array;
|
|
110
105
|
/**
|
|
111
106
|
* (Safe copy) Determines whether the passed value is an Array.
|
|
@@ -120,7 +115,6 @@ const isArray = _Array.isArray;
|
|
|
120
115
|
*
|
|
121
116
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/console
|
|
122
117
|
*/
|
|
123
|
-
// Capture references at module initialization time
|
|
124
118
|
const _console = globalThis.console;
|
|
125
119
|
/**
|
|
126
120
|
* (Safe copy) Outputs a message to the console.
|
|
@@ -206,7 +200,6 @@ _console.timeLog.bind(_console);
|
|
|
206
200
|
*
|
|
207
201
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/set
|
|
208
202
|
*/
|
|
209
|
-
// Capture references at module initialization time
|
|
210
203
|
const _Set = globalThis.Set;
|
|
211
204
|
const _Reflect$1 = globalThis.Reflect;
|
|
212
205
|
/**
|
|
@@ -254,7 +247,6 @@ const getType = (target) => {
|
|
|
254
247
|
*
|
|
255
248
|
* @module @hyperfrontend/immutable-api-utils/built-in-copy/map
|
|
256
249
|
*/
|
|
257
|
-
// Capture references at module initialization time
|
|
258
250
|
const _Map = globalThis.Map;
|
|
259
251
|
const _Reflect = globalThis.Reflect;
|
|
260
252
|
/**
|
|
@@ -532,14 +524,11 @@ function formatMessage(namespace, message, meta) {
|
|
|
532
524
|
*/
|
|
533
525
|
function createScopedLogger(namespace, options = {}) {
|
|
534
526
|
const { level = 'error', sanitizeSecrets = true } = options;
|
|
535
|
-
// Create wrapper functions that add namespace prefix and sanitization
|
|
536
527
|
const createLogFn = (baseFn) => (message, meta) => {
|
|
537
528
|
const processedMeta = sanitizeSecrets && meta ? sanitize(meta) : meta;
|
|
538
529
|
baseFn(formatMessage(namespace, message, processedMeta));
|
|
539
530
|
};
|
|
540
|
-
// Create base logger with wrapped functions
|
|
541
531
|
const baseLogger = createLogger(createLogFn(error), createLogFn(warn), createLogFn(log), createLogFn(info), createLogFn(debug));
|
|
542
|
-
// Set initial log level (use global override if set)
|
|
543
532
|
baseLogger.setLogLevel(level);
|
|
544
533
|
const scopedLogger = freeze({
|
|
545
534
|
error: (message, meta) => baseLogger.error(message, meta),
|
|
@@ -550,7 +539,6 @@ function createScopedLogger(namespace, options = {}) {
|
|
|
550
539
|
setLogLevel: baseLogger.setLogLevel,
|
|
551
540
|
getLogLevel: baseLogger.getLogLevel,
|
|
552
541
|
});
|
|
553
|
-
// Register logger for global level management
|
|
554
542
|
loggerRegistry.add(scopedLogger);
|
|
555
543
|
return scopedLogger;
|
|
556
544
|
}
|
|
@@ -881,7 +869,6 @@ const cacheRegistry = createSet();
|
|
|
881
869
|
function createCache(options) {
|
|
882
870
|
const { ttl, maxSize } = options ?? {};
|
|
883
871
|
const store = createMap();
|
|
884
|
-
// Track insertion order for FIFO eviction
|
|
885
872
|
const insertionOrder = [];
|
|
886
873
|
/**
|
|
887
874
|
* Check if an entry is expired.
|
|
@@ -932,12 +919,10 @@ function createCache(options) {
|
|
|
932
919
|
return entry.value;
|
|
933
920
|
},
|
|
934
921
|
set(key, value) {
|
|
935
|
-
// If key exists, remove from order first
|
|
936
922
|
if (store.has(key)) {
|
|
937
923
|
removeFromOrder(key);
|
|
938
924
|
}
|
|
939
925
|
else {
|
|
940
|
-
// Evict if needed before adding new entry
|
|
941
926
|
evictIfNeeded();
|
|
942
927
|
}
|
|
943
928
|
// eslint-disable-next-line workspace/no-unsafe-builtin-methods -- Date.now() is needed for Jest fake timers compatibility
|
|
@@ -970,7 +955,6 @@ function createCache(options) {
|
|
|
970
955
|
return [...insertionOrder];
|
|
971
956
|
},
|
|
972
957
|
};
|
|
973
|
-
// Register cache for global operations
|
|
974
958
|
cacheRegistry.add(cache);
|
|
975
959
|
return freeze(cache);
|
|
976
960
|
}
|
|
@@ -1001,7 +985,6 @@ function collectAllDependencies(packageJson) {
|
|
|
1001
985
|
function parseVersionString(versionString) {
|
|
1002
986
|
if (versionString === undefined || versionString === null)
|
|
1003
987
|
return undefined;
|
|
1004
|
-
// Manual parsing instead of regex to avoid ReDoS
|
|
1005
988
|
let start = 0;
|
|
1006
989
|
while (start < versionString.length) {
|
|
1007
990
|
const char = versionString[start];
|
|
@@ -1062,7 +1045,6 @@ function expressDetector(projectPath, packageJson) {
|
|
|
1062
1045
|
version = parseVersionString(deps['express']);
|
|
1063
1046
|
sources.push({ type: 'package.json', field: 'dependencies.express' });
|
|
1064
1047
|
}
|
|
1065
|
-
// @types/express (indicates usage)
|
|
1066
1048
|
if (deps['@types/express']) {
|
|
1067
1049
|
confidence += 10;
|
|
1068
1050
|
sources.push({ type: 'package.json', field: 'dependencies.@types/express' });
|
|
@@ -1098,13 +1080,11 @@ function nestDetector(projectPath, packageJson) {
|
|
|
1098
1080
|
let version;
|
|
1099
1081
|
let configPath;
|
|
1100
1082
|
const deps = collectAllDependencies(pkg);
|
|
1101
|
-
// @nestjs/core package
|
|
1102
1083
|
if (deps['@nestjs/core']) {
|
|
1103
1084
|
confidence += 70;
|
|
1104
1085
|
version = parseVersionString(deps['@nestjs/core']);
|
|
1105
1086
|
sources.push({ type: 'package.json', field: 'dependencies.@nestjs/core' });
|
|
1106
1087
|
}
|
|
1107
|
-
// @nestjs/common
|
|
1108
1088
|
if (deps['@nestjs/common']) {
|
|
1109
1089
|
confidence += 15;
|
|
1110
1090
|
sources.push({ type: 'package.json', field: 'dependencies.@nestjs/common' });
|
|
@@ -1155,7 +1135,6 @@ function fastifyDetector(projectPath, packageJson) {
|
|
|
1155
1135
|
confidence += 15;
|
|
1156
1136
|
sources.push({ type: 'package.json', field: 'dependencies (fastify plugins)' });
|
|
1157
1137
|
}
|
|
1158
|
-
// @types/fastify (older versions)
|
|
1159
1138
|
if (deps['@types/fastify']) {
|
|
1160
1139
|
confidence += 5;
|
|
1161
1140
|
sources.push({ type: 'package.json', field: 'dependencies.@types/fastify' });
|
|
@@ -1190,7 +1169,6 @@ function koaDetector(projectPath, packageJson) {
|
|
|
1190
1169
|
version = parseVersionString(deps['koa']);
|
|
1191
1170
|
sources.push({ type: 'package.json', field: 'dependencies.koa' });
|
|
1192
1171
|
}
|
|
1193
|
-
// @types/koa
|
|
1194
1172
|
if (deps['@types/koa']) {
|
|
1195
1173
|
confidence += 10;
|
|
1196
1174
|
sources.push({ type: 'package.json', field: 'dependencies.@types/koa' });
|
|
@@ -1733,7 +1711,6 @@ function remixDetector(projectPath, packageJson) {
|
|
|
1733
1711
|
let confidence = 0;
|
|
1734
1712
|
let version;
|
|
1735
1713
|
const deps = collectAllDependencies(pkg);
|
|
1736
|
-
// @remix-run packages
|
|
1737
1714
|
if (deps['@remix-run/react']) {
|
|
1738
1715
|
confidence += 70;
|
|
1739
1716
|
version = parseVersionString(deps['@remix-run/react']);
|
|
@@ -2009,7 +1986,6 @@ function sveltekitDetector(projectPath, packageJson) {
|
|
|
2009
1986
|
let confidence = 0;
|
|
2010
1987
|
let version;
|
|
2011
1988
|
const deps = collectAllDependencies(pkg);
|
|
2012
|
-
// @sveltejs/kit package
|
|
2013
1989
|
if (deps['@sveltejs/kit']) {
|
|
2014
1990
|
confidence += 70;
|
|
2015
1991
|
version = parseVersionString(deps['@sveltejs/kit']);
|
|
@@ -2088,13 +2064,11 @@ function qwikDetector(projectPath, packageJson) {
|
|
|
2088
2064
|
let confidence = 0;
|
|
2089
2065
|
let version;
|
|
2090
2066
|
const deps = collectAllDependencies(pkg);
|
|
2091
|
-
// @builder.io/qwik package
|
|
2092
2067
|
if (deps['@builder.io/qwik']) {
|
|
2093
2068
|
confidence += 70;
|
|
2094
2069
|
version = parseVersionString(deps['@builder.io/qwik']);
|
|
2095
2070
|
sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik' });
|
|
2096
2071
|
}
|
|
2097
|
-
// @builder.io/qwik-city
|
|
2098
2072
|
if (deps['@builder.io/qwik-city']) {
|
|
2099
2073
|
confidence += 20;
|
|
2100
2074
|
sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik-city' });
|
|
@@ -2187,23 +2161,19 @@ function angularJSDetector(projectPath, packageJson) {
|
|
|
2187
2161
|
let confidence = 0;
|
|
2188
2162
|
let version;
|
|
2189
2163
|
const deps = collectAllDependencies(pkg);
|
|
2190
|
-
// AngularJS package (angular, not @angular/core)
|
|
2191
2164
|
if (deps['angular']) {
|
|
2192
2165
|
confidence += 70;
|
|
2193
2166
|
version = parseVersionString(deps['angular']);
|
|
2194
2167
|
sources.push({ type: 'package.json', field: 'dependencies.angular' });
|
|
2195
2168
|
}
|
|
2196
|
-
// AngularJS router
|
|
2197
2169
|
if (deps['angular-route']) {
|
|
2198
2170
|
confidence += 15;
|
|
2199
2171
|
sources.push({ type: 'package.json', field: 'dependencies.angular-route' });
|
|
2200
2172
|
}
|
|
2201
|
-
// AngularJS resource
|
|
2202
2173
|
if (deps['angular-resource']) {
|
|
2203
2174
|
confidence += 10;
|
|
2204
2175
|
sources.push({ type: 'package.json', field: 'dependencies.angular-resource' });
|
|
2205
2176
|
}
|
|
2206
|
-
// AngularJS animate
|
|
2207
2177
|
if (deps['angular-animate']) {
|
|
2208
2178
|
confidence += 5;
|
|
2209
2179
|
sources.push({ type: 'package.json', field: 'dependencies.angular-animate' });
|
|
@@ -2234,23 +2204,19 @@ function backboneDetector(projectPath, packageJson) {
|
|
|
2234
2204
|
let confidence = 0;
|
|
2235
2205
|
let version;
|
|
2236
2206
|
const deps = collectAllDependencies(pkg);
|
|
2237
|
-
// Backbone package
|
|
2238
2207
|
if (deps['backbone']) {
|
|
2239
2208
|
confidence += 70;
|
|
2240
2209
|
version = parseVersionString(deps['backbone']);
|
|
2241
2210
|
sources.push({ type: 'package.json', field: 'dependencies.backbone' });
|
|
2242
|
-
// Underscore (commonly used with Backbone)
|
|
2243
2211
|
if (deps['underscore']) {
|
|
2244
2212
|
confidence += 15;
|
|
2245
2213
|
sources.push({ type: 'package.json', field: 'dependencies.underscore' });
|
|
2246
2214
|
}
|
|
2247
|
-
// Lodash can be used as underscore replacement
|
|
2248
2215
|
if (deps['lodash']) {
|
|
2249
2216
|
confidence += 5;
|
|
2250
2217
|
sources.push({ type: 'package.json', field: 'dependencies.lodash' });
|
|
2251
2218
|
}
|
|
2252
2219
|
}
|
|
2253
|
-
// Marionette (Backbone framework)
|
|
2254
2220
|
if (deps['backbone.marionette'] || deps['marionette']) {
|
|
2255
2221
|
confidence += 10;
|
|
2256
2222
|
sources.push({ type: 'package.json', field: 'dependencies.backbone.marionette' });
|
|
@@ -2281,18 +2247,15 @@ function emberDetector(projectPath, packageJson) {
|
|
|
2281
2247
|
let confidence = 0;
|
|
2282
2248
|
let version;
|
|
2283
2249
|
const deps = collectAllDependencies(pkg);
|
|
2284
|
-
// Ember source package
|
|
2285
2250
|
if (deps['ember-source']) {
|
|
2286
2251
|
confidence += 70;
|
|
2287
2252
|
version = parseVersionString(deps['ember-source']);
|
|
2288
2253
|
sources.push({ type: 'package.json', field: 'dependencies.ember-source' });
|
|
2289
2254
|
}
|
|
2290
|
-
// Ember CLI
|
|
2291
2255
|
if (deps['ember-cli']) {
|
|
2292
2256
|
confidence += 20;
|
|
2293
2257
|
sources.push({ type: 'package.json', field: 'devDependencies.ember-cli' });
|
|
2294
2258
|
}
|
|
2295
|
-
// Ember Data
|
|
2296
2259
|
if (deps['ember-data']) {
|
|
2297
2260
|
confidence += 10;
|
|
2298
2261
|
sources.push({ type: 'package.json', field: 'dependencies.ember-data' });
|
|
@@ -2323,18 +2286,15 @@ function jqueryDetector(projectPath, packageJson) {
|
|
|
2323
2286
|
let confidence = 0;
|
|
2324
2287
|
let version;
|
|
2325
2288
|
const deps = collectAllDependencies(pkg);
|
|
2326
|
-
// jQuery package
|
|
2327
2289
|
if (deps['jquery']) {
|
|
2328
2290
|
confidence += 80;
|
|
2329
2291
|
version = parseVersionString(deps['jquery']);
|
|
2330
2292
|
sources.push({ type: 'package.json', field: 'dependencies.jquery' });
|
|
2331
2293
|
}
|
|
2332
|
-
// jQuery UI
|
|
2333
2294
|
if (deps['jquery-ui']) {
|
|
2334
2295
|
confidence += 10;
|
|
2335
2296
|
sources.push({ type: 'package.json', field: 'dependencies.jquery-ui' });
|
|
2336
2297
|
}
|
|
2337
|
-
// jQuery plugins
|
|
2338
2298
|
if (deps['jquery-validation']) {
|
|
2339
2299
|
confidence += 5;
|
|
2340
2300
|
sources.push({ type: 'package.json', field: 'dependencies.jquery-validation' });
|
|
@@ -2463,7 +2423,6 @@ function prettierDetector(projectPath, packageJson) {
|
|
|
2463
2423
|
confidence += 30;
|
|
2464
2424
|
sources.push({ type: 'package.json', field: 'prettier' });
|
|
2465
2425
|
}
|
|
2466
|
-
// .prettierignore file
|
|
2467
2426
|
if (exists(node_path.join(projectPath, '.prettierignore'))) {
|
|
2468
2427
|
confidence += 10;
|
|
2469
2428
|
sources.push({ type: 'config-file', path: '.prettierignore' });
|
|
@@ -2558,7 +2517,6 @@ function biomeDetector(projectPath, packageJson) {
|
|
|
2558
2517
|
let configPath;
|
|
2559
2518
|
let version;
|
|
2560
2519
|
const deps = collectAllDependencies(pkg);
|
|
2561
|
-
// @biomejs/biome package
|
|
2562
2520
|
if (deps['@biomejs/biome']) {
|
|
2563
2521
|
confidence += 70;
|
|
2564
2522
|
version = parseVersionString(deps['@biomejs/biome']);
|
|
@@ -2827,7 +2785,7 @@ function npmWorkspacesDetector(workspacePath, packageJson) {
|
|
|
2827
2785
|
sources.push({ type: 'lockfile', path: 'package-lock.json' });
|
|
2828
2786
|
}
|
|
2829
2787
|
if (exists(node_path.join(workspacePath, 'yarn.lock'))) {
|
|
2830
|
-
return null;
|
|
2788
|
+
return null;
|
|
2831
2789
|
}
|
|
2832
2790
|
if (confidence === 0) {
|
|
2833
2791
|
return null;
|
|
@@ -3170,7 +3128,6 @@ function checkTsConfigStrict(projectPath) {
|
|
|
3170
3128
|
if (!content)
|
|
3171
3129
|
return undefined;
|
|
3172
3130
|
try {
|
|
3173
|
-
// Simple JSON parsing - doesn't handle comments but good enough for strict check
|
|
3174
3131
|
const cleanContent = content.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');
|
|
3175
3132
|
const parsed = parse(cleanContent);
|
|
3176
3133
|
return parsed?.compilerOptions?.strict === true;
|
|
@@ -3193,19 +3150,16 @@ function typescriptDetector(projectPath, packageJson) {
|
|
|
3193
3150
|
let configPath;
|
|
3194
3151
|
let version;
|
|
3195
3152
|
const deps = collectAllDependencies(pkg);
|
|
3196
|
-
// TypeScript package
|
|
3197
3153
|
if (deps['typescript']) {
|
|
3198
3154
|
confidence += 50;
|
|
3199
3155
|
version = parseVersionString(deps['typescript']);
|
|
3200
3156
|
sources.push({ type: 'package.json', field: 'dependencies.typescript' });
|
|
3201
3157
|
}
|
|
3202
|
-
// tsconfig.json
|
|
3203
3158
|
if (exists(node_path.join(projectPath, 'tsconfig.json'))) {
|
|
3204
3159
|
confidence += 40;
|
|
3205
3160
|
configPath = 'tsconfig.json';
|
|
3206
3161
|
sources.push({ type: 'config-file', path: 'tsconfig.json' });
|
|
3207
3162
|
}
|
|
3208
|
-
// tsconfig.*.json variants
|
|
3209
3163
|
const tsconfigVariants = ['tsconfig.build.json', 'tsconfig.lib.json', 'tsconfig.spec.json', 'tsconfig.app.json'];
|
|
3210
3164
|
for (const variant of tsconfigVariants) {
|
|
3211
3165
|
if (exists(node_path.join(projectPath, variant))) {
|
|
@@ -3214,7 +3168,6 @@ function typescriptDetector(projectPath, packageJson) {
|
|
|
3214
3168
|
break;
|
|
3215
3169
|
}
|
|
3216
3170
|
}
|
|
3217
|
-
// @types packages
|
|
3218
3171
|
const typePackages = keys(deps).filter((d) => d.startsWith('@types/'));
|
|
3219
3172
|
if (typePackages.length > 0) {
|
|
3220
3173
|
confidence += 10;
|
|
@@ -3248,24 +3201,20 @@ function flowDetector(projectPath, packageJson) {
|
|
|
3248
3201
|
let configPath;
|
|
3249
3202
|
let version;
|
|
3250
3203
|
const deps = collectAllDependencies(pkg);
|
|
3251
|
-
// flow-bin package
|
|
3252
3204
|
if (deps['flow-bin']) {
|
|
3253
3205
|
confidence += 60;
|
|
3254
3206
|
version = parseVersionString(deps['flow-bin']);
|
|
3255
3207
|
sources.push({ type: 'package.json', field: 'dependencies.flow-bin' });
|
|
3256
3208
|
}
|
|
3257
|
-
// .flowconfig
|
|
3258
3209
|
if (exists(node_path.join(projectPath, '.flowconfig'))) {
|
|
3259
3210
|
confidence += 40;
|
|
3260
3211
|
configPath = '.flowconfig';
|
|
3261
3212
|
sources.push({ type: 'config-file', path: '.flowconfig' });
|
|
3262
3213
|
}
|
|
3263
|
-
// flow-typed directory
|
|
3264
3214
|
if (exists(node_path.join(projectPath, 'flow-typed'))) {
|
|
3265
3215
|
confidence += 10;
|
|
3266
3216
|
sources.push({ type: 'directory', path: 'flow-typed/' });
|
|
3267
3217
|
}
|
|
3268
|
-
// @babel/preset-flow
|
|
3269
3218
|
if (deps['@babel/preset-flow']) {
|
|
3270
3219
|
confidence += 10;
|
|
3271
3220
|
sources.push({ type: 'package.json', field: 'dependencies.@babel/preset-flow' });
|
|
@@ -3289,7 +3238,6 @@ function flowDetector(projectPath, packageJson) {
|
|
|
3289
3238
|
* @returns `true` if the content contains JSDoc type annotations.
|
|
3290
3239
|
*/
|
|
3291
3240
|
function hasJsDocTypes(content) {
|
|
3292
|
-
// Check for JSDoc type annotations
|
|
3293
3241
|
return (content.includes('@type {') ||
|
|
3294
3242
|
content.includes('@param {') ||
|
|
3295
3243
|
content.includes('@returns {') ||
|
|
@@ -3308,14 +3256,11 @@ function jsdocDetector(projectPath, packageJson) {
|
|
|
3308
3256
|
const sources = [];
|
|
3309
3257
|
let confidence = 0;
|
|
3310
3258
|
const deps = collectAllDependencies(pkg);
|
|
3311
|
-
// jsdoc package
|
|
3312
3259
|
if (deps['jsdoc']) {
|
|
3313
3260
|
confidence += 30;
|
|
3314
3261
|
sources.push({ type: 'package.json', field: 'dependencies.jsdoc' });
|
|
3315
3262
|
}
|
|
3316
|
-
// typescript with checkJs (JSDoc type checking)
|
|
3317
3263
|
if (deps['typescript']) {
|
|
3318
|
-
// Check if checkJs is enabled in tsconfig
|
|
3319
3264
|
const tsconfigPath = node_path.join(projectPath, 'tsconfig.json');
|
|
3320
3265
|
const content = readFileIfExists(tsconfigPath);
|
|
3321
3266
|
if (content) {
|
|
@@ -3332,12 +3277,10 @@ function jsdocDetector(projectPath, packageJson) {
|
|
|
3332
3277
|
}
|
|
3333
3278
|
}
|
|
3334
3279
|
}
|
|
3335
|
-
// Check for jsconfig.json (VS Code JS type checking)
|
|
3336
3280
|
if (exists(node_path.join(projectPath, 'jsconfig.json'))) {
|
|
3337
3281
|
confidence += 40;
|
|
3338
3282
|
sources.push({ type: 'config-file', path: 'jsconfig.json' });
|
|
3339
3283
|
}
|
|
3340
|
-
// Sample check for JSDoc annotations in source files
|
|
3341
3284
|
const srcDir = node_path.join(projectPath, 'src');
|
|
3342
3285
|
if (exists(srcDir)) {
|
|
3343
3286
|
try {
|
|
@@ -3388,8 +3331,6 @@ const detectAllCache = createCache({ ttl: 60000, maxSize: 50 });
|
|
|
3388
3331
|
function isDetectAllOptions(value) {
|
|
3389
3332
|
if (typeof value !== 'object' || value === null)
|
|
3390
3333
|
return false;
|
|
3391
|
-
// DetectAllOptions has skipCache or packageJson fields specifically
|
|
3392
|
-
// PackageJson never has skipCache field
|
|
3393
3334
|
return 'skipCache' in value || 'packageJson' in value;
|
|
3394
3335
|
}
|
|
3395
3336
|
/**
|
|
@@ -3421,9 +3362,7 @@ function isDetectAllOptions(value) {
|
|
|
3421
3362
|
* ```
|
|
3422
3363
|
*/
|
|
3423
3364
|
function detectAll(projectPath, packageJsonOrOptions) {
|
|
3424
|
-
// Handle backward-compatible arguments
|
|
3425
3365
|
const options = isDetectAllOptions(packageJsonOrOptions) ? packageJsonOrOptions : { packageJson: packageJsonOrOptions };
|
|
3426
|
-
// Check cache first (unless skipCache is true)
|
|
3427
3366
|
if (!options.skipCache) {
|
|
3428
3367
|
const cached = detectAllCache.get(projectPath);
|
|
3429
3368
|
if (cached) {
|
|
@@ -3474,7 +3413,6 @@ function detectAll(projectPath, packageJsonOrOptions) {
|
|
|
3474
3413
|
legacyFrameworks: result.legacyFrameworks.map((f) => f.id),
|
|
3475
3414
|
testingFrameworks: result.testingFrameworks.map((f) => f.id),
|
|
3476
3415
|
});
|
|
3477
|
-
// Cache the result
|
|
3478
3416
|
detectAllCache.set(projectPath, result);
|
|
3479
3417
|
return result;
|
|
3480
3418
|
}
|
|
@@ -3844,10 +3782,6 @@ function usesFramework(projectPath, frameworkId, minConfidence = 50) {
|
|
|
3844
3782
|
return allFrameworks.some((f) => f.id === frameworkId && f.confidence >= minConfidence);
|
|
3845
3783
|
}
|
|
3846
3784
|
|
|
3847
|
-
/**
|
|
3848
|
-
* Pattern matching utilities with ReDoS protection.
|
|
3849
|
-
* Uses character-by-character matching instead of regex where possible.
|
|
3850
|
-
*/
|
|
3851
3785
|
/**
|
|
3852
3786
|
* Match path against glob pattern using safe character iteration.
|
|
3853
3787
|
* Avoids regex to prevent ReDoS attacks.
|
|
@@ -3885,17 +3819,14 @@ function matchGlobPattern(path, pattern) {
|
|
|
3885
3819
|
* @returns True if remaining segments match
|
|
3886
3820
|
*/
|
|
3887
3821
|
function matchSegments(pathParts, patternParts, pathIdx, patternIdx) {
|
|
3888
|
-
// Base cases
|
|
3889
3822
|
if (pathIdx === pathParts.length && patternIdx === patternParts.length) {
|
|
3890
|
-
return true;
|
|
3823
|
+
return true;
|
|
3891
3824
|
}
|
|
3892
3825
|
if (patternIdx >= patternParts.length) {
|
|
3893
|
-
return false;
|
|
3826
|
+
return false;
|
|
3894
3827
|
}
|
|
3895
3828
|
const patternPart = patternParts[patternIdx];
|
|
3896
|
-
// Handle ** (globstar) - matches zero or more directories
|
|
3897
3829
|
if (patternPart === '**') {
|
|
3898
|
-
// Try matching rest of pattern against current position and all future positions
|
|
3899
3830
|
for (let i = pathIdx; i <= pathParts.length; i++) {
|
|
3900
3831
|
if (matchSegments(pathParts, patternParts, i, patternIdx + 1)) {
|
|
3901
3832
|
return true;
|
|
@@ -3904,10 +3835,9 @@ function matchSegments(pathParts, patternParts, pathIdx, patternIdx) {
|
|
|
3904
3835
|
return false;
|
|
3905
3836
|
}
|
|
3906
3837
|
if (pathIdx >= pathParts.length) {
|
|
3907
|
-
return false;
|
|
3838
|
+
return false;
|
|
3908
3839
|
}
|
|
3909
3840
|
const pathPart = pathParts[pathIdx];
|
|
3910
|
-
// Match current segment
|
|
3911
3841
|
if (matchSegment(pathPart, patternPart)) {
|
|
3912
3842
|
return matchSegments(pathParts, patternParts, pathIdx + 1, patternIdx + 1);
|
|
3913
3843
|
}
|
|
@@ -3927,12 +3857,10 @@ function matchSegment(text, pattern) {
|
|
|
3927
3857
|
while (patternIdx < pattern.length) {
|
|
3928
3858
|
const char = pattern[patternIdx];
|
|
3929
3859
|
if (char === '*') {
|
|
3930
|
-
// * matches zero or more characters
|
|
3931
3860
|
patternIdx++;
|
|
3932
3861
|
if (patternIdx === pattern.length) {
|
|
3933
|
-
return true;
|
|
3862
|
+
return true;
|
|
3934
3863
|
}
|
|
3935
|
-
// Try matching rest of pattern at each position in text
|
|
3936
3864
|
for (let i = textIdx; i <= text.length; i++) {
|
|
3937
3865
|
if (matchSegmentFrom(text, i, pattern, patternIdx)) {
|
|
3938
3866
|
return true;
|
|
@@ -3941,7 +3869,6 @@ function matchSegment(text, pattern) {
|
|
|
3941
3869
|
return false;
|
|
3942
3870
|
}
|
|
3943
3871
|
else if (char === '?') {
|
|
3944
|
-
// ? matches exactly one character
|
|
3945
3872
|
if (textIdx >= text.length) {
|
|
3946
3873
|
return false;
|
|
3947
3874
|
}
|
|
@@ -3949,10 +3876,8 @@ function matchSegment(text, pattern) {
|
|
|
3949
3876
|
patternIdx++;
|
|
3950
3877
|
}
|
|
3951
3878
|
else if (char === '{') {
|
|
3952
|
-
// {a,b,c} matches any alternative
|
|
3953
3879
|
const closeIdx = findClosingBrace(pattern, patternIdx);
|
|
3954
3880
|
if (closeIdx === -1) {
|
|
3955
|
-
// Unmatched brace, treat as literal
|
|
3956
3881
|
if (textIdx >= text.length || text[textIdx] !== char) {
|
|
3957
3882
|
return false;
|
|
3958
3883
|
}
|
|
@@ -3970,7 +3895,6 @@ function matchSegment(text, pattern) {
|
|
|
3970
3895
|
}
|
|
3971
3896
|
}
|
|
3972
3897
|
else {
|
|
3973
|
-
// Literal character
|
|
3974
3898
|
if (textIdx >= text.length || text[textIdx] !== char) {
|
|
3975
3899
|
return false;
|
|
3976
3900
|
}
|
|
@@ -4256,7 +4180,8 @@ const entryPointLogger = createScopedLogger('project-scope:heuristics:entry-poin
|
|
|
4256
4180
|
*/
|
|
4257
4181
|
const entryPointCache = createCache({ ttl: 60000, maxSize: 50 });
|
|
4258
4182
|
/**
|
|
4259
|
-
* Common entry point patterns.
|
|
4183
|
+
* Common entry point patterns by project type.
|
|
4184
|
+
* Used for convention-based entry point discovery.
|
|
4260
4185
|
*/
|
|
4261
4186
|
const ENTRY_POINT_PATTERNS = {
|
|
4262
4187
|
/** Library entry patterns */
|
|
@@ -4522,29 +4447,23 @@ const depsLogger = createScopedLogger('project-scope:heuristics:deps');
|
|
|
4522
4447
|
*/
|
|
4523
4448
|
function extractImports(content) {
|
|
4524
4449
|
const imports = [];
|
|
4525
|
-
// ES import with 'from': import X from 'path' or import { X } from 'path'
|
|
4526
|
-
// Use non-greedy match and avoid nested quantifiers by matching "from" keyword directly
|
|
4527
4450
|
const esImportFromRegex = /import\s+.+?\s+from\s+['"]([^'"]+)['"]/g;
|
|
4528
4451
|
let match;
|
|
4529
4452
|
while ((match = esImportFromRegex.exec(content)) !== null) {
|
|
4530
4453
|
imports.push(match[1]);
|
|
4531
4454
|
}
|
|
4532
|
-
// Side-effect import: import 'path'
|
|
4533
4455
|
const sideEffectImportRegex = /import\s+['"]([^'"]+)['"]/g;
|
|
4534
4456
|
while ((match = sideEffectImportRegex.exec(content)) !== null) {
|
|
4535
4457
|
imports.push(match[1]);
|
|
4536
4458
|
}
|
|
4537
|
-
// Dynamic import: import('path')
|
|
4538
4459
|
const dynamicImportRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
4539
4460
|
while ((match = dynamicImportRegex.exec(content)) !== null) {
|
|
4540
4461
|
imports.push(match[1]);
|
|
4541
4462
|
}
|
|
4542
|
-
// require: require('path')
|
|
4543
4463
|
const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
4544
4464
|
while ((match = requireRegex.exec(content)) !== null) {
|
|
4545
4465
|
imports.push(match[1]);
|
|
4546
4466
|
}
|
|
4547
|
-
// Re-export: export * from 'path' or export { X } from 'path'
|
|
4548
4467
|
const exportFromRegex = /export\s+.+?\s+from\s+['"]([^'"]+)['"]/g;
|
|
4549
4468
|
while ((match = exportFromRegex.exec(content)) !== null) {
|
|
4550
4469
|
imports.push(match[1]);
|