@orpc/openapi 0.0.0-next.fd1db03 → 0.0.0-next.ff5907c
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.
- package/dist/chunk-LPBZEW4B.js +165 -0
- package/dist/chunk-UU2TTVB2.js +32 -0
- package/dist/chunk-XGHV4TH3.js +13 -0
- package/dist/fetch.js +5 -657
- package/dist/hono.js +9 -0
- package/dist/index.js +283 -63
- package/dist/next.js +9 -0
- package/dist/node.js +30 -0
- package/dist/src/adapters/fetch/index.d.ts +2 -0
- package/dist/src/adapters/fetch/openapi-handler.d.ts +11 -0
- package/dist/src/adapters/hono/index.d.ts +2 -0
- package/dist/src/adapters/next/index.d.ts +2 -0
- package/dist/src/adapters/node/index.d.ts +2 -0
- package/dist/src/adapters/node/openapi-handler.d.ts +11 -0
- package/dist/src/adapters/standard/index.d.ts +4 -0
- package/dist/src/adapters/standard/openapi-codec.d.ts +16 -0
- package/dist/src/adapters/standard/openapi-handler.d.ts +7 -0
- package/dist/src/adapters/standard/openapi-matcher.d.ts +20 -0
- package/dist/src/index.d.ts +5 -1
- package/dist/src/openapi-generator.d.ts +21 -10
- package/dist/src/openapi-input-structure-parser.d.ts +2 -2
- package/dist/src/openapi-operation-extender.d.ts +7 -0
- package/dist/src/openapi-output-structure-parser.d.ts +2 -2
- package/dist/src/schema-converter.d.ts +2 -2
- package/dist/src/schema.d.ts +1 -1
- package/dist/src/utils.d.ts +2 -16
- package/dist/standard.js +10 -0
- package/package.json +31 -14
- package/dist/chunk-KNYXLM77.js +0 -107
- package/dist/src/fetch/bracket-notation.d.ts +0 -84
- package/dist/src/fetch/index.d.ts +0 -10
- package/dist/src/fetch/input-structure-compact.d.ts +0 -6
- package/dist/src/fetch/input-structure-detailed.d.ts +0 -11
- package/dist/src/fetch/openapi-handler-server.d.ts +0 -7
- package/dist/src/fetch/openapi-handler-serverless.d.ts +0 -7
- package/dist/src/fetch/openapi-handler.d.ts +0 -33
- package/dist/src/fetch/openapi-payload-codec.d.ts +0 -15
- package/dist/src/fetch/openapi-procedure-matcher.d.ts +0 -19
- package/dist/src/fetch/schema-coercer.d.ts +0 -10
- package/dist/src/json-serializer.d.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -1,9 +1,53 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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"].
|
|
51
|
-
const method = contract["~orpc"].route?.method
|
|
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"].
|
|
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,
|
|
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
|
|
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 {
|
|
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";
|
|
@@ -283,20 +335,20 @@ var NON_LOGIC_KEYWORDS = [
|
|
|
283
335
|
// src/schema-utils.ts
|
|
284
336
|
var SchemaUtils = class {
|
|
285
337
|
isFileSchema(schema) {
|
|
286
|
-
return
|
|
338
|
+
return isObject2(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
|
|
287
339
|
}
|
|
288
340
|
isObjectSchema(schema) {
|
|
289
|
-
return
|
|
341
|
+
return isObject2(schema) && 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 (!
|
|
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 (!
|
|
380
|
+
if (!isObject2(example)) {
|
|
329
381
|
return example;
|
|
330
382
|
}
|
|
331
383
|
return Object.entries(example).reduce((acc, [key, value]) => {
|
|
@@ -369,61 +421,219 @@ var SchemaUtils = class {
|
|
|
369
421
|
|
|
370
422
|
// src/openapi-generator.ts
|
|
371
423
|
var OpenAPIGenerator = class {
|
|
424
|
+
contentBuilder;
|
|
425
|
+
parametersBuilder;
|
|
426
|
+
schemaConverter;
|
|
427
|
+
schemaUtils;
|
|
428
|
+
jsonSerializer;
|
|
429
|
+
pathParser;
|
|
430
|
+
inputStructureParser;
|
|
431
|
+
outputStructureParser;
|
|
432
|
+
errorHandlerStrategy;
|
|
433
|
+
ignoreUndefinedPathProcedures;
|
|
434
|
+
considerMissingTagDefinitionAsError;
|
|
435
|
+
strictErrorResponses;
|
|
372
436
|
constructor(options) {
|
|
373
|
-
this.options = options;
|
|
374
437
|
this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
|
|
375
438
|
this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
|
|
376
439
|
this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
|
|
377
|
-
this.jsonSerializer = options?.jsonSerializer ?? new
|
|
440
|
+
this.jsonSerializer = options?.jsonSerializer ?? new OpenAPIJsonSerializer();
|
|
378
441
|
this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
|
|
379
442
|
this.pathParser = new OpenAPIPathParser();
|
|
380
443
|
this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
|
|
381
444
|
this.outputStructureParser = options?.outputStructureParser ?? new OpenAPIOutputStructureParser(this.schemaConverter, this.schemaUtils);
|
|
445
|
+
this.errorHandlerStrategy = options?.errorHandlerStrategy ?? "throw";
|
|
446
|
+
this.ignoreUndefinedPathProcedures = options?.ignoreUndefinedPathProcedures ?? false;
|
|
447
|
+
this.considerMissingTagDefinitionAsError = options?.considerMissingTagDefinitionAsError ?? false;
|
|
448
|
+
this.strictErrorResponses = options?.strictErrorResponses ?? true;
|
|
382
449
|
}
|
|
383
|
-
contentBuilder;
|
|
384
|
-
parametersBuilder;
|
|
385
|
-
schemaConverter;
|
|
386
|
-
schemaUtils;
|
|
387
|
-
jsonSerializer;
|
|
388
|
-
pathParser;
|
|
389
|
-
inputStructureParser;
|
|
390
|
-
outputStructureParser;
|
|
391
450
|
async generate(router, doc) {
|
|
392
451
|
const builder = new OpenApiBuilder({
|
|
393
452
|
...doc,
|
|
394
453
|
openapi: "3.1.1"
|
|
395
454
|
});
|
|
396
455
|
const rootTags = doc.tags?.map((tag) => tag.name) ?? [];
|
|
397
|
-
await
|
|
456
|
+
await eachAllContractProcedure({
|
|
457
|
+
path: [],
|
|
458
|
+
router
|
|
459
|
+
}, ({ contract, path }) => {
|
|
398
460
|
try {
|
|
399
461
|
const def = contract["~orpc"];
|
|
400
|
-
if (this.
|
|
462
|
+
if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
|
|
401
463
|
return;
|
|
402
464
|
}
|
|
403
|
-
const method = def.route?.method
|
|
404
|
-
const httpPath = def.route?.path ?
|
|
405
|
-
const {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
+
}
|
|
636
|
+
if (this.considerMissingTagDefinitionAsError && def.route?.tags) {
|
|
427
637
|
const missingTag = def.route?.tags.find((tag) => !rootTags.includes(tag));
|
|
428
638
|
if (missingTag !== void 0) {
|
|
429
639
|
throw new OpenAPIError(
|
|
@@ -439,12 +649,11 @@ var OpenAPIGenerator = class {
|
|
|
439
649
|
operationId: path.join("."),
|
|
440
650
|
parameters: parameters.length ? parameters : void 0,
|
|
441
651
|
requestBody,
|
|
442
|
-
responses
|
|
443
|
-
[def.route?.successStatus ?? 200]: successResponse
|
|
444
|
-
}
|
|
652
|
+
responses
|
|
445
653
|
};
|
|
654
|
+
const extendedOperation = extendOperation(operation, contract);
|
|
446
655
|
builder.addPath(httpPath, {
|
|
447
|
-
[method.toLocaleLowerCase()]:
|
|
656
|
+
[method.toLocaleLowerCase()]: extendedOperation
|
|
448
657
|
});
|
|
449
658
|
} catch (e) {
|
|
450
659
|
if (e instanceof OpenAPIError) {
|
|
@@ -452,21 +661,29 @@ var OpenAPIGenerator = class {
|
|
|
452
661
|
Generate OpenAPI Error: ${e.message}
|
|
453
662
|
Happened at path: ${path.join(".")}
|
|
454
663
|
`, { cause: e });
|
|
455
|
-
if (this.
|
|
664
|
+
if (this.errorHandlerStrategy === "throw") {
|
|
456
665
|
throw error;
|
|
457
666
|
}
|
|
458
|
-
|
|
667
|
+
if (this.errorHandlerStrategy === "log") {
|
|
668
|
+
console.error(error);
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
throw e;
|
|
459
672
|
}
|
|
460
673
|
}
|
|
461
674
|
});
|
|
462
675
|
return this.jsonSerializer.serialize(builder.getSpec());
|
|
463
676
|
}
|
|
464
677
|
};
|
|
678
|
+
|
|
679
|
+
// src/index.ts
|
|
680
|
+
var oo = {
|
|
681
|
+
spec: setOperationExtender
|
|
682
|
+
};
|
|
465
683
|
export {
|
|
466
684
|
CompositeSchemaConverter,
|
|
467
685
|
JSONSchema,
|
|
468
686
|
Format as JSONSchemaFormat,
|
|
469
|
-
JSONSerializer,
|
|
470
687
|
NON_LOGIC_KEYWORDS,
|
|
471
688
|
OpenAPIContentBuilder,
|
|
472
689
|
OpenAPIGenerator,
|
|
@@ -474,8 +691,11 @@ export {
|
|
|
474
691
|
OpenAPIPathParser,
|
|
475
692
|
OpenApiBuilder,
|
|
476
693
|
SchemaUtils,
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
694
|
+
extendOperation,
|
|
695
|
+
getOperationExtender,
|
|
696
|
+
oo,
|
|
697
|
+
setOperationExtender,
|
|
698
|
+
standardizeHTTPPath,
|
|
699
|
+
toOpenAPI31RoutePattern
|
|
480
700
|
};
|
|
481
701
|
//# sourceMappingURL=index.js.map
|
package/dist/next.js
ADDED
package/dist/node.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OpenAPICodec,
|
|
3
|
+
OpenAPIMatcher
|
|
4
|
+
} from "./chunk-LPBZEW4B.js";
|
|
5
|
+
import "./chunk-XGHV4TH3.js";
|
|
6
|
+
|
|
7
|
+
// src/adapters/node/openapi-handler.ts
|
|
8
|
+
import { sendStandardResponse, toStandardRequest } from "@orpc/server-standard-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 = 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 };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
OpenAPIHandler
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
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>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openapi-handler.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Context, Router } from '@orpc/server';
|
|
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>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openapi-handler.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
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** unnoq */
|
|
2
|
-
|
|
2
|
+
import { setOperationExtender } from './openapi-operation-extender';
|
|
3
3
|
export * from './openapi';
|
|
4
4
|
export * from './openapi-content-builder';
|
|
5
5
|
export * from './openapi-generator';
|
|
6
|
+
export * from './openapi-operation-extender';
|
|
6
7
|
export * from './openapi-parameters-builder';
|
|
7
8
|
export * from './openapi-path-parser';
|
|
8
9
|
export * from './schema';
|
|
9
10
|
export * from './schema-converter';
|
|
10
11
|
export * from './schema-utils';
|
|
11
12
|
export * from './utils';
|
|
13
|
+
export declare const oo: {
|
|
14
|
+
spec: typeof setOperationExtender;
|
|
15
|
+
};
|
|
12
16
|
//# sourceMappingURL=index.d.ts.map
|