@orpc/openapi 0.0.0-next.011bc88 → 0.0.0-next.0361c32

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 (40) hide show
  1. package/dist/chunk-HC5PVG4R.js +52 -0
  2. package/dist/chunk-ICLAXOVR.js +32 -0
  3. package/dist/chunk-PWOV66X6.js +421 -0
  4. package/dist/fetch.js +5 -590
  5. package/dist/hono.js +9 -0
  6. package/dist/index.js +296 -112
  7. package/dist/next.js +9 -0
  8. package/dist/node.js +30 -0
  9. package/dist/src/adapters/fetch/index.d.ts +2 -0
  10. package/dist/src/adapters/fetch/openapi-handler.d.ts +10 -0
  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 +2 -0
  14. package/dist/src/adapters/node/openapi-handler.d.ts +10 -0
  15. package/dist/src/adapters/standard/index.d.ts +6 -0
  16. package/dist/src/adapters/standard/openapi-codec.d.ts +15 -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/adapters/standard/openapi-serializer.d.ts +11 -0
  20. package/dist/src/openapi-error.d.ts +3 -0
  21. package/dist/src/openapi-generator.d.ts +25 -9
  22. package/dist/src/openapi-input-structure-parser.d.ts +22 -0
  23. package/dist/src/openapi-output-structure-parser.d.ts +18 -0
  24. package/dist/src/openapi-parameters-builder.d.ts +3 -0
  25. package/dist/src/schema-converter.d.ts +2 -2
  26. package/dist/src/schema.d.ts +1 -1
  27. package/dist/src/utils.d.ts +1 -16
  28. package/dist/standard.js +14 -0
  29. package/package.json +27 -10
  30. package/dist/chunk-KNYXLM77.js +0 -107
  31. package/dist/src/fetch/index.d.ts +0 -10
  32. package/dist/src/fetch/input-builder-full.d.ts +0 -11
  33. package/dist/src/fetch/input-builder-simple.d.ts +0 -6
  34. package/dist/src/fetch/openapi-handler-server.d.ts +0 -7
  35. package/dist/src/fetch/openapi-handler-serverless.d.ts +0 -7
  36. package/dist/src/fetch/openapi-handler.d.ts +0 -30
  37. package/dist/src/fetch/openapi-payload-codec.d.ts +0 -15
  38. package/dist/src/fetch/openapi-procedure-matcher.d.ts +0 -19
  39. package/dist/src/fetch/schema-coercer.d.ts +0 -10
  40. /package/dist/src/{fetch → adapters/standard}/bracket-notation.d.ts +0 -0
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import {
2
2
  JSONSerializer,
3
- forEachAllContractProcedure,
4
- forEachContractProcedure,
5
3
  standardizeHTTPPath
6
- } from "./chunk-KNYXLM77.js";
4
+ } from "./chunk-HC5PVG4R.js";
7
5
 
8
6
  // src/openapi.ts
9
7
  import { OpenApiBuilder } from "openapi3-ts/oas31";
@@ -35,15 +33,164 @@ var OpenAPIContentBuilder = class {
35
33
  }
36
34
  };
