@orpc/openapi 0.0.0-next.ccd4e42 → 0.0.0-next.cd121e3

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 +29 -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} +207 -92
  20. package/dist/shared/openapi.BHG_gu5Z.mjs +8 -0
  21. package/dist/shared/openapi.CDsfPHgw.mjs +148 -0
  22. package/dist/shared/openapi.D0VMNR6V.mjs +25 -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 -35
  26. package/dist/chunk-BHJYKXQL.js +0 -52
  27. package/dist/chunk-HQ34JZI7.js +0 -32
  28. package/dist/chunk-M5HOHBLW.js +0 -432
  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 -10
  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 -10
  39. package/dist/src/adapters/standard/bracket-notation.d.ts +0 -84
  40. package/dist/src/adapters/standard/index.d.ts +0 -7
  41. package/dist/src/adapters/standard/openapi-codec.d.ts +0 -18
  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/adapters/standard/schema-coercer.d.ts +0 -10
  46. package/dist/src/index.d.ts +0 -12
  47. package/dist/src/json-serializer.d.ts +0 -5
  48. package/dist/src/openapi-content-builder.d.ts +0 -10
  49. package/dist/src/openapi-error.d.ts +0 -3
  50. package/dist/src/openapi-generator.d.ts +0 -67
  51. package/dist/src/openapi-input-structure-parser.d.ts +0 -22
  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 -16
@@ -1,14 +1,61 @@
1
- import {
2
- JSONSerializer,
3
- standardizeHTTPPath
4
- } from "./chunk-BHJYKXQL.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.ts
7
- import { OpenApiBuilder } from "openapi3-ts/oas31";
14
+ const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
15
+ function setOperationExtender(o, extend) {
16
+ return new Proxy(o, {
17
+ get(target, prop, receiver) {
18
+ if (prop === OPERATION_EXTENDER_SYMBOL) {
19
+ return extend;
20
+ }
21
+ return Reflect.get(target, prop, receiver);
22
+ }
23
+ });
24
+ }
25
+ function getOperationExtender(o) {
26
+ return o[OPERATION_EXTENDER_SYMBOL];
27
+ }
28
+ function extendOperation(operation, procedure) {
29
+ const operationExtenders = [];
30
+ for (const errorItem of Object.values(procedure["~orpc"].errorMap)) {
31
+ const maybeExtender = getOperationExtender(errorItem);
32
+ if (maybeExtender) {
33
+ operationExtenders.push(maybeExtender);
34
+ }
35
+ }
36
+ if (isProcedure(procedure)) {
37
+ for (const middleware of procedure["~orpc"].middlewares) {
38
+ const maybeExtender = getOperationExtender(middleware);
39
+ if (maybeExtender) {
40
+ operationExtenders.push(maybeExtender);
41
+ }
42
+ }
43
+ }
44
+ let currentOperation = operation;
45
+ for (const extender of operationExtenders) {
46
+ if (typeof extender === "function") {
47
+ currentOperation = extender(currentOperation, procedure);
48
+ } else {
49
+ currentOperation = {
50
+ ...currentOperation,
51
+ ...extender
52
+ };
53
+ }
54
+ }
55
+ return currentOperation;
56
+ }
8
57
 
9
- // src/openapi-content-builder.ts
10
- import { findDeepMatches } from "@orpc/shared";
11
- var OpenAPIContentBuilder = class {
58
+ class OpenAPIContentBuilder {
12
59
  constructor(schemaUtils) {
13
60
  this.schemaUtils = schemaUtils;
14
61
  }
@@ -31,20 +78,12 @@ var OpenAPIContentBuilder = class {
31
78
  }
32
79
  return content;
33
80
  }
34
- };
81
+ }
35
82
 
36
- // src/openapi-generator.ts
37
- import { fallbackContractConfig as fallbackContractConfig2, fallbackORPCErrorStatus } from "@orpc/contract";
38
- import { eachAllContractProcedure } from "@orpc/server";
39
- import { group } from "@orpc/shared";
83
+ class OpenAPIError extends Error {
84
+ }
40
85
 
