@orpc/openapi 0.0.0-next.da8ae32 → 0.0.0-next.df024bb

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 (60) hide show
  1. package/README.md +91 -0
  2. package/dist/adapters/fetch/index.d.mts +14 -0
  3. package/dist/adapters/fetch/index.d.ts +14 -0
  4. package/dist/adapters/fetch/index.mjs +10 -0
  5. package/dist/adapters/hono/index.d.mts +7 -0
  6. package/dist/adapters/hono/index.d.ts +7 -0
  7. package/dist/adapters/hono/index.mjs +10 -0
  8. package/dist/adapters/next/index.d.mts +7 -0
  9. package/dist/adapters/next/index.d.ts +7 -0
  10. package/dist/adapters/next/index.mjs +10 -0
  11. package/dist/adapters/node/index.d.mts +14 -0
  12. package/dist/adapters/node/index.d.ts +14 -0
  13. package/dist/adapters/node/index.mjs +31 -0
  14. package/dist/adapters/standard/index.d.mts +24 -0
  15. package/dist/adapters/standard/index.d.ts +24 -0
  16. package/dist/adapters/standard/index.mjs +7 -0
  17. package/dist/index.d.mts +169 -0
  18. package/dist/index.d.ts +169 -0
  19. package/dist/{index.js → index.mjs} +160 -101
  20. package/dist/shared/openapi.BHG_gu5Z.mjs +8 -0
  21. package/dist/shared/openapi.BcJH4F9P.mjs +27 -0
  22. package/dist/shared/openapi.CDsfPHgw.mjs +148 -0
  23. package/dist/shared/openapi.Dz_6xooR.d.mts +7 -0
  24. package/dist/shared/openapi.Dz_6xooR.d.ts +7 -0
  25. package/package.json +28 -32
  26. package/dist/chunk-DRV7KYES.js +0 -420
  27. package/dist/chunk-HC5PVG4R.js +0 -52
  28. package/dist/chunk-NHYWV7BW.js +0 -32
  29. package/dist/fetch.js +0 -9
  30. package/dist/hono.js +0 -9
  31. package/dist/next.js +0 -9
  32. package/dist/node.js +0 -30
  33. package/dist/src/adapters/fetch/index.d.ts +0 -2
  34. package/dist/src/adapters/fetch/openapi-handler.d.ts +0 -11
  35. package/dist/src/adapters/hono/index.d.ts +0 -2
  36. package/dist/src/adapters/next/index.d.ts +0 -2
  37. package/dist/src/adapters/node/index.d.ts +0 -2
  38. package/dist/src/adapters/node/openapi-handler.d.ts +0 -11
  39. package/dist/src/adapters/standard/bracket-notation.d.ts +0 -84
  40. package/dist/src/adapters/standard/index.d.ts +0 -6
  41. package/dist/src/adapters/standard/openapi-codec.d.ts +0 -15
  42. package/dist/src/adapters/standard/openapi-handler.d.ts +0 -7
  43. package/dist/src/adapters/standard/openapi-matcher.d.ts +0 -20
  44. package/dist/src/adapters/standard/openapi-serializer.d.ts +0 -11
  45. package/dist/src/index.d.ts +0 -17
  46. package/dist/src/json-serializer.d.ts +0 -5
  47. package/dist/src/openapi-content-builder.d.ts +0 -10
  48. package/dist/src/openapi-error.d.ts +0 -3
  49. package/dist/src/openapi-generator.d.ts +0 -67
  50. package/dist/src/openapi-input-structure-parser.d.ts +0 -22
  51. package/dist/src/openapi-operation-extender.d.ts +0 -7
  52. package/dist/src/openapi-output-structure-parser.d.ts +0 -18
  53. package/dist/src/openapi-parameters-builder.d.ts +0 -12
  54. package/dist/src/openapi-path-parser.d.ts +0 -8
  55. package/dist/src/openapi.d.ts +0 -3
  56. package/dist/src/schema-converter.d.ts +0 -16
  57. package/dist/src/schema-utils.d.ts +0 -11
  58. package/dist/src/schema.d.ts +0 -12
  59. package/dist/src/utils.d.ts +0 -3
  60. package/dist/standard.js +0 -14
