@foss.global/codefeed 5.3.0 → 5.4.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 +22 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.giteasourceinventory.d.ts +11 -1
- package/dist_ts/classes.giteasourceinventory.js +77 -10
- 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 +3 -3
- package/readme.md +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.giteasourceinventory.ts +100 -14
- 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.4.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.
|
|
14
|
+
"@foss.global/forgefixtures": "^1.1.0",
|
|
15
15
|
"@git.zone/tsrepo": "^2.1.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.3.0",
|
|
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
|
@@ -200,7 +200,7 @@ The package reads take selectors from the inventory's package records: the packa
|
|
|
200
200
|
- `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
201
|
- `npm-version`: the version document.
|
|
202
202
|
- `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>`.
|
|
203
|
+
- `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
204
|
- `cargo-index-entry`: the version's line of the sparse index; a missing line rejects with `package-document-missing`.
|
|
205
205
|
- `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
206
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,9 +3,11 @@ import * as transport from './forgeinventory.transport.js';
|
|
|
3
3
|
import * as validation from './forgeinventory.validation.js';
|
|
4
4
|
import { ForgeRequestClient } from './forgeinventory.client.js';
|
|
5
5
|
import type { IForgeRequestMetrics, IForgeRequestOptions } from './forgeinventory.client.js';
|
|
6
|
+
import { verifiedPackageDownload } from './forgeinventory.transfer.js';
|
|
6
7
|
import { measureGiteaMirror } from './giteasourceinventory.git.js';
|
|
7
8
|
import {
|
|
8
9
|
cargoIndexPath, comparePackages, composeGiteaPackageContent, containerIndexMediaTypes, npmPackagePath, packageKey, packageTypePattern,
|
|
10
|
+
readSwiftManifest, swiftManifestCandidates, swiftPackageParts,
|
|
9
11
|
} from './giteasourceinventory.packages.js';
|
|
10
12
|
|
|
11
13
|
type TMeasure = plugins.fossInterfaces.data.TForgeSourceMeasure;
|
|
@@ -32,6 +34,7 @@ type IPackageRef = plugins.fossInterfaces.data.IForgeSourcePackageRef;
|
|
|
32
34
|
type IPackageRecord = plugins.fossInterfaces.data.IForgeSourcePackageInventory;
|
|
33
35
|
type IPackageVersion = plugins.fossInterfaces.data.IForgeSourcePackageVersion;
|
|
34
36
|
type IPackageBlob = plugins.fossInterfaces.data.IForgeSourcePackageBlob;
|
|
37
|
+
type ISwiftManifest = plugins.fossInterfaces.data.IForgeSourceSwiftManifest;
|
|
35
38
|
|
|
36
39
|
export interface IGiteaSourceInventoryOptions {
|
|
37
40
|
/** Operator-assigned identity of the source instance. */
|
|
@@ -58,8 +61,18 @@ export interface IGiteaSourceInventoryOptions {
|
|
|
58
61
|
pageSize?: number;
|
|
59
62
|
/** Pages read per listing before the listing counts as partial. */
|
|
60
63
|
maxPages?: number;
|
|
64
|
+
/** Deadline of one REST, registry or LFS batch request, and the idle limit of a Swift archive download; defaults to 60 s, at most 300 s. */
|
|
61
65
|
requestTimeoutMs?: number;
|
|
62
66
|
maxResponseBytes?: number;
|
|
67
|
+
/**
|
|
68
|
+
* The largest Swift source archive, in bytes, that the inventory reads for
|
|
69
|
+
* the version's `manifests`; defaults to 128 MiB, at most 1 GiB. A version
|
|
70
|
+
* whose recorded archive is larger is not read and records `manifests:
|
|
71
|
+
* null`. A consumer passes the cap its own store puts on an archive.
|
|
72
|
+
*/
|
|
73
|
+
maxSwiftArchiveBytes?: number;
|
|
74
|
+
/** Wall-clock limit of one Swift archive download; defaults to 30 minutes, at most six hours. */
|
|
75
|
+
packageTransferTimeoutMs?: number;
|
|
63
76
|
}
|
|
64
77
|
|
|
65
78
|
/** A class of source data a run measures only when its discovery selects it. */
|
|
@@ -88,6 +101,9 @@ export type TGiteaSourceRepositoryLookup =
|
|
|
88
101
|
| { status: 'present'; id: string; owner: string; name: string }
|
|
89
102
|
| { status: 'absent'; id: string };
|
|
90
103
|
|
|
104
|
+
/** A file of a version as its listing reports it: the name, and the content's SHA-256 and size as a canonical decimal. */
|
|
105
|
+
interface IVersionFile { name: string; sha256: string; size: string }
|
|
106
|
+
|
|
91
107
|
interface IListing {
|
|
92
108
|
items: unknown[];
|
|
93
109
|
/** A sanitized reason when the listing did not finish. */
|
|
@@ -415,11 +431,13 @@ const compareText = (aArg: string, bArg: string): number => aArg < bArg ? -1 : a
|
|
|
415
431
|
export class GiteaSourceInventory {
|
|
416
432
|
readonly #options: {
|
|
417
433
|
instanceId: string; baseUrl: string; pageSize: number; maxPages: number; requestTimeoutMs: number; maxResponseBytes: number;
|
|
418
|
-
token: string; caCertificates?: string[]; gitWorkDir: string; gitTimeoutMs: number;
|
|
434
|
+
token: string; caCertificates?: string[]; gitWorkDir: string; gitTimeoutMs: number; maxSwiftArchiveBytes: number; packageTransferTimeoutMs: number;
|
|
419
435
|
};
|
|
420
436
|
readonly #transport: transport.TForgeTransport;
|
|
421
437
|
readonly #client: ForgeRequestClient;
|
|
422
438
|
#lfsClient: ForgeRequestClient | null = null;
|
|
439
|
+
/** The Swift archive GETs, which go through `verifiedPackageDownload` instead of a request client. */
|
|
440
|
+
readonly #archiveMetrics: IForgeRequestMetrics = { requests: 0, responseBytes: 0, rateLimitedRequests: 0 };
|
|
423
441
|
#readerLogin: Promise<string> | null = null;
|
|
424
442
|
|
|
425
443
|
constructor(optionsArg: IGiteaSourceInventoryOptions) {
|
|
@@ -435,9 +453,12 @@ export class GiteaSourceInventory {
|
|
|
435
453
|
requestTimeoutMs: optionsArg.requestTimeoutMs ?? 60_000,
|
|
436
454
|
maxResponseBytes: optionsArg.maxResponseBytes ?? 16 * 1024 * 1024,
|
|
437
455
|
gitTimeoutMs: optionsArg.gitTimeoutMs ?? 30 * 60 * 1000,
|
|
456
|
+
maxSwiftArchiveBytes: optionsArg.maxSwiftArchiveBytes ?? 128 * 1024 * 1024,
|
|
457
|
+
packageTransferTimeoutMs: optionsArg.packageTransferTimeoutMs ?? 30 * 60 * 1000,
|
|
438
458
|
};
|
|
439
459
|
for (const [name, maximum] of [
|
|
440
460
|
['pageSize', 100], ['maxPages', 1_000_000], ['requestTimeoutMs', 300_000], ['maxResponseBytes', 64 * 1024 * 1024], ['gitTimeoutMs', 6 * 60 * 60 * 1000],
|
|
461
|
+
['maxSwiftArchiveBytes', 1024 * 1024 * 1024], ['packageTransferTimeoutMs', 6 * 60 * 60 * 1000],
|
|
441
462
|
] as const) {
|
|
442
463
|
const value = limits[name];
|
|
443
464
|
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) throw new validation.ForgeInventoryError('invalid-limits');
|
|
@@ -459,14 +480,15 @@ export class GiteaSourceInventory {
|
|
|
459
480
|
/** Validated, normalized instance root; contains no credentials or API suffix. */
|
|
460
481
|
public get baseUrl(): string { return this.#options.baseUrl; }
|
|
461
482
|
|
|
462
|
-
/** REST and LFS batch requests together. */
|
|
483
|
+
/** REST, registry and LFS batch requests and Swift archive GETs together. */
|
|
463
484
|
public get metrics(): IForgeRequestMetrics {
|
|
464
485
|
const rest = this.#client.metrics;
|
|
465
486
|
const lfs = this.#lfsClient?.metrics ?? { requests: 0, responseBytes: 0, rateLimitedRequests: 0 };
|
|
487
|
+
const archives = this.#archiveMetrics;
|
|
466
488
|
return {
|
|
467
|
-
requests: rest.requests + lfs.requests,
|
|
468
|
-
responseBytes: rest.responseBytes + lfs.responseBytes,
|
|
469
|
-
rateLimitedRequests: rest.rateLimitedRequests + lfs.rateLimitedRequests,
|
|
489
|
+
requests: rest.requests + lfs.requests + archives.requests,
|
|
490
|
+
responseBytes: rest.responseBytes + lfs.responseBytes + archives.responseBytes,
|
|
491
|
+
rateLimitedRequests: rest.rateLimitedRequests + lfs.rateLimitedRequests + archives.rateLimitedRequests,
|
|
470
492
|
};
|
|
471
493
|
}
|
|
472
494
|
|
|
@@ -805,9 +827,11 @@ export class GiteaSourceInventory {
|
|
|
805
827
|
* whose only file is `manifest.json`, are read by digest for their
|
|
806
828
|
* references; no other manifest is read. npm packages add the dist-tags Gitea
|
|
807
829
|
* serves (a derived `latest` included) and each version's deprecation,
|
|
808
|
-
* Cargo crates each version's yank from the sparse index
|
|
809
|
-
*
|
|
810
|
-
*
|
|
830
|
+
* Cargo crates each version's yank from the sparse index, Swift packages
|
|
831
|
+
* each version's manifests, read from its archive's file names and Gitea's
|
|
832
|
+
* manifest route. Every read is a GET; reading an index or a Swift archive
|
|
833
|
+
* counts a download of its version, an accepted read stamp (S10 ruling,
|
|
834
|
+
* Addendum 1; S10 C5 ruling, Addendum 2).
|
|
811
835
|
*/
|
|
812
836
|
async #package(refArg: IPackageRef, signalArg?: AbortSignal): Promise<IPackageRecord> {
|
|
813
837
|
const packagePath = `/packages/${encodeURIComponent(refArg.owner)}/${encodeURIComponent(refArg.type)}/${encodeURIComponent(refArg.name)}`;
|
|
@@ -838,11 +862,11 @@ export class GiteaSourceInventory {
|
|
|
838
862
|
}
|
|
839
863
|
versions.sort((aArg, bArg) => compareDecimal(aArg.id, bArg.id));
|
|
840
864
|
const blobs = new Map<string, IPackageBlob>();
|
|
841
|
-
const filesByVersion = new Map<string,
|
|
865
|
+
const filesByVersion = new Map<string, IVersionFile[]>();
|
|
842
866
|
for (const version of versions) {
|
|
843
867
|
const files = (await this.#get(`${packagePath}/${encodeURIComponent(version.version)}/files`, { signal: signalArg })).body;
|
|
844
868
|
if (!Array.isArray(files)) throw new validation.ForgeInventoryError('invalid-page');
|
|
845
|
-
const read:
|
|
869
|
+
const read: IVersionFile[] = [];
|
|
846
870
|
for (const fileArg of files) {
|
|
847
871
|
const file = validation.record(fileArg);
|
|
848
872
|
const sha256 = requiredString(file.sha256);
|
|
@@ -853,7 +877,7 @@ export class GiteaSourceInventory {
|
|
|
853
877
|
const name = requiredString(file.name);
|
|
854
878
|
blob.files.push({ versionId: version.id, id: validation.decimal(file.id), name });
|
|
855
879
|
blobs.set(sha256, blob);
|
|
856
|
-
read.push({ name, sha256 });
|
|
880
|
+
read.push({ name, sha256, size });
|
|
857
881
|
}
|
|
858
882
|
filesByVersion.set(version.id, read);
|
|
859
883
|
}
|
|
@@ -866,6 +890,7 @@ export class GiteaSourceInventory {
|
|
|
866
890
|
if (record.type === 'container') await this.#containerReferences(record, filesByVersion, signalArg);
|
|
867
891
|
if (record.type === 'npm') await this.#npmState(record, signalArg);
|
|
868
892
|
if (record.type === 'cargo') await this.#cargoYanks(record, signalArg);
|
|
893
|
+
if (record.type === 'swift') await this.#swiftManifests(record, filesByVersion, signalArg);
|
|
869
894
|
return record;
|
|
870
895
|
}
|
|
871
896
|
|
|
@@ -876,9 +901,7 @@ export class GiteaSourceInventory {
|
|
|
876
901
|
* bytes must hash to the listed SHA-256 and the response must be an index or
|
|
877
902
|
* a manifest list, else the unit fails with `unexpected-manifest-shape`.
|
|
878
903
|
*/
|
|
879
|
-
async #containerReferences(
|
|
880
|
-
recordArg: IPackageRecord, filesArg: ReadonlyMap<string, Array<{ name: string; sha256: string }>>, signalArg?: AbortSignal,
|
|
881
|
-
): Promise<void> {
|
|
904
|
+
async #containerReferences(recordArg: IPackageRecord, filesArg: ReadonlyMap<string, IVersionFile[]>, signalArg?: AbortSignal): Promise<void> {
|
|
882
905
|
if (!/^[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*$/.test(recordArg.name)) {
|
|
883
906
|
throw new validation.ForgeInventoryError('invalid-image-name');
|
|
884
907
|
}
|
|
@@ -911,6 +934,69 @@ export class GiteaSourceInventory {
|
|
|
911
934
|
}
|
|
912
935
|
}
|
|
913
936
|
|
|
937
|
+
/**
|
|
938
|
+
* Each Swift version's `manifests`. Gitea stores one file per version, its
|
|
939
|
+
* source archive, and anything else fails the unit with
|
|
940
|
+
* `swift-version-files-unexpected`. An archive over `maxSwiftArchiveBytes`
|
|
941
|
+
* by its recorded size is not read and records `null`. Otherwise the
|
|
942
|
+
* archive is read once and verified against its recorded size and SHA-256,
|
|
943
|
+
* its central directory gives the candidate keys (`swiftManifestCandidates`),
|
|
944
|
+
* and the manifest route is asked for each: a 200 is recorded with the size
|
|
945
|
+
* and SHA-256 of the bytes, the 303 to the release's `Package.swift` means
|
|
946
|
+
* Gitea holds no such manifest, and `''` must answer 200. A failed read
|
|
947
|
+
* fails the unit; it never records `null`.
|
|
948
|
+
*/
|
|
949
|
+
async #swiftManifests(recordArg: IPackageRecord, filesArg: ReadonlyMap<string, IVersionFile[]>, signalArg?: AbortSignal): Promise<void> {
|
|
950
|
+
const parts = swiftPackageParts(recordArg.name);
|
|
951
|
+
for (const version of recordArg.versions) {
|
|
952
|
+
const files = filesArg.get(version.id)!;
|
|
953
|
+
if (files.length !== 1) throw new validation.ForgeInventoryError('swift-version-files-unexpected');
|
|
954
|
+
// The native store's comparison: an archive of exactly the bound is held.
|
|
955
|
+
if (BigInt(files[0].size) > BigInt(this.#options.maxSwiftArchiveBytes)) {
|
|
956
|
+
version.manifests = null;
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
const keys = swiftManifestCandidates(await this.#swiftArchive(recordArg, parts, version, files[0], signalArg));
|
|
960
|
+
const manifests: ISwiftManifest[] = [];
|
|
961
|
+
for (const key of keys) {
|
|
962
|
+
const manifest = await readSwiftManifest(this.#client, this.#options.baseUrl, recordArg.owner, parts, version.version, key === '' ? null : key, signalArg);
|
|
963
|
+
if (manifest === null) continue;
|
|
964
|
+
manifests.push({ key, size: manifest.bytes.byteLength, sha256: plugins.crypto.createHash('sha256').update(manifest.bytes).digest('hex') });
|
|
965
|
+
}
|
|
966
|
+
version.manifests = manifests;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* A Swift version's source archive, read once with the reader's `token`
|
|
972
|
+
* authorization through `verifiedPackageDownload` (exact size, SHA-256
|
|
973
|
+
* before the last chunk) into one buffer of the recorded size. The read
|
|
974
|
+
* counts a download of the version, an accepted read stamp (S10 ruling
|
|
975
|
+
* item 8; S10 C5 ruling, Addendum 2).
|
|
976
|
+
*/
|
|
977
|
+
async #swiftArchive(
|
|
978
|
+
recordArg: IPackageRecord, partsArg: { scope: string; name: string }, versionArg: IPackageVersion, fileArg: IVersionFile, signalArg?: AbortSignal,
|
|
979
|
+
): Promise<Buffer> {
|
|
980
|
+
const url = new URL(`${this.#options.baseUrl}/api/packages/${encodeURIComponent(recordArg.owner)}/swift/${encodeURIComponent(partsArg.scope)}/${
|
|
981
|
+
encodeURIComponent(partsArg.name)}/${encodeURIComponent(versionArg.version)}.zip`);
|
|
982
|
+
const bytes = Number(fileArg.size);
|
|
983
|
+
const stream = await verifiedPackageDownload(
|
|
984
|
+
{
|
|
985
|
+
caCertificates: this.#options.caCertificates, packageTransferTimeoutMs: this.#options.packageTransferTimeoutMs,
|
|
986
|
+
requestTimeoutMs: this.#options.requestTimeoutMs, metrics: this.#archiveMetrics,
|
|
987
|
+
},
|
|
988
|
+
url, { authorization: `token ${this.#options.token}`, accept: 'application/vnd.swift.registry.v1+zip' },
|
|
989
|
+
{ sha256: fileArg.sha256, size: fileArg.size, bytes }, signalArg, null,
|
|
990
|
+
);
|
|
991
|
+
const archive = Buffer.alloc(bytes);
|
|
992
|
+
let offset = 0;
|
|
993
|
+
for await (const chunk of stream as AsyncIterable<Uint8Array>) {
|
|
994
|
+
archive.set(chunk, offset);
|
|
995
|
+
offset += chunk.byteLength;
|
|
996
|
+
}
|
|
997
|
+
return archive;
|
|
998
|
+
}
|
|
999
|
+
|
|
914
1000
|
/** Every dist-tag Gitea serves, a `latest` it derives included, and each version's deprecation from the package document. */
|
|
915
1001
|
async #npmState(recordArg: IPackageRecord, signalArg?: AbortSignal): Promise<void> {
|
|
916
1002
|
const registry = `${this.#options.baseUrl}/api/packages/${encodeURIComponent(recordArg.owner)}/npm`;
|