@torpor/adapter-node 0.0.30 → 0.1.1

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @torpor/adapter-node
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [168dff3]
8
+ - Updated dependencies [051998b]
9
+ - @torpor/build@0.4.0
10
+
11
+ ## 0.1.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 51dbba7: Chore: drop CJS build and go ESM only
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [bbdc8d3]
20
+ - Updated dependencies [e1ae2bb]
21
+ - Updated dependencies [51dbba7]
22
+ - Updated dependencies [62b0d2e]
23
+ - @torpor/build@0.3.0
24
+
3
25
  ## 0.0.30
4
26
 
5
27
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { Adapter } from '@torpor/build';
1
+ import { Adapter } from "@torpor/build";
2
2
 
3
+ //#region src/adapter.d.ts
3
4
  declare const _default: Adapter;
4
-
5
+ //#endregion
5
6
  export { _default as node };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/adapter.ts"],"sourcesContent":[],"mappings":";;;cAIA,UAmBuB"}
package/dist/index.js CHANGED
@@ -1,131 +1,110 @@
1
- // src/createNodeServer.ts
2
- import { createServer } from "http";
1
+ import { createServer } from "node:http";
2
+ import { Readable } from "node:stream";
3
+ import { isArrayBufferView } from "node:util/types";
3
4
 
4
- // src/constants.ts
5
- var INTERNAL_BODY = Symbol("internal_body");
5
+ //#region src/constants.ts
6
+ const INTERNAL_BODY = Symbol("internal_body");
6
7
 
7
- // src/nodeMessageToRequest.ts
8
- import { Readable } from "stream";
9
-
10
- // src/flattenHeaders.ts
8
+ //#endregion
9
+ //#region src/flattenHeaders.ts
11
10
  function flattenHeaders(headers) {
12
- const flatHeaders = new Headers();
13
- for (const [key, value] of Object.entries(headers)) {
14
- if (value === void 0 || value === null) {
15
- continue;
16
- } else if (Array.isArray(value)) {
17
- for (const v of value) {
18
- if (v !== void 0 && v !== null) {
19
- value.forEach((v2) => flatHeaders.append(key, v2));
20
- }
21
- }
22
- } else {
23
- flatHeaders.set(key, String(value));
24
- }
25
- }
26
- return flatHeaders;
11
+ const flatHeaders = new Headers();
12
+ for (const [key, value] of Object.entries(headers)) if (value === void 0 || value === null) continue;
13
+ else if (Array.isArray(value)) {
14
+ for (const v of value) if (v !== void 0 && v !== null) value.forEach((v$1) => flatHeaders.append(key, v$1));
15
+ } else flatHeaders.set(key, String(value));
16
+ return flatHeaders;
27
17
  }
28
18
 
29
- // src/nodeMessageToRequest.ts
19
+ //#endregion
20
+ //#region src/nodeMessageToRequest.ts
30
21
  async function nodeMessageToRequest(req) {
31
- let path = req.url;
32
- if (path === void 0) {
33
- throw new Error(`Empty request URL`);
34
- }
35
- if (!path.startsWith("/")) {
36
- path = "/" + path;
37
- }
38
- const { host } = req.headers;
39
- if (host == void 0) {
40
- throw new Error(`Missing "Host" header`);
41
- }
42
- const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
43
- const url = `${protocol}://${host}${path}`;
44
- const headers = flattenHeaders(req.headers);
45
- const body = req.method !== "GET" && req.method !== "HEAD" ? Readable.toWeb(req) : null;
46
- return new Request(url, {
47
- method: req.method,
48
- headers,
49
- body,
50
- // @ts-ignore this is needed for using a Readable for some reason
51
- duplex: "half"
52
- });
22
+ let path = req.url;
23
+ if (path === void 0) throw new Error(`Empty request URL`);
24
+ if (!path.startsWith("/")) path = "/" + path;
25
+ const { host } = req.headers;
26
+ if (host == void 0) throw new Error(`Missing "Host" header`);
27
+ const url = `${"encrypted" in req.socket && req.socket.encrypted ? "https" : "http"}://${host}${path}`;
28
+ const headers = flattenHeaders(req.headers);
29
+ const body = req.method !== "GET" && req.method !== "HEAD" ? Readable.toWeb(req) : null;
30
+ return new Request(url, {
31
+ method: req.method,
32
+ headers,
33
+ body,
34
+ duplex: "half"
35
+ });
53
36
  }
54
37
 
