@orpc/openapi 0.0.0-next.f99e554 → 0.0.0-next.fe39bf3

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 (42) hide show
  1. package/dist/chunk-LPBZEW4B.js +165 -0
  2. package/dist/chunk-UU2TTVB2.js +32 -0
  3. package/dist/chunk-XGHV4TH3.js +13 -0
  4. package/dist/fetch.js +5 -42
  5. package/dist/hono.js +9 -0
  6. package/dist/index.js +259 -48
  7. package/dist/next.js +9 -0
  8. package/dist/node.js +20 -36
  9. package/dist/src/adapters/fetch/index.d.ts +0 -8
  10. package/dist/src/adapters/fetch/openapi-handler.d.ts +9 -31
  11. package/dist/src/adapters/hono/index.d.ts +2 -0
  12. package/dist/src/adapters/next/index.d.ts +2 -0
  13. package/dist/src/adapters/node/index.d.ts +0 -3
  14. package/dist/src/adapters/node/openapi-handler.d.ts +8 -9
  15. package/dist/src/adapters/standard/index.d.ts +4 -0
  16. package/dist/src/adapters/standard/openapi-codec.d.ts +16 -0
  17. package/dist/src/adapters/standard/openapi-handler.d.ts +7 -0
  18. package/dist/src/adapters/standard/openapi-matcher.d.ts +20 -0
  19. package/dist/src/index.d.ts +5 -1
  20. package/dist/src/openapi-generator.d.ts +12 -5
  21. package/dist/src/openapi-input-structure-parser.d.ts +2 -2
  22. package/dist/src/openapi-operation-extender.d.ts +7 -0
  23. package/dist/src/openapi-output-structure-parser.d.ts +2 -2
  24. package/dist/src/schema-converter.d.ts +2 -2
  25. package/dist/src/schema.d.ts +1 -1
  26. package/dist/src/utils.d.ts +2 -16
  27. package/dist/standard.js +10 -0
  28. package/package.json +25 -14
  29. package/dist/chunk-KNYXLM77.js +0 -107
  30. package/dist/chunk-YXHH6XHB.js +0 -642
  31. package/dist/src/adapters/fetch/bracket-notation.d.ts +0 -84
  32. package/dist/src/adapters/fetch/input-structure-compact.d.ts +0 -6
  33. package/dist/src/adapters/fetch/input-structure-detailed.d.ts +0 -11
  34. package/dist/src/adapters/fetch/openapi-handler-server.d.ts +0 -7
  35. package/dist/src/adapters/fetch/openapi-handler-serverless.d.ts +0 -7
  36. package/dist/src/adapters/fetch/openapi-payload-codec.d.ts +0 -15
  37. package/dist/src/adapters/fetch/openapi-procedure-matcher.d.ts +0 -19
  38. package/dist/src/adapters/fetch/schema-coercer.d.ts +0 -10
  39. package/dist/src/adapters/node/openapi-handler-server.d.ts +0 -7
  40. package/dist/src/adapters/node/openapi-handler-serverless.d.ts +0 -7
  41. package/dist/src/adapters/node/types.d.ts +0 -2
  42. package/dist/src/json-serializer.d.ts +0 -5
