sigmap 6.9.0 → 6.10.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.
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ module.exports = { detectWorkspaces, inferPackage, scopeToPackage };
5
+
6
+ function detectWorkspaces(cwd) {
7
+ const pkgPath = path.join(cwd, 'package.json');
8
+ if (!fs.existsSync(pkgPath)) return [];
9
+
10
+ let pkg;
11
+ try {
12
+ pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
13
+ } catch {
14
+ return [];
15
+ }
16
+
17
+ const patterns = pkg.workspaces || [];
18
+ const dirs = [];
19
+
20
+ // Handle both flat array and object with packages field (Yarn v2 format)
21
+ const patternArray = Array.isArray(patterns) ? patterns : (patterns.packages || []);
22
+
23
+ for (const p of patternArray) {
24
+ const base = p.replace(/\/\*\*?$/, '');
25
+ const resolved = path.join(cwd, base);
26
+ if (fs.existsSync(resolved)) {
27
+ try {
28
+ for (const entry of fs.readdirSync(resolved, { withFileTypes: true })) {
29
+ if (entry.isDirectory()) dirs.push(path.join(resolved, entry.name));
30
+ }
31
+ } catch (_) {}
32
+ }
33
+ }
34
+
35
+ return dirs;
36
+ }
37
+
38
+ // Infer package from query tokens: "add rate limiting to payments" → "packages/payments"
39
+ function inferPackage(query, workspaceDirs, cwd) {
40
+ const tokens = query.toLowerCase().split(/\W+/).filter(t => t.length > 2);
41
+
42
+ // Find longest matching package name
43
+ let bestMatch = null;
44
+ let bestLen = 0;
45
+ let bestMatchLen = 0;
46
+
47
+ for (const dir of workspaceDirs) {
48
+ const name = path.basename(dir).toLowerCase();
49
+ for (const token of tokens) {
50
+ const matchLen = _getMatchLength(name, token);
51
+ // Only consider matches; use longest match, and break ties by longest package name
52
+ if (matchLen > 0 && (matchLen > bestLen || (matchLen === bestLen && name.length > bestMatchLen))) {
53
+ bestMatch = dir;
54
+ bestLen = matchLen;
55
+ bestMatchLen = name.length;
56
+ }
57
+ }
58
+ }
59
+
60
+ return bestMatch;
61
+ }
62
+
63
+ function _getMatchLength(name, token) {
64
+ if (name === token) return 1000 + name.length; // Exact match is best
65
+ if (name.startsWith(token) && token.length >= 3) return 100 + token.length;
66
+ if (token.startsWith(name) && name.length >= 3) return name.length;
67
+ return 0;
68
+ }
69
+
70
+ // Return boost multiplier for files inside the inferred package
71
+ function scopeToPackage(filePath, packageDir) {
72
+ const normalized = filePath.replace(/\\/g, '/');
73
+ const normalizedPkg = packageDir.replace(/\\/g, '/');
74
+
75
+ // Ensure we match the directory boundary, not just a prefix
76
+ // e.g., packages/payment should not match packages/payment-old
77
+ if (normalized.startsWith(normalizedPkg)) {
78
+ const afterPrefix = normalized.slice(normalizedPkg.length);
79
+ // Check if next char is / or if it's the exact match
80
+ if (afterPrefix === '' || afterPrefix[0] === '/') {
81
+ return 0.30;
82
+ }
83
+ }
84
+ return 0;
85
+ }