@nxtedition/lib 19.1.7 → 19.3.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/package.json +1 -1
- package/s3.js +85 -0
package/package.json
CHANGED
package/s3.js
CHANGED
|
@@ -3,10 +3,73 @@ import stream from 'node:stream'
|
|
|
3
3
|
import tp from 'node:timers/promises'
|
|
4
4
|
import AWS from '@aws-sdk/client-s3'
|
|
5
5
|
import PQueue from 'p-queue'
|
|
6
|
+
import { NodeHttpHandler } from '@smithy/node-http-handler'
|
|
7
|
+
import undici from 'undici'
|
|
6
8
|
|
|
7
9
|
const QUEUE = new PQueue({ concurrency: 8 })
|
|
8
10
|
const MD5_HEX_EXPR = /^[A-F0-9]{32}$/i
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import('undici').Dispatcher} Dispatcher
|
|
14
|
+
* @typedef {import('@aws-sdk/client-s3').S3ClientConfig & {dispatcher?: Dispatcher}} S3ClientConfig
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export class S3Client extends AWS.S3Client {
|
|
18
|
+
/**
|
|
19
|
+
* @param {S3ClientConfig} config
|
|
20
|
+
*/
|
|
21
|
+
constructor(config) {
|
|
22
|
+
const { dispatcher, ...options } = config
|
|
23
|
+
super({
|
|
24
|
+
requestHandler: new UndiciRequestHandler(dispatcher),
|
|
25
|
+
...options,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class UndiciRequestHandler extends NodeHttpHandler {
|
|
31
|
+
#dispatcher
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {Dispatcher=} dispatcher
|
|
35
|
+
*/
|
|
36
|
+
constructor(dispatcher) {
|
|
37
|
+
super()
|
|
38
|
+
this.#dispatcher = dispatcher
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('@smithy/protocol-http').HttpRequest} request
|
|
43
|
+
* @param {import('@smithy/types').HttpHandlerOptions=} options
|
|
44
|
+
*/
|
|
45
|
+
async handle(request, options) {
|
|
46
|
+
const abortSignal = options?.abortSignal
|
|
47
|
+
|
|
48
|
+
const { protocol, hostname, port, path, ...requestOptions } = request
|
|
49
|
+
// NOTE: Expect header is not supported by undici
|
|
50
|
+
const { Expect, ...headers } = request.headers
|
|
51
|
+
const typedMethod = /** @type {import('undici').Dispatcher.HttpMethod} */ (request.method)
|
|
52
|
+
|
|
53
|
+
const url = `${request.protocol}//${request.hostname}${request.port ? `:${request.port}` : ''}${request.path}`
|
|
54
|
+
|
|
55
|
+
const response = await undici.request(url, {
|
|
56
|
+
...requestOptions,
|
|
57
|
+
method: typedMethod,
|
|
58
|
+
signal: abortSignal,
|
|
59
|
+
dispatcher: this.#dispatcher,
|
|
60
|
+
headers,
|
|
61
|
+
body: request.body,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
response: {
|
|
66
|
+
...response,
|
|
67
|
+
headers: getTransformedHeaders(response.headers),
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
10
73
|
/**
|
|
11
74
|
* Uploads a file to S3 using multipart upload.
|
|
12
75
|
*
|
|
@@ -241,3 +304,25 @@ export async function upload({
|
|
|
241
304
|
signal?.removeEventListener('abort', onAbort)
|
|
242
305
|
}
|
|
243
306
|
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* @see https://github.com/smithy-lang/smithy-typescript/blob/main/packages/node-http-handler/src/get-transformed-headers.ts
|
|
310
|
+
*
|
|
311
|
+
* @param {import('http2').IncomingHttpHeaders} headers
|
|
312
|
+
* @returns {import('@smithy/types').HeaderBag}
|
|
313
|
+
*/
|
|
314
|
+
function getTransformedHeaders(headers) {
|
|
315
|
+
/**
|
|
316
|
+
* @type {import('@smithy/types').HeaderBag}
|
|
317
|
+
*/
|
|
318
|
+
const transformedHeaders = {}
|
|
319
|
+
|
|
320
|
+
for (const name of Object.keys(headers)) {
|
|
321
|
+
const headerValues = headers[name]
|
|
322
|
+
transformedHeaders[name] = Array.isArray(headerValues)
|
|
323
|
+
? headerValues.join(',')
|
|
324
|
+
: headerValues ?? ''
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return transformedHeaders
|
|
328
|
+
}
|