hono 2.2.1 → 2.2.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/hono.js +46 -33
- package/dist/cjs/middleware/validator/middleware.js +15 -15
- package/dist/cjs/middleware/validator/validator.js +9 -1
- package/dist/hono.d.ts +21 -20
- package/dist/hono.js +46 -33
- package/dist/middleware/serve-static/bun.d.ts +3 -2
- package/dist/middleware/serve-static/module.d.mts +1 -1
- package/dist/middleware/serve-static/serve-static.d.ts +3 -2
- package/dist/middleware/validator/middleware.d.ts +7 -6
- package/dist/middleware/validator/middleware.js +15 -15
- package/dist/middleware/validator/validator.d.ts +1 -0
- package/dist/middleware/validator/validator.js +9 -1
- package/package.json +1 -1
package/dist/cjs/hono.js
CHANGED
|
@@ -29,13 +29,20 @@ class Hono extends defineDynamicClass() {
|
|
|
29
29
|
return c.text('404 Not Found', 404);
|
|
30
30
|
};
|
|
31
31
|
this.errorHandler = (err, c) => {
|
|
32
|
-
console.
|
|
32
|
+
console.trace(err.message);
|
|
33
33
|
const message = 'Internal Server Error';
|
|
34
34
|
return c.text(message, 500);
|
|
35
35
|
};
|
|
36
|
+
this.handleEvent = (event) => {
|
|
37
|
+
return this.fetch(event.request, event);
|
|
38
|
+
};
|
|
36
39
|
this.fetch = (request, Environment, executionCtx) => {
|
|
37
40
|
return this.dispatch(request, executionCtx, Environment);
|
|
38
41
|
};
|
|
42
|
+
this.request = async (input, requestInit) => {
|
|
43
|
+
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
44
|
+
return await this.fetch(req);
|
|
45
|
+
};
|
|
39
46
|
(0, request_1.extendRequestPrototype)();
|
|
40
47
|
const allMethods = [...router_1.METHODS, router_2.METHOD_NAME_ALL_LOWERCASE];
|
|
41
48
|
allMethods.map((method) => {
|
|
@@ -98,7 +105,13 @@ class Hono extends defineDynamicClass() {
|
|
|
98
105
|
matchRoute(method, path) {
|
|
99
106
|
return this.router.match(method, path);
|
|
100
107
|
}
|
|
101
|
-
|
|
108
|
+
handleError(err, c) {
|
|
109
|
+
if (err instanceof Error) {
|
|
110
|
+
return this.errorHandler(err, c);
|
|
111
|
+
}
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
dispatch(request, eventOrExecutionCtx, env) {
|
|
102
115
|
const path = (0, url_1.getPathFromURL)(request.url, this.strict);
|
|
103
116
|
const method = request.method;
|
|
104
117
|
const result = this.matchRoute(method, path);
|
|
@@ -107,46 +120,46 @@ class Hono extends defineDynamicClass() {
|
|
|
107
120
|
// Do not `compose` if it has only one handler
|
|
108
121
|
if (result && result.handlers.length === 1) {
|
|
109
122
|
const handler = result.handlers[0];
|
|
123
|
+
let res;
|
|
110
124
|
try {
|
|
111
|
-
|
|
112
|
-
if (res)
|
|
113
|
-
|
|
114
|
-
if (awaited)
|
|
115
|
-
return awaited;
|
|
116
|
-
}
|
|
117
|
-
return this.notFoundHandler(c);
|
|
125
|
+
res = handler(c, async () => { });
|
|
126
|
+
if (!res)
|
|
127
|
+
return this.notFoundHandler(c);
|
|
118
128
|
}
|
|
119
129
|
catch (err) {
|
|
120
|
-
|
|
121
|
-
return this.errorHandler(err, c);
|
|
122
|
-
}
|
|
123
|
-
throw err;
|
|
130
|
+
return this.handleError(err, c);
|
|
124
131
|
}
|
|
132
|
+
if (res instanceof Response)
|
|
133
|
+
return res;
|
|
134
|
+
return (async () => {
|
|
135
|
+
let awaited;
|
|
136
|
+
try {
|
|
137
|
+
awaited = await res;
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
return this.handleError(err, c);
|
|
141
|
+
}
|
|
142
|
+
if (!awaited) {
|
|
143
|
+
return this.notFoundHandler(c);
|
|
144
|
+
}
|
|
145
|
+
return awaited;
|
|
146
|
+
})();
|
|
125
147
|
}
|
|
126
148
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
127
149
|
const composed = (0, compose_1.compose)(handlers, this.notFoundHandler);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
return (async () => {
|
|
151
|
+
try {
|
|
152
|
+
const tmp = composed(c);
|
|
153
|
+
const context = tmp instanceof Promise ? await tmp : tmp;
|
|
154
|
+
if (!context.finalized) {
|
|
155
|
+
throw new Error('Context is not finalized. You may forget returning Response object or `await next()`');
|
|
156
|
+
}
|
|
157
|
+
return context.res;
|
|
134
158
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (err instanceof Error) {
|
|
138
|
-
return this.errorHandler(err, c);
|
|
159
|
+
catch (err) {
|
|
160
|
+
return this.handleError(err, c);
|
|
139
161
|
}
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
return context.res;
|
|
143
|
-
}
|
|
144
|
-
handleEvent(event) {
|
|
145
|
-
return this.dispatch(event.request, event);
|
|
146
|
-
}
|
|
147
|
-
request(input, requestInit) {
|
|
148
|
-
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
149
|
-
return this.dispatch(req);
|
|
162
|
+
})();
|
|
150
163
|
}
|
|
151
164
|
}
|
|
152
165
|
exports.Hono = Hono;
|
|
@@ -2,21 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validatorMiddleware = void 0;
|
|
4
4
|
const validator_1 = require("./validator");
|
|
5
|
-
function getValidatorList(schema) {
|
|
6
|
-
const map = [];
|
|
7
|
-
for (const [key, value] of Object.entries(schema)) {
|
|
8
|
-
if (value instanceof validator_1.VBase) {
|
|
9
|
-
map.push([[key], value]);
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
const children = getValidatorList(value);
|
|
13
|
-
for (const [keys, validator] of children) {
|
|
14
|
-
map.push([[key, ...keys], validator]);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return map;
|
|
19
|
-
}
|
|
20
5
|
const validatorMiddleware = (validationFunction, options) => {
|
|
21
6
|
const v = new validator_1.Validator();
|
|
22
7
|
const handler = async (c, next) => {
|
|
@@ -54,3 +39,18 @@ const validatorMiddleware = (validationFunction, options) => {
|
|
|
54
39
|
return handler;
|
|
55
40
|
};
|
|
56
41
|
exports.validatorMiddleware = validatorMiddleware;
|
|
42
|
+
function getValidatorList(schema) {
|
|
43
|
+
const map = [];
|
|
44
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
45
|
+
if (value instanceof validator_1.VBase) {
|
|
46
|
+
map.push([[key], value]);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const children = getValidatorList(value);
|
|
50
|
+
for (const [keys, validator] of children) {
|
|
51
|
+
map.push([[key, ...keys], validator]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return map;
|
|
56
|
+
}
|
|
@@ -31,6 +31,7 @@ class VBase {
|
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
33
|
this.isOptional = () => {
|
|
34
|
+
this._optional = true;
|
|
34
35
|
return this.addRule(() => true);
|
|
35
36
|
};
|
|
36
37
|
this.isEqual = (comparison) => {
|
|
@@ -101,7 +102,13 @@ class VBase {
|
|
|
101
102
|
this.validateValue = (value) => {
|
|
102
103
|
// Check type
|
|
103
104
|
if (typeof value !== this.type) {
|
|
104
|
-
|
|
105
|
+
if (this._optional && typeof value === 'undefined') {
|
|
106
|
+
// Do nothing.
|
|
107
|
+
// The value is allowed to be `undefined` if it is `optional`
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
105
112
|
}
|
|
106
113
|
// Sanitize
|
|
107
114
|
for (const sanitizer of this.sanitizers) {
|
|
@@ -119,6 +126,7 @@ class VBase {
|
|
|
119
126
|
this.type = options.type || 'string';
|
|
120
127
|
this.rules = [];
|
|
121
128
|
this.sanitizers = [];
|
|
129
|
+
this._optional = false;
|
|
122
130
|
}
|
|
123
131
|
message(value) {
|
|
124
132
|
this._message = value;
|
package/dist/hono.d.ts
CHANGED
|
@@ -18,28 +18,28 @@ export declare type Next = () => Promise<void>;
|
|
|
18
18
|
declare type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer _Pattern}` ? Name : NameWithPattern;
|
|
19
19
|
declare type ParamKey<Component> = Component extends `:${infer NameWithPattern}` ? ParamKeyName<NameWithPattern> : never;
|
|
20
20
|
declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
|
|
21
|
-
interface HandlerInterface<T extends string, E extends Partial<Environment>,
|
|
22
|
-
<Path extends string,
|
|
23
|
-
(...handlers: Handler<string, E
|
|
24
|
-
<Path extends string,
|
|
25
|
-
(path: string, ...handlers: Handler<string, E
|
|
21
|
+
interface HandlerInterface<T extends string, E extends Partial<Environment>, U = Hono<E, T>> {
|
|
22
|
+
<Path extends string, Data extends ValidatedData>(...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E, Data>[]): U;
|
|
23
|
+
(...handlers: Handler<string, E>[]): U;
|
|
24
|
+
<Path extends string, Data extends ValidatedData>(path: Path, ...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E, Data>[]): U;
|
|
25
|
+
(path: string, ...handlers: Handler<string, E>[]): U;
|
|
26
26
|
}
|
|
27
27
|
interface Route<E extends Partial<Environment> = Environment, D extends ValidatedData = ValidatedData> {
|
|
28
28
|
path: string;
|
|
29
29
|
method: string;
|
|
30
30
|
handler: Handler<string, E, D>;
|
|
31
31
|
}
|
|
32
|
-
declare const Hono_base: new <E_1 extends Partial<Environment> = Environment, T extends string = string,
|
|
33
|
-
all: HandlerInterface<T, E_1,
|
|
34
|
-
get: HandlerInterface<T, E_1,
|
|
35
|
-
post: HandlerInterface<T, E_1,
|
|
36
|
-
put: HandlerInterface<T, E_1,
|
|
37
|
-
delete: HandlerInterface<T, E_1,
|
|
38
|
-
head: HandlerInterface<T, E_1,
|
|
39
|
-
options: HandlerInterface<T, E_1,
|
|
40
|
-
patch: HandlerInterface<T, E_1,
|
|
32
|
+
declare const Hono_base: new <E_1 extends Partial<Environment> = Environment, T extends string = string, U = Hono<E_1, T, ValidatedData>>() => {
|
|
33
|
+
all: HandlerInterface<T, E_1, U>;
|
|
34
|
+
get: HandlerInterface<T, E_1, U>;
|
|
35
|
+
post: HandlerInterface<T, E_1, U>;
|
|
36
|
+
put: HandlerInterface<T, E_1, U>;
|
|
37
|
+
delete: HandlerInterface<T, E_1, U>;
|
|
38
|
+
head: HandlerInterface<T, E_1, U>;
|
|
39
|
+
options: HandlerInterface<T, E_1, U>;
|
|
40
|
+
patch: HandlerInterface<T, E_1, U>;
|
|
41
41
|
};
|
|
42
|
-
export declare class Hono<E extends Partial<Environment> = Environment, P extends string = '/', D extends ValidatedData = ValidatedData> extends Hono_base<E, P,
|
|
42
|
+
export declare class Hono<E extends Partial<Environment> = Environment, P extends string = '/', D extends ValidatedData = ValidatedData> extends Hono_base<E, P, Hono<E, P, D>> {
|
|
43
43
|
readonly router: Router<Handler<string, E, D>>;
|
|
44
44
|
readonly strict: boolean;
|
|
45
45
|
private _tempPath;
|
|
@@ -49,15 +49,16 @@ export declare class Hono<E extends Partial<Environment> = Environment, P extend
|
|
|
49
49
|
private notFoundHandler;
|
|
50
50
|
private errorHandler;
|
|
51
51
|
route(path: string, app?: Hono<any>): Hono<E, P, D>;
|
|
52
|
-
use<Path extends string = string,
|
|
53
|
-
use<Path extends string = string,
|
|
52
|
+
use<Path extends string = string, Data extends ValidatedData = D>(...middleware: Handler<Path, E, Data>[]): Hono<E, Path, Data>;
|
|
53
|
+
use<Path extends string = string, Data extends ValidatedData = D>(arg1: string, ...middleware: Handler<Path, E, Data>[]): Hono<E, Path, D>;
|
|
54
54
|
onError(handler: ErrorHandler<E>): Hono<E, P, D>;
|
|
55
55
|
notFound(handler: NotFoundHandler<E>): Hono<E, P, D>;
|
|
56
56
|
private addRoute;
|
|
57
57
|
private matchRoute;
|
|
58
|
+
private handleError;
|
|
58
59
|
private dispatch;
|
|
59
|
-
handleEvent(event: FetchEvent)
|
|
60
|
-
fetch: (request: Request, Environment?: E['Bindings'], executionCtx?: ExecutionContext) => Promise<Response>;
|
|
61
|
-
request(input: RequestInfo, requestInit?: RequestInit)
|
|
60
|
+
handleEvent: (event: FetchEvent) => Response | Promise<Response>;
|
|
61
|
+
fetch: (request: Request, Environment?: E['Bindings'], executionCtx?: ExecutionContext) => Response | Promise<Response>;
|
|
62
|
+
request: (input: RequestInfo, requestInit?: RequestInit) => Promise<Response>;
|
|
62
63
|
}
|
|
63
64
|
export {};
|
package/dist/hono.js
CHANGED
|
@@ -26,13 +26,20 @@ export class Hono extends defineDynamicClass() {
|
|
|
26
26
|
return c.text('404 Not Found', 404);
|
|
27
27
|
};
|
|
28
28
|
this.errorHandler = (err, c) => {
|
|
29
|
-
console.
|
|
29
|
+
console.trace(err.message);
|
|
30
30
|
const message = 'Internal Server Error';
|
|
31
31
|
return c.text(message, 500);
|
|
32
32
|
};
|
|
33
|
+
this.handleEvent = (event) => {
|
|
34
|
+
return this.fetch(event.request, event);
|
|
35
|
+
};
|
|
33
36
|
this.fetch = (request, Environment, executionCtx) => {
|
|
34
37
|
return this.dispatch(request, executionCtx, Environment);
|
|
35
38
|
};
|
|
39
|
+
this.request = async (input, requestInit) => {
|
|
40
|
+
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
41
|
+
return await this.fetch(req);
|
|
42
|
+
};
|
|
36
43
|
extendRequestPrototype();
|
|
37
44
|
const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
|
|
38
45
|
allMethods.map((method) => {
|
|
@@ -95,7 +102,13 @@ export class Hono extends defineDynamicClass() {
|
|
|
95
102
|
matchRoute(method, path) {
|
|
96
103
|
return this.router.match(method, path);
|
|
97
104
|
}
|
|
98
|
-
|
|
105
|
+
handleError(err, c) {
|
|
106
|
+
if (err instanceof Error) {
|
|
107
|
+
return this.errorHandler(err, c);
|
|
108
|
+
}
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
dispatch(request, eventOrExecutionCtx, env) {
|
|
99
112
|
const path = getPathFromURL(request.url, this.strict);
|
|
100
113
|
const method = request.method;
|
|
101
114
|
const result = this.matchRoute(method, path);
|
|
@@ -104,45 +117,45 @@ export class Hono extends defineDynamicClass() {
|
|
|
104
117
|
// Do not `compose` if it has only one handler
|
|
105
118
|
if (result && result.handlers.length === 1) {
|
|
106
119
|
const handler = result.handlers[0];
|
|
120
|
+
let res;
|
|
107
121
|
try {
|
|
108
|
-
|
|
109
|
-
if (res)
|
|
110
|
-
|
|
111
|
-
if (awaited)
|
|
112
|
-
return awaited;
|
|
113
|
-
}
|
|
114
|
-
return this.notFoundHandler(c);
|
|
122
|
+
res = handler(c, async () => { });
|
|
123
|
+
if (!res)
|
|
124
|
+
return this.notFoundHandler(c);
|
|
115
125
|
}
|
|
116
126
|
catch (err) {
|
|
117
|
-
|
|
118
|
-
return this.errorHandler(err, c);
|
|
119
|
-
}
|
|
120
|
-
throw err;
|
|
127
|
+
return this.handleError(err, c);
|
|
121
128
|
}
|
|
129
|
+
if (res instanceof Response)
|
|
130
|
+
return res;
|
|
131
|
+
return (async () => {
|
|
132
|
+
let awaited;
|
|
133
|
+
try {
|
|
134
|
+
awaited = await res;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return this.handleError(err, c);
|
|
138
|
+
}
|
|
139
|
+
if (!awaited) {
|
|
140
|
+
return this.notFoundHandler(c);
|
|
141
|
+
}
|
|
142
|
+
return awaited;
|
|
143
|
+
})();
|
|
122
144
|
}
|
|
123
145
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
124
146
|
const composed = compose(handlers, this.notFoundHandler);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
return (async () => {
|
|
148
|
+
try {
|
|
149
|
+
const tmp = composed(c);
|
|
150
|
+
const context = tmp instanceof Promise ? await tmp : tmp;
|
|
151
|
+
if (!context.finalized) {
|
|
152
|
+
throw new Error('Context is not finalized. You may forget returning Response object or `await next()`');
|
|
153
|
+
}
|
|
154
|
+
return context.res;
|
|
131
155
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (err instanceof Error) {
|
|
135
|
-
return this.errorHandler(err, c);
|
|
156
|
+
catch (err) {
|
|
157
|
+
return this.handleError(err, c);
|
|
136
158
|
}
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
return context.res;
|
|
140
|
-
}
|
|
141
|
-
handleEvent(event) {
|
|
142
|
-
return this.dispatch(event.request, event);
|
|
143
|
-
}
|
|
144
|
-
request(input, requestInit) {
|
|
145
|
-
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
146
|
-
return this.dispatch(req);
|
|
159
|
+
})();
|
|
147
160
|
}
|
|
148
161
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Context } from '../../context';
|
|
2
|
+
import type { Next } from '../../hono';
|
|
2
3
|
export declare type ServeStaticOptions = {
|
|
3
4
|
root?: string;
|
|
4
5
|
path?: string;
|
|
5
6
|
};
|
|
6
|
-
export declare const serveStatic: (options?: ServeStaticOptions) =>
|
|
7
|
+
export declare const serveStatic: (options?: ServeStaticOptions) => (c: Context, next: Next) => Promise<Response | undefined>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ServeStaticOptions } from './serve-static';
|
|
2
|
-
declare const module: (options?: ServeStaticOptions) => import("../../hono").
|
|
2
|
+
declare const module: (options?: ServeStaticOptions) => (c: import("../..").Context<string, any, import("../../hono").ValidatedData>, next: import("../..").Next) => Promise<Response | undefined>;
|
|
3
3
|
export { module as serveStatic };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { Context } from '../../context';
|
|
3
|
+
import type { Next } from '../../hono';
|
|
3
4
|
export declare type ServeStaticOptions = {
|
|
4
5
|
root?: string;
|
|
5
6
|
path?: string;
|
|
6
7
|
manifest?: object | string;
|
|
7
8
|
namespace?: KVNamespace;
|
|
8
9
|
};
|
|
9
|
-
export declare const serveStatic: (options?: ServeStaticOptions) =>
|
|
10
|
+
export declare const serveStatic: (options?: ServeStaticOptions) => (c: Context, next: Next) => Promise<Response | undefined>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Context } from '../../context';
|
|
2
|
-
import type { Environment,
|
|
2
|
+
import type { Environment, Next, ValidatedData } from '../../hono';
|
|
3
3
|
import { Validator } from './validator';
|
|
4
4
|
import type { VString, VNumber, VBoolean, VObject, ValidateResult } from './validator';
|
|
5
|
-
declare type ValidationFunction<T> = (v: Validator, c: Context) => T;
|
|
6
5
|
declare type Schema = {
|
|
7
6
|
[key: string]: VString | VNumber | VBoolean | VObject | Schema;
|
|
8
7
|
};
|
|
@@ -14,8 +13,10 @@ declare type ResultSet = {
|
|
|
14
13
|
messages: string[];
|
|
15
14
|
results: ValidateResult[];
|
|
16
15
|
};
|
|
17
|
-
declare type Done = (resultSet: ResultSet, context: Context) => Response | void;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
declare type Done<Env extends Partial<Environment>> = (resultSet: ResultSet, context: Context<string, Env>) => Response | void;
|
|
17
|
+
declare type ValidationFunction<T, Env extends Partial<Environment>> = (v: Validator, c: Context<string, Env>) => T;
|
|
18
|
+
declare type MiddlewareHandler<Data extends ValidatedData = ValidatedData, Env extends Partial<Environment> = Environment> = (c: Context<string, Env, Data>, next: Next) => Promise<void> | Promise<Response | undefined>;
|
|
19
|
+
export declare const validatorMiddleware: <T extends Schema, Env extends Partial<Environment>>(validationFunction: ValidationFunction<T, Env>, options?: {
|
|
20
|
+
done?: Done<Env> | undefined;
|
|
21
|
+
} | undefined) => MiddlewareHandler<SchemaToProp<T>, Env>;
|
|
21
22
|
export {};
|
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
import { VBase, Validator } from './validator';
|
|
2
|
-
function getValidatorList(schema) {
|
|
3
|
-
const map = [];
|
|
4
|
-
for (const [key, value] of Object.entries(schema)) {
|
|
5
|
-
if (value instanceof VBase) {
|
|
6
|
-
map.push([[key], value]);
|
|
7
|
-
}
|
|
8
|
-
else {
|
|
9
|
-
const children = getValidatorList(value);
|
|
10
|
-
for (const [keys, validator] of children) {
|
|
11
|
-
map.push([[key, ...keys], validator]);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return map;
|
|
16
|
-
}
|
|
17
2
|
export const validatorMiddleware = (validationFunction, options) => {
|
|
18
3
|
const v = new Validator();
|
|
19
4
|
const handler = async (c, next) => {
|
|
@@ -50,3 +35,18 @@ export const validatorMiddleware = (validationFunction, options) => {
|
|
|
50
35
|
};
|
|
51
36
|
return handler;
|
|
52
37
|
};
|
|
38
|
+
function getValidatorList(schema) {
|
|
39
|
+
const map = [];
|
|
40
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
41
|
+
if (value instanceof VBase) {
|
|
42
|
+
map.push([[key], value]);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const children = getValidatorList(value);
|
|
46
|
+
for (const [keys, validator] of children) {
|
|
47
|
+
map.push([[key, ...keys], validator]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return map;
|
|
52
|
+
}
|
|
@@ -27,6 +27,7 @@ export class VBase {
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
this.isOptional = () => {
|
|
30
|
+
this._optional = true;
|
|
30
31
|
return this.addRule(() => true);
|
|
31
32
|
};
|
|
32
33
|
this.isEqual = (comparison) => {
|
|
@@ -97,7 +98,13 @@ export class VBase {
|
|
|
97
98
|
this.validateValue = (value) => {
|
|
98
99
|
// Check type
|
|
99
100
|
if (typeof value !== this.type) {
|
|
100
|
-
|
|
101
|
+
if (this._optional && typeof value === 'undefined') {
|
|
102
|
+
// Do nothing.
|
|
103
|
+
// The value is allowed to be `undefined` if it is `optional`
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
101
108
|
}
|
|
102
109
|
// Sanitize
|
|
103
110
|
for (const sanitizer of this.sanitizers) {
|
|
@@ -115,6 +122,7 @@ export class VBase {
|
|
|
115
122
|
this.type = options.type || 'string';
|
|
116
123
|
this.rules = [];
|
|
117
124
|
this.sanitizers = [];
|
|
125
|
+
this._optional = false;
|
|
118
126
|
}
|
|
119
127
|
message(value) {
|
|
120
128
|
this._message = value;
|