@foss.global/codefeed 5.3.0 → 5.5.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 +41 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.giteasourceinventory.d.ts +38 -16
- package/dist_ts/classes.giteasourceinventory.js +537 -79
- package/dist_ts/classes.giteasourcetransfer.js +8 -103
- package/dist_ts/forgeinventory.transfer.d.ts +24 -0
- package/dist_ts/forgeinventory.transfer.js +77 -1
- package/dist_ts/giteasourceinventory.packages.d.ts +49 -0
- package/dist_ts/giteasourceinventory.packages.js +180 -1
- package/dist_ts/giteasourcetransfer.documents.d.ts +19 -4
- package/dist_ts/giteasourcetransfer.documents.js +49 -5
- package/package.json +4 -4
- package/readme.md +28 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.giteasourceinventory.ts +598 -83
- package/ts/classes.giteasourcetransfer.ts +10 -104
- package/ts/forgeinventory.transfer.ts +88 -0
- package/ts/giteasourceinventory.packages.ts +168 -0
- package/ts/giteasourcetransfer.documents.ts +47 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import * as validation from './forgeinventory.validation.js';
|
|
3
|
+
import { swiftManifestKey } from './giteasourcetransfer.documents.js';
|
|
3
4
|
/** Media types Gitea serves an index or a manifest list as; an index candidate must be one of them. */
|
|
4
5
|
export const containerIndexMediaTypes = Object.freeze([
|
|
5
6
|
'application/vnd.oci.image.index.v1+json',
|
|
@@ -50,6 +51,184 @@ export const swiftPackageParts = (nameArg) => {
|
|
|
50
51
|
throw new validation.ForgeInventoryError('invalid-swift-name');
|
|
51
52
|
return { scope: match[1], name: match[2] };
|
|
52
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* A Swift release's `Package.swift`, or with `swiftVersionArg` its alternate
|
|
56
|
+
* manifest, read with `clientArg`'s `token` authorization; null when Gitea
|
|
57
|
+
* redirects the alternate one to the release's own `Package.swift` (303),
|
|
58
|
+
* which is how it answers a version it holds no manifest for. No redirect is
|
|
59
|
+
* followed: any other redirect rejects with `swift-manifest-redirect-unexpected`,
|
|
60
|
+
* a redirect of `Package.swift` itself with `http-<status>`, and a body that
|
|
61
|
+
* is not `text/x-swift` with `invalid-content-type`. The read counts no
|
|
62
|
+
* download.
|
|
63
|
+
*/
|
|
64
|
+
export const readSwiftManifest = async (clientArg, baseUrlArg, ownerArg, partsArg, versionArg, swiftVersionArg, signalArg) => {
|
|
65
|
+
const url = new URL(`${baseUrlArg}/api/packages/${encodeURIComponent(ownerArg)}/swift/${encodeURIComponent(partsArg.scope)}/${encodeURIComponent(partsArg.name)}/${encodeURIComponent(versionArg)}/Package.swift`);
|
|
66
|
+
if (swiftVersionArg !== null)
|
|
67
|
+
url.searchParams.set('swift-version', swiftVersionArg);
|
|
68
|
+
const response = await clientArg.requestBytesOrRedirect(url, { accept: 'application/vnd.swift.registry.v1+swift', signal: signalArg });
|
|
69
|
+
if (response.kind === 'redirect') {
|
|
70
|
+
if (swiftVersionArg === null)
|
|
71
|
+
throw new validation.ForgeInventoryError(`http-${response.status}`);
|
|
72
|
+
// Gitea's answer for a missing alternate manifest: 303 to the release's
|
|
73
|
+
// `Package.swift` under its configured root, with the owner lowercased
|
|
74
|
+
// and scope, name and version as the request named them.
|
|
75
|
+
const expected = new URL(`${baseUrlArg}/api/packages/${ownerArg.toLowerCase()}/swift/${partsArg.scope}/${partsArg.name}/${versionArg}/Package.swift`);
|
|
76
|
+
let location = null;
|
|
77
|
+
try {
|
|
78
|
+
location = response.location === null ? null : new URL(response.location, url);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
location = null;
|
|
82
|
+
}
|
|
83
|
+
if (response.status !== 303 || location === null || location.href !== expected.href) {
|
|
84
|
+
throw new validation.ForgeInventoryError('swift-manifest-redirect-unexpected');
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
if (response.mediaType !== 'text/x-swift')
|
|
89
|
+
throw new validation.ForgeInventoryError('invalid-content-type');
|
|
90
|
+
return { bytes: response.bytes, mediaType: 'text/x-swift' };
|
|
91
|
+
};
|
|
92
|
+
/** Distinct manifest keys read per Swift version, `''` included; Gitea keeps at most 64 manifests (`maxManifestFiles`). */
|
|
93
|
+
const maxSwiftManifestCandidates = 64;
|
|
94
|
+
/**
|
|
95
|
+
* The name of every central-directory entry of a zip archive, in directory
|
|
96
|
+
* order, each byte one code unit (Go strings are bytes, and only ASCII names
|
|
97
|
+
* can match `manifestPattern`). It reads the directory as Go 1.27.2's
|
|
98
|
+
* `archive/zip` `NewReader` does, the archive/zip Gitea 28.2.0 builds with:
|
|
99
|
+
* - the end record is the last signature in the final 65 KiB whose comment
|
|
100
|
+
* fits in the archive;
|
|
101
|
+
* - its zip64 locator and end record are used when a count, size or offset
|
|
102
|
+
* is saturated and a locator for disk 0 of 1 sits right before it;
|
|
103
|
+
* - the base offset of data prepended to the archive is the end record's
|
|
104
|
+
* position minus the directory's size and offset, unless a directory
|
|
105
|
+
* header sits at the unadjusted offset;
|
|
106
|
+
* - headers are read one after another until one is malformed or cut off
|
|
107
|
+
* (a zip64 field too short for the saturated sizes and offset it stands
|
|
108
|
+
* for is malformed), and their count must agree with the end record's in
|
|
109
|
+
* its low 16 bits.
|
|
110
|
+
* Anything Go refuses rejects with `swift-archive-invalid`.
|
|
111
|
+
*/
|
|
112
|
+
export const zipEntryNames = (archiveArg) => {
|
|
113
|
+
const invalid = () => new validation.ForgeInventoryError('swift-archive-invalid');
|
|
114
|
+
const size = archiveArg.byteLength;
|
|
115
|
+
const sizeBig = BigInt(size);
|
|
116
|
+
let endOffset = -1;
|
|
117
|
+
for (let index = size - 22; index >= Math.max(0, size - 65 * 1024); index--) {
|
|
118
|
+
if (archiveArg.readUInt32LE(index) === 0x06054b50) {
|
|
119
|
+
endOffset = index;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (endOffset < 0 || endOffset + 22 + archiveArg.readUInt16LE(endOffset + 20) > size)
|
|
124
|
+
throw invalid();
|
|
125
|
+
let directoryEnd = BigInt(endOffset);
|
|
126
|
+
let records = BigInt(archiveArg.readUInt16LE(endOffset + 10));
|
|
127
|
+
let directorySize = BigInt(archiveArg.readUInt32LE(endOffset + 12));
|
|
128
|
+
let directoryOffset = BigInt(archiveArg.readUInt32LE(endOffset + 16));
|
|
129
|
+
if (records === 0xffffn || directorySize === 0xffffffffn || directoryOffset === 0xffffffffn) {
|
|
130
|
+
const locator = endOffset - 20;
|
|
131
|
+
if (locator >= 0 && archiveArg.readUInt32LE(locator) === 0x07064b50 && archiveArg.readUInt32LE(locator + 4) === 0
|
|
132
|
+
&& archiveArg.readUInt32LE(locator + 16) === 1) {
|
|
133
|
+
// Go reads the offset as an int64: one past its range is negative and leaves the archive as zip32.
|
|
134
|
+
const record = archiveArg.readBigInt64LE(locator + 8);
|
|
135
|
+
if (record >= 0n) {
|
|
136
|
+
if (record + 56n > sizeBig || archiveArg.readUInt32LE(Number(record)) !== 0x06064b50)
|
|
137
|
+
throw invalid();
|
|
138
|
+
directoryEnd = record;
|
|
139
|
+
records = archiveArg.readBigUInt64LE(Number(record) + 32);
|
|
140
|
+
directorySize = archiveArg.readBigUInt64LE(Number(record) + 40);
|
|
141
|
+
directoryOffset = archiveArg.readBigUInt64LE(Number(record) + 48);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (directorySize > 0x7fffffffffffffffn || directoryOffset > 0x7fffffffffffffffn)
|
|
146
|
+
throw invalid();
|
|
147
|
+
let baseOffset = directoryEnd - directorySize - directoryOffset;
|
|
148
|
+
if (baseOffset + directoryOffset < 0n || baseOffset + directoryOffset >= sizeBig)
|
|
149
|
+
throw invalid();
|
|
150
|
+
if (baseOffset > 0n && directoryHeader(archiveArg, Number(directoryOffset)).kind === 'entry')
|
|
151
|
+
baseOffset = 0n;
|
|
152
|
+
const names = [];
|
|
153
|
+
let offset = Number(baseOffset + directoryOffset);
|
|
154
|
+
while (true) {
|
|
155
|
+
const header = directoryHeader(archiveArg, offset);
|
|
156
|
+
if (header.kind === 'end')
|
|
157
|
+
break;
|
|
158
|
+
// Go's `io.ReadFull` reports a read that gets no byte at all as `io.EOF`, which fails the archive.
|
|
159
|
+
if (header.kind === 'eof')
|
|
160
|
+
throw invalid();
|
|
161
|
+
names.push(header.name);
|
|
162
|
+
offset = header.next;
|
|
163
|
+
}
|
|
164
|
+
if ((BigInt(names.length) & 0xffffn) !== (records & 0xffffn))
|
|
165
|
+
throw invalid();
|
|
166
|
+
return names;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* The central-directory header at `offsetArg`, as Go 1.27.2's
|
|
170
|
+
* `readDirectoryHeader` reads it: `entry` with its name and the offset of the
|
|
171
|
+
* next header; `end` where Go stops reading headers (a header cut off by the
|
|
172
|
+
* archive's end, another signature, or a zip64 field shorter than 8 bytes for
|
|
173
|
+
* each saturated size and offset); `eof` where a read gets no byte at all.
|
|
174
|
+
*/
|
|
175
|
+
const directoryHeader = (archiveArg, offsetArg) => {
|
|
176
|
+
const available = archiveArg.byteLength - offsetArg;
|
|
177
|
+
if (available <= 0)
|
|
178
|
+
return { kind: 'eof' };
|
|
179
|
+
if (available < 46)
|
|
180
|
+
return { kind: 'end' };
|
|
181
|
+
if (archiveArg.readUInt32LE(offsetArg) !== 0x02014b50)
|
|
182
|
+
return { kind: 'end' };
|
|
183
|
+
const nameLength = archiveArg.readUInt16LE(offsetArg + 28);
|
|
184
|
+
const extraLength = archiveArg.readUInt16LE(offsetArg + 30);
|
|
185
|
+
const commentLength = archiveArg.readUInt16LE(offsetArg + 32);
|
|
186
|
+
const variable = nameLength + extraLength + commentLength;
|
|
187
|
+
if (variable > 0 && available === 46)
|
|
188
|
+
return { kind: 'eof' };
|
|
189
|
+
if (available - 46 < variable)
|
|
190
|
+
return { kind: 'end' };
|
|
191
|
+
const saturated = [20, 24, 42].filter((fieldArg) => archiveArg.readUInt32LE(offsetArg + fieldArg) === 0xffffffff).length;
|
|
192
|
+
let extra = offsetArg + 46 + nameLength;
|
|
193
|
+
const extraEnd = extra + extraLength;
|
|
194
|
+
while (extraEnd - extra >= 4) {
|
|
195
|
+
const tag = archiveArg.readUInt16LE(extra);
|
|
196
|
+
const fieldSize = archiveArg.readUInt16LE(extra + 2);
|
|
197
|
+
extra += 4;
|
|
198
|
+
if (extraEnd - extra < fieldSize)
|
|
199
|
+
break;
|
|
200
|
+
// The zip64 field holds 8 bytes for each saturated field, in order.
|
|
201
|
+
if (tag === 0x0001 && fieldSize < 8 * saturated)
|
|
202
|
+
return { kind: 'end' };
|
|
203
|
+
extra += fieldSize;
|
|
204
|
+
}
|
|
205
|
+
return { kind: 'entry', name: archiveArg.toString('latin1', offsetArg + 46, offsetArg + 46 + nameLength), next: offsetArg + 46 + variable };
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* The keys of the manifests Gitea 28.2.0 may hold for a Swift source
|
|
209
|
+
* archive, sorted in code-unit order: `''`, and the key of every
|
|
210
|
+
* central-directory entry, in any directory, whose name does not end in `/`
|
|
211
|
+
* and whose base name matches Gitea's `manifestPattern` and parses
|
|
212
|
+
* (`swiftManifestKey`). Gitea keeps only the manifests of the shallowest
|
|
213
|
+
* directory, so the keys are a superset of what it holds, and its answer for
|
|
214
|
+
* each key decides. More than `maxSwiftManifestCandidates` distinct keys
|
|
215
|
+
* reject with `swift-manifest-candidates-over-bound`; an archive Go's
|
|
216
|
+
* `archive/zip` refuses with `swift-archive-invalid`.
|
|
217
|
+
*/
|
|
218
|
+
export const swiftManifestCandidates = (archiveArg) => {
|
|
219
|
+
const keys = new Set(['']);
|
|
220
|
+
for (const name of zipEntryNames(archiveArg)) {
|
|
221
|
+
if (name.endsWith('/'))
|
|
222
|
+
continue;
|
|
223
|
+
const key = swiftManifestKey(name.slice(name.lastIndexOf('/') + 1));
|
|
224
|
+
if (key === null)
|
|
225
|
+
continue;
|
|
226
|
+
keys.add(key);
|
|
227
|
+
if (keys.size > maxSwiftManifestCandidates)
|
|
228
|
+
throw new validation.ForgeInventoryError('swift-manifest-candidates-over-bound');
|
|
229
|
+
}
|
|
230
|
+
return [...keys].sort(compareText);
|
|
231
|
+
};
|
|
53
232
|
/**
|
|
54
233
|
* The digest of the manifest a container version holds: `sha256:` and the
|
|
55
234
|
* SHA-256 of the blob holding the version's `manifest.json`; null for a
|
|
@@ -136,4 +315,4 @@ export const composeGiteaPackageContent = (discoveredArg, packagesArg) => {
|
|
|
136
315
|
owners: owners.map((ownerArg) => ({ owner: ownerArg, ...group(refs.filter((refArg) => refArg.owner === ownerArg), records) })),
|
|
137
316
|
};
|
|
138
317
|
};
|
|
139
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0ZWFzb3VyY2VpbnZlbnRvcnkucGFja2FnZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9naXRlYXNvdXJjZWludmVudG9yeS5wYWNrYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLGdDQUFnQyxDQUFDO0FBVTdELHVHQUF1RztBQUN2RyxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RSx5Q0FBeUM7SUFDekMsMkRBQTJEO0NBQzVELENBQUMsQ0FBQztBQUVILGtHQUFrRztBQUNsRyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMxRSxHQUFHLHdCQUF3QjtJQUMzQiw0Q0FBNEM7SUFDNUMsc0RBQXNEO0NBQ3ZELENBQUMsQ0FBQztBQUVILCtHQUErRztBQUMvRyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyx5QkFBeUIsQ0FBQztBQUU1RCxpSEFBaUg7QUFDakgsTUFBTSxjQUFjLEdBQUcsc0RBQXNELENBQUM7QUFDOUUsMEVBQTBFO0FBQzFFLE1BQU0sZ0JBQWdCLEdBQUcsK0JBQStCLENBQUM7QUFDekQseUhBQXlIO0FBQ3pILE1BQU0sbUJBQW1CLEdBQUcscUVBQXFFLENBQUM7QUFFbEcsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFVLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXJHLHdIQUF3SDtBQUN4SCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFtQixFQUFVLEVBQUUs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
|
|
318
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0ZWFzb3VyY2VpbnZlbnRvcnkucGFja2FnZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9naXRlYXNvdXJjZWludmVudG9yeS5wYWNrYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLGdDQUFnQyxDQUFDO0FBRTdELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBVXRFLHVHQUF1RztBQUN2RyxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RSx5Q0FBeUM7SUFDekMsMkRBQTJEO0NBQzVELENBQUMsQ0FBQztBQUVILGtHQUFrRztBQUNsRyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMxRSxHQUFHLHdCQUF3QjtJQUMzQiw0Q0FBNEM7SUFDNUMsc0RBQXNEO0NBQ3ZELENBQUMsQ0FBQztBQUVILCtHQUErRztBQUMvRyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyx5QkFBeUIsQ0FBQztBQUU1RCxpSEFBaUg7QUFDakgsTUFBTSxjQUFjLEdBQUcsc0RBQXNELENBQUM7QUFDOUUsMEVBQTBFO0FBQzFFLE1BQU0sZ0JBQWdCLEdBQUcsK0JBQStCLENBQUM7QUFDekQseUhBQXlIO0FBQ3pILE1BQU0sbUJBQW1CLEdBQUcscUVBQXFFLENBQUM7QUFFbEcsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFVLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXJHLHdIQUF3SDtBQUN4SCxN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
|
|
@@ -28,8 +28,23 @@ export interface IGiteaCanonicalPackageDocument {
|
|
|
28
28
|
*/
|
|
29
29
|
export declare const canonicalPackageDocument: (kindArg: TGiteaCanonicalPackageDocumentKind, bytesArg: Uint8Array) => IGiteaCanonicalPackageDocument;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* Whether `valueArg` is a Swift version Gitea 28.2.0 can key an alternate
|
|
32
|
+
* manifest (`Package@swift-<v>.swift`) by. Gitea parses the file name's
|
|
33
|
+
* version with go-version's `NewSemver`, refuses an archive whose version
|
|
34
|
+
* does not parse (`ErrInvalidManifestVersion`), and keys the manifest by
|
|
35
|
+
* `TrimmedVersionString`: major and minor, and the patch only when it is not
|
|
36
|
+
* zero, each in decimal without leading zeros (`modules/packages/swift/metadata.go`).
|
|
37
|
+
* So a key has two or three segments, no leading zeros, no zero patch, and
|
|
38
|
+
* every segment at most 9223372036854775807, compared by value.
|
|
34
39
|
*/
|
|
35
|
-
export declare const
|
|
40
|
+
export declare const isSwiftManifestVersion: (valueArg: unknown) => valueArg is string;
|
|
41
|
+
/**
|
|
42
|
+
* The key Gitea 28.2.0 would hold a manifest with base name `baseNameArg`
|
|
43
|
+
* by: `''` for `Package.swift`; for `Package@swift-<v>.swift`, `<v>` parsed
|
|
44
|
+
* as go-version's `NewSemver` parses it (leading zeros allowed, every segment
|
|
45
|
+
* a signed 64-bit integer, missing segments zero) and written as
|
|
46
|
+
* `TrimmedVersionString` writes it, a key `isSwiftManifestVersion` accepts.
|
|
47
|
+
* Null when the name is not a manifest name, or when a segment is over int64,
|
|
48
|
+
* which `NewSemver` refuses, so Gitea can never hold the key.
|
|
49
|
+
*/
|
|
50
|
+
export declare const swiftManifestKey: (baseNameArg: string) => string | null;
|
|
@@ -78,9 +78,53 @@ export const canonicalPackageDocument = (kindArg, bytesArg) => {
|
|
|
78
78
|
return { bytes, sha256: plugins.crypto.createHash('sha256').update(bytes).digest('hex') };
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* The largest segment Gitea's version parser reads: hashicorp/go-version
|
|
82
|
+
* (v1.9.0 in Gitea 28.2.0) parses every segment as a signed 64-bit integer
|
|
83
|
+
* and refuses a larger one.
|
|
84
84
|
*/
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const maxSwiftVersionSegment = 9223372036854775807n;
|
|
86
|
+
/** Major and minor, and an optional patch, in decimal without leading zeros. */
|
|
87
|
+
const trimmedSwiftVersionShape = /^(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\.([1-9]\d*))?$/;
|
|
88
|
+
/**
|
|
89
|
+
* Whether `valueArg` is a Swift version Gitea 28.2.0 can key an alternate
|
|
90
|
+
* manifest (`Package@swift-<v>.swift`) by. Gitea parses the file name's
|
|
91
|
+
* version with go-version's `NewSemver`, refuses an archive whose version
|
|
92
|
+
* does not parse (`ErrInvalidManifestVersion`), and keys the manifest by
|
|
93
|
+
* `TrimmedVersionString`: major and minor, and the patch only when it is not
|
|
94
|
+
* zero, each in decimal without leading zeros (`modules/packages/swift/metadata.go`).
|
|
95
|
+
* So a key has two or three segments, no leading zeros, no zero patch, and
|
|
96
|
+
* every segment at most 9223372036854775807, compared by value.
|
|
97
|
+
*/
|
|
98
|
+
export const isSwiftManifestVersion = (valueArg) => {
|
|
99
|
+
if (typeof valueArg !== 'string')
|
|
100
|
+
return false;
|
|
101
|
+
const match = trimmedSwiftVersionShape.exec(valueArg);
|
|
102
|
+
if (!match)
|
|
103
|
+
return false;
|
|
104
|
+
return match.slice(1).every((segmentArg) => segmentArg === undefined || BigInt(segmentArg) <= maxSwiftVersionSegment);
|
|
105
|
+
};
|
|
106
|
+
/** Gitea 28.2.0's `manifestPattern` (`modules/packages/swift/metadata.go:27`), matched against a file's base name. */
|
|
107
|
+
const swiftManifestNamePattern = /^Package(?:@swift-(\d+(?:\.\d+)?(?:\.\d+)?))?\.swift$/;
|
|
108
|
+
/**
|
|
109
|
+
* The key Gitea 28.2.0 would hold a manifest with base name `baseNameArg`
|
|
110
|
+
* by: `''` for `Package.swift`; for `Package@swift-<v>.swift`, `<v>` parsed
|
|
111
|
+
* as go-version's `NewSemver` parses it (leading zeros allowed, every segment
|
|
112
|
+
* a signed 64-bit integer, missing segments zero) and written as
|
|
113
|
+
* `TrimmedVersionString` writes it, a key `isSwiftManifestVersion` accepts.
|
|
114
|
+
* Null when the name is not a manifest name, or when a segment is over int64,
|
|
115
|
+
* which `NewSemver` refuses, so Gitea can never hold the key.
|
|
116
|
+
*/
|
|
117
|
+
export const swiftManifestKey = (baseNameArg) => {
|
|
118
|
+
const match = swiftManifestNamePattern.exec(baseNameArg);
|
|
119
|
+
if (!match)
|
|
120
|
+
return null;
|
|
121
|
+
if (match[1] === undefined)
|
|
122
|
+
return '';
|
|
123
|
+
const segments = match[1].split('.').map((segmentArg) => BigInt(segmentArg));
|
|
124
|
+
if (segments.some((segmentArg) => segmentArg > maxSwiftVersionSegment))
|
|
125
|
+
return null;
|
|
126
|
+
const [major, minor = 0n, patch = 0n] = segments;
|
|
127
|
+
const key = patch === 0n ? `${major}.${minor}` : `${major}.${minor}.${patch}`;
|
|
128
|
+
return isSwiftManifestVersion(key) ? key : null;
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0ZWFzb3VyY2V0cmFuc2Zlci5kb2N1bWVudHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9naXRlYXNvdXJjZXRyYW5zZmVyLmRvY3VtZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLGdDQUFnQyxDQUFDO0FBaUI3RDs7OztHQUlHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBd0UsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM3RyxhQUFhLEVBQUUsWUFBWTtJQUMzQixlQUFlLEVBQUUsSUFBSTtJQUNyQixtQkFBbUIsRUFBRSxRQUFRO0lBQzdCLG1CQUFtQixFQUFFLElBQUk7Q0FDMUIsQ0FBQyxDQUFDO0FBRUg7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQWUsRUFBRSxRQUFnQixFQUFVLEVBQUU7SUFDdEUsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsT0FBTyxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3hELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFFLENBQUM7UUFDN0MsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUUsQ0FBQztRQUNoRCxJQUFJLFNBQVMsS0FBSyxVQUFVO1lBQUUsT0FBTyxTQUFTLEdBQUcsVUFBVSxDQUFDO1FBQzVELElBQUksSUFBSSxTQUFTLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxLQUFLLElBQUksVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENB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LEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDN0UsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLEdBQUcsc0JBQXNCLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNwRixNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEVBQUUsS0FBSyxHQUFHLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUNqRCxNQUFNLEdBQUcsR0FBRyxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksS0FBSyxJQUFJLEtBQUssRUFBRSxDQUFDO0lBQzlFLE9BQU8sc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2xELENBQUMsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foss.global/codefeed",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.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": {
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"author": "Task Venture Capital GmbH",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@foss.global/forgefixtures": "^1.
|
|
15
|
-
"@git.zone/tsrepo": "^2.
|
|
14
|
+
"@foss.global/forgefixtures": "^1.2.0",
|
|
15
|
+
"@git.zone/tsrepo": "^2.2.0",
|
|
16
16
|
"@push.rocks/qenv": "^8.2.1",
|
|
17
17
|
"@types/node": "^26.6.6"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@foss.global/gitmanager": "^2.4.0",
|
|
21
|
-
"@foss.global/interfaces": "^3.
|
|
21
|
+
"@foss.global/interfaces": "^3.5.1",
|
|
22
22
|
"@push.rocks/lik": "^6.4.4",
|
|
23
23
|
"@push.rocks/smartnpm": "^2.1.3",
|
|
24
24
|
"@push.rocks/smarttime": "^5.0.1"
|
package/readme.md
CHANGED
|
@@ -101,13 +101,13 @@ const results = await reader.measureUnits(reader.units(discovery), {
|
|
|
101
101
|
const inventory = composeGiteaSourceInventory(discovery, results, [{ package: '@foss.global/codefeed', version }]);
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
A run is split into units: the instance, each owner and each repository. `measureUnit` never rejects; a unit whose primary record cannot be read becomes `failed` with a sanitized reason. A resumed run measures failed units, and units holding a partial measure, again and passes all results to `composeGiteaSourceInventory`, where the last result per unit wins. The composed document is deterministic: it carries no timestamps, sorts owners, repositories, packages and reasons, and does not depend on the order of the results. An aborted signal or a rejected `onResult` aborts the units in flight, hands over no further result, and rejects `measureUnits` once every worker has stopped.
|
|
104
|
+
A run is split into units: the instance, each owner and each repository, and, when discovery selects them, each package and each repository's collaboration. `measureUnit` never rejects; a unit whose primary record cannot be read becomes `failed` with a sanitized reason. A resumed run measures failed units, and units holding a partial measure, again and passes all results to `composeGiteaSourceInventory`, where the last result per unit wins. The composed document is deterministic: it carries no timestamps, sorts owners, repositories, packages and reasons, and does not depend on the order of the results. An aborted signal or a rejected `onResult` aborts the units in flight, hands over no further result, and rejects `measureUnits` once every worker has stopped.
|
|
105
105
|
|
|
106
106
|
Discovery records each repository's Gitea `id` as a canonical decimal string, and `units()` passes it into the repository unit. A unit with an `id` fails with `repository-identity-changed` when its name answers with another id, as after a rename and a new repository under the old name; a unit without one, from a discovery stored by an earlier version, is checked by name only. `composeGiteaSourceInventory` counts a repository result for another id than discovery recorded as a failed unit (`repository: unit failed: repository-identity-changed`), and adds `repository: duplicate-id` when two measured repositories share one id, which a discovery without ids cannot rule out.
|
|
107
107
|
|
|
108
108
|
`lookupRepository(id)` reads one repository by its id through `GET /api/v1/repositories/{id}`, which keeps answering after a rename or transfer. It resolves `{ status: 'present', id, owner, name }` with the name Gitea gives the repository now, or `{ status: 'absent', id }` only when Gitea answers 404, which a site administrator gets only for a deleted repository. Every other failed read rejects with its code, so a timeout or a 500 never counts as a deletion; an id that is not a canonical decimal rejects with `invalid-repository-id` without a request.
|
|
109
109
|
|
|
110
|
-
What is measured: users with their account flags, two-factor and SSH/GPG keys; organizations, members, teams, team memberships and repository grants; repositories with their flags, Git refs split into branches, tags, pull request refs and other refs, Git objects and their uncompressed bytes, LFS objects referenced anywhere in history with the bytes Gitea holds and the number it lacks, issues, pull requests, comments, reviews, review comments, labels, milestones, reactions and attachments; releases including drafts, assets and asset bytes; wiki pages; collaborators, team grants, SSH deploy keys, deploy tokens, webhooks, branch and tag protections and push mirrors; packages per type with versions, files and bytes; system webhooks, Actions runners, workflows, runs, artifacts and the number of Actions secrets and variables; unadopted repositories.
|
|
110
|
+
What is measured: users with their account flags, two-factor and SSH/GPG keys; organizations, members, teams, team memberships and repository grants; repositories with their flags, Git refs split into branches, tags, pull request refs and other refs, Git objects and their uncompressed bytes, LFS objects referenced anywhere in history with the bytes Gitea holds and the number it lacks, issues, pull requests, comments, reviews, review comments, labels, milestones, reactions and attachments, with comments, reactions and attachments also split by kind (`collaboration.byKind`) and pull requests counted as open, closed and merged; project boards per repository and per owner; releases including drafts, assets and asset bytes; wiki pages; collaborators, team grants, SSH deploy keys, deploy tokens, webhooks, branch and tag protections and push mirrors; packages per type with versions, files and bytes; system webhooks, Actions runners, workflows, runs, artifacts and the number of Actions secrets and variables; unadopted repositories.
|
|
111
111
|
|
|
112
112
|
Beyond counts, each repository keeps records of what the migration recreates. `description` is the repository's description exactly as Gitea's API reports it, without trimming or normalising; `''` means the source has none. A description that is not a string fails the repository unit with `invalid-string`, so the inventory stays incomplete; reports from readers before 4.4.0 carry no `description`, which a consumer treats as unread, never as `''`. `releaseRecords` lists every release, drafts and prereleases included, sorted by numeric id, as `TForgeSourceRelease` records (narrow on `draft` before reading `publishedAt` as a string): tag name, target commitish, name, body, the draft and prerelease flags, created and published times as Gitea reports them (a published release must carry a valid publication time; a draft's is recorded as reported, `null` on Gitea 28 and never replaced by its creation time, and a draft's tag does not exist as a Git ref yet; on Gitea 28 a new release's creation time is the date of the commit it points at), an author snapshot (account id and login; Gitea's placeholder for a deleted account has id `-1`) and its assets sorted by numeric id with id, storage `uuid`, name, size, download count and creation time. Gitea exposes no content digest, so a record carries none; a replaced file carries another id and uuid, and the download count moves with every download, so it never decides whether a release changed. `protections` holds the branch protection rules sorted by rule name (code-unit order) with every restriction Gitea reads back, allowlists included, and the tag protection rules sorted by numeric id with their name pattern and allowlist. `releaseRecords` is null while a release count is not complete, and `protections` is null while either protection count is not; the counts then say why.
|
|
113
113
|
|
|
@@ -124,9 +124,33 @@ Secrets are counted, never named: the report carries no tokens, Actions secret o
|
|
|
124
124
|
Git-level measures come from a mirror clone of every ref Gitea advertises, `refs/pull/*` included, made with `@foss.global/gitmanager` in a fresh directory below `gitWorkDir` and removed afterwards. The reader's login and token form Basic credentials; the credential reaches Git only through GIT_CONFIG_* entries in the child process environment; it is never in the URL, the command line or any file. The private CA list applies to the clone as well. The mirror's HEAD becomes the repository's `head`: the ref it names as `target` and whether it `resolves`. In a repository that is not `empty`, a HEAD that does not resolve names a missing branch, such as a default branch deleted at the source, and a `target` other than `refs/heads/<defaultBranch>` means Gitea's setting and its Git HEAD disagree. `head` is null when the mirror or its refs could not be read. A detached source HEAD is one such case: GitManager's mirror import requires a symbolic HEAD, so the clone fails with `git-mirror-failed`, and this reader never reports a `target` of null. The same mirror records `refDigests`: for each of `refs/heads/`, `refs/tags/` and `refs/notes/`, GitManager's ref `inventoryDigest` (HEAD and the refs under that prefix) and the `refCount` of that selection, read as one single-ref `listRefs` page per prefix; codefeed computes no digest of its own. Any other GitManager repository with the same HEAD and refs under a prefix reports the same digest, so a migration compares them with its native copy. Pull request refs have no digest, and `git.otherRefs - refDigests.notes.refCount` refs lie outside every digested namespace. `refDigests` is null whenever `head` is, or when any of the three reads fails; it is never partial. The mirror's distinct LFS pointers, from every reachable revision, are checked against Gitea in batches of 100: an object with a download action counts as held, one answered with error 404 as missing, and any other answer makes the LFS measures `partial`. A clone that fails or exceeds `gitTimeoutMs` makes every Git and LFS measure of that repository `partial`; only the API-reported size stays complete. A clone starts only once its scratch reservation, twice the reported size plus 64 MiB, fits the free space of the file system that holds `gitWorkDir`, counting the reservations of the clones already in flight from every reader in the process. A clone that does not fit waits for them, in arrival order; one that does not fit even alone makes every Git and LFS measure of its repository `partial` with `git-workdir-too-small`, so the inventory stays incomplete. Size `gitWorkDir` for the largest repositories measured at once.
|
|
125
125
|
|
|
126
126
|
Known gaps that keep an inventory incomplete:
|
|
127
|
-
-
|
|
127
|
+
- Gitea's issue and repository comment listings leave out the kind whose unit is disabled (Gitea 28.2.0 `ListIssues`, `ListRepoIssueComments`) and answer 404 only when both are. Each kind is therefore measured on its own: with the pull request unit disabled, `issues` and every issue measure of `collaboration.byKind` stay measured, and only the pull request measures (`pullRequests`, `reviews`, `reviewComments`, the pull request kinds and states of `byKind`) and the mixed measures that include them (`comments`, `reactions`, `attachments`, `attachmentBytes`) are `notMeasured`, and the reverse. An issue unit configured as an external tracker keeps `features.issues` true but lists no issue, so its issue measures are `notMeasured` too, never a complete zero. A repository record whose `has_issues` disagrees with its trackers fails the repository unit with `inconsistent-issue-unit`, and one whose `projects_mode` is not `repo`, `owner` or `all` with `invalid-projects-mode` (`invalid-string` when it is missing); Gitea 28.2.0 cannot produce either state, so they mean a forge the reader was not built against (S8 U3 ruling, Q3). A disabled wiki hides its pages, and a projects unit that allows only owner boards (`projects_mode` `owner`) hides the repository's boards (`collaboration.projects`), which Gitea still serves while the projects unit is disabled. Labels, milestones, releases and Actions stay readable while their units are disabled.
|
|
128
128
|
- Gitea 28 answers 404 to every pull request route of an archived repository, reads included. The reviews of each pull request are still requested; when an archived repository answers 404 there, `reviews` and `reviewComments` are `partial` with the reason `repository-archived` (in `incompleteReasons` as `repository.collaboration.reviews: repository-archived`). Its issues, pull requests, comments and `refs/pull/*` stay measured. A 404 in a repository that is not archived stays `http-404`.
|
|
129
129
|
|
|
130
|
+
#### Collaboration records
|
|
131
|
+
|
|
132
|
+
Issues are recorded only when discovery selects the collaboration class: `reader.discover(signal, { classes: ['collaboration'] })` sets `discovery.collaboration: true`, and `units()` then adds one `{ kind: 'collaboration', owner, name, id }` unit per repository, keyed by the repository's discovered id (S8 ruling D12). A discovery that selects the class while a repository has no id rejects in `units()` with `repository-id-missing`, and composing it names `collaboration: repository-id-missing`; it is never keyed by name. Without the class, discovery carries no `collaboration`, no collaboration unit is measured, and the composed inventory has neither `collaboration` nor any organization's `labelRecords`, so the records are unread. The classes combine: `{ classes: ['packages', 'collaboration'] }`.
|
|
133
|
+
|
|
134
|
+
A collaboration unit returns an `IForgeSourceCollaborationInventory` (`@foss.global/interfaces` 3.4), read with GETs and the administrator's token, never through `Sudo`:
|
|
135
|
+
|
|
136
|
+
- The repository must still answer its name with the discovered id, else the unit fails with `repository-identity-changed`.
|
|
137
|
+
- `labels` is every label of the repository, used or not, and `milestones` every milestone (`state=all`), each sorted by numeric id. Organization labels are not repeated here: each organization owner records them as `labelRecords`, and an issue's `labelIds` may name either.
|
|
138
|
+
- `highestNumber` is the highest number Gitea's issue listing holds, issues and pull requests together, since they share one sequence; `0` when it lists none, and not measured when both units are disabled. A deleted number, or one a disabled unit hides, is invisible to every read, so Gitea may have allocated higher ones (S8 ruling D1).
|
|
139
|
+
- `issues` holds every issue, never a pull request, sorted by number, with its comments sorted by id. Title, body, comment bodies, logins and `ref` are verbatim, never trimmed; times are Gitea's RFC 3339 strings as served. Each issue records its poster, Gitea's original author (null when it reports none), assignees, label, milestone and project ids, `locked`, `pinOrder`, `dueDate`, `timeEstimate` and the counts of its tracked times (`/times`), dependencies (`/dependencies`), attachments and reactions; each comment its poster, original author, times and attachment and reaction counts. Gitea's `content_version`, a counter for concurrent edits, is not recorded.
|
|
140
|
+
- `issues` is `notMeasured`, and no issue's comments, reactions, tracked times or dependencies are requested, while Gitea's API hides them: when the issue unit is disabled or an external tracker, when time tracking is switched off for the repository (`internal_tracker.enable_time_tracker`) or the instance (`/settings/repository` `time_tracking_disabled`), or when dependencies are switched off (`internal_tracker.enable_issue_dependencies`). Gitea 28.2.0 then answers 404 to every issue's `/times` or `/dependencies`, and a refused read must never count as none (S8 U1 ruling). Each such case leaves the repository's issues to the owner's per-repository decision (S8 ruling D13); switching the setting on at the source resolves it. Labels and milestones stay readable in every case.
|
|
141
|
+
- `issues` is also `notMeasured`, again without a read of any issue, when Gitea imported the repository (its record's `original_url` is not empty) and the listing holds at least one issue, with the reason "Gitea imported this repository (original_url is set); its API names the importing account as poster and never reports the original author." Gitea's API names the account that ran the import as the poster of every imported issue and comment and never reports the original author (see the facts below), so recording them would credit the wrong account (S8 U3 ruling, Q1). Comments are part of their issues, so the rule covers them. An imported repository without issues keeps a complete empty list. The rule does not depend on `mirror`: a mirror converted to a normal repository keeps its `original_url`. `original_url` itself is never recorded, and a record without it as a string fails the unit with `invalid-string`. A forge whose API fills the original author has it recorded as `originalAuthor`.
|
|
142
|
+
- A unit is read whole or fails, never partly: any listing that does not finish fails it with the listing's reason, and so do an issue naming a milestone the listing lacks (`issue-milestone-unlisted`), an issue number listed twice (`duplicate-number`), an original author id without a name (`invalid-original-author`) and a result over `forgeSourceInventoryUnitMaxBytes` (`unit-over-bound`). A resumed run measures a failed unit again.
|
|
143
|
+
|
|
144
|
+
`composeGiteaSourceInventory` carries `collaboration`, sorted by owner and name, and every organization's `labelRecords` (null while its `labels` count is not complete) exactly when discovery selects collaboration. A unit that failed, was not measured or answers for another name adds `collaboration: unit failed: <code>` or `collaboration: unit not measured`, and a list that is `notMeasured` adds its path, such as `collaboration.issues: <reason>`. Owner and repository results stored by a reader before this version lack `labelRecords`, `projects` and `collaboration.byKind`; composing them names each as a reason, so the inventory stays incomplete until those units are measured again.
|
|
145
|
+
|
|
146
|
+
Gitea 28.2.0 facts behind the records, verified with the forgefixtures Gitea:
|
|
147
|
+
- Label and milestone listings are not gated by the issue unit: they answer while it is disabled (the routes carry no unit check, `routers/api/v1/api.go`).
|
|
148
|
+
- `/issues/{index}/times` answers 404 while time tracking is off for the repository, and `/issues/{index}/dependencies` while dependencies are off.
|
|
149
|
+
- `/orgs/{org}/projects` and `/users/{user}/projects` answer the site administrator's token for private organizations and users alike. A repository's `/projects` keeps listing its boards while its projects unit is disabled (Gitea then reports `projects_mode` `all`) and answers 404 while `projects_mode` is `owner`.
|
|
150
|
+
- Gitea applies `internal_tracker` only beside `has_issues: true`, and `projects_mode` only beside `has_projects: true`, in a repository edit.
|
|
151
|
+
- An issue's comments and a comment's reactions are served whole, without pages (`ListIssueComments` takes no page options); the reader requests them once and checks the rows against `X-Total-Count` when Gitea sends it.
|
|
152
|
+
- Gitea's REST API never fills `original_author` or `original_author_id` of an issue or comment (Gitea 28.2.0 `services/convert/issue.go` `toIssue` and `services/convert/issue_comment.go` `ToAPIComment` do not set them), so `originalAuthor` is null for all content. Content Gitea itself imported from another service keeps its source authors only in Gitea's database: through the API every such issue and comment reads as posted by the account that ran the import (`services/migrations/gitea_uploader.go`), as the fixture test shows with an import from Gitea's own loopback listener. This is why an imported repository's issues are `notMeasured` rather than recorded.
|
|
153
|
+
|
|
130
154
|
#### Packages
|
|
131
155
|
|
|
132
156
|
Packages are measured only when discovery selects their class: `reader.discover(signal, { classes: ['packages'] })` lists every package from the administrator package listing (`/admin/packages`, user-owned packages included) as `discovery.packages`, and `units()` then adds one unit per package. Without the class, discovery carries no `packages`, no package unit is measured, and the composed inventory has neither `packages` nor `totals.packageContent`, so the package class is unread; a stored discovery from an earlier reader composes as before. An unknown class rejects with `invalid-options`.
|
|
@@ -200,7 +224,7 @@ The package reads take selectors from the inventory's package records: the packa
|
|
|
200
224
|
- `readPackageDocument(package, version, kind, options?)` returns a version's metadata with the SHA-256 of the returned bytes, which a consumer records beside the version id:
|
|
201
225
|
- `npm-version`: the version document.
|
|
202
226
|
- `swift-release`: the release metadata.
|
|
203
|
-
- `swift-manifest`: `Package.swift`, which must answer 200. With `{ swiftVersion }` (`5.8`, `5.9.1`: trimmed as Gitea keys alternate manifests, the patch only when it is not zero; anything else rejects with `swift-version-invalid` before any request) it reads `Package@swift-<v>.swift` through `?swift-version=` without following a redirect, and resolves `null` only when Gitea answers 303 to the release's own `Package.swift` URL, its answer for a version it holds no manifest for. Any other redirect rejects with `swift-manifest-redirect-unexpected`, any other status with `http-<status>`.
|
|
227
|
+
- `swift-manifest`: `Package.swift`, which must answer 200. With `{ swiftVersion }` (`5.8`, `5.9.1`: trimmed as Gitea keys alternate manifests, two or three segments without leading zeros, the patch only when it is not zero, each segment at most 9223372036854775807; anything else rejects with `swift-version-invalid` before any request) it reads `Package@swift-<v>.swift` through `?swift-version=` without following a redirect, and resolves `null` only when Gitea answers 303 to the release's own `Package.swift` URL, its answer for a version it holds no manifest for. Any other redirect rejects with `swift-manifest-redirect-unexpected`, any other status with `http-<status>`.
|
|
204
228
|
- `cargo-index-entry`: the version's line of the sparse index; a missing line rejects with `package-document-missing`.
|
|
205
229
|
- `cargo-description`: `{"description":…}` from the crate's entry in the Cargo search (`api/v1/crates?q=<name>`, the entry with exactly that name, read page by page, at most 200 pages of 50). Gitea's search describes only the version with the highest id, so its `max_version` must be the requested version; otherwise, or when no entry has the name, it rejects with `package-document-missing`, and a search that has not run out after 200 pages with `cargo-search-over-bound`.
|
|
206
230
|
|
package/ts/00_commitinfo_data.ts
CHANGED