@foss.global/codefeed 1.13.0 → 1.15.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 +19 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.forgeinventory.d.ts +9 -0
- package/dist_ts/classes.forgeinventory.js +111 -11
- package/dist_ts/classes.forgeinventoryscanner.d.ts +4 -0
- package/dist_ts/classes.forgeinventoryscanner.js +52 -14
- package/dist_ts/forgeinventory.validation.d.ts +2 -0
- package/dist_ts/forgeinventory.validation.js +15 -1
- package/package.json +3 -3
- package/readme.md +12 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.forgeinventory.ts +104 -12
- package/ts/classes.forgeinventoryscanner.ts +60 -13
- package/ts/forgeinventory.validation.ts +13 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-09-05 - 1.15.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- expose normalized forge inventory base URL (forgeinventory)
|
|
8
|
+
- Add a read-only adapter baseUrl getter for the validated, normalized forge instance root.
|
|
9
|
+
- Normalize configured forge base URLs by removing multiple trailing slashes.
|
|
10
|
+
- Update @foss.global/gitmanager to ^1.7.1.
|
|
11
|
+
|
|
12
|
+
## 2026-09-05 - 1.14.0
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- add optional forge issue inventory scanning (forgeinventory)
|
|
17
|
+
- Adds scanner includeIssues support and adapter listIssues pages for visible Gitea and GitLab issues.
|
|
18
|
+
- Validates repository-scoped issue cursors, repository identity, issue payload fields and provider timestamps.
|
|
19
|
+
- Reports issue collection status and returns scanned issues alongside repositories and namespaces.
|
|
20
|
+
- Updates forge inventory documentation, tests and @foss.global/interfaces to support issue DTOs.
|
|
21
|
+
|
|
3
22
|
## 2026-09-05 - 1.13.0
|
|
4
23
|
|
|
5
24
|
### Features
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@foss.global/codefeed',
|
|
6
|
-
version: '1.
|
|
6
|
+
version: '1.15.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=
|
|
@@ -32,11 +32,16 @@ export type TForgeInventoryVersionInspection = {
|
|
|
32
32
|
reason: string;
|
|
33
33
|
observation: plugins.fossInterfaces.data.IForgeInventoryObservation;
|
|
34
34
|
};
|
|
35
|
+
type TRepositoryScope = Extract<plugins.fossInterfaces.data.TForgeInventoryScope, {
|
|
36
|
+
kind: 'repository';
|
|
37
|
+
}>;
|
|
35
38
|
/** Read-only, caller-visible API observations. This adapter never claims admin completeness. */
|
|
36
39
|
export declare class ForgeInventoryAdapter {
|
|
37
40
|
#private;
|
|
38
41
|
constructor(optionsArg: IForgeInventoryOptions);
|
|
39
42
|
get instance(): plugins.fossInterfaces.data.IForgeInventoryInstance;
|
|
43
|
+
/** Validated, normalized instance root; contains no credentials or API suffix. */
|
|
44
|
+
get baseUrl(): string;
|
|
40
45
|
get metrics(): IForgeInventoryMetrics;
|
|
41
46
|
observation(startedAt: string): plugins.fossInterfaces.data.IForgeInventoryObservation;
|
|
42
47
|
listRepositories(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryRepository>>;
|
|
@@ -44,9 +49,13 @@ export declare class ForgeInventoryAdapter {
|
|
|
44
49
|
listNamespaces(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryNamespace>>;
|
|
45
50
|
/** Gitea admin organizations/users or GitLab caller-visible group/personal namespaces. */
|
|
46
51
|
listNamespaceDirectory(requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryNamespace>>;
|
|
52
|
+
/** All visible open/closed issues in one stable repository, excluding Gitea pull requests. */
|
|
53
|
+
listIssues(scopeArg: TRepositoryScope, requestArg?: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryIssue>>;
|
|
47
54
|
/** A fresh, bounded observation; failures never retain a previously observed version. */
|
|
48
55
|
inspectVersion(requestArg?: Omit<IForgeInventoryRequest, 'cursor'>): Promise<TForgeInventoryVersionInspection>;
|
|
49
56
|
private identity;
|
|
57
|
+
private repositoryScope;
|
|
58
|
+
private issue;
|
|
50
59
|
private namespace;
|
|
51
60
|
private directoryNamespace;
|
|
52
61
|
private repository;
|
|
@@ -15,7 +15,7 @@ export class ForgeInventoryAdapter {
|
|
|
15
15
|
}
|
|
16
16
|
this.#options = {
|
|
17
17
|
...optionsArg,
|
|
18
|
-
baseUrl: baseUrl.replace(
|
|
18
|
+
baseUrl: baseUrl.replace(/\/+$/, ''),
|
|
19
19
|
pageSize: optionsArg.pageSize ?? 50,
|
|
20
20
|
maxPages: optionsArg.maxPages ?? 1000,
|
|
21
21
|
requestTimeoutMs: optionsArg.requestTimeoutMs ?? 30_000,
|
|
@@ -32,6 +32,8 @@ export class ForgeInventoryAdapter {
|
|
|
32
32
|
get instance() {
|
|
33
33
|
return { instanceId: this.#options.instanceId, kind: this.#options.kind, version: null };
|
|
34
34
|
}
|
|
35
|
+
/** Validated, normalized instance root; contains no credentials or API suffix. */
|
|
36
|
+
get baseUrl() { return this.#options.baseUrl; }
|
|
35
37
|
get metrics() { return { ...this.#metrics }; }
|
|
36
38
|
observation(startedAt) {
|
|
37
39
|
return {
|
|
@@ -52,6 +54,11 @@ export class ForgeInventoryAdapter {
|
|
|
52
54
|
throw new validation.ForgeInventoryError('namespace-directory-requires-token');
|
|
53
55
|
return this.page('namespaceDirectory', (item, state) => this.directoryNamespace(item, state), requestArg);
|
|
54
56
|
}
|
|
57
|
+
/** All visible open/closed issues in one stable repository, excluding Gitea pull requests. */
|
|
58
|
+
listIssues(scopeArg, requestArg = {}) {
|
|
59
|
+
const scope = this.repositoryScope(scopeArg);
|
|
60
|
+
return this.page('issues', (item) => this.issue(item, scope), requestArg, scope);
|
|
61
|
+
}
|
|
55
62
|
/** A fresh, bounded observation; failures never retain a previously observed version. */
|
|
56
63
|
async inspectVersion(requestArg = {}) {
|
|
57
64
|
const startedAt = new Date().toISOString();
|
|
@@ -77,6 +84,64 @@ export class ForgeInventoryAdapter {
|
|
|
77
84
|
throw new validation.ForgeInventoryError('invalid-identity');
|
|
78
85
|
return { status: 'identified', ref: { instanceId: this.#options.instanceId, idNamespace, objectId, parentObjectId: null } };
|
|
79
86
|
}
|
|
87
|
+
repositoryScope(scopeArg) {
|
|
88
|
+
const expectedNamespace = this.#options.kind === 'gitea' ? 'gitea.repository.id' : 'gitlab.project.id';
|
|
89
|
+
if (scopeArg?.kind !== 'repository' || scopeArg.identity?.status !== 'identified' ||
|
|
90
|
+
scopeArg.identity.ref.instanceId !== this.#options.instanceId || scopeArg.identity.ref.idNamespace !== expectedNamespace ||
|
|
91
|
+
scopeArg.identity.ref.parentObjectId !== null || typeof scopeArg.identity.ref.objectId !== 'string' ||
|
|
92
|
+
validation.decimal(scopeArg.identity.ref.objectId) === '0' || !Array.isArray(scopeArg.location?.pathSegments) ||
|
|
93
|
+
scopeArg.location.pathSegments.length < 2 || (this.#options.kind === 'gitea' && scopeArg.location.pathSegments.length !== 2)) {
|
|
94
|
+
throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
95
|
+
}
|
|
96
|
+
const pathSegments = scopeArg.location.pathSegments.map((segment) => {
|
|
97
|
+
if (validation.segments(segment).length !== 1)
|
|
98
|
+
throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
99
|
+
return segment;
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
kind: 'repository', identity: { status: 'identified', ref: {
|
|
103
|
+
instanceId: this.#options.instanceId, idNamespace: expectedNamespace, objectId: scopeArg.identity.ref.objectId, parentObjectId: null,
|
|
104
|
+
} },
|
|
105
|
+
location: { pathSegments, webUrl: validation.httpUrl(scopeArg.location.webUrl) },
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
issue(itemArg, scope) {
|
|
109
|
+
const item = validation.record(itemArg);
|
|
110
|
+
const gitea = this.#options.kind === 'gitea';
|
|
111
|
+
if (gitea && item.pull_request !== undefined && item.pull_request !== null)
|
|
112
|
+
throw new validation.ForgeInventoryError('unexpected-pull-request');
|
|
113
|
+
const repositoryId = validation.decimal(gitea ? validation.record(item.repository).id : item.project_id);
|
|
114
|
+
if (repositoryId !== scope.identity.ref.objectId)
|
|
115
|
+
throw new validation.ForgeInventoryError('issue-repository-mismatch');
|
|
116
|
+
const number = validation.decimal(gitea ? item.number : item.iid);
|
|
117
|
+
if (number === '0' || typeof item.title !== 'string' || !item.title)
|
|
118
|
+
throw new validation.ForgeInventoryError('invalid-issue');
|
|
119
|
+
const body = gitea ? item.body : item.description;
|
|
120
|
+
if (body !== undefined && body !== null && typeof body !== 'string')
|
|
121
|
+
throw new validation.ForgeInventoryError('invalid-issue-body');
|
|
122
|
+
const state = item.state === (gitea ? 'open' : 'opened') ? 'open' : item.state === 'closed' ? 'closed' : null;
|
|
123
|
+
if (state === null && item.state !== undefined && item.state !== null)
|
|
124
|
+
throw new validation.ForgeInventoryError('invalid-issue-state');
|
|
125
|
+
const actor = gitea ? item.user : item.author;
|
|
126
|
+
let author = { status: 'unresolved', reason: 'Provider author identity was not exposed.' };
|
|
127
|
+
if (actor !== undefined && actor !== null) {
|
|
128
|
+
const actorId = validation.record(actor).id;
|
|
129
|
+
if (gitea && [-1, -2, '-1', '-2'].includes(actorId)) {
|
|
130
|
+
author = { status: 'unresolved', reason: 'Gitea reports a deleted or built-in author without a regular user identity.' };
|
|
131
|
+
}
|
|
132
|
+
else if (actorId !== undefined && actorId !== null) {
|
|
133
|
+
author = this.identity(gitea ? 'gitea.user.id' : 'gitlab.user.id', actorId);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
identity: this.identity(gitea ? 'gitea.issue.id' : 'gitlab.issue.id', item.id), repository: scope.identity,
|
|
138
|
+
location: { pathSegments: [...scope.location.pathSegments, ...(gitea ? [] : ['-']), 'issues', number], webUrl: validation.httpUrl(gitea ? item.html_url : item.web_url) },
|
|
139
|
+
number, title: item.title, body: body ?? null, state,
|
|
140
|
+
providerType: gitea ? 'issue' : validation.optionalString(item.issue_type),
|
|
141
|
+
confidential: gitea ? null : validation.optionalBoolean(item.confidential), author,
|
|
142
|
+
createdAt: validation.timestamp(item.created_at), updatedAt: validation.timestamp(item.updated_at), closedAt: validation.timestamp(item.closed_at),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
80
145
|
namespace(itemArg) {
|
|
81
146
|
const item = validation.record(itemArg);
|
|
82
147
|
if (this.#options.kind === 'gitea') {
|
|
@@ -158,8 +223,26 @@ export class ForgeInventoryAdapter {
|
|
|
158
223
|
gitSizeBytes: validation.gitlabSize(item.statistics),
|
|
159
224
|
};
|
|
160
225
|
}
|
|
161
|
-
url(state) {
|
|
226
|
+
url(state, scope) {
|
|
162
227
|
const gitea = this.#options.kind === 'gitea';
|
|
228
|
+
if (state.collection === 'issues') {
|
|
229
|
+
if (!scope)
|
|
230
|
+
throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
231
|
+
const endpoint = gitea ? `repos/${scope.location.pathSegments.map(encodeURIComponent).join('/')}/issues`
|
|
232
|
+
: `projects/${scope.identity.ref.objectId}/issues`;
|
|
233
|
+
const url = new URL(`${this.#options.baseUrl}/api/${gitea ? 'v1' : 'v4'}/${endpoint}`);
|
|
234
|
+
url.searchParams.set(gitea ? 'limit' : 'per_page', String(this.#options.pageSize));
|
|
235
|
+
url.searchParams.set('page', String(state.page));
|
|
236
|
+
url.searchParams.set('state', 'all');
|
|
237
|
+
if (gitea)
|
|
238
|
+
url.searchParams.set('type', 'issues');
|
|
239
|
+
else {
|
|
240
|
+
url.searchParams.set('scope', 'all');
|
|
241
|
+
url.searchParams.set('order_by', 'created_at');
|
|
242
|
+
url.searchParams.set('sort', 'asc');
|
|
243
|
+
}
|
|
244
|
+
return url;
|
|
245
|
+
}
|
|
163
246
|
const endpoint = state.collection === 'repositories' ? (gitea ? 'repos/search' : 'projects')
|
|
164
247
|
: state.collection === 'namespaceDirectory' ? (gitea ? `admin/${state.phase === 'organizations' ? 'orgs' : 'users'}` : 'namespaces')
|
|
165
248
|
: (gitea ? 'orgs' : 'groups');
|
|
@@ -196,10 +279,10 @@ export class ForgeInventoryAdapter {
|
|
|
196
279
|
const payload = Buffer.from(JSON.stringify(state)).toString('base64url');
|
|
197
280
|
return `${payload}.${plugins.crypto.createHmac('sha256', this.#cursorKey).update(payload).digest('base64url')}`;
|
|
198
281
|
}
|
|
199
|
-
continuation(collection, cursor) {
|
|
282
|
+
continuation(collection, cursor, repositoryKey = null) {
|
|
200
283
|
const directory = collection === 'namespaceDirectory' && this.#options.kind === 'gitea';
|
|
201
284
|
if (cursor === undefined)
|
|
202
|
-
return { version:
|
|
285
|
+
return { version: 3, collection, repositoryKey, page: 1, pagesRead: 0, phase: directory ? 'organizations' : null, after: null };
|
|
203
286
|
try {
|
|
204
287
|
if (cursor.length > 2048)
|
|
205
288
|
throw new Error();
|
|
@@ -209,7 +292,7 @@ export class ForgeInventoryAdapter {
|
|
|
209
292
|
!plugins.crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)))
|
|
210
293
|
throw new Error();
|
|
211
294
|
const state = JSON.parse(Buffer.from(payload, 'base64url').toString());
|
|
212
|
-
if (state.version !==
|
|
295
|
+
if (state.version !== 3 || state.collection !== collection || state.repositoryKey !== repositoryKey || !Number.isSafeInteger(state.page) ||
|
|
213
296
|
!Number.isSafeInteger(state.pagesRead) || state.pagesRead < 1 || state.pagesRead >= this.#options.maxPages ||
|
|
214
297
|
state.page < 1 || state.page > state.pagesRead + 1 ||
|
|
215
298
|
(directory ? state.phase !== 'organizations' && state.phase !== 'users' : state.phase !== null) ||
|
|
@@ -222,11 +305,28 @@ export class ForgeInventoryAdapter {
|
|
|
222
305
|
throw new validation.ForgeInventoryError('invalid-cursor');
|
|
223
306
|
}
|
|
224
307
|
}
|
|
225
|
-
async page(collection, map, requestArg) {
|
|
226
|
-
const
|
|
308
|
+
async page(collection, map, requestArg, scope) {
|
|
309
|
+
const repositoryKey = scope ? plugins.crypto.createHash('sha256').update(JSON.stringify(scope)).digest('hex') : null;
|
|
310
|
+
const state = this.continuation(collection, requestArg.cursor, repositoryKey);
|
|
227
311
|
const startedAt = new Date().toISOString();
|
|
228
|
-
const url = this.url(state);
|
|
229
|
-
|
|
312
|
+
const url = this.url(state, scope);
|
|
313
|
+
let pageRequest = requestArg;
|
|
314
|
+
if (collection === 'issues' && this.#options.kind === 'gitea' && scope) {
|
|
315
|
+
// Gitea addresses issue lists by mutable path. Check ownership even for empty pages.
|
|
316
|
+
const before = this.#metrics.responseBytes;
|
|
317
|
+
const repositoryUrl = new URL(`${this.#options.baseUrl}/api/v1/repos/${scope.location.pathSegments.map(encodeURIComponent).join('/')}`);
|
|
318
|
+
const probe = await this.request(repositoryUrl, requestArg);
|
|
319
|
+
if (validation.decimal(validation.record(probe.body).id) !== scope.identity.ref.objectId) {
|
|
320
|
+
throw new validation.ForgeInventoryError('repository-identity-changed');
|
|
321
|
+
}
|
|
322
|
+
if (requestArg.maxResponseBytes !== undefined) {
|
|
323
|
+
const remaining = requestArg.maxResponseBytes - (this.#metrics.responseBytes - before);
|
|
324
|
+
if (remaining <= 0)
|
|
325
|
+
throw new validation.ForgeInventoryError('response-size-limit');
|
|
326
|
+
pageRequest = { ...requestArg, maxResponseBytes: remaining };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const { body, headers } = await this.request(url, pageRequest);
|
|
230
330
|
let rows = body;
|
|
231
331
|
if (this.#options.kind === 'gitea' && collection === 'repositories') {
|
|
232
332
|
const envelope = validation.record(body);
|
|
@@ -247,7 +347,7 @@ export class ForgeInventoryAdapter {
|
|
|
247
347
|
catch {
|
|
248
348
|
pagination = { status: 'incomplete', reason: 'Invalid or inconsistent pagination metadata.' };
|
|
249
349
|
}
|
|
250
|
-
return { schemaVersion: 1, instance: this.instance, scope: { kind: 'instance' }, observation: this.observation(startedAt), items, pagination };
|
|
350
|
+
return { schemaVersion: 1, instance: this.instance, scope: scope ?? { kind: 'instance' }, observation: this.observation(startedAt), items, pagination };
|
|
251
351
|
}
|
|
252
352
|
next(state, current, headers, rows) {
|
|
253
353
|
const keyset = this.#options.kind === 'gitlab' && state.collection === 'repositories';
|
|
@@ -379,4 +479,4 @@ export class ForgeInventoryAdapter {
|
|
|
379
479
|
}
|
|
380
480
|
}
|
|
381
481
|
}
|
|
382
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mb3JnZWludmVudG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZm9yZ2VpbnZlbnRvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLFVBQVUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU3RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQTRDckUsZ0dBQWdHO0FBQ2hHLE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsUUFBUSxDQUF1RTtJQUMvRSxVQUFVLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUMsUUFBUSxHQUEyQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUV0RyxZQUFZLFVBQWtDO1FBQzVDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUU7WUFDNUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUM5QyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLHlCQUF5QixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUcsTUFBTSxJQUFJLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FB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
|
|
482
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mb3JnZWludmVudG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZm9yZ2VpbnZlbnRvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxLQUFLLFVBQVUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU3RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQStDckUsZ0dBQWdHO0FBQ2hHLE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsUUFBUSxDQUF1RTtJQUMvRSxVQUFVLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUMsUUFBUSxHQUEyQixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUV0RyxZQUFZLFVBQWtDO1FBQzVDLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUU7WUFDNUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUM5QyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLHlCQUF5QixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUcsTUFBTSxJQUFJLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FB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
|
|
@@ -12,11 +12,14 @@ export interface IForgeInventoryScanOptions {
|
|
|
12
12
|
inspectVersion?: boolean;
|
|
13
13
|
/** Include personal namespaces through authenticated directory endpoints. Defaults to false. */
|
|
14
14
|
namespaceDirectory?: boolean;
|
|
15
|
+
/** Inspect all visible open/closed issues in the observed repositories. Defaults to false. */
|
|
16
|
+
includeIssues?: boolean;
|
|
15
17
|
}
|
|
16
18
|
export interface IForgeInventoryScan {
|
|
17
19
|
report: plugins.fossInterfaces.data.IForgeInventoryReport;
|
|
18
20
|
repositories: plugins.fossInterfaces.data.IForgeInventoryRepository[];
|
|
19
21
|
namespaces: plugins.fossInterfaces.data.IForgeInventoryNamespace[];
|
|
22
|
+
issues: plugins.fossInterfaces.data.IForgeInventoryIssue[];
|
|
20
23
|
metrics: IForgeInventoryMetrics;
|
|
21
24
|
versionInspection: TForgeInventoryVersionInspection | {
|
|
22
25
|
status: 'notInspected';
|
|
@@ -30,4 +33,5 @@ export declare class ForgeInventoryScanner {
|
|
|
30
33
|
scan(optionsArg?: IForgeInventoryScanOptions): Promise<IForgeInventoryScan>;
|
|
31
34
|
private capability;
|
|
32
35
|
private collect;
|
|
36
|
+
private collectIssues;
|
|
33
37
|
}
|
|
@@ -26,42 +26,56 @@ export class ForgeInventoryScanner {
|
|
|
26
26
|
throw new ForgeInventoryError('invalid-scan-limits');
|
|
27
27
|
}
|
|
28
28
|
if ((optionsArg.inspectVersion !== undefined && typeof optionsArg.inspectVersion !== 'boolean') ||
|
|
29
|
-
(optionsArg.namespaceDirectory !== undefined && typeof optionsArg.namespaceDirectory !== 'boolean')
|
|
29
|
+
(optionsArg.namespaceDirectory !== undefined && typeof optionsArg.namespaceDirectory !== 'boolean') ||
|
|
30
|
+
(optionsArg.includeIssues !== undefined && typeof optionsArg.includeIssues !== 'boolean')) {
|
|
30
31
|
throw new ForgeInventoryError('invalid-scan-options');
|
|
31
32
|
}
|
|
33
|
+
const { signal } = optionsArg;
|
|
34
|
+
const inspectVersion = optionsArg.inspectVersion ?? false;
|
|
35
|
+
const namespaceDirectory = optionsArg.namespaceDirectory ?? false;
|
|
36
|
+
const includeIssues = optionsArg.includeIssues ?? false;
|
|
32
37
|
if (this.#running)
|
|
33
38
|
throw new ForgeInventoryError('scan-already-running');
|
|
34
39
|
this.#running = true;
|
|
35
40
|
const controller = new AbortController();
|
|
36
41
|
const abort = () => controller.abort();
|
|
37
|
-
if (
|
|
42
|
+
if (signal?.aborted)
|
|
38
43
|
controller.abort();
|
|
39
|
-
|
|
44
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
40
45
|
const timeout = setTimeout(abort, timeoutMs);
|
|
41
46
|
const before = this.#adapter.metrics;
|
|
42
47
|
const deadline = Date.now() + timeoutMs;
|
|
43
48
|
const remainingBytes = () => maxScanResponseBytes - (this.#adapter.metrics.responseBytes - before.responseBytes);
|
|
44
49
|
const collections = Object.fromEntries(Object.keys(entityClasses).map((key) => [key, {
|
|
45
50
|
capability: { status: 'unverified', reason: 'No inventory reader has inspected this entity class.' },
|
|
46
|
-
result: { status: 'notInspected', reason: '
|
|
51
|
+
result: { status: 'notInspected', reason: 'No inventory reader has inspected this entity class in this scan.' },
|
|
47
52
|
}]));
|
|
48
53
|
try {
|
|
49
54
|
if (Date.now() >= deadline)
|
|
50
55
|
controller.abort();
|
|
51
|
-
const versionInspection =
|
|
56
|
+
const versionInspection = inspectVersion
|
|
52
57
|
? await this.#adapter.inspectVersion({ signal: controller.signal, maxResponseBytes: remainingBytes() })
|
|
53
58
|
: { status: 'notInspected', reason: 'Server version inspection was not requested.' };
|
|
54
|
-
const namespaces = await this.collect((request) =>
|
|
59
|
+
const namespaces = await this.collect((request) => namespaceDirectory
|
|
55
60
|
? this.#adapter.listNamespaceDirectory(request) : this.#adapter.listNamespaces(request), maxItems, controller.signal, deadline, remainingBytes);
|
|
56
61
|
const repositories = await this.collect((request) => this.#adapter.listRepositories(request), maxItems, controller.signal, deadline, remainingBytes);
|
|
62
|
+
const issues = includeIssues
|
|
63
|
+
? await this.collectIssues(repositories, maxItems, controller.signal, deadline, remainingBytes) : null;
|
|
64
|
+
if (issues)
|
|
65
|
+
collections.issues = {
|
|
66
|
+
capability: repositories.items.length === 0
|
|
67
|
+
? { status: 'unverified', reason: 'No repository issue endpoint was inspected.' }
|
|
68
|
+
: this.capability(issues, ['Only API-visible issue metadata is enumerated.', 'Comments, associations, attachments and historical import fidelity are not established.']),
|
|
69
|
+
result: issues.result,
|
|
70
|
+
};
|
|
57
71
|
const namespaceLimitation = 'Only organization/group namespaces were inspected; personal namespaces and full private namespace coverage remain uninspected.';
|
|
58
72
|
collections.namespaces = {
|
|
59
73
|
capability: this.capability(namespaces, [
|
|
60
|
-
...(
|
|
74
|
+
...(namespaceDirectory ? [] : [namespaceLimitation]),
|
|
61
75
|
'Live API visibility does not prove administrator completeness.',
|
|
62
76
|
'Namespace metadata does not establish user identity or permission inventory.',
|
|
63
77
|
]),
|
|
64
|
-
result: !
|
|
78
|
+
result: !namespaceDirectory && namespaces.result.status === 'enumerated' ? {
|
|
65
79
|
status: 'incomplete', observation: namespaces.result.observation,
|
|
66
80
|
observedCount: namespaces.result.count, reason: namespaceLimitation,
|
|
67
81
|
} : namespaces.result,
|
|
@@ -83,13 +97,13 @@ export class ForgeInventoryScanner {
|
|
|
83
97
|
schemaVersion: 1,
|
|
84
98
|
instance: { ...this.#adapter.instance, version: versionInspection.status === 'observed' ? versionInspection.version : null },
|
|
85
99
|
scope: { kind: 'instance' }, collections,
|
|
86
|
-
additionalCollections:
|
|
100
|
+
additionalCollections: namespaceDirectory ? [] : [{
|
|
87
101
|
name: this.#adapter.instance.kind === 'gitea' ? 'gitea.organizations' : 'gitlab.groups',
|
|
88
102
|
capability: this.capability(namespaces, ['Endpoint visibility and live pagination limits apply.']),
|
|
89
103
|
result: namespaces.result,
|
|
90
104
|
}],
|
|
91
105
|
},
|
|
92
|
-
repositories: repositories.items, namespaces: namespaces.items, versionInspection,
|
|
106
|
+
repositories: repositories.items, namespaces: namespaces.items, issues: issues?.items ?? [], versionInspection,
|
|
93
107
|
metrics: {
|
|
94
108
|
requests: after.requests - before.requests,
|
|
95
109
|
responseBytes: after.responseBytes - before.responseBytes,
|
|
@@ -100,7 +114,7 @@ export class ForgeInventoryScanner {
|
|
|
100
114
|
finally {
|
|
101
115
|
controller.abort();
|
|
102
116
|
clearTimeout(timeout);
|
|
103
|
-
|
|
117
|
+
signal?.removeEventListener('abort', abort);
|
|
104
118
|
this.#running = false;
|
|
105
119
|
}
|
|
106
120
|
}
|
|
@@ -109,10 +123,9 @@ export class ForgeInventoryScanner {
|
|
|
109
123
|
? { status: 'available', limitations }
|
|
110
124
|
: { status: 'unverified', reason: 'No successful enumeration or entity observation established this reader capability.' };
|
|
111
125
|
}
|
|
112
|
-
async collect(read, maxItems, signal, deadline, remainingBytes) {
|
|
126
|
+
async collect(read, maxItems, signal, deadline, remainingBytes, identities = new Set()) {
|
|
113
127
|
const startedAt = new Date().toISOString();
|
|
114
128
|
const items = [];
|
|
115
|
-
const identities = new Set();
|
|
116
129
|
let cursor;
|
|
117
130
|
const incomplete = (reason) => ({ items, result: {
|
|
118
131
|
status: 'incomplete', observation: this.#adapter.observation(startedAt), observedCount: String(items.length), reason,
|
|
@@ -151,5 +164,30 @@ export class ForgeInventoryScanner {
|
|
|
151
164
|
cursor = page.pagination.cursor;
|
|
152
165
|
}
|
|
153
166
|
}
|
|
167
|
+
async collectIssues(repositories, maxItems, signal, deadline, remainingBytes) {
|
|
168
|
+
const startedAt = new Date().toISOString();
|
|
169
|
+
const items = [];
|
|
170
|
+
const identities = new Set();
|
|
171
|
+
const incomplete = (reason) => ({
|
|
172
|
+
items, result: { status: 'incomplete', observation: this.#adapter.observation(startedAt), observedCount: String(items.length), reason },
|
|
173
|
+
});
|
|
174
|
+
for (const repository of repositories.items) {
|
|
175
|
+
const collection = await this.collect((request) => this.#adapter.listIssues({
|
|
176
|
+
kind: 'repository', identity: repository.identity, location: repository.location,
|
|
177
|
+
}, request), maxItems - items.length, signal, deadline, remainingBytes, identities);
|
|
178
|
+
for (const item of collection.items)
|
|
179
|
+
items.push(item);
|
|
180
|
+
if (collection.result.status !== 'enumerated') {
|
|
181
|
+
return incomplete('reason' in collection.result ? collection.result.reason : 'Repository issue scan did not complete.');
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (signal.aborted || Date.now() >= deadline)
|
|
185
|
+
return incomplete('Scan aborted or deadline reached.');
|
|
186
|
+
if (repositories.result.status !== 'enumerated')
|
|
187
|
+
return incomplete('The repository inventory was incomplete.');
|
|
188
|
+
return {
|
|
189
|
+
items, result: { status: 'enumerated', observation: this.#adapter.observation(startedAt), count: String(items.length), sizeBytes: unknownSize('Issue storage bytes were not measured.') },
|
|
190
|
+
};
|
|
191
|
+
}
|
|
154
192
|
}
|
|
155
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mb3JnZWludmVudG9yeXNjYW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmZvcmdlaW52ZW50b3J5c2Nhbm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV6RixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUF3QjdELE1BQU0sYUFBYSxHQUFHO0lBQ3BCLFVBQVUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUk7SUFDakYsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSTtJQUMzRixNQUFNLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxJQUFJO0lBQzFGLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUk7SUFDaEYsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSTtJQUNoRyxRQUFRLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUk7SUFDM0YsS0FBSyxFQUFFLElBQUksRUFB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
|
|
193
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mb3JnZWludmVudG9yeXNjYW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmZvcmdlaW52ZW50b3J5c2Nhbm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV6RixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFnQzdELE1BQU0sYUFBYSxHQUFHO0lBQ3BCLFVBQVUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUk7SUFDakYsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSTtJQUMzRixNQUFNLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxJQUFJO0lBQzFGLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUk7SUFDaEYsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSTtJQUNoRyxRQUFRLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUk7SUFDM0YsS0FBSyxFQUFFLElBQUksRUFB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
|
|
@@ -7,6 +7,8 @@ export declare const record: (value: unknown) => Record<string, unknown>;
|
|
|
7
7
|
export declare const decimal: (value: unknown) => string;
|
|
8
8
|
export declare const optionalString: (value: unknown) => string | null;
|
|
9
9
|
export declare const optionalBoolean: (value: unknown) => boolean | null;
|
|
10
|
+
/** Keep provider timestamp precision and offset; reject invalid calendar dates. */
|
|
11
|
+
export declare const timestamp: (value: unknown) => string | null;
|
|
10
12
|
export declare const segments: (value: unknown) => string[];
|
|
11
13
|
export declare const visibility: (value: unknown) => plugins.fossInterfaces.data.TForgeInventoryVisibility | null;
|
|
12
14
|
export declare const httpUrl: (value: unknown) => string | null;
|
|
@@ -35,6 +35,20 @@ export const optionalBoolean = (value) => {
|
|
|
35
35
|
throw new ForgeInventoryError('invalid-boolean');
|
|
36
36
|
return value;
|
|
37
37
|
};
|
|
38
|
+
/** Keep provider timestamp precision and offset; reject invalid calendar dates. */
|
|
39
|
+
export const timestamp = (value) => {
|
|
40
|
+
if (value === undefined || value === null)
|
|
41
|
+
return null;
|
|
42
|
+
if (typeof value !== 'string')
|
|
43
|
+
throw new ForgeInventoryError('invalid-timestamp');
|
|
44
|
+
const match = value.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/);
|
|
45
|
+
if (!match || !Number.isFinite(Date.parse(value)) || Number(match[2]) < 1 || Number(match[2]) > 12 ||
|
|
46
|
+
Number(match[3]) < 1 || Number(match[3]) > new Date(Date.UTC(Number(match[1]), Number(match[2]), 0)).getUTCDate() ||
|
|
47
|
+
Number(match[4]) > 23 || Number(match[5]) > 59 || Number(match[6]) > 59) {
|
|
48
|
+
throw new ForgeInventoryError('invalid-timestamp');
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
};
|
|
38
52
|
export const segments = (value) => {
|
|
39
53
|
const path = optionalString(value);
|
|
40
54
|
if (!path || path.split('/').some((part) => !part || part === '.' || part === '..' || /[\\\u0000-\u001f\u007f]/.test(part))) {
|
|
@@ -90,4 +104,4 @@ export const gitlabSize = (statistics) => {
|
|
|
90
104
|
return unknownSize('Repository size was not exposed.');
|
|
91
105
|
return { status: 'measured', value: decimal(size), accuracy: 'estimate' };
|
|
92
106
|
};
|
|
93
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZ2VpbnZlbnRvcnkudmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2ZvcmdlaW52ZW50b3J5LnZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLG1CQUFvQixTQUFRLEtBQUs7SUFDNUMsWUFBNEIsSUFBWTtRQUN0QywwRUFBMEU7UUFDMUUsS0FBSyxDQUFDLG9CQUFvQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRlIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUd0QyxJQUFJLENBQUMsSUFBSSxHQUFHLHFCQUFxQixDQUFDO0lBQ3BDLENBQUM7Q0FDRjtBQUVELE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQWMsRUFBMkIsRUFBRTtJQUNoRSxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDaEUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUNELE9BQU8sS0FBZ0MsQ0FBQztBQUMxQyxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxLQUFjLEVBQVUsRUFBRTtJQUNoRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMzRSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksd0JBQXdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxJQUFJLG1CQUFtQixDQUFDLDhCQUE4QixDQUFDLENBQUM7QUFDaEUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBYyxFQUFpQixFQUFFO0lBQzlELElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkUsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDL0UsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFjLEVBQWtCLEVBQUU7SUFDaEUsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkQsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDakYsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRixtRkFBbUY7QUFDbkYsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBYyxFQUFpQixFQUFFO0lBQ3pELElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsb0ZBQW9GLENBQUMsQ0FBQztJQUNoSCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRTtRQUNoRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUU7UUFDakgsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUMxRSxNQUFNLElBQUksbUJBQW1CLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxLQUFjLEVBQVksRUFBRTtJQUNuRCxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLHlCQUF5QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUgsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFDRCxrRkFBa0Y7SUFDbEYsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLEtBQWMsRUFBZ0UsRUFBRTtJQUN6RyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLElBQUk7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2RCxJQUFJLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLFVBQVUsSUFBSSxLQUFLLEtBQUssU0FBUztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3BGLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3RELENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQWMsRUFBaUIsRUFBRTtJQUN2RCxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsSUFBSSxJQUFJLEtBQUssSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9CLElBQUksQ0FBQztRQUNILE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzdILE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQztJQUNsQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDbkQsQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQWMsRUFBaUIsRUFBRTtJQUN0RCxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsSUFBSSxJQUFJLEtBQUssSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9CLDJFQUEyRTtJQUMzRSxJQUFJLDJDQUEyQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN4RSxJQUFJLENBQUM7UUFDSCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixJQUFJLEdBQUcsQ0FBQyxRQUFRLEtBQUssTUFBTSxJQUFJLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6RixPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7SUFDbEIsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2xELENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFjLEVBQXVELEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBRXBJLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQW1CLEVBQXVELEVBQUU7SUFDckcsSUFBSSxVQUFVLEtBQUssU0FBUyxJQUFJLFVBQVUsS0FBSyxJQUFJO1FBQUUsT0FBTyxXQUFXLENBQUMseUNBQXlDLENBQUMsQ0FBQztJQUNuSCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsZUFBZSxDQUFDO0lBQ2hELElBQUksSUFBSSxLQUFLLFNBQVMsSUFBSSxJQUFJLEtBQUssSUFBSTtRQUFFLE9BQU8sV0FBVyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDaEcsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFDNUUsQ0FBQyxDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foss.global/codefeed",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The @foss.global/codefeed module generates commit/activity feeds from forge providers including Gitea and GitManager.",
|
|
6
6
|
"exports": {
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"@types/node": "^26.4.1"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@foss.global/gitmanager": "^1.
|
|
22
|
-
"@foss.global/interfaces": "^0.
|
|
21
|
+
"@foss.global/gitmanager": "^1.7.1",
|
|
22
|
+
"@foss.global/interfaces": "^0.13.0",
|
|
23
23
|
"@push.rocks/lik": "^6.2.2",
|
|
24
24
|
"@push.rocks/qenv": "^6.1.3",
|
|
25
25
|
"@push.rocks/smartnpm": "^2.0.6",
|
package/readme.md
CHANGED
|
@@ -16,7 +16,7 @@ Requires Node.js 18+ (global fetch/Request/Response) and ESM.
|
|
|
16
16
|
|
|
17
17
|
## Read-only forge inventory
|
|
18
18
|
|
|
19
|
-
`ForgeInventoryScanner` observes repositories and namespaces on a Gitea or GitLab instance, with optional server version discovery and authenticated namespace directories. It returns operator-facing DTOs from `@foss.global/interfaces`, distinct observed counts, available Git size estimates, and request/response-byte/rate-limit metrics. The scanner uses its own bounded GET transport. It does not mutate the forge or persist runtime data.
|
|
19
|
+
`ForgeInventoryScanner` observes repositories and namespaces on a Gitea or GitLab instance, with optional issue inventory, server version discovery and authenticated namespace directories. It returns operator-facing DTOs from `@foss.global/interfaces`, distinct observed counts, available Git size estimates, and request/response-byte/rate-limit metrics. The scanner uses its own bounded GET transport. It does not mutate the forge or persist runtime data.
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
import { ForgeInventoryScanner } from '@foss.global/codefeed';
|
|
@@ -37,6 +37,7 @@ const inventory = await scanner.scan({
|
|
|
37
37
|
timeoutMs: 60_000, // all collection and version requests together
|
|
38
38
|
maxScanResponseBytes: 64 * 1024 * 1024,
|
|
39
39
|
inspectVersion: true, // optional fresh version probe; default false
|
|
40
|
+
includeIssues: true, // optional issue metadata scan; default false
|
|
40
41
|
// namespaceDirectory: true, // requires a token; Gitea requires admin access
|
|
41
42
|
// signal: abortController.signal,
|
|
42
43
|
});
|
|
@@ -56,15 +57,23 @@ The scanner marks observations `publicOnly` without a token and `callerVisible`
|
|
|
56
57
|
|
|
57
58
|
Every canonical entity class is present in the report. By default, the canonical `namespaces` result remains `incomplete`, including after organization/group endpoints are exhausted, because personal namespaces and full private namespace coverage are not established. Endpoint counts appear separately as `gitea.organizations` or `gitlab.groups` in `additionalCollections`.
|
|
58
59
|
|
|
59
|
-
Set `namespaceDirectory: true` to include personal namespaces. Gitea enumerates `/admin/orgs` followed by `/admin/users`; GitLab enumerates `/namespaces` without owner or top-level filters. A configured token is required. Access failures remain explicit and never fall back to public organization/group listings. Gitea's two directory phases share one `maxPages` limit, including empty-page probes. Successful completion produces an `enumerated` canonical namespace result within `callerVisible` access; `additionalCollections` is empty in this mode. It does not prove instance-wide administrator coverage, a frozen export, complete users, or permissions. Only namespace metadata is retained from the directory responses; user email/login-source and billing fields are discarded.
|
|
60
|
+
Set `namespaceDirectory: true` to include personal namespaces. Gitea enumerates `/admin/orgs` followed by `/admin/users`; GitLab enumerates `/namespaces` without owner or top-level filters. A configured token is required. Access failures remain explicit and never fall back to public organization/group listings. Gitea's two directory phases share one `maxPages` limit, including empty-page probes. Successful completion produces an `enumerated` canonical namespace result within `callerVisible` access; `additionalCollections` is empty in this mode. It does not prove instance-wide administrator coverage, a frozen export, complete users, or permissions. Only namespace metadata is retained from the directory responses; user email/login-source and billing fields are discarded. Entity classes without an enabled reader remain `notInspected` with unverified capabilities.
|
|
60
61
|
|
|
61
62
|
Set `inspectVersion: true` to probe `/api/v1/version` on Gitea or `/api/v4/version` on GitLab before collection requests. `versionInspection` records `observed` with its timestamped observation, `unverified` with a safe reason, or `notInspected` when disabled. `report.instance.version` is set only after a successful probe in that scan. Denied or malformed responses never reuse an earlier version. A failed probe allows collection reads to proceed while the shared deadline and byte budget permit. The reported version is provider metadata, not proof that a real server version has been qualified.
|
|
62
63
|
|
|
64
|
+
Set `includeIssues: true` to read all visible open and closed issues in every observed repository. Gitea uses `state=all&type=issues` and rejects unexpected pull-request records. GitLab uses the stable project ID with `state=all&scope=all`, without author, confidentiality or issue-type filters. The returned `issues` array uses the shared `IForgeInventoryIssue` contract: stable row ID, separate repository-local number, repository identity, title/body, state, confidentiality, provider issue type, reported author and original timestamp precision/offset. Empty body text remains empty. Missing metadata is unknown; Gitea deleted/built-in authors remain unresolved. This is an observation of reported authors, not proof of original attribution for previously imported issues.
|
|
65
|
+
|
|
66
|
+
Issue pagination is bounded per repository by `maxPages`. The issue `maxItems` limit and duplicate detection span all observed repositories; deadline and response-byte limits span the entire scan. Gitea checks the current repository ID at its mutable path before each issue page, including empty pages, and also validates each issue's repository ID. These identity probes count in metrics and consume the same scan/caller byte budget. GitLab verifies each issue's returned project ID. A denied issue page, changed repository identity, incomplete repository enumeration or reached limit leaves issue inventory incomplete. No deletion or missing-issue inference follows from a partial scan. Comments, labels, milestones, assignees, attachments and history remain uninspected; outbound issue creation/update is not implemented by this scanner. Scan choices and the cancellation signal are captured at the beginning of each scan.
|
|
67
|
+
|
|
68
|
+
For one repository, call `adapter.listIssues({ kind: 'repository', identity: repository.identity, location: repository.location }, { cursor?, signal?, maxResponseBytes? })` using a previously observed repository. Its cursor is additionally bound to that exact repository identity and location. The response carries repository scope; a foreign, unresolved or malformed repository identity is rejected before network access.
|
|
69
|
+
|
|
63
70
|
Provider IDs remain namespaced decimal strings, separate from mutable paths. Gitea organizations and repository owners share `gitea.user.id`; GitLab groups use `gitlab.group.id`, while a personal project namespace uses `gitlab.namespace.id` rather than a user ID. Nested paths preserve literal hyphens. Numeric JSON IDs or sizes outside JavaScript's safe integer range fail closed; canonical decimal strings retain their precision. Missing metadata remains unknown. Gitea's rounded `size` field is not used as a separate Git byte measurement. Exposed GitLab repository statistics are estimates, and their sum is available only when every observed repository has a measurement. Neither quantity estimates bytes for a Git push.
|
|
64
71
|
|
|
72
|
+
The adapter's read-only `baseUrl` property exposes the validated, normalized HTTPS instance root, including its deployment subpath and without a trailing slash. Connection management can retain this value without copying URL validation or exposing the private token. It identifies a location, not an instance identity or verified server.
|
|
73
|
+
|
|
65
74
|
For incremental consumption, `ForgeInventoryAdapter.listRepositories({ cursor?, signal?, maxResponseBytes? })`, `.listNamespaces(...)` and `.listNamespaceDirectory(...)` return shared inventory pages. A `more` result contains a signed cursor bound to that adapter object, collection, directory phase and fixed query/page policy. Reuse it only with the same adapter; it is disposable process-local state, not a durable checkpoint. `exhausted` describes the selected endpoint or completed directory within the recorded visibility. Page methods throw `ForgeInventoryError` for request and payload failures, while malformed continuation metadata returns an `incomplete` page retaining its validated items. The scanner converts those failures into an incomplete collection report. `.inspectVersion({ signal?, maxResponseBytes? })` returns a fresh observed/unverified result separately; it does not mutate the adapter's `instance` or page metadata, whose version remains unknown.
|
|
66
75
|
|
|
67
|
-
The implementation has synthetic protocol fixtures based on the [Gitea 1.24.7 API schema](https://raw.githubusercontent.com/go-gitea/gitea/v1.24.7/templates/swagger/v1_json.tmpl), [Gitea pagination documentation](https://docs.gitea.com/development/api-usage/#pagination), and the GitLab [projects](https://docs.gitlab.com/api/projects/), [groups](https://docs.gitlab.com/api/groups/), [namespaces](https://docs.gitlab.com/api/namespaces/), [metadata](https://docs.gitlab.com/api/metadata/) and [pagination](https://docs.gitlab.com/api/rest/#pagination) contracts. Real server/version qualification, native inventory, administrator completeness, full ref/object enumeration, collaboration, packages, collision analysis and migration manifests remain pending.
|
|
76
|
+
The implementation has synthetic protocol fixtures based on the [Gitea 1.24.7 API schema](https://raw.githubusercontent.com/go-gitea/gitea/v1.24.7/templates/swagger/v1_json.tmpl), [Gitea pagination documentation](https://docs.gitea.com/development/api-usage/#pagination), and the GitLab [projects](https://docs.gitlab.com/api/projects/), [groups](https://docs.gitlab.com/api/groups/), [namespaces](https://docs.gitlab.com/api/namespaces/), [metadata](https://docs.gitlab.com/api/metadata/), [issues](https://docs.gitlab.com/api/issues/) and [pagination](https://docs.gitlab.com/api/rest/#pagination) contracts. Real server/version qualification, native inventory, administrator completeness, full ref/object enumeration, collaboration, packages, collision analysis and migration manifests remain pending.
|
|
68
77
|
|
|
69
78
|
## Quick Start
|
|
70
79
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -33,10 +33,13 @@ export type TForgeInventoryVersionInspection =
|
|
|
33
33
|
| { status: 'observed'; version: string; observation: plugins.fossInterfaces.data.IForgeInventoryObservation }
|
|
34
34
|
| { status: 'unverified'; reason: string; observation: plugins.fossInterfaces.data.IForgeInventoryObservation };
|
|
35
35
|
|
|
36
|
-
type
|
|
36
|
+
type TRepositoryScope = Extract<plugins.fossInterfaces.data.TForgeInventoryScope, { kind: 'repository' }>;
|
|
37
|
+
type TIdentifiedRepositoryScope = TRepositoryScope & { identity: Extract<plugins.fossInterfaces.data.TForgeInventoryIdentity, { status: 'identified' }> };
|
|
38
|
+
type TCollection = 'repositories' | 'namespaces' | 'namespaceDirectory' | 'issues';
|
|
37
39
|
interface IContinuation {
|
|
38
|
-
version:
|
|
40
|
+
version: 3;
|
|
39
41
|
collection: TCollection;
|
|
42
|
+
repositoryKey: string | null;
|
|
40
43
|
/** Endpoint page, reset when a directory moves from organizations to users. */
|
|
41
44
|
page: number;
|
|
42
45
|
/** Completed requests across every endpoint in this collection. */
|
|
@@ -60,7 +63,7 @@ export class ForgeInventoryAdapter {
|
|
|
60
63
|
}
|
|
61
64
|
this.#options = {
|
|
62
65
|
...optionsArg,
|
|
63
|
-
baseUrl: baseUrl.replace(
|
|
66
|
+
baseUrl: baseUrl.replace(/\/+$/, ''),
|
|
64
67
|
pageSize: optionsArg.pageSize ?? 50,
|
|
65
68
|
maxPages: optionsArg.maxPages ?? 1000,
|
|
66
69
|
requestTimeoutMs: optionsArg.requestTimeoutMs ?? 30_000,
|
|
@@ -78,6 +81,9 @@ export class ForgeInventoryAdapter {
|
|
|
78
81
|
return { instanceId: this.#options.instanceId, kind: this.#options.kind, version: null };
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
/** Validated, normalized instance root; contains no credentials or API suffix. */
|
|
85
|
+
public get baseUrl(): string { return this.#options.baseUrl; }
|
|
86
|
+
|
|
81
87
|
public get metrics(): IForgeInventoryMetrics { return { ...this.#metrics }; }
|
|
82
88
|
|
|
83
89
|
public observation(startedAt: string): plugins.fossInterfaces.data.IForgeInventoryObservation {
|
|
@@ -102,6 +108,12 @@ export class ForgeInventoryAdapter {
|
|
|
102
108
|
return this.page('namespaceDirectory', (item, state) => this.directoryNamespace(item, state), requestArg);
|
|
103
109
|
}
|
|
104
110
|
|
|
111
|
+
/** All visible open/closed issues in one stable repository, excluding Gitea pull requests. */
|
|
112
|
+
public listIssues(scopeArg: TRepositoryScope, requestArg: IForgeInventoryRequest = {}): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<plugins.fossInterfaces.data.IForgeInventoryIssue>> {
|
|
113
|
+
const scope = this.repositoryScope(scopeArg);
|
|
114
|
+
return this.page('issues', (item) => this.issue(item, scope), requestArg, scope);
|
|
115
|
+
}
|
|
116
|
+
|
|
105
117
|
/** A fresh, bounded observation; failures never retain a previously observed version. */
|
|
106
118
|
public async inspectVersion(requestArg: Omit<IForgeInventoryRequest, 'cursor'> = {}): Promise<TForgeInventoryVersionInspection> {
|
|
107
119
|
const startedAt = new Date().toISOString();
|
|
@@ -127,6 +139,59 @@ export class ForgeInventoryAdapter {
|
|
|
127
139
|
return { status: 'identified', ref: { instanceId: this.#options.instanceId, idNamespace, objectId, parentObjectId: null } };
|
|
128
140
|
}
|
|
129
141
|
|
|
142
|
+
private repositoryScope(scopeArg: TRepositoryScope): TIdentifiedRepositoryScope {
|
|
143
|
+
const expectedNamespace = this.#options.kind === 'gitea' ? 'gitea.repository.id' : 'gitlab.project.id';
|
|
144
|
+
if (scopeArg?.kind !== 'repository' || scopeArg.identity?.status !== 'identified' ||
|
|
145
|
+
scopeArg.identity.ref.instanceId !== this.#options.instanceId || scopeArg.identity.ref.idNamespace !== expectedNamespace ||
|
|
146
|
+
scopeArg.identity.ref.parentObjectId !== null || typeof scopeArg.identity.ref.objectId !== 'string' ||
|
|
147
|
+
validation.decimal(scopeArg.identity.ref.objectId) === '0' || !Array.isArray(scopeArg.location?.pathSegments) ||
|
|
148
|
+
scopeArg.location.pathSegments.length < 2 || (this.#options.kind === 'gitea' && scopeArg.location.pathSegments.length !== 2)) {
|
|
149
|
+
throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
150
|
+
}
|
|
151
|
+
const pathSegments = scopeArg.location.pathSegments.map((segment) => {
|
|
152
|
+
if (validation.segments(segment).length !== 1) throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
153
|
+
return segment;
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
kind: 'repository', identity: { status: 'identified', ref: {
|
|
157
|
+
instanceId: this.#options.instanceId, idNamespace: expectedNamespace, objectId: scopeArg.identity.ref.objectId, parentObjectId: null,
|
|
158
|
+
} },
|
|
159
|
+
location: { pathSegments, webUrl: validation.httpUrl(scopeArg.location.webUrl) },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private issue(itemArg: unknown, scope: TIdentifiedRepositoryScope): plugins.fossInterfaces.data.IForgeInventoryIssue {
|
|
164
|
+
const item = validation.record(itemArg);
|
|
165
|
+
const gitea = this.#options.kind === 'gitea';
|
|
166
|
+
if (gitea && item.pull_request !== undefined && item.pull_request !== null) throw new validation.ForgeInventoryError('unexpected-pull-request');
|
|
167
|
+
const repositoryId = validation.decimal(gitea ? validation.record(item.repository).id : item.project_id);
|
|
168
|
+
if (repositoryId !== scope.identity.ref.objectId) throw new validation.ForgeInventoryError('issue-repository-mismatch');
|
|
169
|
+
const number = validation.decimal(gitea ? item.number : item.iid);
|
|
170
|
+
if (number === '0' || typeof item.title !== 'string' || !item.title) throw new validation.ForgeInventoryError('invalid-issue');
|
|
171
|
+
const body = gitea ? item.body : item.description;
|
|
172
|
+
if (body !== undefined && body !== null && typeof body !== 'string') throw new validation.ForgeInventoryError('invalid-issue-body');
|
|
173
|
+
const state = item.state === (gitea ? 'open' : 'opened') ? 'open' : item.state === 'closed' ? 'closed' : null;
|
|
174
|
+
if (state === null && item.state !== undefined && item.state !== null) throw new validation.ForgeInventoryError('invalid-issue-state');
|
|
175
|
+
const actor = gitea ? item.user : item.author;
|
|
176
|
+
let author: plugins.fossInterfaces.data.TForgeInventoryIdentity = { status: 'unresolved', reason: 'Provider author identity was not exposed.' };
|
|
177
|
+
if (actor !== undefined && actor !== null) {
|
|
178
|
+
const actorId = validation.record(actor).id;
|
|
179
|
+
if (gitea && [-1, -2, '-1', '-2'].includes(actorId as number | string)) {
|
|
180
|
+
author = { status: 'unresolved', reason: 'Gitea reports a deleted or built-in author without a regular user identity.' };
|
|
181
|
+
} else if (actorId !== undefined && actorId !== null) {
|
|
182
|
+
author = this.identity(gitea ? 'gitea.user.id' : 'gitlab.user.id', actorId);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
identity: this.identity(gitea ? 'gitea.issue.id' : 'gitlab.issue.id', item.id), repository: scope.identity,
|
|
187
|
+
location: { pathSegments: [...scope.location.pathSegments, ...(gitea ? [] : ['-']), 'issues', number], webUrl: validation.httpUrl(gitea ? item.html_url : item.web_url) },
|
|
188
|
+
number, title: item.title, body: body ?? null, state,
|
|
189
|
+
providerType: gitea ? 'issue' : validation.optionalString(item.issue_type),
|
|
190
|
+
confidential: gitea ? null : validation.optionalBoolean(item.confidential), author,
|
|
191
|
+
createdAt: validation.timestamp(item.created_at), updatedAt: validation.timestamp(item.updated_at), closedAt: validation.timestamp(item.closed_at),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
130
195
|
private namespace(itemArg: unknown): plugins.fossInterfaces.data.IForgeInventoryNamespace {
|
|
131
196
|
const item = validation.record(itemArg);
|
|
132
197
|
if (this.#options.kind === 'gitea') {
|
|
@@ -204,8 +269,19 @@ export class ForgeInventoryAdapter {
|
|
|
204
269
|
};
|
|
205
270
|
}
|
|
206
271
|
|
|
207
|
-
private url(state: IContinuation): URL {
|
|
272
|
+
private url(state: IContinuation, scope?: TIdentifiedRepositoryScope): URL {
|
|
208
273
|
const gitea = this.#options.kind === 'gitea';
|
|
274
|
+
if (state.collection === 'issues') {
|
|
275
|
+
if (!scope) throw new validation.ForgeInventoryError('invalid-repository-scope');
|
|
276
|
+
const endpoint = gitea ? `repos/${scope.location.pathSegments.map(encodeURIComponent).join('/')}/issues`
|
|
277
|
+
: `projects/${scope.identity.ref.objectId}/issues`;
|
|
278
|
+
const url = new URL(`${this.#options.baseUrl}/api/${gitea ? 'v1' : 'v4'}/${endpoint}`);
|
|
279
|
+
url.searchParams.set(gitea ? 'limit' : 'per_page', String(this.#options.pageSize));
|
|
280
|
+
url.searchParams.set('page', String(state.page)); url.searchParams.set('state', 'all');
|
|
281
|
+
if (gitea) url.searchParams.set('type', 'issues');
|
|
282
|
+
else { url.searchParams.set('scope', 'all'); url.searchParams.set('order_by', 'created_at'); url.searchParams.set('sort', 'asc'); }
|
|
283
|
+
return url;
|
|
284
|
+
}
|
|
209
285
|
const endpoint = state.collection === 'repositories' ? (gitea ? 'repos/search' : 'projects')
|
|
210
286
|
: state.collection === 'namespaceDirectory' ? (gitea ? `admin/${state.phase === 'organizations' ? 'orgs' : 'users'}` : 'namespaces')
|
|
211
287
|
: (gitea ? 'orgs' : 'groups');
|
|
@@ -235,9 +311,9 @@ export class ForgeInventoryAdapter {
|
|
|
235
311
|
return `${payload}.${plugins.crypto.createHmac('sha256', this.#cursorKey).update(payload).digest('base64url')}`;
|
|
236
312
|
}
|
|
237
313
|
|
|
238
|
-
private continuation(collection: TCollection, cursor?: string): IContinuation {
|
|
314
|
+
private continuation(collection: TCollection, cursor?: string, repositoryKey: string | null = null): IContinuation {
|
|
239
315
|
const directory = collection === 'namespaceDirectory' && this.#options.kind === 'gitea';
|
|
240
|
-
if (cursor === undefined) return { version:
|
|
316
|
+
if (cursor === undefined) return { version: 3, collection, repositoryKey, page: 1, pagesRead: 0, phase: directory ? 'organizations' : null, after: null };
|
|
241
317
|
try {
|
|
242
318
|
if (cursor.length > 2048) throw new Error();
|
|
243
319
|
const [payload, signature, extra] = cursor.split('.');
|
|
@@ -245,7 +321,7 @@ export class ForgeInventoryAdapter {
|
|
|
245
321
|
if (extra !== undefined || !signature || signature.length !== expected.length ||
|
|
246
322
|
!plugins.crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) throw new Error();
|
|
247
323
|
const state = JSON.parse(Buffer.from(payload, 'base64url').toString()) as IContinuation;
|
|
248
|
-
if (state.version !==
|
|
324
|
+
if (state.version !== 3 || state.collection !== collection || state.repositoryKey !== repositoryKey || !Number.isSafeInteger(state.page) ||
|
|
249
325
|
!Number.isSafeInteger(state.pagesRead) || state.pagesRead < 1 || state.pagesRead >= this.#options.maxPages ||
|
|
250
326
|
state.page < 1 || state.page > state.pagesRead + 1 ||
|
|
251
327
|
(directory ? state.phase !== 'organizations' && state.phase !== 'users' : state.phase !== null) ||
|
|
@@ -255,11 +331,27 @@ export class ForgeInventoryAdapter {
|
|
|
255
331
|
} catch { throw new validation.ForgeInventoryError('invalid-cursor'); }
|
|
256
332
|
}
|
|
257
333
|
|
|
258
|
-
private async page<TItem>(collection: TCollection, map: (value: unknown, state: IContinuation) => TItem, requestArg: IForgeInventoryRequest): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<TItem>> {
|
|
259
|
-
const
|
|
334
|
+
private async page<TItem>(collection: TCollection, map: (value: unknown, state: IContinuation) => TItem, requestArg: IForgeInventoryRequest, scope?: TIdentifiedRepositoryScope): Promise<plugins.fossInterfaces.data.IForgeInventoryPage<TItem>> {
|
|
335
|
+
const repositoryKey = scope ? plugins.crypto.createHash('sha256').update(JSON.stringify(scope)).digest('hex') : null;
|
|
336
|
+
const state = this.continuation(collection, requestArg.cursor, repositoryKey);
|
|
260
337
|
const startedAt = new Date().toISOString();
|
|
261
|
-
const url = this.url(state);
|
|
262
|
-
|
|
338
|
+
const url = this.url(state, scope);
|
|
339
|
+
let pageRequest = requestArg;
|
|
340
|
+
if (collection === 'issues' && this.#options.kind === 'gitea' && scope) {
|
|
341
|
+
// Gitea addresses issue lists by mutable path. Check ownership even for empty pages.
|
|
342
|
+
const before = this.#metrics.responseBytes;
|
|
343
|
+
const repositoryUrl = new URL(`${this.#options.baseUrl}/api/v1/repos/${scope.location.pathSegments.map(encodeURIComponent).join('/')}`);
|
|
344
|
+
const probe = await this.request(repositoryUrl, requestArg);
|
|
345
|
+
if (validation.decimal(validation.record(probe.body).id) !== scope.identity.ref.objectId) {
|
|
346
|
+
throw new validation.ForgeInventoryError('repository-identity-changed');
|
|
347
|
+
}
|
|
348
|
+
if (requestArg.maxResponseBytes !== undefined) {
|
|
349
|
+
const remaining = requestArg.maxResponseBytes - (this.#metrics.responseBytes - before);
|
|
350
|
+
if (remaining <= 0) throw new validation.ForgeInventoryError('response-size-limit');
|
|
351
|
+
pageRequest = { ...requestArg, maxResponseBytes: remaining };
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const { body, headers } = await this.request(url, pageRequest);
|
|
263
355
|
let rows: unknown = body;
|
|
264
356
|
if (this.#options.kind === 'gitea' && collection === 'repositories') {
|
|
265
357
|
const envelope = validation.record(body);
|
|
@@ -277,7 +369,7 @@ export class ForgeInventoryAdapter {
|
|
|
277
369
|
} catch {
|
|
278
370
|
pagination = { status: 'incomplete', reason: 'Invalid or inconsistent pagination metadata.' };
|
|
279
371
|
}
|
|
280
|
-
return { schemaVersion: 1, instance: this.instance, scope: { kind: 'instance' }, observation: this.observation(startedAt), items, pagination };
|
|
372
|
+
return { schemaVersion: 1, instance: this.instance, scope: scope ?? { kind: 'instance' }, observation: this.observation(startedAt), items, pagination };
|
|
281
373
|
}
|
|
282
374
|
|
|
283
375
|
private next(state: IContinuation, current: URL, headers: Headers, rows: unknown[]): IContinuation | null {
|
|
@@ -15,16 +15,24 @@ export interface IForgeInventoryScanOptions {
|
|
|
15
15
|
inspectVersion?: boolean;
|
|
16
16
|
/** Include personal namespaces through authenticated directory endpoints. Defaults to false. */
|
|
17
17
|
namespaceDirectory?: boolean;
|
|
18
|
+
/** Inspect all visible open/closed issues in the observed repositories. Defaults to false. */
|
|
19
|
+
includeIssues?: boolean;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export interface IForgeInventoryScan {
|
|
21
23
|
report: plugins.fossInterfaces.data.IForgeInventoryReport;
|
|
22
24
|
repositories: plugins.fossInterfaces.data.IForgeInventoryRepository[];
|
|
23
25
|
namespaces: plugins.fossInterfaces.data.IForgeInventoryNamespace[];
|
|
26
|
+
issues: plugins.fossInterfaces.data.IForgeInventoryIssue[];
|
|
24
27
|
metrics: IForgeInventoryMetrics;
|
|
25
28
|
versionInspection: TForgeInventoryVersionInspection | { status: 'notInspected'; reason: string };
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
interface ICollectedItems<TItem> {
|
|
32
|
+
items: TItem[];
|
|
33
|
+
result: plugins.fossInterfaces.data.TForgeInventoryCollectionResult;
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
const entityClasses = {
|
|
29
37
|
namespaces: true, users: true, teams: true, memberships: true, repositories: true,
|
|
30
38
|
gitRefs: true, gitObjects: true, protectedRefs: true, publicSshKeys: true, deployKeys: true,
|
|
@@ -54,39 +62,52 @@ export class ForgeInventoryScanner {
|
|
|
54
62
|
throw new ForgeInventoryError('invalid-scan-limits');
|
|
55
63
|
}
|
|
56
64
|
if ((optionsArg.inspectVersion !== undefined && typeof optionsArg.inspectVersion !== 'boolean') ||
|
|
57
|
-
(optionsArg.namespaceDirectory !== undefined && typeof optionsArg.namespaceDirectory !== 'boolean')
|
|
65
|
+
(optionsArg.namespaceDirectory !== undefined && typeof optionsArg.namespaceDirectory !== 'boolean') ||
|
|
66
|
+
(optionsArg.includeIssues !== undefined && typeof optionsArg.includeIssues !== 'boolean')) {
|
|
58
67
|
throw new ForgeInventoryError('invalid-scan-options');
|
|
59
68
|
}
|
|
69
|
+
const { signal } = optionsArg;
|
|
70
|
+
const inspectVersion = optionsArg.inspectVersion ?? false;
|
|
71
|
+
const namespaceDirectory = optionsArg.namespaceDirectory ?? false;
|
|
72
|
+
const includeIssues = optionsArg.includeIssues ?? false;
|
|
60
73
|
if (this.#running) throw new ForgeInventoryError('scan-already-running');
|
|
61
74
|
this.#running = true;
|
|
62
75
|
const controller = new AbortController();
|
|
63
76
|
const abort = () => controller.abort();
|
|
64
|
-
if (
|
|
65
|
-
|
|
77
|
+
if (signal?.aborted) controller.abort();
|
|
78
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
66
79
|
const timeout = setTimeout(abort, timeoutMs);
|
|
67
80
|
const before = this.#adapter.metrics;
|
|
68
81
|
const deadline = Date.now() + timeoutMs;
|
|
69
82
|
const remainingBytes = () => maxScanResponseBytes - (this.#adapter.metrics.responseBytes - before.responseBytes);
|
|
70
83
|
const collections = Object.fromEntries(Object.keys(entityClasses).map((key) => [key, {
|
|
71
84
|
capability: { status: 'unverified', reason: 'No inventory reader has inspected this entity class.' },
|
|
72
|
-
result: { status: 'notInspected', reason: '
|
|
85
|
+
result: { status: 'notInspected', reason: 'No inventory reader has inspected this entity class in this scan.' },
|
|
73
86
|
}])) as plugins.fossInterfaces.data.IForgeInventoryReport['collections'];
|
|
74
87
|
try {
|
|
75
88
|
if (Date.now() >= deadline) controller.abort();
|
|
76
|
-
const versionInspection: IForgeInventoryScan['versionInspection'] =
|
|
89
|
+
const versionInspection: IForgeInventoryScan['versionInspection'] = inspectVersion
|
|
77
90
|
? await this.#adapter.inspectVersion({ signal: controller.signal, maxResponseBytes: remainingBytes() })
|
|
78
91
|
: { status: 'notInspected', reason: 'Server version inspection was not requested.' };
|
|
79
|
-
const namespaces = await this.collect((request) =>
|
|
92
|
+
const namespaces = await this.collect((request) => namespaceDirectory
|
|
80
93
|
? this.#adapter.listNamespaceDirectory(request) : this.#adapter.listNamespaces(request), maxItems, controller.signal, deadline, remainingBytes);
|
|
81
94
|
const repositories = await this.collect((request) => this.#adapter.listRepositories(request), maxItems, controller.signal, deadline, remainingBytes);
|
|
95
|
+
const issues = includeIssues
|
|
96
|
+
? await this.collectIssues(repositories, maxItems, controller.signal, deadline, remainingBytes) : null;
|
|
97
|
+
if (issues) collections.issues = {
|
|
98
|
+
capability: repositories.items.length === 0
|
|
99
|
+
? { status: 'unverified', reason: 'No repository issue endpoint was inspected.' }
|
|
100
|
+
: this.capability(issues, ['Only API-visible issue metadata is enumerated.', 'Comments, associations, attachments and historical import fidelity are not established.']),
|
|
101
|
+
result: issues.result,
|
|
102
|
+
};
|
|
82
103
|
const namespaceLimitation = 'Only organization/group namespaces were inspected; personal namespaces and full private namespace coverage remain uninspected.';
|
|
83
104
|
collections.namespaces = {
|
|
84
105
|
capability: this.capability(namespaces, [
|
|
85
|
-
...(
|
|
106
|
+
...(namespaceDirectory ? [] : [namespaceLimitation]),
|
|
86
107
|
'Live API visibility does not prove administrator completeness.',
|
|
87
108
|
'Namespace metadata does not establish user identity or permission inventory.',
|
|
88
109
|
]),
|
|
89
|
-
result: !
|
|
110
|
+
result: !namespaceDirectory && namespaces.result.status === 'enumerated' ? {
|
|
90
111
|
status: 'incomplete', observation: namespaces.result.observation,
|
|
91
112
|
observedCount: namespaces.result.count, reason: namespaceLimitation,
|
|
92
113
|
} : namespaces.result,
|
|
@@ -108,13 +129,13 @@ export class ForgeInventoryScanner {
|
|
|
108
129
|
schemaVersion: 1,
|
|
109
130
|
instance: { ...this.#adapter.instance, version: versionInspection.status === 'observed' ? versionInspection.version : null },
|
|
110
131
|
scope: { kind: 'instance' }, collections,
|
|
111
|
-
additionalCollections:
|
|
132
|
+
additionalCollections: namespaceDirectory ? [] : [{
|
|
112
133
|
name: this.#adapter.instance.kind === 'gitea' ? 'gitea.organizations' : 'gitlab.groups',
|
|
113
134
|
capability: this.capability(namespaces, ['Endpoint visibility and live pagination limits apply.']),
|
|
114
135
|
result: namespaces.result,
|
|
115
136
|
}],
|
|
116
137
|
},
|
|
117
|
-
repositories: repositories.items, namespaces: namespaces.items, versionInspection,
|
|
138
|
+
repositories: repositories.items, namespaces: namespaces.items, issues: issues?.items ?? [], versionInspection,
|
|
118
139
|
metrics: {
|
|
119
140
|
requests: after.requests - before.requests,
|
|
120
141
|
responseBytes: after.responseBytes - before.responseBytes,
|
|
@@ -122,7 +143,7 @@ export class ForgeInventoryScanner {
|
|
|
122
143
|
},
|
|
123
144
|
};
|
|
124
145
|
} finally {
|
|
125
|
-
controller.abort(); clearTimeout(timeout);
|
|
146
|
+
controller.abort(); clearTimeout(timeout); signal?.removeEventListener('abort', abort);
|
|
126
147
|
this.#running = false;
|
|
127
148
|
}
|
|
128
149
|
}
|
|
@@ -138,10 +159,10 @@ export class ForgeInventoryScanner {
|
|
|
138
159
|
private async collect<TItem extends { identity: plugins.fossInterfaces.data.TForgeInventoryIdentity }>(
|
|
139
160
|
read: (request: IForgeInventoryRequest) => Promise<plugins.fossInterfaces.data.IForgeInventoryPage<TItem>>,
|
|
140
161
|
maxItems: number, signal: AbortSignal, deadline: number, remainingBytes: () => number,
|
|
141
|
-
|
|
162
|
+
identities = new Set<string>(),
|
|
163
|
+
): Promise<ICollectedItems<TItem>> {
|
|
142
164
|
const startedAt = new Date().toISOString();
|
|
143
165
|
const items: TItem[] = [];
|
|
144
|
-
const identities = new Set<string>();
|
|
145
166
|
let cursor: string | undefined;
|
|
146
167
|
const incomplete = (reason: string) => ({ items, result: {
|
|
147
168
|
status: 'incomplete' as const, observation: this.#adapter.observation(startedAt), observedCount: String(items.length), reason,
|
|
@@ -169,4 +190,30 @@ export class ForgeInventoryScanner {
|
|
|
169
190
|
cursor = page.pagination.cursor;
|
|
170
191
|
}
|
|
171
192
|
}
|
|
193
|
+
|
|
194
|
+
private async collectIssues(
|
|
195
|
+
repositories: ICollectedItems<plugins.fossInterfaces.data.IForgeInventoryRepository>,
|
|
196
|
+
maxItems: number, signal: AbortSignal, deadline: number, remainingBytes: () => number,
|
|
197
|
+
): Promise<ICollectedItems<plugins.fossInterfaces.data.IForgeInventoryIssue>> {
|
|
198
|
+
const startedAt = new Date().toISOString();
|
|
199
|
+
const items: plugins.fossInterfaces.data.IForgeInventoryIssue[] = [];
|
|
200
|
+
const identities = new Set<string>();
|
|
201
|
+
const incomplete = (reason: string): ICollectedItems<plugins.fossInterfaces.data.IForgeInventoryIssue> => ({
|
|
202
|
+
items, result: { status: 'incomplete', observation: this.#adapter.observation(startedAt), observedCount: String(items.length), reason },
|
|
203
|
+
});
|
|
204
|
+
for (const repository of repositories.items) {
|
|
205
|
+
const collection = await this.collect((request) => this.#adapter.listIssues({
|
|
206
|
+
kind: 'repository', identity: repository.identity, location: repository.location,
|
|
207
|
+
}, request), maxItems - items.length, signal, deadline, remainingBytes, identities);
|
|
208
|
+
for (const item of collection.items) items.push(item);
|
|
209
|
+
if (collection.result.status !== 'enumerated') {
|
|
210
|
+
return incomplete('reason' in collection.result ? collection.result.reason : 'Repository issue scan did not complete.');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (signal.aborted || Date.now() >= deadline) return incomplete('Scan aborted or deadline reached.');
|
|
214
|
+
if (repositories.result.status !== 'enumerated') return incomplete('The repository inventory was incomplete.');
|
|
215
|
+
return {
|
|
216
|
+
items, result: { status: 'enumerated', observation: this.#adapter.observation(startedAt), count: String(items.length), sizeBytes: unknownSize('Issue storage bytes were not measured.') },
|
|
217
|
+
};
|
|
218
|
+
}
|
|
172
219
|
}
|
|
@@ -37,6 +37,19 @@ export const optionalBoolean = (value: unknown): boolean | null => {
|
|
|
37
37
|
return value;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
/** Keep provider timestamp precision and offset; reject invalid calendar dates. */
|
|
41
|
+
export const timestamp = (value: unknown): string | null => {
|
|
42
|
+
if (value === undefined || value === null) return null;
|
|
43
|
+
if (typeof value !== 'string') throw new ForgeInventoryError('invalid-timestamp');
|
|
44
|
+
const match = value.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$/);
|
|
45
|
+
if (!match || !Number.isFinite(Date.parse(value)) || Number(match[2]) < 1 || Number(match[2]) > 12 ||
|
|
46
|
+
Number(match[3]) < 1 || Number(match[3]) > new Date(Date.UTC(Number(match[1]), Number(match[2]), 0)).getUTCDate() ||
|
|
47
|
+
Number(match[4]) > 23 || Number(match[5]) > 59 || Number(match[6]) > 59) {
|
|
48
|
+
throw new ForgeInventoryError('invalid-timestamp');
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
};
|
|
52
|
+
|
|
40
53
|
export const segments = (value: unknown): string[] => {
|
|
41
54
|
const path = optionalString(value);
|
|
42
55
|
if (!path || path.split('/').some((part) => !part || part === '.' || part === '..' || /[\\\u0000-\u001f\u007f]/.test(part))) {
|