hono 2.2.5 → 2.3.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.
@@ -1,30 +1,113 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VBooleanArray = exports.VStringArray = exports.VNumberArray = exports.VObject = exports.VBoolean = exports.VNumber = exports.VString = exports.VBase = exports.Validator = void 0;
3
+ exports.VBooleanArray = exports.VStringArray = exports.VNumberArray = exports.VBoolean = exports.VNumber = exports.VString = exports.VBase = exports.Validator = exports.VArray = exports.VObject = exports.VObjectBase = void 0;
4
4
  const json_1 = require("../../utils/json");
5
5
  const rule_1 = require("./rule");
6
6
  const sanitizer_1 = require("./sanitizer");
7
+ class VObjectBase {
8
+ constructor(container, key) {
9
+ this.keys = [];
10
+ this._isOptional = false;
11
+ this.getValidators = () => {
12
+ const validators = [];
13
+ const thisKeys = [];
14
+ Object.assign(thisKeys, this.keys);
15
+ const walk = (container, keys, isOptional) => {
16
+ for (const v of Object.values(container)) {
17
+ if (v instanceof VArray || v instanceof VObject) {
18
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
19
+ // @ts-ignore
20
+ isOptional || (isOptional = v._isOptional);
21
+ keys.push(...v.keys);
22
+ walk(v.container, keys, isOptional);
23
+ const tmp = [];
24
+ Object.assign(tmp, thisKeys);
25
+ keys = tmp;
26
+ }
27
+ else if (v instanceof VBase) {
28
+ if (isOptional)
29
+ v.isOptional();
30
+ v.baseKeys.push(...keys);
31
+ validators.push(v);
32
+ }
33
+ }
34
+ };
35
+ walk(this.container, this.keys, this._isOptional);
36
+ return validators;
37
+ };
38
+ this.container = container;
39
+ if (this instanceof VArray) {
40
+ this.keys.push(key, '[*]');
41
+ }
42
+ else if (this instanceof VObject) {
43
+ this.keys.push(key);
44
+ }
45
+ }
46
+ isOptional() {
47
+ this._isOptional = true;
48
+ return this;
49
+ }
50
+ }
51
+ exports.VObjectBase = VObjectBase;
52
+ class VObject extends VObjectBase {
53
+ constructor(container, key) {
54
+ super(container, key);
55
+ }
56
+ }
57
+ exports.VObject = VObject;
58
+ class VArray extends VObjectBase {
59
+ constructor(container, key) {
60
+ super(container, key);
61
+ this.type = 'array';
62
+ }
63
+ }
64
+ exports.VArray = VArray;
7
65
  class Validator {
8
66
  constructor() {
67
+ this.isArray = false;
9
68
  this.query = (key) => new VString({ target: 'query', key: key });
10
69
  this.header = (key) => new VString({ target: 'header', key: key });
11
70
  this.body = (key) => new VString({ target: 'body', key: key });
12
- this.json = (key) => new VString({ target: 'json', key: key });
71
+ this.json = (key) => {
72
+ if (this.isArray) {
73
+ return new VStringArray({ target: 'json', key: key });
74
+ }
75
+ else {
76
+ return new VString({ target: 'json', key: key });
77
+ }
78
+ };
79
+ this.array = (path, validator) => {
80
+ this.isArray = true;
81
+ const res = validator(this);
82
+ const arr = new VArray(res, path);
83
+ return arr;
84
+ };
85
+ this.object = (path, validator) => {
86
+ this.isArray = false;
87
+ const res = validator(this);
88
+ const obj = new VObject(res, path);
89
+ return obj;
90
+ };
13
91
  }
14
92
  }
15
93
  exports.Validator = Validator;