37
35
 
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";
40
+
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 {
48
+ constructor(schemaConverter, schemaUtils, pathParser) {
49
+ this.schemaConverter = schemaConverter;
50
+ this.schemaUtils = schemaUtils;
51
+ this.pathParser = pathParser;
52
+ }
53
+ parse(contract, structure) {
54
+ const inputSchema = this.schemaConverter.convert(contract["~orpc"].inputSchema, { strategy: "input" });
55
+ const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route?.method);
56
+ const httpPath = contract["~orpc"].route?.path;
57
+ if (this.schemaUtils.isAnySchema(inputSchema)) {
58
+ return {
59
+ paramsSchema: void 0,
60
+ querySchema: void 0,
61
+ headersSchema: void 0,
62
+ bodySchema: void 0
63
+ };
64
+ }
65
+ if (structure === "detailed") {
66
+ return this.parseDetailedSchema(inputSchema);
67
+ } else {
68
+ return this.parseCompactSchema(inputSchema, method, httpPath);
69
+ }
70
+ }
71
+ parseDetailedSchema(inputSchema) {
72
+ if (!this.schemaUtils.isObjectSchema(inputSchema)) {
73
+ throw new OpenAPIError(`When input structure is 'detailed', input schema must be an object.`);
74
+ }
75
+ if (inputSchema.properties && Object.keys(inputSchema.properties).some((key) => !["params", "query", "headers", "body"].includes(key))) {
76
+ throw new OpenAPIError(`When input structure is 'detailed', input schema must be only can contain 'params', 'query', 'headers' and 'body' properties.`);
77
+ }
78
+ let paramsSchema = inputSchema.properties?.params;
79
+ let querySchema = inputSchema.properties?.query;
80
+ let headersSchema = inputSchema.properties?.headers;
81
+ const bodySchema = inputSchema.properties?.body;
82
+ if (paramsSchema !== void 0 && this.schemaUtils.isAnySchema(paramsSchema)) {
83
+ paramsSchema = void 0;
84
+ }
85
+ if (paramsSchema !== void 0 && !this.schemaUtils.isObjectSchema(paramsSchema)) {
86
+ throw new OpenAPIError(`When input structure is 'detailed', params schema in input schema must be an object.`);
87
+ }
88
+ if (querySchema !== void 0 && this.schemaUtils.isAnySchema(querySchema)) {
89
+ querySchema = void 0;
90
+ }
91
+ if (querySchema !== void 0 && !this.schemaUtils.isObjectSchema(querySchema)) {
92
+ throw new OpenAPIError(`When input structure is 'detailed', query schema in input schema must be an object.`);
93
+ }
94
+ if (headersSchema !== void 0 && this.schemaUtils.isAnySchema(headersSchema)) {
95
+ headersSchema = void 0;
96
+ }
97
+ if (headersSchema !== void 0 && !this.schemaUtils.isObjectSchema(headersSchema)) {
98
+ throw new OpenAPIError(`When input structure is 'detailed', headers schema in input schema must be an object.`);
99
+ }
100
+ return { paramsSchema, querySchema, headersSchema, bodySchema };
101
+ }
102
+ parseCompactSchema(inputSchema, method, httpPath) {
103
+ const dynamic = httpPath ? this.pathParser.parseDynamicParams(httpPath) : [];
104
+ if (dynamic.length === 0) {
105
+ if (method === "GET") {
106
+ let querySchema = inputSchema;
107
+ if (querySchema !== void 0 && this.schemaUtils.isAnySchema(querySchema)) {
108
+ querySchema = void 0;
109
+ }
110
+ if (querySchema !== void 0 && !this.schemaUtils.isObjectSchema(querySchema)) {
111
+ throw new OpenAPIError(`When input structure is 'compact' and method is 'GET', input schema must be an object.`);
112
+ }
113
+ return {
114
+ paramsSchema: void 0,
115
+ querySchema,
116
+ headersSchema: void 0,
117
+ bodySchema: void 0
118
+ };
119
+ }
120
+ return {
121
+ paramsSchema: void 0,
122
+ querySchema: void 0,
123
+ headersSchema: void 0,
124
+ bodySchema: inputSchema
125
+ };
126
+ }
127
+ if (!this.schemaUtils.isObjectSchema(inputSchema)) {
128
+ throw new OpenAPIError(`When input structure is 'compact' and path has dynamic parameters, input schema must be an object.`);
129
+ }
130
+ const [params, rest] = this.schemaUtils.separateObjectSchema(inputSchema, dynamic.map((v) => v.name));
131
+ return {
132
+ paramsSchema: params,
133
+ querySchema: method === "GET" ? rest : void 0,
134
+ headersSchema: void 0,
135
+ bodySchema: method !== "GET" ? rest : void 0
136
+ };
137
+ }
138
+ };
139
+
140
+ // src/openapi-output-structure-parser.ts
141
+ var OpenAPIOutputStructureParser = class {
142
+ constructor(schemaConverter, schemaUtils) {
143
+ this.schemaConverter = schemaConverter;
144
+ this.schemaUtils = schemaUtils;
145
+ }
146
+ parse(contract, structure) {
147
+ const outputSchema = this.schemaConverter.convert(contract["~orpc"].outputSchema, { strategy: "output" });
148
+ if (this.schemaUtils.isAnySchema(outputSchema)) {
149
+ return {
150
+ headersSchema: void 0,
151
+ bodySchema: void 0
152
+ };
153
+ }
154
+ if (structure === "detailed") {
155
+ return this.parseDetailedSchema(outputSchema);
156
+ } else {
157
+ return this.parseCompactSchema(outputSchema);
158
+ }
159
+ }
160
+ parseDetailedSchema(outputSchema) {
161
+ if (!this.schemaUtils.isObjectSchema(outputSchema)) {
162
+ throw new OpenAPIError(`When output structure is 'detailed', output schema must be an object.`);
163
+ }
164
+ if (outputSchema.properties && Object.keys(outputSchema.properties).some((key) => !["headers", "body"].includes(key))) {
165
+ throw new OpenAPIError(`When output structure is 'detailed', output schema must be only can contain 'headers' and 'body' properties.`);
166
+ }
167
+ let headersSchema = outputSchema.properties?.headers;
168
+ const bodySchema = outputSchema.properties?.body;
169
+ if (headersSchema !== void 0 && this.schemaUtils.isAnySchema(headersSchema)) {
170
+ headersSchema = void 0;
171
+ }
172
+ if (headersSchema !== void 0 && !this.schemaUtils.isObjectSchema(headersSchema)) {
173
+ throw new OpenAPIError(`When output structure is 'detailed', headers schema in output schema must be an object.`);
174
+ }
175
+ return { headersSchema, bodySchema };
176
+ }
177
+ parseCompactSchema(outputSchema) {
178
+ return {
179
+ headersSchema: void 0,
180
+ bodySchema: outputSchema
181
+ };
182
+ }
183
+ };
184
+
38
185
  // src/openapi-parameters-builder.ts