package/dist/index.js CHANGED
@@ -1,9 +1,53 @@
1
1
  import {
2
- JSONSerializer,
3
- forEachAllContractProcedure,
4
- forEachContractProcedure,
5
- standardizeHTTPPath
6
- } from "./chunk-KNYXLM77.js";
2
+ standardizeHTTPPath,
3
+ toOpenAPI31RoutePattern
4
+ } from "./chunk-XGHV4TH3.js";
5
+
6
+ // src/openapi-operation-extender.ts
7
+ import { isProcedure } from "@orpc/server";
8
+ var OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
9
+ function setOperationExtender(o, extend) {
10
+ return new Proxy(o, {
11
+ get(target, prop, receiver) {
12
+ if (prop === OPERATION_EXTENDER_SYMBOL) {
13
+ return extend;
14
+ }
15
+ return Reflect.get(target, prop, receiver);
16
+ }
17
+ });
18
+ }
19
+ function getOperationExtender(o) {
20
+ return o[OPERATION_EXTENDER_SYMBOL];
21
+ }
22
+ function extendOperation(operation, procedure) {
23
+ const operationExtenders = [];
24
+ for (const errorItem of Object.values(procedure["~orpc"].errorMap)) {
25
+ const maybeExtender = getOperationExtender(errorItem);
26
+ if (maybeExtender) {
27
+ operationExtenders.push(maybeExtender);
28
+ }
29
+ }
30
+ if (isProcedure(procedure)) {
31
+ for (const middleware of procedure["~orpc"].middlewares) {
32
+ const maybeExtender = getOperationExtender(middleware);
33
+ if (maybeExtender) {
34
+ operationExtenders.push(maybeExtender);
35
+ }
36
+ }
37
+ }
38
+ let currentOperation = operation;
39
+ for (const extender of operationExtenders) {
40
+ if (typeof extender === "function") {
41
+ currentOperation = extender(currentOperation, procedure);
42
+ } else {
43
+ currentOperation = {
44
+ ...currentOperation,
45
+ ...extender
46
+ };
47
+ }
48
+ }
49
+ return currentOperation;
50
+ }
7
51
 
8
52
  // src/openapi.ts
9
53
  import { OpenApiBuilder } from "openapi3-ts/oas31";
@@ -35,11 +79,19 @@ var OpenAPIContentBuilder = class {
35
79
  }
36
80
  };
37
81
 
82
+ // src/openapi-generator.ts
83
+ import { fallbackORPCErrorStatus } from "@orpc/client";
84
+ import { OpenAPIJsonSerializer } from "@orpc/client/openapi";
85
+ import { fallbackContractConfig as fallbackContractConfig2, getEventIteratorSchemaDetails } from "@orpc/contract";
86
+ import { eachAllContractProcedure } from "@orpc/server";
87
+ import { group } from "@orpc/shared";
88
+
38
89
  // src/openapi-error.ts
39
90
  var OpenAPIError = class extends Error {
40
91
  };
41
92
 
42
93
  // src/openapi-input-structure-parser.ts
