@nx.js/http 0.0.1 → 0.0.2
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/dist/body.d.ts +3 -0
- package/dist/body.js +94 -0
- package/dist/body.js.map +1 -0
- package/dist/deferred.d.ts +6 -0
- package/dist/deferred.js +12 -0
- package/dist/deferred.js.map +1 -0
- package/dist/headers.d.ts +4 -0
- package/dist/headers.js +46 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +1 -23
- package/dist/index.js +13 -205
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +5 -0
- package/dist/server.js +135 -0
- package/dist/server.js.map +1 -0
- package/dist/static.d.ts +25 -0
- package/dist/static.js +50 -0
- package/dist/static.js.map +1 -0
- package/dist/unshiftable-readable-stream.d.ts +16 -0
- package/dist/unshiftable-readable-stream.js +69 -0
- package/dist/unshiftable-readable-stream.js.map +1 -0
- package/dist/util.d.ts +8 -0
- package/dist/util.js +62 -0
- package/dist/util.js.map +1 -0
- package/package.json +6 -4
package/dist/body.d.ts
ADDED
package/dist/body.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { flushBytes, readUntilEol } from './util';
|
|
2
|
+
function bodyWithContentLength(unshiftable, contentLengthVal) {
|
|
3
|
+
let bytesRead = 0;
|
|
4
|
+
const reader = unshiftable.readable.getReader();
|
|
5
|
+
const contentLength = parseInt(contentLengthVal, 10);
|
|
6
|
+
//console.log(`content-length: ${contentLength}`);
|
|
7
|
+
return new ReadableStream({
|
|
8
|
+
async pull(controller) {
|
|
9
|
+
if (bytesRead < contentLength) {
|
|
10
|
+
unshiftable.resume();
|
|
11
|
+
const { done, value } = await reader.read();
|
|
12
|
+
unshiftable.pause();
|
|
13
|
+
if (done) {
|
|
14
|
+
reader.releaseLock();
|
|
15
|
+
controller.close();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const remainingLength = contentLength - bytesRead;
|
|
19
|
+
const chunkLength = value.length;
|
|
20
|
+
if (chunkLength <= remainingLength) {
|
|
21
|
+
controller.enqueue(value);
|
|
22
|
+
bytesRead += chunkLength;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// If the chunk is larger than needed, slice it to fit and unshift the rest back
|
|
26
|
+
const neededPart = value.slice(0, remainingLength);
|
|
27
|
+
const excessPart = value.slice(remainingLength);
|
|
28
|
+
controller.enqueue(neededPart);
|
|
29
|
+
unshiftable.unshift(excessPart);
|
|
30
|
+
bytesRead += neededPart.length;
|
|
31
|
+
reader.releaseLock();
|
|
32
|
+
controller.close(); // Close the stream as we have read the required content length
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
reader.releaseLock();
|
|
37
|
+
controller.close(); // Close the stream if bytesRead is already equal to contentLength
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
cancel() {
|
|
41
|
+
reader.cancel();
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function bodyWithChunkedEncoding(unshiftable) {
|
|
46
|
+
const reader = unshiftable.readable.getReader();
|
|
47
|
+
return new ReadableStream({
|
|
48
|
+
async pull(controller) {
|
|
49
|
+
const numBytesHex = await readUntilEol(reader, unshiftable);
|
|
50
|
+
const numBytes = parseInt(numBytesHex, 16);
|
|
51
|
+
if (Number.isNaN(numBytes)) {
|
|
52
|
+
return controller.error(new Error(`Invalid chunk size: ${numBytesHex}`));
|
|
53
|
+
}
|
|
54
|
+
if (numBytes > 0) {
|
|
55
|
+
await flushBytes(controller, numBytes, reader, unshiftable);
|
|
56
|
+
}
|
|
57
|
+
const empty = await readUntilEol(reader, unshiftable);
|
|
58
|
+
if (empty) {
|
|
59
|
+
return controller.error(new Error(`Expected \\r\\n after data chunk, received: ${empty}`));
|
|
60
|
+
}
|
|
61
|
+
if (numBytes === 0) {
|
|
62
|
+
// This is the final chunk
|
|
63
|
+
reader.releaseLock();
|
|
64
|
+
controller.close();
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
cancel(reason) {
|
|
68
|
+
if (reason) {
|
|
69
|
+
reader.cancel(reason);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
reader.cancel();
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export function bodyStream(unshiftable, headers) {
|
|
78
|
+
const contentLength = headers.get('content-length');
|
|
79
|
+
if (typeof contentLength === 'string') {
|
|
80
|
+
return bodyWithContentLength(unshiftable, contentLength);
|
|
81
|
+
}
|
|
82
|
+
const transferEncoding = headers.get('transfer-encoding')?.split(/\s*,\s*/);
|
|
83
|
+
if (transferEncoding?.includes('chunked')) {
|
|
84
|
+
return bodyWithChunkedEncoding(unshiftable);
|
|
85
|
+
}
|
|
86
|
+
// Identity transfer encoding - read until the end of the stream for the body
|
|
87
|
+
const body = new TransformStream();
|
|
88
|
+
unshiftable.readable.pipeTo(body.writable).finally(() => {
|
|
89
|
+
unshiftable.pause();
|
|
90
|
+
});
|
|
91
|
+
unshiftable.resume();
|
|
92
|
+
return body.readable;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=body.js.map
|
package/dist/body.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.js","sourceRoot":"","sources":["../src/body.ts"],"names":[],"mappings":"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"}
|
package/dist/deferred.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred.js","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAQ;IACpB,OAAO,CAAa;IACpB,OAAO,CAAkB;IACzB,MAAM,CAAoB;IAE1B;QACC,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACJ,CAAC;CACD"}
|
package/dist/headers.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { concat, indexOfEol, decoder } from './util';
|
|
2
|
+
export async function readHeaders(unshiftable) {
|
|
3
|
+
let leftover = null;
|
|
4
|
+
const reader = unshiftable.readable.getReader();
|
|
5
|
+
const lines = [];
|
|
6
|
+
while (true) {
|
|
7
|
+
unshiftable.resume();
|
|
8
|
+
const next = await reader.read();
|
|
9
|
+
unshiftable.pause();
|
|
10
|
+
if (next.done)
|
|
11
|
+
return lines;
|
|
12
|
+
const chunk = leftover
|
|
13
|
+
? concat(leftover, next.value)
|
|
14
|
+
: next.value;
|
|
15
|
+
let pos = 0;
|
|
16
|
+
while (true) {
|
|
17
|
+
const eol = indexOfEol(chunk, pos);
|
|
18
|
+
if (eol === -1) {
|
|
19
|
+
leftover = chunk.slice(pos);
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
const line = decoder.decode(chunk.slice(pos, eol));
|
|
23
|
+
pos = eol + 2;
|
|
24
|
+
if (line) {
|
|
25
|
+
lines.push(line);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// end of headers
|
|
29
|
+
unshiftable.unshift(chunk.slice(pos));
|
|
30
|
+
reader.releaseLock();
|
|
31
|
+
return lines;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function toHeaders(input) {
|
|
37
|
+
const headers = new Headers();
|
|
38
|
+
for (const line of input) {
|
|
39
|
+
const col = line.indexOf(':');
|
|
40
|
+
const name = line.slice(0, col);
|
|
41
|
+
const value = line.slice(col + 1).trim();
|
|
42
|
+
headers.set(name, value);
|
|
43
|
+
}
|
|
44
|
+
return headers;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrD,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,WAA8B;IAE9B,IAAI,QAAQ,GAAsB,IAAI,CAAC;IACvC,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,OAAO,IAAI,EAAE,CAAC;QACb,WAAW,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,KAAK,GAAe,QAAQ;YACjC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC;YAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACd,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,OAAO,IAAI,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACnC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBAChB,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC5B,MAAM;YACP,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACnD,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YACd,IAAI,IAAI,EAAE,CAAC;gBACV,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,iBAAiB;gBACjB,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAe;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="nxjs-runtime" />
|
|
2
|
+
export { createStaticFileHandler } from './static';
|
|
2
3
|
/**
|
|
3
4
|
* Handler function for processing an HTTP request.
|
|
4
5
|
*/
|
|
@@ -18,29 +19,6 @@ export interface ListenOptions extends Omit<Switch.ListenOptions, 'accept'> {
|
|
|
18
19
|
* @param handler The HTTP handler function to invoke when an HTTP request is received
|
|
19
20
|
*/
|
|
20
21
|
export declare function createServerHandler(handler: ServerHandler): ({ socket }: Switch.SocketEvent) => Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Creates an HTTP handler function which serves file contents from the filesystem.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
*
|
|
26
|
-
* ```typescript
|
|
27
|
-
* const fileHandler = http.createStaticFileHandler('sdmc:/switch/');
|
|
28
|
-
*
|
|
29
|
-
* http.listen({
|
|
30
|
-
* port: 8080,
|
|
31
|
-
* async fetch(req) {
|
|
32
|
-
* let res = await fileHandler(req);
|
|
33
|
-
* if (!res) {
|
|
34
|
-
* res = new Response('File not found', { status: 404 });
|
|
35
|
-
* }
|
|
36
|
-
* return res;
|
|
37
|
-
* }
|
|
38
|
-
* });
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @param root Root directory where static files are served from
|
|
42
|
-
*/
|
|
43
|
-
export declare function createStaticFileHandler(root: Switch.PathLike): (req: Request) => Promise<Response | null>;
|
|
44
22
|
/**
|
|
45
23
|
* Creates an HTTP server and listens on the `port` number specified in the options object.
|
|
46
24
|
* The `fetch` function will be invoked upon receiving an HTTP request.
|
package/dist/index.js
CHANGED
|
@@ -1,116 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
function indexOfEol(arr, offset) {
|
|
5
|
-
for (let i = offset; i < arr.length - 1; i++) {
|
|
6
|
-
if (arr[i] === 13 && arr[i + 1] === 10) {
|
|
7
|
-
return i;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
return -1;
|
|
11
|
-
}
|
|
12
|
-
function concat(a, b) {
|
|
13
|
-
const c = new Uint8Array(a.length + b.length);
|
|
14
|
-
c.set(a, 0);
|
|
15
|
-
c.set(b, a.length);
|
|
16
|
-
return c;
|
|
17
|
-
}
|
|
18
|
-
async function* headersIterator(reader) {
|
|
19
|
-
let leftover = null;
|
|
20
|
-
while (true) {
|
|
21
|
-
const next = await reader.read();
|
|
22
|
-
if (next.done)
|
|
23
|
-
throw new Error('Stream closed before end of headers');
|
|
24
|
-
const chunk = leftover
|
|
25
|
-
? concat(leftover, next.value)
|
|
26
|
-
: next.value;
|
|
27
|
-
let pos = 0;
|
|
28
|
-
while (true) {
|
|
29
|
-
const eol = indexOfEol(chunk, pos);
|
|
30
|
-
if (eol === -1) {
|
|
31
|
-
leftover = chunk.slice(pos);
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
const line = decoder.decode(chunk.slice(pos, eol));
|
|
35
|
-
pos = eol + 2;
|
|
36
|
-
if (line) {
|
|
37
|
-
yield { line };
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
// end of headers
|
|
41
|
-
leftover = chunk.slice(pos);
|
|
42
|
-
yield { line: null, leftover };
|
|
43
|
-
reader.releaseLock();
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
const STATUS_CODES = {
|
|
50
|
-
'100': 'Continue',
|
|
51
|
-
'101': 'Switching Protocols',
|
|
52
|
-
'102': 'Processing',
|
|
53
|
-
'103': 'Early Hints',
|
|
54
|
-
'200': 'OK',
|
|
55
|
-
'201': 'Created',
|
|
56
|
-
'202': 'Accepted',
|
|
57
|
-
'203': 'Non-Authoritative Information',
|
|
58
|
-
'204': 'No Content',
|
|
59
|
-
'205': 'Reset Content',
|
|
60
|
-
'206': 'Partial Content',
|
|
61
|
-
'207': 'Multi-Status',
|
|
62
|
-
'208': 'Already Reported',
|
|
63
|
-
'226': 'IM Used',
|
|
64
|
-
'300': 'Multiple Choices',
|
|
65
|
-
'301': 'Moved Permanently',
|
|
66
|
-
'302': 'Found',
|
|
67
|
-
'303': 'See Other',
|
|
68
|
-
'304': 'Not Modified',
|
|
69
|
-
'305': 'Use Proxy',
|
|
70
|
-
'307': 'Temporary Redirect',
|
|
71
|
-
'308': 'Permanent Redirect',
|
|
72
|
-
'400': 'Bad Request',
|
|
73
|
-
'401': 'Unauthorized',
|
|
74
|
-
'402': 'Payment Required',
|
|
75
|
-
'403': 'Forbidden',
|
|
76
|
-
'404': 'Not Found',
|
|
77
|
-
'405': 'Method Not Allowed',
|
|
78
|
-
'406': 'Not Acceptable',
|
|
79
|
-
'407': 'Proxy Authentication Required',
|
|
80
|
-
'408': 'Request Timeout',
|
|
81
|
-
'409': 'Conflict',
|
|
82
|
-
'410': 'Gone',
|
|
83
|
-
'411': 'Length Required',
|
|
84
|
-
'412': 'Precondition Failed',
|
|
85
|
-
'413': 'Payload Too Large',
|
|
86
|
-
'414': 'URI Too Long',
|
|
87
|
-
'415': 'Unsupported Media Type',
|
|
88
|
-
'416': 'Range Not Satisfiable',
|
|
89
|
-
'417': 'Expectation Failed',
|
|
90
|
-
'418': "I'm a Teapot",
|
|
91
|
-
'421': 'Misdirected Request',
|
|
92
|
-
'422': 'Unprocessable Entity',
|
|
93
|
-
'423': 'Locked',
|
|
94
|
-
'424': 'Failed Dependency',
|
|
95
|
-
'425': 'Too Early',
|
|
96
|
-
'426': 'Upgrade Required',
|
|
97
|
-
'428': 'Precondition Required',
|
|
98
|
-
'429': 'Too Many Requests',
|
|
99
|
-
'431': 'Request Header Fields Too Large',
|
|
100
|
-
'451': 'Unavailable For Legal Reasons',
|
|
101
|
-
'500': 'Internal Server Error',
|
|
102
|
-
'501': 'Not Implemented',
|
|
103
|
-
'502': 'Bad Gateway',
|
|
104
|
-
'503': 'Service Unavailable',
|
|
105
|
-
'504': 'Gateway Timeout',
|
|
106
|
-
'505': 'HTTP Version Not Supported',
|
|
107
|
-
'506': 'Variant Also Negotiates',
|
|
108
|
-
'507': 'Insufficient Storage',
|
|
109
|
-
'508': 'Loop Detected',
|
|
110
|
-
'509': 'Bandwidth Limit Exceeded',
|
|
111
|
-
'510': 'Not Extended',
|
|
112
|
-
'511': 'Network Authentication Required',
|
|
113
|
-
};
|
|
1
|
+
import { UnshiftableStream } from './unshiftable-readable-stream';
|
|
2
|
+
import { readRequest, writeResponse } from './server';
|
|
3
|
+
export { createStaticFileHandler } from './static';
|
|
114
4
|
/**
|
|
115
5
|
* Creates a socket handler function which accepts a socket
|
|
116
6
|
* event and parses the incoming data as an HTTP request.
|
|
@@ -120,97 +10,18 @@ const STATUS_CODES = {
|
|
|
120
10
|
* @param handler The HTTP handler function to invoke when an HTTP request is received
|
|
121
11
|
*/
|
|
122
12
|
export function createServerHandler(handler) {
|
|
123
|
-
return async
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
const [method, path, httpVersion] = firstLine.value.line.split(' ');
|
|
133
|
-
let leftover;
|
|
134
|
-
for await (const v of hi) {
|
|
135
|
-
if (typeof v.line === 'string') {
|
|
136
|
-
const col = v.line.indexOf(':');
|
|
137
|
-
const name = v.line.slice(0, col);
|
|
138
|
-
const value = v.line.slice(col + 1).trim();
|
|
139
|
-
reqHeaders.set(name, value);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
leftover = v.leftover;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const host = reqHeaders.get('host');
|
|
146
|
-
const req = new Request(`http://${host}${path}`, {
|
|
147
|
-
method,
|
|
148
|
-
headers: reqHeaders,
|
|
149
|
-
});
|
|
150
|
-
const res = await handler(req);
|
|
151
|
-
res.headers.set('connection', 'close');
|
|
152
|
-
let headersStr = '';
|
|
153
|
-
for (const [k, v] of res.headers) {
|
|
154
|
-
headersStr += `${k}: ${v}\r\n`;
|
|
155
|
-
}
|
|
156
|
-
const statusText = res.statusText || STATUS_CODES[res.status];
|
|
157
|
-
const resHeader = `${httpVersion} ${res.status} ${statusText}\r\n${headersStr}\r\n`;
|
|
158
|
-
const w = socket.writable.getWriter();
|
|
159
|
-
w.write(encoder.encode(resHeader));
|
|
160
|
-
if (res.body) {
|
|
161
|
-
w.releaseLock();
|
|
162
|
-
await res.body.pipeTo(socket.writable);
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
await w.close();
|
|
13
|
+
return async ({ socket }) => {
|
|
14
|
+
const unshiftable = new UnshiftableStream(socket.readable);
|
|
15
|
+
while (true) {
|
|
16
|
+
const req = await readRequest(unshiftable);
|
|
17
|
+
if (!req)
|
|
18
|
+
break;
|
|
19
|
+
const res = await handler(req);
|
|
20
|
+
writeResponse(socket.writable, res, 'HTTP/1.1');
|
|
166
21
|
}
|
|
167
22
|
socket.close();
|
|
168
23
|
};
|
|
169
24
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Creates an HTTP handler function which serves file contents from the filesystem.
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
*
|
|
175
|
-
* ```typescript
|
|
176
|
-
* const fileHandler = http.createStaticFileHandler('sdmc:/switch/');
|
|
177
|
-
*
|
|
178
|
-
* http.listen({
|
|
179
|
-
* port: 8080,
|
|
180
|
-
* async fetch(req) {
|
|
181
|
-
* let res = await fileHandler(req);
|
|
182
|
-
* if (!res) {
|
|
183
|
-
* res = new Response('File not found', { status: 404 });
|
|
184
|
-
* }
|
|
185
|
-
* return res;
|
|
186
|
-
* }
|
|
187
|
-
* });
|
|
188
|
-
* ```
|
|
189
|
-
*
|
|
190
|
-
* @param root Root directory where static files are served from
|
|
191
|
-
*/
|
|
192
|
-
export function createStaticFileHandler(root) {
|
|
193
|
-
if (!String(root).endsWith('/')) {
|
|
194
|
-
throw new Error('`root` directory must end with a "/"');
|
|
195
|
-
}
|
|
196
|
-
return async function (req) {
|
|
197
|
-
const { pathname } = new URL(req.url);
|
|
198
|
-
const url = new URL(pathname.slice(1), root);
|
|
199
|
-
const stat = await Switch.stat(url);
|
|
200
|
-
if (!stat)
|
|
201
|
-
return null;
|
|
202
|
-
// TODO: replace with readable stream API
|
|
203
|
-
const data = await Switch.readFile(url);
|
|
204
|
-
if (!data)
|
|
205
|
-
return null;
|
|
206
|
-
return new Response(data, {
|
|
207
|
-
headers: {
|
|
208
|
-
'content-length': String(data.byteLength),
|
|
209
|
-
'content-type': mime.getType(pathname) || 'application/octet-stream',
|
|
210
|
-
},
|
|
211
|
-
});
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
25
|
/**
|
|
215
26
|
* Creates an HTTP server and listens on the `port` number specified in the options object.
|
|
216
27
|
* The `fetch` function will be invoked upon receiving an HTTP request.
|
|
@@ -228,10 +39,7 @@ export function createStaticFileHandler(root) {
|
|
|
228
39
|
* ```
|
|
229
40
|
*/
|
|
230
41
|
export function listen(opts) {
|
|
231
|
-
const
|
|
232
|
-
return Switch.listen({
|
|
233
|
-
...opts,
|
|
234
|
-
accept: handler,
|
|
235
|
-
});
|
|
42
|
+
const accept = createServerHandler(opts.fetch);
|
|
43
|
+
return Switch.listen({ ...opts, accept });
|
|
236
44
|
}
|
|
237
45
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAcnD;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAsB;IACzD,OAAO,KAAK,EAAE,EAAE,MAAM,EAAsB,EAAE,EAAE;QAC/C,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG;gBAAE,MAAM;YAChB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,MAAM,CAAC,IAAmB;IACzC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="nxjs-runtime" />
|
|
2
|
+
import type { UnshiftableStream } from './unshiftable-readable-stream';
|
|
3
|
+
export declare function readRequest(unshiftable: UnshiftableStream): Promise<Request | null>;
|
|
4
|
+
export declare function createChunkedWriter(readable: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
|
|
5
|
+
export declare function writeResponse(writable: WritableStream<Uint8Array>, res: Response, httpVersion: string): Promise<void>;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { encoder } from './util';
|
|
2
|
+
import { bodyStream } from './body';
|
|
3
|
+
import { readHeaders, toHeaders } from './headers';
|
|
4
|
+
const STATUS_CODES = {
|
|
5
|
+
'100': 'Continue',
|
|
6
|
+
'101': 'Switching Protocols',
|
|
7
|
+
'102': 'Processing',
|
|
8
|
+
'103': 'Early Hints',
|
|
9
|
+
'200': 'OK',
|
|
10
|
+
'201': 'Created',
|
|
11
|
+
'202': 'Accepted',
|
|
12
|
+
'203': 'Non-Authoritative Information',
|
|
13
|
+
'204': 'No Content',
|
|
14
|
+
'205': 'Reset Content',
|
|
15
|
+
'206': 'Partial Content',
|
|
16
|
+
'207': 'Multi-Status',
|
|
17
|
+
'208': 'Already Reported',
|
|
18
|
+
'226': 'IM Used',
|
|
19
|
+
'300': 'Multiple Choices',
|
|
20
|
+
'301': 'Moved Permanently',
|
|
21
|
+
'302': 'Found',
|
|
22
|
+
'303': 'See Other',
|
|
23
|
+
'304': 'Not Modified',
|
|
24
|
+
'305': 'Use Proxy',
|
|
25
|
+
'307': 'Temporary Redirect',
|
|
26
|
+
'308': 'Permanent Redirect',
|
|
27
|
+
'400': 'Bad Request',
|
|
28
|
+
'401': 'Unauthorized',
|
|
29
|
+
'402': 'Payment Required',
|
|
30
|
+
'403': 'Forbidden',
|
|
31
|
+
'404': 'Not Found',
|
|
32
|
+
'405': 'Method Not Allowed',
|
|
33
|
+
'406': 'Not Acceptable',
|
|
34
|
+
'407': 'Proxy Authentication Required',
|
|
35
|
+
'408': 'Request Timeout',
|
|
36
|
+
'409': 'Conflict',
|
|
37
|
+
'410': 'Gone',
|
|
38
|
+
'411': 'Length Required',
|
|
39
|
+
'412': 'Precondition Failed',
|
|
40
|
+
'413': 'Payload Too Large',
|
|
41
|
+
'414': 'URI Too Long',
|
|
42
|
+
'415': 'Unsupported Media Type',
|
|
43
|
+
'416': 'Range Not Satisfiable',
|
|
44
|
+
'417': 'Expectation Failed',
|
|
45
|
+
'418': "I'm a Teapot",
|
|
46
|
+
'421': 'Misdirected Request',
|
|
47
|
+
'422': 'Unprocessable Entity',
|
|
48
|
+
'423': 'Locked',
|
|
49
|
+
'424': 'Failed Dependency',
|
|
50
|
+
'425': 'Too Early',
|
|
51
|
+
'426': 'Upgrade Required',
|
|
52
|
+
'428': 'Precondition Required',
|
|
53
|
+
'429': 'Too Many Requests',
|
|
54
|
+
'431': 'Request Header Fields Too Large',
|
|
55
|
+
'451': 'Unavailable For Legal Reasons',
|
|
56
|
+
'500': 'Internal Server Error',
|
|
57
|
+
'501': 'Not Implemented',
|
|
58
|
+
'502': 'Bad Gateway',
|
|
59
|
+
'503': 'Service Unavailable',
|
|
60
|
+
'504': 'Gateway Timeout',
|
|
61
|
+
'505': 'HTTP Version Not Supported',
|
|
62
|
+
'506': 'Variant Also Negotiates',
|
|
63
|
+
'507': 'Insufficient Storage',
|
|
64
|
+
'508': 'Loop Detected',
|
|
65
|
+
'509': 'Bandwidth Limit Exceeded',
|
|
66
|
+
'510': 'Not Extended',
|
|
67
|
+
'511': 'Network Authentication Required',
|
|
68
|
+
};
|
|
69
|
+
export async function readRequest(unshiftable) {
|
|
70
|
+
const rawHeaders = await readHeaders(unshiftable);
|
|
71
|
+
if (!rawHeaders.length) {
|
|
72
|
+
// Malformed HTTP request - no header sent
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const [method, path, _httpVersion] = rawHeaders[0].split(' ');
|
|
76
|
+
const headers = toHeaders(rawHeaders.slice(1));
|
|
77
|
+
const host = headers.get('host');
|
|
78
|
+
const body = method === 'GET' || method === 'HEAD'
|
|
79
|
+
? null
|
|
80
|
+
: bodyStream(unshiftable, headers);
|
|
81
|
+
return new Request(`http://${host}${path}`, {
|
|
82
|
+
method,
|
|
83
|
+
body,
|
|
84
|
+
headers,
|
|
85
|
+
// @ts-expect-error wtf Node.js - https://github.com/nodejs/node/issues/46221
|
|
86
|
+
duplex: 'half',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function createChunkedWriter(readable) {
|
|
90
|
+
const reader = readable.getReader();
|
|
91
|
+
return new ReadableStream({
|
|
92
|
+
async pull(controller) {
|
|
93
|
+
const { done, value } = await reader.read();
|
|
94
|
+
const bytes = done ? 0 : value.length;
|
|
95
|
+
controller.enqueue(encoder.encode(`${bytes.toString(16)}\r\n`));
|
|
96
|
+
if (value)
|
|
97
|
+
controller.enqueue(value);
|
|
98
|
+
controller.enqueue(encoder.encode(`\r\n`));
|
|
99
|
+
if (done)
|
|
100
|
+
controller.close();
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
export async function writeResponse(writable, res, httpVersion) {
|
|
105
|
+
const close = res.headers.get('connection') === 'close';
|
|
106
|
+
const chunked = !(close || res.headers.has('content-length'));
|
|
107
|
+
if (!res.headers.has('date')) {
|
|
108
|
+
res.headers.set('date', new Date().toUTCString());
|
|
109
|
+
}
|
|
110
|
+
if (!res.headers.has('content-type')) {
|
|
111
|
+
res.headers.set('content-type', 'text/plain');
|
|
112
|
+
}
|
|
113
|
+
if (chunked) {
|
|
114
|
+
res.headers.set('transfer-encoding', 'chunked');
|
|
115
|
+
}
|
|
116
|
+
let headersStr = '';
|
|
117
|
+
for (const [k, v] of res.headers) {
|
|
118
|
+
headersStr += `${k}: ${v}\r\n`;
|
|
119
|
+
}
|
|
120
|
+
const statusText = res.statusText || STATUS_CODES[res.status];
|
|
121
|
+
const header = `${httpVersion} ${res.status} ${statusText}\r\n${headersStr}\r\n`;
|
|
122
|
+
const w = writable.getWriter();
|
|
123
|
+
w.write(encoder.encode(header));
|
|
124
|
+
w.releaseLock();
|
|
125
|
+
let body = res.body;
|
|
126
|
+
if (body) {
|
|
127
|
+
if (chunked)
|
|
128
|
+
body = createChunkedWriter(body);
|
|
129
|
+
await body.pipeTo(writable, { preventClose: true });
|
|
130
|
+
}
|
|
131
|
+
if (close) {
|
|
132
|
+
await writable.close();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/static.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="nxjs-runtime" />
|
|
2
|
+
export declare function resolvePath(url: string, root: string): URL;
|
|
3
|
+
/**
|
|
4
|
+
* Creates an HTTP handler function which serves file contents from the filesystem.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const fileHandler = http.createStaticFileHandler('sdmc:/switch/');
|
|
10
|
+
*
|
|
11
|
+
* http.listen({
|
|
12
|
+
* port: 8080,
|
|
13
|
+
* async fetch(req) {
|
|
14
|
+
* let res = await fileHandler(req);
|
|
15
|
+
* if (!res) {
|
|
16
|
+
* res = new Response('File not found', { status: 404 });
|
|
17
|
+
* }
|
|
18
|
+
* return res;
|
|
19
|
+
* }
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @param root Root directory where static files are served from
|
|
24
|
+
*/
|
|
25
|
+
export declare function createStaticFileHandler(root: Switch.PathLike): (req: Request) => Promise<Response | null>;
|
package/dist/static.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import mime from 'mime';
|
|
2
|
+
export function resolvePath(url, root) {
|
|
3
|
+
const { pathname } = new URL(url);
|
|
4
|
+
const resolved = new URL(pathname.replace(/^\/*/, ''), root);
|
|
5
|
+
return resolved;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Creates an HTTP handler function which serves file contents from the filesystem.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const fileHandler = http.createStaticFileHandler('sdmc:/switch/');
|
|
14
|
+
*
|
|
15
|
+
* http.listen({
|
|
16
|
+
* port: 8080,
|
|
17
|
+
* async fetch(req) {
|
|
18
|
+
* let res = await fileHandler(req);
|
|
19
|
+
* if (!res) {
|
|
20
|
+
* res = new Response('File not found', { status: 404 });
|
|
21
|
+
* }
|
|
22
|
+
* return res;
|
|
23
|
+
* }
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @param root Root directory where static files are served from
|
|
28
|
+
*/
|
|
29
|
+
export function createStaticFileHandler(root) {
|
|
30
|
+
let rootStr = String(root);
|
|
31
|
+
if (!rootStr.endsWith('/'))
|
|
32
|
+
rootStr += '/';
|
|
33
|
+
return async (req) => {
|
|
34
|
+
const url = resolvePath(req.url, rootStr);
|
|
35
|
+
const stat = await Switch.stat(url);
|
|
36
|
+
if (!stat)
|
|
37
|
+
return null;
|
|
38
|
+
// TODO: replace with readable stream API
|
|
39
|
+
const data = await Switch.readFile(url);
|
|
40
|
+
if (!data)
|
|
41
|
+
return null;
|
|
42
|
+
return new Response(data, {
|
|
43
|
+
headers: {
|
|
44
|
+
'content-length': String(data.byteLength),
|
|
45
|
+
'content-type': mime.getType(url.pathname) || 'application/octet-stream',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=static.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../src/static.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,IAAY;IACpD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7D,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAqB;IAC5D,IAAI,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,GAAG,CAAC;IAC3C,OAAO,KAAK,EAAE,GAAY,EAA4B,EAAE;QACvD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,yCAAyC;QACzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;YACzB,OAAO,EAAE;gBACR,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;gBACzC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,0BAA0B;aACxE;SACD,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="nxjs-runtime" />
|
|
2
|
+
import { Deferred } from './deferred';
|
|
3
|
+
export declare class UnshiftableStream {
|
|
4
|
+
buffer: Uint8Array;
|
|
5
|
+
reader: ReadableStreamDefaultReader<Uint8Array>;
|
|
6
|
+
readable: ReadableStream<Uint8Array>;
|
|
7
|
+
paused?: Deferred<void>;
|
|
8
|
+
constructor(sourceStream: ReadableStream<Uint8Array>);
|
|
9
|
+
unshift: (data: Uint8Array) => void;
|
|
10
|
+
pause(): void;
|
|
11
|
+
resume(): void;
|
|
12
|
+
read(): Promise<ReadableStreamReadDoneResult<Uint8Array> | {
|
|
13
|
+
done: boolean;
|
|
14
|
+
value: Uint8Array;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Deferred } from './deferred';
|
|
2
|
+
export class UnshiftableStream {
|
|
3
|
+
buffer;
|
|
4
|
+
reader;
|
|
5
|
+
readable;
|
|
6
|
+
paused;
|
|
7
|
+
constructor(sourceStream) {
|
|
8
|
+
this.buffer = new Uint8Array();
|
|
9
|
+
this.reader = sourceStream.getReader();
|
|
10
|
+
this.pause();
|
|
11
|
+
// Wrap the read method in a ReadableStream
|
|
12
|
+
this.readable = new ReadableStream({
|
|
13
|
+
pull: async (controller) => {
|
|
14
|
+
const { done, value } = await this.read();
|
|
15
|
+
if (done) {
|
|
16
|
+
controller.close();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
controller.enqueue(value);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
cancel: () => {
|
|
23
|
+
this.reader.cancel();
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Method to unshift data back to the stream
|
|
28
|
+
unshift = (data) => {
|
|
29
|
+
const newData = new Uint8Array(this.buffer.length + data.length);
|
|
30
|
+
newData.set(data, 0);
|
|
31
|
+
newData.set(this.buffer, data.length);
|
|
32
|
+
this.buffer = newData;
|
|
33
|
+
};
|
|
34
|
+
pause() {
|
|
35
|
+
if (this.paused)
|
|
36
|
+
return;
|
|
37
|
+
//console.log('pause');
|
|
38
|
+
this.paused = new Deferred();
|
|
39
|
+
}
|
|
40
|
+
resume() {
|
|
41
|
+
const p = this.paused;
|
|
42
|
+
if (!p)
|
|
43
|
+
return;
|
|
44
|
+
//console.log('resume');
|
|
45
|
+
this.paused = undefined;
|
|
46
|
+
p.resolve();
|
|
47
|
+
}
|
|
48
|
+
// Read method that checks the buffer first
|
|
49
|
+
async read() {
|
|
50
|
+
//console.log('read')
|
|
51
|
+
if (this.paused) {
|
|
52
|
+
//console.log('read paused')
|
|
53
|
+
await this.paused.promise;
|
|
54
|
+
}
|
|
55
|
+
//console.log('read resume')
|
|
56
|
+
if (this.buffer.length > 0) {
|
|
57
|
+
const value = this.buffer;
|
|
58
|
+
//console.log('buffer', { value })
|
|
59
|
+
this.buffer = new Uint8Array(); // Clear the buffer after reading
|
|
60
|
+
return { done: false, value };
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const result = await this.reader.read();
|
|
64
|
+
//console.log({ result })
|
|
65
|
+
return result; // Return data from the source stream
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=unshiftable-readable-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unshiftable-readable-stream.js","sourceRoot":"","sources":["../src/unshiftable-readable-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,OAAO,iBAAiB;IAC7B,MAAM,CAAa;IACnB,MAAM,CAA0C;IAChD,QAAQ,CAA6B;IACrC,MAAM,CAAkB;IAExB,YAAY,YAAwC;QACnD,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,2CAA2C;QAC3C,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAa;YAC9C,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBAC1B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1C,IAAI,IAAI,EAAE,CAAC;oBACV,UAAU,CAAC,KAAK,EAAE,CAAC;gBACpB,CAAC;qBAAM,CAAC;oBACP,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;YACF,CAAC;YACD,MAAM,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,OAAO,GAAG,CAAC,IAAgB,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;IACvB,CAAC,CAAC;IAEF,KAAK;QACJ,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,uBAAuB;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,MAAM;QACL,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,wBAAwB;QACxB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,CAAC,CAAC,OAAO,EAAE,CAAC;IACb,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,IAAI;QACT,qBAAqB;QACrB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,4BAA4B;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAC3B,CAAC;QACD,4BAA4B;QAC5B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,kCAAkC;YAClC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC,CAAC,iCAAiC;YACjE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACxC,yBAAyB;YACzB,OAAO,MAAM,CAAC,CAAC,qCAAqC;QACrD,CAAC;IACF,CAAC;CACD"}
|
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="nxjs-runtime" />
|
|
2
|
+
import type { UnshiftableStream } from './unshiftable-readable-stream';
|
|
3
|
+
export declare const encoder: TextEncoder;
|
|
4
|
+
export declare const decoder: TextDecoder;
|
|
5
|
+
export declare function indexOfEol(arr: ArrayLike<number>, offset?: number): number;
|
|
6
|
+
export declare function concat(a: Uint8Array, b: Uint8Array): Uint8Array;
|
|
7
|
+
export declare function readUntilEol(reader: ReadableStreamDefaultReader<Uint8Array>, unshiftable: UnshiftableStream): Promise<string>;
|
|
8
|
+
export declare function flushBytes(controller: ReadableStreamDefaultController<Uint8Array>, numBytes: number, reader: ReadableStreamDefaultReader<Uint8Array>, unshiftable: UnshiftableStream): Promise<void>;
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const encoder = new TextEncoder();
|
|
2
|
+
export const decoder = new TextDecoder();
|
|
3
|
+
export function indexOfEol(arr, offset = 0) {
|
|
4
|
+
for (let i = offset; i < arr.length - 1; i++) {
|
|
5
|
+
if (arr[i] === 13 && arr[i + 1] === 10) {
|
|
6
|
+
return i;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return -1;
|
|
10
|
+
}
|
|
11
|
+
export function concat(a, b) {
|
|
12
|
+
const c = new Uint8Array(a.length + b.length);
|
|
13
|
+
c.set(a, 0);
|
|
14
|
+
c.set(b, a.length);
|
|
15
|
+
return c;
|
|
16
|
+
}
|
|
17
|
+
export async function readUntilEol(reader, unshiftable) {
|
|
18
|
+
let buffered = new Uint8Array(0);
|
|
19
|
+
while (true) {
|
|
20
|
+
unshiftable.resume();
|
|
21
|
+
const { done, value } = await reader.read();
|
|
22
|
+
unshiftable.pause();
|
|
23
|
+
if (done)
|
|
24
|
+
break;
|
|
25
|
+
buffered = concat(buffered, value);
|
|
26
|
+
const i = indexOfEol(buffered);
|
|
27
|
+
if (i !== -1) {
|
|
28
|
+
if (buffered.length > i + 2) {
|
|
29
|
+
unshiftable.unshift(buffered.slice(i + 2));
|
|
30
|
+
buffered = buffered.slice(0, i);
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return decoder.decode(buffered);
|
|
36
|
+
}
|
|
37
|
+
export async function flushBytes(controller, numBytes, reader, unshiftable) {
|
|
38
|
+
let numFlushed = 0;
|
|
39
|
+
while (true) {
|
|
40
|
+
unshiftable.resume();
|
|
41
|
+
const { done, value } = await reader.read();
|
|
42
|
+
unshiftable.pause();
|
|
43
|
+
if (done)
|
|
44
|
+
break;
|
|
45
|
+
const numRemaining = numBytes - numFlushed;
|
|
46
|
+
if (value.length > numRemaining) {
|
|
47
|
+
unshiftable.unshift(value.slice(numRemaining));
|
|
48
|
+
const chunk = value.slice(0, numRemaining);
|
|
49
|
+
numFlushed += chunk.length;
|
|
50
|
+
controller.enqueue(chunk);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
numFlushed += value.length;
|
|
55
|
+
controller.enqueue(value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (numFlushed !== numBytes) {
|
|
59
|
+
// TODO: throw error?
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx.js/http",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "HTTP server for nx.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"@types/mime-types": "^2.1.4",
|
|
14
13
|
"typescript": "^5.3.2",
|
|
15
|
-
"
|
|
14
|
+
"vite": "^5.1.6",
|
|
15
|
+
"vitest": "^1.3.1",
|
|
16
|
+
"nxjs-runtime": "0.0.39"
|
|
16
17
|
},
|
|
17
18
|
"keywords": [
|
|
18
19
|
"nx.js",
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
"mime": "^4.0.1"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
|
-
"build": "tsc"
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"test": "vitest"
|
|
30
32
|
}
|
|
31
33
|
}
|