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.
- package/README.md +47 -55
- package/{cjs → lib}/body.d.ts +2 -3
- package/lib/body.js +10 -0
- package/{esm → lib}/bodyHelpers.d.ts +2 -4
- package/lib/bodyHelpers.js +89 -0
- package/{esm → lib}/dx.d.ts +5 -8
- package/lib/dx.js +127 -0
- package/{cjs → lib}/dxHelpers.d.ts +0 -4
- package/{esm → lib}/dxHelpers.js +0 -2
- package/{cjs → lib}/index.d.ts +0 -1
- package/{esm/index.d.ts → lib/index.js} +0 -1
- package/lib/logger.js +56 -0
- package/lib/router.d.ts +42 -0
- package/lib/router.js +43 -0
- package/lib/static.js +22 -0
- package/{cjs → lib}/staticHelpers.d.ts +0 -2
- package/lib/staticHelpers.js +186 -0
- package/{cjs → lib}/stream.d.ts +2 -7
- package/lib/stream.js +90 -0
- package/{esm → lib}/vendors/contentType.js +0 -1
- package/{cjs → lib}/vendors/etag.d.ts +0 -3
- package/lib/vendors/etag.js +104 -0
- package/{cjs → lib}/vendors/fresh.d.ts +2 -2
- package/lib/vendors/fresh.js +95 -0
- package/lib/vendors/mime.d.ts +1 -0
- package/lib/vendors/mime.js +35 -0
- package/{esm → lib}/vendors/mimeDb.js +0 -1
- package/{cjs → lib}/vendors/mimeScore.d.ts +1 -1
- package/lib/vendors/mimeScore.js +45 -0
- package/{cjs → lib}/vendors/onFinished.d.ts +1 -1
- package/lib/vendors/onFinished.js +231 -0
- package/lib/vendors/rangeParser.d.ts +20 -0
- package/lib/vendors/rangeParser.js +121 -0
- package/package.json +10 -19
- package/cjs/body.js +0 -14
- package/cjs/bodyHelpers.d.ts +0 -16
- package/cjs/bodyHelpers.js +0 -101
- package/cjs/connect.d.ts +0 -5
- package/cjs/connect.js +0 -44
- package/cjs/dx.d.ts +0 -46
- package/cjs/dx.js +0 -144
- package/cjs/dxHelpers.js +0 -123
- package/cjs/express.d.ts +0 -4
- package/cjs/express.js +0 -43
- package/cjs/helpers.js +0 -14
- package/cjs/index.js +0 -38
- package/cjs/logger.js +0 -61
- package/cjs/package.json +0 -3
- package/cjs/polyfillWithResolvers.d.ts +0 -1
- package/cjs/polyfillWithResolvers.js +0 -17
- package/cjs/router.js +0 -47
- package/cjs/static.js +0 -27
- package/cjs/staticHelpers.js +0 -195
- package/cjs/stream.js +0 -97
- package/cjs/vendors/contentType.js +0 -92
- package/cjs/vendors/etag.js +0 -136
- package/cjs/vendors/fresh.js +0 -102
- package/cjs/vendors/mime.d.ts +0 -1
- package/cjs/vendors/mime.js +0 -42
- package/cjs/vendors/mimeDb.js +0 -9417
- package/cjs/vendors/mimeScore.js +0 -50
- package/cjs/vendors/onFinished.js +0 -245
- package/cjs/vendors/rangeParser.d.ts +0 -10
- package/cjs/vendors/rangeParser.js +0 -126
- package/esm/body.d.ts +0 -8
- package/esm/body.js +0 -11
- package/esm/bodyHelpers.js +0 -90
- package/esm/connect.d.ts +0 -5
- package/esm/connect.js +0 -40
- package/esm/dx.js +0 -128
- package/esm/dxHelpers.d.ts +0 -49
- package/esm/express.d.ts +0 -4
- package/esm/express.js +0 -35
- package/esm/helpers.js +0 -3
- package/esm/index.js +0 -9
- package/esm/logger.d.ts +0 -3
- package/esm/logger.js +0 -57
- package/esm/polyfillWithResolvers.d.ts +0 -1
- package/esm/polyfillWithResolvers.js +0 -16
- package/esm/router.js +0 -44
- package/esm/static.d.ts +0 -5
- package/esm/static.js +0 -23
- package/esm/staticHelpers.d.ts +0 -18
- package/esm/staticHelpers.js +0 -188
- package/esm/stream.d.ts +0 -12
- package/esm/stream.js +0 -92
- package/esm/vendors/contentType.d.ts +0 -4
- package/esm/vendors/etag.d.ts +0 -10
- package/esm/vendors/etag.js +0 -105
- package/esm/vendors/fresh.d.ts +0 -23
- package/esm/vendors/fresh.js +0 -96
- package/esm/vendors/mime.d.ts +0 -1
- package/esm/vendors/mime.js +0 -35
- package/esm/vendors/mimeDb.d.ts +0 -9413
- package/esm/vendors/mimeScore.d.ts +0 -5
- package/esm/vendors/mimeScore.js +0 -46
- package/esm/vendors/onFinished.d.ts +0 -14
- package/esm/vendors/onFinished.js +0 -241
- package/esm/vendors/rangeParser.d.ts +0 -10
- package/esm/vendors/rangeParser.js +0 -122
- /package/{cjs → lib}/helpers.d.ts +0 -0
- /package/{esm/helpers.d.ts → lib/helpers.js} +0 -0
- /package/{cjs → lib}/logger.d.ts +0 -0
- /package/{cjs → lib}/static.d.ts +0 -0
- /package/{cjs → lib}/vendors/contentType.d.ts +0 -0
- /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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
|
package/esm/dxHelpers.d.ts
DELETED
|
@@ -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
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
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=
|
package/esm/staticHelpers.d.ts
DELETED
|
@@ -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>;
|
package/esm/staticHelpers.js
DELETED
|
@@ -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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
|