94
+ import { fallbackContractConfig } from "@orpc/contract";
43
95
  var OpenAPIInputStructureParser = class {
44
96
  constructor(schemaConverter, schemaUtils, pathParser) {
45
97
  this.schemaConverter = schemaConverter;
@@ -47,8 +99,8 @@ var OpenAPIInputStructureParser = class {
47
99
  this.pathParser = pathParser;
48
100
  }
49
101
  parse(contract, structure) {
50
- const inputSchema = this.schemaConverter.convert(contract["~orpc"].InputSchema, { strategy: "input" });
51
- const method = contract["~orpc"].route?.method ?? "POST";
102
+ const inputSchema = this.schemaConverter.convert(contract["~orpc"].inputSchema, { strategy: "input" });
103
+ const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route?.method);
52
104
  const httpPath = contract["~orpc"].route?.path;
53
105
  if (this.schemaUtils.isAnySchema(inputSchema)) {
54
106
  return {
@@ -140,7 +192,7 @@ var OpenAPIOutputStructureParser = class {
140
192
  this.schemaUtils = schemaUtils;
141
193
  }
142
194
  parse(contract, structure) {
143
- const outputSchema = this.schemaConverter.convert(contract["~orpc"].OutputSchema, { strategy: "output" });
195
+ const outputSchema = this.schemaConverter.convert(contract["~orpc"].outputSchema, { strategy: "output" });
144
196
  if (this.schemaUtils.isAnySchema(outputSchema)) {
145
197
  return {
146
198
  headersSchema: void 0,
@@ -179,14 +231,14 @@ var OpenAPIOutputStructureParser = class {
179
231
  };
180
232
 
181
233
  // src/openapi-parameters-builder.ts
182
- import { get, isPlainObject, omit } from "@orpc/shared";
234
+ import { get, isObject, omit } from "@orpc/shared";
183
235
  var OpenAPIParametersBuilder = class {
184
236
  build(paramIn, jsonSchema, options) {
185
237
  const parameters = [];
186
238
  for (const name in jsonSchema.properties) {
187
239
  const schema = jsonSchema.properties[name];
188
240
  const paramExamples = jsonSchema.examples?.filter((example) => {
189
- return isPlainObject(example) && name in example;
241
+ return isObject(example) && name in example;
190
242
  }).map((example) => {
191
243
  return example[name];
192
244
  });
@@ -247,7 +299,7 @@ var CompositeSchemaConverter = class {
247
299
  };
248
300
 
249
301
  // src/schema-utils.ts
250
- import { isPlainObject as isPlainObject2 } from "@orpc/shared";
302
+ import { isObject as isObject2 } from "@orpc/shared";
251
303
 
252
304
  // src/schema.ts
253
305
  import * as JSONSchema from "json-schema-typed/draft-2020-12";
@@ -289,14 +341,14 @@ var SchemaUtils = class {
289
341
  return typeof schema === "object" && schema.type === "object";
290
342
  }
291
343
  isAnySchema(schema) {
292
- return schema === true || Object.keys(schema).length === 0;
344
+ return schema === true || Object.keys(schema).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
293
345
  }
294
346
  isUndefinableSchema(schema) {
295
347
  const [matches] = this.filterSchemaBranches(schema, (schema2) => {
296
348
  if (typeof schema2 === "boolean") {
297
349
  return schema2;
298
350
  }
299
- return Object.keys(schema2).length === 0;
351
+ return Object.keys(schema2).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
300
352
  });
301
353
  return matches.length > 0;
302
354
  }
@@ -309,7 +361,7 @@ var SchemaUtils = class {
309
361
  }, {});
310
362
  matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
311
363
  matched.examples = schema.examples?.map((example) => {
312
- if (!isPlainObject2(example)) {
364
+ if (!isObject2(example)) {
313
365
  return example;
314
366
  }
315
367
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -325,7 +377,7 @@ var SchemaUtils = class {
325
377
  }, {});
326
378
  rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
327
379
  rest.examples = schema.examples?.map((example) => {
328
- if (!isPlainObject2(example)) {
380
+ if (!isObject2(example)) {
329
381
  return example;
330
382
  }
331
383
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -380,11 +432,12 @@ var OpenAPIGenerator = class {
380
432
  errorHandlerStrategy;
381
433
  ignoreUndefinedPathProcedures;
382
434
  considerMissingTagDefinitionAsError;
435
+ strictErrorResponses;
383
436
  constructor(options) {
384
437
  this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
385
438
  this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
386
439
  this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
387
- this.jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
440
+ this.jsonSerializer = options?.jsonSerializer ?? new OpenAPIJsonSerializer();
388
441
  this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
389
442
  this.pathParser = new OpenAPIPathParser();
390
443
  this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
@@ -392,6 +445,7 @@ var OpenAPIGenerator = class {
392
445
  this.errorHandlerStrategy = options?.errorHandlerStrategy ?? "throw";
393
446
  this.ignoreUndefinedPathProcedures = options?.ignoreUndefinedPathProcedures ?? false;
394
447
  this.considerMissingTagDefinitionAsError = options?.considerMissingTagDefinitionAsError ?? false;
448
+ this.strictErrorResponses = options?.strictErrorResponses ?? true;
395
449
  }
396
450
  async generate(router, doc) {
397
451
  const builder = new OpenApiBuilder({
@@ -399,35 +453,186 @@ var OpenAPIGenerator = class {
399
453
  openapi: "3.1.1"
400
454
  });
401
455
  const rootTags = doc.tags?.map((tag) => tag.name) ?? [];
402
- await forEachAllContractProcedure(router, ({ contract, path }) => {
456
+ await eachAllContractProcedure({
457
+ path: [],
458
+ router
459
+ }, ({ contract, path }) => {
403
460
  try {
404
461
  const def = contract["~orpc"];
405
462
  if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
406
463
  return;
407
464
  }
408
- const method = def.route?.method ?? "POST";
409
- const httpPath = def.route?.path ? standardizeHTTPPath(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
410
- const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, def.route?.inputStructure ?? "compact");
411
- const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, def.route?.outputStructure ?? "compact");
412
- const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
413
- required: true
414
- }) : [];
415
- const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
416
- const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
417
- const parameters = [...params, ...query, ...headers];
418
- const requestBody = bodySchema !== void 0 ? {
419
- required: this.schemaUtils.isUndefinableSchema(bodySchema),
420
- content: this.contentBuilder.build(bodySchema)
421
- } : void 0;
422
- const successResponse = {
423
- description: "OK",
424
- content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema, {
425
- example: def.outputExample
426
- }) : void 0,
427
- headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema, {
428
- example: def.outputExample
429
- }) : void 0
430
- };
465
+ const method = fallbackContractConfig2("defaultMethod", def.route?.method);
466
+ const httpPath = def.route?.path ? toOpenAPI31RoutePattern(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
467
+ const { parameters, requestBody } = (() => {
468
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.inputSchema);
469
+ if (eventIteratorSchemaDetails) {
470
+ const requestBody3 = {
471
+ required: true,
472
+ content: {
473
+ "text/event-stream": {
474
+ schema: {
475
+ oneOf: [
476
+ {
477
+ type: "object",
478
+ properties: {
479
+ event: { type: "string", const: "message" },
480
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
481
+ id: { type: "string" },
482
+ retry: { type: "number" }
483
+ },
484
+ required: ["event", "data"]
485
+ },
486
+ {
487
+ type: "object",
488
+ properties: {
489
+ event: { type: "string", const: "done" },
490
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
491
+ id: { type: "string" },
492
+ retry: { type: "number" }
493
+ },
494
+ required: ["event", "data"]
495
+ },
496
+ {
497
+ type: "object",
498
+ properties: {
499
+ event: { type: "string", const: "error" },
500
+ data: {},
501
+ id: { type: "string" },
502
+ retry: { type: "number" }
503
+ },
504
+ required: ["event", "data"]
505
+ }
506
+ ]
507
+ }
508
+ }
509
+ }
510
+ };
511
+ return { requestBody: requestBody3, parameters: [] };
512
+ }
513
+ const inputStructure = fallbackContractConfig2("defaultInputStructure", def.route?.inputStructure);
514
+ const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, inputStructure);
515
+ const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
516
+ required: true
517
+ }) : [];
518
+ const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
519
+ const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
520
+ const parameters2 = [...params, ...query, ...headers];
521
+ const requestBody2 = bodySchema !== void 0 ? {
522
+ required: this.schemaUtils.isUndefinableSchema(bodySchema),
523
+ content: this.contentBuilder.build(bodySchema)
524
+ } : void 0;
525
+ return { parameters: parameters2, requestBody: requestBody2 };
526
+ })();
527
+ const { responses } = (() => {
528
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.outputSchema);
529
+ if (eventIteratorSchemaDetails) {
530
+ const responses3 = {};
531
+ responses3[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
532
+ description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
533
+ content: {
534
+ "text/event-stream": {
535
+ schema: {
536
+ oneOf: [
537
+ {
538
+ type: "object",
539
+ properties: {
540
+ event: { type: "string", const: "message" },
541
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
542
+ id: { type: "string" },
543
+ retry: { type: "number" }
544
+ },
545
+ required: ["event", "data"]
546
+ },
547
+ {
548
+ type: "object",
549
+ properties: {
550
+ event: { type: "string", const: "done" },
551
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
552
+ id: { type: "string" },
553
+ retry: { type: "number" }
554
+ },
555
+ required: ["event", "data"]
556
+ },
557
+ {
558
+ type: "object",
559
+ properties: {
560
+ event: { type: "string", const: "error" },
561
+ data: {},
562
+ id: { type: "string" },
563
+ retry: { type: "number" }
564
+ },
565
+ required: ["event", "data"]
566
+ }
567
+ ]
568
+ }
569
+ }
570
+ }
571
+ };
572
+ return { responses: responses3 };
573
+ }
574
+ const outputStructure = fallbackContractConfig2("defaultOutputStructure", def.route?.outputStructure);
575
+ const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, outputStructure);
576
+ const responses2 = {};
577
+ responses2[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
578
+ description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
579
+ content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema) : void 0,
580
+ headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema) : void 0
581
+ };
582
+ return { responses: responses2 };
583
+ })();
584
+ const errors = group(Object.entries(def.errorMap ?? {}).filter(([_, config]) => config).map(([code, config]) => ({
585
+ ...config,
586
+ code,
587
+ status: fallbackORPCErrorStatus(code, config?.status)
588
+ })), (error) => error.status);
589
+ for (const status in errors) {
590
+ const configs = errors[status];
591
+ if (!configs || configs.length === 0) {
592
+ continue;
593
+ }
594
+ const schemas = configs.map(({ data, code, message }) => {
595
+ const json = {
596
+ type: "object",
597
+ properties: {
598
+ defined: { const: true },
599
+ code: { const: code },
600
+ status: { const: Number(status) },
601
+ message: { type: "string", default: message },
602
+ data: {}
603
+ },
604
+ required: ["defined", "code", "status", "message"]
605
+ };
606
+ if (data) {
607
+ const dataJson = this.schemaConverter.convert(data, { strategy: "output" });
608
+ json.properties.data = dataJson;
609
+ if (!this.schemaUtils.isUndefinableSchema(dataJson)) {
610
+ json.required.push("data");
611
+ }
612
+ }
613
+ return json;
614
+ });
615
+ if (this.strictErrorResponses) {
616
+ schemas.push({
617
+ type: "object",
618
+ properties: {
619
+ defined: { const: false },
620
+ code: { type: "string" },
621
+ status: { type: "number" },
622
+ message: { type: "string" },
623
+ data: {}
624
+ },
625
+ required: ["defined", "code", "status", "message"]
626
+ });
627
+ }
628
+ const contentSchema = schemas.length === 1 ? schemas[0] : {
629
+ oneOf: schemas
630
+ };
631
+ responses[status] = {
632
+ description: status,
633
+ content: this.contentBuilder.build(contentSchema)
634
+ };
635
+ }
431
636
  if (this.considerMissingTagDefinitionAsError && def.route?.tags) {
432
637
  const missingTag = def.route?.tags.find((tag) => !rootTags.includes(tag));
433
638
  if (missingTag !== void 0) {
@@ -444,12 +649,11 @@ var OpenAPIGenerator = class {
444
649
  operationId: path.join("."),
445
650
  parameters: parameters.length ? parameters : void 0,
446
651
  requestBody,
447
- responses: {
448
- [def.route?.successStatus ?? 200]: successResponse
449
- }
652
+ responses
450
653
  };
654
+ const extendedOperation = extendOperation(operation, contract);
451
655
  builder.addPath(httpPath, {
452
- [method.toLocaleLowerCase()]: operation
656
+ [method.toLocaleLowerCase()]: extendedOperation
453
657
  });
454
658
  } catch (e) {
455
659
  if (e instanceof OpenAPIError) {
@@ -471,11 +675,15 @@ var OpenAPIGenerator = class {
471
675
  return this.jsonSerializer.serialize(builder.getSpec());
472
676
  }
473
677
  };
678
+
679
+ // src/index.ts
680
+ var oo = {
681
+ spec: setOperationExtender
682
+ };
474
683
  export {
475
684
  CompositeSchemaConverter,
476
685
  JSONSchema,
477
686
  Format as JSONSchemaFormat,
478
- JSONSerializer,
479
687
  NON_LOGIC_KEYWORDS,
480
688
  OpenAPIContentBuilder,
481
689
  OpenAPIGenerator,
@@ -483,8 +691,11 @@ export {
483
691
  OpenAPIPathParser,
484
692
  OpenApiBuilder,
485
693
  SchemaUtils,
486
- forEachAllContractProcedure,
487
- forEachContractProcedure,
488
- standardizeHTTPPath
694
+ extendOperation,
695
+ getOperationExtender,
696
+ oo,
697
+ setOperationExtender,
698
+ standardizeHTTPPath,
699
+ toOpenAPI31RoutePattern
489
700
  };
490
701
  //# sourceMappingURL=index.js.map
package/dist/next.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ OpenAPIHandler
3
+ } from "./chunk-UU2TTVB2.js";
4
+ import "./chunk-LPBZEW4B.js";
5
+ import "./chunk-XGHV4TH3.js";
6
+ export {
7
+ OpenAPIHandler
8
+ };
9
+ //# sourceMappingURL=next.js.map
package/dist/node.js CHANGED
@@ -1,46 +1,30 @@
1
1
  import {
2
- OpenAPIHandler
3
- } from "./chunk-YXHH6XHB.js";
4
- import "./chunk-KNYXLM77.js";
2
+ OpenAPICodec,
3
+ OpenAPIMatcher
4
+ } from "./chunk-LPBZEW4B.js";
5
+ import "./chunk-XGHV4TH3.js";
5
6
 
6
7
  // src/adapters/node/openapi-handler.ts
7
- import { createRequest, sendResponse } from "@mjackson/node-fetch-server";
8
- import { ORPC_HANDLER_HEADER } from "@orpc/shared";
9
- var OpenAPIHandler2 = class {
10
- openapiFetchHandler;
11
- constructor(hono, router, options) {
12
- this.openapiFetchHandler = new OpenAPIHandler(hono, router, options);
13
- }
14
- condition(request) {
15
- return request.headers[ORPC_HANDLER_HEADER] === void 0;
16
- }
17
- async handle(req, res, ...[options]) {
18
- const request = createRequest(req, res, options);
19
- const castedOptions = options ?? {};
20
- const response = await this.openapiFetchHandler.fetch(request, castedOptions);
21
- await options?.beforeSend?.(response, castedOptions.context);
22
- return await sendResponse(res, response);
23
- }
24
- };
25
-
26
- // src/adapters/node/openapi-handler-server.ts
27
- import { TrieRouter } from "hono/router/trie-router";
28
- var OpenAPIServerHandler = class extends OpenAPIHandler2 {
8
+ import { sendStandardResponse, toStandardRequest } from "@orpc/server-standard-node";
9
+ import { StandardHandler } from "@orpc/server/standard";
10
+ var OpenAPIHandler = class {
11
+ standardHandler;
29
12
  constructor(router, options) {
30
- super(new TrieRouter(), router, options);
13
+ const matcher = options?.matcher ?? new OpenAPIMatcher(options);
14
+ const codec = options?.codec ?? new OpenAPICodec(options);
15
+ this.standardHandler = new StandardHandler(router, matcher, codec, { ...options });
31
16
  }
32
- };
33
-
34
- // src/adapters/node/openapi-handler-serverless.ts
35
- import { LinearRouter } from "hono/router/linear-router";
36
- var OpenAPIServerlessHandler = class extends OpenAPIHandler2 {
37
- constructor(router, options) {
38
- super(new LinearRouter(), router, options);
17
+ async handle(req, res, ...rest) {
18
+ const standardRequest = toStandardRequest(req, res);
19
+ const result = await this.standardHandler.handle(standardRequest, ...rest);
20
+ if (!result.matched) {
21
+ return { matched: false };
22
+ }
23
+ await sendStandardResponse(res, result.response);
24
+ return { matched: true };
39
25
  }
40
26
  };
41
27
  export {
42
- OpenAPIHandler2 as OpenAPIHandler,
43
- OpenAPIServerHandler,
44
- OpenAPIServerlessHandler
28
+ OpenAPIHandler
45
29
  };
46
30
  //# sourceMappingURL=node.js.map
@@ -1,10 +1,2 @@
1
- export * from './bracket-notation';
2
- export * from './input-structure-compact';
3
- export * from './input-structure-detailed';
4
1
  export * from './openapi-handler';
5
- export * from './openapi-handler-server';
6
- export * from './openapi-handler-serverless';
7
- export * from './openapi-payload-codec';
8
- export * from './openapi-procedure-matcher';
9
- export * from './schema-coercer';
10
2
  //# sourceMappingURL=index.d.ts.map
@@ -1,33 +1,11 @@
1
- import type { Context, Router, WithSignal } from '@orpc/server';
2
- import type { ConditionalFetchHandler, FetchOptions } from '@orpc/server/fetch';
3
- import type { PublicInputStructureCompact } from './input-structure-compact';
4
- import { type Hooks } from '@orpc/shared';
5
- import { type PublicJSONSerializer } from '../../json-serializer';
6
- import { type PublicInputStructureDetailed } from './input-structure-detailed';
7
- import { type PublicOpenAPIPayloadCodec } from './openapi-payload-codec';
8
- import { type Hono, type PublicOpenAPIProcedureMatcher } from './openapi-procedure-matcher';
9
- import { type SchemaCoercer } from './schema-coercer';
10
- export type OpenAPIHandlerOptions<T extends Context> = Hooks<Request, Response, T, WithSignal> & {
11
- jsonSerializer?: PublicJSONSerializer;
12
- procedureMatcher?: PublicOpenAPIProcedureMatcher;
13
- payloadCodec?: PublicOpenAPIPayloadCodec;
14
- inputBuilderSimple?: PublicInputStructureCompact;
15
- inputBuilderFull?: PublicInputStructureDetailed;
16
- schemaCoercers?: SchemaCoercer[];
17
- };
18
- export declare class OpenAPIHandler<T extends Context> implements ConditionalFetchHandler<T> {
19
- private readonly options?;
20
- private readonly procedureMatcher;
21
- private readonly payloadCodec;
22
- private readonly inputStructureCompact;
23
- private readonly inputStructureDetailed;
24
- private readonly compositeSchemaCoercer;
25
- constructor(hono: Hono, router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>> | undefined);
26
- condition(request: Request): boolean;
27
- fetch(request: Request, ...[options]: [options: FetchOptions<T>] | (undefined extends T ? [] : never)): Promise<Response>;
28
- private decodeInput;
29
- private encodeOutput;
30
- private assertDetailedOutput;
31
- private convertToORPCError;
1
+ import type { Context, Router } from '@orpc/server';
2
+ import type { FetchHandler, FetchHandleResult } from '@orpc/server/fetch';
3
+ import type { StandardHandleOptions } from '@orpc/server/standard';
4
+ import type { MaybeOptionalOptions } from '@orpc/shared';
5
+ import type { OpenAPIHandlerOptions } from '../standard';
6
+ export declare class OpenAPIHandler<T extends Context> implements FetchHandler<T> {
7
+ private readonly standardHandler;
8
+ constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
9
+ handle(request: Request, ...rest: MaybeOptionalOptions<StandardHandleOptions<T>>): Promise<FetchHandleResult>;
32
10
  }
33
11
  //# sourceMappingURL=openapi-handler.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from '../fetch';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from '../fetch';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,2 @@
1
1
  export * from './openapi-handler';
2
- export * from './openapi-handler-server';
3
- export * from './openapi-handler-serverless';
4
- export * from './types';
5
2
  //# sourceMappingURL=index.d.ts.map
@@ -1,12 +1,11 @@
1
1
  import type { Context, Router } from '@orpc/server';
2
- import type { ConditionalRequestHandler, RequestOptions } from '@orpc/server/node';
3
- import type { IncomingMessage, ServerResponse } from 'node:http';
4
- import type { OpenAPIHandlerOptions } from '../fetch/openapi-handler';
5
- import type { Hono } from '../fetch/openapi-procedure-matcher';
6
- export declare class OpenAPIHandler<T extends Context> implements ConditionalRequestHandler<T> {
7
- private readonly openapiFetchHandler;
8
- constructor(hono: Hono, router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
9
- condition(request: IncomingMessage): boolean;
10
- handle(req: IncomingMessage, res: ServerResponse, ...[options]: [options: RequestOptions<T>] | (undefined extends T ? [] : never)): Promise<void>;
2
+ import type { NodeHttpHandler, NodeHttpHandleResult, NodeHttpRequest, NodeHttpResponse } from '@orpc/server/node';
3
+ import type { StandardHandleOptions } from '@orpc/server/standard';
4
+ import type { MaybeOptionalOptions } from '@orpc/shared';
5
+ import type { OpenAPIHandlerOptions } from '../standard';
6
+ export declare class OpenAPIHandler<T extends Context> implements NodeHttpHandler<T> {
7
+ private readonly standardHandler;
8
+ constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
9
+ handle(req: NodeHttpRequest, res: NodeHttpResponse, ...rest: MaybeOptionalOptions<StandardHandleOptions<T>>): Promise<NodeHttpHandleResult>;
11
10
  }
12
11
  //# sourceMappingURL=openapi-handler.d.ts.map
@@ -0,0 +1,4 @@
1
+ export * from './openapi-codec';
2
+ export * from './openapi-handler';
3
+ export * from './openapi-matcher';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { ORPCError } from '@orpc/client';
2
+ import type { AnyProcedure } from '@orpc/server';
3
+ import type { StandardRequest, StandardResponse } from '@orpc/server-standard';
4
+ import type { StandardCodec, StandardParams } from '@orpc/server/standard';
5
+ import { OpenAPISerializer } from '@orpc/client/openapi';
6
+ export interface OpenAPICodecOptions {
7
+ serializer?: OpenAPISerializer;
8
+ }
9
+ export declare class OpenAPICodec implements StandardCodec {
10
+ private readonly serializer;
11
+ constructor(options?: OpenAPICodecOptions);
12
+ decode(request: StandardRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
13
+ encode(output: unknown, procedure: AnyProcedure): StandardResponse;
14
+ encodeError(error: ORPCError<any, any>): StandardResponse;
15
+ }
16
+ //# sourceMappingURL=openapi-codec.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { Context } from '@orpc/server';
2
+ import type { RPCHandlerOptions } from '@orpc/server/standard';
3
+ import type { OpenAPICodecOptions } from './openapi-codec';
4
+ import type { OpenAPIMatcherOptions } from './openapi-matcher';
5
+ export interface OpenAPIHandlerOptions<T extends Context> extends RPCHandlerOptions<T>, OpenAPIMatcherOptions, OpenAPICodecOptions {
6
+ }
7
+ //# sourceMappingURL=openapi-handler.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { AnyRouter } from '@orpc/server';
2
+ import type { StandardMatcher, StandardMatchResult } from '@orpc/server/standard';
3
+ import { type HTTPPath } from '@orpc/contract';
4
+ export interface OpenAPIMatcherOptions {
5
+ /**
6
+ * Ignore procedure that does not have a method defined in the contract.
7
+ *
8
+ * @default false
9
+ */
10
+ ignoreUndefinedMethod?: boolean;
11
+ }
12
+ export declare class OpenAPIMatcher implements StandardMatcher {
13
+ private readonly tree;
14
+ private readonly ignoreUndefinedMethod;
15
+ constructor(options?: OpenAPIMatcherOptions);
16
+ private pendingRouters;
17
+ init(router: AnyRouter, path?: string[]): void;
18
+ match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
19
+ }
20
+ //# sourceMappingURL=openapi-matcher.d.ts.map