hono 4.5.0 → 4.5.2
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/cjs/client/client.js +9 -2
- package/dist/cjs/middleware/bearer-auth/index.js +7 -5
- package/dist/cjs/middleware/csrf/index.js +1 -1
- package/dist/cjs/middleware/secure-headers/secure-headers.js +5 -2
- package/dist/cjs/validator/validator.js +6 -4
- package/dist/client/client.js +9 -2
- package/dist/middleware/bearer-auth/index.js +7 -5
- package/dist/middleware/csrf/index.js +1 -1
- package/dist/middleware/secure-headers/secure-headers.js +5 -2
- package/dist/types/context.d.ts +1 -1
- package/dist/types/helper/factory/index.d.ts +0 -4
- package/dist/types/middleware/bearer-auth/index.d.ts +1 -1
- package/dist/types/middleware/jwt/jwt.d.ts +5 -4
- package/dist/types/middleware/secure-headers/secure-headers.d.ts +2 -0
- package/dist/types/utils/types.d.ts +2 -2
- package/dist/validator/validator.js +6 -4
- package/package.json +5 -5
- package/dist/cjs/test-utils/setup-vitest.js +0 -49
- package/dist/test-utils/setup-vitest.js +0 -31
|
@@ -157,8 +157,15 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
157
157
|
"ws"
|
|
158
158
|
);
|
|
159
159
|
const targetUrl = new URL(webSocketUrl);
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
const queryParams = opts.args[0]?.query;
|
|
161
|
+
if (queryParams) {
|
|
162
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
163
|
+
if (Array.isArray(value)) {
|
|
164
|
+
value.forEach((item) => targetUrl.searchParams.append(key, item));
|
|
165
|
+
} else {
|
|
166
|
+
targetUrl.searchParams.set(key, value);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
162
169
|
}
|
|
163
170
|
return new WebSocket(targetUrl.toString());
|
|
164
171
|
}
|
|
@@ -33,28 +33,30 @@ const bearerAuth = (options) => {
|
|
|
33
33
|
if (!options.realm) {
|
|
34
34
|
options.realm = "";
|
|
35
35
|
}
|
|
36
|
-
if (
|
|
36
|
+
if (options.prefix === void 0) {
|
|
37
37
|
options.prefix = PREFIX;
|
|
38
38
|
}
|
|
39
39
|
const realm = options.realm?.replace(/"/g, '\\"');
|
|
40
|
+
const prefixRegexStr = options.prefix === "" ? "" : `${options.prefix} +`;
|
|
41
|
+
const regexp = new RegExp(`^${prefixRegexStr}(${TOKEN_STRINGS}) *$`);
|
|
42
|
+
const wwwAuthenticatePrefix = options.prefix === "" ? "" : `${options.prefix} `;
|
|
40
43
|
return async function bearerAuth2(c, next) {
|
|
41
44
|
const headerToken = c.req.header(options.headerName || HEADER);
|
|
42
45
|
if (!headerToken) {
|
|
43
46
|
const res = new Response("Unauthorized", {
|
|
44
47
|
status: 401,
|
|
45
48
|
headers: {
|
|
46
|
-
"WWW-Authenticate": `${
|
|
49
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}realm="` + realm + '"'
|
|
47
50
|
}
|
|
48
51
|
});
|
|
49
52
|
throw new import_http_exception.HTTPException(401, { res });
|
|
50
53
|
} else {
|
|
51
|
-
const regexp = new RegExp("^" + options.prefix + " +(" + TOKEN_STRINGS + ") *$");
|
|
52
54
|
const match = regexp.exec(headerToken);
|
|
53
55
|
if (!match) {
|
|
54
56
|
const res = new Response("Bad Request", {
|
|
55
57
|
status: 400,
|
|
56
58
|
headers: {
|
|
57
|
-
"WWW-Authenticate": `${
|
|
59
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}error="invalid_request"`
|
|
58
60
|
}
|
|
59
61
|
});
|
|
60
62
|
throw new import_http_exception.HTTPException(400, { res });
|
|
@@ -76,7 +78,7 @@ const bearerAuth = (options) => {
|
|
|
76
78
|
const res = new Response("Unauthorized", {
|
|
77
79
|
status: 401,
|
|
78
80
|
headers: {
|
|
79
|
-
"WWW-Authenticate": `${
|
|
81
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}error="invalid_token"`
|
|
80
82
|
}
|
|
81
83
|
});
|
|
82
84
|
throw new import_http_exception.HTTPException(401, { res });
|
|
@@ -42,7 +42,7 @@ const csrf = (options) => {
|
|
|
42
42
|
}
|
|
43
43
|
return handler(origin, c);
|
|
44
44
|
};
|
|
45
|
-
return async function
|
|
45
|
+
return async function csrf2(c, next) {
|
|
46
46
|
if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "") && !isAllowedOrigin(c.req.header("origin"), c)) {
|
|
47
47
|
const res = new Response("Forbidden", {
|
|
48
48
|
status: 403
|
|
@@ -49,7 +49,8 @@ const DEFAULT_OPTIONS = {
|
|
|
49
49
|
xDownloadOptions: true,
|
|
50
50
|
xFrameOptions: true,
|
|
51
51
|
xPermittedCrossDomainPolicies: true,
|
|
52
|
-
xXssProtection: true
|
|
52
|
+
xXssProtection: true,
|
|
53
|
+
removePoweredBy: true
|
|
53
54
|
};
|
|
54
55
|
const generateNonce = () => {
|
|
55
56
|
const buffer = new Uint8Array(16);
|
|
@@ -85,7 +86,9 @@ const secureHeaders = (customOptions) => {
|
|
|
85
86
|
const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
|
|
86
87
|
await next();
|
|
87
88
|
setHeaders(ctx, headersToSetForReq);
|
|
88
|
-
|
|
89
|
+
if (options?.removePoweredBy) {
|
|
90
|
+
ctx.res.headers.delete("X-Powered-By");
|
|
91
|
+
}
|
|
89
92
|
};
|
|
90
93
|
};
|
|
91
94
|
function getFilteredHeaders(options) {
|
|
@@ -24,15 +24,17 @@ module.exports = __toCommonJS(validator_exports);
|
|
|
24
24
|
var import_cookie = require("../helper/cookie");
|
|
25
25
|
var import_http_exception = require("../http-exception");
|
|
26
26
|
var import_buffer = require("../utils/buffer");
|
|
27
|
+
const jsonRegex = /^application\/([a-z-\.]+\+)?json$/;
|
|
28
|
+
const multipartRegex = /^multipart\/form-data(; boundary=[A-Za-z0-9'()+_,\-./:=?]+)?$/;
|
|
29
|
+
const urlencodedRegex = /^application\/x-www-form-urlencoded$/;
|
|
27
30
|
const validator = (target, validationFunc) => {
|
|
28
31
|
return async (c, next) => {
|
|
29
32
|
let value = {};
|
|
30
33
|
const contentType = c.req.header("Content-Type");
|
|
31
34
|
switch (target) {
|
|
32
35
|
case "json":
|
|
33
|
-
if (!contentType ||
|
|
34
|
-
|
|
35
|
-
throw new import_http_exception.HTTPException(400, { message });
|
|
36
|
+
if (!contentType || !jsonRegex.test(contentType)) {
|
|
37
|
+
break;
|
|
36
38
|
}
|
|
37
39
|
try {
|
|
38
40
|
value = await c.req.json();
|
|
@@ -42,7 +44,7 @@ const validator = (target, validationFunc) => {
|
|
|
42
44
|
}
|
|
43
45
|
break;
|
|
44
46
|
case "form": {
|
|
45
|
-
if (!contentType) {
|
|
47
|
+
if (!contentType || !(multipartRegex.test(contentType) || urlencodedRegex.test(contentType))) {
|
|
46
48
|
break;
|
|
47
49
|
}
|
|
48
50
|
let formData;
|
package/dist/client/client.js
CHANGED
|
@@ -141,8 +141,15 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
141
141
|
"ws"
|
|
142
142
|
);
|
|
143
143
|
const targetUrl = new URL(webSocketUrl);
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
const queryParams = opts.args[0]?.query;
|
|
145
|
+
if (queryParams) {
|
|
146
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
value.forEach((item) => targetUrl.searchParams.append(key, item));
|
|
149
|
+
} else {
|
|
150
|
+
targetUrl.searchParams.set(key, value);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
146
153
|
}
|
|
147
154
|
return new WebSocket(targetUrl.toString());
|
|
148
155
|
}
|
|
@@ -11,28 +11,30 @@ var bearerAuth = (options) => {
|
|
|
11
11
|
if (!options.realm) {
|
|
12
12
|
options.realm = "";
|
|
13
13
|
}
|
|
14
|
-
if (
|
|
14
|
+
if (options.prefix === void 0) {
|
|
15
15
|
options.prefix = PREFIX;
|
|
16
16
|
}
|
|
17
17
|
const realm = options.realm?.replace(/"/g, '\\"');
|
|
18
|
+
const prefixRegexStr = options.prefix === "" ? "" : `${options.prefix} +`;
|
|
19
|
+
const regexp = new RegExp(`^${prefixRegexStr}(${TOKEN_STRINGS}) *$`);
|
|
20
|
+
const wwwAuthenticatePrefix = options.prefix === "" ? "" : `${options.prefix} `;
|
|
18
21
|
return async function bearerAuth2(c, next) {
|
|
19
22
|
const headerToken = c.req.header(options.headerName || HEADER);
|
|
20
23
|
if (!headerToken) {
|
|
21
24
|
const res = new Response("Unauthorized", {
|
|
22
25
|
status: 401,
|
|
23
26
|
headers: {
|
|
24
|
-
"WWW-Authenticate": `${
|
|
27
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}realm="` + realm + '"'
|
|
25
28
|
}
|
|
26
29
|
});
|
|
27
30
|
throw new HTTPException(401, { res });
|
|
28
31
|
} else {
|
|
29
|
-
const regexp = new RegExp("^" + options.prefix + " +(" + TOKEN_STRINGS + ") *$");
|
|
30
32
|
const match = regexp.exec(headerToken);
|
|
31
33
|
if (!match) {
|
|
32
34
|
const res = new Response("Bad Request", {
|
|
33
35
|
status: 400,
|
|
34
36
|
headers: {
|
|
35
|
-
"WWW-Authenticate": `${
|
|
37
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}error="invalid_request"`
|
|
36
38
|
}
|
|
37
39
|
});
|
|
38
40
|
throw new HTTPException(400, { res });
|
|
@@ -54,7 +56,7 @@ var bearerAuth = (options) => {
|
|
|
54
56
|
const res = new Response("Unauthorized", {
|
|
55
57
|
status: 401,
|
|
56
58
|
headers: {
|
|
57
|
-
"WWW-Authenticate": `${
|
|
59
|
+
"WWW-Authenticate": `${wwwAuthenticatePrefix}error="invalid_token"`
|
|
58
60
|
}
|
|
59
61
|
});
|
|
60
62
|
throw new HTTPException(401, { res });
|
|
@@ -20,7 +20,7 @@ var csrf = (options) => {
|
|
|
20
20
|
}
|
|
21
21
|
return handler(origin, c);
|
|
22
22
|
};
|
|
23
|
-
return async function
|
|
23
|
+
return async function csrf2(c, next) {
|
|
24
24
|
if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "") && !isAllowedOrigin(c.req.header("origin"), c)) {
|
|
25
25
|
const res = new Response("Forbidden", {
|
|
26
26
|
status: 403
|
|
@@ -26,7 +26,8 @@ var DEFAULT_OPTIONS = {
|
|
|
26
26
|
xDownloadOptions: true,
|
|
27
27
|
xFrameOptions: true,
|
|
28
28
|
xPermittedCrossDomainPolicies: true,
|
|
29
|
-
xXssProtection: true
|
|
29
|
+
xXssProtection: true,
|
|
30
|
+
removePoweredBy: true
|
|
30
31
|
};
|
|
31
32
|
var generateNonce = () => {
|
|
32
33
|
const buffer = new Uint8Array(16);
|
|
@@ -62,7 +63,9 @@ var secureHeaders = (customOptions) => {
|
|
|
62
63
|
const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
|
|
63
64
|
await next();
|
|
64
65
|
setHeaders(ctx, headersToSetForReq);
|
|
65
|
-
|
|
66
|
+
if (options?.removePoweredBy) {
|
|
67
|
+
ctx.res.headers.delete("X-Powered-By");
|
|
68
|
+
}
|
|
66
69
|
};
|
|
67
70
|
};
|
|
68
71
|
function getFilteredHeaders(options) {
|
package/dist/types/context.d.ts
CHANGED
|
@@ -122,7 +122,7 @@ interface JSONRespond {
|
|
|
122
122
|
*
|
|
123
123
|
* @returns {Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? (JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T>) : never, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
|
|
124
124
|
*/
|
|
125
|
-
type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> :
|
|
125
|
+
type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U, 'json'>;
|
|
126
126
|
/**
|
|
127
127
|
* Interface representing a function that responds with HTML content.
|
|
128
128
|
*
|
|
@@ -62,10 +62,6 @@ export declare class Factory<E extends Env = any, P extends string = any> {
|
|
|
62
62
|
constructor(init?: {
|
|
63
63
|
initApp?: InitApp<E>;
|
|
64
64
|
});
|
|
65
|
-
/**
|
|
66
|
-
* @experimental
|
|
67
|
-
* `createApp` is an experimental feature.
|
|
68
|
-
*/
|
|
69
65
|
createApp: () => Hono<E>;
|
|
70
66
|
createMiddleware: <I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => MiddlewareHandler<E, P, I>;
|
|
71
67
|
createHandlers: CreateHandlersInterface<E, P>;
|
|
@@ -26,7 +26,7 @@ type BearerAuthOptions = {
|
|
|
26
26
|
* @param {string | string[]} [options.token] - The string or array of strings to validate the incoming bearer token against.
|
|
27
27
|
* @param {Function} [options.verifyToken] - The function to verify the token.
|
|
28
28
|
* @param {string} [options.realm=""] - The domain name of the realm, as part of the returned WWW-Authenticate challenge header.
|
|
29
|
-
* @param {string} [options.prefix="Bearer"] - The prefix (or known as `schema`) for the Authorization header value.
|
|
29
|
+
* @param {string} [options.prefix="Bearer"] - The prefix (or known as `schema`) for the Authorization header value. If set to the empty string, no prefix is expected.
|
|
30
30
|
* @param {string} [options.headerName=Authorization] - The header name.
|
|
31
31
|
* @param {Function} [options.hashFunction] - A function to handle hashing for safe comparison of authentication tokens.
|
|
32
32
|
* @returns {MiddlewareHandler} The middleware handler function.
|
|
@@ -6,6 +6,7 @@ import type { MiddlewareHandler } from '../../types';
|
|
|
6
6
|
import type { CookiePrefixOptions } from '../../utils/cookie';
|
|
7
7
|
import '../../context';
|
|
8
8
|
import type { SignatureAlgorithm } from '../../utils/jwt/jwa';
|
|
9
|
+
import type { SignatureKey } from '../../utils/jwt/jws';
|
|
9
10
|
export type JwtVariables = {
|
|
10
11
|
jwtPayload: any;
|
|
11
12
|
};
|
|
@@ -15,7 +16,7 @@ export type JwtVariables = {
|
|
|
15
16
|
* @see {@link https://hono.dev/docs/middleware/builtin/jwt}
|
|
16
17
|
*
|
|
17
18
|
* @param {object} options - The options for the JWT middleware.
|
|
18
|
-
* @param {
|
|
19
|
+
* @param {SignatureKey} [options.secret] - A value of your secret key.
|
|
19
20
|
* @param {string} [options.cookie] - If this value is set, then the value is retrieved from the cookie header using that value as a key, which is then validated as a token.
|
|
20
21
|
* @param {SignatureAlgorithm} [options.alg=HS256] - An algorithm type that is used for verifying. Available types are `HS256` | `HS384` | `HS512` | `RS256` | `RS384` | `RS512` | `PS256` | `PS384` | `PS512` | `ES256` | `ES384` | `ES512` | `EdDSA`.
|
|
21
22
|
* @returns {MiddlewareHandler} The middleware handler function.
|
|
@@ -37,7 +38,7 @@ export type JwtVariables = {
|
|
|
37
38
|
* ```
|
|
38
39
|
*/
|
|
39
40
|
export declare const jwt: (options: {
|
|
40
|
-
secret:
|
|
41
|
+
secret: SignatureKey;
|
|
41
42
|
cookie?: string | {
|
|
42
43
|
key: string;
|
|
43
44
|
secret?: string | BufferSource;
|
|
@@ -45,9 +46,9 @@ export declare const jwt: (options: {
|
|
|
45
46
|
};
|
|
46
47
|
alg?: SignatureAlgorithm;
|
|
47
48
|
}) => MiddlewareHandler;
|
|
48
|
-
export declare const verify: (token: string, publicKey:
|
|
49
|
+
export declare const verify: (token: string, publicKey: SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<import("../../utils/jwt/types").JWTPayload>;
|
|
49
50
|
export declare const decode: (token: string) => {
|
|
50
51
|
header: import("../../utils/jwt/jwt").TokenHeader;
|
|
51
52
|
payload: import("../../utils/jwt/types").JWTPayload;
|
|
52
53
|
};
|
|
53
|
-
export declare const sign: (payload: import("../../utils/jwt/types").JWTPayload, privateKey:
|
|
54
|
+
export declare const sign: (payload: import("../../utils/jwt/types").JWTPayload, privateKey: SignatureKey, alg?: "HS256" | "HS384" | "HS512" | "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA") => Promise<string>;
|
|
@@ -62,6 +62,7 @@ interface SecureHeadersOptions {
|
|
|
62
62
|
xFrameOptions?: overridableHeader;
|
|
63
63
|
xPermittedCrossDomainPolicies?: overridableHeader;
|
|
64
64
|
xXssProtection?: overridableHeader;
|
|
65
|
+
removePoweredBy?: boolean;
|
|
65
66
|
}
|
|
66
67
|
export declare const NONCE: ContentSecurityPolicyOptionHandler;
|
|
67
68
|
/**
|
|
@@ -85,6 +86,7 @@ export declare const NONCE: ContentSecurityPolicyOptionHandler;
|
|
|
85
86
|
* @param {overridableHeader} [customOptions.xFrameOptions=true] - Settings for the X-Frame-Options header.
|
|
86
87
|
* @param {overridableHeader} [customOptions.xPermittedCrossDomainPolicies=true] - Settings for the X-Permitted-Cross-Domain-Policies header.
|
|
87
88
|
* @param {overridableHeader} [customOptions.xXssProtection=true] - Settings for the X-XSS-Protection header.
|
|
89
|
+
* @param {boolean} [customOptions.removePoweredBy=true] - Settings for remove X-Powered-By header.
|
|
88
90
|
* @returns {MiddlewareHandler} The middleware handler function.
|
|
89
91
|
*
|
|
90
92
|
* @example
|
|
@@ -11,7 +11,7 @@ export type IfAnyThenEmptyObject<T> = 0 extends 1 & T ? {} : T;
|
|
|
11
11
|
export type JSONPrimitive = string | boolean | number | null;
|
|
12
12
|
export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[];
|
|
13
13
|
export type JSONObject = {
|
|
14
|
-
[key: string]: JSONPrimitive | JSONArray | JSONObject | object;
|
|
14
|
+
[key: string]: JSONPrimitive | JSONArray | JSONObject | object | InvalidJSONValue;
|
|
15
15
|
};
|
|
16
16
|
export type InvalidJSONValue = undefined | symbol | ((...args: unknown[]) => unknown);
|
|
17
17
|
type InvalidToNull<T> = T extends InvalidJSONValue ? null : T;
|
|
@@ -27,7 +27,7 @@ export type JSONParsed<T> = T extends {
|
|
|
27
27
|
toJSON(): infer J;
|
|
28
28
|
} ? (() => J) extends () => JSONPrimitive ? J : (() => J) extends () => {
|
|
29
29
|
toJSON(): unknown;
|
|
30
|
-
} ? {} : JSONParsed<J> : T extends JSONPrimitive ? T : T extends InvalidJSONValue ? never : T extends [] ? [] : T extends readonly [infer R, ...infer U] ? [JSONParsed<InvalidToNull<R>>, ...JSONParsed<U>] : T extends Array<infer U> ? Array<JSONParsed<InvalidToNull<U>>> : T extends Set<unknown> | Map<unknown, unknown> ? {} : T extends object ? {
|
|
30
|
+
} ? {} : JSONParsed<J> : T extends JSONPrimitive ? T : T extends InvalidJSONValue ? never : T extends [] ? [] : T extends readonly [infer R, ...infer U] ? [JSONParsed<InvalidToNull<R>>, ...JSONParsed<U>] : T extends Array<infer U> ? Array<JSONParsed<InvalidToNull<U>>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<JSONParsed<InvalidToNull<U>>> : T extends Set<unknown> | Map<unknown, unknown> ? {} : T extends object ? {
|
|
31
31
|
[K in keyof OmitSymbolKeys<T> as IsInvalid<T[K]> extends true ? never : K]: boolean extends IsInvalid<T[K]> ? JSONParsed<T[K]> | undefined : JSONParsed<T[K]>;
|
|
32
32
|
} : never;
|
|
33
33
|
/**
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
import { getCookie } from "../helper/cookie/index.js";
|
|
3
3
|
import { HTTPException } from "../http-exception.js";
|
|
4
4
|
import { bufferToFormData } from "../utils/buffer.js";
|
|
5
|
+
var jsonRegex = /^application\/([a-z-\.]+\+)?json$/;
|
|
6
|
+
var multipartRegex = /^multipart\/form-data(; boundary=[A-Za-z0-9'()+_,\-./:=?]+)?$/;
|
|
7
|
+
var urlencodedRegex = /^application\/x-www-form-urlencoded$/;
|
|
5
8
|
var validator = (target, validationFunc) => {
|
|
6
9
|
return async (c, next) => {
|
|
7
10
|
let value = {};
|
|
8
11
|
const contentType = c.req.header("Content-Type");
|
|
9
12
|
switch (target) {
|
|
10
13
|
case "json":
|
|
11
|
-
if (!contentType ||
|
|
12
|
-
|
|
13
|
-
throw new HTTPException(400, { message });
|
|
14
|
+
if (!contentType || !jsonRegex.test(contentType)) {
|
|
15
|
+
break;
|
|
14
16
|
}
|
|
15
17
|
try {
|
|
16
18
|
value = await c.req.json();
|
|
@@ -20,7 +22,7 @@ var validator = (target, validationFunc) => {
|
|
|
20
22
|
}
|
|
21
23
|
break;
|
|
22
24
|
case "form": {
|
|
23
|
-
if (!contentType) {
|
|
25
|
+
if (!contentType || !(multipartRegex.test(contentType) || urlencodedRegex.test(contentType))) {
|
|
24
26
|
break;
|
|
25
27
|
}
|
|
26
28
|
let formData;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.2",
|
|
4
4
|
"description": "Web framework built on Web Standards",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,12 +25,13 @@
|
|
|
25
25
|
"format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime_tests/**/*.{js,ts,tsx}\"",
|
|
26
26
|
"format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime_tests/**/*.{js,ts,tsx}\"",
|
|
27
27
|
"copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json ",
|
|
28
|
-
"build": "
|
|
28
|
+
"build": "bun run --shell bun remove-dist && bun ./build.ts && bun run copy:package.cjs.json",
|
|
29
29
|
"postbuild": "publint",
|
|
30
|
-
"watch": "
|
|
30
|
+
"watch": "bun run --shell bun remove-dist && bun ./build.ts --watch && bun run copy:package.cjs.json",
|
|
31
31
|
"coverage": "vitest --run --coverage",
|
|
32
32
|
"prerelease": "bun test:deno && bun run build",
|
|
33
|
-
"release": "np"
|
|
33
|
+
"release": "np",
|
|
34
|
+
"remove-dist": "rm -rf dist"
|
|
34
35
|
},
|
|
35
36
|
"exports": {
|
|
36
37
|
".": {
|
|
@@ -627,7 +628,6 @@
|
|
|
627
628
|
"np": "7.7.0",
|
|
628
629
|
"prettier": "^2.6.2",
|
|
629
630
|
"publint": "^0.1.8",
|
|
630
|
-
"rimraf": "^3.0.2",
|
|
631
631
|
"supertest": "^6.3.3",
|
|
632
632
|
"typescript": "^5.3.3",
|
|
633
633
|
"vite-plugin-fastly-js-compute": "^0.4.2",
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
-
for (let key of __getOwnPropNames(from))
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
-
}
|
|
14
|
-
return to;
|
|
15
|
-
};
|
|
16
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
18
|
-
mod
|
|
19
|
-
));
|
|
20
|
-
var nodeCrypto = __toESM(require("node:crypto"), 1);
|
|
21
|
-
var import_vitest = require("vitest");
|
|
22
|
-
if (!globalThis.crypto) {
|
|
23
|
-
import_vitest.vi.stubGlobal("crypto", nodeCrypto);
|
|
24
|
-
import_vitest.vi.stubGlobal("CryptoKey", nodeCrypto.webcrypto.CryptoKey);
|
|
25
|
-
}
|
|
26
|
-
class MockCache {
|
|
27
|
-
name;
|
|
28
|
-
store;
|
|
29
|
-
constructor(name, store) {
|
|
30
|
-
this.name = name;
|
|
31
|
-
this.store = store;
|
|
32
|
-
}
|
|
33
|
-
async match(key) {
|
|
34
|
-
return this.store.get(key) || null;
|
|
35
|
-
}
|
|
36
|
-
async keys() {
|
|
37
|
-
return this.store.keys();
|
|
38
|
-
}
|
|
39
|
-
async put(key, response) {
|
|
40
|
-
this.store.set(key, response);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const globalStore = /* @__PURE__ */ new Map();
|
|
44
|
-
const caches = {
|
|
45
|
-
open: (name) => {
|
|
46
|
-
return new MockCache(name, globalStore);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
import_vitest.vi.stubGlobal("caches", caches);
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// src/test-utils/setup-vitest.ts
|
|
2
|
-
import * as nodeCrypto from "node:crypto";
|
|
3
|
-
import { vi } from "vitest";
|
|
4
|
-
if (!globalThis.crypto) {
|
|
5
|
-
vi.stubGlobal("crypto", nodeCrypto);
|
|
6
|
-
vi.stubGlobal("CryptoKey", nodeCrypto.webcrypto.CryptoKey);
|
|
7
|
-
}
|
|
8
|
-
var MockCache = class {
|
|
9
|
-
name;
|
|
10
|
-
store;
|
|
11
|
-
constructor(name, store) {
|
|
12
|
-
this.name = name;
|
|
13
|
-
this.store = store;
|
|
14
|
-
}
|
|
15
|
-
async match(key) {
|
|
16
|
-
return this.store.get(key) || null;
|
|
17
|
-
}
|
|
18
|
-
async keys() {
|
|
19
|
-
return this.store.keys();
|
|
20
|
-
}
|
|
21
|
-
async put(key, response) {
|
|
22
|
-
this.store.set(key, response);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
var globalStore = /* @__PURE__ */ new Map();
|
|
26
|
-
var caches = {
|
|
27
|
-
open: (name) => {
|
|
28
|
-
return new MockCache(name, globalStore);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
vi.stubGlobal("caches", caches);
|