dx-server 0.12.2 → 0.13.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.
Files changed (106) hide show
  1. package/README.md +47 -55
  2. package/{cjs → lib}/body.d.ts +2 -3
  3. package/lib/body.js +10 -0
  4. package/{esm → lib}/bodyHelpers.d.ts +2 -4
  5. package/lib/bodyHelpers.js +89 -0
  6. package/{esm → lib}/dx.d.ts +5 -8
  7. package/lib/dx.js +127 -0
  8. package/{cjs → lib}/dxHelpers.d.ts +0 -4
  9. package/{esm → lib}/dxHelpers.js +0 -2
  10. package/{cjs → lib}/index.d.ts +0 -1
  11. package/{esm/index.d.ts → lib/index.js} +0 -1
  12. package/lib/logger.js +56 -0
  13. package/lib/router.d.ts +42 -0
  14. package/lib/router.js +43 -0
  15. package/lib/static.js +22 -0
  16. package/{cjs → lib}/staticHelpers.d.ts +0 -2
  17. package/lib/staticHelpers.js +186 -0
  18. package/{cjs → lib}/stream.d.ts +2 -7
  19. package/lib/stream.js +90 -0
  20. package/{esm → lib}/vendors/contentType.js +0 -1
  21. package/{cjs → lib}/vendors/etag.d.ts +0 -3
  22. package/lib/vendors/etag.js +104 -0
  23. package/{cjs → lib}/vendors/fresh.d.ts +2 -2
  24. package/lib/vendors/fresh.js +95 -0
  25. package/lib/vendors/mime.d.ts +1 -0
  26. package/lib/vendors/mime.js +35 -0
  27. package/{esm → lib}/vendors/mimeDb.js +0 -1
  28. package/{cjs → lib}/vendors/mimeScore.d.ts +1 -1
  29. package/lib/vendors/mimeScore.js +45 -0
  30. package/{cjs → lib}/vendors/onFinished.d.ts +1 -1
  31. package/lib/vendors/onFinished.js +231 -0
  32. package/lib/vendors/rangeParser.d.ts +20 -0
  33. package/lib/vendors/rangeParser.js +121 -0
  34. package/package.json +10 -19
  35. package/cjs/body.js +0 -14
  36. package/cjs/bodyHelpers.d.ts +0 -16
  37. package/cjs/bodyHelpers.js +0 -101
  38. package/cjs/connect.d.ts +0 -5
  39. package/cjs/connect.js +0 -44
  40. package/cjs/dx.d.ts +0 -46
  41. package/cjs/dx.js +0 -144
  42. package/cjs/dxHelpers.js +0 -123
  43. package/cjs/express.d.ts +0 -4
  44. package/cjs/express.js +0 -43
  45. package/cjs/helpers.js +0 -14
  46. package/cjs/index.js +0 -38
  47. package/cjs/logger.js +0 -61
  48. package/cjs/package.json +0 -3
  49. package/cjs/polyfillWithResolvers.d.ts +0 -1
  50. package/cjs/polyfillWithResolvers.js +0 -17
  51. package/cjs/router.js +0 -47
  52. package/cjs/static.js +0 -27
  53. package/cjs/staticHelpers.js +0 -195
  54. package/cjs/stream.js +0 -97
  55. package/cjs/vendors/contentType.js +0 -92
  56. package/cjs/vendors/etag.js +0 -136
  57. package/cjs/vendors/fresh.js +0 -102
  58. package/cjs/vendors/mime.d.ts +0 -1
  59. package/cjs/vendors/mime.js +0 -42
  60. package/cjs/vendors/mimeDb.js +0 -9417
  61. package/cjs/vendors/mimeScore.js +0 -50
  62. package/cjs/vendors/onFinished.js +0 -245
  63. package/cjs/vendors/rangeParser.d.ts +0 -10
  64. package/cjs/vendors/rangeParser.js +0 -126
  65. package/esm/body.d.ts +0 -8
  66. package/esm/body.js +0 -11
  67. package/esm/bodyHelpers.js +0 -90
  68. package/esm/connect.d.ts +0 -5
  69. package/esm/connect.js +0 -40
  70. package/esm/dx.js +0 -128
  71. package/esm/dxHelpers.d.ts +0 -49
  72. package/esm/express.d.ts +0 -4
  73. package/esm/express.js +0 -35
  74. package/esm/helpers.js +0 -3
  75. package/esm/index.js +0 -9
  76. package/esm/logger.d.ts +0 -3
  77. package/esm/logger.js +0 -57
  78. package/esm/polyfillWithResolvers.d.ts +0 -1
  79. package/esm/polyfillWithResolvers.js +0 -16
  80. package/esm/router.js +0 -44
  81. package/esm/static.d.ts +0 -5
  82. package/esm/static.js +0 -23
  83. package/esm/staticHelpers.d.ts +0 -18
  84. package/esm/staticHelpers.js +0 -188
  85. package/esm/stream.d.ts +0 -12
  86. package/esm/stream.js +0 -92
  87. package/esm/vendors/contentType.d.ts +0 -4
  88. package/esm/vendors/etag.d.ts +0 -10
  89. package/esm/vendors/etag.js +0 -105
  90. package/esm/vendors/fresh.d.ts +0 -23
  91. package/esm/vendors/fresh.js +0 -96
  92. package/esm/vendors/mime.d.ts +0 -1
  93. package/esm/vendors/mime.js +0 -35
  94. package/esm/vendors/mimeDb.d.ts +0 -9413
  95. package/esm/vendors/mimeScore.d.ts +0 -5
  96. package/esm/vendors/mimeScore.js +0 -46
  97. package/esm/vendors/onFinished.d.ts +0 -14
  98. package/esm/vendors/onFinished.js +0 -241
  99. package/esm/vendors/rangeParser.d.ts +0 -10
  100. package/esm/vendors/rangeParser.js +0 -122
  101. /package/{cjs → lib}/helpers.d.ts +0 -0
  102. /package/{esm/helpers.d.ts → lib/helpers.js} +0 -0
  103. /package/{cjs → lib}/logger.d.ts +0 -0
  104. /package/{cjs → lib}/static.d.ts +0 -0
  105. /package/{cjs → lib}/vendors/contentType.d.ts +0 -0
  106. /package/{cjs → lib}/vendors/mimeDb.d.ts +0 -0
