@bepalo/spine 1.5.17 → 2.7.19

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.
Files changed (110) hide show
  1. package/README.md +532 -1
  2. package/dist/auth-middlewares.d.ts.map +1 -1
  3. package/dist/auth-middlewares.js +1 -0
  4. package/dist/auth-middlewares.js.map +1 -1
  5. package/dist/cache.d.ts +72 -0
  6. package/dist/cache.d.ts.map +1 -0
  7. package/dist/cache.js +387 -0
  8. package/dist/cache.js.map +1 -0
  9. package/dist/cjs/auth-middlewares.d.ts.map +1 -1
  10. package/dist/cjs/auth-middlewares.js +1 -0
  11. package/dist/cjs/auth-middlewares.js.map +1 -1
  12. package/dist/cjs/cache.d.ts +72 -0
  13. package/dist/cjs/cache.d.ts.map +1 -0
  14. package/dist/cjs/cache.js +387 -0
  15. package/dist/cjs/cache.js.map +1 -0
  16. package/dist/cjs/exp-cache.d.ts +101 -0
  17. package/dist/cjs/exp-cache.d.ts.map +1 -0
  18. package/dist/cjs/exp-cache.js +551 -0
  19. package/dist/cjs/exp-cache.js.map +1 -0
  20. package/dist/cjs/generator.d.ts +142 -19
  21. package/dist/cjs/generator.d.ts.map +1 -1
  22. package/dist/cjs/generator.js +416 -36
  23. package/dist/cjs/generator.js.map +1 -1
  24. package/dist/cjs/helpers.d.ts +49 -2
  25. package/dist/cjs/helpers.d.ts.map +1 -1
  26. package/dist/cjs/helpers.js +169 -14
  27. package/dist/cjs/helpers.js.map +1 -1
  28. package/dist/cjs/index.d.ts +2 -0
  29. package/dist/cjs/index.d.ts.map +1 -1
  30. package/dist/cjs/index.js +3 -0
  31. package/dist/cjs/index.js.map +1 -1
  32. package/dist/cjs/linked-list.d.ts +35 -0
  33. package/dist/cjs/linked-list.d.ts.map +1 -0
  34. package/dist/cjs/linked-list.js +300 -0
  35. package/dist/cjs/linked-list.js.map +1 -0
  36. package/dist/cjs/middlewares.d.ts +264 -28
  37. package/dist/cjs/middlewares.d.ts.map +1 -1
  38. package/dist/cjs/middlewares.js +691 -44
  39. package/dist/cjs/middlewares.js.map +1 -1
  40. package/dist/cjs/parsers.d.ts +32 -10
  41. package/dist/cjs/parsers.d.ts.map +1 -1
  42. package/dist/cjs/parsers.js +84 -46
  43. package/dist/cjs/parsers.js.map +1 -1
  44. package/dist/cjs/router.d.ts +5 -6
  45. package/dist/cjs/router.d.ts.map +1 -1
  46. package/dist/cjs/router.js +272 -149
  47. package/dist/cjs/router.js.map +1 -1
  48. package/dist/cjs/status.d.ts.map +1 -1
  49. package/dist/cjs/status.js +80 -79
  50. package/dist/cjs/status.js.map +1 -1
  51. package/dist/cjs/types.d.ts +74 -2
  52. package/dist/cjs/types.d.ts.map +1 -1
  53. package/dist/cjs/types.js +15 -2
  54. package/dist/cjs/types.js.map +1 -1
  55. package/dist/cjs/utils.d.ts +1 -0
  56. package/dist/cjs/utils.d.ts.map +1 -1
  57. package/dist/cjs/utils.js +1 -0
  58. package/dist/cjs/utils.js.map +1 -1
  59. package/dist/cjs/utils.node.d.ts +1 -1
  60. package/dist/cjs/utils.node.d.ts.map +1 -1
  61. package/dist/cjs/utils.node.js +31 -7
  62. package/dist/cjs/utils.node.js.map +1 -1
  63. package/dist/exp-cache.d.ts +101 -0
  64. package/dist/exp-cache.d.ts.map +1 -0
  65. package/dist/exp-cache.js +551 -0
  66. package/dist/exp-cache.js.map +1 -0
  67. package/dist/generator.d.ts +142 -19
  68. package/dist/generator.d.ts.map +1 -1
  69. package/dist/generator.js +416 -36
  70. package/dist/generator.js.map +1 -1
  71. package/dist/helpers.d.ts +49 -2
  72. package/dist/helpers.d.ts.map +1 -1
  73. package/dist/helpers.js +169 -14
  74. package/dist/helpers.js.map +1 -1
  75. package/dist/index.d.ts +2 -0
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +3 -0
  78. package/dist/index.js.map +1 -1
  79. package/dist/linked-list.d.ts +35 -0
  80. package/dist/linked-list.d.ts.map +1 -0
  81. package/dist/linked-list.js +300 -0
  82. package/dist/linked-list.js.map +1 -0
  83. package/dist/middlewares.d.ts +264 -28
  84. package/dist/middlewares.d.ts.map +1 -1
  85. package/dist/middlewares.js +691 -44
  86. package/dist/middlewares.js.map +1 -1
  87. package/dist/parsers.d.ts +32 -10
  88. package/dist/parsers.d.ts.map +1 -1
  89. package/dist/parsers.js +84 -46
  90. package/dist/parsers.js.map +1 -1
  91. package/dist/router.d.ts +5 -6
  92. package/dist/router.d.ts.map +1 -1
  93. package/dist/router.js +272 -149
  94. package/dist/router.js.map +1 -1
  95. package/dist/status.d.ts.map +1 -1
  96. package/dist/status.js +80 -79
  97. package/dist/status.js.map +1 -1
  98. package/dist/types.d.ts +74 -2
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +15 -2
  101. package/dist/types.js.map +1 -1
  102. package/dist/utils.d.ts +1 -0
  103. package/dist/utils.d.ts.map +1 -1
  104. package/dist/utils.js +1 -0
  105. package/dist/utils.js.map +1 -1
  106. package/dist/utils.node.d.ts +1 -1
  107. package/dist/utils.node.d.ts.map +1 -1
  108. package/dist/utils.node.js +31 -7
  109. package/dist/utils.node.js.map +1 -1
  110. package/package.json +6 -2
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ // src/middlewares.ts
2
3
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
4
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
5
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -9,23 +10,123 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
10
  });
