vafast 0.3.10 → 0.4.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.
Files changed (43) hide show
  1. package/README.md +61 -0
  2. package/dist/defineRoute.d.ts +101 -3
  3. package/dist/defineRoute.js +30 -1
  4. package/dist/defineRoute.js.map +1 -1
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.js +363 -50
  7. package/dist/index.js.map +1 -1
  8. package/dist/monitoring/index.js +18 -1
  9. package/dist/monitoring/index.js.map +1 -1
  10. package/dist/monitoring/native-monitor.js +18 -1
  11. package/dist/monitoring/native-monitor.js.map +1 -1
  12. package/dist/node-server/index.js +46 -2
  13. package/dist/node-server/index.js.map +1 -1
  14. package/dist/node-server/serve.d.ts +16 -1
  15. package/dist/node-server/serve.js +46 -2
  16. package/dist/node-server/serve.js.map +1 -1
  17. package/dist/router/index.js +2 -1
  18. package/dist/router/index.js.map +1 -1
  19. package/dist/router.js +2 -1
  20. package/dist/router.js.map +1 -1
  21. package/dist/serve.js +46 -2
  22. package/dist/serve.js.map +1 -1
  23. package/dist/server/index.js +18 -1
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/server-factory.js +18 -1
  26. package/dist/server/server-factory.js.map +1 -1
  27. package/dist/server/server.d.ts +15 -1
  28. package/dist/server/server.js +18 -1
  29. package/dist/server/server.js.map +1 -1
  30. package/dist/types/types.d.ts +12 -0
  31. package/dist/utils/create-handler.d.ts +12 -3
  32. package/dist/utils/create-handler.js +2 -1
  33. package/dist/utils/create-handler.js.map +1 -1
  34. package/dist/utils/index.d.ts +4 -1
  35. package/dist/utils/index.js +224 -1
  36. package/dist/utils/index.js.map +1 -1
  37. package/dist/utils/route-registry.d.ts +134 -0
  38. package/dist/utils/route-registry.js +128 -0
  39. package/dist/utils/route-registry.js.map +1 -0
  40. package/dist/utils/sse.d.ts +87 -0
  41. package/dist/utils/sse.js +181 -0
  42. package/dist/utils/sse.js.map +1 -0
  43. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,26 +1,27 @@
1
1
  // src/router.ts
