@orpc/openapi 0.0.0-next.aa57fb6 → 0.0.0-next.c29cb6d

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/fetch.js CHANGED
@@ -1,703 +1,591 @@
1
1
  import {
2
- eachContractProcedureLeaf
3
- } from "./chunk-KZIT2WCV.js";
2
+ JSONSerializer,
3
+ forEachContractProcedure,
4
+ standardizeHTTPPath
5
+ } from "./chunk-KNYXLM77.js";
4
6
 
5
- // src/fetch/base-handler.ts
6
- import { ORPC_HEADER, standardizeHTTPPath } from "@orpc/contract";
7
- import { createProcedureCaller, isLazy, isProcedure, LAZY_LOADER_SYMBOL, LAZY_ROUTER_PREFIX_SYMBOL, ORPCError } from "@orpc/server";
8
- import { isPlainObject, mapValues, trim, value } from "@orpc/shared";
9
- import { OpenAPIDeserializer, OpenAPISerializer, zodCoerce } from "@orpc/transformer";
10
- function createOpenAPIHandler(createHonoRouter) {
11
- const resolveRouter = createResolveRouter(createHonoRouter);
12
- return async (options) => {
13
- if (options.request.headers.get(ORPC_HEADER) !== null) {
14
- return void 0;
15
- }
16
- const context = await value(options.context);
17
- const accept = options.request.headers.get("Accept") || void 0;
18
- const serializer = new OpenAPISerializer({ accept });
19
- const handler = async () => {
20
- const url = new URL(options.request.url);
21
- const pathname = `/${trim(url.pathname.replace(options.prefix ?? "", ""), "/")}`;
22
- const customMethod = options.request.method === "POST" ? url.searchParams.get("method")?.toUpperCase() : void 0;
23
- const method = customMethod || options.request.method;
24
- const match = await resolveRouter(options.router, method, pathname);
25
- if (!match) {
26
- throw new ORPCError({ code: "NOT_FOUND", message: "Not found" });
27
- }
28
- const procedure = isLazy(match.procedure) ? (await match.procedure[LAZY_LOADER_SYMBOL]()).default : match.procedure;
29
- const path = match.path;
30
- if (!isProcedure(procedure)) {
31
- throw new ORPCError({
32
- code: "NOT_FOUND",
33
- message: "Not found"
34
- });
35
- }
36
- const params = procedure.zz$p.contract.zz$cp.InputSchema ? zodCoerce(
37
- procedure.zz$p.contract.zz$cp.InputSchema,
38
- match.params,
39
- { bracketNotation: true }
40
- ) : match.params;
41
- const input = await deserializeInput(options.request, procedure);
42
- const mergedInput = mergeParamsAndInput(params, input);
43
- const caller = createProcedureCaller({
44
- context,
45
- procedure,
46
- path
7
+ // src/fetch/bracket-notation.ts
8
+ import { isPlainObject } from "@orpc/shared";
9
+ function serialize(payload, parentKey = "") {
10
+ if (!Array.isArray(payload) && !isPlainObject(payload))
11
+ return [["", payload]];
12
+ const result = [];
13
+ function helper(value, path) {
14
+ if (Array.isArray(value)) {
15
+ value.forEach((item, index) => {
16
+ helper(item, [...path, String(index)]);
47
17
  });
48
- const output = await caller(mergedInput);
49
- const { body, headers } = serializer.serialize(output);
50
- return new Response(body, {
51
- status: 200,
52
- headers
53
- });
54
- };
55
- try {
56
- return await options.hooks?.(context, {
57
- next: handler,
58
- response: (response) => response
59
- }) ?? await handler();
60
- } catch (e) {
61
- const error = toORPCError(e);
62
- try {
63
- const { body, headers } = serializer.serialize(error.toJSON());
64
- return new Response(body, {
65
- status: error.status,
66
- headers
67
- });
68
- } catch (e2) {
69
- const error2 = toORPCError(e2);
70
- const { body, headers } = new OpenAPISerializer().serialize(
71
- error2.toJSON()
72
- );
73
- return new Response(body, {
74
- status: error2.status,
75
- headers
76
- });
18
+ } else if (isPlainObject(value)) {
19
+ for (const [key, val] of Object.entries(value)) {
20
+ helper(val, [...path, key]);
77
21
  }
22
+ } else {
23
+ result.push([stringifyPath(path), value]);
78
24
  }
79
- };
25
+ }
26
+ helper(payload, parentKey ? [parentKey] : []);
27
+ return result;
80
28
  }
81
- var routingCache = /* @__PURE__ */ new Map();
82
- var pendingCache = /* @__PURE__ */ new Map();
83
- function createResolveRouter(createHonoRouter) {
84
- const addRoutes = (routing, pending, options) => {
85
- const lazies = eachContractProcedureLeaf(options, ({ path, contract }) => {
86
- const method = contract.zz$cp.method ?? "POST";
87
- const httpPath = contract.zz$cp.path ? openAPIPathToRouterPath(contract.zz$cp.path) : `/${path.map(encodeURIComponent).join("/")}`;
88
- routing.add(method, httpPath, path);
89
- });
90
- pending.ref.push(...lazies);
91
- };
92
- return async (router, method, pathname) => {
93
- const pending = (() => {
94
- let pending2 = pendingCache.get(router);
95
- if (!pending2) {
96
- pending2 = { ref: [] };
97
- pendingCache.set(router, pending2);
98
- }
99
- return pending2;
100
- })();
101
- const routing = (() => {
102
- let routing2 = routingCache.get(router);
103
- if (!routing2) {
104
- routing2 = createHonoRouter();
105
- routingCache.set(router, routing2);
106
- addRoutes(routing2, pending, { router, path: [] });
107
- }
108
- return routing2;
109
- })();
110
- const newPending = [];
111
- for (const item of pending.ref) {
112
- if (LAZY_ROUTER_PREFIX_SYMBOL in item.lazy && item.lazy[LAZY_ROUTER_PREFIX_SYMBOL] && !pathname.startsWith(item.lazy[LAZY_ROUTER_PREFIX_SYMBOL]) && !pathname.startsWith(`/${item.path.map(encodeURIComponent).join("/")}`)) {
113
- newPending.push(item);
114
- continue;
115
- }
116
- const router2 = (await item.lazy[LAZY_LOADER_SYMBOL]()).default;
117
- addRoutes(routing, pending, { path: item.path, router: router2 });
29
+ function deserialize(entities) {
30
+ if (entities.length === 0) {
31
+ return void 0;
32
+ }
33
+ const isRootArray = entities.every(([path]) => path === "");
34
+ const result = isRootArray ? [] : {};
35
+ const arrayPushPaths = /* @__PURE__ */ new Set();
36
+ for (const [path, _] of entities) {
37
+ const segments = parsePath(path);
38
+ const base = segments.slice(0, -1).join(".");
39
+ const last = segments[segments.length - 1];
40
+ if (last === "") {
41
+ arrayPushPaths.add(base);
42
+ } else {
43
+ arrayPushPaths.delete(base);
118
44
  }
119
- pending.ref = newPending;
120
- const [matches, params_] = routing.match(method, pathname);
121
- const [match] = matches.sort((a, b) => {
122
- return Object.keys(a[1]).length - Object.keys(b[1]).length;
123
- });
124
- if (!match) {
125
- return void 0;
45
+ }
46
+ function setValue(obj, segments, value, fullPath) {
47
+ const [first, ...rest_] = segments;
48
+ if (Array.isArray(obj) && first === "") {
49
+ ;
50
+ obj.push(value);
51
+ return;
126
52
  }
127
- const path = match[0];
128
- const params = params_ ? mapValues(
129
- match[1],
130
- (v) => params_[v]
131
- ) : match[1];
132
- let current = router;
133
- for (const segment of path) {
134
- if (typeof current !== "object" && typeof current !== "function" || !current) {
135
- current = void 0;
136
- break;
53
+ const objAsRecord = obj;
54
+ if (rest_.length === 0) {
55
+ objAsRecord[first] = value;
56
+ return;
57
+ }
58
+ const rest = rest_;
59
+ if (rest[0] === "") {
60
+ const pathToCheck = segments.slice(0, -1).join(".");
61
+ if (rest.length === 1 && arrayPushPaths.has(pathToCheck)) {
62
+ if (!(first in objAsRecord)) {
63
+ objAsRecord[first] = [];
64
+ }
65
+ if (Array.isArray(objAsRecord[first])) {
66
+ ;
67
+ objAsRecord[first].push(value);
68
+ return;
69
+ }
137
70
  }
138
- current = current[segment];
71
+ if (!(first in objAsRecord)) {
72
+ objAsRecord[first] = {};
73
+ }
74
+ const target = objAsRecord[first];
75
+ target[""] = value;
76
+ return;
139
77
  }
140
- return isProcedure(current) || isLazy(current) ? {
141
- path,
142
- procedure: current,
143
- params: { ...params }
144
- // params from hono not a normal object, so we need spread here
145
- } : void 0;
146
- };
147
- }
148
- function mergeParamsAndInput(coercedParams, input) {
149
- if (Object.keys(coercedParams).length === 0) {
150
- return input;
151
- }
152
- if (!isPlainObject(input)) {
153
- return coercedParams;
78
+ if (!(first in objAsRecord)) {
79
+ objAsRecord[first] = {};
80
+ }
81
+ setValue(
82
+ objAsRecord[first],
83
+ rest,
84
+ value,
85
+ fullPath
86
+ );
154
87
  }
155
- return {
156
- ...coercedParams,
157
- ...input
158
- };
159
- }
160
- async function deserializeInput(request, procedure) {
161
- const deserializer = new OpenAPIDeserializer({
162
- schema: procedure.zz$p.contract.zz$cp.InputSchema
163
- });
164
- try {
165
- return await deserializer.deserialize(request);
166
- } catch (e) {
167
- throw new ORPCError({
168
- code: "BAD_REQUEST",
169
- message: "Cannot parse request. Please check the request body and Content-Type header.",
170
- cause: e
171
- });
88
+ for (const [path, value] of entities) {
89
+ const segments = parsePath(path);
90
+ setValue(result, segments, value, path);
172
91
  }
92
+ return result;
173
93
  }
174
- function toORPCError(e) {
175
- return e instanceof ORPCError ? e : new ORPCError({
176
- code: "INTERNAL_SERVER_ERROR",
177
- message: "Internal server error",
178
- cause: e
94
+ function escapeSegment(segment) {
95
+ return segment.replace(/[\\[\]]/g, (match) => {
96
+ switch (match) {
97
+ case "\\":
98
+ return "\\\\";
99
+ case "[":
100
+ return "\\[";
101
+ case "]":
102
+ return "\\]";
103
+ default:
104
+ return match;
105
+ }
179
106
  });
180
107
  }
181
- function openAPIPathToRouterPath(path) {
182
- return standardizeHTTPPath(path).replace(/\{([^}]+)\}/g, ":$1");
108
+ function stringifyPath(path) {
109
+ const [first, ...rest] = path;
110
+ const firstSegment = escapeSegment(first);
111
+ const base = first === "" ? "" : firstSegment;
112
+ return rest.reduce(
113
+ (result, segment) => `${result}[${escapeSegment(segment)}]`,
114
+ base
115
+ );
183
116
  }
184
-
185
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/router.js
186
- var METHOD_NAME_ALL = "ALL";
187
- var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
188
- var UnsupportedPathError = class extends Error {
189
- };
190
-
191
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/utils/url.js
192
- var checkOptionalParameter = (path) => {
193
- if (!path.match(/\:.+\?$/)) {
194
- return null;
195
- }
196
- const segments = path.split("/");
197
- const results = [];
198
- let basePath = "";
199
- segments.forEach((segment) => {
200
- if (segment !== "" && !/\:/.test(segment)) {
201
- basePath += "/" + segment;
202
- } else if (/\:/.test(segment)) {
203
- if (/\?/.test(segment)) {
204
- if (results.length === 0 && basePath === "") {
205
- results.push("/");
117
+ function parsePath(path) {
118
+ if (path === "")
119
+ return [""];
120
+ const result = [];
121
+ let currentSegment = "";
122
+ let inBracket = false;
123
+ let bracketContent = "";
124
+ let backslashCount = 0;
125
+ for (let i = 0; i < path.length; i++) {
126
+ const char = path[i];
127
+ if (char === "\\") {
128
+ backslashCount++;
129
+ continue;
130
+ }
131
+ if (backslashCount > 0) {
132
+ const literalBackslashes = "\\".repeat(Math.floor(backslashCount / 2));
133
+ if (char === "[" || char === "]") {
134
+ if (backslashCount % 2 === 1) {
135
+ if (inBracket) {
136
+ bracketContent += literalBackslashes + char;
137
+ } else {
138
+ currentSegment += literalBackslashes + char;
139
+ }
206
140
  } else {
207
- results.push(basePath);
141
+ if (inBracket) {
142
+ bracketContent += literalBackslashes;
143
+ } else {
144
+ currentSegment += literalBackslashes;
145
+ }
146
+ if (char === "[" && !inBracket) {
147
+ if (currentSegment !== "" || result.length === 0) {
148
+ result.push(currentSegment);
149
+ }
150
+ inBracket = true;
151
+ bracketContent = "";
152
+ currentSegment = "";
153
+ } else if (char === "]" && inBracket) {
154
+ result.push(bracketContent);
155
+ inBracket = false;
156
+ bracketContent = "";
157
+ } else {
158
+ if (inBracket) {
159
+ bracketContent += char;
160
+ } else {
161
+ currentSegment += char;
162
+ }
163
+ }
208
164
  }
209
- const optionalSegment = segment.replace("?", "");
210
- basePath += "/" + optionalSegment;
211
- results.push(basePath);
212
165
  } else {
213
- basePath += "/" + segment;
166
+ const allBackslashes = "\\".repeat(backslashCount);
167
+ if (inBracket) {
168
+ bracketContent += allBackslashes + char;
169
+ } else {
170
+ currentSegment += allBackslashes + char;
171
+ }
214
172
  }
173
+ backslashCount = 0;
174
+ continue;
215
175
  }
216
- });
217
- return results.filter((v, i, a) => a.indexOf(v) === i);
218
- };
219
-
220
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/router/reg-exp-router/node.js
221
- var LABEL_REG_EXP_STR = "[^/]+";
222
- var ONLY_WILDCARD_REG_EXP_STR = ".*";
223
- var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
224
- var PATH_ERROR = Symbol();
225
- var regExpMetaChars = new Set(".\\+*[^]$()");
226
- function compareKey(a, b) {
227
- if (a.length === 1) {
228
- return b.length === 1 ? a < b ? -1 : 1 : -1;
229
- }
230
- if (b.length === 1) {
231
- return 1;
232
- }
233
- if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
234
- return 1;
235
- } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
236
- return -1;
237
- }
238
- if (a === LABEL_REG_EXP_STR) {
239
- return 1;
240
- } else if (b === LABEL_REG_EXP_STR) {
241
- return -1;
242
- }
243
- return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
244
- }
245
- var Node = class {
246
- #index;
247
- #varIndex;
248
- #children = /* @__PURE__ */ Object.create(null);
249
- insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
250
- if (tokens.length === 0) {
251
- if (this.#index !== void 0) {
252
- throw PATH_ERROR;
253
- }
254
- if (pathErrorCheckOnly) {
255
- return;
176
+ if (char === "[" && !inBracket) {
177
+ if (currentSegment !== "" || result.length === 0) {
178
+ result.push(currentSegment);
256
179
  }
257
- this.#index = index;
258
- return;
180
+ inBracket = true;
181
+ bracketContent = "";
182
+ currentSegment = "";
183
+ continue;
259
184
  }
260
- const [token, ...restTokens] = tokens;
261
- const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
262
- let node;
263
- if (pattern) {
264
- const name = pattern[1];
265
- let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
266
- if (name && pattern[2]) {
267
- regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
268
- if (/\((?!\?:)/.test(regexpStr)) {
269
- throw PATH_ERROR;
270
- }
271
- }
272
- node = this.#children[regexpStr];
273
- if (!node) {
274
- if (Object.keys(this.#children).some(
275
- (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
276
- )) {
277
- throw PATH_ERROR;
278
- }
279
- if (pathErrorCheckOnly) {
280
- return;
281
- }
282
- node = this.#children[regexpStr] = new Node();
283
- if (name !== "") {
284
- node.#varIndex = context.varIndex++;
285
- }
286
- }
287
- if (!pathErrorCheckOnly && name !== "") {
288
- paramMap.push([name, node.#varIndex]);
289
- }
185
+ if (char === "]" && inBracket) {
186
+ result.push(bracketContent);
187
+ inBracket = false;
188
+ bracketContent = "";
189
+ continue;
190
+ }
191
+ if (inBracket) {
192
+ bracketContent += char;
290
193
  } else {
291
- node = this.#children[token];
292
- if (!node) {
293
- if (Object.keys(this.#children).some(
294
- (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
295
- )) {
296
- throw PATH_ERROR;
297
- }
298
- if (pathErrorCheckOnly) {
299
- return;
300
- }
301
- node = this.#children[token] = new Node();
302
- }
194
+ currentSegment += char;
303
195
  }
304
- node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
305
196
  }
306
- buildRegExpStr() {
307
- const childKeys = Object.keys(this.#children).sort(compareKey);
308
- const strList = childKeys.map((k) => {
309
- const c = this.#children[k];
310
- return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
311
- });
312
- if (typeof this.#index === "number") {
313
- strList.unshift(`#${this.#index}`);
314
- }
315
- if (strList.length === 0) {
316
- return "";
197
+ if (backslashCount > 0) {
198
+ const remainingBackslashes = "\\".repeat(backslashCount);
199
+ if (inBracket) {
200
+ bracketContent += remainingBackslashes;
201
+ } else {
202
+ currentSegment += remainingBackslashes;
317
203
  }
318
- if (strList.length === 1) {
319
- return strList[0];
204
+ }
205
+ if (inBracket) {
206
+ if (currentSegment !== "" || result.length === 0) {
207
+ result.push(currentSegment);
320
208
  }
321
- return "(?:" + strList.join("|") + ")";
209
+ result.push(`[${bracketContent}`);
210
+ } else if (currentSegment !== "" || result.length === 0) {
211
+ result.push(currentSegment);
212
+ }
213
+ return result;
214
+ }
215
+
216
+ // src/fetch/input-builder-full.ts
217
+ var InputBuilderFull = class {
218
+ build(params, query, headers, body) {
219
+ return {
220
+ params,
221
+ query,
222
+ headers,
223
+ body
224
+ };
322
225
  }
323
226
  };
324
227
 
325
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/router/reg-exp-router/trie.js
326
- var Trie = class {
327
- #context = { varIndex: 0 };
328
- #root = new Node();
329
- insert(path, index, pathErrorCheckOnly) {
330
- const paramAssoc = [];
331
- const groups = [];
332
- for (let i = 0; ; ) {
333
- let replaced = false;
334
- path = path.replace(/\{[^}]+\}/g, (m) => {
335
- const mark = `@\\${i}`;
336
- groups[i] = [mark, m];
337
- i++;
338
- replaced = true;
339
- return mark;
340
- });
341
- if (!replaced) {
342
- break;
343
- }
228
+ // src/fetch/input-builder-simple.ts
229
+ import { isPlainObject as isPlainObject2 } from "@orpc/shared";
230
+ var InputBuilderSimple = class {
231
+ build(params, payload) {
232
+ if (Object.keys(params).length === 0) {
233
+ return payload;
344
234
  }
345
- const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
346
- for (let i = groups.length - 1; i >= 0; i--) {
347
- const [mark] = groups[i];
348
- for (let j = tokens.length - 1; j >= 0; j--) {
349
- if (tokens[j].indexOf(mark) !== -1) {
350
- tokens[j] = tokens[j].replace(mark, groups[i][1]);
351
- break;
352
- }
353
- }
235
+ if (!isPlainObject2(payload)) {
236
+ return params;
354
237
  }
355
- this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
356
- return paramAssoc;
357
- }
358
- buildRegExp() {
359
- let regexp = this.#root.buildRegExpStr();
360
- if (regexp === "") {
361
- return [/^$/, [], []];
362
- }
363
- let captureIndex = 0;
364
- const indexReplacementMap = [];
365
- const paramReplacementMap = [];
366
- regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
367
- if (handlerIndex !== void 0) {
368
- indexReplacementMap[++captureIndex] = Number(handlerIndex);
369
- return "$()";
370
- }
371
- if (paramIndex !== void 0) {
372
- paramReplacementMap[Number(paramIndex)] = ++captureIndex;
373
- return "";
374
- }
375
- return "";
376
- });
377
- return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
238
+ return {
239
+ ...params,
240
+ ...payload
241
+ };
378
242
  }
379
243
  };
380
244
 
381
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/router/reg-exp-router/router.js
382
- var emptyParam = [];
383
- var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
384
- var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
385
- function buildWildcardRegExp(path) {
386
- return wildcardRegExpCache[path] ??= new RegExp(
387
- path === "*" ? "" : `^${path.replace(
388
- /\/\*$|([.\\+*[^\]$()])/g,
389
- (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
390
- )}$`
391
- );
392
- }
393
- function clearWildcardRegExpCache() {
394
- wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
395
- }
396
- function buildMatcherFromPreprocessedRoutes(routes) {
397
- const trie = new Trie();
398
- const handlerData = [];
399
- if (routes.length === 0) {
400
- return nullMatcher;
245
+ // src/fetch/openapi-handler.ts
246
+ import { createProcedureClient, ORPCError as ORPCError2 } from "@orpc/server";
247
+ import { executeWithHooks, ORPC_HANDLER_HEADER, trim } from "@orpc/shared";
248
+
249
+ // src/fetch/openapi-payload-codec.ts
250
+ import { ORPCError } from "@orpc/server";
251
+ import { findDeepMatches } from "@orpc/shared";
252
+ import cd from "content-disposition";
253
+ import { safeParse } from "fast-content-type-parse";
254
+ import wcmatch from "wildcard-match";
255
+ var OpenAPIPayloadCodec = class {
256
+ constructor(jsonSerializer) {
257
+ this.jsonSerializer = jsonSerializer;
401
258
  }
402
- const routesWithStaticPathFlag = routes.map(
403
- (route) => [!/\*|\/:/.test(route[0]), ...route]
404
- ).sort(
405
- ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
406
- );
407
- const staticMap = /* @__PURE__ */ Object.create(null);
408
- for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
409
- const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
410
- if (pathErrorCheckOnly) {
411
- staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
412
- } else {
413
- j++;
259
+ encode(payload, accept) {
260
+ const typeMatchers = (accept?.split(",").map(safeParse) ?? [{ type: "*/*" }]).map(({ type }) => wcmatch(type));
261
+ if (payload instanceof Blob) {
262
+ const contentType = payload.type || "application/octet-stream";
263
+ if (typeMatchers.some((isMatch) => isMatch(contentType))) {
264
+ const headers = new Headers({
265
+ "Content-Type": contentType
266
+ });
267
+ if (payload instanceof File && payload.name) {
268
+ headers.append("Content-Disposition", cd(payload.name));
269
+ }
270
+ return {
271
+ body: payload,
272
+ headers
273
+ };
274
+ }
414
275
  }
415
- let paramAssoc;
416
- try {
417
- paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
418
- } catch (e) {
419
- throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
276
+ const handledPayload = this.jsonSerializer.serialize(payload);
277
+ const hasBlobs = findDeepMatches((v) => v instanceof Blob, handledPayload).values.length > 0;
278
+ const isExpectedMultipartFormData = typeMatchers.some(
279
+ (isMatch) => isMatch("multipart/form-data")
280
+ );
281
+ if (hasBlobs && isExpectedMultipartFormData) {
282
+ return this.encodeAsFormData(handledPayload);
420
283
  }
421
- if (pathErrorCheckOnly) {
422
- continue;
284
+ if (typeMatchers.some((isMatch) => isMatch("application/json"))) {
285
+ return this.encodeAsJSON(handledPayload);
423
286
  }
424
- handlerData[j] = handlers.map(([h, paramCount]) => {
425
- const paramIndexMap = /* @__PURE__ */ Object.create(null);
426
- paramCount -= 1;
427
- for (; paramCount >= 0; paramCount--) {
428
- const [key, value2] = paramAssoc[paramCount];
429
- paramIndexMap[key] = value2;
430
- }
431
- return [h, paramIndexMap];
287
+ if (typeMatchers.some(
288
+ (isMatch) => isMatch("application/x-www-form-urlencoded")
289
+ )) {
290
+ return this.encodeAsURLSearchParams(handledPayload);
291
+ }
292
+ if (isExpectedMultipartFormData) {
293
+ return this.encodeAsFormData(handledPayload);
294
+ }
295
+ throw new ORPCError({
296
+ code: "NOT_ACCEPTABLE",
297
+ message: `Unsupported content-type: ${accept}`
432
298
  });
433
299
  }
434
- const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
435
- for (let i = 0, len = handlerData.length; i < len; i++) {
436
- for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
437
- const map = handlerData[i][j]?.[1];
438
- if (!map) {
439
- continue;
440
- }
441
- const keys = Object.keys(map);
442
- for (let k = 0, len3 = keys.length; k < len3; k++) {
443
- map[keys[k]] = paramReplacementMap[map[keys[k]]];
444
- }
300
+ encodeAsJSON(payload) {
301
+ if (payload === void 0) {
302
+ return {
303
+ body: void 0,
304
+ headers: new Headers({
305
+ "content-type": "application/json"
306
+ })
307
+ };
445
308
  }
309
+ return {
310
+ body: JSON.stringify(payload),
311
+ headers: new Headers({
312
+ "content-type": "application/json"
313
+ })
314
+ };
446
315
  }
447
- const handlerMap = [];
448
- for (const i in indexReplacementMap) {
449
- handlerMap[i] = handlerData[indexReplacementMap[i]];
450
- }
451
- return [regexp, handlerMap, staticMap];
452
- }
453
- function findMiddleware(middleware, path) {
454
- if (!middleware) {
455
- return void 0;
456
- }
457
- for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
458
- if (buildWildcardRegExp(k).test(path)) {
459
- return [...middleware[k]];
316
+ encodeAsFormData(payload) {
317
+ const form = new FormData();
318
+ for (const [path, value] of serialize(payload)) {
319
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
320
+ form.append(path, value.toString());
321
+ } else if (value === null) {
322
+ form.append(path, "null");
323
+ } else if (value instanceof Date) {
324
+ form.append(
325
+ path,
326
+ Number.isNaN(value.getTime()) ? "Invalid Date" : value.toISOString()
327
+ );
328
+ } else if (value instanceof Blob) {
329
+ form.append(path, value);
330
+ }
460
331
  }
332
+ return {
333
+ body: form
334
+ };
461
335
  }
462
- return void 0;
463
- }
464
- var RegExpRouter = class {
465
- name = "RegExpRouter";
466
- #middleware;
467
- #routes;
468
- constructor() {
469
- this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
470
- this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
336
+ encodeAsURLSearchParams(payload) {
337
+ const params = new URLSearchParams();
338
+ for (const [path, value] of serialize(payload)) {
339
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
340
+ params.append(path, value.toString());
341
+ } else if (value === null) {
342
+ params.append(path, "null");
343
+ } else if (value instanceof Date) {
344
+ params.append(
345
+ path,
346
+ Number.isNaN(value.getTime()) ? "Invalid Date" : value.toISOString()
347
+ );
348
+ }
349
+ }
350
+ return {
351
+ body: params.toString(),
352
+ headers: new Headers({
353
+ "content-type": "application/x-www-form-urlencoded"
354
+ })
355
+ };
471
356
  }
472
- add(method, path, handler) {
473
- const middleware = this.#middleware;
474
- const routes = this.#routes;
475
- if (!middleware || !routes) {
476
- throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
357
+ async decode(re) {
358
+ if (re instanceof Headers || re instanceof URLSearchParams || re instanceof FormData) {
359
+ return deserialize([...re.entries()]);
477
360
  }
478
- if (!middleware[method]) {
479
- ;
480
- [middleware, routes].forEach((handlerMap) => {
481
- handlerMap[method] = /* @__PURE__ */ Object.create(null);
482
- Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
483
- handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
484
- });
361
+ const contentType = re.headers.get("content-type");
362
+ const contentDisposition = re.headers.get("content-disposition");
363
+ const fileName = contentDisposition ? cd.parse(contentDisposition).parameters.filename : void 0;
364
+ if (fileName) {
365
+ const blob2 = await re.blob();
366
+ const file = new File([blob2], fileName, {
367
+ type: blob2.type
485
368
  });
369
+ return file;
486
370
  }
487
- if (path === "/*") {
488
- path = "*";
489
- }
490
- const paramCount = (path.match(/\/:/g) || []).length;
491
- if (/\*$/.test(path)) {
492
- const re = buildWildcardRegExp(path);
493
- if (method === METHOD_NAME_ALL) {
494
- Object.keys(middleware).forEach((m) => {
495
- middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
496
- });
497
- } else {
498
- middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
371
+ if (!contentType || contentType.startsWith("application/json")) {
372
+ if (!re.body) {
373
+ return void 0;
499
374
  }
500
- Object.keys(middleware).forEach((m) => {
501
- if (method === METHOD_NAME_ALL || method === m) {
502
- Object.keys(middleware[m]).forEach((p) => {
503
- re.test(p) && middleware[m][p].push([handler, paramCount]);
504
- });
505
- }
506
- });
507
- Object.keys(routes).forEach((m) => {
508
- if (method === METHOD_NAME_ALL || method === m) {
509
- Object.keys(routes[m]).forEach(
510
- (p) => re.test(p) && routes[m][p].push([handler, paramCount])
511
- );
512
- }
513
- });
514
- return;
375
+ return await re.json();
515
376
  }
516
- const paths = checkOptionalParameter(path) || [path];
517
- for (let i = 0, len = paths.length; i < len; i++) {
518
- const path2 = paths[i];
519
- Object.keys(routes).forEach((m) => {
520
- if (method === METHOD_NAME_ALL || method === m) {
521
- routes[m][path2] ||= [
522
- ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
523
- ];
524
- routes[m][path2].push([handler, paramCount - len + i + 1]);
525
- }
526
- });
377
+ if (contentType.startsWith("application/x-www-form-urlencoded")) {
378
+ const params = new URLSearchParams(await re.text());
379
+ return this.decode(params);
527
380
  }
381
+ if (contentType.startsWith("text/")) {
382
+ const text = await re.text();
383
+ return text;
384
+ }
385
+ if (contentType.startsWith("multipart/form-data")) {
386
+ const form = await re.formData();
387
+ return this.decode(form);
388
+ }
389
+ const blob = await re.blob();
390
+ return new File([blob], "blob", {
391
+ type: blob.type
392
+ });
528
393
  }
529
- match(method, path) {
530
- clearWildcardRegExpCache();
531
- const matchers = this.#buildAllMatchers();
532
- this.match = (method2, path2) => {
533
- const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
534
- const staticMatch = matcher[2][path2];
535
- if (staticMatch) {
536
- return staticMatch;
537
- }
538
- const match = path2.match(matcher[0]);
539
- if (!match) {
540
- return [[], emptyParam];
394
+ };
395
+
396
+ // src/fetch/openapi-procedure-matcher.ts
397
+ import { getLazyRouterPrefix, getRouterChild, isProcedure, unlazy } from "@orpc/server";
398
+ import { mapValues } from "@orpc/shared";
399
+ var OpenAPIProcedureMatcher = class {
400
+ constructor(hono, router) {
401
+ this.hono = hono;
402
+ this.router = router;
403
+ this.pendingRouters = [{ path: [], router }];
404
+ }
405
+ pendingRouters;
406
+ async match(method, pathname) {
407
+ await this.handlePendingRouters(pathname);
408
+ const [matches, paramStash] = this.hono.match(method, pathname);
409
+ const [match] = matches.sort((a, b) => {
410
+ const slashCountA = a[0][0].split("/").length;
411
+ const slashCountB = b[0][0].split("/").length;
412
+ if (slashCountA !== slashCountB) {
413
+ return slashCountB - slashCountA;
541
414
  }
542
- const index = match.indexOf("", 1);
543
- return [matcher[1][index], match];
415
+ const paramsCountA = Object.keys(a[1]).length;
416
+ const paramsCountB = Object.keys(b[1]).length;
417
+ return paramsCountA - paramsCountB;
418
+ });
419
+ if (!match) {
420
+ return void 0;
421
+ }
422
+ const path = match[0][1];
423
+ const params = paramStash ? mapValues(
424
+ match[1],
425
+ // if paramStash is defined, then match[1] is ParamIndexMap
426
+ (v) => paramStash[v]
427
+ ) : match[1];
428
+ const { default: maybeProcedure } = await unlazy(getRouterChild(this.router, ...path));
429
+ if (!isProcedure(maybeProcedure)) {
430
+ return void 0;
431
+ }
432
+ return {
433
+ path,
434
+ procedure: maybeProcedure,
435
+ params: { ...params }
436
+ // normalize params from hono
544
437
  };
545
- return this.match(method, path);
546
438
  }
547
- #buildAllMatchers() {
548
- const matchers = /* @__PURE__ */ Object.create(null);
549
- Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
550
- matchers[method] ||= this.#buildMatcher(method);
439
+ add(path, router) {
440
+ const lazies = forEachContractProcedure({ path, router }, ({ path: path2, contract }) => {
441
+ const method = contract["~orpc"].route?.method ?? "POST";
442
+ const httpPath = contract["~orpc"].route?.path ? this.convertOpenAPIPathToRouterPath(contract["~orpc"].route?.path) : `/${path2.map(encodeURIComponent).join("/")}`;
443
+ this.hono.add(method, httpPath, [httpPath, path2]);
551
444
  });
552
- this.#middleware = this.#routes = void 0;
553
- return matchers;
445
+ this.pendingRouters.push(...lazies);
554
446
  }
555
- #buildMatcher(method) {
556
- const routes = [];
557
- let hasOwnRoute = method === METHOD_NAME_ALL;
558
- [this.#middleware, this.#routes].forEach((r) => {
559
- const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];
560
- if (ownRoute.length !== 0) {
561
- hasOwnRoute ||= true;
562
- routes.push(...ownRoute);
563
- } else if (method !== METHOD_NAME_ALL) {
564
- routes.push(
565
- ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])
566
- );
447
+ async handlePendingRouters(pathname) {
448
+ const newPendingLazyRouters = [];
449
+ for (const item of this.pendingRouters) {
450
+ const lazyPrefix = getLazyRouterPrefix(item.router);
451
+ if (lazyPrefix && !pathname.startsWith(lazyPrefix) && !pathname.startsWith(`/${item.path.map(encodeURIComponent).join("/")}`)) {
452
+ newPendingLazyRouters.push(item);
453
+ continue;
567
454
  }
568
- });
569
- if (!hasOwnRoute) {
570
- return null;
571
- } else {
572
- return buildMatcherFromPreprocessedRoutes(routes);
455
+ const { default: router } = await unlazy(item.router);
456
+ this.add(item.path, router);
573
457
  }
458
+ this.pendingRouters = newPendingLazyRouters;
459
+ }
460
+ convertOpenAPIPathToRouterPath(path) {
461
+ return standardizeHTTPPath(path).replace(/\{([^}]+)\}/g, ":$1");
574
462
  }
575
463
  };
576
464
 
577
- // src/fetch/server-handler.ts
578
- function createOpenAPIServerHandler() {
579
- return createOpenAPIHandler(() => new RegExpRouter());
580
- }
581
-
582
- // ../../node_modules/.pnpm/hono@4.6.12/node_modules/hono/dist/router/linear-router/router.js
583
- var emptyParams = /* @__PURE__ */ Object.create(null);
584
- var splitPathRe = /\/(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/[^\/\?]+|(\?)/g;
585
- var splitByStarRe = /\*/;
586
- var LinearRouter = class {
587
- name = "LinearRouter";
588
- #routes = [];
589
- add(method, path, handler) {
590
- for (let i = 0, paths = checkOptionalParameter(path) || [path], len = paths.length; i < len; i++) {
591
- this.#routes.push([method, paths[i], handler]);
465
+ // src/fetch/schema-coercer.ts
466
+ var CompositeSchemaCoercer = class {
467
+ constructor(coercers) {
468
+ this.coercers = coercers;
469
+ }
470
+ coerce(schema, value) {
471
+ let current = value;
472
+ for (const coercer of this.coercers) {
473
+ current = coercer.coerce(schema, current);
592
474
  }
475
+ return current;
593
476
  }
594
- match(method, path) {
595
- const handlers = [];
596
- ROUTES_LOOP:
597
- for (let i = 0, len = this.#routes.length; i < len; i++) {
598
- const [routeMethod, routePath, handler] = this.#routes[i];
599
- if (routeMethod === method || routeMethod === METHOD_NAME_ALL) {
600
- if (routePath === "*" || routePath === "/*") {
601
- handlers.push([handler, emptyParams]);
602
- continue;
603
- }
604
- const hasStar = routePath.indexOf("*") !== -1;
605
- const hasLabel = routePath.indexOf(":") !== -1;
606
- if (!hasStar && !hasLabel) {
607
- if (routePath === path || routePath + "/" === path) {
608
- handlers.push([handler, emptyParams]);
609
- }
610
- } else if (hasStar && !hasLabel) {
611
- const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
612
- const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe);
613
- const lastIndex = parts.length - 1;
614
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
615
- const part = parts[j];
616
- const index = path.indexOf(part, pos);
617
- if (index !== pos) {
618
- continue ROUTES_LOOP;
619
- }
620
- pos += part.length;
621
- if (j === lastIndex) {
622
- if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
623
- continue ROUTES_LOOP;
624
- }
625
- } else {
626
- const index2 = path.indexOf("/", pos);
627
- if (index2 === -1) {
628
- continue ROUTES_LOOP;
629
- }
630
- pos = index2;
631
- }
632
- }
633
- handlers.push([handler, emptyParams]);
634
- } else if (hasLabel && !hasStar) {
635
- const params = /* @__PURE__ */ Object.create(null);
636
- const parts = routePath.match(splitPathRe);
637
- const lastIndex = parts.length - 1;
638
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
639
- if (pos === -1 || pos >= path.length) {
640
- continue ROUTES_LOOP;
641
- }
642
- const part = parts[j];
643
- if (part.charCodeAt(1) === 58) {
644
- let name = part.slice(2);
645
- let value2;
646
- if (name.charCodeAt(name.length - 1) === 125) {
647
- const openBracePos = name.indexOf("{");
648
- const pattern = name.slice(openBracePos + 1, -1);
649
- const restPath = path.slice(pos + 1);
650
- const match = new RegExp(pattern, "d").exec(restPath);
651
- if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
652
- continue ROUTES_LOOP;
653
- }
654
- name = name.slice(0, openBracePos);
655
- value2 = restPath.slice(...match.indices[0]);
656
- pos += match.indices[0][1] + 1;
657
- } else {
658
- let endValuePos = path.indexOf("/", pos + 1);
659
- if (endValuePos === -1) {
660
- if (pos + 1 === path.length) {
661
- continue ROUTES_LOOP;
662
- }
663
- endValuePos = path.length;
664
- }
665
- value2 = path.slice(pos + 1, endValuePos);
666
- pos = endValuePos;
667
- }
668
- params[name] ||= value2;
669
- } else {
670
- const index = path.indexOf(part, pos);
671
- if (index !== pos) {
672
- continue ROUTES_LOOP;
673
- }
674
- pos += part.length;
675
- }
676
- if (j === lastIndex) {
677
- if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
678
- continue ROUTES_LOOP;
679
- }
680
- }
681
- }
682
- handlers.push([handler, params]);
683
- } else if (hasLabel && hasStar) {
684
- throw new UnsupportedPathError();
685
- }
477
+ };
478
+
479
+ // src/fetch/openapi-handler.ts
480
+ var OpenAPIHandler = class {
481
+ constructor(hono, router, options) {
482
+ this.options = options;
483
+ const jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
484
+ this.procedureMatcher = options?.procedureMatcher ?? new OpenAPIProcedureMatcher(hono, router);
485
+ this.payloadCodec = options?.payloadCodec ?? new OpenAPIPayloadCodec(jsonSerializer);
486
+ this.inputBuilderSimple = options?.inputBuilderSimple ?? new InputBuilderSimple();
487
+ this.inputBuilderFull = options?.inputBuilderFull ?? new InputBuilderFull();
488
+ this.compositeSchemaCoercer = new CompositeSchemaCoercer(options?.schemaCoercers ?? []);
489
+ }
490
+ procedureMatcher;
491
+ payloadCodec;
492
+ inputBuilderSimple;
493
+ inputBuilderFull;
494
+ compositeSchemaCoercer;
495
+ condition(request) {
496
+ return request.headers.get(ORPC_HANDLER_HEADER) === null;
497
+ }
498
+ async fetch(request, ...[options]) {
499
+ const context = options?.context;
500
+ const headers = request.headers;
501
+ const accept = headers.get("Accept") || void 0;
502
+ const execute = async () => {
503
+ const url = new URL(request.url);
504
+ const pathname = `/${trim(url.pathname.replace(options?.prefix ?? "", ""), "/")}`;
505
+ const query = url.searchParams;
506
+ const customMethod = request.method === "POST" ? query.get("method")?.toUpperCase() : void 0;
507
+ const method = customMethod || request.method;
508
+ const match = await this.procedureMatcher.match(method, pathname);
509
+ if (!match) {
510
+ throw new ORPCError2({ code: "NOT_FOUND", message: "Not found" });
511
+ }
512
+ const decodedPayload = request.method === "GET" ? await this.payloadCodec.decode(query) : await this.payloadCodec.decode(request);
513
+ const input = this.inputBuilderSimple.build(match.params, decodedPayload);
514
+ const coercedInput = this.compositeSchemaCoercer.coerce(match.procedure["~orpc"].contract["~orpc"].InputSchema, input);
515
+ const client = createProcedureClient({
516
+ context,
517
+ procedure: match.procedure,
518
+ path: match.path
519
+ });
520
+ const output = await client(coercedInput, { signal: options?.signal });
521
+ const { body, headers: headers2 } = this.payloadCodec.encode(output);
522
+ return new Response(body, { headers: headers2 });
523
+ };
524
+ try {
525
+ return await executeWithHooks({
526
+ context,
527
+ execute,
528
+ input: request,
529
+ hooks: this.options,
530
+ meta: {
531
+ signal: options?.signal
686
532
  }
533
+ });
534
+ } catch (e) {
535
+ const error = this.convertToORPCError(e);
536
+ try {
537
+ const { body, headers: headers2 } = this.payloadCodec.encode(error.toJSON(), accept);
538
+ return new Response(body, {
539
+ status: error.status,
540
+ headers: headers2
541
+ });
542
+ } catch (e2) {
543
+ const error2 = this.convertToORPCError(e2);
544
+ const { body, headers: headers2 } = this.payloadCodec.encode(error2.toJSON());
545
+ return new Response(body, {
546
+ status: error2.status,
547
+ headers: headers2
548
+ });
687
549
  }
688
- return [handlers];
550
+ }
551
+ }
552
+ convertToORPCError(e) {
553
+ return e instanceof ORPCError2 ? e : new ORPCError2({
554
+ code: "INTERNAL_SERVER_ERROR",
555
+ message: "Internal server error",
556
+ cause: e
557
+ });
689
558
  }
690
559
  };
691
560
 
692
- // src/fetch/serverless-handler.ts
693
- function createOpenAPIServerlessHandler() {
694
- return createOpenAPIHandler(() => new LinearRouter());
695
- }
561
+ // src/fetch/openapi-handler-server.ts
562
+ import { TrieRouter } from "hono/router/trie-router";
563
+ var OpenAPIServerHandler = class extends OpenAPIHandler {
564
+ constructor(router, options) {
565
+ super(new TrieRouter(), router, options);
566
+ }
567
+ };
568
+
569
+ // src/fetch/openapi-handler-serverless.ts
570
+ import { LinearRouter } from "hono/router/linear-router";
571
+ var OpenAPIServerlessHandler = class extends OpenAPIHandler {
572
+ constructor(router, options) {
573
+ super(new LinearRouter(), router, options);
574
+ }
575
+ };
696
576
  export {
697
- createOpenAPIHandler,
698
- createOpenAPIServerHandler,
699
- createOpenAPIServerlessHandler,
700
- createResolveRouter,
701
- openAPIPathToRouterPath
577
+ CompositeSchemaCoercer,
578
+ InputBuilderFull,
579
+ InputBuilderSimple,
580
+ OpenAPIHandler,
581
+ OpenAPIPayloadCodec,
582
+ OpenAPIProcedureMatcher,
583
+ OpenAPIServerHandler,
584
+ OpenAPIServerlessHandler,
585
+ deserialize,
586
+ escapeSegment,
587
+ parsePath,
588
+ serialize,
589
+ stringifyPath
702
590
  };
703
591
  //# sourceMappingURL=fetch.js.map