@orpc/openapi 0.0.0-next.d42488d → 0.0.0-next.d74cac4
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-5QMOOQSF.js +32 -0
- package/dist/chunk-HC5PVG4R.js +52 -0
- package/dist/chunk-TOZPXKQC.js +450 -0
- package/dist/fetch.js +5 -587
- package/dist/hono.js +9 -0
- package/dist/index.js +450 -113
- 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 +6 -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/adapters/standard/openapi-serializer.d.ts +11 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/openapi-error.d.ts +3 -0
- package/dist/src/openapi-generator.d.ts +25 -9
- package/dist/src/openapi-input-structure-parser.d.ts +22 -0
- package/dist/src/openapi-operation-extender.d.ts +7 -0
- package/dist/src/openapi-output-structure-parser.d.ts +18 -0
- package/dist/src/openapi-parameters-builder.d.ts +3 -0
- package/dist/src/schema-converter.d.ts +2 -2
- package/dist/src/schema.d.ts +1 -1
- package/dist/src/utils.d.ts +1 -16
- package/dist/standard.js +14 -0
- package/package.json +30 -13
- package/dist/chunk-KNYXLM77.js +0 -107
- package/dist/src/fetch/index.d.ts +0 -10
- package/dist/src/fetch/input-builder-full.d.ts +0 -11
- package/dist/src/fetch/input-builder-simple.d.ts +0 -6
- 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 -30
- 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/{fetch → adapters/standard}/bracket-notation.d.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -1,9 +1,53 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JSONSerializer,
|
|
3
|
-
forEachAllContractProcedure,
|
|
4
|
-
forEachContractProcedure,
|
|
5
3
|
standardizeHTTPPath
|
|
6
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HC5PVG4R.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,15 +79,164 @@ var OpenAPIContentBuilder = class {
|
|
|
35
79
|
}
|
|
36
80
|
};
|
|
37
81
|
|
|
82
|
+
// src/openapi-generator.ts
|
|
83
|
+
import { fallbackContractConfig as fallbackContractConfig2, fallbackORPCErrorStatus, getEventIteratorSchemaDetails } from "@orpc/contract";
|
|
84
|
+
import { eachAllContractProcedure } from "@orpc/server";
|
|
85
|
+
import { group } from "@orpc/shared";
|
|
86
|
+
|
|
87
|
+
// src/openapi-error.ts
|
|
88
|
+
var OpenAPIError = class extends Error {
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/openapi-input-structure-parser.ts
|
|
92
|
+
import { fallbackContractConfig } from "@orpc/contract";
|
|
93
|
+
var OpenAPIInputStructureParser = class {
|
|
94
|
+
constructor(schemaConverter, schemaUtils, pathParser) {
|
|
95
|
+
this.schemaConverter = schemaConverter;
|
|
96
|
+
this.schemaUtils = schemaUtils;
|
|
97
|
+
this.pathParser = pathParser;
|
|
98
|
+
}
|
|
99
|
+
parse(contract, structure) {
|
|
100
|
+
const inputSchema = this.schemaConverter.convert(contract["~orpc"].inputSchema, { strategy: "input" });
|
|
101
|
+
const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route?.method);
|
|
102
|
+
const httpPath = contract["~orpc"].route?.path;
|
|
103
|
+
if (this.schemaUtils.isAnySchema(inputSchema)) {
|
|
104
|
+
return {
|
|
105
|
+
paramsSchema: void 0,
|
|
106
|
+
querySchema: void 0,
|
|
107
|
+
headersSchema: void 0,
|
|
108
|
+
bodySchema: void 0
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (structure === "detailed") {
|
|
112
|
+
return this.parseDetailedSchema(inputSchema);
|
|
113
|
+
} else {
|
|
114
|
+
return this.parseCompactSchema(inputSchema, method, httpPath);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
parseDetailedSchema(inputSchema) {
|
|
118
|
+
if (!this.schemaUtils.isObjectSchema(inputSchema)) {
|
|
119
|
+
throw new OpenAPIError(`When input structure is 'detailed', input schema must be an object.`);
|
|
120
|
+
}
|
|
121
|
+
if (inputSchema.properties && Object.keys(inputSchema.properties).some((key) => !["params", "query", "headers", "body"].includes(key))) {
|
|
122
|
+
throw new OpenAPIError(`When input structure is 'detailed', input schema must be only can contain 'params', 'query', 'headers' and 'body' properties.`);
|
|
123
|
+
}
|
|
124
|
+
let paramsSchema = inputSchema.properties?.params;
|
|
125
|
+
let querySchema = inputSchema.properties?.query;
|
|
126
|
+
let headersSchema = inputSchema.properties?.headers;
|
|
127
|
+
const bodySchema = inputSchema.properties?.body;
|
|
128
|
+
if (paramsSchema !== void 0 && this.schemaUtils.isAnySchema(paramsSchema)) {
|
|
129
|
+
paramsSchema = void 0;
|
|
130
|
+
}
|
|
131
|
+
if (paramsSchema !== void 0 && !this.schemaUtils.isObjectSchema(paramsSchema)) {
|
|
132
|
+
throw new OpenAPIError(`When input structure is 'detailed', params schema in input schema must be an object.`);
|
|
133
|
+
}
|
|
134
|
+
if (querySchema !== void 0 && this.schemaUtils.isAnySchema(querySchema)) {
|
|
135
|
+
querySchema = void 0;
|
|
136
|
+
}
|
|
137
|
+
if (querySchema !== void 0 && !this.schemaUtils.isObjectSchema(querySchema)) {
|
|
138
|
+
throw new OpenAPIError(`When input structure is 'detailed', query schema in input schema must be an object.`);
|
|
139
|
+
}
|
|
140
|
+
if (headersSchema !== void 0 && this.schemaUtils.isAnySchema(headersSchema)) {
|
|
141
|
+
headersSchema = void 0;
|
|
142
|
+
}
|
|
143
|
+
if (headersSchema !== void 0 && !this.schemaUtils.isObjectSchema(headersSchema)) {
|
|
144
|
+
throw new OpenAPIError(`When input structure is 'detailed', headers schema in input schema must be an object.`);
|
|
145
|
+
}
|
|
146
|
+
return { paramsSchema, querySchema, headersSchema, bodySchema };
|
|
147
|
+
}
|
|
148
|
+
parseCompactSchema(inputSchema, method, httpPath) {
|
|
149
|
+
const dynamic = httpPath ? this.pathParser.parseDynamicParams(httpPath) : [];
|
|
150
|
+
if (dynamic.length === 0) {
|
|
151
|
+
if (method === "GET") {
|
|
152
|
+
let querySchema = inputSchema;
|
|
153
|
+
if (querySchema !== void 0 && this.schemaUtils.isAnySchema(querySchema)) {
|
|
154
|
+
querySchema = void 0;
|
|
155
|
+
}
|
|
156
|
+
if (querySchema !== void 0 && !this.schemaUtils.isObjectSchema(querySchema)) {
|
|
157
|
+
throw new OpenAPIError(`When input structure is 'compact' and method is 'GET', input schema must be an object.`);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
paramsSchema: void 0,
|
|
161
|
+
querySchema,
|
|
162
|
+
headersSchema: void 0,
|
|
163
|
+
bodySchema: void 0
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
paramsSchema: void 0,
|
|
168
|
+
querySchema: void 0,
|
|
169
|
+
headersSchema: void 0,
|
|
170
|
+
bodySchema: inputSchema
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (!this.schemaUtils.isObjectSchema(inputSchema)) {
|
|
174
|
+
throw new OpenAPIError(`When input structure is 'compact' and path has dynamic parameters, input schema must be an object.`);
|
|
175
|
+
}
|
|
176
|
+
const [params, rest] = this.schemaUtils.separateObjectSchema(inputSchema, dynamic.map((v) => v.name));
|
|
177
|
+
return {
|
|
178
|
+
paramsSchema: params,
|
|
179
|
+
querySchema: method === "GET" ? rest : void 0,
|
|
180
|
+
headersSchema: void 0,
|
|
181
|
+
bodySchema: method !== "GET" ? rest : void 0
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// src/openapi-output-structure-parser.ts
|
|
187
|
+
var OpenAPIOutputStructureParser = class {
|
|
188
|
+
constructor(schemaConverter, schemaUtils) {
|
|
189
|
+
this.schemaConverter = schemaConverter;
|
|
190
|
+
this.schemaUtils = schemaUtils;
|
|
191
|
+
}
|
|
192
|
+
parse(contract, structure) {
|
|
193
|
+
const outputSchema = this.schemaConverter.convert(contract["~orpc"].outputSchema, { strategy: "output" });
|
|
194
|
+
if (this.schemaUtils.isAnySchema(outputSchema)) {
|
|
195
|
+
return {
|
|
196
|
+
headersSchema: void 0,
|
|
197
|
+
bodySchema: void 0
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (structure === "detailed") {
|
|
201
|
+
return this.parseDetailedSchema(outputSchema);
|
|
202
|
+
} else {
|
|
203
|
+
return this.parseCompactSchema(outputSchema);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
parseDetailedSchema(outputSchema) {
|
|
207
|
+
if (!this.schemaUtils.isObjectSchema(outputSchema)) {
|
|
208
|
+
throw new OpenAPIError(`When output structure is 'detailed', output schema must be an object.`);
|
|
209
|
+
}
|
|
210
|
+
if (outputSchema.properties && Object.keys(outputSchema.properties).some((key) => !["headers", "body"].includes(key))) {
|
|
211
|
+
throw new OpenAPIError(`When output structure is 'detailed', output schema must be only can contain 'headers' and 'body' properties.`);
|
|
212
|
+
}
|
|
213
|
+
let headersSchema = outputSchema.properties?.headers;
|
|
214
|
+
const bodySchema = outputSchema.properties?.body;
|
|
215
|
+
if (headersSchema !== void 0 && this.schemaUtils.isAnySchema(headersSchema)) {
|
|
216
|
+
headersSchema = void 0;
|
|
217
|
+
}
|
|
218
|
+
if (headersSchema !== void 0 && !this.schemaUtils.isObjectSchema(headersSchema)) {
|
|
219
|
+
throw new OpenAPIError(`When output structure is 'detailed', headers schema in output schema must be an object.`);
|
|
220
|
+
}
|
|
221
|
+
return { headersSchema, bodySchema };
|
|
222
|
+
}
|
|
223
|
+
parseCompactSchema(outputSchema) {
|
|
224
|
+
return {
|
|
225
|
+
headersSchema: void 0,
|
|
226
|
+
bodySchema: outputSchema
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
38
231
|
// src/openapi-parameters-builder.ts
|
|
39
|
-
import { get,
|
|
232
|
+
import { get, isObject, omit } from "@orpc/shared";
|
|
40
233
|
var OpenAPIParametersBuilder = class {
|
|
41
234
|
build(paramIn, jsonSchema, options) {
|
|
42
235
|
const parameters = [];
|
|
43
236
|
for (const name in jsonSchema.properties) {
|
|
44
237
|
const schema = jsonSchema.properties[name];
|
|
45
238
|
const paramExamples = jsonSchema.examples?.filter((example) => {
|
|
46
|
-
return
|
|
239
|
+
return isObject(example) && name in example;
|
|
47
240
|
}).map((example) => {
|
|
48
241
|
return example[name];
|
|
49
242
|
});
|
|
@@ -63,6 +256,14 @@ var OpenAPIParametersBuilder = class {
|
|
|
63
256
|
}
|
|
64
257
|
return parameters;
|
|
65
258
|
}
|
|
259
|
+
buildHeadersObject(jsonSchema, options) {
|
|
260
|
+
const parameters = this.build("header", jsonSchema, options);
|
|
261
|
+
const headersObject = {};
|
|
262
|
+
for (const param of parameters) {
|
|
263
|
+
headersObject[param.name] = omit(param, ["name", "in"]);
|
|
264
|
+
}
|
|
265
|
+
return headersObject;
|
|
266
|
+
}
|
|
66
267
|
};
|
|
67
268
|
|
|
68
269
|
// src/openapi-path-parser.ts
|
|
@@ -96,7 +297,7 @@ var CompositeSchemaConverter = class {
|
|
|
96
297
|
};
|
|
97
298
|
|
|
98
299
|
// src/schema-utils.ts
|
|
99
|
-
import {
|
|
300
|
+
import { isObject as isObject2 } from "@orpc/shared";
|
|
100
301
|
|
|
101
302
|
// src/schema.ts
|
|
102
303
|
import * as JSONSchema from "json-schema-typed/draft-2020-12";
|
|
@@ -138,14 +339,14 @@ var SchemaUtils = class {
|
|
|
138
339
|
return typeof schema === "object" && schema.type === "object";
|
|
139
340
|
}
|
|
140
341
|
isAnySchema(schema) {
|
|
141
|
-
return schema === true || Object.keys(schema).length === 0;
|
|
342
|
+
return schema === true || Object.keys(schema).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
|
|
142
343
|
}
|
|
143
344
|
isUndefinableSchema(schema) {
|
|
144
345
|
const [matches] = this.filterSchemaBranches(schema, (schema2) => {
|
|
145
346
|
if (typeof schema2 === "boolean") {
|
|
146
347
|
return schema2;
|
|
147
348
|
}
|
|
148
|
-
return Object.keys(schema2).length === 0;
|
|
349
|
+
return Object.keys(schema2).filter((key) => !NON_LOGIC_KEYWORDS.includes(key)).length === 0;
|
|
149
350
|
});
|
|
150
351
|
return matches.length > 0;
|
|
151
352
|
}
|
|
@@ -158,7 +359,7 @@ var SchemaUtils = class {
|
|
|
158
359
|
}, {});
|
|
159
360
|
matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
|
|
160
361
|
matched.examples = schema.examples?.map((example) => {
|
|
161
|
-
if (!
|
|
362
|
+
if (!isObject2(example)) {
|
|
162
363
|
return example;
|
|
163
364
|
}
|
|
164
365
|
return Object.entries(example).reduce((acc, [key, value]) => {
|
|
@@ -174,7 +375,7 @@ var SchemaUtils = class {
|
|
|
174
375
|
}, {});
|
|
175
376
|
rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
|
|
176
377
|
rest.examples = schema.examples?.map((example) => {
|
|
177
|
-
if (!
|
|
378
|
+
if (!isObject2(example)) {
|
|
178
379
|
return example;
|
|
179
380
|
}
|
|
180
381
|
return Object.entries(example).reduce((acc, [key, value]) => {
|
|
@@ -218,130 +419,264 @@ var SchemaUtils = class {
|
|
|
218
419
|
|
|
219
420
|
// src/openapi-generator.ts
|
|
220
421
|
var OpenAPIGenerator = class {
|
|
422
|
+
contentBuilder;
|
|
423
|
+
parametersBuilder;
|
|
424
|
+
schemaConverter;
|
|
425
|
+
schemaUtils;
|
|
426
|
+
jsonSerializer;
|
|
427
|
+
pathParser;
|
|
428
|
+
inputStructureParser;
|
|
429
|
+
outputStructureParser;
|
|
430
|
+
errorHandlerStrategy;
|
|
431
|
+
ignoreUndefinedPathProcedures;
|
|
432
|
+
considerMissingTagDefinitionAsError;
|
|
433
|
+
strictErrorResponses;
|
|
221
434
|
constructor(options) {
|
|
222
|
-
this.options = options;
|
|
223
435
|
this.parametersBuilder = options?.parametersBuilder ?? new OpenAPIParametersBuilder();
|
|
224
436
|
this.schemaConverter = new CompositeSchemaConverter(options?.schemaConverters ?? []);
|
|
225
437
|
this.schemaUtils = options?.schemaUtils ?? new SchemaUtils();
|
|
226
438
|
this.jsonSerializer = options?.jsonSerializer ?? new JSONSerializer();
|
|
227
439
|
this.contentBuilder = options?.contentBuilder ?? new OpenAPIContentBuilder(this.schemaUtils);
|
|
228
440
|
this.pathParser = new OpenAPIPathParser();
|
|
441
|
+
this.inputStructureParser = options?.inputStructureParser ?? new OpenAPIInputStructureParser(this.schemaConverter, this.schemaUtils, this.pathParser);
|
|
442
|
+
this.outputStructureParser = options?.outputStructureParser ?? new OpenAPIOutputStructureParser(this.schemaConverter, this.schemaUtils);
|
|
443
|
+
this.errorHandlerStrategy = options?.errorHandlerStrategy ?? "throw";
|
|
444
|
+
this.ignoreUndefinedPathProcedures = options?.ignoreUndefinedPathProcedures ?? false;
|
|
445
|
+
this.considerMissingTagDefinitionAsError = options?.considerMissingTagDefinitionAsError ?? false;
|
|
446
|
+
this.strictErrorResponses = options?.strictErrorResponses ?? true;
|
|
229
447
|
}
|
|
230
|
-
contentBuilder;
|
|
231
|
-
parametersBuilder;
|
|
232
|
-
schemaConverter;
|
|
233
|
-
schemaUtils;
|
|
234
|
-
jsonSerializer;
|
|
235
|
-
pathParser;
|
|
236
448
|
async generate(router, doc) {
|
|
237
449
|
const builder = new OpenApiBuilder({
|
|
238
450
|
...doc,
|
|
239
451
|
openapi: "3.1.1"
|
|
240
452
|
});
|
|
241
453
|
const rootTags = doc.tags?.map((tag) => tag.name) ?? [];
|
|
242
|
-
await
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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;
|
|
454
|
+
await eachAllContractProcedure({
|
|
455
|
+
path: [],
|
|
456
|
+
router
|
|
457
|
+
}, ({ contract, path }) => {
|
|
458
|
+
try {
|
|
459
|
+
const def = contract["~orpc"];
|
|
460
|
+
if (this.ignoreUndefinedPathProcedures && def.route?.path === void 0) {
|
|
461
|
+
return;
|
|
258
462
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
463
|
+
const method = fallbackContractConfig2("defaultMethod", def.route?.method);
|
|
464
|
+
const httpPath = def.route?.path ? standardizeHTTPPath(def.route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
|
|
465
|
+
const { parameters, requestBody } = (() => {
|
|
466
|
+
const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.inputSchema);
|
|
467
|
+
if (eventIteratorSchemaDetails) {
|
|
468
|
+
const requestBody3 = {
|
|
469
|
+
required: true,
|
|
470
|
+
content: {
|
|
471
|
+
"text/event-stream": {
|
|
472
|
+
schema: {
|
|
473
|
+
oneOf: [
|
|
474
|
+
{
|
|
475
|
+
type: "object",
|
|
476
|
+
properties: {
|
|
477
|
+
event: { type: "string", const: "message" },
|
|
478
|
+
data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
|
|
479
|
+
id: { type: "string" },
|
|
480
|
+
retry: { type: "number" }
|
|
481
|
+
},
|
|
482
|
+
required: ["event", "data"]
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
type: "object",
|
|
486
|
+
properties: {
|
|
487
|
+
event: { type: "string", const: "done" },
|
|
488
|
+
data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
|
|
489
|
+
id: { type: "string" },
|
|
490
|
+
retry: { type: "number" }
|
|
491
|
+
},
|
|
492
|
+
required: ["event", "data"]
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
type: "object",
|
|
496
|
+
properties: {
|
|
497
|
+
event: { type: "string", const: "error" },
|
|
498
|
+
data: {},
|
|
499
|
+
id: { type: "string" },
|
|
500
|
+
retry: { type: "number" }
|
|
501
|
+
},
|
|
502
|
+
required: ["event", "data"]
|
|
503
|
+
}
|
|
504
|
+
]
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
return { requestBody: requestBody3, parameters: [] };
|
|
510
|
+
}
|
|
511
|
+
const inputStructure = fallbackContractConfig2("defaultInputStructure", def.route?.inputStructure);
|
|
512
|
+
const { paramsSchema, querySchema, headersSchema, bodySchema } = this.inputStructureParser.parse(contract, inputStructure);
|
|
513
|
+
const params = paramsSchema ? this.parametersBuilder.build("path", paramsSchema, {
|
|
514
|
+
required: true
|
|
515
|
+
}) : [];
|
|
516
|
+
const query = querySchema ? this.parametersBuilder.build("query", querySchema) : [];
|
|
517
|
+
const headers = headersSchema ? this.parametersBuilder.build("header", headersSchema) : [];
|
|
518
|
+
const parameters2 = [...params, ...query, ...headers];
|
|
519
|
+
const requestBody2 = bodySchema !== void 0 ? {
|
|
520
|
+
required: this.schemaUtils.isUndefinableSchema(bodySchema),
|
|
521
|
+
content: this.contentBuilder.build(bodySchema)
|
|
522
|
+
} : void 0;
|
|
523
|
+
return { parameters: parameters2, requestBody: requestBody2 };
|
|
524
|
+
})();
|
|
525
|
+
const { responses } = (() => {
|
|
526
|
+
const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(def.outputSchema);
|
|
527
|
+
if (eventIteratorSchemaDetails) {
|
|
528
|
+
const responses3 = {};
|
|
529
|
+
responses3[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
|
|
530
|
+
description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
|
|
531
|
+
content: {
|
|
532
|
+
"text/event-stream": {
|
|
533
|
+
schema: {
|
|
534
|
+
oneOf: [
|
|
535
|
+
{
|
|
536
|
+
type: "object",
|
|
537
|
+
properties: {
|
|
538
|
+
event: { type: "string", const: "message" },
|
|
539
|
+
data: this.schemaConverter.convert(eventIteratorSchemaDetails.yields, { strategy: "input" }),
|
|
540
|
+
id: { type: "string" },
|
|
541
|
+
retry: { type: "number" }
|
|
542
|
+
},
|
|
543
|
+
required: ["event", "data"]
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
type: "object",
|
|
547
|
+
properties: {
|
|
548
|
+
event: { type: "string", const: "done" },
|
|
549
|
+
data: this.schemaConverter.convert(eventIteratorSchemaDetails.returns, { strategy: "input" }),
|
|
550
|
+
id: { type: "string" },
|
|
551
|
+
retry: { type: "number" }
|
|
552
|
+
},
|
|
553
|
+
required: ["event", "data"]
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
type: "object",
|
|
557
|
+
properties: {
|
|
558
|
+
event: { type: "string", const: "error" },
|
|
559
|
+
data: {},
|
|
560
|
+
id: { type: "string" },
|
|
561
|
+
retry: { type: "number" }
|
|
562
|
+
},
|
|
563
|
+
required: ["event", "data"]
|
|
564
|
+
}
|
|
565
|
+
]
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
return { responses: responses3 };
|
|
571
|
+
}
|
|
572
|
+
const outputStructure = fallbackContractConfig2("defaultOutputStructure", def.route?.outputStructure);
|
|
573
|
+
const { headersSchema: resHeadersSchema, bodySchema: resBodySchema } = this.outputStructureParser.parse(contract, outputStructure);
|
|
574
|
+
const responses2 = {};
|
|
575
|
+
responses2[fallbackContractConfig2("defaultSuccessStatus", def.route?.successStatus)] = {
|
|
576
|
+
description: fallbackContractConfig2("defaultSuccessDescription", def.route?.successDescription),
|
|
577
|
+
content: resBodySchema !== void 0 ? this.contentBuilder.build(resBodySchema) : void 0,
|
|
578
|
+
headers: resHeadersSchema !== void 0 ? this.parametersBuilder.buildHeadersObject(resHeadersSchema) : void 0
|
|
579
|
+
};
|
|
580
|
+
return { responses: responses2 };
|
|
581
|
+
})();
|
|
582
|
+
const errors = group(Object.entries(def.errorMap ?? {}).filter(([_, config]) => config).map(([code, config]) => ({
|
|
583
|
+
...config,
|
|
584
|
+
code,
|
|
585
|
+
status: fallbackORPCErrorStatus(code, config?.status)
|
|
586
|
+
})), (error) => error.status);
|
|
587
|
+
for (const status in errors) {
|
|
588
|
+
const configs = errors[status];
|
|
589
|
+
if (!configs || configs.length === 0) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const schemas = configs.map(({ data, code, message }) => {
|
|
593
|
+
const json = {
|
|
594
|
+
type: "object",
|
|
595
|
+
properties: {
|
|
596
|
+
defined: { const: true },
|
|
597
|
+
code: { const: code },
|
|
598
|
+
status: { const: Number(status) },
|
|
599
|
+
message: { type: "string", default: message },
|
|
600
|
+
data: {}
|
|
601
|
+
},
|
|
602
|
+
required: ["defined", "code", "status", "message"]
|
|
603
|
+
};
|
|
604
|
+
if (data) {
|
|
605
|
+
const dataJson = this.schemaConverter.convert(data, { strategy: "output" });
|
|
606
|
+
json.properties.data = dataJson;
|
|
607
|
+
if (!this.schemaUtils.isUndefinableSchema(dataJson)) {
|
|
608
|
+
json.required.push("data");
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return json;
|
|
612
|
+
});
|
|
613
|
+
if (this.strictErrorResponses) {
|
|
614
|
+
schemas.push({
|
|
615
|
+
type: "object",
|
|
616
|
+
properties: {
|
|
617
|
+
defined: { const: false },
|
|
618
|
+
code: { type: "string" },
|
|
619
|
+
status: { type: "number" },
|
|
620
|
+
message: { type: "string" },
|
|
621
|
+
data: {}
|
|
622
|
+
},
|
|
623
|
+
required: ["defined", "code", "status", "message"]
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
const contentSchema = schemas.length === 1 ? schemas[0] : {
|
|
627
|
+
oneOf: schemas
|
|
628
|
+
};
|
|
629
|
+
responses[status] = {
|
|
630
|
+
description: status,
|
|
631
|
+
content: this.contentBuilder.build(contentSchema)
|
|
632
|
+
};
|
|
266
633
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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;
|
|
288
|
-
}
|
|
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;
|
|
634
|
+
if (this.considerMissingTagDefinitionAsError && def.route?.tags) {
|
|
635
|
+
const missingTag = def.route?.tags.find((tag) => !rootTags.includes(tag));
|
|
636
|
+
if (missingTag !== void 0) {
|
|
637
|
+
throw new OpenAPIError(
|
|
638
|
+
`Tag "${missingTag}" is missing definition. Please define it in OpenAPI root tags object`
|
|
639
|
+
);
|
|
640
|
+
}
|
|
297
641
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
642
|
+
const operation = {
|
|
643
|
+
summary: def.route?.summary,
|
|
644
|
+
description: def.route?.description,
|
|
645
|
+
deprecated: def.route?.deprecated,
|
|
646
|
+
tags: def.route?.tags ? [...def.route.tags] : void 0,
|
|
647
|
+
operationId: path.join("."),
|
|
648
|
+
parameters: parameters.length ? parameters : void 0,
|
|
649
|
+
requestBody,
|
|
650
|
+
responses
|
|
303
651
|
};
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
652
|
+
const extendedOperation = extendOperation(operation, contract);
|
|
653
|
+
builder.addPath(httpPath, {
|
|
654
|
+
[method.toLocaleLowerCase()]: extendedOperation
|
|
655
|
+
});
|
|
656
|
+
} catch (e) {
|
|
657
|
+
if (e instanceof OpenAPIError) {
|
|
658
|
+
const error = new OpenAPIError(`
|
|
659
|
+
Generate OpenAPI Error: ${e.message}
|
|
660
|
+
Happened at path: ${path.join(".")}
|
|
661
|
+
`, { cause: e });
|
|
662
|
+
if (this.errorHandlerStrategy === "throw") {
|
|
663
|
+
throw error;
|
|
664
|
+
}
|
|
665
|
+
if (this.errorHandlerStrategy === "log") {
|
|
666
|
+
console.error(error);
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
throw e;
|
|
319
670
|
}
|
|
320
671
|
}
|
|
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
|
-
200: successResponse
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
builder.addPath(httpPath, {
|
|
334
|
-
[method.toLocaleLowerCase()]: operation
|
|
335
|
-
});
|
|
336
672
|
});
|
|
337
673
|
return this.jsonSerializer.serialize(builder.getSpec());
|
|
338
674
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
// src/index.ts
|
|
678
|
+
var oo = {
|
|
679
|
+
spec: setOperationExtender
|
|
345
680
|
};
|
|
346
681
|
export {
|
|
347
682
|
CompositeSchemaConverter,
|
|
@@ -355,8 +690,10 @@ export {
|
|
|
355
690
|
OpenAPIPathParser,
|
|
356
691
|
OpenApiBuilder,
|
|
357
692
|
SchemaUtils,
|
|
358
|
-
|
|
359
|
-
|
|
693
|
+
extendOperation,
|
|
694
|
+
getOperationExtender,
|
|
695
|
+
oo,
|
|
696
|
+
setOperationExtender,
|
|
360
697
|
standardizeHTTPPath
|
|
361
698
|
};
|
|
362
699
|
//# sourceMappingURL=index.js.map
|