2
2
  function flattenNestedRoutes(routes) {
3
3
  const flattened = [];
4
- function processRoute(route, parentPath = "", parentMiddleware = []) {
5
- const currentPath = normalizePath(parentPath + route.path);
4
+ function processRoute(route2, parentPath = "", parentMiddleware = []) {
5
+ const currentPath = normalizePath(parentPath + route2.path);
6
6
  const currentMiddleware = [
7
7
  ...parentMiddleware,
8
- ...route.middleware || []
8
+ ...route2.middleware || []
9
9
  ];
10
- if ("method" in route && "handler" in route) {
10
+ if ("method" in route2 && "handler" in route2) {
11
+ const leafRoute = route2;
11
12
  flattened.push({
12
- ...route,
13
+ ...leafRoute,
13
14
  fullPath: currentPath,
14
15
  middlewareChain: currentMiddleware
15
16
  });
16
- } else if ("children" in route && route.children) {
17
- for (const child of route.children) {
17
+ } else if ("children" in route2 && route2.children) {
18
+ for (const child of route2.children) {
18
19
  processRoute(child, currentPath, currentMiddleware);
19
20
  }
20
21
  }
21
22
  }
22
- for (const route of routes) {
23
- processRoute(route);
23
+ for (const route2 of routes) {
24
+ processRoute(route2);
24
25
  }
25
26
  return flattened;
26
27
  }
@@ -187,12 +188,12 @@ var BaseServer = class {
187
188
  */
188
189
  logFlattenedRoutes(routes, type = "\u8DEF\u7531") {
189
190
  console.log(`\u{1F680} \u6241\u5E73\u5316\u540E\u7684${type}:`);
190
- for (const route of routes) {
191
- const method = route.method || "GET";
192
- const path = route.fullPath || route.path;
191
+ for (const route2 of routes) {
192
+ const method = route2.method || "GET";
193
+ const path = route2.fullPath || route2.path;
193
194
  console.log(` ${method} ${path}`);
194
- if (route.middlewareChain && route.middlewareChain.length > 0) {
195
- console.log(` \u4E2D\u95F4\u4EF6\u94FE: ${route.middlewareChain.length} \u4E2A`);
195
+ if (route2.middlewareChain && route2.middlewareChain.length > 0) {
196
+ console.log(` \u4E2D\u95F4\u4EF6\u94FE: ${route2.middlewareChain.length} \u4E2A`);
196
197
  }
197
198
  }
198
199
  console.log("");
@@ -203,13 +204,13 @@ var BaseServer = class {
203
204
  */
204
205
  detectRouteConflicts(routes) {
205
206
  const pathGroups = /* @__PURE__ */ new Map();
206
- for (const route of routes) {
207
- const path = route.fullPath || route.path;
208
- const method = route.method || "GET";
207
+ for (const route2 of routes) {
208
+ const path = route2.fullPath || route2.path;
209
+ const method = route2.method || "GET";
209
210
  if (!pathGroups.has(path)) {
210
211
  pathGroups.set(path, []);
211
212
  }
212
- pathGroups.get(path).push({ ...route, method });
213
+ pathGroups.get(path).push({ ...route2, method });
213
214
  }
214
215
  for (const [path, routeList] of pathGroups) {
215
216
  if (routeList.length > 1) {
@@ -219,8 +220,8 @@ var BaseServer = class {
219
220
  console.warn(
220
221
  `\u26A0\uFE0F \u8DEF\u7531\u51B2\u7A81: ${uniqueMethods[0]} ${path} \u5B9A\u4E49\u4E86 ${routeList.length} \u6B21`
221
222
  );
222
- routeList.forEach((route, index) => {
223
- console.warn(` ${index + 1}. ${route.method} ${path}`);
223
+ routeList.forEach((route2, index) => {
224
+ console.warn(` ${index + 1}. ${route2.method} ${path}`);
224
225
  });
225
226
  } else {
226
227
  console.log(`\u2139\uFE0F \u8DEF\u5F84 ${path} \u652F\u6301\u65B9\u6CD5: ${uniqueMethods.join(", ")}`);
@@ -526,12 +527,12 @@ var Server = class extends BaseServer {
526
527
  registerRoutes(routes) {
527
528
  const flattened = flattenNestedRoutes(routes);
528
529
  this.routes.push(...flattened);
529
- for (const route of flattened) {
530
+ for (const route2 of flattened) {
530
531
  this.router.register(
531
- route.method,
532
- route.fullPath,
533
- route.handler,
534
- route.middlewareChain || []
532
+ route2.method,
533
+ route2.fullPath,
534
+ route2.handler,
535
+ route2.middlewareChain || []
535
536
  );
536
537
  }
537
538
  this.detectRouteConflicts(flattened);
@@ -608,18 +609,18 @@ var Server = class extends BaseServer {
608
609
  }
609
610
  return this.createErrorResponse(method, pathname);
610
611
  };
611
- addRoute(route) {
612
+ addRoute(route2) {
612
613
  const flattenedRoute = {
613
- ...route,
614
- fullPath: route.path,
615
- middlewareChain: route.middleware || []
614
+ ...route2,
615
+ fullPath: route2.path,
616
+ middlewareChain: route2.middleware || []
616
617
  };
617
618
  this.routes.push(flattenedRoute);
618
619
  this.router.register(
619
- route.method,
620
- route.path,
621
- route.handler,
622
- route.middleware || []
620
+ route2.method,
621
+ route2.path,
622
+ route2.handler,
623
+ route2.middleware || []
623
624
  );
624
625
  }
625
626
  addRoutes(routes) {
@@ -628,31 +629,47 @@ var Server = class extends BaseServer {
628
629
  getRoutes() {
629
630
  return this.router.getRoutes();
630
631
  }
632
+ /**
633
+ * 获取完整的路由元信息(不含 handler 和 middleware)
634
+ *
635
+ * 用于 API 文档生成、Webhook 事件注册、权限检查等场景
636
+ *
637
+ * @example
638
+ * ```typescript
639
+ * const routes = server.getRoutesWithMeta()
640
+ * for (const route of routes) {
641
+ * console.log(route.fullPath, route.name, route.description)
642
+ * }
643
+ * ```
644
+ */
645
+ getRoutesWithMeta() {
646
+ return this.routes;
647
+ }
631
648
  };
632
649
 
633
650
  // src/middleware/component-router.ts
634
651
  function flattenComponentRoutes(routes) {
635
652
  const flattened = [];
636
- function processRoute(route, parentPath = "", parentMiddleware = []) {
637
- const currentPath = parentPath + route.path;
653
+ function processRoute(route2, parentPath = "", parentMiddleware = []) {
654
+ const currentPath = parentPath + route2.path;
638
655
  const currentMiddleware = [
639
656
  ...parentMiddleware,
640
- ...route.middleware || []
657
+ ...route2.middleware || []
641
658
  ];
642
- if ("component" in route) {
659
+ if ("component" in route2) {
643
660
  flattened.push({
644
- ...route,
661
+ ...route2,
645
662
  fullPath: currentPath,
646
663
  middlewareChain: currentMiddleware
647
664
  });
648
- } else if ("children" in route && route.children) {
649
- for (const child of route.children) {
665
+ } else if ("children" in route2 && route2.children) {
666
+ for (const child of route2.children) {
650
667
  processRoute(child, currentPath, currentMiddleware);
651
668
  }
652
669
  }
653
670
  }
654
- for (const route of routes) {
655
- processRoute(route);
671
+ for (const route2 of routes) {
672
+ processRoute(route2);
656
673
  }
657
674
  return flattened;
658
675
  }
@@ -880,9 +897,9 @@ var ComponentServer = class extends BaseServer {
880
897
  return new Response("Method Not Allowed", { status: 405 });
881
898
  }
882
899
  let matchedRoute = null;
883
- for (const route of this.routes) {
884
- if (PathMatcher.matchPath(route.fullPath, pathname)) {
885
- matchedRoute = route;
900
+ for (const route2 of this.routes) {
901
+ if (PathMatcher.matchPath(route2.fullPath, pathname)) {
902
+ matchedRoute = route2;
886
903
  break;
887
904
  }
888
905
  }
@@ -1314,7 +1331,7 @@ function createHandler(schemaOrHandler, maybeHandler) {
1314
1331
  if (schema.body || schema.query || schema.params || schema.headers || schema.cookies) {
1315
1332
  precompileSchemas(schema);
1316
1333
  }
1317
- return async (req) => {
1334
+ const handlerFn = async (req) => {
1318
1335
  try {
1319
1336
  const query = parseQuery(req);
1320
1337
  const headers = parseHeaders(req);
@@ -1345,6 +1362,7 @@ function createHandler(schemaOrHandler, maybeHandler) {
1345
1362
  return handleInternalError(error);
1346
1363
  }
1347
1364
  };
1365
+ return handlerFn;
1348
1366
  }
1349
1367
  function createHandlerWithExtra(schemaOrHandler, maybeHandler) {
1350
1368
  const hasSchema = !isHandler(schemaOrHandler);
@@ -1587,6 +1605,225 @@ var Patterns = {
1587
1605
  JWT: JWT_REGEX
1588
1606
  };
1589
1607
 
1608
+ // src/utils/sse.ts
1609
+ function formatSSEEvent(event) {
1610
+ const lines = [];
1611
+ if (event.id !== void 0) {
1612
+ lines.push(`id: ${event.id}`);
1613
+ }
1614
+ if (event.event !== void 0) {
1615
+ lines.push(`event: ${event.event}`);
1616
+ }
1617
+ if (event.retry !== void 0) {
1618
+ lines.push(`retry: ${event.retry}`);
1619
+ }
1620
+ const dataStr = typeof event.data === "string" ? event.data : JSON.stringify(event.data);
1621
+ const dataLines = dataStr.split("\n");
1622
+ for (const line of dataLines) {
1623
+ lines.push(`data: ${line}`);
1624
+ }
1625
+ return lines.join("\n") + "\n\n";
1626
+ }
1627
+ function createSSEHandler(schemaOrGenerator, maybeGenerator) {
1628
+ const hasSchema = typeof schemaOrGenerator !== "function";
1629
+ const schema = hasSchema ? schemaOrGenerator : {};
1630
+ const generator = hasSchema ? maybeGenerator : schemaOrGenerator;
1631
+ if (schema.body || schema.query || schema.params || schema.headers || schema.cookies) {
1632
+ precompileSchemas(schema);
1633
+ }
1634
+ const handlerFn = async (req) => {
1635
+ try {
1636
+ const query = parseQuery(req);
1637
+ const headers = parseHeaders(req);
1638
+ const cookies = parseCookies(req);
1639
+ const params = req.params || {};
1640
+ const data = { body: void 0, query, params, headers, cookies };
1641
+ if (schema.body || schema.query || schema.params || schema.headers || schema.cookies) {
1642
+ validateAllSchemas(schema, data);
1643
+ }
1644
+ const stream2 = new ReadableStream({
1645
+ async start(controller) {
1646
+ const encoder2 = new TextEncoder();
1647
+ try {
1648
+ const gen = generator({
1649
+ req,
1650
+ body: void 0,
1651
+ query,
1652
+ params,
1653
+ headers,
1654
+ cookies
1655
+ });
1656
+ for await (const event of gen) {
1657
+ const formatted = formatSSEEvent(event);
1658
+ controller.enqueue(encoder2.encode(formatted));
1659
+ }
1660
+ } catch (error) {
1661
+ const errorEvent = formatSSEEvent({
1662
+ event: "error",
1663
+ data: {
1664
+ message: error instanceof Error ? error.message : "Unknown error"
1665
+ }
1666
+ });
1667
+ controller.enqueue(encoder2.encode(errorEvent));
1668
+ } finally {
1669
+ controller.close();
1670
+ }
1671
+ }
1672
+ });
1673
+ return new Response(stream2, {
1674
+ headers: {
1675
+ "Content-Type": "text/event-stream",
1676
+ "Cache-Control": "no-cache",
1677
+ "Connection": "keep-alive",
1678
+ "X-Accel-Buffering": "no"
1679
+ // Nginx 禁用缓冲
1680
+ }
1681
+ });
1682
+ } catch (error) {
1683
+ return new Response(
1684
+ JSON.stringify({
1685
+ success: false,
1686
+ error: "Validation Error",
1687
+ message: error instanceof Error ? error.message : "Unknown error"
1688
+ }),
1689
+ {
1690
+ status: 400,
1691
+ headers: { "Content-Type": "application/json" }
1692
+ }
1693
+ );
1694
+ }
1695
+ };
1696
+ const handler = handlerFn;
1697
+ handler.__sse = { __brand: "SSE" };
1698
+ handler.__schema = schema;
1699
+ handler.__returnType = void 0;
1700
+ return handler;
1701
+ }
1702
+
1703
+ // src/utils/route-registry.ts
1704
+ var RouteRegistry = class {
1705
+ /** 所有路由元信息 */
1706
+ routes = [];
1707
+ /** 路由映射表:METHOD:fullPath -> RouteMeta */
1708
+ routeMap = /* @__PURE__ */ new Map();
1709
+ /** 分类映射表:category -> RouteMeta[] */
1710
+ categoryMap = /* @__PURE__ */ new Map();
1711
+ constructor(routes) {
1712
+ this.buildRegistry(routes);
1713
+ }
1714
+ /**
1715
+ * 构建注册表
1716
+ */
1717
+ buildRegistry(routes) {
1718
+ for (const route2 of routes) {
1719
+ const meta = {
1720
+ method: route2.method,
1721
+ path: route2.path,
1722
+ fullPath: route2.fullPath,
1723
+ name: route2.name,
1724
+ description: route2.description
1725
+ };
1726
+ for (const key of Object.keys(route2)) {
1727
+ if (!["method", "path", "fullPath", "name", "description", "handler", "middleware", "middlewareChain"].includes(key)) {
1728
+ meta[key] = route2[key];
1729
+ }
1730
+ }
1731
+ this.routes.push(meta);
1732
+ this.routeMap.set(`${route2.method}:${route2.fullPath}`, meta);
1733
+ const category = this.extractCategory(route2.fullPath);
1734
+ if (!this.categoryMap.has(category)) {
1735
+ this.categoryMap.set(category, []);
1736
+ }
1737
+ this.categoryMap.get(category).push(meta);
1738
+ }
1739
+ }
1740
+ /**
1741
+ * 提取分类(第一段路径)
1742
+ */
1743
+ extractCategory(path) {
1744
+ const segments = path.split("/").filter(Boolean);
1745
+ return segments[0] || "root";
1746
+ }
1747
+ // ============================================
1748
+ // 查询接口
1749
+ // ============================================
1750
+ /**
1751
+ * 获取所有路由元信息
1752
+ */
1753
+ getAll() {
1754
+ return [...this.routes];
1755
+ }
1756
+ /**
1757
+ * 按 method + path 查询路由
1758
+ */
1759
+ get(method, path) {
1760
+ return this.routeMap.get(`${method}:${path}`);
1761
+ }
1762
+ /**
1763
+ * 检查路由是否存在
1764
+ */
1765
+ has(method, path) {
1766
+ return this.routeMap.has(`${method}:${path}`);
1767
+ }
1768
+ /**
1769
+ * 按分类获取路由
1770
+ */
1771
+ getByCategory(category) {
1772
+ return this.categoryMap.get(category) || [];
1773
+ }
1774
+ /**
1775
+ * 获取所有分类
1776
+ */
1777
+ getCategories() {
1778
+ return Array.from(this.categoryMap.keys()).sort();
1779
+ }
1780
+ /**
1781
+ * 筛选有特定字段的路由
1782
+ *
1783
+ * @example
1784
+ * ```typescript
1785
+ * // 获取所有配置了 webhook 的路由
1786
+ * const webhookRoutes = registry.filter('webhook')
1787
+ * ```
1788
+ */
1789
+ filter(field) {
1790
+ return this.routes.filter((r) => field in r && r[field] !== void 0);
1791
+ }
1792
+ /**
1793
+ * 按条件筛选路由
1794
+ *
1795
+ * @example
1796
+ * ```typescript
1797
+ * // 获取所有 POST 请求
1798
+ * const postRoutes = registry.filterBy(r => r.method === 'POST')
1799
+ * ```
1800
+ */
1801
+ filterBy(predicate) {
1802
+ return this.routes.filter(predicate);
1803
+ }
1804
+ /**
1805
+ * 获取路由数量
1806
+ */
1807
+ get size() {
1808
+ return this.routes.length;
1809
+ }
1810
+ /**
1811
+ * 遍历所有路由
1812
+ */
1813
+ forEach(callback) {
1814
+ this.routes.forEach(callback);
1815
+ }
1816
+ /**
1817
+ * 映射所有路由
1818
+ */
1819
+ map(callback) {
1820
+ return this.routes.map(callback);
1821
+ }
1822
+ };
1823
+ function createRouteRegistry(routes) {
1824
+ return new RouteRegistry(routes);
1825
+ }
1826
+
1590
1827
  // src/middleware/authMiddleware.ts
1591
1828
  var requireAuth = async (req, next) => {
1592
1829
  const token = getCookie2(req, "auth");
@@ -1885,6 +2122,29 @@ function createPermissionAuth(permissions, options) {
1885
2122
  }
1886
2123
 
1887
2124
  // src/defineRoute.ts
2125
+ function route(method, path, handler, middleware) {
2126
+ return {
2127
+ method,
2128
+ path,
2129
+ handler,
2130
+ middleware
2131
+ };
2132
+ }
2133
+ function get(path, handler, middleware) {
2134
+ return route("GET", path, handler, middleware);
2135
+ }
2136
+ function post(path, handler, middleware) {
2137
+ return route("POST", path, handler, middleware);
2138
+ }
2139
+ function put(path, handler, middleware) {
2140
+ return route("PUT", path, handler, middleware);
2141
+ }
2142
+ function del(path, handler, middleware) {
2143
+ return route("DELETE", path, handler, middleware);
2144
+ }
2145
+ function patch(path, handler, middleware) {
2146
+ return route("PATCH", path, handler, middleware);
2147
+ }
1888
2148
  function defineRoutes(routes) {
1889
2149
  return routes;
1890
2150
  }
@@ -1893,8 +2153,8 @@ function defineRoutes(routes) {
1893
2153
  function createTypedRoute(config) {
1894
2154
  return config;
1895
2155
  }
1896
- function isTypedRoute(route) {
1897
- return route && typeof route === "object" && "method" in route && "path" in route && "handler" in route;
2156
+ function isTypedRoute(route2) {
2157
+ return route2 && typeof route2 === "object" && "method" in route2 && "path" in route2 && "handler" in route2;
1898
2158
  }
1899
2159
 
1900
2160
  // src/node-server/serve.ts
@@ -2108,10 +2368,53 @@ function createRequestHandler(fetch, defaultHost, onError) {
2108
2368
  };
2109
2369
  }
2110
2370
  function serve(options, callback) {
2111
- const { fetch, port = 3e3, hostname = "0.0.0.0", onError } = options;
2371
+ const { fetch, port = 3e3, hostname = "0.0.0.0", onError, gracefulShutdown } = options;
2112
2372
  const defaultHost = `${hostname === "0.0.0.0" ? "localhost" : hostname}:${port}`;
2113
2373
  const handler = createRequestHandler(fetch, defaultHost, onError);
2114
2374
  const server = createServer(handler);
2375
+ const connections = /* @__PURE__ */ new Set();
2376
+ server.on("connection", (socket) => {
2377
+ connections.add(socket);
2378
+ socket.on("close", () => connections.delete(socket));
2379
+ });
2380
+ let isShuttingDown = false;
2381
+ const shutdown = async () => {
2382
+ if (isShuttingDown) return;
2383
+ isShuttingDown = true;
2384
+ const shutdownOptions = typeof gracefulShutdown === "object" ? gracefulShutdown : {};
2385
+ const timeout = shutdownOptions.timeout ?? 3e4;
2386
+ if (shutdownOptions.onShutdown) {
2387
+ await shutdownOptions.onShutdown();
2388
+ }
2389
+ return new Promise((resolve) => {
2390
+ const forceCloseTimer = setTimeout(() => {
2391
+ for (const socket of connections) {
2392
+ socket.destroy();
2393
+ }
2394
+ connections.clear();
2395
+ resolve();
2396
+ }, timeout);
2397
+ server.close(() => {
2398
+ clearTimeout(forceCloseTimer);
2399
+ shutdownOptions.onShutdownComplete?.();
2400
+ resolve();
2401
+ });
2402
+ for (const socket of connections) {
2403
+ if (!socket.writableLength) {
2404
+ socket.end();
2405
+ }
2406
+ }
2407
+ });
2408
+ };
2409
+ if (gracefulShutdown) {
2410
+ const shutdownOptions = typeof gracefulShutdown === "object" ? gracefulShutdown : {};
2411
+ const signals = shutdownOptions.signals ?? ["SIGINT", "SIGTERM"];
2412
+ for (const signal of signals) {
2413
+ process.on(signal, () => {
2414
+ shutdown().then(() => process.exit(0));
2415
+ });
2416
+ }
2417
+ }
2115
2418
  server.listen(port, hostname, callback);
2116
2419
  return {
2117
2420
  server,
@@ -2122,7 +2425,8 @@ function serve(options, callback) {
2122
2425
  if (err) reject(err);
2123
2426
  else resolve();
2124
2427
  });
2125
- })
2428
+ }),
2429
+ shutdown
2126
2430
  };
2127
2431
  }
2128
2432
 
@@ -2136,6 +2440,7 @@ export {
2136
2440
  FormatRegistry2 as FormatRegistry,
2137
2441
  HtmlRenderer,
2138
2442
  Patterns,
2443
+ RouteRegistry,
2139
2444
  Server,
2140
2445
  ServerFactory,
2141
2446
  TokenError,
@@ -2152,13 +2457,17 @@ export {
2152
2457
  createPermissionAuth,
2153
2458
  createRequestValidator,
2154
2459
  createRoleAuth,
2460
+ createRouteRegistry,
2461
+ createSSEHandler,
2155
2462
  createTokenPair,
2156
2463
  createTypedRoute,
2157
2464
  createValidator,
2158
2465
  defineRoutes,
2466
+ del,
2159
2467
  empty,
2160
2468
  flattenNestedRoutes,
2161
2469
  generateToken,
2470
+ get,
2162
2471
  getCookie,
2163
2472
  getHeader,
2164
2473
  getLocals,
@@ -2180,13 +2489,17 @@ export {
2180
2489
  parseQueryFast,
2181
2490
  parseRequest,
2182
2491
  parseToken,
2492
+ patch,
2493
+ post,
2183
2494
  precompileSchemas,
2495
+ put,
2184
2496
  rateLimit,
2185
2497
  redirect,
2186
2498
  refreshToken,
2187
2499
  registerFormat,
2188
2500
  registerFormats,
2189
2501
  requireAuth,
2502
+ route,
2190
2503
  serve,
2191
2504
  setLocals,
2192
2505
  simpleHandler,