@@ -1,11 +1,17 @@
1
- import {
2
- JSONSerializer,
3
- standardizeHTTPPath
4
- } from "./chunk-HC5PVG4R.js";
1
+ import { isProcedure, eachAllContractProcedure } from '@orpc/server';
2
+ import { OpenApiBuilder } from 'openapi3-ts/oas31';
3
+ export { OpenApiBuilder } from 'openapi3-ts/oas31';
4
+ import { findDeepMatches, isObject, get, omit, group } from '@orpc/shared';
5
+ import { fallbackORPCErrorStatus } from '@orpc/client';
6
+ import { fallbackContractConfig, getEventIteratorSchemaDetails } from '@orpc/contract';
7
+ import { OpenAPIJsonSerializer } from '@orpc/openapi-client/standard';
8
+ import * as draft202012 from 'json-schema-typed/draft-2020-12';
9
+ export { draft202012 as JSONSchema };
10
+ export { Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
11
+ import { t as toOpenAPI31RoutePattern } from './shared/openapi.BHG_gu5Z.mjs';
12
+ export { s as standardizeHTTPPath } from './shared/openapi.BHG_gu5Z.mjs';
5
13
 
6
- // src/openapi-operation-extender.ts
7
- import { isProcedure } from "@orpc/server";
8
- var OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
14
+ const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
9
15
  function setOperationExtender(o, extend) {
10
16
  return new Proxy(o, {
11
17
  get(target, prop, receiver) {
@@ -49,12 +55,7 @@ function extendOperation(operation, procedure) {
49
55
  return currentOperation;
50
56
  }
51
57
 
52
- // src/openapi.ts
53
- import { OpenApiBuilder } from "openapi3-ts/oas31";
54
-
55
- // src/openapi-content-builder.ts
56
- import { findDeepMatches } from "@orpc/shared";
57
- var OpenAPIContentBuilder = class {
58
+ class OpenAPIContentBuilder {
58
59
  constructor(schemaUtils) {
59
60
  this.schemaUtils = schemaUtils;
60
61
  }
@@ -77,20 +78,12 @@ var OpenAPIContentBuilder = class {
77
78
  }
78
79
  return content;
79
80
  }
80
- };
81
-
82
- // src/openapi-generator.ts
83
- import { fallbackContractConfig as fallbackContractConfig2, fallbackORPCErrorStatus } from "@orpc/contract";
84
- import { eachAllContractProcedure } from "@orpc/server";
85
- import { group } from "@orpc/shared";
81
+ }
86
82
 
87
- // src/openapi-error.ts
88
- var OpenAPIError = class extends Error {
89
- };
83
+ class OpenAPIError extends Error {
84
+ }
90
85
 
91
- // src/openapi-input-structure-parser.ts
92
- import { fallbackContractConfig } from "@orpc/contract";
93
- var OpenAPIInputStructureParser = class {
86
+ class OpenAPIInputStructureParser {
94
87
  constructor(schemaConverter, schemaUtils, pathParser) {
95
88
  this.schemaConverter = schemaConverter;
96
89
  this.schemaUtils = schemaUtils;
@@ -181,10 +174,9 @@ var OpenAPIInputStructureParser = class {
181
174
  bodySchema: method !== "GET" ? rest : void 0
182
175
  };
183
176
  }
184
- };
177
+ }
185
178
 
186
- // src/openapi-output-structure-parser.ts
187
- var OpenAPIOutputStructureParser = class {
179
+ class OpenAPIOutputStructureParser {
188
180
  constructor(schemaConverter, schemaUtils) {
189
181
  this.schemaConverter = schemaConverter;
190
182
  this.schemaUtils = schemaUtils;
@@ -226,11 +218,9 @@ var OpenAPIOutputStructureParser = class {
226
218
  bodySchema: outputSchema
227
219
  };
228
220
  }
229
- };
221
+ }
230
222
 
231
- // src/openapi-parameters-builder.ts
232
- import { get, isObject, omit } from "@orpc/shared";
233
- var OpenAPIParametersBuilder = class {
223
+ class OpenAPIParametersBuilder {
234
224
  build(paramIn, jsonSchema, options) {
235
225
  const parameters = [];
236
226
  for (const name in jsonSchema.properties) {
@@ -264,10 +254,9 @@ var OpenAPIParametersBuilder = class {
264
254
  }
265
255
  return headersObject;
266
256
  }
267
- };
257
+ }
268
258
 
269
- // src/openapi-path-parser.ts
270
- var OpenAPIPathParser = class {
259
+ class OpenAPIPathParser {
271
260
  parseDynamicParams(path) {
272
261
  const raws = path.match(/\{([^}]+)\}/g) ?? [];
273
262
  return raws.map((raw) => {
@@ -275,10 +264,9 @@ var OpenAPIPathParser = class {
275
264
  return { name, raw };
276
265
  });
277
266
  }
278
- };
267
+ }
279
268
 
280
- // src/schema-converter.ts
281
- var CompositeSchemaConverter = class {
269
+ class CompositeSchemaConverter {
282
270
  converters;
283
271
  constructor(converters) {
284
272
  this.converters = converters;
@@ -294,15 +282,9 @@ var CompositeSchemaConverter = class {
294
282
  }
295
283
  return {};
296
284
  }
297
- };
298
-
299
- // src/schema-utils.ts
300
- import { isObject as isObject2 } from "@orpc/shared";
285
+ }
301
286
 
302
- // src/schema.ts
303
- import * as JSONSchema from "json-schema-typed/draft-2020-12";
304
- import { Format } from "json-schema-typed/draft-2020-12";
305
- var NON_LOGIC_KEYWORDS = [
287
+ const NON_LOGIC_KEYWORDS = [
306
288
  // Core Documentation Keywords
307
289
  "$anchor",
308
290
  "$comment",
@@ -330,13 +312,12 @@ var NON_LOGIC_KEYWORDS = [
330
312
  "$dynamicRef"
331
313
  ];
332
314
 
333
- // src/schema-utils.ts
334
- var SchemaUtils = class {
315
+ class SchemaUtils {
335
316
  isFileSchema(schema) {
336
- return typeof schema === "object" && schema.type === "string" && typeof schema.contentMediaType === "string";
317
+ return isObject(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
337
318
  }
338
319
  isObjectSchema(schema) {
339
- return typeof schema === "object" && schema.type === "object";
320
+ return isObject(schema) && schema.type === "object";
340
321
  }
341
322
  isAnySchema(schema) {
342
323
  return schema === true || Object.keys(schema).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
@@ -359,7 +340,7 @@ var SchemaUtils = class {
359
340
  }, {});
360
341
  matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
361
342
  matched.examples = schema.examples?.map((example) => {
362
- if (!isObject2(example)) {
343
+ if (!isObject(example)) {
363
344
  return example;
364
345
  }
365
346
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -375,7 +356,7 @@ var SchemaUtils = class {
375
356
  }, {});
376
357
  rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
377
358
  rest.examples = schema.examples?.map((example) => {
378
- if (!isObject2(example)) {
359
+ if (!isObject(example)) {
379
360
  return example;
380
361
  }
381
362
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -415,10 +396,9 @@ var SchemaUtils = class {
415
396
  }
416
397
  return [matches, schema];
417
398
  }
418
- };
399
+ }
419
400
 
420
- // src/openapi-generator.ts
421
- var OpenAPIGenerator = class {
401
+ class OpenAPIGenerator {
422
402
  contentBuilder;
423
403
  parametersBuilder;
424
404
  schemaConverter;
@@ -435,7 +415,7 @@ var OpenAPIGenerator = class {
435
415
  this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
436
416
  this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
437
417
  this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
438
- this.jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
418
+ this.jsonSerializer = options?.jsonSerializer ?? new OpenAPIJsonSerializer();
439
419
  this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
440
420
  this.pathParser = new OpenAPIPathParser();
441
421
  this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
@@ -460,28 +440,125 @@ var OpenAPIGenerator = class {
460
440
  if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
461
441
  return;
462
442
  }
463
- const method = fallbackContractConfig2("defaultMethod", def.route?.method);
464
- const httpPath = def.route?.path ? standardizeHTTPPath(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
465
- const inputStructure = fallbackContractConfig2("defaultInputStructure", def.route?.inputStructure);
466
- const outputStructure = fallbackContractConfig2("defaultOutputStructure", def.route?.outputStructure);
467
- const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, inputStructure);
468
- const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, outputStructure);
469
- const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
470
- required: true
471
- }) : [];
472
- const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
473
- const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
474
- const parameters = [...params, ...query, ...headers];
475
- const requestBody = bodySchema !== void 0 ? {
476
- required: this.schemaUtils.isUndefinableSchema(bodySchema),
477
- content: this.contentBuilder.build(bodySchema)
478
- } : void 0;
479
- const responses = {};
480
- responses[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
481
- description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
482
- content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema) : void 0,
483
- headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema) : void 0
484
- };
443
+ const method = fallbackContractConfig("defaultMethod", def.route?.method);
444
+ const httpPath = def.route?.path ? toOpenAPI31RoutePattern(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
445
+ const { parameters, requestBody } = (() => {
446
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.inputSchema);
447
+ if (eventIteratorSchemaDetails) {
448
+ const requestBody3 = {
449
+ required: true,
450
+ content: {
451
+ "text/event-stream": {
452
+ schema: {
453
+ oneOf: [
454
+ {
455
+ type: "object",
456
+ properties: {
457
+ event: { type: "string", const: "message" },
458
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
459
+ id: { type: "string" },
460
+ retry: { type: "number" }
461
+ },
462
+ required: ["event", "data"]
463
+ },
464
+ {
465
+ type: "object",
466
+ properties: {
467
+ event: { type: "string", const: "done" },
468
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
469
+ id: { type: "string" },
470
+ retry: { type: "number" }
471
+ },
472
+ required: ["event", "data"]
473
+ },
474
+ {
475
+ type: "object",
476
+ properties: {
477
+ event: { type: "string", const: "error" },
478
+ data: {},
479
+ id: { type: "string" },
480
+ retry: { type: "number" }
481
+ },
482
+ required: ["event", "data"]
483
+ }
484
+ ]
485
+ }
486
+ }
487
+ }
488
+ };
489
+ return { requestBody: requestBody3, parameters: [] };
490
+ }
491
+ const inputStructure = fallbackContractConfig("defaultInputStructure", def.route?.inputStructure);
492
+ const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, inputStructure);
493
+ const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
494
+ required: true
495
+ }) : [];
496
+ const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
497
+ const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
498
+ const parameters2 = [...params, ...query, ...headers];
499
+ const requestBody2 = bodySchema !== void 0 ? {
500
+ required: this.schemaUtils.isUndefinableSchema(bodySchema),
501
+ content: this.contentBuilder.build(bodySchema)
502
+ } : void 0;
503
+ return { parameters: parameters2, requestBody: requestBody2 };
504
+ })();
505
+ const { responses } = (() => {
506
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.outputSchema);
507
+ if (eventIteratorSchemaDetails) {
508
+ const responses3 = {};
509
+ responses3[fallbackContractConfig("defaultSuccessStatus", def.route?.successStatus)] = {
510
+ description: fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription),
511
+ content: {
512
+ "text/event-stream": {
513
+ schema: {
514
+ oneOf: [
515
+ {
516
+ type: "object",
517
+ properties: {
518
+ event: { type: "string", const: "message" },
519
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
520
+ id: { type: "string" },
521
+ retry: { type: "number" }
522
+ },
523
+ required: ["event", "data"]
524
+ },
525
+ {
526
+ type: "object",
527
+ properties: {
528
+ event: { type: "string", const: "done" },
529
+ data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
530
+ id: { type: "string" },
531
+ retry: { type: "number" }
532
+ },
533
+ required: ["event", "data"]
534
+ },
535
+ {
536
+ type: "object",
537
+ properties: {
538
+ event: { type: "string", const: "error" },
539
+ data: {},
540
+ id: { type: "string" },
541
+ retry: { type: "number" }
542
+ },
543
+ required: ["event", "data"]
544
+ }
545
+ ]
546
+ }
547
+ }
548
+ }
549
+ };
550
+ return { responses: responses3 };
551
+ }
552
+ const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route?.outputStructure);
553
+ const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, outputStructure);
554
+ const responses2 = {};
555
+ responses2[fallbackContractConfig("defaultSuccessStatus", def.route?.successStatus)] = {
556
+ description: fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription),
557
+ content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema) : void 0,
558
+ headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema) : void 0
559
+ };
560
+ return { responses: responses2 };
561
+ })();
485
562
  const errors = group(Object.entries(def.errorMap ?? {}).filter(([_, config]) => config).map(([code, config]) => ({
486
563
  ...config,
487
564
  code,
@@ -573,30 +650,12 @@ var OpenAPIGenerator = class {
573
650
  }
574
651
  }
575
652
  });
576
- return this.jsonSerializer.serialize(builder.getSpec());
653
+ return this.jsonSerializer.serialize(builder.getSpec())[0];
577
654
  }
