@elysiajs/openapi 1.4.11 → 1.4.13
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/bun.lock +79 -144
- package/dist/cjs/gen/index.js +1021 -344
- package/dist/cjs/index.js +1255 -351
- package/dist/cjs/openapi.d.ts +6 -1
- package/dist/cjs/openapi.js +233 -11
- package/dist/gen/index.mjs +1021 -344
- package/dist/index.mjs +1255 -351
- package/dist/openapi.d.ts +6 -1
- package/dist/openapi.mjs +233 -11
- package/package.json +3 -4
package/dist/cjs/openapi.d.ts
CHANGED
|
@@ -10,7 +10,12 @@ export declare const capitalize: (word: string) => string;
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const getPossiblePath: (path: string) => string[];
|
|
12
12
|
export declare const getLoosePath: (path: string) => string;
|
|
13
|
-
export declare const unwrapSchema: (schema: InputSchema["body"], mapJsonSchema?: MapJsonSchema) => OpenAPIV3.SchemaObject | undefined;
|
|
13
|
+
export declare const unwrapSchema: (schema: InputSchema["body"], mapJsonSchema?: MapJsonSchema, io?: "input" | "output") => OpenAPIV3.SchemaObject | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Convert TypeBox enum-like Union schemas to OpenAPI enum schemas
|
|
16
|
+
*
|
|
17
|
+
* Otherwise, return the schema as is
|
|
18
|
+
*/
|
|
14
19
|
export declare const enumToOpenApi: <T extends TAnySchema | OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined>(_schema: T) => T;
|
|
15
20
|
/**
|
|
16
21
|
* Converts Elysia routes to OpenAPI 3.0.3 paths schema
|
package/dist/cjs/openapi.js
CHANGED
|
@@ -32,15 +32,13 @@ module.exports = __toCommonJS(openapi_exports);
|
|
|
32
32
|
var import_elysia = require("elysia");
|
|
33
33
|
|
|
34
34
|
// node_modules/@sinclair/typebox/build/esm/type/symbols/symbols.mjs
|
|
35
|
-
var
|
|
36
|
-
var ReadonlyKind = Symbol.for("TypeBox.Readonly");
|
|
37
|
-
var OptionalKind = Symbol.for("TypeBox.Optional");
|
|
38
|
-
var Hint = Symbol.for("TypeBox.Hint");
|
|
39
|
-
var Kind = Symbol.for("TypeBox.Kind");
|
|
35
|
+
var Kind = /* @__PURE__ */ Symbol.for("TypeBox.Kind");
|
|
40
36
|
|
|
41
37
|
// src/openapi.ts
|
|
42
38
|
var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
|
|
43
|
-
var toRef = (name) => import_elysia.t.Ref(
|
|
39
|
+
var toRef = (name) => import_elysia.t.Ref(
|
|
40
|
+
name.startsWith("#/") ? name : `#/components/schemas/${name}`
|
|
41
|
+
);
|
|
44
42
|
var toOperationId = (method, paths) => {
|
|
45
43
|
let operationId = method.toLowerCase();
|
|
46
44
|
if (!paths || paths === "/") return operationId + "Index";
|
|
@@ -101,6 +99,219 @@ openapi({
|
|
|
101
99
|
})`
|
|
102
100
|
};
|
|
103
101
|
var warned = {};
|
|
102
|
+
var mergeObjectSchemas = (schemas) => {
|
|
103
|
+
if (schemas.length === 0)
|
|
104
|
+
return {
|
|
105
|
+
schema: void 0,
|
|
106
|
+
notObjects: []
|
|
107
|
+
};
|
|
108
|
+
if (schemas.length === 1)
|
|
109
|
+
return schemas[0].type === "object" ? {
|
|
110
|
+
schema: schemas[0],
|
|
111
|
+
notObjects: []
|
|
112
|
+
} : {
|
|
113
|
+
schema: void 0,
|
|
114
|
+
notObjects: schemas
|
|
115
|
+
};
|
|
116
|
+
let newSchema;
|
|
117
|
+
const notObjects = [];
|
|
118
|
+
let additionalPropertiesIsTrue = false;
|
|
119
|
+
let additionalPropertiesIsFalse = false;
|
|
120
|
+
for (const schema of schemas) {
|
|
121
|
+
if (!schema) continue;
|
|
122
|
+
if (schema.type !== "object") {
|
|
123
|
+
notObjects.push(schema);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if ("additionalProperties" in schema) {
|
|
127
|
+
if (schema.additionalProperties === true)
|
|
128
|
+
additionalPropertiesIsTrue = true;
|
|
129
|
+
else if (schema.additionalProperties === false)
|
|
130
|
+
additionalPropertiesIsFalse = true;
|
|
131
|
+
}
|
|
132
|
+
if (!newSchema) {
|
|
133
|
+
newSchema = schema;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
newSchema = {
|
|
137
|
+
...newSchema,
|
|
138
|
+
...schema,
|
|
139
|
+
properties: {
|
|
140
|
+
...newSchema.properties,
|
|
141
|
+
...schema.properties
|
|
142
|
+
},
|
|
143
|
+
required: [
|
|
144
|
+
...newSchema?.required ?? [],
|
|
145
|
+
...schema.required ?? []
|
|
146
|
+
]
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (newSchema) {
|
|
150
|
+
if (newSchema.required)
|
|
151
|
+
newSchema.required = [...new Set(newSchema.required)];
|
|
152
|
+
if (additionalPropertiesIsFalse) newSchema.additionalProperties = false;
|
|
153
|
+
else if (additionalPropertiesIsTrue)
|
|
154
|
+
newSchema.additionalProperties = true;
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
schema: newSchema,
|
|
158
|
+
notObjects
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
var isTSchema = (value) => {
|
|
162
|
+
if (!value || typeof value !== "object") return false;
|
|
163
|
+
if (Kind in value) return true;
|
|
164
|
+
const keys = Object.keys(value);
|
|
165
|
+
if (keys.length > 0 && keys.every((k) => !isNaN(Number(k)))) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
};
|
|
170
|
+
var normalizeSchemaReference = (schema) => {
|
|
171
|
+
if (!schema) return void 0;
|
|
172
|
+
if (typeof schema !== "string") return schema;
|
|
173
|
+
return toRef(schema);
|
|
174
|
+
};
|
|
175
|
+
var mergeSchemaProperty = (existing, incoming, vendors) => {
|
|
176
|
+
if (!existing) return incoming;
|
|
177
|
+
if (!incoming) return existing;
|
|
178
|
+
let existingSchema = normalizeSchemaReference(existing);
|
|
179
|
+
let incomingSchema = normalizeSchemaReference(incoming);
|
|
180
|
+
if (!existingSchema) return incoming;
|
|
181
|
+
if (!incomingSchema) return existing;
|
|
182
|
+
if (!isTSchema(incomingSchema) && incomingSchema["~standard"])
|
|
183
|
+
incomingSchema = unwrapSchema(incomingSchema, vendors);
|
|
184
|
+
if (!isTSchema(existingSchema) && existingSchema["~standard"])
|
|
185
|
+
existingSchema = unwrapSchema(existingSchema, vendors);
|
|
186
|
+
if (!incomingSchema) return existingSchema;
|
|
187
|
+
if (!existingSchema) return incomingSchema;
|
|
188
|
+
const { schema: mergedSchema, notObjects } = mergeObjectSchemas([
|
|
189
|
+
existingSchema,
|
|
190
|
+
incomingSchema
|
|
191
|
+
]);
|
|
192
|
+
if (notObjects.length > 0) {
|
|
193
|
+
if (mergedSchema) return import_elysia.t.Intersect([mergedSchema, ...notObjects]);
|
|
194
|
+
return notObjects.length === 1 ? notObjects[0] : import_elysia.t.Intersect(notObjects);
|
|
195
|
+
}
|
|
196
|
+
return mergedSchema;
|
|
197
|
+
};
|
|
198
|
+
var unwrapResponseSchema = (schema, vendors) => typeof schema === "string" ? normalizeSchemaReference(schema) : !schema ? void 0 : isTSchema(schema) ? schema : (
|
|
199
|
+
// @ts-ignore
|
|
200
|
+
schema["~standard"] ? unwrapSchema(schema, vendors, "output") : Object.fromEntries(
|
|
201
|
+
Object.entries(schema).map(([status, schema2]) => [
|
|
202
|
+
status,
|
|
203
|
+
typeof schema2 === "string" ? normalizeSchemaReference(schema2) : isTSchema(schema2) ? schema2 : unwrapSchema(
|
|
204
|
+
schema2,
|
|
205
|
+
vendors,
|
|
206
|
+
"output"
|
|
207
|
+
)
|
|
208
|
+
])
|
|
209
|
+
)
|
|
210
|
+
);
|
|
211
|
+
var mergeResponseSchema = (_existing, _incoming, vendors) => {
|
|
212
|
+
if (!_existing) return _incoming;
|
|
213
|
+
if (!_incoming) return _existing;
|
|
214
|
+
let existing = unwrapResponseSchema(_existing, vendors);
|
|
215
|
+
let incoming = unwrapResponseSchema(_incoming, vendors);
|
|
216
|
+
if (!existing && !incoming) return void 0;
|
|
217
|
+
if (incoming && !existing) return incoming;
|
|
218
|
+
if (existing && !incoming) return existing;
|
|
219
|
+
if (isTSchema(existing) || existing?.["~standard"])
|
|
220
|
+
existing = {
|
|
221
|
+
200: existing
|
|
222
|
+
};
|
|
223
|
+
if (isTSchema(incoming) || incoming?.["~standard"])
|
|
224
|
+
incoming = {
|
|
225
|
+
200: incoming
|
|
226
|
+
};
|
|
227
|
+
const schema = {
|
|
228
|
+
...incoming
|
|
229
|
+
};
|
|
230
|
+
for (const status of Object.keys(existing ?? {})) {
|
|
231
|
+
const existingSchema = existing[status];
|
|
232
|
+
const incomingSchema = incoming[status];
|
|
233
|
+
if (existingSchema && incomingSchema)
|
|
234
|
+
schema[status] = mergeSchemaProperty(
|
|
235
|
+
existingSchema,
|
|
236
|
+
incomingSchema,
|
|
237
|
+
vendors
|
|
238
|
+
);
|
|
239
|
+
else if (existingSchema) schema[status] = existingSchema;
|
|
240
|
+
else if (incomingSchema) schema[status] = incomingSchema;
|
|
241
|
+
}
|
|
242
|
+
return schema;
|
|
243
|
+
};
|
|
244
|
+
var mergeStandaloneValidators = (hooks, vendors) => {
|
|
245
|
+
const merged = { ...hooks };
|
|
246
|
+
if (!hooks.standaloneValidator?.length) return merged;
|
|
247
|
+
for (const validator of hooks.standaloneValidator) {
|
|
248
|
+
if (validator.body)
|
|
249
|
+
merged.body = mergeSchemaProperty(
|
|
250
|
+
merged.body,
|
|
251
|
+
validator.body,
|
|
252
|
+
vendors
|
|
253
|
+
);
|
|
254
|
+
if (validator.headers)
|
|
255
|
+
merged.headers = mergeSchemaProperty(
|
|
256
|
+
merged.headers,
|
|
257
|
+
validator.headers,
|
|
258
|
+
vendors
|
|
259
|
+
);
|
|
260
|
+
if (validator.query)
|
|
261
|
+
merged.query = mergeSchemaProperty(
|
|
262
|
+
merged.query,
|
|
263
|
+
validator.query,
|
|
264
|
+
vendors
|
|
265
|
+
);
|
|
266
|
+
if (validator.params)
|
|
267
|
+
merged.params = mergeSchemaProperty(
|
|
268
|
+
merged.params,
|
|
269
|
+
validator.params,
|
|
270
|
+
vendors
|
|
271
|
+
);
|
|
272
|
+
if (validator.cookie)
|
|
273
|
+
merged.cookie = mergeSchemaProperty(
|
|
274
|
+
merged.cookie,
|
|
275
|
+
validator.cookie,
|
|
276
|
+
vendors
|
|
277
|
+
);
|
|
278
|
+
if (validator.response)
|
|
279
|
+
merged.response = mergeResponseSchema(
|
|
280
|
+
merged.response,
|
|
281
|
+
validator.response,
|
|
282
|
+
vendors
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
if (typeof merged.body === "string")
|
|
286
|
+
merged.body = normalizeSchemaReference(merged.body);
|
|
287
|
+
if (typeof merged.headers === "string")
|
|
288
|
+
merged.headers = normalizeSchemaReference(merged.headers);
|
|
289
|
+
if (typeof merged.query === "string")
|
|
290
|
+
merged.query = normalizeSchemaReference(merged.query);
|
|
291
|
+
if (typeof merged.params === "string")
|
|
292
|
+
merged.params = normalizeSchemaReference(merged.params);
|
|
293
|
+
if (typeof merged.cookie === "string")
|
|
294
|
+
merged.cookie = normalizeSchemaReference(merged.cookie);
|
|
295
|
+
if (merged.response && typeof merged.response !== "string") {
|
|
296
|
+
const response = merged.response;
|
|
297
|
+
if ("type" in response || "$ref" in response) {
|
|
298
|
+
if (typeof response === "string")
|
|
299
|
+
merged.response = normalizeSchemaReference(response);
|
|
300
|
+
} else {
|
|
301
|
+
for (const [status, schema] of Object.entries(response))
|
|
302
|
+
if (typeof schema === "string")
|
|
303
|
+
response[status] = normalizeSchemaReference(schema);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return merged;
|
|
307
|
+
};
|
|
308
|
+
var flattenRoutes = (routes, vendors) => routes.map((route) => {
|
|
309
|
+
if (!route.hooks?.standaloneValidator?.length) return route;
|
|
310
|
+
return {
|
|
311
|
+
...route,
|
|
312
|
+
hooks: mergeStandaloneValidators(route.hooks, vendors)
|
|
313
|
+
};
|
|
314
|
+
});
|
|
104
315
|
var unwrapReference = (schema, definitions) => {
|
|
105
316
|
const ref = schema?.$ref;
|
|
106
317
|
if (!ref) return schema;
|
|
@@ -108,13 +319,20 @@ var unwrapReference = (schema, definitions) => {
|
|
|
108
319
|
if (ref && definitions[name]) schema = definitions[name];
|
|
109
320
|
return enumToOpenApi(schema);
|
|
110
321
|
};
|
|
111
|
-
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
322
|
+
var unwrapSchema = (schema, mapJsonSchema, io = "input") => {
|
|
112
323
|
if (!schema) return;
|
|
113
324
|
if (typeof schema === "string") schema = toRef(schema);
|
|
114
325
|
if (Kind in schema) return enumToOpenApi(schema);
|
|
115
|
-
if (
|
|
326
|
+
if (!schema?.["~standard"] && // @ts-ignore
|
|
327
|
+
(schema.$schema || schema.type || schema.properties || schema.items))
|
|
328
|
+
return schema;
|
|
329
|
+
if (!schema?.["~standard"]) return;
|
|
116
330
|
const vendor = schema["~standard"].vendor;
|
|
117
331
|
try {
|
|
332
|
+
if (schema["~standard"]?.jsonSchema?.[io])
|
|
333
|
+
return schema["~standard"]?.jsonSchema?.[io]?.({
|
|
334
|
+
target: "draft-2020-12"
|
|
335
|
+
});
|
|
118
336
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
119
337
|
return enumToOpenApi(mapJsonSchema[vendor](schema));
|
|
120
338
|
switch (vendor) {
|
|
@@ -209,7 +427,6 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
209
427
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
210
428
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
211
429
|
const definitions = app.getGlobalDefinitions?.().type;
|
|
212
|
-
const routes = app.getGlobalRoutes();
|
|
213
430
|
if (references) {
|
|
214
431
|
if (!Array.isArray(references)) references = [references];
|
|
215
432
|
for (let i = 0; i < references.length; i++) {
|
|
@@ -217,6 +434,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
217
434
|
if (typeof reference === "function") references[i] = reference();
|
|
218
435
|
}
|
|
219
436
|
}
|
|
437
|
+
const routes = flattenRoutes(app.getGlobalRoutes(), vendors);
|
|
220
438
|
for (const route of routes) {
|
|
221
439
|
if (route.hooks?.detail?.hide) continue;
|
|
222
440
|
const method = route.method.toLowerCase();
|
|
@@ -406,7 +624,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
406
624
|
if (typeof hooks.response === "object" && // TypeBox
|
|
407
625
|
!hooks.response.type && !hooks.response.$ref && !hooks.response["~standard"]) {
|
|
408
626
|
for (let [status, schema] of Object.entries(hooks.response)) {
|
|
409
|
-
const response = unwrapSchema(schema, vendors);
|
|
627
|
+
const response = unwrapSchema(schema, vendors, "output");
|
|
410
628
|
if (!response) continue;
|
|
411
629
|
const { type, description, $ref, ..._options } = unwrapReference(response, definitions);
|
|
412
630
|
operation.responses[status] = {
|
|
@@ -423,7 +641,11 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
423
641
|
};
|
|
424
642
|
}
|
|
425
643
|
} else {
|
|
426
|
-
const response = unwrapSchema(
|
|
644
|
+
const response = unwrapSchema(
|
|
645
|
+
hooks.response,
|
|
646
|
+
vendors,
|
|
647
|
+
"output"
|
|
648
|
+
);
|
|
427
649
|
if (response) {
|
|
428
650
|
const {
|
|
429
651
|
type: _type,
|