39
- import { get, isPlainObject } from "@orpc/shared";
186
+ import { get, isObject, omit } from "@orpc/shared";
40
187
  var OpenAPIParametersBuilder = class {
41
188
  build(paramIn, jsonSchema, options) {
42
189
  const parameters = [];
43
190
  for (const name in jsonSchema.properties) {
44
191
  const schema = jsonSchema.properties[name];
45
192
  const paramExamples = jsonSchema.examples?.filter((example) => {
46
- return isPlainObject(example) && name in example;
193
+ return isObject(example) && name in example;
47
194
  }).map((example) => {
48
195
  return example[name];
49
196
  });
@@ -63,6 +210,14 @@ var OpenAPIParametersBuilder = class {
63
210
  }
64
211
  return parameters;
65
212
  }
213
+ buildHeadersObject(jsonSchema, options) {
214
+ const parameters = this.build("header", jsonSchema, options);
215
+ const headersObject = {};
216
+ for (const param of parameters) {
217
+ headersObject[param.name] = omit(param, ["name", "in"]);
218
+ }
219
+ return headersObject;
220
+ }
66
221
  };
67
222
 
68
223
  // src/openapi-path-parser.ts
@@ -96,7 +251,7 @@ var CompositeSchemaConverter = class {
96
251
  };
97
252
 
98
253
  // src/schema-utils.ts
99
- import { isPlainObject as isPlainObject2 } from "@orpc/shared";
254
+ import { isObject as isObject2 } from "@orpc/shared";
100
255
 
101
256
  // src/schema.ts
102
257
  import * as JSONSchema from "json-schema-typed/draft-2020-12";
@@ -138,14 +293,14 @@ var SchemaUtils = class {
138
293
  return typeof schema === "object" && schema.type === "object";
139
294
  }
140
295
  isAnySchema(schema) {
141
- return schema === true || Object.keys(schema).length === 0;
296
+ return schema === true || Object.keys(schema).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
142
297
  }
143
298
  isUndefinableSchema(schema) {
144
299
  const [matches] = this.filterSchemaBranches(schema, (schema2) => {
145
300
  if (typeof schema2 === "boolean") {
146
301
  return schema2;
147
302
  }
148
- return Object.keys(schema2).length === 0;
303
+ return Object.keys(schema2).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
149
304
  });
150
305
  return matches.length > 0;
151
306
  }
@@ -158,7 +313,7 @@ var SchemaUtils = class {
158
313
  }, {});