578
- };
655
+ }
579
656
 
580
- // src/index.ts
581
- var oo = {
657
+ const oo = {
582
658
  spec: setOperationExtender
583
659
  };
584
- export {
585
- CompositeSchemaConverter,
586
- JSONSchema,
587
- Format as JSONSchemaFormat,
588
- JSONSerializer,
589
- NON_LOGIC_KEYWORDS,
590
- OpenAPIContentBuilder,
591
- OpenAPIGenerator,
592
- OpenAPIParametersBuilder,
593
- OpenAPIPathParser,
594
- OpenApiBuilder,
595
- SchemaUtils,
596
- extendOperation,
597
- getOperationExtender,
598
- oo,
599
- setOperationExtender,
600
- standardizeHTTPPath
601
- };
602
- //# sourceMappingURL=index.js.map
660
+
661
+ export { CompositeSchemaConverter, NON_LOGIC_KEYWORDS, OpenAPIContentBuilder, OpenAPIGenerator, OpenAPIParametersBuilder, OpenAPIPathParser, SchemaUtils, extendOperation, getOperationExtender, oo, setOperationExtender, toOpenAPI31RoutePattern };
@@ -0,0 +1,8 @@
1
+ function standardizeHTTPPath(path) {
2
+ return `/${path.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
3
+ }
4
+ function toOpenAPI31RoutePattern(path) {
5
+ return standardizeHTTPPath(path).replace(/\{\+([^}]+)\}/g, "{$1}");
6
+ }
7
+
8
+ export { standardizeHTTPPath as s, toOpenAPI31RoutePattern as t };
@@ -0,0 +1,27 @@
1
+ import { StandardHandler } from '@orpc/server/standard';
2
+ import { toStandardLazyRequest, toFetchResponse } from '@orpc/standard-server-fetch';
3
+ import { a as OpenAPIMatcher, O as OpenAPICodec } from './openapi.CDsfPHgw.mjs';
4
+
5
+ class OpenAPIHandler {
6
+ standardHandler;
7
+ constructor(router, options) {
8
+ const matcher = options?.matcher ?? new OpenAPIMatcher();
9
+ const codec = options?.codec ?? new OpenAPICodec();
10
+ this.standardHandler = new StandardHandler(router, matcher, codec, options);
11
+ }
12
+ async handle(request, ...[
13
+ options = {}
14
+ ]) {
15
+ const standardRequest = toStandardLazyRequest(request);
16
+ const result = await this.standardHandler.handle(standardRequest, options);
17
+ if (!result.matched) {
18
+ return result;
19
+ }
20
+ return {
21
+ matched: true,
22
+ response: toFetchResponse(result.response, options)
23
+ };
24
+ }
25
+ }
26
+
27
+ export { OpenAPIHandler as O };
@@ -0,0 +1,148 @@
1
+ import { fallbackContractConfig } from '@orpc/contract';
2
+ import { OpenAPISerializer } from '@orpc/openapi-client/standard';
3
+ import { isObject } from '@orpc/shared';
4
+ import { eachContractProcedure, convertPathToHttpPath, isProcedure, getLazyRouterPrefix, unlazy, getRouterChild, createContractedProcedure } from '@orpc/server';
5
+ import { createRouter, addRoute, findRoute } from 'rou3';
6
+ import { s as standardizeHTTPPath } from './openapi.BHG_gu5Z.mjs';
7
+
8
+ class OpenAPICodec {
9
+ constructor(serializer = new OpenAPISerializer()) {
10
+ this.serializer = serializer;
11
+ }
12
+ async decode(request, params, procedure) {
13
+ const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
14
+ if (inputStructure === "compact") {
15
+ const data = request.method === "GET" ? this.serializer.deserialize(request.url.searchParams) : this.serializer.deserialize(await request.body());
16
+ if (data === void 0) {
17
+ return params;
18
+ }
19
+ if (isObject(data)) {
20
+ return {
21
+ ...params,
22
+ ...data
23
+ };
24
+ }
25
+ return data;
26
+ }
27
+ const deserializeSearchParams = () => {
28
+ return this.serializer.deserialize(request.url.searchParams);
29
+ };
30
+ return {
31
+ params,
32
+ get query() {
33
+ const value = deserializeSearchParams();
34
+ Object.defineProperty(this, "query", { value, writable: true });
35
+ return value;
36
+ },
37
+ set query(value) {
38
+ Object.defineProperty(this, "query", { value, writable: true });
39
+ },
40
+ headers: request.headers,
41
+ body: this.serializer.deserialize(await request.body())
42
+ };
43
+ }
44
+ encode(output, procedure) {
45
+ const successStatus = fallbackContractConfig("defaultSuccessStatus", procedure["~orpc"].route.successStatus);
46
+ const outputStructure = fallbackContractConfig("defaultOutputStructure", procedure["~orpc"].route.outputStructure);
47
+ if (outputStructure === "compact") {
48
+ return {
49
+ status: successStatus,
50
+ headers: {},
51
+ body: this.serializer.serialize(output)
52
+ };
53
+ }
54
+ if (!isObject(output)) {
55
+ throw new Error(
56
+ 'Invalid output structure for "detailed" output. Expected format: { body: any, headers?: Record<string, string | string[] | undefined> }'
57
+ );
58
+ }
59
+ return {
60
+ status: successStatus,
61
+ headers: output.headers ?? {},
62
+ body: this.serializer.serialize(output.body)
63
+ };
64
+ }
65
+ encodeError(error) {
66
+ return {
67
+ status: error.status,
68
+ headers: {},
69
+ body: this.serializer.serialize(error.toJSON())
70
+ };
71
+ }
72
+ }
73
+
74
+ class OpenAPIMatcher {
75
+ tree = createRouter();
76
+ pendingRouters = [];
77
+ init(router, path = []) {
78
+ const laziedOptions = eachContractProcedure({
79
+ router,
80
+ path
81
+ }, ({ path: path2, contract }) => {
82
+ const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
83
+ const httpPath = contract["~orpc"].route.path ? toRou3Pattern(contract["~orpc"].route.path) : convertPathToHttpPath(path2);
84
+ if (isProcedure(contract)) {
85
+ addRoute(this.tree, method, httpPath, {
86
+ path: path2,
87
+ contract,
88
+ procedure: contract,
89
+ // this mean dev not used contract-first so we can used contract as procedure directly
90
+ router
91
+ });
92
+ } else {
93
+ addRoute(this.tree, method, httpPath, {
94
+ path: path2,
95
+ contract,
96
+ procedure: void 0,
97
+ router
98
+ });
99
+ }
100
+ });
101
+ this.pendingRouters.push(...laziedOptions.map((option) => ({
102
+ ...option,
103
+ httpPathPrefix: convertPathToHttpPath(option.path),
104
+ laziedPrefix: getLazyRouterPrefix(option.lazied)
105
+ })));
106
+ }
107
+ async match(method, pathname) {
108
+ if (this.pendingRouters.length) {
109
+ const newPendingRouters = [];
110
+ for (const pendingRouter of this.pendingRouters) {
111
+ if (!pendingRouter.laziedPrefix || pathname.startsWith(pendingRouter.laziedPrefix) || pathname.startsWith(pendingRouter.httpPathPrefix)) {
112
+ const { default: router } = await unlazy(pendingRouter.lazied);
113
+ this.init(router, pendingRouter.path);
114
+ } else {
115
+ newPendingRouters.push(pendingRouter);
116
+ }
117
+ }
118
+ this.pendingRouters = newPendingRouters;
119
+ }
120
+ const match = findRoute(this.tree, method, pathname);
121
+ if (!match) {
122
+ return void 0;
123
+ }
124
+ if (!match.data.procedure) {
125
+ const { default: maybeProcedure } = await unlazy(getRouterChild(match.data.router, ...match.data.path));
126
+ if (!isProcedure(maybeProcedure)) {
127
+ throw new Error(`
128
+ [Contract-First] Missing or invalid implementation for procedure at path: ${convertPathToHttpPath(match.data.path)}.
129
+ Ensure that the procedure is correctly defined and matches the expected contract.
130
+ `);
131
+ }
132
+ match.data.procedure = createContractedProcedure(match.data.contract, maybeProcedure);
133
+ }
134
+ return {
135
+ path: match.data.path,
136
+ procedure: match.data.procedure,
137
+ params: match.params ? decodeParams(match.params) : void 0
138
+ };
139
+ }
140
+ }
141
+ function toRou3Pattern(path) {
142
+ return standardizeHTTPPath(path).replace(/\{\+([^}]+)\}/g, "**:$1").replace(/\{([^}]+)\}/g, ":$1");
143
+ }
144
+ function decodeParams(params) {
145
+ return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, decodeURIComponent(value)]));
146
+ }
147
+
148
+ export { OpenAPICodec as O, OpenAPIMatcher as a };
@@ -0,0 +1,7 @@
1
+ import { Context } from '@orpc/server';
2
+ import { RPCHandlerOptions } from '@orpc/server/standard';
3
+
4
+ interface OpenAPIHandlerOptions<T extends Context> extends RPCHandlerOptions<T> {
5
+ }
6
+
7
+ export type { OpenAPIHandlerOptions as O };
@@ -0,0 +1,7 @@
1
+ import { Context } from '@orpc/server';
2
+ import { RPCHandlerOptions } from '@orpc/server/standard';
3
+
4
+ interface OpenAPIHandlerOptions<T extends Context> extends RPCHandlerOptions<T> {
5
+ }
6
+
7
+ export type { OpenAPIHandlerOptions as O };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/openapi",
3
3
  "type": "module",
4
- "version": "0.0.0-next.da8ae32",
4
+ "version": "0.0.0-next.df024bb",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -15,61 +15,57 @@
15
15
  ],
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/src/index.d.ts",
19
- "import": "./dist/index.js",
20
- "default": "./dist/index.js"
18
+ "types": "./dist/index.d.mts",
19
+ "import": "./dist/index.mjs",
20
+ "default": "./dist/index.mjs"
21
21
  },
22
22
  "./standard": {
23
- "types": "./dist/src/adapters/standard/index.d.ts",
24
- "import": "./dist/standard.js",
25
- "default": "./dist/standard.js"
23
+ "types": "./dist/adapters/standard/index.d.mts",
24
+ "import": "./dist/adapters/standard/index.mjs",
25
+ "default": "./dist/adapters/standard/index.mjs"
26
26
  },
27
27
  "./fetch": {
28
- "types": "./dist/src/adapters/fetch/index.d.ts",
29
- "import": "./dist/fetch.js",
30
- "default": "./dist/fetch.js"
28
+ "types": "./dist/adapters/fetch/index.d.mts",
29
+ "import": "./dist/adapters/fetch/index.mjs",
30
+ "default": "./dist/adapters/fetch/index.mjs"
31
31
  },
32
32
  "./hono": {
33
- "types": "./dist/src/adapters/hono/index.d.ts",
34
- "import": "./dist/hono.js",
35
- "default": "./dist/hono.js"
33
+ "types": "./dist/adapters/hono/index.d.mts",
34
+ "import": "./dist/adapters/hono/index.mjs",
35
+ "default": "./dist/adapters/hono/index.mjs"
36
36
  },
37
37
  "./next": {
38
- "types": "./dist/src/adapters/next/index.d.ts",
39
- "import": "./dist/next.js",
40
- "default": "./dist/next.js"
38
+ "types": "./dist/adapters/next/index.d.mts",
39
+ "import": "./dist/adapters/next/index.mjs",
40
+ "default": "./dist/adapters/next/index.mjs"
41
41
  },
42
42
  "./node": {
43
- "types": "./dist/src/adapters/node/index.d.ts",
44
- "import": "./dist/node.js",
45
- "default": "./dist/node.js"
46
- },
47
- "./🔒/*": {
48
- "types": "./dist/src/*.d.ts"
43
+ "types": "./dist/adapters/node/index.d.mts",
44
+ "import": "./dist/adapters/node/index.mjs",
45
+ "default": "./dist/adapters/node/index.mjs"
49
46
  }
50
47
  },
51
48
  "files": [
52
- "!**/*.map",
53
- "!**/*.tsbuildinfo",
54
49
  "dist"
55
50
  ],
56
51
  "dependencies": {
57
- "escape-string-regexp": "^5.0.0",
58
- "fast-content-type-parse": "^2.0.0",
59
52
  "json-schema-typed": "^8.0.1",
60
53
  "openapi3-ts": "^4.4.0",
61
54
  "rou3": "^0.5.1",
62
- "wildcard-match": "^5.1.3",
63
- "@orpc/contract": "0.0.0-next.da8ae32",
64
- "@orpc/server": "0.0.0-next.da8ae32",
65
- "@orpc/shared": "0.0.0-next.da8ae32"
55
+ "@orpc/client": "0.0.0-next.df024bb",
56
+ "@orpc/openapi-client": "0.0.0-next.df024bb",
57
+ "@orpc/contract": "0.0.0-next.df024bb",
58
+ "@orpc/shared": "0.0.0-next.df024bb",
59
+ "@orpc/server": "0.0.0-next.df024bb",
60
+ "@orpc/standard-server": "0.0.0-next.df024bb",
61
+ "@orpc/standard-server-fetch": "0.0.0-next.df024bb",
62
+ "@orpc/standard-server-node": "0.0.0-next.df024bb"
66
63
  },
67
64
  "devDependencies": {
68
- "@readme/openapi-parser": "^2.6.0",
69
65
  "zod": "^3.24.1"
70
66
  },
71
67
  "scripts": {
72
- "build": "tsup --onSuccess='tsc -b --noCheck'",
68
+ "build": "unbuild",
73
69
  "build:watch": "pnpm run build --watch",
74
70
  "type:check": "tsc -b"
75
71
  }