@foss.global/codefeed 1.11.1 → 1.13.0

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 CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026-09-05 - 1.13.0
4
+
5
+ ### Features
6
+
7
+ - add version inspection and namespace directory scanning (forgeinventory)
8
+ - Add optional per-scan server version inspection with observed, unverified, and notInspected states.
9
+ - Add token-gated namespace directory enumeration for Gitea admin org/user endpoints and GitLab namespaces, including personal namespaces.
10
+ - Update scan reporting, cursor validation, documentation, and tests for directory pagination and version inspection behavior.
11
+
12
+ ## 2026-09-05 - 1.12.0
13
+
14
+ ### Features
15
+
16
+ - add read-only forge inventory scanner for Gitea and GitLab (forge-inventory)
17
+ - Add ForgeInventoryAdapter and ForgeInventoryScanner exports for bounded repository and namespace observations.
18
+ - Validate provider payloads, cursors, URLs, response budgets, aborts, and rate-limit metrics without leaking tokens or response bodies.
19
+ - Document scanner usage and add protocol fixture tests for Gitea and GitLab inventory behavior.
20
+ - Update @foss.global/interfaces to ^0.12.0 for inventory DTO support.
21
+
22
+ ### Fixes
23
+
24
+ - update package manager and development tooling dependencies (deps)
25
+ - Updated @git.zone/tsbundle to ^2.13.0
26
+ - Updated @git.zone/tsrun to ^2.0.6
27
+ - Updated @git.zone/tstest to ^4.0.0
28
+ - Updated @types/node to ^26.4.1
29
+ - Updated pnpm to 11.25.0
30
+ - correct default tag workflow repository URL and remove release job (ci)
31
+ - Set the computed repository URL to include the code.foss.global host.
32
+ - Remove the tag-triggered npm publish release job from the default tags workflow.
33
+
3
34
  ## 2026-07-21 - 1.11.1
4
35
 
5
36
  ### Fixes
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@foss.global/codefeed',
6
- version: '1.11.1',
6
+ version: '1.13.0',
7
7
  description: 'The @foss.global/codefeed module generates commit/activity feeds from forge providers including Gitea and GitManager.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHVIQUF1SDtDQUNySSxDQUFBIn0=