55
- // src/responseToNodeResponse.ts
56
- import { isArrayBufferView } from "util/types";
38
+ //#endregion
39
+ //#region src/responseToNodeResponse.ts
57
40
  async function responseToNodeResponse(res, outgoing) {
58
- outgoing.statusCode = res.status;
59
- outgoing.statusMessage = res.statusText;
60
- res.headers.forEach((value, key) => {
61
- outgoing.setHeader(key, value);
62
- });
63
- const body = res[INTERNAL_BODY];
64
- if (body === null || body === void 0) {
65
- outgoing.writeHead(res.status, res.statusText);
66
- outgoing.end();
67
- } else if (typeof body === "string" || body instanceof Uint8Array) {
68
- outgoing.writeHead(res.status, res.statusText);
69
- outgoing.end(body);
70
- } else if (body instanceof Blob) {
71
- outgoing.writeHead(res.status, res.statusText);
72
- outgoing.end(new Uint8Array(await body.arrayBuffer()));
73
- } else if (body instanceof ArrayBuffer) {
74
- outgoing.writeHead(res.status, res.statusText);
75
- outgoing.end(new Uint8Array(body));
76
- } else if (isArrayBufferView(body)) {
77
- outgoing.writeHead(res.status, res.statusText);
78
- outgoing.end(new Uint8Array(body.buffer));
79
- } else if (body instanceof FormData) {
80
- outgoing.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
81
- outgoing.writeHead(res.status, res.statusText);
82
- outgoing.end();
83
- } else {
84
- outgoing.writeHead(res.status, res.statusText);
85
- outgoing.end();
86
- }
41
+ outgoing.statusCode = res.status;
42
+ outgoing.statusMessage = res.statusText;
43
+ res.headers.forEach((value, key) => {
44
+ outgoing.setHeader(key, value);
45
+ });
46
+ const body = res[INTERNAL_BODY];
47
+ if (body === null || body === void 0) {
48
+ outgoing.writeHead(res.status, res.statusText);
49
+ outgoing.end();
50
+ } else if (typeof body === "string" || body instanceof Uint8Array) {
51
+ outgoing.writeHead(res.status, res.statusText);
52
+ outgoing.end(body);
53
+ } else if (body instanceof Blob) {
54
+ outgoing.writeHead(res.status, res.statusText);
55
+ outgoing.end(new Uint8Array(await body.arrayBuffer()));
56
+ } else if (body instanceof ArrayBuffer) {
57
+ outgoing.writeHead(res.status, res.statusText);
58
+ outgoing.end(new Uint8Array(body));
59
+ } else if (isArrayBufferView(body)) {
60
+ outgoing.writeHead(res.status, res.statusText);
61
+ outgoing.end(new Uint8Array(body.buffer));
62
+ } else if (body instanceof FormData) {
63
+ outgoing.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
64
+ outgoing.writeHead(res.status, res.statusText);
65
+ outgoing.end();
66
+ } else {
67
+ outgoing.writeHead(res.status, res.statusText);
68
+ outgoing.end();
69
+ }
87
70
  }
88
71
 
