@foss.global/codefeed 5.2.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 +46 -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.d.ts +52 -15
- package/dist_ts/classes.giteasourcetransfer.js +93 -103
- package/dist_ts/forgeinventory.client.d.ts +21 -1
- package/dist_ts/forgeinventory.client.js +30 -5
- package/dist_ts/forgeinventory.transfer.d.ts +24 -0
- package/dist_ts/forgeinventory.transfer.js +77 -1
- package/dist_ts/forgeinventory.transport.d.ts +21 -7
- package/dist_ts/forgeinventory.transport.js +15 -10
- package/dist_ts/giteasourceinventory.packages.d.ts +49 -0
- package/dist_ts/giteasourceinventory.packages.js +180 -1
- package/dist_ts/giteasourcetransfer.documents.d.ts +50 -0
- package/dist_ts/giteasourcetransfer.documents.js +130 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +2 -1
- package/package.json +3 -3
- package/readme.md +10 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.giteasourceinventory.ts +100 -14
- package/ts/classes.giteasourcetransfer.ts +145 -102
- package/ts/forgeinventory.client.ts +48 -6
- package/ts/forgeinventory.transfer.ts +88 -0
- package/ts/forgeinventory.transport.ts +33 -13
- package/ts/giteasourceinventory.packages.ts +168 -0
- package/ts/giteasourcetransfer.documents.ts +140 -0
- package/ts/index.ts +2 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as transport from './forgeinventory.transport.js';
|
|
1
2
|
import * as validation from './forgeinventory.validation.js';
|
|
2
3
|
/**
|
|
3
4
|
* One bounded, credential-scoped read at a time, a GET or a POST with a JSON
|
|
@@ -14,7 +15,7 @@ export class ForgeRequestClient {
|
|
|
14
15
|
get metrics() { return { ...this.#metrics }; }
|
|
15
16
|
async request(url, requestArg = {}) {
|
|
16
17
|
const mediaType = requestArg.mediaType ?? 'application/json';
|
|
17
|
-
const response = await this.#
|
|
18
|
+
const response = await this.#body(url, {
|
|
18
19
|
signal: requestArg.signal, maxResponseBytes: requestArg.maxResponseBytes, headers: requestArg.headers, accept: mediaType, requiredMediaType: mediaType,
|
|
19
20
|
...(requestArg.json === undefined ? {} : { body: { mediaType, bytes: new TextEncoder().encode(JSON.stringify(requestArg.json)) } }),
|
|
20
21
|
});
|
|
@@ -27,9 +28,29 @@ export class ForgeRequestClient {
|
|
|
27
28
|
}
|
|
28
29
|
/** A GET whose body is returned as the bytes that arrived, with the media type the response declared. */
|
|
29
30
|
async requestBytes(url, requestArg) {
|
|
30
|
-
const response = await this.#
|
|
31
|
+
const response = await this.#body(url, requestArg);
|
|
31
32
|
return { bytes: response.bytes, mediaType: mediaTypeOf(response.headers), headers: response.headers };
|
|
32
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* A GET like `requestBytes`, except that a redirect status resolves as
|
|
36
|
+
* `{ kind: 'redirect', status, location }` instead of rejecting. The
|
|
37
|
+
* redirect is never followed and its body is discarded unread; any status
|
|
38
|
+
* other than 200 and a redirect still rejects with `http-<status>`.
|
|
39
|
+
*/
|
|
40
|
+
async requestBytesOrRedirect(url, requestArg) {
|
|
41
|
+
const response = await this.#read(url, { ...requestArg, redirect: 'return' });
|
|
42
|
+
return response.kind === 'redirect'
|
|
43
|
+
? response
|
|
44
|
+
: { kind: 'bytes', bytes: response.bytes, mediaType: mediaTypeOf(response.headers), headers: response.headers };
|
|
45
|
+
}
|
|
46
|
+
/** A read that refuses redirects, so it always answers a body. */
|
|
47
|
+
async #body(url, requestArg) {
|
|
48
|
+
const response = await this.#read(url, requestArg);
|
|
49
|
+
// The transport refuses every redirect status in this mode, so a redirect never arrives here.
|
|
50
|
+
if (response.kind === 'redirect')
|
|
51
|
+
throw new validation.ForgeInventoryError('request-or-json-failed');
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
33
54
|
async #read(url, requestArg) {
|
|
34
55
|
const { signal } = requestArg;
|
|
35
56
|
const maxBytes = requestArg.maxResponseBytes ?? this.#options.maxResponseBytes;
|
|
@@ -48,10 +69,14 @@ export class ForgeRequestClient {
|
|
|
48
69
|
const headers = {
|
|
49
70
|
accept: requestArg.accept, ...(requestArg.body ? { 'content-type': requestArg.body.mediaType } : {}), ...requestArg.headers, ...this.#options.headers,
|
|
50
71
|
};
|
|
51
|
-
const response = await this.#options.transport(url, headers, controller.signal, requestArg.body?.bytes);
|
|
72
|
+
const response = await this.#options.transport(url, headers, controller.signal, requestArg.body?.bytes, { redirect: requestArg.redirect ?? 'refuse' });
|
|
52
73
|
bodyChunks = response.body?.[Symbol.asyncIterator]();
|
|
53
74
|
if (response.status === 429)
|
|
54
75
|
this.#metrics.rateLimitedRequests++;
|
|
76
|
+
if (requestArg.redirect === 'return' && transport.redirectStatuses.has(response.status)) {
|
|
77
|
+
// The body is discarded unread by the `finally` below.
|
|
78
|
+
return { kind: 'redirect', status: response.status, location: response.headers.get('location') };
|
|
79
|
+
}
|
|
55
80
|
if (response.status !== 200)
|
|
56
81
|
throw new validation.ForgeInventoryError(`http-${response.status}`);
|
|
57
82
|
if ((requestArg.requiredMediaType !== undefined && mediaTypeOf(response.headers) !== requestArg.requiredMediaType) || !bodyChunks) {
|
|
@@ -73,7 +98,7 @@ export class ForgeRequestClient {
|
|
|
73
98
|
}
|
|
74
99
|
if (controller.signal.aborted || Date.now() >= deadline)
|
|
75
100
|
throw new validation.ForgeInventoryError('request-aborted-or-timed-out');
|
|
76
|
-
return { bytes: Buffer.concat(chunks), headers: response.headers };
|
|
101
|
+
return { kind: 'bytes', bytes: Buffer.concat(chunks), headers: response.headers };
|
|
77
102
|
}
|
|
78
103
|
catch (error) {
|
|
79
104
|
if (error instanceof validation.ForgeInventoryError)
|
|
@@ -94,4 +119,4 @@ export class ForgeRequestClient {
|
|
|
94
119
|
}
|
|
95
120
|
/** A response's media type without parameters, lowercased; null when it sent none. */
|
|
96
121
|
const mediaTypeOf = (headersArg) => headersArg.get('content-type')?.split(';')[0].trim().toLowerCase() || null;
|
|
97
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZ2VpbnZlbnRvcnkuY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvZm9yZ2VpbnZlbnRvcnkuY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxTQUFTLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFVBQVUsTUFBTSxnQ0FBZ0MsQ0FBQztBQThFN0Q7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ3BCLFFBQVEsQ0FBNkI7SUFDckMsUUFBUSxHQUF5QixFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUVwRyxZQUFZLFVBQXNDO1FBQ2hELElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxHQUFHLFVBQVUsRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ3hFLENBQUM7SUFFRCxJQUFXLE9BQU8sS0FBMkIsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVwRSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQVEsRUFBRSxVQUFVLEdBQXlCLEVBQUU7UUFDbEUsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLFNBQVMsSUFBSSxrQkFBa0IsQ0FBQztRQUM3RCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO1lBQ3JDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLFNBQVM7WUFDdEosR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxF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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import * as validation from './forgeinventory.validation.js';
|
|
3
|
+
import type { IForgeRequestMetrics } from './forgeinventory.client.js';
|
|
3
4
|
/**
|
|
4
5
|
* Reads and drops at most 64 KiB of a response body that carries nothing the
|
|
5
6
|
* caller uses, so its connection can be reused; a longer or failing body is
|
|
@@ -73,3 +74,26 @@ export declare function heldBackChunks(sourceArg: AsyncIterable<Uint8Array>, siz
|
|
|
73
74
|
* The stream errors with what `chunksArg` throws.
|
|
74
75
|
*/
|
|
75
76
|
export declare const createTransferStream: (boundsArg: ITransferBounds, chunksArg: AsyncGenerator<Uint8Array, void, undefined>, onEndArg?: () => void) => InstanceType<typeof plugins.stream.Readable>;
|
|
77
|
+
/** The reader settings a verified package content download runs with. */
|
|
78
|
+
export interface IVerifiedPackageDownloadOptions {
|
|
79
|
+
/** PEM certificates that replace the default trust store for the download's connection. */
|
|
80
|
+
caCertificates?: string[];
|
|
81
|
+
/** Wall-clock limit of the whole download, the closing `identifiedArg` read included. */
|
|
82
|
+
packageTransferTimeoutMs: number;
|
|
83
|
+
/** Idle limit of the download, re-armed on every chunk and before the closing `identifiedArg` read. */
|
|
84
|
+
requestTimeoutMs: number;
|
|
85
|
+
/** Counts the request, a 429 answer and every body byte that arrives, as `ForgeRequestClient` counts its reads. */
|
|
86
|
+
metrics?: IForgeRequestMetrics;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Streams one package content download verified against `contentArg`, sent
|
|
90
|
+
* over node:https with the caller's CA certificates: the response must be a
|
|
91
|
+
* 200 whose `content-length`, when sent, is the size; the last chunk is held
|
|
92
|
+
* back until the size and SHA-256 match and `identifiedArg`, when given, has
|
|
93
|
+
* passed once more.
|
|
94
|
+
*/
|
|
95
|
+
export declare const verifiedPackageDownload: (optionsArg: IVerifiedPackageDownloadOptions, urlArg: URL, headersArg: Record<string, string>, contentArg: {
|
|
96
|
+
sha256: string;
|
|
97
|
+
size: string;
|
|
98
|
+
bytes: number;
|
|
99
|
+
}, signalArg: AbortSignal | undefined, identifiedArg: ((signalArg: AbortSignal) => Promise<void>) | null) => Promise<InstanceType<typeof plugins.stream.Readable>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
+
import * as transport from './forgeinventory.transport.js';
|
|
2
3
|
import * as validation from './forgeinventory.validation.js';
|
|
3
4
|
/** Response bytes read from an unused answer before the rest is discarded. */
|
|
4
5
|
const maxDiscardedResponseBytes = 64 * 1024;
|
|
@@ -171,4 +172,79 @@ export const createTransferStream = (boundsArg, chunksArg, onEndArg) => {
|
|
|
171
172
|
});
|
|
172
173
|
return stream;
|
|
173
174
|
};
|
|
174
|
-
|
|
175
|
+
/** Passes `sourceArg`'s chunks on, adding each one's bytes to `metricsArg` as it arrives. */
|
|
176
|
+
async function* countedBytes(sourceArg, metricsArg) {
|
|
177
|
+
for await (const chunk of sourceArg) {
|
|
178
|
+
if (chunk instanceof Uint8Array)
|
|
179
|
+
metricsArg.responseBytes += chunk.byteLength;
|
|
180
|
+
yield chunk;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** The `heldBackChunks` codes of a package content download. */
|
|
184
|
+
const packageContentCodes = {
|
|
185
|
+
invalidChunk: 'package-content-invalid-chunk', overrun: 'package-content-size-overrun', short: 'package-content-short-body',
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Streams one package content download verified against `contentArg`, sent
|
|
189
|
+
* over node:https with the caller's CA certificates: the response must be a
|
|
190
|
+
* 200 whose `content-length`, when sent, is the size; the last chunk is held
|
|
191
|
+
* back until the size and SHA-256 match and `identifiedArg`, when given, has
|
|
192
|
+
* passed once more.
|
|
193
|
+
*/
|
|
194
|
+
export const verifiedPackageDownload = async (optionsArg, urlArg, headersArg, contentArg, signalArg, identifiedArg) => {
|
|
195
|
+
if (signalArg?.aborted)
|
|
196
|
+
throw new validation.ForgeInventoryError('request-aborted');
|
|
197
|
+
const agents = transport.createNodeAgents(optionsArg.caCertificates);
|
|
198
|
+
const close = () => agents.https?.destroy();
|
|
199
|
+
const transfer = createTransferBounds(signalArg, {
|
|
200
|
+
limitMs: optionsArg.packageTransferTimeoutMs, idleMs: optionsArg.requestTimeoutMs,
|
|
201
|
+
timedOutCode: 'package-content-transfer-timed-out', failedCode: 'package-content-transfer-failed',
|
|
202
|
+
});
|
|
203
|
+
const { metrics } = optionsArg;
|
|
204
|
+
let body;
|
|
205
|
+
try {
|
|
206
|
+
if (metrics)
|
|
207
|
+
metrics.requests++;
|
|
208
|
+
const response = await transfer.run(() => transport.sendNodeRequest(urlArg, { method: 'GET', headers: headersArg, signal: transfer.signal, agents }));
|
|
209
|
+
if (metrics && response.status === 429)
|
|
210
|
+
metrics.rateLimitedRequests++;
|
|
211
|
+
if (response.status !== 200 || !response.body) {
|
|
212
|
+
await transfer.run(() => discardBody(response.body));
|
|
213
|
+
throw new validation.ForgeInventoryError(`http-${response.status}`);
|
|
214
|
+
}
|
|
215
|
+
const length = response.headers.get('content-length');
|
|
216
|
+
if (length !== null && length.trim() !== contentArg.size) {
|
|
217
|
+
await transfer.run(() => discardBody(response.body));
|
|
218
|
+
throw new validation.ForgeInventoryError('package-content-size-mismatch');
|
|
219
|
+
}
|
|
220
|
+
body = metrics ? countedBytes(response.body, metrics) : response.body;
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
const failure = transfer.failure(error, 'package-content-download-failed');
|
|
224
|
+
transfer.end();
|
|
225
|
+
close();
|
|
226
|
+
throw failure;
|
|
227
|
+
}
|
|
228
|
+
const hash = plugins.crypto.createHash('sha256');
|
|
229
|
+
const complete = async () => {
|
|
230
|
+
if (hash.digest('hex') !== contentArg.sha256)
|
|
231
|
+
throw new validation.ForgeInventoryError('package-content-digest-mismatch');
|
|
232
|
+
if (identifiedArg) {
|
|
233
|
+
transfer.touch();
|
|
234
|
+
await transfer.run(() => identifiedArg(transfer.signal));
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
const chunks = async function* () {
|
|
238
|
+
try {
|
|
239
|
+
yield* heldBackChunks(transfer.watch(body), contentArg.bytes, packageContentCodes, { inspect: (chunkArg) => hash.update(chunkArg), complete });
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
throw transfer.failure(error, 'package-content-download-failed');
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
transfer.end();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
return createTransferStream(transfer, chunks(), close);
|
|
249
|
+
};
|
|
250
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZ2VpbnZlbnRvcnkudHJhbnNmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9mb3JnZWludmVudG9yeS50cmFuc2Zlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssU0FBUyxNQUFNLCtCQUErQixDQUFDO0FBQzNELE9BQU8sS0FBSyxVQUFVLE1BQU0sZ0NBQWdDLENBQUM7QUFHN0QsOEVBQThFO0FBQzlFLE1BQU0seUJBQXlCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUU1Qzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLEtBQUssRUFBRSxPQUF5QyxFQUFpQixFQUFFO0lBQzVGLElBQUksQ0FBQyxPQUFPO1FBQUUsT0FBTztJQUNyQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7SUFDL0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsSUFBSSxDQUFDO1FBQ0gsT0FBTyxLQUFLLElBQUkseUJBQXlCLEVBQUUsQ0FBQztZQUMxQyxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNuQyxJQUFJLE1BQU0sQ0FBQyxJQUFJO2dCQUFFLE9BQU87WUFDeEIsS0FBSyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsMENBQTBDO0lBQzVDLENBQUM7WUFBUyxDQUFDO1FBQ1QsSUFBSSxDQUFDO1lBQUMsTUFBTSxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUFDLENBQUM7UUFBQyxNQUFNLENBQUMsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0lBQy9FLENBQUM7QUFDSCxDQUFDLENBQUM7QUFnQ0Y7Ozs7R0FJRztBQUNILE1B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
|
|
@@ -6,13 +6,24 @@ export interface IForgeTransportResponse {
|
|
|
6
6
|
/** Iterated at most once; returning the iterator before the end cancels the body and discards the connection. */
|
|
7
7
|
body: AsyncIterable<Uint8Array> | null;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* What a transport does with a redirect status: `refuse` rejects it, `return`
|
|
11
|
+
* resolves it as the response it is, `Location` included. Neither follows it.
|
|
12
|
+
*/
|
|
13
|
+
export type TForgeRedirectMode = 'refuse' | 'return';
|
|
14
|
+
export interface IForgeTransportOptions {
|
|
15
|
+
/** Defaults to `refuse`. */
|
|
16
|
+
redirect?: TForgeRedirectMode;
|
|
17
|
+
}
|
|
9
18
|
/**
|
|
10
19
|
* Sends one credential-scoped GET, or a POST of `body` when one is given, and
|
|
11
|
-
* resolves once response headers arrive. A redirect status
|
|
12
|
-
*
|
|
13
|
-
* body is still being read.
|
|
20
|
+
* resolves once response headers arrive. A redirect status is never followed:
|
|
21
|
+
* it rejects, unless `options.redirect` is `return`. Aborting `signal`
|
|
22
|
+
* discards the connection, also while the body is still being read.
|
|
14
23
|
*/
|
|
15
|
-
export type TForgeTransport = (url: URL, headers: Record<string, string>, signal: AbortSignal, body?: Uint8Array<ArrayBuffer
|
|
24
|
+
export type TForgeTransport = (url: URL, headers: Record<string, string>, signal: AbortSignal, body?: Uint8Array<ArrayBuffer>, options?: IForgeTransportOptions) => Promise<IForgeTransportResponse>;
|
|
25
|
+
/** The fetch statuses whose redirect mode `error` turns them into a network error. */
|
|
26
|
+
export declare const redirectStatuses: ReadonlySet<number>;
|
|
16
27
|
/** Node's global `fetch` with the process-wide default trust store. */
|
|
17
28
|
export declare const globalFetchTransport: TForgeTransport;
|
|
18
29
|
/** The agents a node request may use; a URL whose protocol has no agent is refused. */
|
|
@@ -27,6 +38,8 @@ export interface INodeRequest {
|
|
|
27
38
|
body?: Uint8Array | AsyncIterable<Uint8Array>;
|
|
28
39
|
signal: AbortSignal;
|
|
29
40
|
agents: INodeRequestAgents;
|
|
41
|
+
/** Defaults to `refuse`. */
|
|
42
|
+
redirect?: TForgeRedirectMode;
|
|
30
43
|
}
|
|
31
44
|
export interface INodeResponse extends IForgeTransportResponse {
|
|
32
45
|
/**
|
|
@@ -42,9 +55,10 @@ export interface INodeResponse extends IForgeTransportResponse {
|
|
|
42
55
|
export declare const createNodeAgents: (caCertificatesArg?: string[], allowHttpArg?: boolean) => INodeRequestAgents;
|
|
43
56
|
/**
|
|
44
57
|
* Sends one request through `node:http` or `node:https` and resolves once
|
|
45
|
-
* response headers arrive. A redirect status
|
|
46
|
-
*
|
|
47
|
-
* sent or read. A streamed body that fails
|
|
58
|
+
* response headers arrive. A redirect status is never followed: it rejects,
|
|
59
|
+
* unless `redirect` is `return`. Aborting `signal` discards the connection,
|
|
60
|
+
* also while a body is still being sent or read. A streamed body that fails
|
|
61
|
+
* destroys the request and rejects.
|
|
48
62
|
*/
|
|
49
63
|
export declare const sendNodeRequest: (url: URL, requestArg: INodeRequest) => Promise<INodeResponse>;
|
|
50
64
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
/** The fetch statuses whose redirect mode `error` turns them into a network error. */
|
|
3
|
-
const redirectStatuses = new Set([301, 302, 303, 307, 308]);
|
|
3
|
+
export const redirectStatuses = new Set([301, 302, 303, 307, 308]);
|
|
4
4
|
/**
|
|
5
5
|
* Idle keep-alive sockets close after this delay, or earlier when the server
|
|
6
6
|
* announces a shorter `Keep-Alive: timeout`, so a pooled socket is not reused
|
|
@@ -8,8 +8,10 @@ const redirectStatuses = new Set([301, 302, 303, 307, 308]);
|
|
|
8
8
|
*/
|
|
9
9
|
const idleSocketTimeoutMs = 4_000;
|
|
10
10
|
/** Node's global `fetch` with the process-wide default trust store. */
|
|
11
|
-
export const globalFetchTransport = async (url, headers, signal, body) => {
|
|
12
|
-
|
|
11
|
+
export const globalFetchTransport = async (url, headers, signal, body, options) => {
|
|
12
|
+
// Node's fetch answers `manual` with the redirect response itself, status and `Location` included.
|
|
13
|
+
const redirect = options?.redirect === 'return' ? 'manual' : 'error';
|
|
14
|
+
const response = await fetch(url, { method: body ? 'POST' : 'GET', headers, body, redirect, credentials: 'omit', signal });
|
|
13
15
|
return { status: response.status, headers: response.headers, body: response.body };
|
|
14
16
|
};
|
|
15
17
|
/**
|
|
@@ -29,9 +31,10 @@ const drained = (requestArg) => new Promise((resolve, reject) => {
|
|
|
29
31
|
});
|
|
30
32
|
/**
|
|
31
33
|
* Sends one request through `node:http` or `node:https` and resolves once
|
|
32
|
-
* response headers arrive. A redirect status
|
|
33
|
-
*
|
|
34
|
-
* sent or read. A streamed body that fails
|
|
34
|
+
* response headers arrive. A redirect status is never followed: it rejects,
|
|
35
|
+
* unless `redirect` is `return`. Aborting `signal` discards the connection,
|
|
36
|
+
* also while a body is still being sent or read. A streamed body that fails
|
|
37
|
+
* destroys the request and rejects.
|
|
35
38
|
*/
|
|
36
39
|
export const sendNodeRequest = (url, requestArg) => new Promise((resolve, reject) => {
|
|
37
40
|
const { signal } = requestArg;
|
|
@@ -86,7 +89,7 @@ export const sendNodeRequest = (url, requestArg) => new Promise((resolve, reject
|
|
|
86
89
|
request.on('response', (response) => {
|
|
87
90
|
try {
|
|
88
91
|
const status = response.statusCode ?? 0;
|
|
89
|
-
if (redirectStatuses.has(status))
|
|
92
|
+
if (redirectStatuses.has(status) && requestArg.redirect !== 'return')
|
|
90
93
|
throw new Error('Refused redirect.');
|
|
91
94
|
// Same combination rules as fetch: repeated fields join with ", ".
|
|
92
95
|
const responseHeaders = new Headers();
|
|
@@ -111,9 +114,11 @@ export const sendNodeRequest = (url, requestArg) => new Promise((resolve, reject
|
|
|
111
114
|
*/
|
|
112
115
|
export const createHttpsTransport = (caCertificates) => {
|
|
113
116
|
const agents = createNodeAgents(caCertificates);
|
|
114
|
-
return async (url, headers, signal, body) => {
|
|
115
|
-
const { sent: _sent, ...response } = await sendNodeRequest(url, {
|
|
117
|
+
return async (url, headers, signal, body, options) => {
|
|
118
|
+
const { sent: _sent, ...response } = await sendNodeRequest(url, {
|
|
119
|
+
method: body ? 'POST' : 'GET', headers, body, signal, agents, redirect: options?.redirect,
|
|
120
|
+
});
|
|
116
121
|
return response;
|
|
117
122
|
};
|
|
118
123
|
};
|
|
119
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZ2VpbnZlbnRvcnkudHJhbnNwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvZm9yZ2VpbnZlbnRvcnkudHJhbnNwb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBK0J4QyxzRkFBc0Y7QUFDdEYsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQXdCLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFFeEY7Ozs7R0FJRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0FBRWxDLHVFQUF1RTtBQUN2RSxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBb0IsS0FBSyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNqRyxtR0FBbUc7SUFDbkcsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3JFLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUMzSCxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNyRixDQUFDLENBQUM7QUEyQkY7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1B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
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
+
import type { ForgeRequestClient } from './forgeinventory.client.js';
|
|
2
3
|
type IPackageRef = plugins.fossInterfaces.data.IForgeSourcePackageRef;
|
|
3
4
|
type IPackageRecord = plugins.fossInterfaces.data.IForgeSourcePackageInventory;
|
|
4
5
|
type IPackageContentTotals = plugins.fossInterfaces.data.IForgeSourcePackageContentTotals;
|
|
@@ -21,6 +22,54 @@ export declare const swiftPackageParts: (nameArg: string) => {
|
|
|
21
22
|
scope: string;
|
|
22
23
|
name: string;
|
|
23
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* A Swift release's `Package.swift`, or with `swiftVersionArg` its alternate
|
|
27
|
+
* manifest, read with `clientArg`'s `token` authorization; null when Gitea
|
|
28
|
+
* redirects the alternate one to the release's own `Package.swift` (303),
|
|
29
|
+
* which is how it answers a version it holds no manifest for. No redirect is
|
|
30
|
+
* followed: any other redirect rejects with `swift-manifest-redirect-unexpected`,
|
|
31
|
+
* a redirect of `Package.swift` itself with `http-<status>`, and a body that
|
|
32
|
+
* is not `text/x-swift` with `invalid-content-type`. The read counts no
|
|
33
|
+
* download.
|
|
34
|
+
*/
|
|
35
|
+
export declare const readSwiftManifest: (clientArg: ForgeRequestClient, baseUrlArg: string, ownerArg: string, partsArg: {
|
|
36
|
+
scope: string;
|
|
37
|
+
name: string;
|
|
38
|
+
}, versionArg: string, swiftVersionArg: string | null, signalArg: AbortSignal | undefined) => Promise<{
|
|
39
|
+
bytes: Buffer;
|
|
40
|
+
mediaType: string;
|
|
41
|
+
} | null>;
|
|
42
|
+
/**
|
|
43
|
+
* The name of every central-directory entry of a zip archive, in directory
|
|
44
|
+
* order, each byte one code unit (Go strings are bytes, and only ASCII names
|
|
45
|
+
* can match `manifestPattern`). It reads the directory as Go 1.27.2's
|
|
46
|
+
* `archive/zip` `NewReader` does, the archive/zip Gitea 28.2.0 builds with:
|
|
47
|
+
* - the end record is the last signature in the final 65 KiB whose comment
|
|
48
|
+
* fits in the archive;
|
|
49
|
+
* - its zip64 locator and end record are used when a count, size or offset
|
|
50
|
+
* is saturated and a locator for disk 0 of 1 sits right before it;
|
|
51
|
+
* - the base offset of data prepended to the archive is the end record's
|
|
52
|
+
* position minus the directory's size and offset, unless a directory
|
|
53
|
+
* header sits at the unadjusted offset;
|
|
54
|
+
* - headers are read one after another until one is malformed or cut off
|
|
55
|
+
* (a zip64 field too short for the saturated sizes and offset it stands
|
|
56
|
+
* for is malformed), and their count must agree with the end record's in
|
|
57
|
+
* its low 16 bits.
|
|
58
|
+
* Anything Go refuses rejects with `swift-archive-invalid`.
|
|
59
|
+
*/
|
|
60
|
+
export declare const zipEntryNames: (archiveArg: Buffer) => string[];
|
|
61
|
+
/**
|
|
62
|
+
* The keys of the manifests Gitea 28.2.0 may hold for a Swift source
|
|
63
|
+
* archive, sorted in code-unit order: `''`, and the key of every
|
|
64
|
+
* central-directory entry, in any directory, whose name does not end in `/`
|
|
65
|
+
* and whose base name matches Gitea's `manifestPattern` and parses
|
|
66
|
+
* (`swiftManifestKey`). Gitea keeps only the manifests of the shallowest
|
|
67
|
+
* directory, so the keys are a superset of what it holds, and its answer for
|
|
68
|
+
* each key decides. More than `maxSwiftManifestCandidates` distinct keys
|
|
69
|
+
* reject with `swift-manifest-candidates-over-bound`; an archive Go's
|
|
70
|
+
* `archive/zip` refuses with `swift-archive-invalid`.
|
|
71
|
+
*/
|
|
72
|
+
export declare const swiftManifestCandidates: (archiveArg: Buffer) => string[];
|
|
24
73
|
/**
|
|
25
74
|
* The digest of the manifest a container version holds: `sha256:` and the
|
|
26
75
|
* SHA-256 of the blob holding the version's `manifest.json`; null for a
|