10
11
  };
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.cors = exports.limitRate = void 0;
13
+ exports.validate = exports.cors = exports.limitRate = exports.securityHeaders = exports.forceHttps = void 0;
13
14
  const helpers_ts_1 = require("./helpers.js");
15
+ const parsers_ts_1 = require("./parsers.js");
16
+ const status_ts_1 = require("./status.js");
14
17
  const types_ts_1 = require("./types.js");
18
+ /**
19
+ * Force http into https
20
+ *
21
+ * @returns {Handler<ExtendContext>} Middleware function
22
+ *
23
+ */
24
+ const forceHttps = (config) => {
25
+ var _a;
26
+ const toPort = (_a = config === null || config === void 0 ? void 0 : config.toPort) !== null && _a !== void 0 ? _a : 443;
27
+ return function ({ url }) {
28
+ if (url.protocol === "http:") {
29
+ const newUrl = new URL(url);
30
+ newUrl.protocol = "https:";
31
+ newUrl.port = toPort === 443 ? "" : String(toPort);
32
+ return (0, helpers_ts_1.redirectPermanentPreserve)(newUrl.toString());
33
+ }
34
+ };
35
+ };
36
+ exports.forceHttps = forceHttps;
37
+ /**
38
+ * Set security headers.
39
+ * - "X-Content-Type-Options": always "nosniff"
40
+ * - "X-Frame-Options": default "DENY"
41
+ * - "Referrer-Policy": from parameters
42
+ * - "Strict-Transport-Security": from parameters
43
+ * - "Content-Security-Policy": from parameters
44
+ *
45
+ * @returns {Handler<ExtendContext>} Middleware function
46
+ *
47
+ */
48
+ const securityHeaders = (config) => {
49
+ const { crossOriginOpenerPolicy, crossOriginEmbedderPolicy, crossOriginResourcePolicy, referrerPolicy, xFrameOptions = "DENY", strictTransportSecurity: hsts_, contentSecurityPolicy: csp_, headers, } = config !== null && config !== void 0 ? config : {};
50
+ const hsts = hsts_ == null
51
+ ? undefined
52
+ : typeof hsts_ === "string"
53
+ ? hsts_
54
+ : typeof hsts_ === "boolean"
55
+ ? hsts_
56
+ ? (0, helpers_ts_1.buildStrictTransportSecurity)({})
57
+ : undefined
58
+ : (0, helpers_ts_1.buildStrictTransportSecurity)(hsts_);
59
+ const contentSecurityPolicy = csp_ == null ? undefined : (0, helpers_ts_1.buildContentSecurityPolicy)(csp_);
60
+ /////////////////////////////////////////////
61
+ const preparedHeaders = [];
62
+ if (headers != null) {
63
+ if (Array.isArray(headers)) {
64
+ for (const [key, value] of headers) {
65
+ preparedHeaders.push([key, value]);
66
+ }
67
+ }
68
+ else {
69
+ for (const key of Object.keys(headers)) {
70
+ preparedHeaders.push([key, headers[key]]);
71
+ }
72
+ }
73
+ }
74
+ /////////////////////////////////////////////
75
+ preparedHeaders.push(["X-Content-Type-Options", "nosniff"]);
76
+ if (xFrameOptions != null) {
77
+ preparedHeaders.push(["X-Frame-Options", xFrameOptions]);
78
+ }
79
+ if (referrerPolicy != undefined) {
80
+ preparedHeaders.push(["Referrer-Policy", referrerPolicy]);
81
+ }
82
+ if (hsts != null) {
83
+ preparedHeaders.push(["Strict-Transport-Security", hsts]);
84
+ }
85
+ if (contentSecurityPolicy != null) {
86
+ preparedHeaders.push(["Content-Security-Policy", contentSecurityPolicy]);
87
+ }
88
+ if (crossOriginOpenerPolicy != null) {
89
+ preparedHeaders.push([
90
+ "Cross-Origin-Opener-Policy",
91
+ crossOriginOpenerPolicy,
92
+ ]);
93
+ }
94
+ if (crossOriginEmbedderPolicy != null) {
95
+ preparedHeaders.push([
96
+ "Cross-Origin-Embedder-Policy",
97
+ crossOriginEmbedderPolicy,
98
+ ]);
99
+ }
100
+ if (crossOriginResourcePolicy != null) {
101
+ preparedHeaders.push([
102
+ "Cross-Origin-Resource-Policy",
103
+ crossOriginResourcePolicy,
104
+ ]);
105
+ }
106
+ /////////////////////////////////////////////
107
+ return function ({ headers }) {
108
+ for (const [key, value] of preparedHeaders) {
109
+ headers.set(key, value);
110
+ }
111
+ };
112
+ };
113
+ exports.securityHeaders = securityHeaders;
15
114
  /**
16
115
  * Creates a rate limiting middleware using token bucket algorithm.
17
116
  * Supports both fixed interval refill and continuous rate-based refill.
18
117
  *
19
- * @template {Record<string, unknown>} ExtendContext - Extend Router Context
20
- * @param {Object} config - Rate limiting configuration
21
- * @param {Function} [config.key] - Function to generate cache key from request and context
22
- * @param {number} [config.maxTokens] - Maximum number of tokens in the bucket
23
- * @param {number} [config.refillInterval] - Fixed interval in seconds for token refill
24
- * @param {number} [config.refillRate] - Continuous refill rate in tokens per second
25
- * @param {number} [config.cleanUpInterval] - Interval in seconds for cleanup timer
26
- * @param {number} [config.cleanUpIdleDelay] - Time in seconds to delay cleanup of filled token buckets
27
- * @param {boolean} [config.setXRateLimitHeaders=false] - Whether to set X-RateLimit headers in response
28
- * @returns {Function} Middleware function that enforces rate limits
118
+ * @template {Record<string, unknown>} ExtendContext Extend Router Context
119
+ * @property {Object} config Rate limiting configuration
120
+ * @property {Function} [config.key] Function to generate cache key from request and context
121
+ * @property {number} [config.maxTokens] Maximum number of tokens in the bucket
122
+ * @property {number} [config.refillInterval] Fixed interval in seconds for token refill
123
+ * @property {number} [config.refillRate] Continuous refill rate in tokens per second
124
+ * @property {number} [config.cleanUpInterval] Interval in seconds for cleanup timer
125
+ * @property {number} [config.cleanUpIdleDelay] Time in seconds to delay cleanup of filled token buckets
126
+ * @property {boolean} [config.setXRateLimitHeaders=false] Whether to set X-RateLimit headers in response
127
+ * @property {boolean} [config.breakPipeline=false] If true, returns Break_Pipeline
128
+ * @property {"status"|"text"|"json"} [config.responseType="text"] Response type
129
+ * @returns {Handler<ExtendContext>} Middleware function that enforces rate limits
29
130
  *
30
131
  * @example
31
132
  * // Fixed interval rate limiting (10 requests per minute)
@@ -45,11 +146,16 @@ const types_ts_1 = require("./types.js");
45
146
  * maxTokens: 100,
46
147
  * });
47
148
  *
48
- * @throws {RouterError} If neither refillInterval nor refillRate is provided
149
+ * @throws {Error} If neither refillInterval nor refillRate is provided
49
150
  */