package/esm/dx.js DELETED
@@ -1,128 +0,0 @@
1
- import { AsyncLocalStorage } from 'node:async_hooks';
2
- import { writeRes } from './dxHelpers.js';
3
- export function makeDxContext(maker) {
4
- const promiseMap = new WeakMap();
5
- const valueMap = new WeakMap();
6
- const context = (...params) => {
7
- const req = getReq();
8
- if (!promiseMap.has(req))
9
- promiseMap.set(req, (async () => {
10
- const value = await maker(...params);
11
- valueMap.set(req, value);
12
- return value;
13
- })());
14
- return promiseMap.get(req);
15
- };
16
- Object.defineProperty(context, 'value', {
17
- get() { return valueMap.get(getReq()); },
18
- set(value) {
19
- const req = getReq();
20
- promiseMap.set(req, Promise.resolve(value));
21
- valueMap.set(req, value);
22
- }
23
- });
24
- context.chain = (...params) => async (next) => {
25
- await context(...params);
26
- return next();
27
- };
28
- context.set = (req, value) => {
29
- promiseMap.set(req, Promise.resolve(value));
30
- valueMap.set(req, value);
31
- };
32
- context.get = req => valueMap.get(req);
33
- return context;
34
- }
35
- const requestStorage = new AsyncLocalStorage();
36
- const dxContext = makeDxContext(options => ({ ...options }));
37
- export function dxServer(req, res, options = {}) {
38
- return async (next) => {
39
- dxContext.set(req, { ...options });
40
- const result = await requestStorage.run({ req, res }, next);
41
- await writeRes(req, res, dxContext.get(req));
42
- return result;
43
- };
44
- }
45
- // method: verb
46
- // url: full url without server, protocol, port.
47
- // headers: if headers are repeated, they are joined by comma. Header names are lowercased.
48
- // rawHeaders: list of header name and value in a flat array. Case is preserved.
49
- export function getReq() { return requestStorage.getStore().req; }
50
- export function getRes() { return requestStorage.getStore().res; }
51
- export function setText(text, { status } = {}) {
52
- const res = getRes();
53
- const dx = dxContext.value;
54
- if (status)
55
- res.statusCode = status;
56
- dx.data = text;
57
- dx.type = 'text';
58
- }
59
- export function setEmpty({ status } = {}) {
60
- const res = getRes();
61
- const dx = dxContext.value;
62
- if (status)
63
- res.statusCode = status;
64
- dx.data = undefined;
65
- dx.type = 'empty';
66
- }
67
- export function setHtml(html, opts = {}) {
68
- setText(html, opts);
69
- const dx = dxContext.value;
70
- dx.type = 'html';
71
- }
72
- export function setFile(filePath, options) {
73
- const dx = dxContext.value;
74
- dx.data = filePath;
75
- dx.type = 'file';
76
- dx.options = options;
77
- }
78
- export function setBuffer(buffer, { status } = {}) {
79
- const res = getRes();
80
- const dx = dxContext.value;
81
- if (status)
82
- res.statusCode = status;
83
- dx.data = buffer;
84
- dx.type = 'buffer';
85
- }
86
- export function setNodeStream(stream, { status } = {}) {
87
- const res = getRes();
88
- const dx = dxContext.value;
89
- if (status)
90
- res.statusCode = status;
91
- dx.data = stream;
92
- dx.type = 'nodeStream';
93
- }
94
- export function setWebStream(stream, { status } = {}) {
95
- const res = getRes();
96
- const dx = dxContext.value;
97
- if (status)
98
- res.statusCode = status;
99
- dx.data = stream;
100
- dx.type = 'webStream';
101
- }
102
- export function setJson(json, { status } = {}) {
103
- const res = getRes();
104
- if (status)
105
- res.statusCode = status;
106
- const dx = dxContext.value;
107
- dx.data = json;
108
- dx.type = 'json';
109
- }
110
- export function setRedirect(url, status) {
111
- const res = getRes();
112
- const dx = dxContext.value;
113
- res.statusCode = status;
114
- dx.data = url;
115
- dx.type = 'redirect';
116
- }
117
- // for download, set content-disposition header
118
- // res.setHeader('Content-disposition', 'attachment; filename=my-movie.MOV')
119
- // res.setHeader('Content-type', 'video/quicktime')
120
- // fileStream.pipe(res)
121
- // or
122
- // send(req, filePath, options).pipe(res) // which will set content-type, content-length, and other cache related headers like staticHelpers.sendFile
123
- // implementing this require a strict validation for the type (attachment) and filename.
124
- // For example: express relies on this
125
- // https://github.com/jshttp/content-disposition/blob/1037e24e4790273da96645ad250061f39e77968c/index.js#L186
126
- // because in most applications, users can specify a simple filename which usually doesn't need to be validated.
127
- // we leave setDownload() implementation for users, for now.
128
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZHgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDbEQsT0FBTyxFQUFpQixRQUFRLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQTtBQXVCdkQsTUFBTSxVQUFVLGFBQWEsQ0FLM0IsS0FBNEM7SUFDN0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxPQUFPLEVBQStCLENBQUE7SUFDN0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQXNCLENBQUE7SUFDbEQsTUFBTSxPQUFPLEdBQWdDLENBQUMsR0FBRyxNQUFjLEVBQUUsRUFBRTtRQUNsRSxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFO2dCQUN6RCxNQUFNLEtBQUssR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFBO2dCQUNwQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQTtnQkFDeEIsT0FBTyxLQUFLLENBQUE7WUFDYixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDTCxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDM0IsQ0FBQyxDQUFBO0lBQ0QsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFO1FBQ3ZDLEdBQUcsS0FBSSxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQSxDQUFBLENBQUM7UUFDckMsR0FBRyxDQUFDLEtBQUs7WUFDUixNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtZQUNwQixVQUFVLENBQUMsR0FBRyxD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
@@ -1,49 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- /// <reference types="node" resolution-mode="require"/>
4
- import type { IncomingMessage, ServerResponse } from 'node:http';
5
- import { Readable } from 'node:stream';
6
- import { type SendFileOptions } from './staticHelpers.js';
7
- import './polyfillWithResolvers.js';
8
- export type DxContext = {
9
- charset?: BufferEncoding;
10
- jsonBeautify?: boolean;
11
- disableEtag?: boolean;
12
- } & ({
13
- type: 'empty';
14
- data: undefined;
15
- options: undefined;
16
- } | {
17
- type: 'text';
18
- data: string;
19
- options: undefined;
20
- } | {
21
- type: 'html';
22
- data: string;
23
- options: undefined;
24
- } | {
25
- type: 'buffer';
26
- data: Buffer;
27
- options: undefined;
28
- } | {
29
- type: 'json';
30
- data: any;
31
- options: undefined;
32
- } | {
33
- type: 'redirect';
34
- data: string;
35
- options: undefined;
36
- } | {
37
- type: 'nodeStream';
38
- data: Readable;
39
- options: undefined;
40
- } | {
41
- type: 'webStream';
42
- data: ReadableStream;
43
- options: undefined;
44
- } | {
45
- type: 'file';
46
- data: string;
47
- options?: SendFileOptions;
48
- });
49
- export declare function writeRes(req: IncomingMessage, res: ServerResponse, { type, data, charset, jsonBeautify, disableEtag, options }: DxContext): Promise<void>;
package/esm/express.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import { type Express, type Router } from 'express';
2
- import './polyfillWithResolvers.js';
3
- export declare function expressApp(setup: (app: Express) => any): Promise<(next: any) => Promise<void>>;
4
- export declare function expressRouter(setup: (router: Router) => any): Promise<(next: any) => Promise<void>>;
package/esm/express.js DELETED
@@ -1,35 +0,0 @@
1
- import express from 'express';
2
- import { getReq, getRes } from './dx.js';
3
- import './polyfillWithResolvers.js';
4
- export async function expressApp(setup) {
5
- const map = new WeakMap();
6
- const app = express();
7
- await setup(app);
8
- app.use((req, _res, _next) => map.get(req)?.resolve());
9
- app.use((err, req, _res, _next) => map.get(req)?.reject(err));
10
- return async (next) => {
11
- const defer = Promise.withResolvers();
12
- const req = getReq();
13
- map.set(req, defer);
14
- app(req, getRes());
15
- await defer.promise;
16
- await next();
17
- };
18
- }
19
- // can be used to chain existing Express app
20
- export async function expressRouter(setup) {
21
- const map = new WeakMap();
22
- const router = express.Router();
23
- await setup(router);
24
- router.use((req, _res, _next) => map.get(req)?.resolve());
25
- router.use((err, req, _res, _next) => map.get(req)?.reject(err));
26
- return async (next) => {
27
- const defer = Promise.withResolvers();
28
- const req = getReq();
29
- map.set(req, defer);
30
- router(req, getRes());
31
- await defer.promise; // if express middleware responses to the request, this will never resolve.
32
- await next();
33
- };
34
- }
35
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sT0FBb0MsTUFBTSxTQUFTLENBQUE7QUFDMUQsT0FBTyxFQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFFdEMsT0FBTyw0QkFBNEIsQ0FBQTtBQUVuQyxNQUFNLENBQUMsS0FBSyxVQUFVLFVBQVUsQ0FBQyxLQUE0QjtJQUM1RCxNQUFNLEdBQUcsR0FBRyxJQUFJLE9BQU8sRUFBOEMsQ0FBQTtJQUNyRSxNQUFNLEdBQUcsR0FBRyxPQUFPLEVBQUUsQ0FBQTtJQUNyQixNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNoQixHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUN0RCxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzdELE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNyQyxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNuQixHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7UUFDbEIsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFBO1FBQ25CLE1BQU0sSUFBSSxFQUFFLENBQUE7SUFDYixDQUFDLENBQUE7QUFDRixDQUFDO0FBRUQsNENBQTRDO0FBQzVDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLEtBQThCO0lBQ2pFLE1BQU0sR0FBRyxHQUFHLElBQUksT0FBTyxFQUE4QyxDQUFBO0lBQ3JFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUMvQixNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNuQixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUN6RCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQ2hFLE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNyQyxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNuQixNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7UUFDckIsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFBLENBQUMsMkVBQTJFO1FBQy9GLE1BQU0sSUFBSSxFQUFFLENBQUE7SUFDYixDQUFDLENBQUE7QUFDRixDQUFDIn0=
package/esm/helpers.js DELETED
@@ -1,3 +0,0 @@
1
- export { writeRes } from './dxHelpers.js';
2
- export { setBufferBodyDefaultOptions, bufferFromReq, jsonFromReq, rawFromReq, textFromReq, urlEncodedFromReq, queryFromReq, } from './bodyHelpers.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQTtBQUN2QyxPQUFPLEVBQ04sMkJBQTJCLEVBQzNCLGFBQWEsRUFDYixXQUFXLEVBQ1gsVUFBVSxFQUNWLFdBQVcsRUFDWCxpQkFBaUIsRUFDakIsWUFBWSxHQUNaLE1BQU0sa0JBQWtCLENBQUEifQ==
package/esm/index.js DELETED
@@ -1,9 +0,0 @@
1
- export { getReq, getRes, setHtml, setNodeStream, setWebStream, setJson, setBuffer, setRedirect, setText, setEmpty, setFile, makeDxContext, } from './dx.js';
2
- import { dxServer } from './dx.js';
3
- export { getBuffer, getJson, getRaw, getText, getUrlEncoded, getQuery, } from './body.js';
4
- export { router } from './router.js';
5
- export { connectMiddlewares } from './connect.js';
6
- export { chainStatic } from './static.js';
7
- export { logJson, default as logger } from './logger.js';
8
- export default dxServer;
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNOLE1BQU0sRUFDTixNQUFNLEVBQ04sT0FBTyxFQUNQLGFBQWEsRUFDYixZQUFZLEVBQ1osT0FBTyxFQUNQLFNBQVMsRUFDVCxXQUFXLEVBQ1gsT0FBTyxFQUNQLFFBQVEsRUFDUixPQUFPLEVBQ1AsYUFBYSxHQUNiLE1BQU0sU0FBUyxDQUFBO0FBQ2hCLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDaEMsT0FBTyxFQUNOLFNBQVMsRUFDVCxPQUFPLEVBQ1AsTUFBTSxFQUNOLE9BQU8sRUFDUCxhQUFhLEVBQ2IsUUFBUSxHQUNSLE1BQU0sV0FBVyxDQUFBO0FBQ2xCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDbEMsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQy9DLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDdkMsT0FBTyxFQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksTUFBTSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRXRELGVBQWUsUUFBUSxDQUFBIn0=
package/esm/logger.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare function logJson(json: any): void;
2
- declare const _default: (log?: typeof logJson) => (next: () => any) => any;
3
- export default _default;
package/esm/logger.js DELETED
@@ -1,57 +0,0 @@
1
- import { getReq, getRes } from './dx.js';
2
- import { hrtime } from 'node:process';
3
- export function logJson(json) {
4
- console.log(JSON.stringify(json));
5
- }
6
- let requestCount = 0;
7
- export default (log = logJson) => function logger(next) {
8
- const res = getRes();
9
- const req = getReq();
10
- const logId = requestCount++;
11
- const start = hrtime.bigint();
12
- const now = new Date(Date.now() + 9 * 60 * 60 * 1000); // jst
13
- log({
14
- level: 'info',
15
- id: logId,
16
- timestamp: [
17
- [
18
- now.getUTCFullYear(),
19
- String(now.getUTCMonth() + 1).padStart(2, '0'),
20
- String(now.getUTCDate()).padStart(2, '0'),
21
- ].join('-'),
22
- [
23
- String(now.getUTCHours()).padStart(2, '0'),
24
- String(now.getUTCMinutes()).padStart(2, '0'),
25
- [String(now.getUTCSeconds()).padStart(2, '0'), String(now.getUTCMilliseconds()).padStart(3, '0')].join('.'),
26
- ].join(':'),
27
- ].join('T'),
28
- remoteAddress: req.socket.remoteAddress,
29
- method: req.method,
30
- url: req.url,
31
- httpVersion: `HTTP/${req.httpVersion}`,
32
- headers: process.env.NODE_ENV === 'production'
33
- ? req.headers
34
- : Object.fromEntries(Object.entries(req.headers).filter(([k]) => [
35
- 'host',
36
- 'referer',
37
- 'referrer',
38
- 'user-agent',
39
- 'x-forwarded-proto',
40
- 'x-forwarded-host',
41
- 'x-forwarded-for',
42
- ].includes(k))),
43
- });
44
- res.once('finish', end).once('close', end).once('error', end);
45
- return next();
46
- function end() {
47
- res.off('finish', end).off('close', end).off('error', end);
48
- const durationNs = hrtime.bigint() - start;
49
- log({
50
- level: 'info',
51
- id: logId,
52
- duration: Number(durationNs) / 1e6, // ms
53
- headers: res.getHeaders(),
54
- });
55
- }
56
- };
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBQyxNQUFNLFNBQVMsQ0FBQTtBQUN0QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRW5DLE1BQU0sVUFBVSxPQUFPLENBQUMsSUFBUztJQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtBQUNsQyxDQUFDO0FBRUQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFBO0FBQ3BCLGVBQWUsQ0FBQyxHQUFHLEdBQUcsT0FBTyxFQUFFLEVBQUUsQ0FBQyxTQUFTLE1BQU0sQ0FBQyxJQUFlO0lBQ2hFLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFBO0lBQ3BCLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFBO0lBQ3BCLE1BQU0sS0FBSyxHQUFHLFlBQVksRUFBRSxDQUFBO0lBRTVCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUM3QixNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUEsQ0FBQyxNQUFNO0lBRTVELEdBQUcsQ0FBQztRQUNILEtBQUssRUFBRSxNQUFNO1FBQ2IsRUFBRSxFQUFFLEtBQUs7UUFDVCxTQUFTLEVBQUU7WUFDVjtnQkFDQyxHQUFHLENBQUMsY0FBYyxFQUFFO2dCQUNwQixNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO2dCQUM5QyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7YUFDekMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ1g7Z0JBQ0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO2dCQUMxQyxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7Z0JBQzVDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7YUFDM0csQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1NBQ1gsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ1gsYUFBYSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYTtRQUN2QyxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07UUFDbEIsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHO1FBQ1osV0FBVyxFQUFFLFFBQVEsR0FBRyxDQUFDLFdBQVcsRUFBRTtRQUN0QyxPQUFPLEVBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssWUFBWTtZQUNwQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU87WUFDYixDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FDbkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQzFDO2dCQUNDLE1BQU07Z0JBQ04sU0FBUztnQkFDVCxVQUFVO2dCQUNWLFlBQVk7Z0JBQ1osbUJBQW1CO2dCQUNuQixrQkFBa0I7Z0JBQ2xCLGlCQUFpQjthQUNqQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FDYixDQUNEO0tBQ0gsQ0FBQyxDQUFBO0lBRUYsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBRTdELE9BQU8sSUFBSSxFQUFFLENBQUE7SUFFYixTQUFTLEdBQUc7UUFDWCxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDMUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQTtRQUMxQyxHQUFHLENBQUM7WUFDSCxLQUFLLEVBQUUsTUFBTTtZQUNiLEVBQUUsRUFBRSxLQUFLO1lBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLEVBQUUsS0FBSztZQUN6QyxPQUFPLEVBQUUsR0FBRyxDQUFDLFVBQVUsRUFBRTtTQUN6QixDQUFDLENBQUE7SUFDSCxDQUFDO0FBQ0YsQ0FBQyxDQUFBIn0=
@@ -1 +0,0 @@
1
- export {};
@@ -1,16 +0,0 @@
1
- if (Promise.withResolvers === undefined)
2
- Promise.withResolvers = function withResolvers() {
3
- let resolve = undefined;
4
- let reject = undefined;
5
- const promise = new Promise((rs, rj) => {
6
- resolve = rs;
7
- reject = rj;
8
- });
9
- return {
10
- resolve,
11
- reject,
12
- promise
13
- };
14
- };
15
- export {};
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWZpbGxXaXRoUmVzb2x2ZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BvbHlmaWxsV2l0aFJlc29sdmVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxJQUFJLE9BQU8sQ0FBQyxhQUFhLEtBQUssU0FBUztJQUFFLE9BQU8sQ0FBQyxhQUFhLEdBQUcsU0FBUyxhQUFhO1FBQ3RGLElBQUksT0FBTyxHQUFHLFNBQVMsQ0FBQTtRQUN2QixJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUE7UUFDdEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDekMsT0FBTyxHQUFHLEVBQUUsQ0FBQTtZQUNaLE1BQU0sR0FBRyxFQUFFLENBQUE7UUFDWixDQUFDLENBQUMsQ0FBQTtRQUNGLE9BQU87WUFDTixPQUFPO1lBQ1AsTUFBTTtZQUNOLE9BQU87U0FDUCxDQUFBO0lBQ0YsQ0FBQyxDQUFBIn0=
package/esm/router.js DELETED
@@ -1,44 +0,0 @@
1
- import { getReq } from './dx.js';
2
- import { urlFromReq } from './bodyHelpers.js';
3
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
4
- const allMethods = [
5
- 'get', 'head', 'post', 'put', 'delete', 'connect', 'options', 'trace', 'patch'
6
- ];
7
- function makeRouter(method, // undefined means any method
8
- routes, { prefix = '', ...options } = {}) {
9
- const routeWithUrlPatterns = routes.map(([pattern, handler]) => [new URLPattern({ pathname: `${prefix}${pattern}` }), handler]);
10
- return next => {
11
- const req = getReq();
12
- if (method !== undefined && req.method !== method.toUpperCase())
13
- return next();
14
- for (const [urlPattern, handler] of routeWithUrlPatterns) {
15
- // '' matches nothing
16
- // '/' matches both https://example.com and https://example.com/
17
- // '/foo' matches https://example.com/foo but not https://example.com/foo/
18
- // '/foo/' matches https://example.com/foo/ but not https://example.com/foo
19
- // path can be '*' for OPTIONS request
20
- // to test: curl -X OPTIONS --request-target '*' http://localhost:3000 -D -
21
- // req.url === '*'
22
- // new URL('*', 'https://example.com').pathname === '/*'
23
- const matched = urlPattern.exec({ pathname: urlFromReq(req).pathname });
24
- if (matched)
25
- return handler({ matched, next });
26
- }
27
- return next();
28
- };
29
- }
30
- export const router = {
31
- method(method, ...params) {
32
- return typeof params[0] === 'string'
33
- ? makeRouter(method, [[params[0], params[1]]], params[2])
34
- : makeRouter(method, Object.entries(params[0]), params[1]);
35
- },
36
- all(...params) {
37
- return typeof params[0] === 'string'
38
- ? makeRouter(undefined, [[params[0], params[1]]], params[2])
39
- : makeRouter(undefined, Object.entries(params[0]), params[1]);
40
- }
41
- };
42
- for (const method of allMethods)
43
- router[method] = router.method.bind(router, method);
44
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLE1BQU0sRUFBQyxNQUFNLFNBQVMsQ0FBQTtBQUM5QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFrQjNDLDREQUE0RDtBQUM1RCxNQUFNLFVBQVUsR0FBRztJQUNsQixLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU87Q0FDckUsQ0FBQTtBQStCVixTQUFTLFVBQVUsQ0FDbEIsTUFBMEIsRUFBRSw2QkFBNkI7QUFDekQsTUFBeUMsRUFDekMsRUFBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLEdBQUcsT0FBTyxLQUFtQixFQUFFO0lBRTdDLE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLEVBQUMsUUFBUSxFQUFFLEdBQUcsTUFBTSxHQUFHLE9BQU8sRUFBRSxFQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO0lBQzdILE9BQU8sSUFBSSxDQUFDLEVBQUU7UUFDYixNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixJQUFJLE1BQU0sS0FBSyxTQUFTLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsV0FBVyxFQUFFO1lBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQTtRQUM5RSxLQUFLLE1BQU0sQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUM3RCxxQkFBcUI7WUFDckIsZ0VBQWdFO1lBQ2hFLDBFQUEwRTtZQUMxRSwyRUFBMkU7WUFFeEUsc0NBQXNDO1lBQ3RDLDJFQUEyRTtZQUMzRSxrQkFBa0I7WUFDbEIsd0RBQXdEO1lBQ3hELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBQyxDQUFDLENBQUE7WUFDckUsSUFBSSxPQUFPO2dCQUFFLE9BQU8sT0FBTyxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUE7UUFDN0MsQ0FBQztRQUNELE9BQU8sSUFBSSxFQUFFLENBQUE7SUFDZCxDQUFDLENBQUE7QUFDRixDQUFDO0FBQ0QsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFXO0lBQzdCLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBRyxNQUFNO1FBQ3ZCLE9BQU8sT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUTtZQUNuQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pELENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDNUQsQ0FBQztJQUNELEdBQUcsQ0FBQyxHQUFHLE1BQU07UUFDWixPQUFPLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVE7WUFDbkMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQy9ELENBQUM7Q0FDRCxDQUFBO0FBRUQsS0FBSyxNQUFNLE1BQU0sSUFBSSxVQUFVO0lBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQSJ9
package/esm/static.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { type Chainable } from './dx.js';
2
- import { type SendFileOptions } from './staticHelpers.js';
3
- export declare function chainStatic(pattern: string, { getPathname, ...options }: SendFileOptions & {
4
- getPathname?(matched: any): string;
5
- }): Chainable;
package/esm/static.js DELETED
@@ -1,23 +0,0 @@
1
- import { getReq, getRes } from './dx.js';
2
- import { sendFileTrusted } from './staticHelpers.js';
3
- import { urlFromReq } from './bodyHelpers.js';
4
- export function chainStatic(pattern, { getPathname, ...options }) {
5
- const urlPattern = new URLPattern({ pathname: pattern });
6
- return async (next) => {
7
- const req = getReq();
8
- if (req.method !== 'GET' && req.method !== 'HEAD')
9
- return next();
10
- const { pathname } = urlFromReq(req);
11
- const matched = urlPattern.exec({ pathname });
12
- if (!matched)
13
- return next();
14
- try {
15
- await sendFileTrusted(req, getRes(), getPathname?.(matched)
16
- ?? decodeURIComponent(pathname), options);
17
- }
18
- catch (e) {
19
- return next(e); // if request's pathname matches pattern, but file is not found, next() will be called with error
20
- }
21
- };
22
- }
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLE1BQU0sRUFBRSxNQUFNLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDdEQsT0FBTyxFQUF1QixlQUFlLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUN4RSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFFM0MsTUFBTSxVQUFVLFdBQVcsQ0FDMUIsT0FBZSxFQUNmLEVBQUMsV0FBVyxFQUFFLEdBQUcsT0FBTyxFQUl2QjtJQUVELE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUE7SUFDdEQsT0FBTyxLQUFLLEVBQUMsSUFBSSxFQUFDLEVBQUU7UUFDbkIsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUE7UUFDcEIsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU07WUFBRSxPQUFPLElBQUksRUFBRSxDQUFBO1FBRWhFLE1BQU0sRUFBQyxRQUFRLEVBQUMsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbEMsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFDLFFBQVEsRUFBQyxDQUFDLENBQUE7UUFDM0MsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLElBQUksRUFBRSxDQUFBO1FBRTNCLElBQUksQ0FBQztZQUNKLE1BQU0sZUFBZSxDQUNwQixHQUFHLEVBQ0gsTUFBTSxFQUFFLEVBQ1AsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDO21CQUNwQixrQkFBa0IsQ0FBQyxRQUFRLENBQUMsRUFDL0IsT0FBTyxDQUNQLENBQUE7UUFDRixDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNaLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUMsaUdBQWlHO1FBQ2pILENBQUM7SUFDRixDQUFDLENBQUE7QUFDRixDQUFDIn0=
@@ -1,18 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- import { IncomingMessage, ServerResponse } from 'node:http';
3
- import './polyfillWithResolvers.js';
4
- export interface SendFileOptions {
5
- allowDotfiles?: boolean;
6
- root?: string;
7
- disableAcceptRanges?: boolean;
8
- disableLastModified?: boolean;
9
- etag?: 'disabled' | 'strong' | 'weak';
10
- disableCacheControl?: boolean;
11
- maxAge?: number;
12
- immutable?: boolean;
13
- end?: number;
14
- start?: number;
15
- }
16
- export declare function sendFileTrusted(req: IncomingMessage, res: ServerResponse, pathname: string, // plain path, not URI-encoded
17
- { root, allowDotfiles, start, end, disableAcceptRanges, disableLastModified, etag, disableCacheControl, maxAge, // 1 year
18
- immutable, }?: SendFileOptions): Promise<void>;
@@ -1,188 +0,0 @@
1
- import './polyfillWithResolvers.js';
2
- import path from 'node:path';
3
- import { stat } from 'node:fs/promises';
4
- import { entityTagPath, statTag } from './vendors/etag.js';
5
- import { contentTypeForExtension } from './vendors/mime.js';
6
- import { fresh, parseHttpDate, parseTokenList } from './vendors/fresh.js';
7
- import { parseRange } from './vendors/rangeParser.js';
8
- import { createReadStream } from 'node:fs';
9
- import { onFinished } from './vendors/onFinished.js';
10
- import { promisify } from 'node:util';
11
- const BYTES_RANGE_REGEXP = /^ *bytes=/;
12
- const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
13
- export async function sendFileTrusted(req, res, pathname, // plain path, not URI-encoded
14
- { root, allowDotfiles, start = 0, end, disableAcceptRanges, disableLastModified, etag = 'strong', disableCacheControl, maxAge = 60 * 60 * 24 * 365 * 1000, // 1 year
15
- immutable, } = {}) {
16
- // null byte(s)
17
- if (pathname.includes('\0'))
18
- throw new Error('Forbidden');
19
- let parts;
20
- if (root) {
21
- // normalize
22
- pathname = path.normalize(`.${path.sep}${pathname}`);
23
- // malicious path
24
- if (UP_PATH_REGEXP.test(pathname))
25
- throw new Error('Forbidden');
26
- // explode path parts
27
- parts = pathname.split(path.sep);
28
- // join / normalize from optional root dir
29
- pathname = path.normalize(path.join(root, pathname));
30
- }
31
- else {
32
- // malicious path
33
- if (UP_PATH_REGEXP.test(pathname))
34
- throw new Error('Forbidden');
35
- // explode path parts
36
- parts = path.normalize(pathname).split(path.sep);
37
- // join / normalize from optional root dir
38
- pathname = path.resolve(pathname);
39
- }
40
- // dotfile handling
41
- if (parts.some(part => part.length > 1 && part[0] === '.') && !allowDotfiles)
42
- throw new Error('Forbidden: dotfiles are not allowed');
43
- // pathEndsWithSep
44
- if (pathname[pathname.length - 1] === path.sep)
45
- throw new Error('Forbidden: directory access is not allowed');
46
- const fileStat = await stat(pathname);
47
- // not found, check extensions
48
- // if (err.code === 'ENOENT' && !path.extname(pathname) && !pathEndsWithSep) throw err
49
- // switch (err.code) {
50
- // case 'ENAMETOOLONG':
51
- // case 'ENOENT':
52
- // case 'ENOTDIR':
53
- // default:
54
- // }
55
- if (fileStat.isDirectory())
56
- throw new Error('Forbidden: directory access is not allowed');
57
- if (res.headersSent)
58
- return;
59
- //region set header fields
60
- if (!disableAcceptRanges && !res.getHeader('Accept-Ranges'))
61
- res.setHeader('Accept-Ranges', 'bytes');
62
- if (!disableCacheControl && !res.getHeader('Cache-Control'))
63
- res.setHeader('Cache-Control', [
64
- `public, max-age=${Math.floor(maxAge / 1000)}`,
65
- immutable && 'immutable',
66
- ].filter(Boolean).join(', '));
67
- if (!disableLastModified && !res.getHeader('Last-Modified'))
68
- res.setHeader('Last-Modified', fileStat.mtime.toUTCString());
69
- if (etag !== 'disabled' && !res.getHeader('ETag'))
70
- res.setHeader('ETag', etag === 'weak' ? statTag(fileStat) : await entityTagPath(fileStat, pathname, false));
71
- //endregion set header fields
72
- // content-type
73
- if (!res.getHeader('Content-Type'))
74
- res.setHeader('Content-Type', contentTypeForExtension(path.extname(pathname).slice(1)) || 'application/octet-stream');
75
- // conditional GET support
76
- // isConditionalGET
77
- if (req.headers['if-match'] || req.headers['if-unmodified-since'] || req.headers['if-none-match'] || req.headers['if-modified-since']) {
78
- //region isPreconditionFailure
79
- // if-match
80
- const match = req.headers['if-match'];
81
- if (match) {
82
- const etag = res.getHeader('ETag');
83
- if (!etag
84
- || (match !== '*' && parseTokenList(match).every(match => match !== etag && match !== 'W/' + etag && 'W/' + match !== etag)))
85
- throw new Error('Precondition Failed: request headers do not match the response');
86
- }
87
- // if-unmodified-since (ignore when using strong etag since mtime may be unreliable)
88
- if (etag === 'weak') {
89
- const unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']);
90
- if (!isNaN(unmodifiedSince)) {
91
- const lastModified = parseHttpDate(res.getHeader('Last-Modified'));
92
- if (isNaN(lastModified) || lastModified > unmodifiedSince)
93
- throw new Error('Precondition Failed: resource has been modified since the specified date');
94
- }
95
- }
96
- //endregion isPreconditionFailure
97
- // isCachable
98
- if ((res.statusCode >= 200 && res.statusCode < 300 || res.statusCode === 304)
99
- && fresh(req.headers, {
100
- etag: res.getHeader('ETag'),
101
- // Only use last-modified for freshness check when using weak Etag
102
- 'last-modified': etag === 'weak' ? res.getHeader('Last-Modified') : undefined
103
- })) {
104
- // removeContentHeaderFields
105
- res.removeHeader('Content-Encoding');
106
- res.removeHeader('Content-Language');
107
- res.removeHeader('Content-Length');
108
- res.removeHeader('Content-Range');
109
- res.removeHeader('Content-Type');
110
- res.statusCode = 304;
111
- return void await promisify(res.end.bind(res))();
112
- }
113
- }
114
- // adjust len to start/end options
115
- let len = fileStat.size;
116
- len = Math.max(0, len - start);
117
- if (end !== undefined) {
118
- const bytes = end - start + 1;
119
- if (len > bytes)
120
- len = bytes;
121
- }
122
- // Range support
123
- let ranges = req.headers.range;
124
- if (!disableAcceptRanges && BYTES_RANGE_REGEXP.test(ranges ?? '')) {
125
- // parse
126
- let rangesNum = parseRange(len, ranges, { combine: true });
127
- // If-Range support
128
- if (!isRangeFresh(req, res))
129
- rangesNum = -2;
130
- // unsatisfiable
131
- if (rangesNum === -1) {
132
- // Content-Range
133
- res.setHeader('Content-Range', contentRange('bytes', len));
134
- // 416 Requested Range Not Satisfiable
135
- throw new Error('Requested Range Not Satisfiable: requested range is not satisfiable');
136
- // return this.error(416, {
137
- // headers: {'Content-Range': res.getHeader('Content-Range')}
138
- // })
139
- }
140
- // valid (syntactically invalid/multiple ranges are treated as a regular response)
141
- if (rangesNum !== -2 && rangesNum.length === 1) {
142
- // Content-Range
143
- res.statusCode = 206;
144
- res.setHeader('Content-Range', contentRange('bytes', len, rangesNum[0]));
145
- // adjust for requested range
146
- start += rangesNum[0].start;
147
- len = rangesNum[0].end - rangesNum[0].start + 1;
148
- }
149
- }
150
- // set read options
151
- end = Math.max(start, start + len - 1);
152
- // content-length
153
- res.setHeader('Content-Length', len);
154
- // HEAD support
155
- if (req.method === 'HEAD')
156
- return void await promisify(res.end.bind(res))();
157
- // Weak ETag path: stream file
158
- const stream = createReadStream(pathname, { start, end });
159
- stream.pipe(res);
160
- const defer = Promise.withResolvers();
161
- onFinished(res, cleanup);
162
- stream.on('error', err => {
163
- cleanup();
164
- defer.reject(err);
165
- });
166
- stream.on('end', defer.resolve);
167
- function cleanup() {
168
- stream.destroy();
169
- }
170
- return defer.promise;
171
- }
172
- function isRangeFresh(req, res) {
173
- const ifRange = req.headers['if-range'];
174
- if (!ifRange)
175
- return true;
176
- // if-range as etag
177
- if (ifRange.indexOf('"') !== -1) {
178
- const etag = res.getHeader('ETag');
179
- return etag && ifRange.includes(etag);
180
- }
181
- // if-range as modified date
182
- const lastModified = res.getHeader('Last-Modified');
183
- return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
184
- }
185
- function contentRange(type, size, range) {
186
- return `${type} ${range ? range.start + '-' + range.end : '*'}/${size}`;
187
- }
188
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljSGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zdGF0aWNIZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sNEJBQTRCLENBQUE7QUFDbkMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQzVCLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUNyQyxPQUFPLEVBQUMsYUFBYSxFQUFFLE9BQU8sRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3hELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3pELE9BQU8sRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBQ3ZFLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUNuRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDeEMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ2xELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFFbkMsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUE7QUFDdEMsTUFBTSxjQUFjLEdBQUcsNEJBQTRCLENBQUE7QUFxQm5ELE1BQU0sQ0FBQyxLQUFLLFVBQVUsZUFBZSxDQUNwQyxHQUFvQixFQUNwQixHQUFtQixFQUNuQixRQUFnQixFQUFFLDhCQUE4QjtBQUNoRCxFQUNDLElBQUksRUFBRSxhQUFhLEVBQ25CLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUNkLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIsSUFBSSxHQUFHLFFBQVEsRUFDZixtQkFBbUIsRUFDbkIsTUFBTSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsU0FBUztBQUM3QyxTQUFTLE1BQ1csRUFBRTtJQUV2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