41
- // src/openapi-error.ts
42
- var OpenAPIError = class extends Error {
43
- };
44
-
45
- // src/openapi-input-structure-parser.ts
46
- import { fallbackContractConfig } from "@orpc/contract";
47
- var OpenAPIInputStructureParser = class {
86
+ class OpenAPIInputStructureParser {
48
87
  constructor(schemaConverter, schemaUtils, pathParser) {
49
88
  this.schemaConverter = schemaConverter;
50
89
  this.schemaUtils = schemaUtils;
@@ -135,10 +174,9 @@ var OpenAPIInputStructureParser = class {
135
174
  bodySchema: method !== "GET" ? rest : void 0
136
175
  };
137
176
  }
138
- };
177
+ }
139
178
 
140
- // src/openapi-output-structure-parser.ts
141
- var OpenAPIOutputStructureParser = class {
179
+ class OpenAPIOutputStructureParser {
142
180
  constructor(schemaConverter, schemaUtils) {
143
181
  this.schemaConverter = schemaConverter;
144
182
  this.schemaUtils = schemaUtils;
@@ -180,17 +218,15 @@ var OpenAPIOutputStructureParser = class {
180
218
  bodySchema: outputSchema
181
219
  };
182
220
  }
183
- };
221
+ }
184
222
 