50
151
  const limitRate = (config) => {
51
152
  var _a;
52
- const { key, maxTokens, refillInterval, refillRate, cleanUpInterval, setXRateLimitHeaders = false, breakPipeline = false, } = config;
153
+ const { key, maxTokens, refillInterval, refillRate, cleanUpInterval, setXRateLimitHeaders = false, breakPipeline = false, responseType = "text", } = config;
154
+ const respond = responseType === "json"
155
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.json)({ [key]: `${tag}: ${content}`, tag }, Object.assign(Object.assign({}, init), { status: code }))
156
+ : responseType === "text"
157
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.text)(`[${key}] ${tag}: ${content}`, Object.assign(Object.assign({}, init), { status: code }))
158
+ : (code, _content, _key, _tag, init) => (0, helpers_ts_1.status)(code, null, init);
53
159
  const cleanUpIdleDelay = -((_a = config.cleanUpIdleDelay) !== null && _a !== void 0 ? _a : 0);
54
160
  const rateLimits = new Map();
55
161
  const now = () => performance.now() / 1000;
@@ -117,7 +223,7 @@ const limitRate = (config) => {
117
223
  }
118
224
  if (entry.tokens <= 0) {
119
225
  ctx.headers.set("Retry-After", Math.ceil(refillInterval - timeElapsed).toFixed());
120
- return (0, helpers_ts_1.status)(429);
226
+ return respond(status_ts_1.Status._429_TooManyRequests, "Rate Limited", "message", "rate-limit");
121
227
  }
122
228
  else {
123
229
  entry.tokens--;
@@ -143,7 +249,7 @@ const limitRate = (config) => {
143
249
  entry.lastRefill = now();
144
250
  if (entry.tokens <= 0) {
145
251
  ctx.headers.set("Retry-After", Math.ceil(1 / refillRate).toFixed());
146
- return (0, helpers_ts_1.status)(429);
252
+ return respond(status_ts_1.Status._429_TooManyRequests, "Rate Limited", "message", "rate-limit");
147
253
  }
148
254
  else {
149
255
  entry.tokens--;
@@ -158,24 +264,27 @@ const limitRate = (config) => {
158
264
  });
159
265
  };
160
266
  }
161
- throw new types_ts_1.RouterError("LIMIT-RATE: `refillInterval` or `refillRate` or both should be set");
267
+ throw new Error("LIMIT-RATE: `refillInterval` or `refillRate` or both should be set");
162
268
  };
163
269
  exports.limitRate = limitRate;
164
270
  /**
165
271
  * Creates a CORS (Cross-Origin Resource Sharing) middleware.
166
272
  * Supports preflight requests and configurable CORS headers.
167
273
  *
168
- * @template {Record<string, unknown>} ExtendContext - Extend Router Context
169
- * @param {Object} [config] - CORS configuration
170
- * @param {string|string[]|"*"} [config.origins="*"] - Allowed origins (wildcard "*", single origin, or array)
171
- * @param {HttpMethod[]} [config.methods=["GET","HEAD","PUT","PATCH","POST","DELETE"]] - Allowed HTTP methods
172
- * @param {string[]} [config.allowedHeaders=["Content-Type","Authorization"]] - Allowed request headers
173
- * @param {string[]} [config.exposedHeaders] - Headers exposed to the browser
174
- * @param {boolean} [config.credentials=false] - Allow credentials (cookies, authorization headers)
175
- * @param {number} [config.maxAge=86400] - Maximum age for preflight cache in seconds
176
- * @param {boolean} [config.varyOrigin=false] - Add Vary: Origin header for caching
177
- * @param {boolean} [options.breakPipeline=false] - If true, stops only pipe flow per handler type after success.
178
- * @returns {Function} Middleware function that handles CORS headers
274
+ * @template {Record<string, unknown>} ExtendContext Extend Router Context
275
+ * @param {Object} [config] CORS configuration
276
+ * @param {string|string[]|"*"} [config.origins="*"] Allowed origins (wildcard "*", single origin, or array)
277
+ * @param {(HttpMethod|HttpMethodUpper|HttpMethodLower)[]} [config.methods=["Get","Head","Put","Patch","Post","Delete"]] Allowed HTTP methods
278
+ * @param {string[]} [config.allowedHeaders=["Content-Type","Authorization"]] Allowed request headers
279
+ * @param {string[]} [config.exposedHeaders] Headers exposed to the browser
280
+ * @param {boolean} [config.credentials=false] Allow credentials (cookies, authorization headers)
281
+ * @param {number} [config.maxAge=86400] Maximum age for preflight cache in seconds
282
+ * @param {boolean} [config.varyOrigin=true] Add Vary: Origin header for caching
283
+ * @param {boolean} [config.breakPipeline=false] If true, returns Break_Pipeline
284
+ * @param {"status"|"text"|"json"} [config.responseType="text"] Response type
285
+ * @returns {Handler<ExtendContext>} Middleware function that handles CORS headers
286
+ *
287
+ * @throws {HttpError} If credentials is enabled with wildcard origin ("*")
179
288
  *
180
289
  * @example
181
290
  * // Basic CORS with all defaults
@@ -186,21 +295,21 @@ exports.limitRate = limitRate;
186
295
  * const corsMiddleware = cors({
187
296
  * origins: ["https://example.com", "https://api.example.com"],
188
297
  * credentials: true,
189
- * methods: ["GET", "POST", "PUT", "DELETE"],
298
+ * methods: ["Get", "Post", "Put", "Delete"],
190
299
  * allowedHeaders: ["Content-Type", "Authorization", "X-Custom-Header"]
191
300
  * });
192
301
  *
193
- * @throws {HttpError} If credentials is true with wildcard origin ("*")
194
302
  */