159
314
  matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
160
315
  matched.examples = schema.examples?.map((example) => {
161
- if (!isPlainObject2(example)) {
316
+ if (!isObject2(example)) {
162
317
  return example;
163
318
  }
164
319
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -174,7 +329,7 @@ var SchemaUtils = class {
174
329
  }, {});
175
330
  rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
176
331
  rest.examples = schema.examples?.map((example) => {
177
- if (!isPlainObject2(example)) {
332
+ if (!isObject2(example)) {
178
333
  return example;
179
334
  }
180
335
  return Object.entries(example).reduce((acc, [key, value]) => {
@@ -218,130 +373,161 @@ var SchemaUtils = class {
218
373
 
219
374
  // src/openapi-generator.ts
220
375
  var OpenAPIGenerator = class {
376
+ contentBuilder;
377
+ parametersBuilder;
378
+ schemaConverter;
379
+ schemaUtils;
380
+ jsonSerializer;
381
+ pathParser;
382
+ inputStructureParser;
383
+ outputStructureParser;
384
+ errorHandlerStrategy;
385
+ ignoreUndefinedPathProcedures;
386
+ considerMissingTagDefinitionAsError;
387
+ strictErrorResponses;
221
388
  constructor(options) {
222
- this.options = options;
223
389
  this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
224
390
  this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
225
391
  this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
226
392
  this.jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
227
393
  this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
228
394
  this.pathParser = new OpenAPIPathParser();
395
+ this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
396
+ this.outputStructureParser = options?.outputStructureParser ?? new OpenAPIOutputStructureParser(this.schemaConverter, this.schemaUtils);
397
+ this.errorHandlerStrategy = options?.errorHandlerStrategy ?? "throw";
398
+ this.ignoreUndefinedPathProcedures = options?.ignoreUndefinedPathProcedures ?? false;
399
+ this.considerMissingTagDefinitionAsError = options?.considerMissingTagDefinitionAsError ?? false;
400
+ this.strictErrorResponses = options?.strictErrorResponses ?? true;
229
401
  }
230
- contentBuilder;
231
- parametersBuilder;
232
- schemaConverter;
233
- schemaUtils;
234
- jsonSerializer;
235
- pathParser;
236
402
  async generate(router, doc) {
237
403
  const builder = new OpenApiBuilder({
238
404
  ...doc,
239
405
  openapi: "3.1.1"
240
406
  });
241
407
  const rootTags = doc.tags?.map((tag) => tag.name) ?? [];
242
- await forEachAllContractProcedure(router, ({ contract, path }) => {
243
- const def = contract["~orpc"];
244
- if (this.options?.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
245
- return;
246
- }
247
- const method = def.route?.method ?? "POST";
248
- const httpPath = def.route?.path ? standardizeHTTPPath(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
249
- let inputSchema = this.schemaConverter.convert(def.InputSchema, { strategy: "input" });
250
- const outputSchema = this.schemaConverter.convert(def.OutputSchema, { strategy: "output" });
251
- const params = (() => {
252
- const dynamic = this.pathParser.parseDynamicParams(httpPath);
253
- if (!dynamic.length) {
254
- return void 0;
255
- }
256
- if (this.schemaUtils.isAnySchema(inputSchema)) {
257
- return void 0;
258
- }
259
- if (!this.schemaUtils.isObjectSchema(inputSchema)) {
260
- this.handleError(
261
- new Error(
262
- `When path has parameters, input schema must be an object [${path.join(".")}]`
263
- )
264
- );
265
- return void 0;
408
+ await eachAllContractProcedure({
409
+ path: [],
410
+ router
411
+ }, ({ contract, path }) => {
412
+ try {
413
+ const def = contract["~orpc"];
414
+ if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
415
+ return;
266
416
  }
267
- const [matched, rest] = this.schemaUtils.separateObjectSchema(inputSchema, dynamic.map((v) => v.name));
268
- inputSchema = rest;
269
- return this.parametersBuilder.build("path", matched, {
270
- example: def.inputExample,
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, {
271
424
  required: true
272
- });
273
- })();
274
- const query = (() => {
275
- if (method !== "GET" || Object.keys(inputSchema).length === 0) {
276
- return void 0;
277
- }
278
- if (this.schemaUtils.isAnySchema(inputSchema)) {
279
- return void 0;
280
- }
281
- if (!this.schemaUtils.isObjectSchema(inputSchema)) {
282
- this.handleError(
283
- new Error(
284
- `When method is GET, input schema must be an object [${path.join(".")}]`
285
- )
286
- );
287
- return void 0;
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
+ };
439
+ const errors = group(Object.entries(def.errorMap ?? {}).filter(([_, config]) => config).map(([code, config]) => ({
440
+ ...config,
441
+ code,
442
+ status: fallbackORPCErrorStatus(code, config?.status)
443
+ })), (error) => error.status);
444
+ for (const status in errors) {
445
+ const configs = errors[status];
446
+ if (!configs || configs.length === 0) {
447
+ continue;
448
+ }
449
+ const schemas = configs.map(({ data, code, message }) => {
450
+ const json = {
451
+ type: "object",
452
+ properties: {
453
+ defined: { const: true },
454
+ code: { const: code },
455
+ status: { const: Number(status) },
456
+ message: { type: "string", default: message },
457
+ data: {}
458
+ },
459
+ required: ["defined", "code", "status", "message"]
460
+ };
461
+ if (data) {
462
+ const dataJson = this.schemaConverter.convert(data, { strategy: "output" });
463
+ json.properties.data = dataJson;
464
+ if (!this.schemaUtils.isUndefinableSchema(dataJson)) {
465
+ json.required.push("data");
466
+ }
467
+ }
468
+ return json;
469
+ });
470
+ if (this.strictErrorResponses) {
471
+ schemas.push({
472
+ type: "object",
473
+ properties: {
474
+ defined: { const: false },
475
+ code: { type: "string" },
476
+ status: { type: "number" },
477
+ message: { type: "string" },
478
+ data: {}
479
+ },
480
+ required: ["defined", "code", "status", "message"]
481
+ });
482
+ }
483
+ const contentSchema = schemas.length === 1 ? schemas[0] : {
484
+ oneOf: schemas
485
+ };
486
+ responses[status] = {
487
+ description: status,
488
+ content: this.contentBuilder.build(contentSchema)
489
+ };
288
490
  }
289
- return this.parametersBuilder.build("query", inputSchema, {
290
- example: def.inputExample
291
- });
292
- })();
293
- const parameters = [...params ?? [], ...query ?? []];
294
- const requestBody = (() => {
295
- if (method === "GET") {
296
- return void 0;
491
+ if (this.considerMissingTagDefinitionAsError && def.route?.tags) {
492
+ const missingTag = def.route?.tags.find((tag) => !rootTags.includes(tag));
493
+ if (missingTag !== void 0) {
494
+ throw new OpenAPIError(
495
+ `Tag "${missingTag}" is missing definition. Please define it in OpenAPI root tags object`
496
+ );
497
+ }
297
498
  }
298
- return {
299
- required: this.schemaUtils.isUndefinableSchema(inputSchema),
300
- content: this.contentBuilder.build(inputSchema, {
301
- example: def.inputExample
302
- })
499
+ const operation = {
500
+ summary: def.route?.summary,
501
+ description: def.route?.description,
502
+ deprecated: def.route?.deprecated,
503
+ tags: def.route?.tags ? [...def.route.tags] : void 0,
504
+ operationId: path.join("."),
505
+ parameters: parameters.length ? parameters : void 0,
506
+ requestBody,
507
+ responses
303
508
  };
304
- })();
305
- const successResponse = {
306
- description: "OK",
307
- content: this.contentBuilder.build(outputSchema, {
308
- example: def.outputExample
309
- })
310
- };
311
- if (this.options?.considerMissingTagDefinitionAsError && def.route?.tags) {
312
- const missingTag = def.route?.tags.find((tag) => !rootTags.includes(tag));
313
- if (missingTag !== void 0) {
314
- this.handleError(
315
- new Error(
316
- `Tag "${missingTag}" is missing definition. Please define it in OpenAPI root tags object. [${path.join(".")}]`
317
- )
318
- );
509
+ builder.addPath(httpPath, {
510
+ [method.toLocaleLowerCase()]: operation
511
+ });
512
+ } catch (e) {
513
+ if (e instanceof OpenAPIError) {
514
+ const error = new OpenAPIError(`
515
+ Generate OpenAPI Error: ${e.message}
516
+ Happened at path: ${path.join(".")}
517
+ `, { cause: e });
518
+ if (this.errorHandlerStrategy === "throw") {
519
+ throw error;
520
+ }
521
+ if (this.errorHandlerStrategy === "log") {
522
+ console.error(error);
523
+ }
524
+ } else {
525
+ throw e;
319
526
  }
320
527
  }
321
- const operation = {
322
- summary: def.route?.summary,
323
- description: def.route?.description,
324
- deprecated: def.route?.deprecated,
325
- tags: def.route?.tags ? [...def.route.tags] : void 0,
326
- operationId: path.join("."),
327
- parameters: parameters.length ? parameters : void 0,
328
- requestBody,
329
- responses: {
330
- [def.route?.successStatus ?? 200]: successResponse
331
- }
332
- };
333
- builder.addPath(httpPath, {
334
- [method.toLocaleLowerCase()]: operation
335
- });
336
528
  });
337
529
  return this.jsonSerializer.serialize(builder.getSpec());
338
530
  }
339
- handleError(error) {
340
- if (this.options?.throwOnError) {
341
- throw error;
342
- }
343
- console.error(error);
344
- }
345
531
  };
346
532
  export {
347
533
  CompositeSchemaConverter,
@@ -355,8 +541,6 @@ export {
355
541
  OpenAPIPathParser,
356
542
  OpenApiBuilder,
357
543
  SchemaUtils,
358
- forEachAllContractProcedure,
359
- forEachContractProcedure,
360
544
  standardizeHTTPPath
361
545
  };
362
546
  //# sourceMappingURL=index.js.map
package/dist/next.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ OpenAPIHandler
3
+ } from "./chunk-ICLAXOVR.js";
4
+ import "./chunk-PWOV66X6.js";
5
+ import "./chunk-HC5PVG4R.js";
6
+ export {
7
+ OpenAPIHandler
8
+ };
9
+ //# sourceMappingURL=next.js.map
package/dist/node.js ADDED
@@ -0,0 +1,30 @@
1
+ import {
2
+ OpenAPICodec,
3
+ OpenAPIMatcher
4
+ } from "./chunk-PWOV66X6.js";
5
+ import "./chunk-HC5PVG4R.js";
6
+
7
+ // src/adapters/node/openapi-handler.ts
8
+ import { nodeHttpResponseSendStandardResponse, nodeHttpToStandardRequest } from "@orpc/server/node";
9
+ import { StandardHandler } from "@orpc/server/standard";
10
+ var OpenAPIHandler = class {
11
+ standardHandler;
12
+ constructor(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 });
16
+ }
17
+ async handle(req, res, ...rest) {
18
+ const standardRequest = nodeHttpToStandardRequest(req, res);
19
+ const result = await this.standardHandler.handle(standardRequest, ...rest);
20
+ if (!result.matched) {
21
+ return { matched: false };
22
+ }
23
+ await nodeHttpResponseSendStandardResponse(res, result.response);
24
+ return { matched: true };
25
+ }
26
+ };
27
+ export {
28
+ OpenAPIHandler
29
+ };
30
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1,2 @@
1
+ export * from './openapi-handler';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { Context, Router } from '@orpc/server';
2
+ import type { FetchHandler, FetchHandleResult } from '@orpc/server/fetch';
3
+ import type { StandardHandleRest } from '@orpc/server/standard';
4
+ import type { OpenAPIHandlerOptions } from '../standard';
5
+ export declare class OpenAPIHandler<T extends Context> implements FetchHandler<T> {
6
+ private readonly standardHandler;
7
+ constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
8
+ handle(request: Request, ...rest: StandardHandleRest<T>): Promise<FetchHandleResult>;
9
+ }
10
+ //# 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
@@ -0,0 +1,2 @@
1
+ export * from './openapi-handler';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { Context, Router } from '@orpc/server';
2
+ import type { NodeHttpHandler, NodeHttpHandleResult, NodeHttpRequest, NodeHttpResponse } from '@orpc/server/node';
3
+ import type { StandardHandleRest } from '@orpc/server/standard';
4
+ import type { OpenAPIHandlerOptions } from '../standard';
5
+ export declare class OpenAPIHandler<T extends Context> implements NodeHttpHandler<T> {
6
+ private readonly standardHandler;
7
+ constructor(router: Router<T, any>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
8
+ handle(req: NodeHttpRequest, res: NodeHttpResponse, ...rest: StandardHandleRest<T>): Promise<NodeHttpHandleResult>;
9
+ }
10
+ //# sourceMappingURL=openapi-handler.d.ts.map
@@ -0,0 +1,6 @@
1
+ export * as BracketNotation from './bracket-notation';
2
+ export * from './openapi-codec';
3
+ export * from './openapi-handler';
4
+ export * from './openapi-matcher';
5
+ export * from './openapi-serializer';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { AnyProcedure } from '@orpc/server';
2
+ import type { StandardCodec, StandardParams, StandardRequest, StandardResponse } from '@orpc/server/standard';
3
+ import { type ORPCError } from '@orpc/contract';
4
+ import { OpenAPISerializer } from './openapi-serializer';
5
+ export interface OpenAPICodecOptions {
6
+ serializer?: OpenAPISerializer;
7
+ }
8
+ export declare class OpenAPICodec implements StandardCodec {
9
+ private readonly serializer;
10
+ constructor(options?: OpenAPICodecOptions);
11
+ decode(request: StandardRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
12
+ encode(output: unknown, procedure: AnyProcedure): StandardResponse;
13
+ encodeError(error: ORPCError<any, any>): StandardResponse;
14
+ }
15
+ //# 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
@@ -0,0 +1,11 @@
1
+ import type { PublicJSONSerializer } from '../../json-serializer';
2
+ export interface OpenAPISerializerOptions {
3
+ jsonSerializer?: PublicJSONSerializer;
4
+ }
5
+ export declare class OpenAPISerializer {
6
+ private readonly jsonSerializer;
7
+ constructor(options?: OpenAPISerializerOptions);
8
+ serialize(data: unknown): unknown;
9
+ deserialize(serialized: unknown): unknown;
10
+ }
11
+ //# sourceMappingURL=openapi-serializer.d.ts.map
@@ -0,0 +1,3 @@
1
+ export declare class OpenAPIError extends Error {
2
+ }
3
+ //# sourceMappingURL=openapi-error.d.ts.map