@orpc/openapi 0.0.0-next.9588d75 → 0.0.0-next.9914009

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 (44) hide show
  1. package/dist/chunk-EVWWILO6.js +25 -0
  2. package/dist/chunk-KNYXLM77.js +107 -0
  3. package/dist/{chunk-UPDKQRQG.js → chunk-X2HG5K4J.js} +178 -192
  4. package/dist/fetch.js +10 -7
  5. package/dist/hono.js +34 -0
  6. package/dist/index.js +445 -4503
  7. package/dist/next.js +34 -0
  8. package/dist/node.js +46 -0
  9. package/dist/src/{fetch → adapters/fetch}/index.d.ts +2 -2
  10. package/dist/src/adapters/fetch/input-structure-compact.d.ts +6 -0
  11. package/dist/src/{fetch/input-builder-full.d.ts → adapters/fetch/input-structure-detailed.d.ts} +3 -3
  12. package/dist/src/adapters/fetch/openapi-handler.d.ts +32 -0
  13. package/dist/src/{fetch → adapters/fetch}/openapi-payload-codec.d.ts +4 -2
  14. package/dist/src/adapters/hono/index.d.ts +2 -0
  15. package/dist/src/adapters/next/index.d.ts +2 -0
  16. package/dist/src/adapters/node/index.d.ts +5 -0
  17. package/dist/src/adapters/node/openapi-handler-server.d.ts +7 -0
  18. package/dist/src/adapters/node/openapi-handler-serverless.d.ts +7 -0
  19. package/dist/src/adapters/node/openapi-handler.d.ts +11 -0
  20. package/dist/src/adapters/node/types.d.ts +2 -0
  21. package/dist/src/index.d.ts +10 -1
  22. package/dist/src/json-serializer.d.ts +5 -0
  23. package/dist/src/openapi-content-builder.d.ts +10 -0
  24. package/dist/src/openapi-error.d.ts +3 -0
  25. package/dist/src/openapi-generator.d.ts +67 -0
  26. package/dist/src/openapi-input-structure-parser.d.ts +22 -0
  27. package/dist/src/openapi-output-structure-parser.d.ts +18 -0
  28. package/dist/src/openapi-parameters-builder.d.ts +12 -0
  29. package/dist/src/openapi-path-parser.d.ts +8 -0
  30. package/dist/src/openapi.d.ts +3 -0
  31. package/dist/src/schema-converter.d.ts +16 -0
  32. package/dist/src/schema-utils.d.ts +11 -0
  33. package/dist/src/schema.d.ts +12 -0
  34. package/dist/src/utils.d.ts +1 -0
  35. package/package.json +21 -6
  36. package/dist/src/fetch/input-builder-simple.d.ts +0 -6
  37. package/dist/src/fetch/openapi-handler.d.ts +0 -28
  38. package/dist/src/generator.d.ts +0 -26
  39. package/dist/src/zod-to-json-schema.d.ts +0 -43
  40. /package/dist/src/{fetch → adapters/fetch}/bracket-notation.d.ts +0 -0
  41. /package/dist/src/{fetch → adapters/fetch}/openapi-handler-server.d.ts +0 -0
  42. /package/dist/src/{fetch → adapters/fetch}/openapi-handler-serverless.d.ts +0 -0
  43. /package/dist/src/{fetch → adapters/fetch}/openapi-procedure-matcher.d.ts +0 -0
  44. /package/dist/src/{fetch → adapters/fetch}/schema-coercer.d.ts +0 -0
