dx-server 0.0.1 → 0.0.3
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 +183 -0
- package/cjs/body.d.ts +30 -0
- package/cjs/body.js +91 -0
- package/cjs/contentType.d.ts +4 -0
- package/cjs/contentType.js +92 -0
- package/cjs/context.d.ts +15 -0
- package/cjs/context.js +27 -0
- package/cjs/error.js +42 -0
- package/cjs/etag.d.ts +7 -0
- package/cjs/etag.js +100 -0
- package/cjs/express.d.ts +49 -0
- package/cjs/express.js +168 -0
- package/cjs/expressApp.d.ts +4 -0
- package/cjs/expressApp.js +44 -0
- package/cjs/file.d.ts +3 -0
- package/cjs/file.js +12 -0
- package/cjs/index.d.ts +6 -0
- package/cjs/index.js +33 -0
- package/cjs/package.json +3 -0
- package/cjs/route.d.ts +38 -0
- package/cjs/route.js +86 -0
- package/cjs/static.d.ts +4 -0
- package/cjs/static.js +60 -0
- package/cjs/stream.d.ts +11 -0
- package/cjs/stream.js +100 -0
- package/esm/body.d.ts +30 -0
- package/esm/body.js +88 -0
- package/esm/contentType.d.ts +4 -0
- package/esm/contentType.js +88 -0
- package/esm/context.d.ts +15 -0
- package/esm/context.js +23 -0
- package/esm/error.js +37 -0
- package/esm/etag.d.ts +7 -0
- package/esm/etag.js +90 -0
- package/esm/express.d.ts +49 -0
- package/esm/express.js +156 -0
- package/esm/expressApp.d.ts +4 -0
- package/esm/expressApp.js +35 -0
- package/esm/file.d.ts +3 -0
- package/esm/file.js +8 -0
- package/esm/index.d.ts +6 -0
- package/esm/index.js +7 -0
- package/esm/route.d.ts +38 -0
- package/esm/route.js +82 -0
- package/esm/static.d.ts +4 -0
- package/esm/static.js +56 -0
- package/esm/stream.d.ts +11 -0
- package/esm/stream.js +92 -0
- package/package.json +32 -5
- package/index.js +0 -1
package/esm/file.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { requestContext, responseContext } from './context.js';
|
|
2
|
+
export const serveFile = ({ prefix = '' }) => next => {
|
|
3
|
+
const req = requestContext.value;
|
|
4
|
+
const res = responseContext.value;
|
|
5
|
+
if (req.method !== 'GET' && req.method !== 'HEAD')
|
|
6
|
+
return next();
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxjQUFjLEVBQUUsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRzVELE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxDQUN4QixFQUFDLE1BQU0sR0FBRyxFQUFFLEVBRVgsRUFDWSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFDdkIsTUFBTSxHQUFHLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQTtJQUNoQyxNQUFNLEdBQUcsR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFBO0lBQ2pDLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNO1FBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQTtBQUNqRSxDQUFDLENBQUEifQ==
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { makeContext, requestContext, responseContext } from './context.js';
|
|
2
|
+
export { expressContext, setHtml, setJson, setBuffer, setRedirect, setText } from './express.js';
|
|
3
|
+
export { bufferBodyContext, jsonBodyContext, queryContext, rawBodyContext, textBodyContext, urlencodedBodyContext } from './body.js';
|
|
4
|
+
export { router } from './route.js';
|
|
5
|
+
export { catchApiError, catchError, notFound, notFoundApi } from './error.js';
|
|
6
|
+
export { expressApp, expressRouter, chainExpressMiddlewares } from './expressApp.js';
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { makeContext, requestContext, responseContext } from './context.js';
|
|
2
|
+
export { expressContext, setHtml, setJson, setBuffer, setRedirect, setText } from './express.js';
|
|
3
|
+
export { bufferBodyContext, jsonBodyContext, queryContext, rawBodyContext, textBodyContext, urlencodedBodyContext } from './body.js';
|
|
4
|
+
export { router } from './route.js';
|
|
5
|
+
export { catchApiError, catchError, notFound, notFoundApi } from './error.js';
|
|
6
|
+
export { expressApp, expressRouter, chainExpressMiddlewares } from './expressApp.js';
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ3pFLE9BQU8sRUFDTixjQUFjLEVBQ2QsT0FBTyxFQUNQLE9BQU8sRUFDUCxTQUFTLEVBQ1QsV0FBVyxFQUNYLE9BQU8sRUFDUCxNQUFNLGNBQWMsQ0FBQTtBQUNyQixPQUFPLEVBQ04saUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixZQUFZLEVBQ1osY0FBYyxFQUNkLGVBQWUsRUFDZixxQkFBcUIsRUFDckIsTUFBTSxXQUFXLENBQUE7QUFDbEIsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFlBQVksQ0FBQTtBQUNqQyxPQUFPLEVBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFDLE1BQU0sWUFBWSxDQUFBO0FBQzNFLE9BQU8sRUFBQyxVQUFVLEVBQUUsYUFBYSxFQUFFLHVCQUF1QixFQUFDLE1BQU0saUJBQWlCLENBQUEifQ==
|
package/esm/route.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Key } from 'path-to-regexp';
|
|
2
|
+
interface RegexpToPathOptions {
|
|
3
|
+
end?: boolean;
|
|
4
|
+
strict?: boolean;
|
|
5
|
+
sensitive?: boolean;
|
|
6
|
+
start?: boolean;
|
|
7
|
+
delimiter?: string;
|
|
8
|
+
endsWith?: string;
|
|
9
|
+
encode?(value: string): string;
|
|
10
|
+
prefixes?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function matchPattern<Params extends Record<Key['name'], string>>(pathname: string, pattern: string, options?: RegexpToPathOptions): {
|
|
13
|
+
matched: any;
|
|
14
|
+
params: any;
|
|
15
|
+
} | undefined;
|
|
16
|
+
interface Chainable<P extends any[] = any[], R = any, Next = (...np: any[]) => any> {
|
|
17
|
+
(next: Next, ...p: P): R;
|
|
18
|
+
}
|
|
19
|
+
interface RouteContext {
|
|
20
|
+
matched: string;
|
|
21
|
+
next(): any;
|
|
22
|
+
params: Record<Key['name'], string>;
|
|
23
|
+
}
|
|
24
|
+
interface RouteDefinition {
|
|
25
|
+
[k: string]: (p: RouteContext) => any;
|
|
26
|
+
}
|
|
27
|
+
interface RouterOptions extends RegexpToPathOptions {
|
|
28
|
+
prefix?: string;
|
|
29
|
+
}
|
|
30
|
+
declare const allMethods: readonly ["get", "head", "post", "put", "delete", "connect", "options", "trace", "patch"];
|
|
31
|
+
type IRouter = {
|
|
32
|
+
[K in typeof allMethods[number]]: (definition: RouteDefinition, options?: RouterOptions) => Chainable;
|
|
33
|
+
} & {
|
|
34
|
+
all(definition: RouteDefinition, options?: RouterOptions): Chainable;
|
|
35
|
+
method(method: string, definition: RouteDefinition, options?: RouterOptions): Chainable;
|
|
36
|
+
};
|
|
37
|
+
export declare const router: IRouter;
|
|
38
|
+
export {};
|
package/esm/route.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { pathToRegexp } from 'path-to-regexp';
|
|
2
|
+
import { requestContext } from './context.js';
|
|
3
|
+
const cache = {};
|
|
4
|
+
const cacheLimit = 10000;
|
|
5
|
+
let cacheCount = 0;
|
|
6
|
+
function compilePath(path, options) {
|
|
7
|
+
const cacheKey = JSON.stringify(options);
|
|
8
|
+
const pathCache = cache[cacheKey] || (cache[cacheKey] = {});
|
|
9
|
+
if (pathCache[path])
|
|
10
|
+
return pathCache[path];
|
|
11
|
+
const keys = [];
|
|
12
|
+
const regexp = pathToRegexp(path, keys, options);
|
|
13
|
+
const result = {
|
|
14
|
+
regexp,
|
|
15
|
+
keys
|
|
16
|
+
};
|
|
17
|
+
if (cacheCount < cacheLimit) {
|
|
18
|
+
pathCache[path] = result;
|
|
19
|
+
cacheCount++;
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
export function matchPattern(pathname, pattern, options) {
|
|
24
|
+
options = { ...options };
|
|
25
|
+
options.end ??= true;
|
|
26
|
+
options.strict ??= false;
|
|
27
|
+
options.sensitive ??= false;
|
|
28
|
+
options.start ??= true;
|
|
29
|
+
if (!pattern && pattern !== '')
|
|
30
|
+
return;
|
|
31
|
+
const { regexp, keys } = compilePath(pattern, options);
|
|
32
|
+
const match = regexp.exec(pathname);
|
|
33
|
+
if (!match)
|
|
34
|
+
return;
|
|
35
|
+
const [matched, ...values] = match;
|
|
36
|
+
return {
|
|
37
|
+
matched,
|
|
38
|
+
params: keys.reduce((acc, key, index) => {
|
|
39
|
+
acc[key.name] = values[index];
|
|
40
|
+
return acc;
|
|
41
|
+
}, {})
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
|
|
45
|
+
const allMethods = [
|
|
46
|
+
'get', 'head', 'post', 'put', 'delete', 'connect', 'options', 'trace', 'patch'
|
|
47
|
+
];
|
|
48
|
+
export const router = {
|
|
49
|
+
method(method, router, { prefix = '', ...options } = {}) {
|
|
50
|
+
return next => {
|
|
51
|
+
const req = requestContext.value;
|
|
52
|
+
if (req.method !== method.toUpperCase())
|
|
53
|
+
return next();
|
|
54
|
+
for (const [pattern, handler] of Object.entries(router)) {
|
|
55
|
+
const match = matchPattern(req.url ?? '', `${prefix}${pattern}`, options);
|
|
56
|
+
if (match)
|
|
57
|
+
return handler({
|
|
58
|
+
...match,
|
|
59
|
+
next,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return next();
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
all(router, { prefix = '', ...options } = {}) {
|
|
66
|
+
return next => {
|
|
67
|
+
const req = requestContext.value;
|
|
68
|
+
for (const [pattern, handler] of Object.entries(router)) {
|
|
69
|
+
const match = matchPattern(req.url ?? '', `${prefix}${pattern}`, options);
|
|
70
|
+
if (match)
|
|
71
|
+
return handler({
|
|
72
|
+
...match,
|
|
73
|
+
next,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return next();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
for (const method of allMethods)
|
|
81
|
+
router[method] = router.method.bind(router, method);
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGdCQUFnQixDQUFBO0FBQzNDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFFM0MsTUFBTSxLQUFLLEdBQXdCLEVBQUUsQ0FBQTtBQUNyQyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUE7QUFDeEIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFBO0FBY2xCLFNBQVMsV0FBVyxDQUFDLElBQVksRUFBRSxPQUE0QjtJQUM5RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3hDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQTtJQUMzRCxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUUzQyxNQUFNLElBQUksR0FBVSxFQUFFLENBQUE7SUFDdEIsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDaEQsTUFBTSxNQUFNLEdBQUc7UUFDZCxNQUFNO1FBQ04sSUFBSTtLQUNKLENBQUE7SUFFRCxJQUFJLFVBQVUsR0FBRyxVQUFVLEVBQUU7UUFDNUIsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQTtRQUN4QixVQUFVLEVBQUUsQ0FBQTtLQUNaO0lBQ0QsT0FBTyxNQUFNLENBQUE7QUFDZCxDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVksQ0FDM0IsUUFBZ0IsRUFDaEIsT0FBZSxFQUNmLE9BQTZCO0lBRTdCLE9BQU8sR0FBRyxFQUFDLEdBQUcsT0FBTyxFQUFDLENBQUE7SUFD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
|
package/esm/static.d.ts
ADDED
package/esm/static.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { requestContext } from './context.js';
|
|
3
|
+
export function staticMiddleware({ root }) {
|
|
4
|
+
return async (next) => {
|
|
5
|
+
const req = requestContext.value;
|
|
6
|
+
if (req.method !== 'GET' && req.method !== 'HEAD')
|
|
7
|
+
return next();
|
|
8
|
+
var forwardError = !fallthrough;
|
|
9
|
+
var originalUrl = parseUrl.original(req);
|
|
10
|
+
var path = parseUrl(req).pathname;
|
|
11
|
+
// make sure redirect occurs at mount
|
|
12
|
+
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
|
|
13
|
+
path = '';
|
|
14
|
+
}
|
|
15
|
+
// create send stream
|
|
16
|
+
var stream = send(req, path, opts);
|
|
17
|
+
// add directory handler
|
|
18
|
+
stream.on('directory', onDirectory);
|
|
19
|
+
// add headers listener
|
|
20
|
+
if (setHeaders) {
|
|
21
|
+
stream.on('headers', setHeaders);
|
|
22
|
+
}
|
|
23
|
+
// add file listener for fallthrough
|
|
24
|
+
if (fallthrough) {
|
|
25
|
+
stream.on('file', function onFile() {
|
|
26
|
+
// once file is determined, always forward error
|
|
27
|
+
forwardError = true;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
// forward errors
|
|
31
|
+
stream.on('error', function error(err) {
|
|
32
|
+
if (forwardError || !(err.statusCode < 500)) {
|
|
33
|
+
next(err);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
next();
|
|
37
|
+
});
|
|
38
|
+
// pipe
|
|
39
|
+
stream.pipe(res);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Collapse all leading slashes into a single slash
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
function collapseLeadingSlashes(str) {
|
|
47
|
+
for (let i = 0; i < str.length; i++) {
|
|
48
|
+
if (str.charCodeAt(i) !== 0x2f /* / */) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return i > 1
|
|
53
|
+
? '/' + str.slice(i)
|
|
54
|
+
: str;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjO0FBQ2QsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUUzQyxNQUFNLFVBQVUsZ0JBQWdCLENBQy9CLEVBQUMsSUFBSSxFQUdKO0lBRUQsT0FBTyxLQUFLLEVBQUUsSUFBZSxFQUFFLEVBQUU7UUFDaEMsTUFBTSxHQUFHLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQTtRQUNoQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTTtZQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFaEUsSUFBSSxZQUFZLEdBQUcsQ0FBQyxXQUFXLENBQUE7UUFDL0IsSUFBSSxXQUFXLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUN4QyxJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFBO1FBRWpDLHFDQUFxQztRQUNyQyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7WUFDNUQsSUFBSSxHQUFHLEVBQUUsQ0FBQTtTQUNUO1FBRUQscUJBQXFCO1FBQ3JCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBRWxDLHdCQUF3QjtRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQTtRQUVuQyx1QkFBdUI7UUFDdkIsSUFBSSxVQUFVLEVBQUU7WUFDZixNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQTtTQUNoQztRQUVELG9DQUFvQztRQUNwQyxJQUFJLFdBQVcsRUFBRTtZQUNoQixNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLE1BQU07Z0JBQ2hDLGdEQUFnRDtnQkFDaEQsWUFBWSxHQUFHLElBQUksQ0FBQTtZQUNwQixDQUFDLENBQUMsQ0FBQTtTQUNGO1FBRUQsaUJBQWlCO1FBQ2pCLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLFNBQVMsS0FBSyxDQUFDLEdBQUc7WUFDcEMsSUFBSSxZQUFZLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLEVBQUU7Z0JBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDVCxPQUFNO2FBQ047WUFFRCxJQUFJLEVBQUUsQ0FBQTtRQUNQLENBQUMsQ0FBQyxDQUFBO1FBRUYsT0FBTztRQUNQLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDakIsQ0FBQyxDQUFBO0FBQ0YsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsc0JBQXNCLENBQUUsR0FBVztJQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNwQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUN2QyxNQUFLO1NBQ0w7S0FDRDtJQUVELE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDWCxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxHQUFHLENBQUE7QUFDUCxDQUFDIn0=
|
package/esm/stream.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
4
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
5
|
+
import type { IncomingMessage } from 'node:http';
|
|
6
|
+
import type { Readable } from 'node:stream';
|
|
7
|
+
export declare function getContentStream(req: IncomingMessage, encoding: string, disableInflate?: boolean): IncomingMessage | import("zlib").Gunzip;
|
|
8
|
+
export declare function readStream(stream: Readable, { length, limit }: {
|
|
9
|
+
length?: number;
|
|
10
|
+
limit?: number;
|
|
11
|
+
}): Promise<Buffer>;
|
package/esm/stream.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createInflate, createGunzip, createBrotliDecompress } from 'node:zlib';
|
|
2
|
+
import makeDefer from 'jdefer';
|
|
3
|
+
// note: there might be multiple encodings applied to the stream
|
|
4
|
+
// we only support one encoding
|
|
5
|
+
export function getContentStream(req, encoding, disableInflate) {
|
|
6
|
+
if (disableInflate && encoding !== 'identity')
|
|
7
|
+
throw new Error(`content-encoding ${encoding} is not supported`);
|
|
8
|
+
switch (encoding) {
|
|
9
|
+
case 'deflate': {
|
|
10
|
+
const stream = createInflate();
|
|
11
|
+
req.pipe(stream);
|
|
12
|
+
return stream;
|
|
13
|
+
}
|
|
14
|
+
case 'gzip': {
|
|
15
|
+
const stream = createGunzip();
|
|
16
|
+
req.pipe(stream);
|
|
17
|
+
return stream;
|
|
18
|
+
}
|
|
19
|
+
case 'br': {
|
|
20
|
+
const stream = createBrotliDecompress();
|
|
21
|
+
req.pipe(stream);
|
|
22
|
+
return stream;
|
|
23
|
+
}
|
|
24
|
+
case 'identity':
|
|
25
|
+
return req;
|
|
26
|
+
default:
|
|
27
|
+
throw new Error(`unsupported content-encoding ${encoding}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// https://github.com/stream-utils/raw-body/blob/191e4b6506dcf77198eed01c8feb4b6817008342/index.js#L155
|
|
31
|
+
export async function readStream(stream, { length, limit }) {
|
|
32
|
+
let completed = false;
|
|
33
|
+
// check the length and limit options.
|
|
34
|
+
// note: we intentionally leave the stream paused,
|
|
35
|
+
// so users should handle the stream themselves.
|
|
36
|
+
if (limit !== undefined && length !== undefined && length > limit)
|
|
37
|
+
throw new Error('request entity too large');
|
|
38
|
+
let received = 0;
|
|
39
|
+
const buffers = [];
|
|
40
|
+
const defer = makeDefer();
|
|
41
|
+
// attach listeners
|
|
42
|
+
stream.on('aborted', onAborted);
|
|
43
|
+
stream.on('close', onClose);
|
|
44
|
+
stream.on('data', onData);
|
|
45
|
+
stream.on('end', onEnd);
|
|
46
|
+
stream.on('error', onError);
|
|
47
|
+
function done(err, result) {
|
|
48
|
+
if (completed)
|
|
49
|
+
return;
|
|
50
|
+
completed = true;
|
|
51
|
+
onClose();
|
|
52
|
+
if (err) {
|
|
53
|
+
stream.unpipe?.();
|
|
54
|
+
stream.pause?.();
|
|
55
|
+
defer.reject(err);
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
defer.resolve(result);
|
|
59
|
+
}
|
|
60
|
+
function onData(chunk) {
|
|
61
|
+
if (completed)
|
|
62
|
+
return;
|
|
63
|
+
received += chunk.length;
|
|
64
|
+
if (limit !== undefined && received > limit) {
|
|
65
|
+
done(new Error('request entity too large'));
|
|
66
|
+
}
|
|
67
|
+
else
|
|
68
|
+
buffers.push(chunk);
|
|
69
|
+
}
|
|
70
|
+
function onError(err) {
|
|
71
|
+
done(err);
|
|
72
|
+
}
|
|
73
|
+
function onEnd() {
|
|
74
|
+
if (length !== undefined && received !== length)
|
|
75
|
+
done(new Error('request size did not match content length'));
|
|
76
|
+
else
|
|
77
|
+
done(undefined, Buffer.concat(buffers));
|
|
78
|
+
}
|
|
79
|
+
function onAborted() {
|
|
80
|
+
done(new Error('request aborted'));
|
|
81
|
+
}
|
|
82
|
+
function onClose() {
|
|
83
|
+
buffers.splice(0, buffers.length);
|
|
84
|
+
stream.off('aborted', onAborted);
|
|
85
|
+
stream.off('data', onData);
|
|
86
|
+
stream.off('end', onEnd);
|
|
87
|
+
stream.off('error', onEnd);
|
|
88
|
+
stream.off('close', onClose);
|
|
89
|
+
}
|
|
90
|
+
return await defer.promise;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUM3RSxPQUFPLFNBQVMsTUFBTSxRQUFRLENBQUE7QUFFOUIsZ0VBQWdFO0FBQ2hFLCtCQUErQjtBQUMvQixNQUFNLFVBQVUsZ0JBQWdCLENBQUMsR0FBb0IsRUFBRSxRQUFnQixFQUFFLGNBQXdCO0lBQ2hHLElBQUksY0FBYyxJQUFJLFFBQVEsS0FBSyxVQUFVO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsUUFBUSxtQkFBbUIsQ0FBQyxDQUFBO0lBRS9HLFFBQVEsUUFBUSxFQUFFO1FBQ2pCLEtBQUssU0FBUyxDQUFDLENBQUM7WUFDZixNQUFNLE1BQU0sR0FBRyxhQUFhLEVBQUUsQ0FBQTtZQUM5QixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQ2hCLE9BQU8sTUFBTSxDQUFBO1NBQ2I7UUFDRCxLQUFLLE1BQU0sQ0FBQyxDQUFDO1lBQ1osTUFBTSxNQUFNLEdBQUcsWUFBWSxFQUFFLENBQUE7WUFDN0IsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUNoQixPQUFPLE1BQU0sQ0FBQTtTQUNiO1FBQ0QsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUNWLE1BQU0sTUFBTSxHQUFHLHNCQUFzQixFQUFFLENBQUE7WUFDdkMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUNoQixPQUFPLE1BQU0sQ0FBQTtTQUNiO1FBQ0QsS0FBSyxVQUFVO1lBQ2QsT0FBTyxHQUFHLENBQUE7UUFDWDtZQUNDLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLFFBQVEsRUFBRSxDQUFDLENBQUE7S0FDNUQ7QUFDRixDQUFDO0FBRUQsdUdBQXVHO0FBQ3ZHLE1B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
|
package/package.json
CHANGED
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dx-server",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"main": "index.js",
|
|
5
|
-
"repository": "
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"main": "./cjs/index.js",
|
|
5
|
+
"repository": "https://github.com/tranvansang/dx-server",
|
|
6
6
|
"author": "Sang Tran <t@sang.jp>",
|
|
7
|
+
"files": [
|
|
8
|
+
"cjs",
|
|
9
|
+
"esm"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./esm/index.js",
|
|
14
|
+
"require": "./cjs/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"prepublish": "./compile.sh"
|
|
20
|
+
},
|
|
7
21
|
"license": "MIT",
|
|
8
|
-
"
|
|
9
|
-
|
|
22
|
+
"packageManager": "yarn@3.6.1",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^20.4.9",
|
|
25
|
+
"@types/path-to-regexp": "^1.7.0",
|
|
26
|
+
"@types/qs": "^6.9.7",
|
|
27
|
+
"type-fest": "^4.2.0",
|
|
28
|
+
"typescript": "^5.1.6"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"jdefer": "^0.0.9",
|
|
32
|
+
"jmisc": "^0.0.9",
|
|
33
|
+
"path-to-regexp": "^6.2.1",
|
|
34
|
+
"qs": "^6.11.2"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
echo 'this is a placeholder for the upcoming package'
|