hono 2.0.5 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compose.js +2 -1
- package/dist/context.d.ts +9 -3
- package/dist/context.js +7 -7
- package/dist/hono.d.ts +2 -0
- package/dist/middleware/etag/index.js +1 -3
- package/dist/middleware/html/index.d.ts +1 -3
- package/dist/middleware/html/index.js +12 -8
- package/dist/middleware/jsx/index.d.ts +13 -3
- package/dist/middleware/jsx/index.js +127 -36
- package/dist/middleware/jsx/jsx-dev-runtime.d.ts +2 -2
- package/dist/middleware/jwt/index.d.ts +1 -0
- package/dist/middleware/jwt/index.js +20 -11
- package/dist/request.d.ts +3 -2
- package/dist/utils/body.d.ts +2 -1
- package/dist/utils/body.js +8 -2
- package/dist/utils/crypto.d.ts +1 -1
- package/dist/utils/crypto.js +20 -1
- package/dist/utils/html.d.ts +4 -2
- package/dist/utils/html.js +35 -12
- package/dist/utils/mime.js +1 -1
- package/package.json +1 -1
package/dist/compose.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.compose = void 0;
|
|
|
4
4
|
const context_1 = require("./context");
|
|
5
5
|
// Based on the code in the MIT licensed `koa-compose` package.
|
|
6
6
|
const compose = (middleware, onError, onNotFound) => {
|
|
7
|
+
const middlewareLength = middleware.length;
|
|
7
8
|
return (context, next) => {
|
|
8
9
|
let index = -1;
|
|
9
10
|
return dispatch(0);
|
|
@@ -13,7 +14,7 @@ const compose = (middleware, onError, onNotFound) => {
|
|
|
13
14
|
}
|
|
14
15
|
let handler = middleware[i];
|
|
15
16
|
index = i;
|
|
16
|
-
if (i ===
|
|
17
|
+
if (i === middlewareLength && next)
|
|
17
18
|
handler = next;
|
|
18
19
|
if (!handler) {
|
|
19
20
|
if (context instanceof context_1.HonoContext && context.finalized === false && onNotFound) {
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import type { NotFoundHandler } from './hono';
|
|
2
|
+
import type { ContextVariableMap, NotFoundHandler } from './hono';
|
|
3
3
|
import type { CookieOptions } from './utils/cookie';
|
|
4
4
|
import type { StatusCode } from './utils/http-status';
|
|
5
5
|
declare type Headers = Record<string, string>;
|
|
@@ -15,8 +15,14 @@ export interface Context<RequestParamKeyType extends string = string, E = Env> {
|
|
|
15
15
|
set res(_res: Response);
|
|
16
16
|
header: (name: string, value: string) => void;
|
|
17
17
|
status: (status: StatusCode) => void;
|
|
18
|
-
set:
|
|
19
|
-
|
|
18
|
+
set: {
|
|
19
|
+
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
|
|
20
|
+
(key: string, value: any): void;
|
|
21
|
+
};
|
|
22
|
+
get: {
|
|
23
|
+
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
24
|
+
<T = any>(key: string): T;
|
|
25
|
+
};
|
|
20
26
|
pretty: (prettyJSON: boolean, space?: number) => void;
|
|
21
27
|
newResponse: (data: Data | null, status: StatusCode, headers: Headers) => Response;
|
|
22
28
|
body: (data: Data | null, status?: StatusCode, headers?: Headers) => Response;
|
package/dist/context.js
CHANGED
|
@@ -39,7 +39,7 @@ class HonoContext {
|
|
|
39
39
|
}
|
|
40
40
|
header(name, value) {
|
|
41
41
|
this._headers || (this._headers = {});
|
|
42
|
-
this._headers[name] = value;
|
|
42
|
+
this._headers[name.toLowerCase()] = value;
|
|
43
43
|
if (this.finalized) {
|
|
44
44
|
this.res.headers.set(name, value);
|
|
45
45
|
}
|
|
@@ -62,7 +62,7 @@ class HonoContext {
|
|
|
62
62
|
this._prettySpace = space;
|
|
63
63
|
}
|
|
64
64
|
newResponse(data, status, headers = {}) {
|
|
65
|
-
const _headers = { ...this._headers
|
|
65
|
+
const _headers = { ...this._headers };
|
|
66
66
|
if (this._res) {
|
|
67
67
|
this._res.headers.forEach((v, k) => {
|
|
68
68
|
_headers[k] = v;
|
|
@@ -70,25 +70,25 @@ class HonoContext {
|
|
|
70
70
|
}
|
|
71
71
|
return new Response(data, {
|
|
72
72
|
status: status || this._status || 200,
|
|
73
|
-
headers: _headers,
|
|
73
|
+
headers: { ..._headers, ...headers },
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
body(data, status = this._status, headers = {}) {
|
|
77
77
|
return this.newResponse(data, status, headers);
|
|
78
78
|
}
|
|
79
79
|
text(text, status = this._status, headers = {}) {
|
|
80
|
-
headers['
|
|
80
|
+
headers['content-type'] = 'text/plain; charset=UTF-8';
|
|
81
81
|
return this.body(text, status, headers);
|
|
82
82
|
}
|
|
83
83
|
json(object, status = this._status, headers = {}) {
|
|
84
84
|
const body = this._pretty
|
|
85
85
|
? JSON.stringify(object, null, this._prettySpace)
|
|
86
86
|
: JSON.stringify(object);
|
|
87
|
-
headers['
|
|
87
|
+
headers['content-type'] = 'application/json; charset=UTF-8';
|
|
88
88
|
return this.body(body, status, headers);
|
|
89
89
|
}
|
|
90
90
|
html(html, status = this._status, headers = {}) {
|
|
91
|
-
headers['
|
|
91
|
+
headers['content-type'] = 'text/html; charset=UTF-8';
|
|
92
92
|
return this.body(html, status, headers);
|
|
93
93
|
}
|
|
94
94
|
redirect(location, status = 302) {
|
|
@@ -103,7 +103,7 @@ class HonoContext {
|
|
|
103
103
|
}
|
|
104
104
|
cookie(name, value, opt) {
|
|
105
105
|
const cookie = (0, cookie_1.serialize)(name, value, opt);
|
|
106
|
-
this.header('
|
|
106
|
+
this.header('set-cookie', cookie);
|
|
107
107
|
}
|
|
108
108
|
notFound() {
|
|
109
109
|
return this.notFoundHandler(this);
|
package/dist/hono.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
2
|
import type { Context } from './context';
|
|
3
3
|
import type { Router } from './router';
|
|
4
|
+
export interface ContextVariableMap {
|
|
5
|
+
}
|
|
4
6
|
declare type Env = Record<string, any>;
|
|
5
7
|
export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>;
|
|
6
8
|
export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response | Promise<Response>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.etag = void 0;
|
|
4
|
-
const body_1 = require("../../utils/body");
|
|
5
4
|
const crypto_1 = require("../../utils/crypto");
|
|
6
5
|
const etag = (options = { weak: false }) => {
|
|
7
6
|
return async (c, next) => {
|
|
@@ -9,8 +8,7 @@ const etag = (options = { weak: false }) => {
|
|
|
9
8
|
await next();
|
|
10
9
|
const res = c.res;
|
|
11
10
|
const clone = res.clone();
|
|
12
|
-
const
|
|
13
|
-
const hash = await (0, crypto_1.sha1)(body);
|
|
11
|
+
const hash = await (0, crypto_1.sha1)(res.body || '');
|
|
14
12
|
const etag = options.weak ? `W/"${hash}"` : `"${hash}"`;
|
|
15
13
|
if (ifNoneMatch && ifNoneMatch === etag) {
|
|
16
14
|
await clone.blob(); // Force using body
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
isEscaped: true;
|
|
3
|
-
};
|
|
1
|
+
import type { HtmlEscapedString } from '../../utils/html';
|
|
4
2
|
export declare const raw: (value: any) => HtmlEscapedString;
|
|
5
3
|
export declare const html: (strings: TemplateStringsArray, ...values: any[]) => HtmlEscapedString;
|
|
@@ -9,24 +9,28 @@ const raw = (value) => {
|
|
|
9
9
|
};
|
|
10
10
|
exports.raw = raw;
|
|
11
11
|
const html = (strings, ...values) => {
|
|
12
|
-
|
|
12
|
+
const buffer = [''];
|
|
13
13
|
for (let i = 0, len = strings.length - 1; i < len; i++) {
|
|
14
|
-
|
|
14
|
+
buffer[0] += strings[i];
|
|
15
15
|
const children = values[i] instanceof Array ? values[i].flat(Infinity) : [values[i]];
|
|
16
16
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
17
17
|
const child = children[i];
|
|
18
|
-
if (typeof child === '
|
|
18
|
+
if (typeof child === 'string') {
|
|
19
|
+
(0, html_1.escapeToBuffer)(child, buffer);
|
|
20
|
+
}
|
|
21
|
+
else if (typeof child === 'boolean' || child === null || child === undefined) {
|
|
19
22
|
continue;
|
|
20
23
|
}
|
|
21
|
-
else if (typeof child === 'object' && child.isEscaped)
|
|
22
|
-
|
|
24
|
+
else if ((typeof child === 'object' && child.isEscaped) ||
|
|
25
|
+
typeof child === 'number') {
|
|
26
|
+
buffer[0] += child;
|
|
23
27
|
}
|
|
24
28
|
else {
|
|
25
|
-
|
|
29
|
+
(0, html_1.escapeToBuffer)(child.toString(), buffer);
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
|
-
|
|
30
|
-
return (0, exports.raw)(
|
|
33
|
+
buffer[0] += strings[strings.length - 1];
|
|
34
|
+
return (0, exports.raw)(buffer[0]);
|
|
31
35
|
};
|
|
32
36
|
exports.html = html;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HtmlEscapedString } from '../../utils/html';
|
|
1
|
+
import type { StringBuffer, HtmlEscaped, HtmlEscapedString } from '../../utils/html';
|
|
2
2
|
declare global {
|
|
3
3
|
namespace jsx.JSX {
|
|
4
4
|
interface IntrinsicElements {
|
|
@@ -6,11 +6,21 @@ declare global {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
+
declare type Child = string | number | JSXNode | Child[];
|
|
10
|
+
export declare class JSXNode implements HtmlEscaped {
|
|
11
|
+
tag: string | Function;
|
|
12
|
+
props: Record<string, any>;
|
|
13
|
+
children: Child[];
|
|
14
|
+
isEscaped: true;
|
|
15
|
+
constructor(tag: string | Function, props: Record<string, any>, children: Child[]);
|
|
16
|
+
toString(): string;
|
|
17
|
+
toStringToBuffer(buffer: StringBuffer): void;
|
|
18
|
+
}
|
|
9
19
|
export { jsxFn as jsx };
|
|
10
|
-
declare const jsxFn: (tag: string | Function, props: Record<string, any>, ...children: (string | HtmlEscapedString)[]) =>
|
|
20
|
+
declare const jsxFn: (tag: string | Function, props: Record<string, any>, ...children: (string | HtmlEscapedString)[]) => JSXNode;
|
|
11
21
|
declare type FC<T = Record<string, any>> = (props: T) => HtmlEscapedString;
|
|
12
22
|
export declare const memo: <T>(component: FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => FC<T>;
|
|
13
23
|
export declare const Fragment: (props: {
|
|
14
24
|
key?: string;
|
|
15
25
|
children?: any;
|
|
16
|
-
}) =>
|
|
26
|
+
}) => JSXNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Fragment = exports.memo = exports.jsx = void 0;
|
|
3
|
+
exports.Fragment = exports.memo = exports.jsx = exports.JSXNode = void 0;
|
|
4
4
|
const html_1 = require("../../utils/html");
|
|
5
5
|
const emptyTags = [
|
|
6
6
|
'area',
|
|
@@ -19,53 +19,144 @@ const emptyTags = [
|
|
|
19
19
|
'track',
|
|
20
20
|
'wbr',
|
|
21
21
|
];
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
const booleanAttributes = [
|
|
23
|
+
'allowfullscreen',
|
|
24
|
+
'async',
|
|
25
|
+
'autofocus',
|
|
26
|
+
'autoplay',
|
|
27
|
+
'checked',
|
|
28
|
+
'controls',
|
|
29
|
+
'default',
|
|
30
|
+
'defer',
|
|
31
|
+
'disabled',
|
|
32
|
+
'formnovalidate',
|
|
33
|
+
'hidden',
|
|
34
|
+
'inert',
|
|
35
|
+
'ismap',
|
|
36
|
+
'itemscope',
|
|
37
|
+
'loop',
|
|
38
|
+
'multiple',
|
|
39
|
+
'muted',
|
|
40
|
+
'nomodule',
|
|
41
|
+
'novalidate',
|
|
42
|
+
'open',
|
|
43
|
+
'playsinline',
|
|
44
|
+
'readonly',
|
|
45
|
+
'required',
|
|
46
|
+
'reversed',
|
|
47
|
+
'selected',
|
|
48
|
+
];
|
|
49
|
+
const childrenToStringToBuffer = (children, buffer) => {
|
|
50
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
51
|
+
const child = children[i];
|
|
52
|
+
if (typeof child === 'string') {
|
|
53
|
+
(0, html_1.escapeToBuffer)(child, buffer);
|
|
38
54
|
}
|
|
39
|
-
else if (
|
|
55
|
+
else if (typeof child === 'boolean' || child === null || child === undefined) {
|
|
40
56
|
continue;
|
|
41
57
|
}
|
|
42
|
-
|
|
58
|
+
else if (child instanceof JSXNode) {
|
|
59
|
+
child.toStringToBuffer(buffer);
|
|
60
|
+
}
|
|
61
|
+
else if (typeof child === 'number' || child.isEscaped) {
|
|
62
|
+
buffer[0] += child;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// `child` type is `Child[]`, so stringify recursively
|
|
66
|
+
childrenToStringToBuffer(child, buffer);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
class JSXNode {
|
|
71
|
+
constructor(tag, props, children) {
|
|
72
|
+
this.isEscaped = true;
|
|
73
|
+
this.tag = tag;
|
|
74
|
+
this.props = props;
|
|
75
|
+
this.children = children;
|
|
76
|
+
}
|
|
77
|
+
toString() {
|
|
78
|
+
const buffer = [''];
|
|
79
|
+
this.toStringToBuffer(buffer);
|
|
80
|
+
return buffer[0];
|
|
43
81
|
}
|
|
44
|
-
|
|
82
|
+
toStringToBuffer(buffer) {
|
|
83
|
+
const tag = this.tag;
|
|
84
|
+
const props = this.props;
|
|
85
|
+
let { children } = this;
|
|
86
|
+
buffer[0] += `<${tag}`;
|
|
87
|
+
const propsKeys = Object.keys(props || {});
|
|
88
|
+
for (let i = 0, len = propsKeys.length; i < len; i++) {
|
|
89
|
+
const v = props[propsKeys[i]];
|
|
90
|
+
if (typeof v === 'string') {
|
|
91
|
+
buffer[0] += ` ${propsKeys[i]}="`;
|
|
92
|
+
(0, html_1.escapeToBuffer)(v, buffer);
|
|
93
|
+
buffer[0] += '"';
|
|
94
|
+
}
|
|
95
|
+
else if (typeof v === 'number') {
|
|
96
|
+
buffer[0] += ` ${propsKeys[i]}="${v}"`;
|
|
97
|
+
}
|
|
98
|
+
else if (v === null || v === undefined) {
|
|
99
|
+
// Do nothing
|
|
100
|
+
}
|
|
101
|
+
else if (typeof v === 'boolean' && booleanAttributes.includes(propsKeys[i])) {
|
|
102
|
+
if (v) {
|
|
103
|
+
buffer[0] += ` ${propsKeys[i]}=""`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (propsKeys[i] === 'dangerouslySetInnerHTML') {
|
|
107
|
+
if (children.length > 0) {
|
|
108
|
+
throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.';
|
|
109
|
+
}
|
|
110
|
+
const escapedString = new String(v.__html);
|
|
111
|
+
escapedString.isEscaped = true;
|
|
112
|
+
children = [escapedString];
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
buffer[0] += ` ${propsKeys[i]}="`;
|
|
116
|
+
(0, html_1.escapeToBuffer)(v.toString(), buffer);
|
|
117
|
+
buffer[0] += '"';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
45
120
|
if (emptyTags.includes(tag)) {
|
|
46
|
-
|
|
121
|
+
buffer[0] += '/>';
|
|
122
|
+
return;
|
|
47
123
|
}
|
|
48
|
-
|
|
124
|
+
buffer[0] += '>';
|
|
125
|
+
childrenToStringToBuffer(children, buffer);
|
|
126
|
+
buffer[0] += `</${tag}>`;
|
|
49
127
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
128
|
+
}
|
|
129
|
+
exports.JSXNode = JSXNode;
|
|
130
|
+
class JSXFunctionNode extends JSXNode {
|
|
131
|
+
toStringToBuffer(buffer) {
|
|
132
|
+
const { children } = this;
|
|
133
|
+
const res = this.tag.call(null, {
|
|
134
|
+
...this.props,
|
|
135
|
+
children: children.length <= 1 ? children[0] : children,
|
|
136
|
+
});
|
|
137
|
+
if (res instanceof JSXNode) {
|
|
138
|
+
res.toStringToBuffer(buffer);
|
|
55
139
|
}
|
|
56
|
-
else if (typeof
|
|
57
|
-
|
|
140
|
+
else if (typeof res === 'number' || res.isEscaped) {
|
|
141
|
+
buffer[0] += res;
|
|
58
142
|
}
|
|
59
143
|
else {
|
|
60
|
-
|
|
144
|
+
(0, html_1.escapeToBuffer)(res, buffer);
|
|
61
145
|
}
|
|
62
146
|
}
|
|
63
|
-
|
|
64
|
-
|
|
147
|
+
}
|
|
148
|
+
class JSXFragmentNode extends JSXNode {
|
|
149
|
+
toStringToBuffer(buffer) {
|
|
150
|
+
childrenToStringToBuffer(this.children, buffer);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const jsxFn = (tag, props, ...children) => {
|
|
154
|
+
if (typeof tag === 'function') {
|
|
155
|
+
return new JSXFunctionNode(tag, props, children);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return new JSXNode(tag, props, children);
|
|
65
159
|
}
|
|
66
|
-
const escapedString = new String(result);
|
|
67
|
-
escapedString.isEscaped = true;
|
|
68
|
-
return escapedString;
|
|
69
160
|
};
|
|
70
161
|
exports.jsx = jsxFn;
|
|
71
162
|
const shallowEqual = (a, b) => {
|
|
@@ -97,6 +188,6 @@ const memo = (component, propsAreEqual = shallowEqual) => {
|
|
|
97
188
|
};
|
|
98
189
|
exports.memo = memo;
|
|
99
190
|
const Fragment = (props) => {
|
|
100
|
-
return
|
|
191
|
+
return new JSXFragmentNode('', {}, props.children || []);
|
|
101
192
|
};
|
|
102
193
|
exports.Fragment = Fragment;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function jsxDEV(tag: string | Function, props: Record<string, any>):
|
|
1
|
+
import type { JSXNode } from '.';
|
|
2
|
+
export declare function jsxDEV(tag: string | Function, props: Record<string, any>): JSXNode;
|
|
@@ -11,17 +11,26 @@ const jwt = (options) => {
|
|
|
11
11
|
}
|
|
12
12
|
return async (ctx, next) => {
|
|
13
13
|
const credentials = ctx.req.headers.get('Authorization');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
let token;
|
|
15
|
+
if (credentials) {
|
|
16
|
+
const parts = credentials.split(/\s+/);
|
|
17
|
+
if (parts.length !== 2) {
|
|
18
|
+
ctx.res = new Response('Unauthorized', {
|
|
19
|
+
status: 401,
|
|
20
|
+
headers: {
|
|
21
|
+
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="invalid credentials structure"`,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
token = parts[1];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if (options.cookie) {
|
|
31
|
+
token = ctx.req.cookie(options.cookie);
|
|
22
32
|
}
|
|
23
|
-
|
|
24
|
-
if (parts.length !== 2) {
|
|
33
|
+
if (!token) {
|
|
25
34
|
ctx.res = new Response('Unauthorized', {
|
|
26
35
|
status: 401,
|
|
27
36
|
headers: {
|
|
@@ -33,7 +42,7 @@ const jwt = (options) => {
|
|
|
33
42
|
let authorized = false;
|
|
34
43
|
let msg = '';
|
|
35
44
|
try {
|
|
36
|
-
authorized = await jwt_1.Jwt.verify(
|
|
45
|
+
authorized = await jwt_1.Jwt.verify(token, options.secret, options.alg);
|
|
37
46
|
}
|
|
38
47
|
catch (e) {
|
|
39
48
|
msg = `${e}`;
|
package/dist/request.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Body } from './utils/body';
|
|
1
2
|
import type { Cookie } from './utils/cookie';
|
|
2
3
|
declare global {
|
|
3
4
|
interface Request<ParamKeyType extends string = string> {
|
|
@@ -22,9 +23,9 @@ declare global {
|
|
|
22
23
|
(name: string): string;
|
|
23
24
|
(): Cookie;
|
|
24
25
|
};
|
|
25
|
-
parsedBody?: Promise<
|
|
26
|
+
parsedBody?: Promise<Body>;
|
|
26
27
|
parseBody: {
|
|
27
|
-
(): Promise<
|
|
28
|
+
(): Promise<Body>;
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
}
|
package/dist/utils/body.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare type Body = string | object | Record<string, string | File> | ArrayBuffer;
|
|
2
|
+
export declare const parseBody: (r: Request | Response) => Promise<Body>;
|
package/dist/utils/body.js
CHANGED
|
@@ -4,7 +4,12 @@ exports.parseBody = void 0;
|
|
|
4
4
|
const parseBody = async (r) => {
|
|
5
5
|
const contentType = r.headers.get('Content-Type') || '';
|
|
6
6
|
if (contentType.includes('application/json')) {
|
|
7
|
-
|
|
7
|
+
let body = {};
|
|
8
|
+
try {
|
|
9
|
+
body = await r.json();
|
|
10
|
+
}
|
|
11
|
+
catch { } // Do nothing
|
|
12
|
+
return body;
|
|
8
13
|
}
|
|
9
14
|
else if (contentType.includes('application/text')) {
|
|
10
15
|
return await r.text();
|
|
@@ -20,6 +25,7 @@ const parseBody = async (r) => {
|
|
|
20
25
|
}, form);
|
|
21
26
|
return data;
|
|
22
27
|
}
|
|
23
|
-
|
|
28
|
+
const arrayBuffer = await r.arrayBuffer();
|
|
29
|
+
return arrayBuffer;
|
|
24
30
|
};
|
|
25
31
|
exports.parseBody = parseBody;
|
package/dist/utils/crypto.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare type Algorithm = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
alias: string;
|
|
4
4
|
};
|
|
5
|
-
declare type Data = string | object |
|
|
5
|
+
declare type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer | ReadableStream;
|
|
6
6
|
export declare const sha256: (data: Data) => Promise<string | null>;
|
|
7
7
|
export declare const sha1: (data: Data) => Promise<string | null>;
|
|
8
8
|
export declare const md5: (data: Data) => Promise<string | null>;
|
package/dist/utils/crypto.js
CHANGED
|
@@ -20,10 +20,29 @@ const md5 = async (data) => {
|
|
|
20
20
|
};
|
|
21
21
|
exports.md5 = md5;
|
|
22
22
|
const createHash = async (data, algorithm) => {
|
|
23
|
+
let sourceBuffer;
|
|
24
|
+
if (data instanceof ReadableStream) {
|
|
25
|
+
let body = '';
|
|
26
|
+
const reader = data.getReader();
|
|
27
|
+
await reader?.read().then(async (chuck) => {
|
|
28
|
+
const value = await (0, exports.createHash)(chuck.value || '', algorithm);
|
|
29
|
+
body += value;
|
|
30
|
+
});
|
|
31
|
+
return body;
|
|
32
|
+
}
|
|
33
|
+
if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) {
|
|
34
|
+
sourceBuffer = data;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (typeof data === 'object') {
|
|
38
|
+
data = JSON.stringify(data);
|
|
39
|
+
}
|
|
40
|
+
sourceBuffer = new TextEncoder().encode(String(data));
|
|
41
|
+
}
|
|
23
42
|
if (crypto && crypto.subtle) {
|
|
24
43
|
const buffer = await crypto.subtle.digest({
|
|
25
44
|
name: algorithm.name,
|
|
26
|
-
},
|
|
45
|
+
}, sourceBuffer);
|
|
27
46
|
const hash = Array.prototype.map
|
|
28
47
|
.call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
|
|
29
48
|
.join('');
|
package/dist/utils/html.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export declare type
|
|
1
|
+
export declare type HtmlEscaped = {
|
|
2
2
|
isEscaped: true;
|
|
3
3
|
};
|
|
4
|
-
export declare
|
|
4
|
+
export declare type HtmlEscapedString = string & HtmlEscaped;
|
|
5
|
+
export declare type StringBuffer = [string];
|
|
6
|
+
export declare const escapeToBuffer: (str: string, buffer: StringBuffer) => void;
|
package/dist/utils/html.js
CHANGED
|
@@ -1,15 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
exports.escapeToBuffer = void 0;
|
|
4
|
+
// The `escapeToBuffer` implementation is based on code from the MIT licensed `react-dom` package.
|
|
5
|
+
// https://github.com/facebook/react/blob/main/packages/react-dom/src/server/escapeTextForBrowser.js
|
|
6
|
+
const escapeRe = /[&<>"]/;
|
|
7
|
+
const escapeToBuffer = (str, buffer) => {
|
|
8
|
+
const match = str.search(escapeRe);
|
|
9
|
+
if (match === -1) {
|
|
10
|
+
buffer[0] += str;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let escape;
|
|
14
|
+
let index;
|
|
15
|
+
let lastIndex = 0;
|
|
16
|
+
for (index = match; index < str.length; index++) {
|
|
17
|
+
switch (str.charCodeAt(index)) {
|
|
18
|
+
case 34: // "
|
|
19
|
+
escape = '"';
|
|
20
|
+
break;
|
|
21
|
+
case 38: // &
|
|
22
|
+
escape = '&';
|
|
23
|
+
break;
|
|
24
|
+
case 60: // <
|
|
25
|
+
escape = '<';
|
|
26
|
+
break;
|
|
27
|
+
case 62: // >
|
|
28
|
+
escape = '>';
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
buffer[0] += str.substring(lastIndex, index) + escape;
|
|
34
|
+
lastIndex = index + 1;
|
|
35
|
+
}
|
|
36
|
+
buffer[0] += str.substring(lastIndex, index);
|
|
9
37
|
};
|
|
10
|
-
|
|
11
|
-
const replaceFn = (m) => entityMap[m];
|
|
12
|
-
const escape = (str) => {
|
|
13
|
-
return str.replace(escapeRe, replaceFn);
|
|
14
|
-
};
|
|
15
|
-
exports.escape = escape;
|
|
38
|
+
exports.escapeToBuffer = escapeToBuffer;
|
package/dist/utils/mime.js
CHANGED