195
303
  const cors = (config) => {
196
- const { origins = "*", methods = ["Get", "Head", "Put", "Patch", "Post", "Delete"], allowedHeaders = ["Content-Type", "Authorization"], exposedHeaders, credentials = false, maxAge = 86400, varyOrigin = false, breakPipeline = false, } = config !== null && config !== void 0 ? config : {};
304
+ const { origins = "*", methods: methods_ = ["Get", "Head", "Put", "Patch", "Post", "Delete"], allowedHeaders = ["Content-Type", "Authorization"], exposedHeaders, credentials = false, maxAge = 86400, varyOrigin = true, breakPipeline = false, responseType = "text", } = config !== null && config !== void 0 ? config : {};
305
+ const respond = responseType === "json"
306
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.json)({ [key]: `${tag}: ${content}`, tag }, Object.assign(Object.assign({}, init), { status: code }))
307
+ : responseType === "text"
308
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.text)(`[${key}] ${tag}: ${content}`, Object.assign(Object.assign({}, init), { status: code }))
309
+ : (code, _content, _key, _tag, init) => (0, helpers_ts_1.status)(code, null, init);
197
310
  const globOrigin = origins === "*" ? "*" : null;
198
- const originsSet = new Set(typeof origins !== "string" ? origins : origins !== "*" ? [] : [origins]);
199
- if (methods != null) {
200
- for (let i = 0; i < methods.length; i++) {
201
- methods[i] = methods[i].toUpperCase();
202
- }
203
- }
311
+ const originsSet = new Set(origins === "*" ? [] : typeof origins === "string" ? [origins] : origins);
312
+ const methods = methods_ === null || methods_ === void 0 ? void 0 : methods_.map((m) => m.toUpperCase());
204
313
  return function (ctx) {
205
314
  const { request, headers } = ctx;
206
315
  const origin = request.headers.get("origin");
@@ -218,8 +327,9 @@ const cors = (config) => {
218
327
  corsOrigin = originsSet.has(origin) ? origin : null;
219
328
  }
220
329
  if (!corsOrigin) {
221
- if (varyOrigin)
222
- ctx.headers.append("Vary", "Origin");
330
+ if (varyOrigin) {
331
+ headers.append("Vary", "Origin");
332
+ }
223
333
  if (breakPipeline) {
224
334
  return types_ts_1.Break_Pipeline;
225
335
  }
@@ -228,30 +338,31 @@ const cors = (config) => {
228
338
  headers.set("Access-Control-Allow-Origin", corsOrigin);
229
339
  if (credentials) {
230
340
  if (corsOrigin === "*")
231
- throw new types_ts_1.HttpError(403, "CORS: Cannot use credentials with wildcard origin");
341
+ throw new types_ts_1.HttpError(status_ts_1.Status._403_Forbidden, "CORS: Cannot use credentials with wildcard origin");
232
342
  headers.set("Access-Control-Allow-Credentials", "true");
233
343
  }
234
344
  if (exposedHeaders && exposedHeaders.length > 0) {
235
345
  headers.set("Access-Control-Expose-Headers", exposedHeaders.join(", "));
236
346
  }
237
- if (varyOrigin) {
347
+ if (varyOrigin && origins !== "*") {
238
348
  headers.append("Vary", "Origin");
239
349
  }
240
350
  if (request.method === "OPTIONS") {
241
351
  if (methods && methods.length > 0) {
242
352
  const requestMethod = request.headers.get("Access-Control-Request-Method");
243
- if (requestMethod && !methods.includes(requestMethod)) {
244
- return (0, helpers_ts_1.status)(405, `Method ${requestMethod} not allowed`);
353
+ if (requestMethod &&
354
+ !methods.includes(requestMethod)) {
355
+ return respond(status_ts_1.Status._405_MethodNotAllowed, `Method ${requestMethod} not allowed`, "error", "CORS");
245
356
  }
246
357
  headers.set("Access-Control-Allow-Methods", methods.join(", "));
247
358
  }
248
359
  if (allowedHeaders && allowedHeaders.length > 0) {
249
360
  headers.set("Access-Control-Allow-Headers", allowedHeaders.join(", "));
250
361
  }
251
- if (maxAge) {
362
+ if (maxAge != null) {
252
363
  headers.set("Access-Control-Max-Age", maxAge.toString());
253
364
  }
254
- return (0, helpers_ts_1.status)(204, null);
365
+ return (0, helpers_ts_1.status)(status_ts_1.Status._204_NoContent, null);
255
366
  }
256
367
  if (breakPipeline) {
257
368
  return types_ts_1.Break_Pipeline;
@@ -259,4 +370,540 @@ const cors = (config) => {
259
370
  };
260
371
  };
261
372
  exports.cors = cors;
373
+ /**
374
+ * Creates a request params, query and body validator middleware function
375
+ *
376
+ * @param {Validator<Record<string, string>,ExtendContext>} [config.params] Parameters validator
377
+ * @param {CustomErrorType} [config.paramsErrors] Parameters validator's expected error instance types other than Error derivatives
378
+ * @param {boolean|ValidateQueryParser<ExtendContext>} [config.queryParse] Parse query before validation. 'true' for default parser or provide a custom parser
379
+ * @param {Validator<Record<string, string>,ExtendContext>} [config.query] Query validator
380
+ * @param {CustomErrorType} [config.queryErrors] Query validator's expected error instance types other than Error derivatives
381
+ * @param {boolean|ValidateCookieParser<ExtendContext>} [config.cookieParse] Parse cookie before validation. 'true' for default parser or provide a custom parser
382
+ * @param {Validator<Record<string, string>,ExtendContext>} [config.cookie] Cookie validator
383
+ * @param {CustomErrorType} [config.cookieErrors] Cookie validator's expected error instance types other than Error derivatives
384
+ * @param {ParseBodyOptions} [config.bodyParseOptions] Body parser options
385
+ * @param {boolean|ValidateBodyParser<ExtendContext>} [config.bodyParse] Parse body before validation. 'true' for default parser or provide a custom parser
386
+ * @param {ValidatorFnIt<ParsedBody,ExtendContext>|Array<ValidatorIt<ParsedBody,ExtendContext>>} [config.body] Body validator
387
+ * @param {CustomErrorType} [config.bodyErrors] Body validator's expected error instance types other than Error derivatives
388
+ * @param {Array<CustomErrorType>} [config.errors] All validator's expected error instance types other than Error derivatives. Can be overridden.
389
+ * @param {boolean} [config.paramsReassign] Reassign validated return value of the params validator function
390
+ * @param {boolean} [config.queryReassign] Reassign validated return value of the query validator function
391
+ * @param {boolean} [config.cookieReassign] Reassign validated return value of the cookie validator function
392
+ * @param {boolean} [config.bodyReassign] Reassign validated return value of the body validator function
393
+ * @param {boolean|{<Target extends Record<string, unknown>>(target: Target,key: string,):void|any;}} [config.strangeParams] Handle strange or unexpected properties
394
+ * @param {boolean|{<Target extends Record<string, unknown>>(target: Target,key: string,):void|any;}} [config.strangeQuery] Handle strange or unexpected properties
395
+ * @param {boolean|{<Target extends Record<string, unknown>>(target: Target,key: string,):void|any;}} [config.strangeCookie] Handle strange or unexpected properties
396
+ * @param {boolean|{<Target extends Record<string, unknown>>(target: Target,key: string,):void|any;}} [config.strangeBody] Handle strange or unexpected properties
397
+ * @param {boolean|{<Target extends Record<string, unknown>>(target: Target,key: string,):void|any;}} [config.strange] A default common option to handle strange or unexpected properties
398
+ * @param {"status"|"text"|"json"} [config.responseType="text"] Response type.
399
+ * - Note: 'status' type will omit content
400
+ * @param {boolean} [config.breakPipeline=false] If true, returns Break_Pipeline
401
+ * @returns {HandlerReturn}
402
+ */
403
+ const validate = ({ responseType = "text", errors, paramsReassign = false, params: paramsValidator, paramsErrors, strangeParams, queryParse, queryReassign = false, query: queryValidator, queryErrors, strangeQuery, cookieParse, cookieReassign = false, cookie: cookieValidator, cookieErrors, strangeCookie, bodyParse, bodyParseOptions, bodyReassign = false, body: bodyValidator, bodyErrors, strangeBody, strange, breakPipeline = false, }) => {
404
+ paramsErrors = paramsErrors !== null && paramsErrors !== void 0 ? paramsErrors : errors;
405
+ queryErrors = queryErrors !== null && queryErrors !== void 0 ? queryErrors : errors;
406
+ cookieErrors = cookieErrors !== null && cookieErrors !== void 0 ? cookieErrors : errors;
407
+ bodyErrors = bodyErrors !== null && bodyErrors !== void 0 ? bodyErrors : errors;
408
+ const errorMatches = (target, errors) => {
409
+ for (const error of errors) {
410
+ if (target instanceof error) {
411
+ return true;
412
+ }
413
+ }
414
+ return false;
415
+ };
416
+ // Validate error instance types
417
+ if (errors) {
418
+ for (let i = 0; i < errors.length; i++) {
419
+ const error = errors[i];
420
+ if (!(typeof error === "function")) {
421
+ throw new TypeError(`Validator errors type at index ${i} is invalid`);
422
+ }
423
+ }
424
+ }
425
+ if (paramsErrors) {
426
+ for (let i = 0; i < paramsErrors.length; i++) {
427
+ const error = paramsErrors[i];
428
+ if (!(typeof error === "function")) {
429
+ throw new TypeError(`Validator paramsErrors type at index ${i} is invalid`);
430
+ }
431
+ }
432
+ }
433
+ if (queryErrors) {
434
+ for (let i = 0; i < queryErrors.length; i++) {
435
+ const error = queryErrors[i];
436
+ if (!(typeof error === "function")) {
437
+ throw new TypeError(`Validator queryErrors type at index ${i} is invalid`);
438
+ }
439
+ }
440
+ }
441
+ if (cookieErrors) {
442
+ for (let i = 0; i < cookieErrors.length; i++) {
443
+ const error = cookieErrors[i];
444
+ if (!(typeof error === "function")) {
445
+ throw new TypeError(`Validator cookieErrors type at index ${i} is invalid`);
446
+ }
447
+ }
448
+ }
449
+ if (bodyErrors) {
450
+ for (let i = 0; i < bodyErrors.length; i++) {
451
+ const error = bodyErrors[i];
452
+ if (!(typeof error === "function")) {
453
+ throw new TypeError(`Validator bodyErrors type at index ${i} is invalid`);
454
+ }
455
+ }
456
+ }
457
+ //
458
+ strangeParams = strangeParams !== null && strangeParams !== void 0 ? strangeParams : strange;
459
+ strangeQuery = strangeQuery !== null && strangeQuery !== void 0 ? strangeQuery : strange;
460
+ strangeCookie = strangeCookie !== null && strangeCookie !== void 0 ? strangeCookie : strange;
461
+ strangeBody = strangeBody !== null && strangeBody !== void 0 ? strangeBody : strange;
462
+ // Validate strangeParams
463
+ if (strangeParams != undefined &&
464
+ typeof strangeParams !== "boolean" &&
465
+ typeof strangeParams !== "function") {
466
+ throw new TypeError("Validator strangeParams type must be either boolean, undefined or a function");
467
+ }
468
+ // Validate strangeQuery
469
+ if (strangeQuery != undefined &&
470
+ typeof strangeQuery !== "boolean" &&
471
+ typeof strangeQuery !== "function") {
472
+ throw new TypeError("Validator strangeQuery type must be either boolean, undefined or a function");
473
+ }
474
+ // Validate strangeCookie
475
+ if (strangeCookie != undefined &&
476
+ typeof strangeCookie !== "boolean" &&
477
+ typeof strangeCookie !== "function") {
478
+ throw new TypeError("Validator strangeCookie type must be either boolean, undefined or a function");
479
+ }
480
+ // Validate strangeBody
481
+ if (strangeBody != undefined &&
482
+ typeof strangeBody !== "boolean" &&
483
+ typeof strangeBody !== "function") {
484
+ throw new TypeError("Validator strangeBody type must be either boolean, undefined or a function");
485
+ }
486
+ // Validate query parser
487
+ if (queryParse != undefined &&
488
+ typeof queryParse !== "boolean" &&
489
+ typeof queryParse !== "function") {
490
+ throw new TypeError("Validator queryParse type must be either boolean, undefined or a function");
491
+ }
492
+ // Validate cookie parser
493
+ if (cookieParse != undefined &&
494
+ typeof cookieParse !== "boolean" &&
495
+ typeof cookieParse !== "function") {
496
+ throw new TypeError("Validator cookieParse type must be either boolean, undefined or a function");
497
+ }
498
+ // Validate body parser
499
+ if (parsers_ts_1.parseBody != undefined &&
500
+ typeof parsers_ts_1.parseBody !== "boolean" &&
501
+ typeof parsers_ts_1.parseBody !== "function") {
502
+ throw new TypeError("Validator parseBody type must be either boolean, undefined or a function");
503
+ }
504
+ const respond = responseType === "json"
505
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.json)({ [key]: `${tag}: ${content}`, tag }, Object.assign(Object.assign({}, init), { status: code }))
506
+ : responseType === "text"
507
+ ? (code, content, key, tag, init) => (0, helpers_ts_1.text)(`[${key}] ${tag}: ${content}`, Object.assign(Object.assign({}, init), { status: code }))
508
+ : (code, _content, _key, _tag, init) => (0, helpers_ts_1.status)(code, null, init);
509
+ //
510
+ // Prepare parsers
511
+ //
512
+ const queryParser = queryParse === true
513
+ ? ((ctx) => {
514
+ if (ctx.query == null) {
515
+ ctx.query = {};
516
+ }
517
+ const searchParams = ctx.url.searchParams;
518
+ for (const key of searchParams.keys()) {
519
+ const values = searchParams.getAll(key);
520
+ ctx.query[key] =
521
+ values.length > 1 ? values[values.length - 1] : values[0];
522
+ }
523
+ })
524
+ : queryParse || undefined;
525
+ const cookieParser = cookieParse === true
526
+ ? ((ctx) => {
527
+ if (ctx.cookie == null) {
528
+ ctx.cookie = {};
529
+ }
530
+ (0, parsers_ts_1.parseCookieFromRequest)(ctx.request, ctx.cookie);
531
+ })
532
+ : cookieParse || undefined;
533
+ const bodyParser = bodyParse === true
534
+ ? (0, parsers_ts_1.parseBody)(bodyParseOptions)
535
+ : bodyParse || undefined;
536
+ ///////////////////////////////////////////////////////////////////////////
537
+ // Validate params validators
538
+ const paramsValidatorIsFunction = typeof paramsValidator === "function";
539
+ const paramsValidatorIsObject = typeof paramsValidator === "object" && !Array.isArray(paramsValidator);
540
+ if (paramsValidator) {
541
+ if (!paramsValidatorIsFunction && !paramsValidatorIsObject) {
542
+ throw new TypeError("Params validator type must be function or object");
543
+ }
544
+ else if (paramsValidatorIsObject) {
545
+ for (const key of Object.keys(paramsValidator)) {
546
+ if (typeof paramsValidator[key] !== "function") {
547
+ throw new TypeError(`Params validator property type must be function at '${key}'`);
548
+ }
549
+ }
550
+ }
551
+ }
552
+ // Validate query validators
553
+ const queryValidatorIsFunction = typeof queryValidator === "function";
554
+ const queryValidatorIsObject = typeof queryValidator === "object" && !Array.isArray(queryValidator);
555
+ if (queryValidator) {
556
+ if (!queryValidatorIsFunction && !queryValidatorIsObject) {
557
+ throw new TypeError("Query validator type must be function or object");
558
+ }
559
+ else if (queryValidatorIsObject) {
560
+ for (const key of Object.keys(queryValidator)) {
561
+ if (typeof queryValidator[key] !== "function") {
562
+ throw new TypeError(`Query validator property type must be function at '${key}'`);
563
+ }
564
+ }
565
+ }
566
+ }
567
+ // Validate cookie validators
568
+ const cookieValidatorIsFunction = typeof cookieValidator === "function";
569
+ const cookieValidatorIsObject = typeof cookieValidator === "object" && !Array.isArray(cookieValidator);
570
+ if (cookieValidator) {
571
+ if (!cookieValidatorIsFunction && !cookieValidatorIsObject) {
572
+ throw new TypeError("Cookie validator type must be function or object");
573
+ }
574
+ else if (cookieValidatorIsObject) {
575
+ for (const key of Object.keys(cookieValidator)) {
576
+ if (typeof cookieValidator[key] !== "function") {
577
+ throw new TypeError(`Cookie validator property type must be function at '${key}'`);
578
+ }
579
+ }
580
+ }
581
+ }
582
+ // Validate body validators
583
+ const bodyValidatorIsFunction = typeof bodyValidator === "function";
584
+ const bodyValidatorIsArray = Array.isArray(bodyValidator);
585
+ const bodyValidatorIsObject = typeof bodyValidator === "object" && !bodyValidatorIsArray;
586
+ const bodyValidators = bodyValidator
587
+ ? Array.isArray(bodyValidator)
588
+ ? bodyValidator
589
+ : [bodyValidator]
590
+ : undefined;
591
+ if (bodyValidators) {
592
+ if (!bodyValidatorIsFunction &&
593
+ !bodyValidatorIsObject &&
594
+ !bodyValidatorIsArray) {
595
+ throw new TypeError("Body validator type must be function or object or array of objects");
596
+ }
597
+ else if (bodyValidatorIsArray && bodyValidators.length === 0) {
598
+ throw new TypeError("Body validator must not be an empty array");
599
+ }
600
+ for (let i = 0; i < bodyValidators.length; i++) {
601
+ const validator = bodyValidators[i];
602
+ const bodyValidatorIsFunction = typeof validator === "function";
603
+ const validatorIsObject = typeof validator === "object" && !Array.isArray(validator);
604
+ if (!bodyValidatorIsFunction && !validatorIsObject) {
605
+ throw new TypeError(bodyValidators.length > 0
606
+ ? `Body validator must be a valid function or object at ${i}`
607
+ : "Body validator must be a valid function or object");
608
+ }
609
+ else if (validatorIsObject) {
610
+ for (const key of Object.keys(validator)) {
611
+ if (typeof validator[key] !== "function") {
612
+ throw new TypeError(bodyValidatorIsArray
613
+ ? `Body validator property type must be function at index ${i} '${key}'`
614
+ : `Body validator property type must be function at '${key}'`);
615
+ }
616
+ }
617
+ }
618
+ }
619
+ }
620
+ ////////////////////////////////////////////////////////////////////////
621
+ return (ctx) => __awaiter(void 0, void 0, void 0, function* () {
622
+ const params = ctx.params;
623
+ // Validate Params
624
+ if (paramsValidatorIsFunction) {
625
+ const result = paramsValidator.apply
626
+ ? paramsValidator.apply(ctx, params)
627
+ : paramsValidator(params);
628
+ if (result instanceof Error) {
629
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "params", "error");
630
+ }
631
+ else if (paramsErrors && errorMatches(result, paramsErrors)) {
632
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "params");
633
+ }
634
+ else if (result instanceof Response ||
635
+ result === types_ts_1.Break_Pipe ||
636
+ result === types_ts_1.Break_Pipeline) {
637
+ return result;
638
+ }
639
+ else if (paramsReassign) {
640
+ ctx.params = result;
641
+ }
642
+ }
643
+ else if (paramsValidatorIsObject) {
644
+ for (const key of Object.keys(params)) {
645
+ const validator = paramsValidator[key];
646
+ if (validator == null && !strangeParams) {
647
+ continue;
648
+ }
649
+ const result = validator == null
650
+ ? typeof strangeParams === "function"
651
+ ? strangeParams(params, key)
652
+ : params[key]
653
+ : validator.apply
654
+ ? validator.apply(ctx, params[key])
655
+ : validator(params[key]);
656
+ if (result instanceof Error) {
657
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "params");
658
+ }
659
+ else if (paramsErrors && errorMatches(result, paramsErrors)) {
660
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "params");
661
+ }
662
+ else if (result instanceof Response ||
663
+ result === types_ts_1.Break_Pipe ||
664
+ result === types_ts_1.Break_Pipeline) {
665
+ return result;
666
+ }
667
+ else if (paramsReassign) {
668
+ params[key] = result;
669
+ }
670
+ }
671
+ }
672
+ // Parse query
673
+ if (queryParser) {
674
+ yield queryParser(ctx);
675
+ }
676
+ const query = ctx.query;
677
+ // Validate Query
678
+ if (queryValidatorIsFunction) {
679
+ const result = queryValidator.apply
680
+ ? queryValidator.apply(ctx, query)
681
+ : queryValidator(query);
682
+ if (result instanceof Error) {
683
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "query");
684
+ }
685
+ else if (queryErrors && errorMatches(result, queryErrors)) {
686
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "query");
687
+ }
688
+ else if (result instanceof Response ||
689
+ result === types_ts_1.Break_Pipe ||
690
+ result === types_ts_1.Break_Pipeline) {
691
+ return result;
692
+ }
693
+ else if (queryReassign) {
694
+ ctx.query = result;
695
+ }
696
+ }
697
+ else if (queryValidatorIsObject) {
698
+ for (const key of Object.keys(query)) {
699
+ const validator = queryValidator[key];
700
+ if (validator == null && !strangeQuery) {
701
+ continue;
702
+ }
703
+ const result = validator == null
704
+ ? typeof strangeQuery === "function"
705
+ ? strangeQuery(query, key)
706
+ : query[key]
707
+ : validator.apply
708
+ ? validator.apply(ctx, query[key])
709
+ : validator(query[key]);
710
+ if (result instanceof Error) {
711
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "query");
712
+ }
713
+ else if (queryErrors && errorMatches(result, queryErrors)) {
714
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "query");
715
+ }
716
+ else if (result instanceof Response ||
717
+ result === types_ts_1.Break_Pipe ||
718
+ result === types_ts_1.Break_Pipeline) {
719
+ return result;
720
+ }
721
+ else if (queryReassign) {
722
+ query[key] = result;
723
+ }
724
+ }
725
+ }
726
+ // Parse cookie
727
+ if (cookieParser) {
728
+ yield cookieParser(ctx);
729
+ }
730
+ const cookie = ctx.cookie;
731
+ // Validate Cookie
732
+ if (cookieValidatorIsFunction) {
733
+ const result = cookieValidator.apply
734
+ ? cookieValidator.apply(ctx, cookie)
735
+ : cookieValidator(cookie);
736
+ if (result instanceof Error) {
737
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "cookie");
738
+ }
739
+ else if (cookieErrors && errorMatches(result, cookieErrors)) {
740
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "cookie");
741
+ }
742
+ else if (result instanceof Response ||
743
+ result === types_ts_1.Break_Pipe ||
744
+ result === types_ts_1.Break_Pipeline) {
745
+ return result;
746
+ }
747
+ else if (cookieReassign) {
748
+ ctx.cookie = result;
749
+ }
750
+ }
751
+ else if (cookieValidatorIsObject) {
752
+ for (const key of Object.keys(cookie)) {
753
+ const validator = cookieValidator[key];
754
+ if (validator == null && !strangeCookie) {
755
+ continue;
756
+ }
757
+ const result = validator == null
758
+ ? typeof strangeCookie === "function"
759
+ ? strangeCookie(cookie, key)
760
+ : cookie[key]
761
+ : validator.apply
762
+ ? validator.apply(ctx, cookie[key])
763
+ : validator(cookie[key]);
764
+ if (result instanceof Error) {
765
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "cookie");
766
+ }
767
+ else if (cookieErrors && errorMatches(result, cookieErrors)) {
768
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "cookie");
769
+ }
770
+ else if (result instanceof Response ||
771
+ result === types_ts_1.Break_Pipe ||
772
+ result === types_ts_1.Break_Pipeline) {
773
+ return result;
774
+ }
775
+ else if (cookieReassign) {
776
+ cookie[key] = result;
777
+ }
778
+ }
779
+ }
780
+ // Parse body
781
+ if (bodyParser) {
782
+ yield bodyParser(ctx);
783
+ }
784
+ const body = ctx.body;
785
+ // Validate Body
786
+ if (bodyValidators) {
787
+ if (Array.isArray(body)) {
788
+ for (let i = 0; i < body.length; i++) {
789
+ const validator = bodyValidators[i % bodyValidators.length];
790
+ const activeBody = body[i];
791
+ if (typeof validator === "function") {
792
+ const result = validator.apply(ctx, activeBody);
793
+ if (result instanceof Error) {
794
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "body");
795
+ }
796
+ else if (bodyErrors && errorMatches(result, bodyErrors)) {
797
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "body");
798
+ }
799
+ else if (result instanceof Response ||
800
+ result === types_ts_1.Break_Pipe ||
801
+ result === types_ts_1.Break_Pipeline) {
802
+ return result;
803
+ }
804
+ else if (bodyReassign) {
805
+ body[i] = result;
806
+ }
807
+ }
808
+ else if (validator) {
809
+ if (activeBody &&
810
+ typeof activeBody === "object" &&
811
+ !Array.isArray(activeBody)) {
812
+ for (const key of Object.keys(activeBody)) {
813
+ const propValidator = validator[key];
814
+ if (propValidator == null && !strangeBody) {
815
+ continue;
816
+ }
817
+ const result = propValidator == null
818
+ ? typeof strangeBody === "function"
819
+ ? strangeBody(activeBody, key)
820
+ : activeBody[key]
821
+ : propValidator.apply
822
+ ? propValidator.apply(ctx, activeBody[key])
823
+ : propValidator(activeBody[key]);
824
+ if (result instanceof Error) {
825
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "body");
826
+ }
827
+ else if (bodyErrors && errorMatches(result, bodyErrors)) {
828
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "body");
829
+ }
830
+ else if (result instanceof Response ||
831
+ result === types_ts_1.Break_Pipe ||
832
+ result === types_ts_1.Break_Pipeline) {
833
+ return result;
834
+ }
835
+ else if (bodyReassign) {
836
+ activeBody[key] = result;
837
+ }
838
+ }
839
+ }
840
+ else {
841
+ return respond(status_ts_1.Status._400_BadRequest, `Invalid body type at index ${i}`, "error", "body");
842
+ }
843
+ }
844
+ }
845
+ }
846
+ else {
847
+ const validator = bodyValidators[0];
848
+ if (typeof validator === "function") {
849
+ const result = validator.apply
850
+ ? validator.apply(ctx, body)
851
+ : validator(body);
852
+ if (result instanceof Error) {
853
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "body");
854
+ }
855
+ else if (bodyErrors && errorMatches(result, bodyErrors)) {
856
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "body");
857
+ }
858
+ else if (result instanceof Response ||
859
+ result === types_ts_1.Break_Pipe ||
860
+ result === types_ts_1.Break_Pipeline) {
861
+ return result;
862
+ }
863
+ else if (bodyReassign) {
864
+ ctx.body = result;
865
+ }
866
+ }
867
+ else if (validator) {
868
+ if (body && typeof body === "object" && !Array.isArray(body)) {
869
+ for (const key of Object.keys(body)) {
870
+ const propValidator = validator[key];
871
+ if (propValidator == null && !strangeBody) {
872
+ continue;
873
+ }
874
+ const result = propValidator == null
875
+ ? typeof strangeBody === "function"
876
+ ? strangeBody(body, key)
877
+ : body
878
+ : propValidator.apply
879
+ ? propValidator.apply(ctx, body[key])
880
+ : propValidator(body[key]);
881
+ if (result instanceof Error) {
882
+ return respond(result.status || status_ts_1.Status._400_BadRequest, result.message, "error", "body");
883
+ }
884
+ else if (bodyErrors && errorMatches(result, bodyErrors)) {
885
+ return respond(result.status || status_ts_1.Status._400_BadRequest, String(result), "error", "body");
886
+ }
887
+ else if (result instanceof Response ||
888
+ result === types_ts_1.Break_Pipe ||
889
+ result === types_ts_1.Break_Pipeline) {
890
+ return result;
891
+ }
892
+ else if (bodyReassign) {
893
+ body[key] = result;
894
+ }
895
+ }
896
+ }
897
+ else {
898
+ return respond(status_ts_1.Status._400_BadRequest, "Invalid body type", "error", "body");
899
+ }
900
+ }
901
+ }
902
+ }
903
+ if (breakPipeline) {
904
+ return types_ts_1.Break_Pipeline;
905
+ }
906
+ });
907
+ };
908
+ exports.validate = validate;
262
909
  //# sourceMappingURL=middlewares.js.map