@elysiajs/openapi 1.4.10 → 1.4.12
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/README.md +1 -1
- package/bun.lock +79 -144
- package/dist/cjs/gen/index.js +1021 -344
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1308 -392
- package/dist/cjs/openapi.d.ts +1 -1
- package/dist/cjs/openapi.js +213 -9
- package/dist/cjs/scalar/index.js +9 -2
- package/dist/cjs/types.d.ts +8 -0
- package/dist/gen/index.mjs +1021 -344
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1308 -392
- package/dist/openapi.d.ts +1 -1
- package/dist/openapi.mjs +213 -9
- package/dist/scalar/index.d.ts +1 -1
- package/dist/scalar/index.mjs +9 -2
- package/dist/types.d.ts +8 -0
- package/package.json +3 -3
package/dist/cjs/openapi.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ 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
14
|
export declare const enumToOpenApi: <T extends TAnySchema | OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined>(_schema: T) => T;
|
|
15
15
|
/**
|
|
16
16
|
* Converts Elysia routes to OpenAPI 3.0.3 paths schema
|
package/dist/cjs/openapi.js
CHANGED
|
@@ -32,11 +32,7 @@ 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);
|
|
@@ -101,6 +97,212 @@ openapi({
|
|
|
101
97
|
})`
|
|
102
98
|
};
|
|
103
99
|
var warned = {};
|
|
100
|
+
var mergeObjectSchemas = (schemas) => {
|
|
101
|
+
if (schemas.length === 0)
|
|
102
|
+
return {
|
|
103
|
+
schema: void 0,
|
|
104
|
+
notObjects: []
|
|
105
|
+
};
|
|
106
|
+
if (schemas.length === 1)
|
|
107
|
+
return schemas[0].type === "object" ? {
|
|
108
|
+
schema: schemas[0],
|
|
109
|
+
notObjects: []
|
|
110
|
+
} : {
|
|
111
|
+
schema: void 0,
|
|
112
|
+
notObjects: schemas
|
|
113
|
+
};
|
|
114
|
+
let newSchema;
|
|
115
|
+
const notObjects = [];
|
|
116
|
+
let additionalPropertiesIsTrue = false;
|
|
117
|
+
let additionalPropertiesIsFalse = false;
|
|
118
|
+
for (const schema of schemas) {
|
|
119
|
+
if (!schema) continue;
|
|
120
|
+
if (schema.type !== "object") {
|
|
121
|
+
notObjects.push(schema);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if ("additionalProperties" in schema) {
|
|
125
|
+
if (schema.additionalProperties === true)
|
|
126
|
+
additionalPropertiesIsTrue = true;
|
|
127
|
+
else if (schema.additionalProperties === false)
|
|
128
|
+
additionalPropertiesIsFalse = true;
|
|
129
|
+
}
|
|
130
|
+
if (!newSchema) {
|
|
131
|
+
newSchema = schema;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
newSchema = {
|
|
135
|
+
...newSchema,
|
|
136
|
+
...schema,
|
|
137
|
+
properties: {
|
|
138
|
+
...newSchema.properties,
|
|
139
|
+
...schema.properties
|
|
140
|
+
},
|
|
141
|
+
required: [
|
|
142
|
+
...newSchema?.required ?? [],
|
|
143
|
+
...schema.required ?? []
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (newSchema) {
|
|
148
|
+
if (newSchema.required)
|
|
149
|
+
newSchema.required = [...new Set(newSchema.required)];
|
|
150
|
+
if (additionalPropertiesIsFalse) newSchema.additionalProperties = false;
|
|
151
|
+
else if (additionalPropertiesIsTrue)
|
|
152
|
+
newSchema.additionalProperties = true;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
schema: newSchema,
|
|
156
|
+
notObjects
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
var isTSchema = (value) => {
|
|
160
|
+
if (!value || typeof value !== "object") return false;
|
|
161
|
+
if (Kind in value) return true;
|
|
162
|
+
const keys = Object.keys(value);
|
|
163
|
+
if (keys.length > 0 && keys.every((k) => !isNaN(Number(k)))) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
};
|
|
168
|
+
var normalizeSchemaReference = (schema) => {
|
|
169
|
+
if (!schema) return void 0;
|
|
170
|
+
if (typeof schema !== "string") return schema;
|
|
171
|
+
return import_elysia.t.Ref(schema);
|
|
172
|
+
};
|
|
173
|
+
var mergeSchemaProperty = (existing, incoming, vendors) => {
|
|
174
|
+
if (!existing) return incoming;
|
|
175
|
+
if (!incoming) return existing;
|
|
176
|
+
const existingSchema = normalizeSchemaReference(existing);
|
|
177
|
+
let incomingSchema = normalizeSchemaReference(incoming);
|
|
178
|
+
if (!existingSchema) return incoming;
|
|
179
|
+
if (!incomingSchema) return existing;
|
|
180
|
+
if (!isTSchema(incomingSchema) && incomingSchema["~standard"])
|
|
181
|
+
incomingSchema = unwrapSchema(incomingSchema, vendors);
|
|
182
|
+
if (!incomingSchema) return existing;
|
|
183
|
+
const { schema: mergedSchema, notObjects } = mergeObjectSchemas([
|
|
184
|
+
existingSchema,
|
|
185
|
+
incomingSchema
|
|
186
|
+
]);
|
|
187
|
+
if (notObjects.length > 0) {
|
|
188
|
+
if (mergedSchema) return import_elysia.t.Intersect([mergedSchema, ...notObjects]);
|
|
189
|
+
return notObjects.length === 1 ? notObjects[0] : import_elysia.t.Intersect(notObjects);
|
|
190
|
+
}
|
|
191
|
+
return mergedSchema;
|
|
192
|
+
};
|
|
193
|
+
var unwrapResponseSchema = (schema, vendors) => typeof schema === "string" ? normalizeSchemaReference(schema) : !schema ? void 0 : isTSchema(schema) ? schema : (
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
schema["~standard"] ? unwrapSchema(schema, vendors, "output") : Object.fromEntries(
|
|
196
|
+
Object.entries(schema).map(([status, schema2]) => [
|
|
197
|
+
status,
|
|
198
|
+
typeof schema2 === "string" ? normalizeSchemaReference(schema2) : isTSchema(schema2) ? schema2 : unwrapSchema(schema2, vendors, "output")
|
|
199
|
+
])
|
|
200
|
+
)
|
|
201
|
+
);
|
|
202
|
+
var mergeResponseSchema = (_existing, _incoming, vendors) => {
|
|
203
|
+
if (!_existing) return _incoming;
|
|
204
|
+
if (!_incoming) return _existing;
|
|
205
|
+
let existing = unwrapResponseSchema(_existing, vendors);
|
|
206
|
+
let incoming = unwrapResponseSchema(_incoming, vendors);
|
|
207
|
+
if (!existing && !incoming) return void 0;
|
|
208
|
+
if (incoming && !existing) return incoming;
|
|
209
|
+
if (existing && !incoming) return existing;
|
|
210
|
+
if (isTSchema(existing) || existing?.["~standard"])
|
|
211
|
+
existing = {
|
|
212
|
+
200: existing
|
|
213
|
+
};
|
|
214
|
+
if (isTSchema(incoming) || incoming?.["~standard"])
|
|
215
|
+
incoming = {
|
|
216
|
+
200: incoming
|
|
217
|
+
};
|
|
218
|
+
const schema = {
|
|
219
|
+
...incoming
|
|
220
|
+
};
|
|
221
|
+
for (const status of Object.keys(existing ?? {})) {
|
|
222
|
+
const existingSchema = existing[status];
|
|
223
|
+
const incomingSchema = incoming[status];
|
|
224
|
+
if (existingSchema && incomingSchema)
|
|
225
|
+
schema[status] = mergeSchemaProperty(
|
|
226
|
+
existingSchema,
|
|
227
|
+
incomingSchema,
|
|
228
|
+
vendors
|
|
229
|
+
);
|
|
230
|
+
else if (existingSchema) schema[status] = existingSchema;
|
|
231
|
+
else if (incomingSchema) schema[status] = incomingSchema;
|
|
232
|
+
}
|
|
233
|
+
return schema;
|
|
234
|
+
};
|
|
235
|
+
var mergeStandaloneValidators = (hooks, vendors) => {
|
|
236
|
+
const merged = { ...hooks };
|
|
237
|
+
if (!hooks.standaloneValidator?.length) return merged;
|
|
238
|
+
for (const validator of hooks.standaloneValidator) {
|
|
239
|
+
if (validator.body)
|
|
240
|
+
merged.body = mergeSchemaProperty(
|
|
241
|
+
merged.body,
|
|
242
|
+
validator.body,
|
|
243
|
+
vendors
|
|
244
|
+
);
|
|
245
|
+
if (validator.headers)
|
|
246
|
+
merged.headers = mergeSchemaProperty(
|
|
247
|
+
merged.headers,
|
|
248
|
+
validator.headers,
|
|
249
|
+
vendors
|
|
250
|
+
);
|
|
251
|
+
if (validator.query)
|
|
252
|
+
merged.query = mergeSchemaProperty(
|
|
253
|
+
merged.query,
|
|
254
|
+
validator.query,
|
|
255
|
+
vendors
|
|
256
|
+
);
|
|
257
|
+
if (validator.params)
|
|
258
|
+
merged.params = mergeSchemaProperty(
|
|
259
|
+
merged.params,
|
|
260
|
+
validator.params,
|
|
261
|
+
vendors
|
|
262
|
+
);
|
|
263
|
+
if (validator.cookie)
|
|
264
|
+
merged.cookie = mergeSchemaProperty(
|
|
265
|
+
merged.cookie,
|
|
266
|
+
validator.cookie,
|
|
267
|
+
vendors
|
|
268
|
+
);
|
|
269
|
+
if (validator.response)
|
|
270
|
+
merged.response = mergeResponseSchema(
|
|
271
|
+
merged.response,
|
|
272
|
+
validator.response,
|
|
273
|
+
vendors
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
if (typeof merged.body === "string")
|
|
277
|
+
merged.body = normalizeSchemaReference(merged.body);
|
|
278
|
+
if (typeof merged.headers === "string")
|
|
279
|
+
merged.headers = normalizeSchemaReference(merged.headers);
|
|
280
|
+
if (typeof merged.query === "string")
|
|
281
|
+
merged.query = normalizeSchemaReference(merged.query);
|
|
282
|
+
if (typeof merged.params === "string")
|
|
283
|
+
merged.params = normalizeSchemaReference(merged.params);
|
|
284
|
+
if (typeof merged.cookie === "string")
|
|
285
|
+
merged.cookie = normalizeSchemaReference(merged.cookie);
|
|
286
|
+
if (merged.response && typeof merged.response !== "string") {
|
|
287
|
+
const response = merged.response;
|
|
288
|
+
if ("type" in response || "$ref" in response) {
|
|
289
|
+
if (typeof response === "string")
|
|
290
|
+
merged.response = normalizeSchemaReference(response);
|
|
291
|
+
} else {
|
|
292
|
+
for (const [status, schema] of Object.entries(response))
|
|
293
|
+
if (typeof schema === "string")
|
|
294
|
+
response[status] = normalizeSchemaReference(schema);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return merged;
|
|
298
|
+
};
|
|
299
|
+
var flattenRoutes = (routes, vendors) => routes.map((route) => {
|
|
300
|
+
if (!route.hooks?.standaloneValidator?.length) return route;
|
|
301
|
+
return {
|
|
302
|
+
...route,
|
|
303
|
+
hooks: mergeStandaloneValidators(route.hooks, vendors)
|
|
304
|
+
};
|
|
305
|
+
});
|
|
104
306
|
var unwrapReference = (schema, definitions) => {
|
|
105
307
|
const ref = schema?.$ref;
|
|
106
308
|
if (!ref) return schema;
|
|
@@ -108,13 +310,15 @@ var unwrapReference = (schema, definitions) => {
|
|
|
108
310
|
if (ref && definitions[name]) schema = definitions[name];
|
|
109
311
|
return enumToOpenApi(schema);
|
|
110
312
|
};
|
|
111
|
-
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
313
|
+
var unwrapSchema = (schema, mapJsonSchema, io = "input") => {
|
|
112
314
|
if (!schema) return;
|
|
113
315
|
if (typeof schema === "string") schema = toRef(schema);
|
|
114
316
|
if (Kind in schema) return enumToOpenApi(schema);
|
|
115
317
|
if (Kind in schema || !schema?.["~standard"]) return;
|
|
116
318
|
const vendor = schema["~standard"].vendor;
|
|
117
319
|
try {
|
|
320
|
+
if (schema["~standard"]?.jsonSchema?.[io])
|
|
321
|
+
return schema["~standard"]?.jsonSchema?.[io]?.();
|
|
118
322
|
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
119
323
|
return enumToOpenApi(mapJsonSchema[vendor](schema));
|
|
120
324
|
switch (vendor) {
|
|
@@ -209,7 +413,6 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
209
413
|
const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
|
|
210
414
|
const paths = /* @__PURE__ */ Object.create(null);
|
|
211
415
|
const definitions = app.getGlobalDefinitions?.().type;
|
|
212
|
-
const routes = app.getGlobalRoutes();
|
|
213
416
|
if (references) {
|
|
214
417
|
if (!Array.isArray(references)) references = [references];
|
|
215
418
|
for (let i = 0; i < references.length; i++) {
|
|
@@ -217,6 +420,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
217
420
|
if (typeof reference === "function") references[i] = reference();
|
|
218
421
|
}
|
|
219
422
|
}
|
|
423
|
+
const routes = flattenRoutes(app.getGlobalRoutes(), vendors);
|
|
220
424
|
for (const route of routes) {
|
|
221
425
|
if (route.hooks?.detail?.hide) continue;
|
|
222
426
|
const method = route.method.toLowerCase();
|
|
@@ -406,7 +610,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
406
610
|
if (typeof hooks.response === "object" && // TypeBox
|
|
407
611
|
!hooks.response.type && !hooks.response.$ref && !hooks.response["~standard"]) {
|
|
408
612
|
for (let [status, schema] of Object.entries(hooks.response)) {
|
|
409
|
-
const response = unwrapSchema(schema, vendors);
|
|
613
|
+
const response = unwrapSchema(schema, vendors, "output");
|
|
410
614
|
if (!response) continue;
|
|
411
615
|
const { type, description, $ref, ..._options } = unwrapReference(response, definitions);
|
|
412
616
|
operation.responses[status] = {
|
|
@@ -423,7 +627,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
423
627
|
};
|
|
424
628
|
}
|
|
425
629
|
} else {
|
|
426
|
-
const response = unwrapSchema(hooks.response, vendors);
|
|
630
|
+
const response = unwrapSchema(hooks.response, vendors, "output");
|
|
427
631
|
if (response) {
|
|
428
632
|
const {
|
|
429
633
|
type: _type,
|
package/dist/cjs/scalar/index.js
CHANGED
|
@@ -143,7 +143,7 @@ var elysiaCSS = `.light-mode {
|
|
|
143
143
|
background-image: var(--stripes), var(--rainbow);
|
|
144
144
|
filter: opacity(4%) saturate(200%);
|
|
145
145
|
}`;
|
|
146
|
-
var ScalarRender = (info, config) => `<!doctype html>
|
|
146
|
+
var ScalarRender = (info, config, embedSpec) => `<!doctype html>
|
|
147
147
|
<html>
|
|
148
148
|
<head>
|
|
149
149
|
<title>${info.title}</title>
|
|
@@ -171,7 +171,14 @@ var ScalarRender = (info, config) => `<!doctype html>
|
|
|
171
171
|
<body>
|
|
172
172
|
<script
|
|
173
173
|
id="api-reference"
|
|
174
|
-
data-
|
|
174
|
+
data-configuration='${JSON.stringify(
|
|
175
|
+
Object.assign(
|
|
176
|
+
config,
|
|
177
|
+
{
|
|
178
|
+
content: embedSpec
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
)}'
|
|
175
182
|
>
|
|
176
183
|
</script>
|
|
177
184
|
<script src="${config.cdn}" crossorigin></script>
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -74,6 +74,14 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
|
|
|
74
74
|
* Additional reference for each endpoint
|
|
75
75
|
*/
|
|
76
76
|
references?: AdditionalReferences;
|
|
77
|
+
/**
|
|
78
|
+
* Embed OpenAPI schema to provider body if possible
|
|
79
|
+
*
|
|
80
|
+
* This is highly discouraged, unless you really have to inline OpenAPI schema
|
|
81
|
+
*
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
embedSpec?: boolean;
|
|
77
85
|
/**
|
|
78
86
|
* Mapping function from Standard schema to OpenAPI schema
|
|
79
87
|
*
|