16
94
  class VBase {
17
95
  constructor(options) {
18
- this.addRule = (rule) => {
19
- this.rules.push(rule);
20
- return this;
21
- };
96
+ this.baseKeys = [];
97
+ this._nested = () => (this.baseKeys.length ? true : false);
22
98
  this.addSanitizer = (sanitizer) => {
23
99
  this.sanitizers.push(sanitizer);
24
100
  return this;
25
101
  };
102
+ this.message = (text) => {
103
+ const len = this.rules.length;
104
+ if (len >= 1) {
105
+ this.rules[len - 1].customMessage = text;
106
+ }
107
+ return this;
108
+ };
26
109
  this.isRequired = () => {
27
- return this.addRule((value) => {
110
+ return this.addRule('isRequired', (value) => {
28
111
  if (value !== undefined && value !== null && value !== '')
29
112
  return true;
30
113
  return false;
@@ -32,34 +115,28 @@ class VBase {
32
115
  };
33
116
  this.isOptional = () => {
34
117
  this._optional = true;
35
- return this.addRule(() => true);
118
+ return this.addRule('isOptional', () => true);
36
119
  };
37
120
  this.isEqual = (comparison) => {
38
- return this.addRule((value) => {
121
+ return this.addRule('isEqual', (value) => {
39
122
  return value === comparison;
40
123
  });
41
124
  };
42
125
  this.asNumber = () => {
43
- const newVNumber = new VNumber(this);
126
+ const newVNumber = new VNumber({ ...this, type: 'number' });
127
+ if (this.isArray)
128
+ return newVNumber.asArray();
44
129
  return newVNumber;
45
130
  };
46
131
  this.asBoolean = () => {
47
- const newVBoolean = new VBoolean(this);
132
+ const newVBoolean = new VBoolean({ ...this, type: 'boolean' });
133
+ if (this.isArray)
134
+ return newVBoolean.asArray();
48
135
  return newVBoolean;
49
136
  };
50
- this.asObject = () => {
51
- const newVObject = new VObject(this);
52
- return newVObject;
53
- };
54
137
  this.validate = async (req) => {
55
- const result = {
56
- isValid: true,
57
- message: undefined,
58
- target: this.target,
59
- key: this.key,
60
- value: undefined,
61
- };
62
138
  let value = undefined;
139
+ let jsonData = undefined;
63
140
  if (this.target === 'query') {
64
141
  value = req.query(this.key);
65
142
  }
@@ -71,105 +148,178 @@ class VBase {
71
148
  value = body[this.key];
72
149
  }
73
150
  if (this.target === 'json') {
151
+ if (this._nested()) {
152
+ this.key = `${this.baseKeys.join('.')}.${this.key}`;
153
+ }
154
+ let obj = {};
74
155
  try {
75
- const obj = (await req.json());
76
- value = (0, json_1.JSONPath)(obj, this.key);
156
+ obj = (await req.json());
77
157
  }
78
158
  catch (e) {
79
159
  throw new Error('Malformed JSON in request body');
80
160
  }
161
+ const dst = {};
162
+ value = (0, json_1.JSONPathCopy)(obj, dst, this.key);
163
+ if (this._nested())
164
+ jsonData = dst;
81
165
  }
82
- result.value = value;
83
- result.isValid = this.validateValue(value);
84
- if (result.isValid === false) {
85
- if (this._message) {
86
- result.message = this._message;
166
+ const results = [];
167
+ let typeRule = this.rules.shift();
168
+ for (const rule of this.rules) {
169
+ if (rule.type === 'type') {
170
+ typeRule = rule;
87
171
  }
88
- else {
89
- const valToStr = Array.isArray(value)
90
- ? `[${value
91
- .map((val) => val === undefined ? 'undefined' : typeof val === 'string' ? `"${val}"` : val)
92
- .join(', ')}]`
93
- : value;
94
- switch (this.target) {
95
- case 'query':
96
- result.message = `Invalid Value: the query parameter "${this.key}" is invalid - ${valToStr}`;
97
- break;
98
- case 'header':
99
- result.message = `Invalid Value: the request header "${this.key}" is invalid - ${valToStr}`;
100
- break;
101
- case 'body':
102
- result.message = `Invalid Value: the request body "${this.key}" is invalid - ${valToStr}`;
103
- break;
104
- case 'json':
105
- result.message = `Invalid Value: the JSON body "${this.key}" is invalid - ${valToStr}`;
106
- break;
107
- }
172
+ else if (rule.type === 'value') {
173
+ const result = this.validateRule(rule, value);
174
+ result.jsonData || (result.jsonData = jsonData);
175
+ results.push(result);
108
176
  }
109
177
  }
110
- return result;
178
+ if (typeRule) {
179
+ const typeResult = this.validateRule(typeRule, value);
180
+ typeResult.jsonData || (typeResult.jsonData = jsonData);
181
+ results.unshift(typeResult);
182
+ }
183
+ return results;
111
184
  };
112
- this.validateValue = (value) => {
113
- // Check type
185
+ this.validateType = (value) => {
114
186
  if (this.isArray) {
115
187
  if (!Array.isArray(value)) {
116
188
  return false;
117
189
  }
118
190
  for (const val of value) {
119
- if (typeof val !== this.type) {
120
- // Value is of wrong type here
121
- // If not optional, or optional and not undefined, return false
122
- if (!this._optional || typeof val !== 'undefined')
123
- return false;
191
+ if (typeof val === 'undefined' && this._nested()) {
192
+ value.pop();
124
193
  }
125
- }
126
- // Sanitize
127
- for (const sanitizer of this.sanitizers) {
128
- value = value.map((innerVal) => sanitizer(innerVal));
129
- }
130
- for (const rule of this.rules) {
131
194
  for (const val of value) {
132
- if (!rule(val)) {
133
- return false;
195
+ if (typeof val !== this.type) {
196
+ // Value is of wrong type here
197
+ // If it is not optional and not undefined, return false
198
+ if (!this._optional || typeof val !== 'undefined')
199
+ return false;
134
200
  }
135
201
  }
136
202
  }
137
- return true;
138
203
  }
139
204
  else {
140
205
  if (typeof value !== this.type) {
141
- if (this._optional && typeof value === 'undefined') {
206
+ if (this._optional && (typeof value === 'undefined' || Array.isArray(value))) {
142
207
  // Do nothing.
143
- // The value is allowed to be `undefined` if it is `optional`
208
+ // If it is optional it's OK to be `undefined` or Array
144
209
  }
145
210
  else {
146
211
  return false;
147
212
  }
148
213
  }
214
+ }
215
+ return true;
216
+ };
217
+ this.validateValue = (func, value) => {
218
+ if (Array.isArray(value)) {
149
219
  // Sanitize
150
220
  for (const sanitizer of this.sanitizers) {
151
- value = sanitizer(value);
221
+ value = value.map((innerVal) => sanitizer(innerVal));
152
222
  }
153
- for (const rule of this.rules) {
154
- if (!rule(value)) {
223
+ for (const val of value) {
224
+ if (!func(val)) {
155
225
  return false;
156
226
  }
157
227
  }
158
228
  return true;
159
229
  }
230
+ else {
231
+ // Sanitize
232
+ for (const sanitizer of this.sanitizers) {
233
+ value = sanitizer(value);
234
+ }
235
+ if (!func(value)) {
236
+ return false;
237
+ }
238
+ return true;
239
+ }
240
+ };
241
+ this.getMessage = (opts) => {
242
+ let keyText;
243
+ const valueText = Array.isArray(opts.value)
244
+ ? `${opts.value
245
+ .map((val) => val === undefined ? 'undefined' : typeof val === 'string' ? `"${val}"` : val)
246
+ .join(', ')}`
247
+ : opts.value;
248
+ switch (this.target) {
249
+ case 'query':
250
+ keyText = `the query parameter "${this.key}"`;
251
+ break;
252
+ case 'header':
253
+ keyText = `the request header "${this.key}"`;
254
+ break;
255
+ case 'body':
256
+ keyText = `the request body "${this.key}"`;
257
+ break;
258
+ case 'json':
259
+ keyText = `the JSON body "${this.key}"`;
260
+ break;
261
+ }
262
+ return `Invalid Value [${valueText}]: ${keyText} is invalid - ${opts.ruleName}`;
160
263
  };
161
264
  this.target = options.target;
162
265
  this.key = options.key;
163
266
  this.type = options.type || 'string';
164
- this.rules = [];
267
+ this.rules = [
268
+ {
269
+ name: this.getTypeRuleName(),
270
+ type: 'type',
271
+ func: this.validateType,
272
+ },
273
+ ];
165
274
  this.sanitizers = [];
166
- this.isArray = options.isArray || false;
167
275
  this._optional = false;
276
+ this.isArray = options.isArray || false;
277
+ }
278
+ addRule(arg, func) {
279
+ if (typeof arg === 'string' && func) {
280
+ this.rules.push({ name: arg, func, type: 'value' });
281
+ }
282
+ else if (arg instanceof Function) {
283
+ this.rules.push({ name: arg.name, func: arg, type: 'value' });
284
+ }
285
+ return this;
168
286
  }
169
- message(value) {
170
- this._message = value;
287
+ get(value) {
288
+ const len = this.rules.length;
289
+ if (len > 0) {
290
+ this.rules[this.rules.length - 1].customMessage = value;
291
+ }
171
292
  return this;
172
293
  }
294
+ getTypeRuleName() {
295
+ const prefix = 'should be';
296
+ return this.isArray ? `${prefix} "${this.type}[]"` : `${prefix} "${this.type}"`;
297
+ }
298
+ validateRule(rule, value) {
299
+ let isValid = false;
300
+ if (this._nested() && this.target != 'json') {
301
+ isValid = false;
302
+ }
303
+ else if (rule.type === 'value') {
304
+ isValid = this.validateValue(rule.func, value);
305
+ }
306
+ else if (rule.type === 'type') {
307
+ isValid = this.validateType(value);
308
+ }
309
+ const message = isValid
310
+ ? undefined
311
+ : rule.customMessage || this.getMessage({ ruleName: rule.name, value });
312
+ const result = {
313
+ isValid: isValid,
314
+ message: message,
315
+ target: this.target,
316
+ key: this.key,
317
+ value,
318
+ ruleName: rule.name,
319
+ ruleType: rule.type,
320
+ };
321
+ return result;
322
+ }
173
323
  }
174
324
  exports.VBase = VBase;
175
325
  class VString extends VBase {
@@ -179,28 +329,28 @@ class VString extends VBase {
179
329
  return new VStringArray(this);
180
330
  };
181
331
  this.isEmpty = (options = { ignore_whitespace: false }) => {
182
- return this.addRule((value) => rule_1.rule.isEmpty(value, options));
332
+ return this.addRule('isEmpty', (value) => rule_1.rule.isEmpty(value, options));
183
333
  };
184
334
  this.isLength = (options, arg2) => {
185
- return this.addRule((value) => rule_1.rule.isLength(value, options, arg2));
335
+ return this.addRule('isLength', (value) => rule_1.rule.isLength(value, options, arg2));
186
336
  };
187
337
  this.isAlpha = () => {
188
- return this.addRule((value) => rule_1.rule.isAlpha(value));
338
+ return this.addRule('isAlpha', (value) => rule_1.rule.isAlpha(value));
189
339
  };
190
340
  this.isNumeric = () => {
191
- return this.addRule((value) => rule_1.rule.isNumeric(value));
341
+ return this.addRule('isNumeric', (value) => rule_1.rule.isNumeric(value));
192
342
  };
193
343
  this.contains = (elem, options = {
194
344
  ignoreCase: false,
195
345
  minOccurrences: 1,
196
346
  }) => {
197
- return this.addRule((value) => rule_1.rule.contains(value, elem, options));
347
+ return this.addRule('contains', (value) => rule_1.rule.contains(value, elem, options));
198
348
  };
199
349
  this.isIn = (options) => {
200
- return this.addRule((value) => rule_1.rule.isIn(value, options));
350
+ return this.addRule('isIn', (value) => rule_1.rule.isIn(value, options));
201
351
  };
202
352
  this.match = (regExp) => {
203
- return this.addRule((value) => rule_1.rule.match(value, regExp));
353
+ return this.addRule('match', (value) => rule_1.rule.match(value, regExp));
204
354
  };
205
355
  this.trim = () => {
206
356
  return this.addSanitizer((value) => sanitizer_1.sanitizer.trim(value));
@@ -216,10 +366,10 @@ class VNumber extends VBase {
216
366
  return new VNumberArray(this);
217
367
  };
218
368
  this.isGte = (min) => {
219
- return this.addRule((value) => rule_1.rule.isGte(value, min));
369
+ return this.addRule('isGte', (value) => rule_1.rule.isGte(value, min));
220
370
  };
221
371
  this.isLte = (min) => {
222
- return this.addRule((value) => rule_1.rule.isLte(value, min));
372
+ return this.addRule('isLte', (value) => rule_1.rule.isLte(value, min));
223
373
  };
224
374
  this.type = 'number';
225
375
  }
@@ -232,26 +382,20 @@ class VBoolean extends VBase {
232
382
  return new VBooleanArray(this);
233
383
  };
234
384
  this.isTrue = () => {
235
- return this.addRule((value) => rule_1.rule.isTrue(value));
385
+ return this.addRule('isTrue', (value) => rule_1.rule.isTrue(value));
236
386
  };
237
387
  this.isFalse = () => {
238
- return this.addRule((value) => rule_1.rule.isFalse(value));
388
+ return this.addRule('isFalse', (value) => rule_1.rule.isFalse(value));
239
389
  };
240
390
  this.type = 'boolean';
241
391
  }
242
392
  }
243
393
  exports.VBoolean = VBoolean;
244
- class VObject extends VBase {
245
- constructor(options) {
246
- super(options);
247
- this.type = 'object';
248
- }
249
- }
250
- exports.VObject = VObject;
251
394
  class VNumberArray extends VNumber {
252
395
  constructor(options) {
253
396
  super(options);
254
397
  this.isArray = true;
398
+ this.rules[0].name = this.getTypeRuleName();
255
399
  }
256
400
  }
257
401
  exports.VNumberArray = VNumberArray;
@@ -259,6 +403,7 @@ class VStringArray extends VString {
259
403
  constructor(options) {
260
404
  super(options);
261
405
  this.isArray = true;
406
+ this.rules[0].name = this.getTypeRuleName();
262
407
  }
263
408
  }
264
409
  exports.VStringArray = VStringArray;
@@ -266,6 +411,7 @@ class VBooleanArray extends VBoolean {
266
411
  constructor(options) {
267
412
  super(options);
268
413
  this.isArray = true;
414
+ this.rules[0].name = this.getTypeRuleName();
269
415
  }
270
416
  }
271
417
  exports.VBooleanArray = VBooleanArray;
@@ -1,33 +1,87 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JSONPath = void 0;
4
- const JSONPathInternal = (data, parts) => {
3
+ exports.JSONPathCopy = void 0;
4
+ const JSONPathCopyInternal = (src, dst, parts, results) => {
5
+ let srcVal = src;
6
+ let dstVal = dst;
5
7
  const length = parts.length;
6
- for (let i = 0; i < length && data !== undefined; i++) {
8
+ for (let i = 0; i < length && srcVal !== undefined && dstVal; i++) {
7
9
  const p = parts[i];
8
- if (p === '') {
9
- continue;
10
+ if (typeof srcVal !== 'object') {
11
+ return srcVal;
10
12
  }
11
- if (typeof data !== 'object' || data === null) {
13
+ if (srcVal === null) {
12
14
  return undefined;
13
15
  }
14
16
  if (p === '*') {
15
17
  const restParts = parts.slice(i + 1);
16
- const values = Object.values(data).map((v) => JSONPathInternal(v, restParts));
17
- return restParts.indexOf('*') === -1 ? values : values.flat();
18
+ const restLength = srcVal.length;
19
+ if (restLength === undefined) {
20
+ parts = Object.keys(srcVal);
21
+ for (const p of parts) {
22
+ const srcVal2 = srcVal;
23
+ const dst2 = {};
24
+ JSONPathCopyInternal(srcVal2, dst2, [p], results);
25
+ dstVal[p] = dst2[p];
26
+ }
27
+ }
28
+ else {
29
+ const res = [];
30
+ for (let i2 = 0; i2 < restLength; i2++) {
31
+ if (typeof srcVal[i2] !== 'object' || srcVal[i2] === undefined) {
32
+ res.push(srcVal[i2]);
33
+ }
34
+ else {
35
+ const srcVal2 = srcVal[i2];
36
+ const dst2 = {};
37
+ const res2 = JSONPathCopyInternal(srcVal2, dst2, restParts, results);
38
+ if (res2 === undefined)
39
+ results.push(undefined);
40
+ dstVal[i2] = dst2;
41
+ }
42
+ }
43
+ if (res.length) {
44
+ Object.assign(dstVal, srcVal);
45
+ results.push(...res);
46
+ }
47
+ }
48
+ return results;
49
+ }
50
+ if (typeof srcVal[p] === 'object') {
51
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
52
+ // @ts-ignore
53
+ dstVal[p] || (dstVal[p] = new srcVal[p].constructor());
54
+ }
55
+ else if (typeof srcVal[p] !== 'undefined') {
56
+ dstVal[p] = srcVal[p];
18
57
  }
19
58
  else {
20
- data = data[p]; // `data` may be an array, but accessing it as an object yields the same result.
59
+ return undefined;
21
60
  }
61
+ srcVal = srcVal[p];
62
+ dstVal = dstVal[p];
63
+ }
64
+ if (typeof srcVal === 'object' && dstVal) {
65
+ Object.assign(dstVal, srcVal);
22
66
  }
23
- return data;
67
+ results.push(srcVal);
68
+ return results;
24
69
  };
25
- const JSONPath = (data, path) => {
70
+ const JSONPathCopy = (src, dst, path) => {
71
+ const results = [];
72
+ const parts = path.replace(/\.?\[(.*?)\]/g, '.$1').split(/\./);
26
73
  try {
27
- return JSONPathInternal(data, path.replace(/\[(.*?)\]/g, '.$1').split(/\./));
74
+ JSONPathCopyInternal(src, dst, parts, results);
75
+ if (results.length === 0) {
76
+ return undefined;
77
+ }
78
+ else if (results.length === 1 && !parts.includes('*')) {
79
+ return results[0];
80
+ }
81
+ return results;
28
82
  }
29
83
  catch (e) {
30
84
  return undefined;
31
85
  }
32
86
  };
33
- exports.JSONPath = JSONPath;
87
+ exports.JSONPathCopy = JSONPathCopy;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeObjects = exports.isObject = void 0;
4
+ /* eslint-disable @typescript-eslint/no-explicit-any */
5
+ const isObject = (val) => val && typeof val === 'object' && !Array.isArray(val);
6
+ exports.isObject = isObject;
7
+ const mergeObjects = (target, source) => {
8
+ const merged = Object.assign({}, target);
9
+ if ((0, exports.isObject)(target) && (0, exports.isObject)(source)) {
10
+ for (const key of Object.keys(source)) {
11
+ if ((0, exports.isObject)(source[key])) {
12
+ if (target[key] === undefined)
13
+ Object.assign(merged, { [key]: source[key] });
14
+ else
15
+ merged[key] = (0, exports.mergeObjects)(target[key], source[key]);
16
+ }
17
+ else if (Array.isArray(source[key]) && Array.isArray(target[key])) {
18
+ const srcArr = source[key];
19
+ const tgtArr = target[key];
20
+ const outArr = [];
21
+ for (let i = 0; i < srcArr.length; i += 1) {
22
+ // If corresponding index for both arrays is an object, then merge them
23
+ // Otherwise just copy src arr index into out arr index
24
+ if ((0, exports.isObject)(srcArr[i]) && (0, exports.isObject)(tgtArr[i])) {
25
+ outArr[i] = (0, exports.mergeObjects)(tgtArr[i], srcArr[i]);
26
+ }
27
+ else {
28
+ outArr[i] = srcArr[i];
29
+ }
30
+ }
31
+ Object.assign(merged, { [key]: outArr });
32
+ }
33
+ else {
34
+ Object.assign(merged, { [key]: source[key] });
35
+ }
36
+ }
37
+ }
38
+ return merged;
39
+ };
40
+ exports.mergeObjects = mergeObjects;
package/dist/hono.d.ts CHANGED
@@ -10,7 +10,7 @@ export declare type Environment = {
10
10
  Variables: Variables;
11
11
  };
12
12
  export declare type ValidatedData = Record<string, any>;
13
- export declare type Handler<RequestParamKeyType extends string = string, E extends Partial<Environment> = Environment, D extends ValidatedData = ValidatedData> = (c: Context<RequestParamKeyType, E, D>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>;
13
+ export declare type Handler<RequestParamKeyType extends string = string, E extends Partial<Environment> = Environment, D extends ValidatedData = ValidatedData> = (c: Context<RequestParamKeyType, E, D>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined | void>;
14
14
  export declare type MiddlewareHandler = <E extends Partial<Environment> = Environment>(c: Context<string, E>, next: Next) => Promise<void> | Promise<Response | undefined>;
15
15
  export declare type NotFoundHandler<E extends Partial<Environment> = Environment> = (c: Context<string, E>) => Response | Promise<Response>;
16
16
  export declare type ErrorHandler<E extends Partial<Environment> = Environment> = (err: Error, c: Context<string, E>) => Response;
@@ -33,12 +33,11 @@ export const basicAuth = (options, ...users) => {
33
33
  }
34
34
  }
35
35
  }
36
- ctx.res = new Response('Unauthorized', {
36
+ return new Response('Unauthorized', {
37
37
  status: 401,
38
38
  headers: {
39
39
  'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"',
40
40
  },
41
41
  });
42
- await next();
43
42
  };
44
43
  };