@@ -0,0 +1,59 @@
1
+ import * as plugins from './plugins.js';
2
+ export { ForgeInventoryError } from './forgeinventory.validation.js';
3
+ export interface IForgeInventoryOptions {
4
+ kind: 'gitea' | 'gitlab';
5
+ instanceId: string;
6
+ /** Instance root, including an optional deployment subpath. HTTPS is required. */
7
+ baseUrl: string;
8
+ /** Personal access token, retained only in this adapter's memory. */
9
+ token?: string;
10
+ pageSize?: number;
11
+ maxPages?: number;
12
+ requestTimeoutMs?: number;
13
+ maxResponseBytes?: number;
14
+ }
15
+ export interface IForgeInventoryRequest {
16
+ cursor?: string;
17
+ signal?: AbortSignal;
18
+ /** Optional lower response-body budget for this request. */
19
+ maxResponseBytes?: number;
20
+ }
21
+ export interface IForgeInventoryMetrics {
22
+ requests: number;
23
+ responseBytes: number;
24
+ rateLimitedRequests: number;
25
+ }
26
+ export type TForgeInventoryVersionInspection = {
27
+ status: 'observed';
28
+ version: string;
29
+ observation: plugins.fossInterfaces.data.IForgeInventoryObservation;
30
+ } | {
31
+ status: 'unverified';
32
+ reason: string;
33
+ observation: plugins.fossInterfaces.data.IForgeInventoryObservation;
34
+ };
35
+ /** Read-only, caller-visible API observations. This adapter never claims admin completeness. */
36
+ export declare class ForgeInventoryAdapter {
37
+ #private;
38
+ constructor(optionsArg: IForgeInventoryOptions);
39
+ get instance(): plugins.fossInterfaces.data.IForgeInventoryInstance;
40
+ get metrics(): IForgeInventoryMetrics;
41
+ observation(startedAt: string): plugins.fossInterfaces.data.IForgeInventoryObservation;
42
+ listRepositories(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryRepository>>;
43
+ /** Organizations/groups only. User namespaces are not enumerated by these endpoints. */
44
+ listNamespaces(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryNamespace>>;
45
+ /** Gitea admin organizations/users or GitLab caller-visible group/personal namespaces. */
46
+ listNamespaceDirectory(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryNamespace>>;
47
+ /** A fresh, bounded observation; failures never retain a previously observed version. */
48
+ inspectVersion(requestArg?: Omit<IForgeInventoryRequest, 'cursor'>): Promise<TForgeInventoryVersionInspection>;
49
+ private identity;
50
+ private namespace;
51
+ private directoryNamespace;
52
+ private repository;
53
+ private url;
54
+ private cursor;
55
+ private continuation;
56
+ private page;
57
+ private next;
58
+ private request;
59
+ }
@@ -0,0 +1,382 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as validation from './forgeinventory.validation.js';
3
+ export { ForgeInventoryError } from './forgeinventory.validation.js';
4
+ /** Read-only, caller-visible API observations. This adapter never claims admin completeness. */
5
+ export class ForgeInventoryAdapter {
6
+ #options;
7
+ #cursorKey = plugins.crypto.randomBytes(32);
8
+ #metrics = { requests: 0, responseBytes: 0, rateLimitedRequests: 0 };
9
+ constructor(optionsArg) {
10
+ const baseUrl = validation.httpUrl(optionsArg.baseUrl);
11
+ if (!baseUrl || !baseUrl.startsWith('https:') || !optionsArg.instanceId.trim() ||
12
+ !['gitea', 'gitlab'].includes(optionsArg.kind) ||
13
+ (optionsArg.token !== undefined && (!optionsArg.token || /[\s\u0000-\u001f\u007f]/.test(optionsArg.token)))) {
14
+ throw new validation.ForgeInventoryError('invalid-options');
15
+ }
16
+ this.#options = {
17
+ ...optionsArg,
18
+ baseUrl: baseUrl.replace(/\/$/, ''),
19
+ pageSize: optionsArg.pageSize ?? 50,
20
+ maxPages: optionsArg.maxPages ?? 1000,
21
+ requestTimeoutMs: optionsArg.requestTimeoutMs ?? 30_000,
22
+ maxResponseBytes: optionsArg.maxResponseBytes ?? 8 * 1024 * 1024,
23
+ };
24
+ for (const [name, maximum] of [
25
+ ['pageSize', 100], ['maxPages', 100_000], ['requestTimeoutMs', 300_000], ['maxResponseBytes', 64 * 1024 * 1024],
26
+ ]) {
27
+ const value = this.#options[name];
28
+ if (!Number.isSafeInteger(value) || value < 1 || value > maximum)
29
+ throw new validation.ForgeInventoryError('invalid-limits');
30
+ }
31
+ }
32
+ get instance() {
33
+ return { instanceId: this.#options.instanceId, kind: this.#options.kind, version: null };
34
+ }
35
+ get metrics() { return { ...this.#metrics }; }
36
+ observation(startedAt) {
37
+ return {
38
+ startedAt, finishedAt: new Date().toISOString(),
39
+ access: this.#options.token ? 'callerVisible' : 'publicOnly', consistency: { status: 'live' },
40
+ };
41
+ }
42
+ listRepositories(requestArg = {}) {
43
+ return this.page('repositories', (item) => this.repository(item), requestArg);
44
+ }
45
+ /** Organizations/groups only. User namespaces are not enumerated by these endpoints. */
46
+ listNamespaces(requestArg = {}) {
47
+ return this.page('namespaces', (item) => this.namespace(item), requestArg);
48
+ }
49
+ /** Gitea admin organizations/users or GitLab caller-visible group/personal namespaces. */
50
+ async listNamespaceDirectory(requestArg = {}) {
51
+ if (!this.#options.token)
52
+ throw new validation.ForgeInventoryError('namespace-directory-requires-token');
53
+ return this.page('namespaceDirectory', (item, state) => this.directoryNamespace(item, state), requestArg);
54
+ }
55
+ /** A fresh, bounded observation; failures never retain a previously observed version. */
56
+ async inspectVersion(requestArg = {}) {
57
+ const startedAt = new Date().toISOString();
58
+ try {
59
+ const { body } = await this.request(new URL(`${this.#options.baseUrl}/api/${this.#options.kind === 'gitea' ? 'v1' : 'v4'}/version`), requestArg);
60
+ const version = validation.record(body).version;
61
+ // Preserve release suffixes while rejecting arbitrary bodies, URLs and control characters.
62
+ if (typeof version !== 'string' || version.length > 128 || !/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9][A-Za-z0-9.+-]*)?$/.test(version)) {
63
+ throw new validation.ForgeInventoryError('invalid-server-version');
64
+ }
65
+ return { status: 'observed', version, observation: this.observation(startedAt) };
66
+ }
67
+ catch (error) {
68
+ return {
69
+ status: 'unverified', observation: this.observation(startedAt),
70
+ reason: error instanceof validation.ForgeInventoryError ? error.message : 'Version inspection failed.',
71
+ };
72
+ }
73
+ }
74
+ identity(idNamespace, value) {
75
+ const objectId = validation.decimal(value);
76
+ if (objectId === '0')
77
+ throw new validation.ForgeInventoryError('invalid-identity');
78
+ return { status: 'identified', ref: { instanceId: this.#options.instanceId, idNamespace, objectId, parentObjectId: null } };
79
+ }
80
+ namespace(itemArg) {
81
+ const item = validation.record(itemArg);
82
+ if (this.#options.kind === 'gitea') {
83
+ const pathSegments = validation.segments(item.name);
84
+ if (pathSegments.length !== 1)
85
+ throw new validation.ForgeInventoryError('invalid-organization-path');
86
+ return {
87
+ identity: this.identity('gitea.user.id', item.id), kind: 'organization', parent: null,
88
+ location: { pathSegments, webUrl: null },
89
+ visibility: validation.visibility(item.visibility === 'limited' ? 'internal' : item.visibility),
90
+ };
91
+ }
92
+ return {
93
+ identity: this.identity('gitlab.group.id', item.id), kind: 'group',
94
+ parent: item.parent_id === null ? null : item.parent_id === undefined
95
+ ? { status: 'unresolved', reason: 'Parent group was not exposed.' }
96
+ : this.identity('gitlab.group.id', item.parent_id),
97
+ location: { pathSegments: validation.segments(item.full_path), webUrl: validation.httpUrl(item.web_url) },
98
+ visibility: validation.visibility(item.visibility),
99
+ };
100
+ }
101
+ directoryNamespace(itemArg, state) {
102
+ const item = validation.record(itemArg);
103
+ if (this.#options.kind === 'gitea') {
104
+ if (state.phase === 'organizations')
105
+ return this.namespace(item);
106
+ const pathSegments = validation.segments(item.login);
107
+ if (pathSegments.length !== 1)
108
+ throw new validation.ForgeInventoryError('invalid-user-namespace-path');
109
+ return {
110
+ identity: this.identity('gitea.user.id', item.id), kind: 'user', parent: null,
111
+ location: { pathSegments, webUrl: validation.httpUrl(item.html_url) },
112
+ visibility: validation.visibility(item.visibility === 'limited' ? 'internal' : item.visibility),
113
+ };
114
+ }
115
+ if (item.kind === 'group')
116
+ return this.namespace(item);
117
+ if (item.kind !== 'user')
118
+ throw new validation.ForgeInventoryError('invalid-namespace-kind');
119
+ const pathSegments = validation.segments(item.full_path);
120
+ if (pathSegments.length !== 1 || (item.parent_id !== undefined && item.parent_id !== null)) {
121
+ throw new validation.ForgeInventoryError('invalid-user-namespace-parent');
122
+ }
123
+ return {
124
+ identity: this.identity('gitlab.namespace.id', item.id), kind: 'user', parent: null,
125
+ location: { pathSegments, webUrl: validation.httpUrl(item.web_url) },
126
+ visibility: validation.visibility(item.visibility),
127
+ };
128
+ }
129
+ repository(itemArg) {
130
+ const item = validation.record(itemArg);
131
+ if (this.#options.kind === 'gitea') {
132
+ const owner = validation.record(item.owner);
133
+ const pathSegments = [...validation.segments(owner.login), ...validation.segments(item.name)];
134
+ if (pathSegments.length !== 2)
135
+ throw new validation.ForgeInventoryError('invalid-repository-path');
136
+ const privateRepo = validation.optionalBoolean(item.private);
137
+ const internalRepo = validation.optionalBoolean(item.internal);
138
+ return {
139
+ identity: this.identity('gitea.repository.id', item.id), namespace: this.identity('gitea.user.id', owner.id),
140
+ location: { pathSegments, webUrl: validation.httpUrl(item.html_url) },
141
+ description: validation.optionalString(item.description),
142
+ visibility: privateRepo === true ? 'private' : internalRepo === true ? 'internal' : privateRepo === false && internalRepo === false ? 'public' : null,
143
+ archived: validation.optionalBoolean(item.archived), defaultBranch: validation.optionalString(item.default_branch),
144
+ httpCloneUrl: validation.httpUrl(item.clone_url), sshCloneUrl: validation.sshUrl(item.ssh_url),
145
+ gitSizeBytes: validation.unknownSize('Gitea size is not a separate Git byte measurement.'),
146
+ };
147
+ }
148
+ const namespace = validation.record(item.namespace);
149
+ if (namespace.kind !== 'group' && namespace.kind !== 'user')
150
+ throw new validation.ForgeInventoryError('invalid-namespace-kind');
151
+ return {
152
+ identity: this.identity('gitlab.project.id', item.id),
153
+ namespace: this.identity(namespace.kind === 'group' ? 'gitlab.group.id' : 'gitlab.namespace.id', namespace.id),
154
+ location: { pathSegments: validation.segments(item.path_with_namespace), webUrl: validation.httpUrl(item.web_url) },
155
+ description: validation.optionalString(item.description), visibility: validation.visibility(item.visibility),
156
+ archived: validation.optionalBoolean(item.archived), defaultBranch: validation.optionalString(item.default_branch),
157
+ httpCloneUrl: validation.httpUrl(item.http_url_to_repo), sshCloneUrl: validation.sshUrl(item.ssh_url_to_repo),
158
+ gitSizeBytes: validation.gitlabSize(item.statistics),
159
+ };
160
+ }
161
+ url(state) {
162
+ const gitea = this.#options.kind === 'gitea';
163
+ const endpoint = state.collection === 'repositories' ? (gitea ? 'repos/search' : 'projects')
164
+ : state.collection === 'namespaceDirectory' ? (gitea ? `admin/${state.phase === 'organizations' ? 'orgs' : 'users'}` : 'namespaces')
165
+ : (gitea ? 'orgs' : 'groups');
166
+ const url = new URL(`${this.#options.baseUrl}/api/${gitea ? 'v1' : 'v4'}/${endpoint}`);
167
+ url.searchParams.set(gitea ? 'limit' : 'per_page', String(this.#options.pageSize));
168
+ if (gitea) {
169
+ url.searchParams.set('page', String(state.page));
170
+ if (state.collection === 'repositories') {
171
+ url.searchParams.set('sort', 'id');
172
+ url.searchParams.set('order', 'asc');
173
+ url.searchParams.set('private', 'true');
174
+ }
175
+ }
176
+ else if (state.collection === 'namespaceDirectory') {
177
+ url.searchParams.set('page', String(state.page));
178
+ }
179
+ else {
180
+ url.searchParams.set('order_by', 'id');
181
+ url.searchParams.set('sort', 'asc');
182
+ if (state.collection === 'repositories') {
183
+ url.searchParams.set('pagination', 'keyset');
184
+ url.searchParams.set('statistics', 'true');
185
+ if (state.after)
186
+ url.searchParams.set('id_after', state.after);
187
+ }
188
+ else {
189
+ url.searchParams.set('all_available', 'true');
190
+ url.searchParams.set('page', String(state.page));
191
+ }
192
+ }
193
+ return url;
194
+ }
195
+ cursor(state) {
196
+ const payload = Buffer.from(JSON.stringify(state)).toString('base64url');
197
+ return `${payload}.${plugins.crypto.createHmac('sha256', this.#cursorKey).update(payload).digest('base64url')}`;
198
+ }
199
+ continuation(collection, cursor) {
200
+ const directory = collection === 'namespaceDirectory' && this.#options.kind === 'gitea';
201
+ if (cursor === undefined)
202
+ return { version: 2, collection, page: 1, pagesRead: 0, phase: directory ? 'organizations' : null, after: null };
203
+ try {
204
+ if (cursor.length > 2048)
205
+ throw new Error();
206
+ const [payload, signature, extra] = cursor.split('.');
207
+ const expected = plugins.crypto.createHmac('sha256', this.#cursorKey).update(payload).digest('base64url');
208
+ if (extra !== undefined || !signature || signature.length !== expected.length ||
209
+ !plugins.crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)))
210
+ throw new Error();
211
+ const state = JSON.parse(Buffer.from(payload, 'base64url').toString());
212
+ if (state.version !== 2 || state.collection !== collection || !Number.isSafeInteger(state.page) ||
213
+ !Number.isSafeInteger(state.pagesRead) || state.pagesRead < 1 || state.pagesRead >= this.#options.maxPages ||
214
+ state.page < 1 || state.page > state.pagesRead + 1 ||
215
+ (directory ? state.phase !== 'organizations' && state.phase !== 'users' : state.phase !== null) ||
216
+ ((collection !== 'repositories' || this.#options.kind !== 'gitlab') && state.after !== null) ||
217
+ (state.after !== null && validation.decimal(state.after) !== state.after))
218
+ throw new Error();
219
+ return state;
220
+ }
221
+ catch {
222
+ throw new validation.ForgeInventoryError('invalid-cursor');
223
+ }
224
+ }
225
+ async page(collection, map, requestArg) {
226
+ const state = this.continuation(collection, requestArg.cursor);
227
+ const startedAt = new Date().toISOString();
228
+ const url = this.url(state);
229
+ const { body, headers } = await this.request(url, requestArg);
230
+ let rows = body;
231
+ if (this.#options.kind === 'gitea' && collection === 'repositories') {
232
+ const envelope = validation.record(body);
233
+ if (envelope.ok !== true)
234
+ throw new validation.ForgeInventoryError('search-not-successful');
235
+ rows = envelope.data;
236
+ }
237
+ if (!Array.isArray(rows) || rows.length > this.#options.pageSize)
238
+ throw new validation.ForgeInventoryError('invalid-page');
239
+ const items = rows.map((item) => map(item, state));
240
+ let pagination;
241
+ try {
242
+ const next = this.next(state, url, headers, rows);
243
+ pagination = next === null ? { status: 'exhausted' } : state.pagesRead + 1 >= this.#options.maxPages
244
+ ? { status: 'incomplete', reason: 'Configured page limit reached.' }
245
+ : { status: 'more', cursor: this.cursor(next) };
246
+ }
247
+ catch {
248
+ pagination = { status: 'incomplete', reason: 'Invalid or inconsistent pagination metadata.' };
249
+ }
250
+ return { schemaVersion: 1, instance: this.instance, scope: { kind: 'instance' }, observation: this.observation(startedAt), items, pagination };
251
+ }
252
+ next(state, current, headers, rows) {
253
+ const keyset = this.#options.kind === 'gitlab' && state.collection === 'repositories';
254
+ let previousId = BigInt(state.after ?? '0');
255
+ if (keyset)
256
+ for (const row of rows) {
257
+ const id = BigInt(validation.decimal(validation.record(row).id));
258
+ if (id <= previousId)
259
+ throw new Error();
260
+ previousId = id;
261
+ }
262
+ const link = headers.get('link');
263
+ let nextUrl = null;
264
+ if (link !== null) {
265
+ if (link.length > 16_384)
266
+ throw new Error();
267
+ for (const entry of link.split(',')) {
268
+ const match = entry.trim().match(/^<([^<>]+)>;\s*rel="(next|prev|first|last)"$/);
269
+ if (!match)
270
+ throw new Error();
271
+ if (match[2] !== 'next')
272
+ continue;
273
+ if (nextUrl !== null)
274
+ throw new Error();
275
+ nextUrl = new URL(match[1], current);
276
+ if (nextUrl.origin !== current.origin || nextUrl.pathname !== current.pathname || nextUrl.username || nextUrl.password || nextUrl.hash)
277
+ throw new Error();
278
+ const expected = new URL(current);
279
+ const changing = keyset ? 'id_after' : 'page';
280
+ expected.searchParams.delete(changing);
281
+ const actual = new URL(nextUrl);
282
+ if (actual.searchParams.getAll(changing).length !== 1)
283
+ throw new Error();
284
+ actual.searchParams.delete(changing);
285
+ expected.searchParams.sort();
286
+ actual.searchParams.sort();
287
+ if (expected.search !== actual.search)
288
+ throw new Error();
289
+ }
290
+ }
291
+ const xNext = headers.get('x-next-page');
292
+ if (!keyset && xNext !== null && xNext !== '' && validation.decimal(xNext) !== String(state.page + 1))
293
+ throw new Error();
294
+ if (rows.length === 0) {
295
+ if (nextUrl || xNext)
296
+ throw new Error();
297
+ if (state.phase === 'organizations')
298
+ return { ...state, phase: 'users', page: 1, pagesRead: state.pagesRead + 1 };
299
+ return null;
300
+ }
301
+ if (keyset) {
302
+ if (!nextUrl)
303
+ return null; // GitLab keyset exhaustion is signalled by no next Link.
304
+ const after = validation.decimal(nextUrl.searchParams.get('id_after'));
305
+ if (after !== previousId.toString())
306
+ throw new Error();
307
+ return { ...state, page: state.page + 1, pagesRead: state.pagesRead + 1, after };
308
+ }
309
+ if (nextUrl && validation.decimal(nextUrl.searchParams.get('page')) !== String(state.page + 1))
310
+ throw new Error();
311
+ if (nextUrl && xNext === '')
312
+ throw new Error();
313
+ // A short page can reflect a server page-size cap. Probe the following page
314
+ // even without Link rather than silently truncating at that cap.
315
+ return { ...state, page: state.page + 1, pagesRead: state.pagesRead + 1 };
316
+ }
317
+ async request(url, requestArg) {
318
+ const { signal } = requestArg;
319
+ const maxBytes = requestArg.maxResponseBytes ?? this.#options.maxResponseBytes;
320
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)
321
+ throw new validation.ForgeInventoryError('invalid-response-budget');
322
+ const controller = new AbortController();
323
+ const abort = () => controller.abort();
324
+ if (signal?.aborted)
325
+ throw new validation.ForgeInventoryError('request-aborted');
326
+ signal?.addEventListener('abort', abort, { once: true });
327
+ const timeout = setTimeout(abort, this.#options.requestTimeoutMs);
328
+ const deadline = Date.now() + this.#options.requestTimeoutMs;
329
+ let reader;
330
+ try {
331
+ const headers = new Headers({ accept: 'application/json' });
332
+ if (this.#options.token)
333
+ headers.set(this.#options.kind === 'gitea' ? 'authorization' : 'private-token', this.#options.kind === 'gitea' ? `token ${this.#options.token}` : this.#options.token);
334
+ this.#metrics.requests++;
335
+ const response = await fetch(url, { method: 'GET', headers, redirect: 'error', credentials: 'omit', signal: controller.signal });
336
+ reader = response.body?.getReader();
337
+ if (response.status === 429)
338
+ this.#metrics.rateLimitedRequests++;
339
+ if (response.status !== 200)
340
+ throw new validation.ForgeInventoryError(`http-${response.status}`);
341
+ if (response.headers.get('content-type')?.split(';')[0].trim().toLowerCase() !== 'application/json' || !reader)
342
+ throw new validation.ForgeInventoryError('invalid-content-type');
343
+ const chunks = [];
344
+ let bytes = 0;
345
+ while (true) {
346
+ const result = await reader.read();
347
+ if (result.done)
348
+ break;
349
+ bytes += result.value.byteLength;
350
+ this.#metrics.responseBytes += result.value.byteLength;
351
+ if (bytes > Math.min(maxBytes, this.#options.maxResponseBytes))
352
+ throw new validation.ForgeInventoryError('response-size-limit');
353
+ if (controller.signal.aborted || Date.now() >= deadline)
354
+ throw new validation.ForgeInventoryError('request-aborted-or-timed-out');
355
+ chunks.push(result.value);
356
+ }
357
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks));
358
+ const body = JSON.parse(text);
359
+ if (controller.signal.aborted || Date.now() >= deadline)
360
+ throw new validation.ForgeInventoryError('request-aborted-or-timed-out');
361
+ return { body, headers: response.headers };
362
+ }
363
+ catch (error) {
364
+ if (error instanceof validation.ForgeInventoryError)
365
+ throw error;
366
+ throw new validation.ForgeInventoryError(controller.signal.aborted ? 'request-aborted-or-timed-out' : 'request-or-json-failed');
367
+ }
368
+ finally {
369
+ controller.abort();
370
+ clearTimeout(timeout);
371
+ signal?.removeEventListener('abort', abort);
372
+ if (reader) {
373
+ try {
374
+ await reader.cancel();
375
+ }
376
+ catch { /* The request has already been aborted. */ }
377
+ reader.releaseLock();
378
+ }
379
+ }
380
+ }
381
+ }
382
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mb3JnZWludmVudG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZm9yZ2VpbnZlbnRvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLFVBQVUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU3RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQTRDckUsZ0dBQWdHO0FBQ2hHLE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsUUFBUSxDQUF1RTtJQUMvRSxVQUFVLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUMsUUFBUSxHQUEyQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUV0RyxZQUFZLFVBQWtDO1FBQzVDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUU7WUFDNUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUM5QyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLHlCQUF5QixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUcsTUFBTSxJQUFJLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FB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
@@ -0,0 +1,33 @@
1
+ import type * as plugins from './plugins.js';
2
+ import type { IForgeInventoryMetrics, IForgeInventoryOptions, TForgeInventoryVersionInspection } from './classes.forgeinventory.js';
3
+ export interface IForgeInventoryScanOptions {
4
+ signal?: AbortSignal;
5
+ /** Maximum distinct items retained per collection. */
6
+ maxItems?: number;
7
+ /** Deadline for the complete scan, including body reads. */
8
+ timeoutMs?: number;
9
+ /** Maximum response bytes consumed across all collection and version requests. */
10
+ maxScanResponseBytes?: number;
11
+ /** Probe the server version at the beginning of this scan. Defaults to false. */
12
+ inspectVersion?: boolean;
13
+ /** Include personal namespaces through authenticated directory endpoints. Defaults to false. */
14
+ namespaceDirectory?: boolean;
15
+ }
16
+ export interface IForgeInventoryScan {
17
+ report: plugins.fossInterfaces.data.IForgeInventoryReport;
18
+ repositories: plugins.fossInterfaces.data.IForgeInventoryRepository[];
19
+ namespaces: plugins.fossInterfaces.data.IForgeInventoryNamespace[];
20
+ metrics: IForgeInventoryMetrics;
21
+ versionInspection: TForgeInventoryVersionInspection | {
22
+ status: 'notInspected';
23
+ reason: string;
24
+ };
25
+ }
26
+ /** A bounded, disposable observation; callers own any durable storage and migration decisions. */
27
+ export declare class ForgeInventoryScanner {
28
+ #private;
29
+ constructor(optionsArg: IForgeInventoryOptions);
30
+ scan(optionsArg?: IForgeInventoryScanOptions): Promise<IForgeInventoryScan>;
31
+ private capability;
32
+ private collect;
33
+ }