89
- // src/createFetchHandler.ts
90
- var GlobalResponse = Response;
91
- globalThis.Response = class Response2 extends GlobalResponse {
92
- [INTERNAL_BODY] = null;
93
- constructor(body, init) {
94
- super(body, init);
95
- this[INTERNAL_BODY] = body;
96
- }
72
+ //#endregion
73
+ //#region src/createFetchHandler.ts
74
+ const GlobalResponse = Response;
75
+ globalThis.Response = class Response$1 extends GlobalResponse {
76
+ [INTERNAL_BODY] = null;
77
+ constructor(body, init) {
78
+ super(body, init);
79
+ this[INTERNAL_BODY] = body;
80
+ }
97
81
  };
98
82
  function createFetchHandler(handler) {
99
- return async (incoming, outgoing) => {
100
- const req = await nodeMessageToRequest(incoming);
101
- const res = await handler(req);
102
- return await responseToNodeResponse(res, outgoing);
103
- };
83
+ return async (incoming, outgoing) => {
84
+ return await responseToNodeResponse(await handler(await nodeMessageToRequest(incoming)), outgoing);
85
+ };
104
86
  }
105
87
 
106
- // src/createNodeServer.ts
88
+ //#endregion
89
+ //#region src/createNodeServer.ts
107
90
  function createNodeServer(handler) {
108
- return createServer(createFetchHandler(handler));
91
+ return createServer(createFetchHandler(handler));
109
92
  }
110
93
 
111
- // src/adapter.ts
112
- var adapter_default = {
113
- serve: (server) => {
114
- process.env.PROTOCOL ??= "http:";
115
- process.env.HOST ??= "localhost";
116
- process.env.PORT ??= "7059";
117
- globalThis.adapter = { env: process.env };
118
- const url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;
119
- console.log(`
120
- Connecting to ${url}`);
121
- const devServer = createNodeServer(server.fetch);
122
- devServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {
123
- console.log(`Listening on ${url}
124
- `);
125
- });
126
- }
127
- };
128
- export {
129
- adapter_default as node
130
- };
94
+ //#endregion
95
+ //#region src/adapter.ts
96
+ var adapter_default = { serve: (server) => {
97
+ process.env.PROTOCOL ??= "http:";
98
+ process.env.HOST ??= "localhost";
99
+ process.env.PORT ??= "7059";
100
+ globalThis.adapter = { env: process.env };
101
+ const url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;
102
+ console.log(`\nConnecting to ${url}`);
103
+ createNodeServer(server.fetch).listen(parseInt(process.env.PORT), process.env.HOST, () => {
104
+ console.log(`Listening on ${url}\n`);
105
+ });
106
+ } };
107
+
108
+ //#endregion
109
+ export { adapter_default as node };
131
110
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/createNodeServer.ts","../src/constants.ts","../src/nodeMessageToRequest.ts","../src/flattenHeaders.ts","../src/responseToNodeResponse.ts","../src/createFetchHandler.ts","../src/adapter.ts"],"sourcesContent":["import { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { createServer } from \"node:http\";\nimport { createFetchHandler } from \"./createFetchHandler\";\n\nexport default function createNodeServer(\n\thandler: (req: Request) => Response | Promise<Response>,\n): Server<typeof IncomingMessage, typeof ServerResponse> {\n\t// Create a server, polyfill it so that it can handle standard fetch methods,\n\t// and pass our app fetch method to the handler\n\treturn createServer(createFetchHandler(handler));\n}\n","export const INTERNAL_BODY: unique symbol = Symbol(\"internal_body\");\n","import { type IncomingMessage } from \"node:http\";\nimport { Http2ServerRequest } from \"node:http2\";\nimport { Readable } from \"node:stream\";\nimport flattenHeaders from \"./flattenHeaders\";\n\n// From https://stackoverflow.com/a/78849544\n// and https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n\nexport default async function nodeMessageToRequest(\n\treq: IncomingMessage | Http2ServerRequest,\n): Promise<Request> {\n\t// Build the full url\n\tlet path = req.url;\n\tif (path === undefined) {\n\t\tthrow new Error(`Empty request URL`);\n\t}\n\tif (!path.startsWith(\"/\")) {\n\t\tpath = \"/\" + path;\n\t}\n\tconst { host } = req.headers;\n\tif (host == undefined) {\n\t\tthrow new Error(`Missing \"Host\" header`);\n\t}\n\tconst protocol = \"encrypted\" in req.socket && req.socket.encrypted ? \"https\" : \"http\";\n\tconst url = `${protocol}://${host}${path}`;\n\n\t// Flatten the headers\n\tconst headers = flattenHeaders(req.headers);\n\n\t// Convert body to Buffer if applicable\n\tconst body =\n\t\treq.method !== \"GET\" && req.method !== \"HEAD\"\n\t\t\t? (Readable.toWeb(req) as ReadableStream) // await readableToBuffer(req)\n\t\t\t: null;\n\n\treturn new Request(url, {\n\t\tmethod: req.method,\n\t\theaders: headers,\n\t\tbody: body,\n\t\t// @ts-ignore this is needed for using a Readable for some reason\n\t\tduplex: \"half\",\n\t});\n}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import { ServerResponse } from \"node:http\";\nimport { Http2ServerResponse } from \"node:http2\";\nimport { isArrayBufferView } from \"node:util/types\";\nimport { INTERNAL_BODY } from \"./constants\";\n\nexport default async function responseToNodeResponse(\n\tres: Response,\n\toutgoing: ServerResponse | Http2ServerResponse,\n): Promise<void> {\n\toutgoing.statusCode = res.status;\n\toutgoing.statusMessage = res.statusText;\n\n\tres.headers.forEach((value, key) => {\n\t\toutgoing.setHeader(key, value);\n\t});\n\n\tconst body = (res as any)[INTERNAL_BODY];\n\n\tif (body === null || body === undefined) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else if (typeof body === \"string\" || body instanceof Uint8Array) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(body);\n\t} else if (body instanceof Blob) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(await body.arrayBuffer()));\n\t} else if (body instanceof ArrayBuffer) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body));\n\t} else if (isArrayBufferView(body)) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body.buffer));\n\t} else if (body instanceof FormData) {\n\t\t// TODO\n\t\toutgoing.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded;charset=UTF-8\");\n\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t}\n}\n","import { type IncomingMessage, ServerResponse } from \"node:http\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"node:http2\";\nimport { INTERNAL_BODY } from \"./constants\";\nimport nodeMessageToRequest from \"./nodeMessageToRequest\";\nimport responseToNodeResponse from \"./responseToNodeResponse\";\n\n// From https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n// Referenced from https://marvinh.dev/blog/modern-way-to-write-javascript-servers/\n\nconst GlobalResponse = Response;\nglobalThis.Response = class Response extends GlobalResponse {\n\t[INTERNAL_BODY]: BodyInit | null | undefined = null;\n\n\tconstructor(body?: BodyInit | null, init?: ResponseInit) {\n\t\tsuper(body, init);\n\t\tthis[INTERNAL_BODY] = body;\n\t}\n};\n\nexport function createFetchHandler(handler: (req: Request) => Response | Promise<Response>) {\n\treturn async (\n\t\tincoming: IncomingMessage | Http2ServerRequest,\n\t\toutgoing: ServerResponse | Http2ServerResponse,\n\t): Promise<void> => {\n\t\tconst req = await nodeMessageToRequest(incoming);\n\t\tconst res = await handler(req);\n\t\treturn await responseToNodeResponse(res, outgoing);\n\t};\n}\n","import { type Adapter } from \"@torpor/build\";\nimport { Server } from \"@torpor/build/server\";\nimport createNodeServer from \"./createNodeServer\";\n\nexport default {\n\tserve: (server: Server) => {\n\t\tprocess.env.PROTOCOL ??= \"http:\";\n\t\tprocess.env.HOST ??= \"localhost\";\n\t\tprocess.env.PORT ??= \"7059\";\n\n\t\t// Put adapter-specific functionality in the `adapter` property of\n\t\t// globalThis for now\n\t\t// @ts-ignore\n\t\tglobalThis.adapter = { env: process.env };\n\n\t\t// Create the Node server and start listening\n\t\tconst url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;\n\t\tconsole.log(`\\nConnecting to ${url}`);\n\t\tconst devServer = createNodeServer(server.fetch);\n\t\tdevServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {\n\t\t\tconsole.log(`Listening on ${url}\\n`);\n\t\t});\n\t},\n} satisfies Adapter as Adapter;\n"],"mappings":"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","names":["v","Response"]}
1
+ {"version":3,"file":"index.js","names":["INTERNAL_BODY: unique symbol","v","Response"],"sources":["../src/constants.ts","../src/flattenHeaders.ts","../src/nodeMessageToRequest.ts","../src/responseToNodeResponse.ts","../src/createFetchHandler.ts","../src/createNodeServer.ts","../src/adapter.ts"],"sourcesContent":["export const INTERNAL_BODY: unique symbol = Symbol(\"internal_body\");\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import { type IncomingMessage } from \"node:http\";\nimport { Http2ServerRequest } from \"node:http2\";\nimport { Readable } from \"node:stream\";\nimport flattenHeaders from \"./flattenHeaders\";\n\n// From https://stackoverflow.com/a/78849544\n// and https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n\nexport default async function nodeMessageToRequest(\n\treq: IncomingMessage | Http2ServerRequest,\n): Promise<Request> {\n\t// Build the full url\n\tlet path = req.url;\n\tif (path === undefined) {\n\t\tthrow new Error(`Empty request URL`);\n\t}\n\tif (!path.startsWith(\"/\")) {\n\t\tpath = \"/\" + path;\n\t}\n\tconst { host } = req.headers;\n\tif (host == undefined) {\n\t\tthrow new Error(`Missing \"Host\" header`);\n\t}\n\tconst protocol = \"encrypted\" in req.socket && req.socket.encrypted ? \"https\" : \"http\";\n\tconst url = `${protocol}://${host}${path}`;\n\n\t// Flatten the headers\n\tconst headers = flattenHeaders(req.headers);\n\n\t// Convert body to Buffer if applicable\n\tconst body =\n\t\treq.method !== \"GET\" && req.method !== \"HEAD\"\n\t\t\t? (Readable.toWeb(req) as ReadableStream) // await readableToBuffer(req)\n\t\t\t: null;\n\n\treturn new Request(url, {\n\t\tmethod: req.method,\n\t\theaders: headers,\n\t\t// eslint-disable-next-line no-invalid-fetch-options\n\t\tbody: body,\n\t\t// @ts-ignore this is needed for using a Readable for some reason\n\t\tduplex: \"half\",\n\t});\n}\n","import { ServerResponse } from \"node:http\";\nimport { Http2ServerResponse } from \"node:http2\";\nimport { isArrayBufferView } from \"node:util/types\";\nimport { INTERNAL_BODY } from \"./constants\";\n\nexport default async function responseToNodeResponse(\n\tres: Response,\n\toutgoing: ServerResponse | Http2ServerResponse,\n): Promise<void> {\n\toutgoing.statusCode = res.status;\n\toutgoing.statusMessage = res.statusText;\n\n\tres.headers.forEach((value, key) => {\n\t\toutgoing.setHeader(key, value);\n\t});\n\n\tconst body = (res as any)[INTERNAL_BODY];\n\n\tif (body === null || body === undefined) {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else if (typeof body === \"string\" || body instanceof Uint8Array) {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(body);\n\t} else if (body instanceof Blob) {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(await body.arrayBuffer()));\n\t} else if (body instanceof ArrayBuffer) {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body));\n\t} else if (isArrayBufferView(body)) {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body.buffer));\n\t} else if (body instanceof FormData) {\n\t\t// TODO\n\t\toutgoing.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded;charset=UTF-8\");\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else {\n\t\t// @ts-ignore\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t}\n}\n","import { type IncomingMessage, ServerResponse } from \"node:http\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"node:http2\";\nimport { INTERNAL_BODY } from \"./constants\";\nimport nodeMessageToRequest from \"./nodeMessageToRequest\";\nimport responseToNodeResponse from \"./responseToNodeResponse\";\n\n// From https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n// Referenced from https://marvinh.dev/blog/modern-way-to-write-javascript-servers/\n\nconst GlobalResponse = Response;\nglobalThis.Response = class Response extends GlobalResponse {\n\t[INTERNAL_BODY]: BodyInit | null | undefined = null;\n\n\tconstructor(body?: BodyInit | null, init?: ResponseInit) {\n\t\tsuper(body, init);\n\t\tthis[INTERNAL_BODY] = body;\n\t}\n};\n\nexport function createFetchHandler(handler: (req: Request) => Response | Promise<Response>) {\n\treturn async (\n\t\tincoming: IncomingMessage | Http2ServerRequest,\n\t\toutgoing: ServerResponse | Http2ServerResponse,\n\t): Promise<void> => {\n\t\tconst req = await nodeMessageToRequest(incoming);\n\t\tconst res = await handler(req);\n\t\treturn await responseToNodeResponse(res, outgoing);\n\t};\n}\n","import { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { createServer } from \"node:http\";\nimport { createFetchHandler } from \"./createFetchHandler\";\n\nexport default function createNodeServer(\n\thandler: (req: Request) => Response | Promise<Response>,\n): Server<typeof IncomingMessage, typeof ServerResponse> {\n\t// Create a server, polyfill it so that it can handle standard fetch methods,\n\t// and pass our app fetch method to the handler\n\treturn createServer(createFetchHandler(handler));\n}\n","import { type Adapter } from \"@torpor/build\";\nimport { Server } from \"@torpor/build/server\";\nimport createNodeServer from \"./createNodeServer\";\n\nexport default {\n\tserve: (server: Server) => {\n\t\tprocess.env.PROTOCOL ??= \"http:\";\n\t\tprocess.env.HOST ??= \"localhost\";\n\t\tprocess.env.PORT ??= \"7059\";\n\n\t\t// Put adapter-specific functionality in the `adapter` property of\n\t\t// globalThis for now\n\t\t// @ts-ignore\n\t\tglobalThis.adapter = { env: process.env };\n\n\t\t// Create the Node server and start listening\n\t\tconst url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;\n\t\tconsole.log(`\\nConnecting to ${url}`);\n\t\tconst devServer = createNodeServer(server.fetch);\n\t\tdevServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {\n\t\t\tconsole.log(`Listening on ${url}\\n`);\n\t\t});\n\t},\n} satisfies Adapter as Adapter;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,15 +1,11 @@
1
1
  {
2
2
  "name": "@torpor/adapter-node",
3
- "version": "0.0.30",
3
+ "version": "0.1.1",
4
4
  "description": "A @torpor/build adapter for running on Node",
5
5
  "type": "module",
6
- "main": "dist/index.cjs",
7
- "module": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
6
  "exports": {
10
7
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.cjs"
8
+ "import": "./dist/index.js"
13
9
  },
14
10
  "publishConfig": {
15
11
  "access": "public"
@@ -18,18 +14,19 @@
18
14
  "author": "",
19
15
  "license": "ISC",
20
16
  "dependencies": {
21
- "vite": "^7.1.1",
22
- "@torpor/build": "^0.2.0"
17
+ "vite": "^7.1.12",
18
+ "@torpor/build": "^0.4.0"
23
19
  },
24
20
  "devDependencies": {
25
21
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
26
- "tsup": "^8.5.0",
27
- "tsx": "^4.20.3",
28
- "typescript": "^5.9.2"
22
+ "@typescript/native-preview": "7.0.0-dev.20251027.1",
23
+ "oxlint-tsgolint": "^0.3.0",
24
+ "tsdown": "^0.15.11",
25
+ "typescript": "^5.9.3"
29
26
  },
30
27
  "scripts": {
31
- "build": "tsc --noEmit && tsup",
32
- "build:watch": "tsup --watch",
33
- "check": "tsc --noEmit"
28
+ "build": "tsgo --noEmit && tsdown",
29
+ "build:watch": "tsdown --watch",
30
+ "check": "tsgo --noEmit && pnpm dlx oxlint --type-aware"
34
31
  }
35
32
  }
@@ -36,6 +36,7 @@ export default async function nodeMessageToRequest(
36
36
  return new Request(url, {
37
37
  method: req.method,
38
38
  headers: headers,
39
+ // eslint-disable-next-line no-invalid-fetch-options
39
40
  body: body,
40
41
  // @ts-ignore this is needed for using a Readable for some reason
41
42
  duplex: "half",
@@ -17,27 +17,33 @@ export default async function responseToNodeResponse(
17
17
  const body = (res as any)[INTERNAL_BODY];
18
18
 
19
19
  if (body === null || body === undefined) {
20
+ // @ts-ignore
20
21
  outgoing.writeHead(res.status, res.statusText);
21
22
  outgoing.end();
22
23
  } else if (typeof body === "string" || body instanceof Uint8Array) {
24
+ // @ts-ignore
23
25
  outgoing.writeHead(res.status, res.statusText);
24
26
  outgoing.end(body);
25
27
  } else if (body instanceof Blob) {
28
+ // @ts-ignore
26
29
  outgoing.writeHead(res.status, res.statusText);
27
30
  outgoing.end(new Uint8Array(await body.arrayBuffer()));
28
31
  } else if (body instanceof ArrayBuffer) {
32
+ // @ts-ignore
29
33
  outgoing.writeHead(res.status, res.statusText);
30
34
  outgoing.end(new Uint8Array(body));
31
35
  } else if (isArrayBufferView(body)) {
36
+ // @ts-ignore
32
37
  outgoing.writeHead(res.status, res.statusText);
33
38
  outgoing.end(new Uint8Array(body.buffer));
34
39
  } else if (body instanceof FormData) {
35
40
  // TODO
36
41
  outgoing.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
37
-
42
+ // @ts-ignore
38
43
  outgoing.writeHead(res.status, res.statusText);
39
44
  outgoing.end();
40
45
  } else {
46
+ // @ts-ignore
41
47
  outgoing.writeHead(res.status, res.statusText);
42
48
  outgoing.end();
43
49
  }
@@ -1,4 +1,4 @@
1
- import { type Options, defineConfig } from "tsup";
1
+ import { type Options, defineConfig } from "tsdown";
2
2
 
3
3
  type Config =
4
4
  | Options
@@ -7,9 +7,7 @@ type Config =
7
7
 
8
8
  export default defineConfig({
9
9
  entry: ["src/index.ts"],
10
- format: ["esm", "cjs"],
10
+ format: "esm",
11
11
  dts: true,
12
- clean: true,
13
- metafile: true,
14
12
  sourcemap: true,
15
13
  }) satisfies Config as Config;
package/dist/index.cjs DELETED
@@ -1,158 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- node: () => adapter_default
24
- });
25
- module.exports = __toCommonJS(index_exports);
26
-
27
- // src/createNodeServer.ts
28
- var import_node_http = require("http");
29
-
30
- // src/constants.ts
31
- var INTERNAL_BODY = Symbol("internal_body");
32
-
33
- // src/nodeMessageToRequest.ts
34
- var import_node_stream = require("stream");
35
-
36
- // src/flattenHeaders.ts
37
- function flattenHeaders(headers) {
38
- const flatHeaders = new Headers();
39
- for (const [key, value] of Object.entries(headers)) {
40
- if (value === void 0 || value === null) {
41
- continue;
42
- } else if (Array.isArray(value)) {
43
- for (const v of value) {
44
- if (v !== void 0 && v !== null) {
45
- value.forEach((v2) => flatHeaders.append(key, v2));
46
- }
47
- }
48
- } else {
49
- flatHeaders.set(key, String(value));
50
- }
51
- }
52
- return flatHeaders;
53
- }
54
-
55
- // src/nodeMessageToRequest.ts
56
- async function nodeMessageToRequest(req) {
57
- let path = req.url;
58
- if (path === void 0) {
59
- throw new Error(`Empty request URL`);
60
- }
61
- if (!path.startsWith("/")) {
62
- path = "/" + path;
63
- }
64
- const { host } = req.headers;
65
- if (host == void 0) {
66
- throw new Error(`Missing "Host" header`);
67
- }
68
- const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
69
- const url = `${protocol}://${host}${path}`;
70
- const headers = flattenHeaders(req.headers);
71
- const body = req.method !== "GET" && req.method !== "HEAD" ? import_node_stream.Readable.toWeb(req) : null;
72
- return new Request(url, {
73
- method: req.method,
74
- headers,
75
- body,
76
- // @ts-ignore this is needed for using a Readable for some reason
77
- duplex: "half"
78
- });
79
- }
80
-
81
- // src/responseToNodeResponse.ts
82
- var import_types = require("util/types");
83
- async function responseToNodeResponse(res, outgoing) {
84
- outgoing.statusCode = res.status;
85
- outgoing.statusMessage = res.statusText;
86
- res.headers.forEach((value, key) => {
87
- outgoing.setHeader(key, value);
88
- });
89
- const body = res[INTERNAL_BODY];
90
- if (body === null || body === void 0) {
91
- outgoing.writeHead(res.status, res.statusText);
92
- outgoing.end();
93
- } else if (typeof body === "string" || body instanceof Uint8Array) {
94
- outgoing.writeHead(res.status, res.statusText);
95
- outgoing.end(body);
96
- } else if (body instanceof Blob) {
97
- outgoing.writeHead(res.status, res.statusText);
98
- outgoing.end(new Uint8Array(await body.arrayBuffer()));
99
- } else if (body instanceof ArrayBuffer) {
100
- outgoing.writeHead(res.status, res.statusText);
101
- outgoing.end(new Uint8Array(body));
102
- } else if ((0, import_types.isArrayBufferView)(body)) {
103
- outgoing.writeHead(res.status, res.statusText);
104
- outgoing.end(new Uint8Array(body.buffer));
105
- } else if (body instanceof FormData) {
106
- outgoing.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
107
- outgoing.writeHead(res.status, res.statusText);
108
- outgoing.end();
109
- } else {
110
- outgoing.writeHead(res.status, res.statusText);
111
- outgoing.end();
112
- }
113
- }
114
-
115
- // src/createFetchHandler.ts
116
- var GlobalResponse = Response;
117
- globalThis.Response = class Response2 extends GlobalResponse {
118
- [INTERNAL_BODY] = null;
119
- constructor(body, init) {
120
- super(body, init);
121
- this[INTERNAL_BODY] = body;
122
- }
123
- };
124
- function createFetchHandler(handler) {
125
- return async (incoming, outgoing) => {
126
- const req = await nodeMessageToRequest(incoming);
127
- const res = await handler(req);
128
- return await responseToNodeResponse(res, outgoing);
129
- };
130
- }
131
-
132
- // src/createNodeServer.ts
133
- function createNodeServer(handler) {
134
- return (0, import_node_http.createServer)(createFetchHandler(handler));
135
- }
136
-
137
- // src/adapter.ts
138
- var adapter_default = {
139
- serve: (server) => {
140
- process.env.PROTOCOL ??= "http:";
141
- process.env.HOST ??= "localhost";
142
- process.env.PORT ??= "7059";
143
- globalThis.adapter = { env: process.env };
144
- const url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;
145
- console.log(`
146
- Connecting to ${url}`);
147
- const devServer = createNodeServer(server.fetch);
148
- devServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {
149
- console.log(`Listening on ${url}
150
- `);
151
- });
152
- }
153
- };
154
- // Annotate the CommonJS export names for ESM import in node:
155
- 0 && (module.exports = {
156
- node
157
- });
158
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/createNodeServer.ts","../src/constants.ts","../src/nodeMessageToRequest.ts","../src/flattenHeaders.ts","../src/responseToNodeResponse.ts","../src/createFetchHandler.ts","../src/adapter.ts"],"sourcesContent":["import node from \"./adapter\";\n\nexport { node };\n","import { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { createServer } from \"node:http\";\nimport { createFetchHandler } from \"./createFetchHandler\";\n\nexport default function createNodeServer(\n\thandler: (req: Request) => Response | Promise<Response>,\n): Server<typeof IncomingMessage, typeof ServerResponse> {\n\t// Create a server, polyfill it so that it can handle standard fetch methods,\n\t// and pass our app fetch method to the handler\n\treturn createServer(createFetchHandler(handler));\n}\n","export const INTERNAL_BODY: unique symbol = Symbol(\"internal_body\");\n","import { type IncomingMessage } from \"node:http\";\nimport { Http2ServerRequest } from \"node:http2\";\nimport { Readable } from \"node:stream\";\nimport flattenHeaders from \"./flattenHeaders\";\n\n// From https://stackoverflow.com/a/78849544\n// and https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n\nexport default async function nodeMessageToRequest(\n\treq: IncomingMessage | Http2ServerRequest,\n): Promise<Request> {\n\t// Build the full url\n\tlet path = req.url;\n\tif (path === undefined) {\n\t\tthrow new Error(`Empty request URL`);\n\t}\n\tif (!path.startsWith(\"/\")) {\n\t\tpath = \"/\" + path;\n\t}\n\tconst { host } = req.headers;\n\tif (host == undefined) {\n\t\tthrow new Error(`Missing \"Host\" header`);\n\t}\n\tconst protocol = \"encrypted\" in req.socket && req.socket.encrypted ? \"https\" : \"http\";\n\tconst url = `${protocol}://${host}${path}`;\n\n\t// Flatten the headers\n\tconst headers = flattenHeaders(req.headers);\n\n\t// Convert body to Buffer if applicable\n\tconst body =\n\t\treq.method !== \"GET\" && req.method !== \"HEAD\"\n\t\t\t? (Readable.toWeb(req) as ReadableStream) // await readableToBuffer(req)\n\t\t\t: null;\n\n\treturn new Request(url, {\n\t\tmethod: req.method,\n\t\theaders: headers,\n\t\tbody: body,\n\t\t// @ts-ignore this is needed for using a Readable for some reason\n\t\tduplex: \"half\",\n\t});\n}\n","import { IncomingHttpHeaders } from \"node:http\";\nimport { OutgoingHttpHeaders } from \"node:http2\";\n\nexport default function flattenHeaders(\n\theaders: IncomingHttpHeaders | OutgoingHttpHeaders,\n): HeadersInit {\n\tconst flatHeaders = new Headers();\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v !== undefined && v !== null) {\n\t\t\t\t\tvalue.forEach((v) => flatHeaders.append(key, v));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.set(key, String(value));\n\t\t}\n\t}\n\treturn flatHeaders;\n\n\t/*\n const flatHeaders: [string, string][] = [];\n\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (value === undefined || value === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (const v of value) {\n\t\t\t\tif (v != null) {\n\t\t\t\t\tflatHeaders.push([key, String(v)]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tflatHeaders.push([key, String(value)]);\n\t\t}\n\t}\n\n\treturn flatHeaders;\n */\n}\n","import { ServerResponse } from \"node:http\";\nimport { Http2ServerResponse } from \"node:http2\";\nimport { isArrayBufferView } from \"node:util/types\";\nimport { INTERNAL_BODY } from \"./constants\";\n\nexport default async function responseToNodeResponse(\n\tres: Response,\n\toutgoing: ServerResponse | Http2ServerResponse,\n): Promise<void> {\n\toutgoing.statusCode = res.status;\n\toutgoing.statusMessage = res.statusText;\n\n\tres.headers.forEach((value, key) => {\n\t\toutgoing.setHeader(key, value);\n\t});\n\n\tconst body = (res as any)[INTERNAL_BODY];\n\n\tif (body === null || body === undefined) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else if (typeof body === \"string\" || body instanceof Uint8Array) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(body);\n\t} else if (body instanceof Blob) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(await body.arrayBuffer()));\n\t} else if (body instanceof ArrayBuffer) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body));\n\t} else if (isArrayBufferView(body)) {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end(new Uint8Array(body.buffer));\n\t} else if (body instanceof FormData) {\n\t\t// TODO\n\t\toutgoing.setHeader(\"Content-Type\", \"application/x-www-form-urlencoded;charset=UTF-8\");\n\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t} else {\n\t\toutgoing.writeHead(res.status, res.statusText);\n\t\toutgoing.end();\n\t}\n}\n","import { type IncomingMessage, ServerResponse } from \"node:http\";\nimport { Http2ServerRequest, Http2ServerResponse } from \"node:http2\";\nimport { INTERNAL_BODY } from \"./constants\";\nimport nodeMessageToRequest from \"./nodeMessageToRequest\";\nimport responseToNodeResponse from \"./responseToNodeResponse\";\n\n// From https://gist.github.com/marvinhagemeister/cc236ec97235ce0305ae9d48a24a607d\n// Referenced from https://marvinh.dev/blog/modern-way-to-write-javascript-servers/\n\nconst GlobalResponse = Response;\nglobalThis.Response = class Response extends GlobalResponse {\n\t[INTERNAL_BODY]: BodyInit | null | undefined = null;\n\n\tconstructor(body?: BodyInit | null, init?: ResponseInit) {\n\t\tsuper(body, init);\n\t\tthis[INTERNAL_BODY] = body;\n\t}\n};\n\nexport function createFetchHandler(handler: (req: Request) => Response | Promise<Response>) {\n\treturn async (\n\t\tincoming: IncomingMessage | Http2ServerRequest,\n\t\toutgoing: ServerResponse | Http2ServerResponse,\n\t): Promise<void> => {\n\t\tconst req = await nodeMessageToRequest(incoming);\n\t\tconst res = await handler(req);\n\t\treturn await responseToNodeResponse(res, outgoing);\n\t};\n}\n","import { type Adapter } from \"@torpor/build\";\nimport { Server } from \"@torpor/build/server\";\nimport createNodeServer from \"./createNodeServer\";\n\nexport default {\n\tserve: (server: Server) => {\n\t\tprocess.env.PROTOCOL ??= \"http:\";\n\t\tprocess.env.HOST ??= \"localhost\";\n\t\tprocess.env.PORT ??= \"7059\";\n\n\t\t// Put adapter-specific functionality in the `adapter` property of\n\t\t// globalThis for now\n\t\t// @ts-ignore\n\t\tglobalThis.adapter = { env: process.env };\n\n\t\t// Create the Node server and start listening\n\t\tconst url = `${process.env.PROTOCOL}//${process.env.HOST}:${process.env.PORT}`;\n\t\tconsole.log(`\\nConnecting to ${url}`);\n\t\tconst devServer = createNodeServer(server.fetch);\n\t\tdevServer.listen(parseInt(process.env.PORT), process.env.HOST, () => {\n\t\t\tconsole.log(`Listening on ${url}\\n`);\n\t\t});\n\t},\n} satisfies Adapter as Adapter;\n"],"mappings":"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","names":["v","Response"]}
package/dist/index.d.cts DELETED
@@ -1,5 +0,0 @@
1
- import { Adapter } from '@torpor/build';
2
-
3
- declare const _default: Adapter;
4
-
5
- export { _default as node };
@@ -1 +0,0 @@
1
- {"inputs":{"src/constants.ts":{"bytes":69,"imports":[],"format":"esm"},"src/flattenHeaders.ts":{"bytes":1017,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true}],"format":"esm"},"src/nodeMessageToRequest.ts":{"bytes":1277,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"stream","kind":"import-statement","external":true},{"path":"src/flattenHeaders.ts","kind":"import-statement","original":"./flattenHeaders"}],"format":"esm"},"src/responseToNodeResponse.ts":{"bytes":1486,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"util/types","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"}],"format":"esm"},"src/createFetchHandler.ts":{"bytes":1119,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"src/nodeMessageToRequest.ts","kind":"import-statement","original":"./nodeMessageToRequest"},{"path":"src/responseToNodeResponse.ts","kind":"import-statement","original":"./responseToNodeResponse"}],"format":"esm"},"src/createNodeServer.ts":{"bytes":506,"imports":[{"path":"http","kind":"import-statement","external":true},{"path":"http","kind":"import-statement","external":true},{"path":"src/createFetchHandler.ts","kind":"import-statement","original":"./createFetchHandler"}],"format":"esm"},"src/adapter.ts":{"bytes":830,"imports":[{"path":"@torpor/build","kind":"import-statement","external":true},{"path":"@torpor/build/server","kind":"import-statement","external":true},{"path":"src/createNodeServer.ts","kind":"import-statement","original":"./createNodeServer"}],"format":"esm"},"src/index.ts":{"bytes":48,"imports":[{"path":"src/adapter.ts","kind":"import-statement","original":"./adapter"}],"format":"esm"}},"outputs":{"dist/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9962},"dist/index.cjs":{"imports":[{"path":"http","kind":"require-call","external":true},{"path":"stream","kind":"require-call","external":true},{"path":"util/types","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":130},"src/createNodeServer.ts":{"bytesInOutput":153},"src/constants.ts":{"bytesInOutput":45},"src/nodeMessageToRequest.ts":{"bytesInOutput":808},"src/flattenHeaders.ts":{"bytesInOutput":472},"src/responseToNodeResponse.ts":{"bytesInOutput":1289},"src/createFetchHandler.ts":{"bytesInOutput":443},"src/adapter.ts":{"bytesInOutput":516}},"bytes":5020}}}
@@ -1 +0,0 @@
1
- {"inputs":{"src/constants.ts":{"bytes":69,"imports":[],"format":"esm"},"src/flattenHeaders.ts":{"bytes":1017,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true}],"format":"esm"},"src/nodeMessageToRequest.ts":{"bytes":1277,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"stream","kind":"import-statement","external":true},{"path":"src/flattenHeaders.ts","kind":"import-statement","original":"./flattenHeaders"}],"format":"esm"},"src/responseToNodeResponse.ts":{"bytes":1486,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"util/types","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"}],"format":"esm"},"src/createFetchHandler.ts":{"bytes":1119,"imports":[{"path":"node:http","kind":"import-statement","external":true},{"path":"node:http2","kind":"import-statement","external":true},{"path":"src/constants.ts","kind":"import-statement","original":"./constants"},{"path":"src/nodeMessageToRequest.ts","kind":"import-statement","original":"./nodeMessageToRequest"},{"path":"src/responseToNodeResponse.ts","kind":"import-statement","original":"./responseToNodeResponse"}],"format":"esm"},"src/createNodeServer.ts":{"bytes":506,"imports":[{"path":"http","kind":"import-statement","external":true},{"path":"http","kind":"import-statement","external":true},{"path":"src/createFetchHandler.ts","kind":"import-statement","original":"./createFetchHandler"}],"format":"esm"},"src/adapter.ts":{"bytes":830,"imports":[{"path":"@torpor/build","kind":"import-statement","external":true},{"path":"@torpor/build/server","kind":"import-statement","external":true},{"path":"src/createNodeServer.ts","kind":"import-statement","original":"./createNodeServer"}],"format":"esm"},"src/index.ts":{"bytes":48,"imports":[{"path":"src/adapter.ts","kind":"import-statement","original":"./adapter"}],"format":"esm"}},"outputs":{"dist/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":9853},"dist/index.js":{"imports":[{"path":"http","kind":"import-statement","external":true},{"path":"stream","kind":"import-statement","external":true},{"path":"util/types","kind":"import-statement","external":true}],"exports":["node"],"entryPoint":"src/index.ts","inputs":{"src/createNodeServer.ts":{"bytesInOutput":128},"src/constants.ts":{"bytesInOutput":45},"src/nodeMessageToRequest.ts":{"bytesInOutput":780},"src/flattenHeaders.ts":{"bytesInOutput":472},"src/responseToNodeResponse.ts":{"bytesInOutput":1277},"src/createFetchHandler.ts":{"bytesInOutput":443},"src/adapter.ts":{"bytesInOutput":516},"src/index.ts":{"bytesInOutput":0}},"bytes":3948}}}