185
- // src/openapi-parameters-builder.ts
186
- import { get, isPlainObject, omit } from "@orpc/shared";
187
- var OpenAPIParametersBuilder = class {
223
+ class OpenAPIParametersBuilder {
188
224
  build(paramIn, jsonSchema, options) {
189
225
  const parameters = [];
190
226
  for (const name in jsonSchema.properties) {
191
227
  const schema = jsonSchema.properties[name];
192
228
  const paramExamples = jsonSchema.examples?.filter((example) => {
193
- return isPlainObject(example) && name in example;
229
+ return isObject(example) && name in example;
194
230
  }).map((example) => {
195
231
  return example[name];
196
232
  });
@@ -218,10 +254,9 @@ var OpenAPIParametersBuilder = class {
218
254
  }
219
255
  return headersObject;
220
256
  }
221
- };
257
+ }
222
258
 
223
- // src/openapi-path-parser.ts
224
- var OpenAPIPathParser = class {
259
+ class OpenAPIPathParser {
225
260
  parseDynamicParams(path) {
226
261
  const raws = path.match(/\{([^}]+)\}/g) ?? [];
227
262
  return raws.map((raw) => {
@@ -229,10 +264,9 @@ var OpenAPIPathParser = class {
229
264
  return { name, raw };
230
265
  });
231
266
  }
232
- };
267
+ }
233
268
 
234
- // src/schema-converter.ts
235
- var CompositeSchemaConverter = class {
269
+ class CompositeSchemaConverter {
236
270
  converters;
237
271
  constructor(converters) {
238
272
  this.converters = converters;
@@ -248,15 +282,9 @@ var CompositeSchemaConverter = class {
248
282
  }
249
283
  return {};
250
284
  }
251
- };
252
-
253
- // src/schema-utils.ts
254
- import { isPlainObject as isPlainObject2 } from "@orpc/shared";
285
+ }
255
286
 
256
- // src/schema.ts
257
- import * as JSONSchema from "json-schema-typed/draft-2020-12";
258
- import { Format } from "json-schema-typed/draft-2020-12";
259
- var NON_LOGIC_KEYWORDS = [
287
+ const NON_LOGIC_KEYWORDS = [
260
288
  // Core Documentation Keywords
261
289
  "$anchor",
262
290
  "$comment",
@@ -284,13 +312,12 @@ var NON_LOGIC_KEYWORDS = [
284
312
  "$dynamicRef"
285
313
  ];
286
314
 
287
- // src/schema-utils.ts
288
- var SchemaUtils = class {
315
+ class SchemaUtils {
289
316
  isFileSchema(schema) {
290
- return typeof schema === "object" && schema.type === "string" && typeof schema.contentMediaType === "string";
317
+ return isObject(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
291
318
  }
292
319
  isObjectSchema(schema) {
293
- return typeof schema === "object" && schema.type === "object";
320
+ return isObject(schema) && schema.type === "object";
294
321
  }
295
322
  isAnySchema(schema) {
296
323
  return schema === true || Object.keys(schema).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
@@ -313,7 +340,7 @@ var SchemaUtils = class {
313
340
  }, {});
314
341
  matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
315
342
  matched.examples = schema.examples?.map((example) => {
316
- if (!isPlainObject2(example)) {
343
+ if (!isObject(example)) {
317
344
  return example;
318
345
  }
319
346
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -329,7 +356,7 @@ var SchemaUtils = class {
329
356
  }, {});
330
357
  rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
331
358
  rest.examples = schema.examples?.map((example) => {
332
- if (!isPlainObject2(example)) {
359
+ if (!isObject(example)) {
333
360
  return example;
334
361
  }
335
362
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -369,10 +396,9 @@ var SchemaUtils = class {
369
396
  }
370
397
  return [matches, schema];
371
398
  }
372
- };
399
+ }
373
400
 
374
- // src/openapi-generator.ts
375
- var OpenAPIGenerator = class {
401
+ class OpenAPIGenerator {
376
402
  contentBuilder;
377
403
  parametersBuilder;
378
404
  schemaConverter;
@@ -389,7 +415,7 @@ var OpenAPIGenerator = class {
389
415
  this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
390
416
  this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
391
417
  this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
392
- this.jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
418
+ this.jsonSerializer = options?.jsonSerializer ?? new OpenAPIJsonSerializer();
393
419
  this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
394
420
  this.pathParser = new OpenAPIPathParser();
395
421
  this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
@@ -414,28 +440,125 @@ var OpenAPIGenerator = class {
414
440
  if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
415
441
  return;
416
442
  }
417
- const method = fallbackContractConfig2("defaultMethod", def.route?.method);
418
- const httpPath = def.route?.path ? standardizeHTTPPath(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
419
- const inputStructure = fallbackContractConfig2("defaultInputStructure", def.route?.inputStructure);
420
- const outputStructure = fallbackContractConfig2("defaultOutputStructure", def.route?.outputStructure);
421
- const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, inputStructure);
422
- const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, outputStructure);
423
- const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
424
- required: true
425
- }) : [];
426
- const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
427
- const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
428
- const parameters = [...params, ...query, ...headers];
429
- const requestBody = bodySchema !== void 0 ? {
430
- required: this.schemaUtils.isUndefinableSchema(bodySchema),
431
- content: this.contentBuilder.build(bodySchema)
432
- } : void 0;
433
- const responses = {};
434
- responses[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
435
- description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
436
- content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema) : void 0,
437
- headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema) : void 0
438
- };
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
+ })();
439
562
  const errors = group(Object.entries(def.errorMap ?? {}).filter(([_, config]) => config).map(([code, config]) => ({
440
563
  ...config,
441
564
  code,
@@ -506,8 +629,9 @@ var OpenAPIGenerator = class {
506
629
  requestBody,
507
630
  responses
508
631
  };
632
+ const extendedOperation = extendOperation(operation, contract);
509
633
  builder.addPath(httpPath, {
510
- [method.toLocaleLowerCase()]: operation
634
+ [method.toLocaleLowerCase()]: extendedOperation
511
635
  });
512
636
  } catch (e) {
513
637
  if (e instanceof OpenAPIError) {
@@ -526,21 +650,12 @@ var OpenAPIGenerator = class {
526
650
  }
527
651
  }
528
652
  });
529
- return this.jsonSerializer.serialize(builder.getSpec());
653
+ return this.jsonSerializer.serialize(builder.getSpec())[0];
530
654
  }
655
+ }
656
+
657
+ const oo = {
658
+ spec: setOperationExtender
531
659
  };
532
- export {
533
- CompositeSchemaConverter,
534
- JSONSchema,
535
- Format as JSONSchemaFormat,
536
- JSONSerializer,
537
- NON_LOGIC_KEYWORDS,
538
- OpenAPIContentBuilder,
539
- OpenAPIGenerator,
540
- OpenAPIParametersBuilder,
541
- OpenAPIPathParser,
542
- OpenApiBuilder,
543
- SchemaUtils,
544
- standardizeHTTPPath
545
- };
546
- //# 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,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,25 @@
1
+ import { StandardHandler } from '@orpc/server/standard';
2
+ import { toStandardRequest, 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, ...[options]) {
13
+ const standardRequest = toStandardRequest(request);
14
+ const result = await this.standardHandler.handle(standardRequest, options);
15
+ if (!result.matched) {
16
+ return result;
17
+ }
18
+ return {
19
+ matched: true,
20
+ response: toFetchResponse(result.response, options)
21
+ };
22
+ }
23
+ }
24
+
25
+ export { OpenAPIHandler 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 };
@@ -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 };