dsh-gitnexus-plus 0.0.0-stage → 0.1.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/LICENSE +38 -0
- package/README.md +483 -2
- package/cordis.patch.yml +18 -0
- package/lib/bin/gitnexus-coverage.d.ts +14 -0
- package/lib/bin/gitnexus-coverage.d.ts.map +1 -0
- package/lib/bin/gitnexus-coverage.js +171 -0
- package/lib/bin/gitnexus-coverage.js.map +1 -0
- package/lib/client.js +1642 -0
- package/lib/gitnexus/analyze.d.ts +148 -0
- package/lib/gitnexus/analyze.d.ts.map +1 -0
- package/lib/gitnexus/analyze.js +283 -0
- package/lib/gitnexus/analyze.js.map +1 -0
- package/lib/gitnexus/commands.d.ts +96 -0
- package/lib/gitnexus/commands.d.ts.map +1 -0
- package/lib/gitnexus/commands.js +132 -0
- package/lib/gitnexus/commands.js.map +1 -0
- package/lib/gitnexus/coverage.d.ts +340 -0
- package/lib/gitnexus/coverage.d.ts.map +1 -0
- package/lib/gitnexus/coverage.js +552 -0
- package/lib/gitnexus/coverage.js.map +1 -0
- package/lib/gitnexus/format.d.ts +16 -0
- package/lib/gitnexus/format.d.ts.map +1 -0
- package/lib/gitnexus/format.js +178 -0
- package/lib/gitnexus/format.js.map +1 -0
- package/lib/gitnexus/git-activity.d.ts +136 -0
- package/lib/gitnexus/git-activity.d.ts.map +1 -0
- package/lib/gitnexus/git-activity.js +345 -0
- package/lib/gitnexus/git-activity.js.map +1 -0
- package/lib/gitnexus/git.d.ts +70 -0
- package/lib/gitnexus/git.d.ts.map +1 -0
- package/lib/gitnexus/git.js +121 -0
- package/lib/gitnexus/git.js.map +1 -0
- package/lib/gitnexus/index-meta.d.ts +150 -0
- package/lib/gitnexus/index-meta.d.ts.map +1 -0
- package/lib/gitnexus/index-meta.js +156 -0
- package/lib/gitnexus/index-meta.js.map +1 -0
- package/lib/gitnexus/install.d.ts +97 -0
- package/lib/gitnexus/install.d.ts.map +1 -0
- package/lib/gitnexus/install.js +228 -0
- package/lib/gitnexus/install.js.map +1 -0
- package/lib/gitnexus/languages.d.ts +73 -0
- package/lib/gitnexus/languages.d.ts.map +1 -0
- package/lib/gitnexus/languages.js +217 -0
- package/lib/gitnexus/languages.js.map +1 -0
- package/lib/gitnexus/root.d.ts +68 -0
- package/lib/gitnexus/root.d.ts.map +1 -0
- package/lib/gitnexus/root.js +162 -0
- package/lib/gitnexus/root.js.map +1 -0
- package/lib/gitnexus/scan.d.ts +67 -0
- package/lib/gitnexus/scan.d.ts.map +1 -0
- package/lib/gitnexus/scan.js +247 -0
- package/lib/gitnexus/scan.js.map +1 -0
- package/lib/gitnexus/toolchain.d.ts +136 -0
- package/lib/gitnexus/toolchain.d.ts.map +1 -0
- package/lib/gitnexus/toolchain.js +251 -0
- package/lib/gitnexus/toolchain.js.map +1 -0
- package/lib/index.d.ts +79 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +211 -0
- package/lib/index.js.map +1 -0
- package/lib/routes/analyze.d.ts +35 -0
- package/lib/routes/analyze.d.ts.map +1 -0
- package/lib/routes/analyze.js +71 -0
- package/lib/routes/analyze.js.map +1 -0
- package/lib/routes/coverage.d.ts +44 -0
- package/lib/routes/coverage.d.ts.map +1 -0
- package/lib/routes/coverage.js +68 -0
- package/lib/routes/coverage.js.map +1 -0
- package/lib/routes/guard.d.ts +92 -0
- package/lib/routes/guard.d.ts.map +1 -0
- package/lib/routes/guard.js +187 -0
- package/lib/routes/guard.js.map +1 -0
- package/lib/routes/install.d.ts +27 -0
- package/lib/routes/install.d.ts.map +1 -0
- package/lib/routes/install.js +46 -0
- package/lib/routes/install.js.map +1 -0
- package/package.json +87 -4
- package/scripts/link-runtime.mjs +146 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language classification for a file path, reusing GitNexus's own detector.
|
|
3
|
+
*
|
|
4
|
+
* `gitnexus-shared` is not published separately, but `analyze` bundles it into
|
|
5
|
+
* `gitnexus/dist/_shared/`. Importing that copy is deliberate: the detector that
|
|
6
|
+
* classified the files *in an existing index* is the one that must classify them
|
|
7
|
+
* in the report. Copying the map from source would be wrong — the installed
|
|
8
|
+
* 1.6.12 differs from the checkout (e.g. `.ipynb` resolves to `null` there, not
|
|
9
|
+
* to `python`), and such gaps are invisible until a percentage looks odd.
|
|
10
|
+
*
|
|
11
|
+
* Three classes, because "is this file in the graph as code?" has three answers:
|
|
12
|
+
*
|
|
13
|
+
* parsed — GitNexus has a LanguageProvider; symbols inside become graph nodes.
|
|
14
|
+
* recognized — known format, no parser; the file exists as a `File` node only.
|
|
15
|
+
* other — not recognised at all.
|
|
16
|
+
*
|
|
17
|
+
* This is the distinction GitHub's language bar cannot express, and it is what
|
|
18
|
+
* makes the widget answer "how much of my repository does GitNexus actually
|
|
19
|
+
* understand?" rather than merely "what is this repo written in?".
|
|
20
|
+
*/
|
|
21
|
+
import type { ScannedFile } from './scan.js';
|
|
22
|
+
/** Which of the three classes a path falls into. */
|
|
23
|
+
export type LanguageClass = 'parsed' | 'recognized' | 'other';
|
|
24
|
+
/**
|
|
25
|
+
* GitNexus's language detector, as this plugin uses it: the handle passed around
|
|
26
|
+
* by {@link classifyFile} and {@link aggregateLanguages}.
|
|
27
|
+
*/
|
|
28
|
+
export interface LanguageDetector {
|
|
29
|
+
getLanguageFromFilename: (filePath: string) => string | null;
|
|
30
|
+
getSyntaxLanguageFromFilename: (filePath: string) => string;
|
|
31
|
+
}
|
|
32
|
+
/** What {@link classifyFile} decides about one path. */
|
|
33
|
+
export interface ClassifiedLanguage {
|
|
34
|
+
key: string;
|
|
35
|
+
label: string;
|
|
36
|
+
color: string;
|
|
37
|
+
klass: LanguageClass;
|
|
38
|
+
}
|
|
39
|
+
/** One row of the language breakdown: a {@link ClassifiedLanguage} with totals. */
|
|
40
|
+
export interface LanguageRow extends ClassifiedLanguage {
|
|
41
|
+
bytes: number;
|
|
42
|
+
files: number;
|
|
43
|
+
}
|
|
44
|
+
/** The language breakdown itself, as returned by {@link aggregateLanguages}. */
|
|
45
|
+
export interface LanguageAggregate {
|
|
46
|
+
rows: LanguageRow[];
|
|
47
|
+
totalFiles: number;
|
|
48
|
+
totalBytes: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load GitNexus's bundled detector once per process.
|
|
52
|
+
* Returns `null` when the bundled copy is unavailable, in which case every file
|
|
53
|
+
* is classified `other` — a degraded but honest answer, never a fabricated one.
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadLanguageDetector(options?: {
|
|
56
|
+
env?: NodeJS.ProcessEnv;
|
|
57
|
+
}): Promise<LanguageDetector | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Classify one repo-relative path.
|
|
60
|
+
*
|
|
61
|
+
* @param filePath repo-relative, forward slashes
|
|
62
|
+
*/
|
|
63
|
+
export declare function classifyFile(filePath: string, det: LanguageDetector | null): ClassifiedLanguage;
|
|
64
|
+
/**
|
|
65
|
+
* Aggregate files into a language breakdown.
|
|
66
|
+
*
|
|
67
|
+
* `klass` rank decides ordering ties so the three visual bands stay contiguous
|
|
68
|
+
* and the bar does not interleave "understood" and "not understood" segments.
|
|
69
|
+
*
|
|
70
|
+
* @param include extra filter, e.g. "is indexed"
|
|
71
|
+
*/
|
|
72
|
+
export declare function aggregateLanguages(files: ScannedFile[], det: LanguageDetector | null, include?: (filePath: string) => boolean): LanguageAggregate;
|
|
73
|
+
//# sourceMappingURL=languages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../../src/gitnexus/languages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,oDAAoD;AACpD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;AAiG9D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC7D,6BAA6B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7D;AAED,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,GACxC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAqBlC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,GAAG,kBAAkB,CA6C/F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAAE,EACpB,GAAG,EAAE,gBAAgB,GAAG,IAAI,EAC5B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GACtC,iBAAiB,CA4BnB"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language classification for a file path, reusing GitNexus's own detector.
|
|
3
|
+
*
|
|
4
|
+
* `gitnexus-shared` is not published separately, but `analyze` bundles it into
|
|
5
|
+
* `gitnexus/dist/_shared/`. Importing that copy is deliberate: the detector that
|
|
6
|
+
* classified the files *in an existing index* is the one that must classify them
|
|
7
|
+
* in the report. Copying the map from source would be wrong — the installed
|
|
8
|
+
* 1.6.12 differs from the checkout (e.g. `.ipynb` resolves to `null` there, not
|
|
9
|
+
* to `python`), and such gaps are invisible until a percentage looks odd.
|
|
10
|
+
*
|
|
11
|
+
* Three classes, because "is this file in the graph as code?" has three answers:
|
|
12
|
+
*
|
|
13
|
+
* parsed — GitNexus has a LanguageProvider; symbols inside become graph nodes.
|
|
14
|
+
* recognized — known format, no parser; the file exists as a `File` node only.
|
|
15
|
+
* other — not recognised at all.
|
|
16
|
+
*
|
|
17
|
+
* This is the distinction GitHub's language bar cannot express, and it is what
|
|
18
|
+
* makes the widget answer "how much of my repository does GitNexus actually
|
|
19
|
+
* understand?" rather than merely "what is this repo written in?".
|
|
20
|
+
*/
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { pathToFileURL } from 'node:url';
|
|
23
|
+
import { findGitnexusRoot } from './root.js';
|
|
24
|
+
/**
|
|
25
|
+
* Display names and stable colours. Colours follow GitHub linguist's palette for
|
|
26
|
+
* the languages it defines, so the bar reads the same as a repository page; the
|
|
27
|
+
* remainder are assigned from a fixed table rather than a hash so a colour never
|
|
28
|
+
* moves between renders.
|
|
29
|
+
*/
|
|
30
|
+
const DISPLAY = Object.freeze({
|
|
31
|
+
javascript: ['JavaScript', '#f1e05a'],
|
|
32
|
+
typescript: ['TypeScript', '#3178c6'],
|
|
33
|
+
python: ['Python', '#3572A5'],
|
|
34
|
+
java: ['Java', '#b07219'],
|
|
35
|
+
c: ['C', '#555555'],
|
|
36
|
+
cpp: ['C++', '#f34b7d'],
|
|
37
|
+
'objective-c': ['Objective-C', '#438eff'],
|
|
38
|
+
csharp: ['C#', '#178600'],
|
|
39
|
+
go: ['Go', '#00ADD8'],
|
|
40
|
+
ruby: ['Ruby', '#701516'],
|
|
41
|
+
rust: ['Rust', '#dea584'],
|
|
42
|
+
php: ['PHP', '#4F5D95'],
|
|
43
|
+
kotlin: ['Kotlin', '#A97BFF'],
|
|
44
|
+
swift: ['Swift', '#F05138'],
|
|
45
|
+
dart: ['Dart', '#00B4AB'],
|
|
46
|
+
vue: ['Vue', '#41b883'],
|
|
47
|
+
cobol: ['COBOL', '#6b6b6b'],
|
|
48
|
+
zig: ['Zig', '#ec915c'],
|
|
49
|
+
// Recognised formats: neutral colours, intentionally outside the code palette.
|
|
50
|
+
markdown: ['Markdown', '#8b949e'],
|
|
51
|
+
json: ['JSON', '#a8a8a8'],
|
|
52
|
+
yaml: ['YAML', '#7d9199'],
|
|
53
|
+
markup: ['HTML', '#e34c26'],
|
|
54
|
+
css: ['CSS', '#563d7c'],
|
|
55
|
+
bash: ['Shell', '#89e051'],
|
|
56
|
+
sql: ['SQL', '#9c9c9c'],
|
|
57
|
+
toml: ['TOML', '#9c4221'],
|
|
58
|
+
ini: ['INI', '#8a8a8a'],
|
|
59
|
+
docker: ['Dockerfile', '#384d54'],
|
|
60
|
+
makefile: ['Makefile', '#427819'],
|
|
61
|
+
// GitNexus's detector does not know these. They are added here so the bar reads
|
|
62
|
+
// like a repository page instead of dumping them into "other" — measured on the
|
|
63
|
+
// GitNexus repository itself, where 6 `.jinja` and 3 `.ps1` files were the only
|
|
64
|
+
// thing separating this breakdown from GitHub's.
|
|
65
|
+
jinja: ['Jinja', '#a52a22'],
|
|
66
|
+
powershell: ['PowerShell', '#012456'],
|
|
67
|
+
batch: ['Batchfile', '#C1F12E'],
|
|
68
|
+
diff: ['Diff', '#8b949e'],
|
|
69
|
+
plaintext: ['Text', '#6e7681'],
|
|
70
|
+
text: ['其他', '#484f58'],
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* Extensions GitNexus's detector has no entry for, mapped to the display keys
|
|
74
|
+
* above. Consulted only after that detector has declined the file, so it can
|
|
75
|
+
* never override a language GitNexus genuinely parses.
|
|
76
|
+
*/
|
|
77
|
+
const SUPPLEMENTARY_EXTENSIONS = Object.freeze({
|
|
78
|
+
'.jinja': 'jinja',
|
|
79
|
+
'.jinja2': 'jinja',
|
|
80
|
+
'.j2': 'jinja',
|
|
81
|
+
'.njk': 'jinja',
|
|
82
|
+
'.ps1': 'powershell',
|
|
83
|
+
'.psm1': 'powershell',
|
|
84
|
+
'.psd1': 'powershell',
|
|
85
|
+
'.ps1xml': 'powershell',
|
|
86
|
+
'.bat': 'batch',
|
|
87
|
+
'.cmd': 'batch',
|
|
88
|
+
'.patch': 'diff',
|
|
89
|
+
'.diff': 'diff',
|
|
90
|
+
'.txt': 'plaintext',
|
|
91
|
+
'.log': 'plaintext',
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* Cases no extension map can decide, resolved by filename.
|
|
95
|
+
* Kept explicit so an unlisted name falls to `other` rather than a guess.
|
|
96
|
+
*/
|
|
97
|
+
const BASENAME_LANGUAGES = Object.freeze({
|
|
98
|
+
dockerfile: 'docker',
|
|
99
|
+
makefile: 'makefile',
|
|
100
|
+
'cmakelists.txt': 'text',
|
|
101
|
+
'.gitignore': 'text',
|
|
102
|
+
'.gitattributes': 'text',
|
|
103
|
+
'.editorconfig': 'text',
|
|
104
|
+
'.npmrc': 'text',
|
|
105
|
+
'.nvmrc': 'text',
|
|
106
|
+
});
|
|
107
|
+
let detector = null;
|
|
108
|
+
/**
|
|
109
|
+
* Load GitNexus's bundled detector once per process.
|
|
110
|
+
* Returns `null` when the bundled copy is unavailable, in which case every file
|
|
111
|
+
* is classified `other` — a degraded but honest answer, never a fabricated one.
|
|
112
|
+
*/
|
|
113
|
+
export async function loadLanguageDetector(options = {}) {
|
|
114
|
+
if (detector !== null)
|
|
115
|
+
return detector;
|
|
116
|
+
const root = findGitnexusRoot(options);
|
|
117
|
+
if (root === null)
|
|
118
|
+
return null;
|
|
119
|
+
try {
|
|
120
|
+
const mod = (await import(pathToFileURL(path.join(root, 'dist', '_shared', 'language-detection.js')).href));
|
|
121
|
+
if (typeof mod.getLanguageFromFilename === 'function') {
|
|
122
|
+
detector = {
|
|
123
|
+
getLanguageFromFilename: mod.getLanguageFromFilename,
|
|
124
|
+
getSyntaxLanguageFromFilename: typeof mod.getSyntaxLanguageFromFilename === 'function'
|
|
125
|
+
? mod.getSyntaxLanguageFromFilename
|
|
126
|
+
: () => 'text',
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* fall through to the degraded path */
|
|
132
|
+
}
|
|
133
|
+
return detector;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Classify one repo-relative path.
|
|
137
|
+
*
|
|
138
|
+
* @param filePath repo-relative, forward slashes
|
|
139
|
+
*/
|
|
140
|
+
export function classifyFile(filePath, det) {
|
|
141
|
+
let key = null;
|
|
142
|
+
let klass = 'other';
|
|
143
|
+
if (det !== null) {
|
|
144
|
+
const parsed = det.getLanguageFromFilename(filePath);
|
|
145
|
+
if (parsed) {
|
|
146
|
+
key = parsed;
|
|
147
|
+
klass = 'parsed';
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const syntax = det.getSyntaxLanguageFromFilename(filePath);
|
|
151
|
+
if (syntax && syntax !== 'text') {
|
|
152
|
+
key = syntax;
|
|
153
|
+
klass = 'recognized';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (key === null) {
|
|
158
|
+
const lastDot = filePath.lastIndexOf('.');
|
|
159
|
+
if (lastDot >= 0) {
|
|
160
|
+
const ext = filePath.slice(lastDot).toLowerCase();
|
|
161
|
+
const supplement = SUPPLEMENTARY_EXTENSIONS[ext];
|
|
162
|
+
if (supplement !== undefined)
|
|
163
|
+
key = supplement;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (key === null) {
|
|
167
|
+
const base = filePath.split('/').pop()?.toLowerCase() ?? '';
|
|
168
|
+
const byName = BASENAME_LANGUAGES[base];
|
|
169
|
+
if (byName !== undefined) {
|
|
170
|
+
key = byName;
|
|
171
|
+
klass = byName === 'text' ? 'other' : 'recognized';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const entry = key !== null ? DISPLAY[key] : undefined;
|
|
175
|
+
// `key === null` already implies `entry === undefined`; stating both is what lets
|
|
176
|
+
// the checker narrow `key` to a string for the return below.
|
|
177
|
+
if (entry === undefined || key === null) {
|
|
178
|
+
return { key: 'text', label: '其他', color: DISPLAY.text[1], klass: 'other' };
|
|
179
|
+
}
|
|
180
|
+
// A supplementary hit is a known format GitNexus cannot parse — never `parsed`.
|
|
181
|
+
if (klass === 'other' && key !== 'text')
|
|
182
|
+
klass = 'recognized';
|
|
183
|
+
return { key, label: entry[0], color: entry[1], klass };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Aggregate files into a language breakdown.
|
|
187
|
+
*
|
|
188
|
+
* `klass` rank decides ordering ties so the three visual bands stay contiguous
|
|
189
|
+
* and the bar does not interleave "understood" and "not understood" segments.
|
|
190
|
+
*
|
|
191
|
+
* @param include extra filter, e.g. "is indexed"
|
|
192
|
+
*/
|
|
193
|
+
export function aggregateLanguages(files, det, include) {
|
|
194
|
+
const map = new Map();
|
|
195
|
+
let totalFiles = 0;
|
|
196
|
+
let totalBytes = 0;
|
|
197
|
+
for (const file of files) {
|
|
198
|
+
if (include && !include(file.path))
|
|
199
|
+
continue;
|
|
200
|
+
const { key, label, color, klass } = classifyFile(file.path, det);
|
|
201
|
+
let row = map.get(key);
|
|
202
|
+
if (row === undefined) {
|
|
203
|
+
row = { key, label, color, klass, files: 0, bytes: 0 };
|
|
204
|
+
map.set(key, row);
|
|
205
|
+
}
|
|
206
|
+
row.files += 1;
|
|
207
|
+
row.bytes += file.size;
|
|
208
|
+
totalFiles += 1;
|
|
209
|
+
totalBytes += file.size;
|
|
210
|
+
}
|
|
211
|
+
const klassRank = { parsed: 0, recognized: 1, other: 2 };
|
|
212
|
+
const rows = [...map.values()].sort((a, b) => klassRank[a.klass] - klassRank[b.klass] ||
|
|
213
|
+
b.bytes - a.bytes ||
|
|
214
|
+
(a.key < b.key ? -1 : 1));
|
|
215
|
+
return { rows, totalFiles, totalBytes };
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=languages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../../src/gitnexus/languages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locate the installed GitNexus package and reuse its own scan primitives.
|
|
3
|
+
*
|
|
4
|
+
* WHY REUSE INSTEAD OF REIMPLEMENT
|
|
5
|
+
* --------------------------------
|
|
6
|
+
* "Which files did GitNexus skip?" has exactly one correct answer: the set
|
|
7
|
+
* `walkRepositoryPaths` produced during `analyze`. Reimplementing that decision
|
|
8
|
+
* here would drift from it silently — the plugin would report a large-file list
|
|
9
|
+
* that no longer matches the index, and nothing would fail loudly.
|
|
10
|
+
*
|
|
11
|
+
* `gitnexus/package.json` declares no `exports` map, so its `dist/**` files are
|
|
12
|
+
* deep-importable. That is what makes reuse possible; it is also why every entry
|
|
13
|
+
* point below is guarded. If a future release closes the exports map or renames a
|
|
14
|
+
* module, `loadScanPrimitives` returns `null` and the caller falls back to the
|
|
15
|
+
* local scan (`./scan-fallback.js`) rather than throwing.
|
|
16
|
+
*/
|
|
17
|
+
/** What a caller may say about where to look for the installed package. */
|
|
18
|
+
export interface RootDiscoveryOptions {
|
|
19
|
+
env?: NodeJS.ProcessEnv;
|
|
20
|
+
moduleUrl?: string;
|
|
21
|
+
discover?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the GitNexus package root, or `null` when no usable install is found.
|
|
25
|
+
*/
|
|
26
|
+
export declare function findGitnexusRoot(options?: RootDiscoveryOptions): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Read the installed GitNexus version. Returned for provenance so a report can
|
|
29
|
+
* state which analyzer produced the index it is judging.
|
|
30
|
+
*/
|
|
31
|
+
export declare function readGitnexusVersion(root: string): string | null;
|
|
32
|
+
/** `walkRepositoryPaths(repoPath, onProgress?, options?)` — GitNexus's own walk. */
|
|
33
|
+
export type WalkRepositoryPaths = (repoPath: string, onProgress?: unknown, options?: object) => Promise<Array<{
|
|
34
|
+
path: string;
|
|
35
|
+
size: number;
|
|
36
|
+
}>>;
|
|
37
|
+
/** `createIgnoreFilter(repoPath, options?)` — the matcher `glob` is handed. */
|
|
38
|
+
export type CreateIgnoreFilter = (repoPath: string, options?: object) => Promise<unknown>;
|
|
39
|
+
/** The slice of the `glob` package this plugin calls. */
|
|
40
|
+
export type GlobFunction = (pattern: string, options: object) => Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* The scan primitives this plugin reuses, all sourced from one GitNexus install.
|
|
43
|
+
*/
|
|
44
|
+
export interface ScanPrimitives {
|
|
45
|
+
gitnexusRoot: string;
|
|
46
|
+
gitnexusVersion: string | null;
|
|
47
|
+
glob: GlobFunction;
|
|
48
|
+
createIgnoreFilter: CreateIgnoreFilter;
|
|
49
|
+
walkRepositoryPaths: WalkRepositoryPaths;
|
|
50
|
+
getMaxFileSizeBytes: () => number;
|
|
51
|
+
DEFAULT_MAX_FILE_SIZE_BYTES: number;
|
|
52
|
+
MAX_FILE_SIZE_UPPER_BOUND_BYTES: number;
|
|
53
|
+
source: 'gitnexus' | 'fallback';
|
|
54
|
+
}
|
|
55
|
+
/** What a caller may override when loading the primitives. */
|
|
56
|
+
export interface LoadScanPrimitivesOptions extends RootDiscoveryOptions {
|
|
57
|
+
root?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Load GitNexus's own scan primitives by deep-importing its dist modules.
|
|
61
|
+
*
|
|
62
|
+
* Every exported member is validated before use: a partial or reshaped module
|
|
63
|
+
* degrades to the fallback rather than producing a wrong answer.
|
|
64
|
+
*
|
|
65
|
+
* @returns `null` when reuse is not possible.
|
|
66
|
+
*/
|
|
67
|
+
export declare function loadScanPrimitives(options?: LoadScanPrimitivesOptions): Promise<ScanPrimitives | null>;
|
|
68
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/gitnexus/root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAcH,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,oBAAyB,GAAG,MAAM,GAAG,IAAI,CAWlF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS/D;AAKD,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC;AAEpD,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE1F,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AA6BnF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,mBAAmB,EAAE,MAAM,MAAM,CAAC;IAClC,2BAA2B,EAAE,MAAM,CAAC;IACpC,+BAA+B,EAAE,MAAM,CAAC;IACxC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACjC;AAED,8DAA8D;AAC9D,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAiDhC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locate the installed GitNexus package and reuse its own scan primitives.
|
|
3
|
+
*
|
|
4
|
+
* WHY REUSE INSTEAD OF REIMPLEMENT
|
|
5
|
+
* --------------------------------
|
|
6
|
+
* "Which files did GitNexus skip?" has exactly one correct answer: the set
|
|
7
|
+
* `walkRepositoryPaths` produced during `analyze`. Reimplementing that decision
|
|
8
|
+
* here would drift from it silently — the plugin would report a large-file list
|
|
9
|
+
* that no longer matches the index, and nothing would fail loudly.
|
|
10
|
+
*
|
|
11
|
+
* `gitnexus/package.json` declares no `exports` map, so its `dist/**` files are
|
|
12
|
+
* deep-importable. That is what makes reuse possible; it is also why every entry
|
|
13
|
+
* point below is guarded. If a future release closes the exports map or renames a
|
|
14
|
+
* module, `loadScanPrimitives` returns `null` and the caller falls back to the
|
|
15
|
+
* local scan (`./scan-fallback.js`) rather than throwing.
|
|
16
|
+
*/
|
|
17
|
+
import { createRequire } from 'node:module';
|
|
18
|
+
import { pathToFileURL } from 'node:url';
|
|
19
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
/** Deep paths inside the `gitnexus` package that this plugin depends on. */
|
|
22
|
+
const DIST = Object.freeze({
|
|
23
|
+
walker: 'dist/core/ingestion/filesystem-walker.js',
|
|
24
|
+
maxFileSize: 'dist/core/ingestion/utils/max-file-size.js',
|
|
25
|
+
ignore: 'dist/config/ignore-service.js',
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Candidate directories that may contain an installed `gitnexus` package.
|
|
29
|
+
* Ordered most-specific first: an explicit override beats PATH discovery, which
|
|
30
|
+
* beats a plain resolution from this package.
|
|
31
|
+
*
|
|
32
|
+
* Discovery always consults the real process environment for `PATH`, even when a
|
|
33
|
+
* caller passes its own `env`. The `env` option governs *configuration*
|
|
34
|
+
* (`GITNEXUS_MAX_FILE_SIZE`, `GITNEXUS_HOME`); which GitNexus is installed on this
|
|
35
|
+
* machine is a fact about the machine, not a per-call setting, and letting a
|
|
36
|
+
* sanitized env blank it out would silently downgrade every caller to the
|
|
37
|
+
* fallback scan.
|
|
38
|
+
*
|
|
39
|
+
* @returns absolute candidate directories (not yet validated)
|
|
40
|
+
*/
|
|
41
|
+
function candidateRoots(options = {}) {
|
|
42
|
+
if (options.discover === false)
|
|
43
|
+
return [];
|
|
44
|
+
const env = { ...process.env, ...(options.env ?? {}) };
|
|
45
|
+
const roots = [];
|
|
46
|
+
if (env.GITNEXUS_PACKAGE_ROOT)
|
|
47
|
+
roots.push(env.GITNEXUS_PACKAGE_ROOT);
|
|
48
|
+
// Probe every PATH entry for a sibling `node_modules/gitnexus` directly.
|
|
49
|
+
//
|
|
50
|
+
// Deliberately NOT "find the gitnexus shim, then derive its prefix": the shim
|
|
51
|
+
// is `.ps1` under nvm4w, and `PATHEXT` on Windows does not list `.ps1`, so
|
|
52
|
+
// shim-based discovery silently finds nothing on the very machines where the
|
|
53
|
+
// CLI is most likely to be installed. Testing the directory is
|
|
54
|
+
// extension-independent and needs no PATHEXT reasoning.
|
|
55
|
+
for (const dir of (env.PATH ?? '').split(path.delimiter)) {
|
|
56
|
+
if (dir === '')
|
|
57
|
+
continue;
|
|
58
|
+
roots.push(path.join(dir, 'node_modules', 'gitnexus'));
|
|
59
|
+
roots.push(path.join(dir, '..', 'node_modules', 'gitnexus'));
|
|
60
|
+
roots.push(path.join(dir, '..', '..', 'node_modules', 'gitnexus'));
|
|
61
|
+
}
|
|
62
|
+
// nvm-for-windows keeps the real tree off PATH behind a junction.
|
|
63
|
+
if (env.NVM_SYMLINK)
|
|
64
|
+
roots.push(path.join(env.NVM_SYMLINK, 'node_modules', 'gitnexus'));
|
|
65
|
+
if (env.NVM_HOME)
|
|
66
|
+
roots.push(path.join(env.NVM_HOME, 'node_modules', 'gitnexus'));
|
|
67
|
+
// Resolve from this package (a real dependency edge, if declared).
|
|
68
|
+
try {
|
|
69
|
+
const here = options.moduleUrl ? path.dirname(new URL(options.moduleUrl).pathname.replace(/^\/([A-Za-z]:)/, '$1')) : undefined;
|
|
70
|
+
const req = createRequire(here ? path.join(here, 'noop.js') : import.meta.url);
|
|
71
|
+
roots.push(path.dirname(req.resolve('gitnexus/package.json')));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
/* not resolvable from here — the other candidates may still work */
|
|
75
|
+
}
|
|
76
|
+
return [...new Set(roots.map((r) => path.resolve(r)))];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve the GitNexus package root, or `null` when no usable install is found.
|
|
80
|
+
*/
|
|
81
|
+
export function findGitnexusRoot(options = {}) {
|
|
82
|
+
for (const root of candidateRoots(options)) {
|
|
83
|
+
try {
|
|
84
|
+
if (existsSync(path.join(root, 'package.json')) && existsSync(path.join(root, DIST.walker))) {
|
|
85
|
+
return root;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* unreadable candidate — keep looking */
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Read the installed GitNexus version. Returned for provenance so a report can
|
|
96
|
+
* state which analyzer produced the index it is judging.
|
|
97
|
+
*/
|
|
98
|
+
export function readGitnexusVersion(root) {
|
|
99
|
+
try {
|
|
100
|
+
const pkg = JSON.parse(readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
101
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** The URL a deep-imported `dist` module is loaded from. */
|
|
108
|
+
const distUrl = (root, relative) => pathToFileURL(path.join(root, relative)).href;
|
|
109
|
+
/**
|
|
110
|
+
* Load GitNexus's own scan primitives by deep-importing its dist modules.
|
|
111
|
+
*
|
|
112
|
+
* Every exported member is validated before use: a partial or reshaped module
|
|
113
|
+
* degrades to the fallback rather than producing a wrong answer.
|
|
114
|
+
*
|
|
115
|
+
* @returns `null` when reuse is not possible.
|
|
116
|
+
*/
|
|
117
|
+
export async function loadScanPrimitives(options = {}) {
|
|
118
|
+
const root = options.root ?? findGitnexusRoot(options);
|
|
119
|
+
if (root === null)
|
|
120
|
+
return null;
|
|
121
|
+
try {
|
|
122
|
+
const [walker, maxSize, ignore] = await Promise.all([
|
|
123
|
+
import(distUrl(root, DIST.walker)),
|
|
124
|
+
import(distUrl(root, DIST.maxFileSize)),
|
|
125
|
+
import(distUrl(root, DIST.ignore)),
|
|
126
|
+
]);
|
|
127
|
+
const createIgnoreFilter = ignore.createIgnoreFilter;
|
|
128
|
+
const walkRepositoryPaths = walker.walkRepositoryPaths;
|
|
129
|
+
const getMaxFileSizeBytes = maxSize.getMaxFileSizeBytes;
|
|
130
|
+
const DEFAULT_MAX_FILE_SIZE_BYTES = maxSize.DEFAULT_MAX_FILE_SIZE_BYTES;
|
|
131
|
+
if (typeof createIgnoreFilter !== 'function' ||
|
|
132
|
+
typeof walkRepositoryPaths !== 'function' ||
|
|
133
|
+
typeof getMaxFileSizeBytes !== 'function' ||
|
|
134
|
+
typeof DEFAULT_MAX_FILE_SIZE_BYTES !== 'number') {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
// `glob` is resolved from GitNexus's own dependency tree so the version that
|
|
138
|
+
// built the ignore filter is the version that consumes it.
|
|
139
|
+
const req = createRequire(path.join(root, 'package.json'));
|
|
140
|
+
const globModule = (await import(pathToFileURL(req.resolve('glob')).href));
|
|
141
|
+
const glob = globModule.glob ?? globModule.default?.glob ?? globModule.default;
|
|
142
|
+
if (typeof glob !== 'function')
|
|
143
|
+
return null;
|
|
144
|
+
return {
|
|
145
|
+
gitnexusRoot: root,
|
|
146
|
+
gitnexusVersion: readGitnexusVersion(root),
|
|
147
|
+
glob,
|
|
148
|
+
createIgnoreFilter,
|
|
149
|
+
walkRepositoryPaths,
|
|
150
|
+
getMaxFileSizeBytes,
|
|
151
|
+
DEFAULT_MAX_FILE_SIZE_BYTES,
|
|
152
|
+
MAX_FILE_SIZE_UPPER_BOUND_BYTES: typeof maxSize.MAX_FILE_SIZE_UPPER_BOUND_BYTES === 'number'
|
|
153
|
+
? maxSize.MAX_FILE_SIZE_UPPER_BOUND_BYTES
|
|
154
|
+
: DEFAULT_MAX_FILE_SIZE_BYTES,
|
|
155
|
+
source: 'gitnexus',
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/gitnexus/root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,4EAA4E;AAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,0CAA0C;IAClD,WAAW,EAAE,4CAA4C;IACzD,MAAM,EAAE,+BAA+B;CACxC,CAAC,CAAC;AASH;;;;;;;;;;;;;GAaG;AACH,SAAS,cAAc,CAAC,UAAgC,EAAE;IACxD,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;IAC1E,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,GAAG,CAAC,qBAAqB;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAErE,yEAAyE;IACzE,EAAE;IACF,8EAA8E;IAC9E,2EAA2E;IAC3E,6EAA6E;IAC7E,+DAA+D;IAC/D,wDAAwD;IACxD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzD,IAAI,GAAG,KAAK,EAAE;YAAE,SAAS;QACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,kEAAkE;IAClE,IAAI,GAAG,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IACxF,IAAI,GAAG,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAElF,mEAAmE;IACnE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/H,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/E,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAgC,EAAE;IACjE,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC5F,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE3E,CAAC;QACF,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,4DAA4D;AAC5D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAU,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AA8D1G;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAqC,EAAE;IAEvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAClD,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAoC;YACrE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAA+B;YACrE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAiC;SACnE,CAAC,CAAC;QAEH,MAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;QACrD,MAAM,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC;QACvD,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,MAAM,2BAA2B,GAAG,OAAO,CAAC,2BAA2B,CAAC;QAExE,IACE,OAAO,kBAAkB,KAAK,UAAU;YACxC,OAAO,mBAAmB,KAAK,UAAU;YACzC,OAAO,mBAAmB,KAAK,UAAU;YACzC,OAAO,2BAA2B,KAAK,QAAQ,EAC/C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6EAA6E;QAC7E,2DAA2D;QAC3D,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAe,CAAC;QACzF,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,OAAO,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC;QAC/E,IAAI,OAAO,IAAI,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC;QAE5C,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC;YAC1C,IAAI;YACJ,kBAAkB;YAClB,mBAAmB;YACnB,mBAAmB;YACnB,2BAA2B;YAC3B,+BAA+B,EAC7B,OAAO,OAAO,CAAC,+BAA+B,KAAK,QAAQ;gBACzD,CAAC,CAAC,OAAO,CAAC,+BAA+B;gBACzC,CAAC,CAAC,2BAA2B;YACjC,MAAM,EAAE,UAAU;SACnB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reproduce GitNexus's scan decision and expose what it discards.
|
|
3
|
+
*
|
|
4
|
+
* `walkRepositoryPaths` (gitnexus/dist/core/ingestion/filesystem-walker.js)
|
|
5
|
+
* makes three cuts and only returns the survivors:
|
|
6
|
+
*
|
|
7
|
+
* 1. `glob(recursive, { nodir: true, dot: false, ignore: createIgnoreFilter(repo) })`
|
|
8
|
+
* — drops dotfiles (`dot: false`) and anything the ignore rules match.
|
|
9
|
+
* 2. `stat.size > maxFileSizeBytes` — the large-file cut. **Counted and logged
|
|
10
|
+
* but never returned**, so an external tool cannot see it.
|
|
11
|
+
* 3. `.d.ts` / `.d.mts` / `.d.cts` whose same-stem implementation was also
|
|
12
|
+
* scanned — suppressed as redundant.
|
|
13
|
+
*
|
|
14
|
+
* This module applies cuts 1 and 3 exactly as upstream does (reusing upstream's
|
|
15
|
+
* own `createIgnoreFilter` and glob), and turns cut 2 — the one that is invisible
|
|
16
|
+
* from outside — into data.
|
|
17
|
+
*
|
|
18
|
+
* Deliberate duplication: the single `glob(...)` call below mirrors
|
|
19
|
+
* `filesystem-walker.js:62-67`. It is four lines and must stay in lockstep with
|
|
20
|
+
* upstream. If it ever drifts, `test/run.mjs` catches it by cross-checking the
|
|
21
|
+
* reported large-file count against what `analyze` itself prints.
|
|
22
|
+
*/
|
|
23
|
+
import { type ScanPrimitives } from './root.js';
|
|
24
|
+
/** One file the scan walked. */
|
|
25
|
+
export interface ScannedFile {
|
|
26
|
+
/** repo-relative, forward slashes */
|
|
27
|
+
path: string;
|
|
28
|
+
/** bytes */
|
|
29
|
+
size: number;
|
|
30
|
+
}
|
|
31
|
+
/** Where the effective size cap came from. */
|
|
32
|
+
export type CapSource = 'env' | 'default' | 'index';
|
|
33
|
+
/** What {@link scanRepository} reports: the survivors plus all three cuts as data. */
|
|
34
|
+
export interface ScanReport {
|
|
35
|
+
/** files GitNexus would hand to the pipeline */
|
|
36
|
+
selected: ScannedFile[];
|
|
37
|
+
/** files dropped by the size cap, largest first */
|
|
38
|
+
large: ScannedFile[];
|
|
39
|
+
/** `.d.ts` dropped as redundant */
|
|
40
|
+
suppressedDeclarations: ScannedFile[];
|
|
41
|
+
/** files that survived the ignore/dotfile cut */
|
|
42
|
+
scannedCount: number;
|
|
43
|
+
/** the effective size cap */
|
|
44
|
+
capBytes: number;
|
|
45
|
+
/** the shipped default */
|
|
46
|
+
defaultCapBytes: number;
|
|
47
|
+
/** where the effective cap came from */
|
|
48
|
+
capSource: CapSource;
|
|
49
|
+
/** hard tree-sitter ceiling */
|
|
50
|
+
maxCapBytes: number;
|
|
51
|
+
gitnexusVersion: string;
|
|
52
|
+
/** reused upstream primitives or a local glob */
|
|
53
|
+
primitives: 'gitnexus' | 'fallback';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Scan a repository the way GitNexus does, and report the size cut as data.
|
|
57
|
+
*
|
|
58
|
+
* @param repoPath absolute path to the repository root
|
|
59
|
+
* @param options `capBytes` overrides the cap (used when the index records its own coverage
|
|
60
|
+
* policy); otherwise `GITNEXUS_MAX_FILE_SIZE` decides, as it does for `analyze`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function scanRepository(repoPath: string, options?: {
|
|
63
|
+
capBytes?: number;
|
|
64
|
+
env?: NodeJS.ProcessEnv;
|
|
65
|
+
primitives?: ScanPrimitives | null;
|
|
66
|
+
}): Promise<ScanReport>;
|
|
67
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/gitnexus/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAkBpE,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpD,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,mDAAmD;IACnD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,mCAAmC;IACnC,sBAAsB,EAAE,WAAW,EAAE,CAAC;IACtC,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,SAAS,EAAE,SAAS,CAAC;IACrB,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;CACrC;AA6CD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B,GACL,OAAO,CAAC,UAAU,CAAC,CAgErB"}
|