@@ -0,0 +1,25 @@
1
+ import {
2
+ OpenAPIHandler
3
+ } from "./chunk-X2HG5K4J.js";
4
+
5
+ // src/adapters/fetch/openapi-handler-server.ts
6
+ import { TrieRouter } from "hono/router/trie-router";
7
+ var OpenAPIServerHandler = class extends OpenAPIHandler {
8
+ constructor(router, options) {
9
+ super(new TrieRouter(), router, options);
10
+ }
11
+ };
12
+
13
+ // src/adapters/fetch/openapi-handler-serverless.ts
14
+ import { LinearRouter } from "hono/router/linear-router";
15
+ var OpenAPIServerlessHandler = class extends OpenAPIHandler {
16
+ constructor(router, options) {
17
+ super(new LinearRouter(), router, options);
18
+ }
19
+ };
20
+
21
+ export {
22
+ OpenAPIServerHandler,
23
+ OpenAPIServerlessHandler
24
+ };
25
+ //# sourceMappingURL=chunk-EVWWILO6.js.map
@@ -0,0 +1,107 @@
1
+ // src/json-serializer.ts
2
+ import { isPlainObject } from "@orpc/shared";
3
+ var JSONSerializer = class {
4
+ serialize(payload) {
5
+ if (payload instanceof Set)
6
+ return this.serialize([...payload]);
7
+ if (payload instanceof Map)
8
+ return this.serialize([...payload.entries()]);
9
+ if (Array.isArray(payload)) {
10
+ return payload.map((v) => v === void 0 ? "undefined" : this.serialize(v));
11
+ }
12
+ if (Number.isNaN(payload))
13
+ return "NaN";
14
+ if (typeof payload === "bigint")
15
+ return payload.toString();
16
+ if (payload instanceof Date && Number.isNaN(payload.getTime())) {
17
+ return "Invalid Date";
18
+ }
19
+ if (payload instanceof RegExp)
20
+ return payload.toString();
21
+ if (payload instanceof URL)
22
+ return payload.toString();
23
+ if (!isPlainObject(payload))
24
+ return payload;
25
+ return Object.keys(payload).reduce(
26
+ (carry, key) => {
27
+ const val = payload[key];
28
+ carry[key] = this.serialize(val);
29
+ return carry;
30
+ },
31
+ {}
32
+ );
33
+ }
34
+ };
35
+
36
+ // src/utils.ts
37
+ import { isContractProcedure } from "@orpc/contract";
38
+ import { getRouterContract, isLazy, isProcedure, unlazy } from "@orpc/server";
39
+ function forEachContractProcedure(options, callback, result = [], isCurrentRouterContract = false) {
40
+ const hiddenContract = getRouterContract(options.router);
41
+ if (!isCurrentRouterContract && hiddenContract) {
42
+ return forEachContractProcedure(
43
+ {
44
+ path: options.path,
45
+ router: hiddenContract
46
+ },
47
+ callback,
48
+ result,
49
+ true
50
+ );
51
+ }
52
+ if (isLazy(options.router)) {
53
+ result.push({
54
+ router: options.router,
55
+ path: options.path
56
+ });
57
+ } else if (isProcedure(options.router)) {
58
+ callback({
59
+ contract: options.router["~orpc"].contract,
60
+ path: options.path
61
+ });
62
+ } else if (isContractProcedure(options.router)) {
63
+ callback({
64
+ contract: options.router,
65
+ path: options.path
66
+ });
67
+ } else {
68
+ for (const key in options.router) {
69
+ forEachContractProcedure(
70
+ {
71
+ router: options.router[key],
72
+ path: [...options.path, key]
73
+ },
74
+ callback,
75
+ result
76
+ );
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ async function forEachAllContractProcedure(router, callback) {
82
+ const pending = [{
83
+ path: [],
84
+ router
85
+ }];
86
+ for (const item of pending) {
87
+ const lazies = forEachContractProcedure(item, callback);
88
+ for (const lazy of lazies) {
89
+ const { default: router2 } = await unlazy(lazy.router);
90
+ pending.push({
91
+ path: lazy.path,
92
+ router: router2
93
+ });
94
+ }
95
+ }
96
+ }
97
+ function standardizeHTTPPath(path) {
98
+ return `/${path.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
99
+ }
100
+
101
+ export {
102
+ JSONSerializer,
103
+ forEachContractProcedure,
104
+ forEachAllContractProcedure,
105
+ standardizeHTTPPath
106
+ };
107
+ //# sourceMappingURL=chunk-KNYXLM77.js.map
@@ -1,4 +1,10 @@
1
- // src/fetch/bracket-notation.ts
1
+ import {
2
+ JSONSerializer,
3
+ forEachContractProcedure,
4
+ standardizeHTTPPath
5
+ } from "./chunk-KNYXLM77.js";
6
+
7
+ // src/adapters/fetch/bracket-notation.ts
2
8
  import { isPlainObject } from "@orpc/shared";
3
9
  function serialize(payload, parentKey = "") {
4
10
  if (!Array.isArray(payload) && !isPlainObject(payload))
@@ -207,21 +213,9 @@ function parsePath(path) {
207
213
  return result;
208
214
  }
209
215
 
210
- // src/fetch/input-builder-full.ts
211
- var InputBuilderFull = class {
212
- build(params, query, headers, body) {
213
- return {
214
- params,
215
- query,
216
- headers,
217
- body
218
- };
219
- }
220
- };
221
-
222
- // src/fetch/input-builder-simple.ts
216
+ // src/adapters/fetch/input-structure-compact.ts
223
217
  import { isPlainObject as isPlainObject2 } from "@orpc/shared";
224
- var InputBuilderSimple = class {
218
+ var InputStructureCompact = class {
225
219
  build(params, payload) {
226
220
  if (Object.keys(params).length === 0) {
227
221
  return payload;
@@ -236,17 +230,28 @@ var InputBuilderSimple = class {
236
230
  }
237
231
  };
238
232
 
239
- // src/fetch/openapi-handler.ts
240
- import { createProcedureClient, ORPCError as ORPCError2 } from "@orpc/server";
241
- import { executeWithHooks, ORPC_HANDLER_HEADER, trim } from "@orpc/shared";
233
+ // src/adapters/fetch/input-structure-detailed.ts
234
+ var InputStructureDetailed = class {
235
+ build(params, query, headers, body) {
236
+ return {
237
+ params,
238
+ query,
239
+ headers,
240
+ body
241
+ };
242
+ }
243
+ };
242
244
 
243
- // src/fetch/openapi-payload-codec.ts
245
+ // src/adapters/fetch/openapi-payload-codec.ts
244
246
  import { ORPCError } from "@orpc/server";
245
- import { findDeepMatches, isPlainObject as isPlainObject3 } from "@orpc/shared";
247
+ import { findDeepMatches } from "@orpc/shared";
246
248
  import cd from "content-disposition";
247
249
  import { safeParse } from "fast-content-type-parse";
248
250
  import wcmatch from "wildcard-match";
249
251
  var OpenAPIPayloadCodec = class {
252
+ constructor(jsonSerializer) {
253
+ this.jsonSerializer = jsonSerializer;
254
+ }
250
255
  encode(payload, accept) {
251
256
  const typeMatchers = (accept?.split(",").map(safeParse) ?? [{ type: "*/*" }]).map(({ type }) => wcmatch(type));
252
257
  if (payload instanceof Blob) {
@@ -264,7 +269,7 @@ var OpenAPIPayloadCodec = class {
264
269
  };
265
270
  }
266
271
  }
267
- const handledPayload = this.serialize(payload);
272
+ const handledPayload = this.jsonSerializer.serialize(payload);
268
273
  const hasBlobs = findDeepMatches((v) => v instanceof Blob, handledPayload).values.length > 0;
269
274
  const isExpectedMultipartFormData = typeMatchers.some(
270
275
  (isMatch) => isMatch("multipart/form-data")
@@ -345,129 +350,60 @@ var OpenAPIPayloadCodec = class {
345
350
  })
346
351
  };
347
352
  }
348
- serialize(payload) {
349
- if (payload instanceof Set)
350
- return this.serialize([...payload]);
351
- if (payload instanceof Map)
352
- return this.serialize([...payload.entries()]);
353
- if (Array.isArray(payload)) {
354
- return payload.map((v) => v === void 0 ? "undefined" : this.serialize(v));
355
- }
356
- if (Number.isNaN(payload))
357
- return "NaN";
358
- if (typeof payload === "bigint")
359
- return payload.toString();
360
- if (payload instanceof Date && Number.isNaN(payload.getTime())) {
361
- return "Invalid Date";
362
- }
363
- if (payload instanceof RegExp)
364
- return payload.toString();
365
- if (payload instanceof URL)
366
- return payload.toString();
367
- if (!isPlainObject3(payload))
368
- return payload;
369
- return Object.keys(payload).reduce(
370
- (carry, key) => {
371
- const val = payload[key];
372
- carry[key] = this.serialize(val);
373
- return carry;
374
- },
375
- {}
376
- );
377
- }
378
353
  async decode(re) {
379
- if (re instanceof Headers || re instanceof URLSearchParams || re instanceof FormData) {
380
- return deserialize([...re.entries()]);
381
- }
382
- const contentType = re.headers.get("content-type");
383
- const contentDisposition = re.headers.get("content-disposition");
384
- const fileName = contentDisposition ? cd.parse(contentDisposition).parameters.filename : void 0;
385
- if (fileName) {
386
- const blob2 = await re.blob();
387
- const file = new File([blob2], fileName, {
388
- type: blob2.type
389
- });
390
- return file;
391
- }
392
- if (!contentType || contentType.startsWith("application/json")) {
393
- if (!re.body) {
394
- return void 0;
354
+ try {
355
+ if (re instanceof Headers || re instanceof URLSearchParams || re instanceof FormData) {
356
+ return deserialize([...re.entries()]);
395
357
  }
396
- return await re.json();
397
- }
398
- if (contentType.startsWith("application/x-www-form-urlencoded")) {
399
- const params = new URLSearchParams(await re.text());
400
- return this.decode(params);
401
- }
402
- if (contentType.startsWith("text/")) {
403
- const text = await re.text();
404
- return text;
405
- }
406
- if (contentType.startsWith("multipart/form-data")) {
407
- const form = await re.formData();
408
- return this.decode(form);
358
+ const contentType = re.headers.get("content-type");
359
+ const contentDisposition = re.headers.get("content-disposition");
360
+ const fileName = contentDisposition ? cd.parse(contentDisposition).parameters.filename : void 0;
361
+ if (fileName) {
362
+ const blob2 = await re.blob();
363
+ const file = new File([blob2], fileName, {
364
+ type: blob2.type
365
+ });
366
+ return file;
367
+ }
368
+ if (!contentType || contentType.startsWith("application/json")) {
369
+ if (!re.body) {
370
+ return void 0;
371
+ }
372
+ const text = await re.text();
373
+ if (!text) {
374
+ return void 0;
375
+ }
376
+ return JSON.parse(text);
377
+ }
378
+ if (contentType.startsWith("application/x-www-form-urlencoded")) {
379
+ const params = new URLSearchParams(await re.text());
380
+ return this.decode(params);
381
+ }
382
+ if (contentType.startsWith("text/")) {
383
+ const text = await re.text();
384
+ return text;
385
+ }
386
+ if (contentType.startsWith("multipart/form-data")) {
387
+ const form = await re.formData();
388
+ return this.decode(form);
389
+ }
390
+ const blob = await re.blob();
391
+ return new File([blob], "blob", {
392
+ type: blob.type
393
+ });
394
+ } catch (e) {
395
+ throw new ORPCError({
396
+ code: "BAD_REQUEST",
397
+ message: "Cannot parse request/response. Please check the request/response body and Content-Type header.",
398
+ cause: e
399
+ });
409
400
  }
410
- const blob = await re.blob();
411
- return new File([blob], "blob", {
412
- type: blob.type
413
- });
414
401
  }
415
402
  };
416
403
 
417
- // src/fetch/openapi-procedure-matcher.ts
418
- import { getLazyRouterPrefix, getRouterChild, isProcedure as isProcedure2, unlazy } from "@orpc/server";
404
+ // src/adapters/fetch/openapi-procedure-matcher.ts
405
+ import { fallbackToGlobalConfig, getLazyRouterPrefix, getRouterChild, isProcedure, unlazy } from "@orpc/server";
419
406
  import { mapValues } from "@orpc/shared";
420
-
421
- // src/utils.ts
422
- import { isContractProcedure } from "@orpc/contract";
423
- import { getRouterContract, isLazy, isProcedure } from "@orpc/server";
424
- function forEachContractProcedure(options, callback, result = [], isCurrentRouterContract = false) {
425
- const hiddenContract = getRouterContract(options.router);
426
- if (!isCurrentRouterContract && hiddenContract) {
427
- return forEachContractProcedure(
428
- {
429
- path: options.path,
430
- router: hiddenContract
431
- },
432
- callback,
433
- result,
434
- true
435
- );
436
- }
437
- if (isLazy(options.router)) {
438
- result.push({
439
- router: options.router,
440
- path: options.path
441
- });
442
- } else if (isProcedure(options.router)) {
443
- callback({
444
- contract: options.router["~orpc"].contract,
445
- path: options.path
446
- });
447
- } else if (isContractProcedure(options.router)) {
448
- callback({
449
- contract: options.router,
450
- path: options.path
451
- });
452
- } else {
453
- for (const key in options.router) {
454
- forEachContractProcedure(
455
- {
456
- router: options.router[key],
457
- path: [...options.path, key]
458
- },
459
- callback,
460
- result
461
- );
462
- }
463
- }
464
- return result;
465
- }
466
- function standardizeHTTPPath(path) {
467
- return `/${path.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
468
- }
469
-
470
- // src/fetch/openapi-procedure-matcher.ts
471
407
  var OpenAPIProcedureMatcher = class {
472
408
  constructor(hono, router) {
473
409
  this.hono = hono;
@@ -498,7 +434,7 @@ var OpenAPIProcedureMatcher = class {
498
434
  (v) => paramStash[v]
499
435
  ) : match[1];
500
436
  const { default: maybeProcedure } = await unlazy(getRouterChild(this.router, ...path));
501
- if (!isProcedure2(maybeProcedure)) {
437
+ if (!isProcedure(maybeProcedure)) {
502
438
  return void 0;
503
439
  }
504
440
  return {
@@ -510,7 +446,7 @@ var OpenAPIProcedureMatcher = class {
510
446
  }
511
447
  add(path, router) {
512
448
  const lazies = forEachContractProcedure({ path, router }, ({ path: path2, contract }) => {
513
- const method = contract["~orpc"].route?.method ?? "POST";
449
+ const method = fallbackToGlobalConfig("defaultMethod", contract["~orpc"].route?.method);
514
450
  const httpPath = contract["~orpc"].route?.path ? this.convertOpenAPIPathToRouterPath(contract["~orpc"].route?.path) : `/${path2.map(encodeURIComponent).join("/")}`;
515
451
  this.hono.add(method, httpPath, [httpPath, path2]);
516
452
  });
@@ -534,7 +470,7 @@ var OpenAPIProcedureMatcher = class {
534
470
  }
535
471
  };
536
472
 
537
- // src/fetch/schema-coercer.ts
473
+ // src/adapters/fetch/schema-coercer.ts
538
474
  var CompositeSchemaCoercer = class {
539
475
  constructor(coercers) {
540
476
  this.coercers = coercers;
@@ -548,49 +484,52 @@ var CompositeSchemaCoercer = class {
548
484
  }
549
485
  };
550
486
 
551
- // src/fetch/openapi-handler.ts
487
+ // src/adapters/fetch/openapi-handler.ts
488
+ import { createProcedureClient, fallbackToGlobalConfig as fallbackToGlobalConfig2, ORPCError as ORPCError2 } from "@orpc/server";
489
+ import { executeWithHooks, isPlainObject as isPlainObject3, trim } from "@orpc/shared";
552
490
  var OpenAPIHandler = class {
553
491
  constructor(hono, router, options) {
554
492
  this.options = options;
493
+ const jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
555
494
  this.procedureMatcher = options?.procedureMatcher ?? new OpenAPIProcedureMatcher(hono, router);
556
- this.payloadCodec = options?.payloadCodec ?? new OpenAPIPayloadCodec();
557
- this.inputBuilderSimple = options?.inputBuilderSimple ?? new InputBuilderSimple();
558
- this.inputBuilderFull = options?.inputBuilderFull ?? new InputBuilderFull();
495
+ this.payloadCodec = options?.payloadCodec ?? new OpenAPIPayloadCodec(jsonSerializer);
496
+ this.inputStructureCompact = options?.inputBuilderSimple ?? new InputStructureCompact();
497
+ this.inputStructureDetailed = options?.inputBuilderFull ?? new InputStructureDetailed();
559
498
  this.compositeSchemaCoercer = new CompositeSchemaCoercer(options?.schemaCoercers ?? []);
560
499
  }
561
500
  procedureMatcher;
562
501
  payloadCodec;
563
- inputBuilderSimple;
564
- inputBuilderFull;
502
+ inputStructureCompact;
503
+ inputStructureDetailed;
565
504
  compositeSchemaCoercer;
566
- condition(request) {
567
- return request.headers.get(ORPC_HANDLER_HEADER) === null;
568
- }
569
- async fetch(request, ...[options]) {
505
+ async handle(request, ...[options]) {
570
506
  const context = options?.context;
571
507
  const headers = request.headers;
572
- const accept = headers.get("Accept") || void 0;
508
+ const accept = headers.get("accept") || void 0;
573
509
  const execute = async () => {
574
510
  const url = new URL(request.url);
575
511
  const pathname = `/${trim(url.pathname.replace(options?.prefix ?? "", ""), "/")}`;
576
512
  const query = url.searchParams;
577
513
  const customMethod = request.method === "POST" ? query.get("method")?.toUpperCase() : void 0;
578
- const method = customMethod || request.method;
579
- const match = await this.procedureMatcher.match(method, pathname);
580
- if (!match) {
581
- throw new ORPCError2({ code: "NOT_FOUND", message: "Not found" });
514
+ const matchedMethod = customMethod || request.method;
515
+ const matched = await this.procedureMatcher.match(matchedMethod, pathname);
516
+ if (!matched) {
517
+ return { matched: false, response: void 0 };
582
518
  }
583
- const decodedPayload = request.method === "GET" ? await this.payloadCodec.decode(query) : await this.payloadCodec.decode(request);
584
- const input = this.inputBuilderSimple.build(match.params, decodedPayload);
585
- const coercedInput = this.compositeSchemaCoercer.coerce(match.procedure["~orpc"].contract["~orpc"].InputSchema, input);
586
- const client = createProcedureClient({
519
+ const contractDef = matched.procedure["~orpc"].contract["~orpc"];
520
+ const input = await this.decodeInput(matched.procedure, matched.params, request);
521
+ const coercedInput = this.compositeSchemaCoercer.coerce(contractDef.InputSchema, input);
522
+ const client = createProcedureClient(matched.procedure, {
587
523
  context,
588
- procedure: match.procedure,
589
- path: match.path
524
+ path: matched.path
525
+ });
526
+ const output = await client(coercedInput, { signal: request.signal });
527
+ const { body, headers: resHeaders } = this.encodeOutput(matched.procedure, output, accept);
528
+ const response = new Response(body, {
529
+ headers: resHeaders,
530
+ status: fallbackToGlobalConfig2("defaultSuccessStatus", contractDef.route?.successStatus)
590
531
  });
591
- const output = await client(coercedInput, { signal: options?.signal });
592
- const { body, headers: headers2 } = this.payloadCodec.encode(output);
593
- return new Response(body, { headers: headers2 });
532
+ return { matched: true, response };
594
533
  };
595
534
  try {
596
535
  return await executeWithHooks({
@@ -599,27 +538,94 @@ var OpenAPIHandler = class {
599
538
  input: request,
600
539
  hooks: this.options,
601
540
  meta: {
602
- signal: options?.signal
541
+ signal: request.signal
603
542
  }
604
543
  });
605
544
  } catch (e) {
606
545
  const error = this.convertToORPCError(e);
607
546
  try {
608
547
  const { body, headers: headers2 } = this.payloadCodec.encode(error.toJSON(), accept);
609
- return new Response(body, {
548
+ const response = new Response(body, {
610
549
  status: error.status,
611
550
  headers: headers2
612
551
  });
552
+ return { matched: true, response };
613
553
  } catch (e2) {
614
554
  const error2 = this.convertToORPCError(e2);
615
- const { body, headers: headers2 } = this.payloadCodec.encode(error2.toJSON());
616
- return new Response(body, {
555
+ const { body, headers: headers2 } = this.payloadCodec.encode(error2.toJSON(), void 0);
556
+ const response = new Response(body, {
617
557
  status: error2.status,
618
558
  headers: headers2
619
559
  });
560
+ return { matched: true, response };
620
561
  }
621
562
  }
622
563
  }
564
+ async decodeInput(procedure, params, request) {
565
+ const inputStructure = fallbackToGlobalConfig2("defaultInputStructure", procedure["~orpc"].contract["~orpc"].route?.inputStructure);
566
+ const url = new URL(request.url);
567
+ const query = url.searchParams;
568
+ const headers = request.headers;
569
+ if (inputStructure === "compact") {
570
+ return this.inputStructureCompact.build(
571
+ params,
572
+ request.method === "GET" ? await this.payloadCodec.decode(query) : await this.payloadCodec.decode(request)
573
+ );
574
+ }
575
+ const decodedQuery = await this.payloadCodec.decode(query);
576
+ const decodedHeaders = await this.payloadCodec.decode(headers);
577
+ const decodedBody = await this.payloadCodec.decode(request);
578
+ return this.inputStructureDetailed.build(params, decodedQuery, decodedHeaders, decodedBody);
579
+ }
580
+ encodeOutput(procedure, output, accept) {
581
+ const outputStructure = fallbackToGlobalConfig2("defaultOutputStructure", procedure["~orpc"].contract["~orpc"].route?.outputStructure);
582
+ if (outputStructure === "compact") {
583
+ return this.payloadCodec.encode(output, accept);
584
+ }
585
+ this.assertDetailedOutput(output);
586
+ const headers = new Headers();
587
+ if (output.headers) {
588
+ for (const [key, value] of Object.entries(output.headers)) {
589
+ headers.append(key, value);
590
+ }
591
+ }
592
+ const { body, headers: encodedHeaders } = this.payloadCodec.encode(output.body, accept);
593
+ if (encodedHeaders) {
594
+ for (const [key, value] of encodedHeaders.entries()) {
595
+ headers.append(key, value);
596
+ }
597
+ }
598
+ return { body, headers };
599
+ }
600
+ assertDetailedOutput(output) {
601
+ const error = new Error(`
602
+ Invalid output structure for 'detailed' output.
603
+ Expected format:
604
+ {
605
+ body?: unknown; // The main response content (optional)
606
+ headers?: { // Additional headers (optional)
607
+ [key: string]: string;
608
+ };
609
+ }
610
+
611
+ Example:
612
+ {
613
+ body: { message: "Success" },
614
+ headers: { "X-Custom-Header": "Custom-Value" },
615
+ }
616
+
617
+ Fix: Ensure your output matches the expected structure.
618
+ `);
619
+ if (!isPlainObject3(output) || Object.keys(output).some((key) => key !== "body" && key !== "headers")) {
620
+ throw error;
621
+ }
622
+ if (output.headers !== void 0 && !isPlainObject3(output.headers)) {
623
+ throw error;
624
+ }
625
+ if (output.headers && Object.entries(output.headers).some(([key, value]) => typeof key !== "string" || typeof value !== "string")) {
626
+ throw error;
627
+ }
628
+ }
623
629
  convertToORPCError(e) {
624
630
  return e instanceof ORPCError2 ? e : new ORPCError2({
625
631
  code: "INTERNAL_SERVER_ERROR",
@@ -629,37 +635,17 @@ var OpenAPIHandler = class {
629
635
  }
630
636
  };
631
637
 
632
- // src/fetch/openapi-handler-server.ts
633
- import { TrieRouter } from "hono/router/trie-router";
634
- var OpenAPIServerHandler = class extends OpenAPIHandler {
635
- constructor(router, options) {
636
- super(new TrieRouter(), router, options);
637
- }
638
- };
639
-
640
- // src/fetch/openapi-handler-serverless.ts
641
- import { LinearRouter } from "hono/router/linear-router";
642
- var OpenAPIServerlessHandler = class extends OpenAPIHandler {
643
- constructor(router, options) {
644
- super(new LinearRouter(), router, options);
645
- }
646
- };
647
-
648
638
  export {
649
639
  serialize,
650
640
  deserialize,
651
641
  escapeSegment,
652
642
  stringifyPath,
653
643
  parsePath,
654
- InputBuilderFull,
655
- InputBuilderSimple,
644
+ InputStructureCompact,
645
+ InputStructureDetailed,
656
646
  OpenAPIPayloadCodec,
657
- forEachContractProcedure,
658
- standardizeHTTPPath,
659
647
  OpenAPIProcedureMatcher,
660
648
  CompositeSchemaCoercer,
661
- OpenAPIHandler,
662
- OpenAPIServerHandler,
663
- OpenAPIServerlessHandler
649
+ OpenAPIHandler
664
650
  };
665
- //# sourceMappingURL=chunk-UPDKQRQG.js.map
651
+ //# sourceMappingURL=chunk-X2HG5K4J.js.map
package/dist/fetch.js CHANGED
@@ -1,22 +1,25 @@
1
+ import {
2
+ OpenAPIServerHandler,
3
+ OpenAPIServerlessHandler
4
+ } from "./chunk-EVWWILO6.js";
1
5
  import {
2
6
  CompositeSchemaCoercer,
3
- InputBuilderFull,
4
- InputBuilderSimple,
7
+ InputStructureCompact,
8
+ InputStructureDetailed,
5
9
  OpenAPIHandler,
6
10
  OpenAPIPayloadCodec,
7
11
  OpenAPIProcedureMatcher,
8
- OpenAPIServerHandler,
9
- OpenAPIServerlessHandler,
10
12
  deserialize,
11
13
  escapeSegment,
12
14
  parsePath,
13
15
  serialize,
14
16
  stringifyPath
15
- } from "./chunk-UPDKQRQG.js";
17
+ } from "./chunk-X2HG5K4J.js";
18
+ import "./chunk-KNYXLM77.js";
16
19
  export {
17
20
  CompositeSchemaCoercer,
18
- InputBuilderFull,
19
- InputBuilderSimple,
21
+ InputStructureCompact,
22
+ InputStructureDetailed,
20
23
  OpenAPIHandler,
21
24
  OpenAPIPayloadCodec,
22
25
  OpenAPIProcedureMatcher,