@elysiajs/openapi 1.4.8 → 1.4.10
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/cjs/gen/index.js +94 -61
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +8976 -425
- package/dist/cjs/openapi.d.ts +2 -1
- package/dist/cjs/openapi.js +113 -73
- package/dist/gen/index.d.ts +6 -4
- package/dist/gen/index.mjs +84 -62
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +8970 -414
- package/dist/openapi.d.ts +2 -1
- package/dist/openapi.mjs +112 -73
- package/package.json +1 -1
package/dist/cjs/openapi.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AnyElysia, type TSchema, type InputSchema } from 'elysia';
|
|
2
2
|
import type { OpenAPIV3 } from 'openapi-types';
|
|
3
|
-
import { type TProperties } from '@sinclair/typebox';
|
|
3
|
+
import { TAnySchema, type TProperties } from '@sinclair/typebox';
|
|
4
4
|
import type { AdditionalReferences, ElysiaOpenAPIConfig, MapJsonSchema } from './types';
|
|
5
5
|
export declare const capitalize: (word: string) => string;
|
|
6
6
|
/**
|
|
@@ -11,6 +11,7 @@ export declare const capitalize: (word: string) => string;
|
|
|
11
11
|
export declare const getPossiblePath: (path: string) => string[];
|
|
12
12
|
export declare const getLoosePath: (path: string) => string;
|
|
13
13
|
export declare const unwrapSchema: (schema: InputSchema["body"], mapJsonSchema?: MapJsonSchema) => OpenAPIV3.SchemaObject | undefined;
|
|
14
|
+
export declare const enumToOpenApi: <T extends TAnySchema | OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined>(_schema: T) => T;
|
|
14
15
|
/**
|
|
15
16
|
* Converts Elysia routes to OpenAPI 3.0.3 paths schema
|
|
16
17
|
* @param routes Array of Elysia route objects
|
package/dist/cjs/openapi.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var openapi_exports = {};
|
|
22
22
|
__export(openapi_exports, {
|
|
23
23
|
capitalize: () => capitalize,
|
|
24
|
+
enumToOpenApi: () => enumToOpenApi,
|
|
24
25
|
getLoosePath: () => getLoosePath,
|
|
25
26
|
getPossiblePath: () => getPossiblePath,
|
|
26
27
|
toOpenAPISchema: () => toOpenAPISchema,
|
|
@@ -105,62 +106,98 @@ var unwrapReference = (schema, definitions) => {
|
|
|
105
106
|
if (!ref) return schema;
|
|
106
107
|
const name = ref.slice(ref.lastIndexOf("/") + 1);
|
|
107
108
|
if (ref && definitions[name]) schema = definitions[name];
|
|
108
|
-
return schema;
|
|
109
|
+
return enumToOpenApi(schema);
|
|
109
110
|
};
|
|
110
111
|
var unwrapSchema = (schema, mapJsonSchema) => {
|
|
111
112
|
if (!schema) return;
|
|
112
113
|
if (typeof schema === "string") schema = toRef(schema);
|
|
113
|
-
if (Kind in schema) return schema;
|
|
114
|
+
if (Kind in schema) return enumToOpenApi(schema);
|
|
114
115
|
if (Kind in schema || !schema?.["~standard"]) return;
|
|
115
116
|
const vendor = schema["~standard"].vendor;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
123
|
-
);
|
|
124
|
-
if ("_zod" in schema) {
|
|
125
|
-
warned.zod4 = true;
|
|
117
|
+
try {
|
|
118
|
+
if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
|
|
119
|
+
return enumToOpenApi(mapJsonSchema[vendor](schema));
|
|
120
|
+
switch (vendor) {
|
|
121
|
+
case "zod":
|
|
122
|
+
if (warned.zod4 || warned.zod3) break;
|
|
126
123
|
console.warn(
|
|
127
|
-
"
|
|
124
|
+
"[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
|
|
128
125
|
);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
if ("_zod" in schema) {
|
|
127
|
+
warned.zod4 = true;
|
|
128
|
+
console.warn(
|
|
129
|
+
"For Zod v4, please provide z.toJSONSchema as follows:\n"
|
|
130
|
+
);
|
|
131
|
+
console.warn(warnings.zod4);
|
|
132
|
+
} else {
|
|
133
|
+
warned.zod3 = true;
|
|
134
|
+
console.warn(
|
|
135
|
+
"For Zod v3, please install zod-to-json-schema package and use it like this:\n"
|
|
136
|
+
);
|
|
137
|
+
console.warn(warnings.zod3);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "valibot":
|
|
141
|
+
if (warned.valibot) break;
|
|
142
|
+
warned.valibot = true;
|
|
132
143
|
console.warn(
|
|
133
|
-
"
|
|
144
|
+
"[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
|
|
134
145
|
);
|
|
135
|
-
console.warn(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
console.warn(
|
|
147
|
+
"Please install @valibot/to-json-schema package and use it like this:\n"
|
|
148
|
+
);
|
|
149
|
+
console.warn(warnings.valibot);
|
|
150
|
+
break;
|
|
151
|
+
case "effect":
|
|
152
|
+
if (warned.effect) break;
|
|
153
|
+
warned.effect = true;
|
|
154
|
+
console.warn(
|
|
155
|
+
"[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
|
|
156
|
+
);
|
|
157
|
+
console.warn(
|
|
158
|
+
"please provide JSONSchema from 'effect' package as follows:\n"
|
|
159
|
+
);
|
|
160
|
+
console.warn(warnings.effect);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
if (vendor === "arktype")
|
|
164
|
+
return enumToOpenApi(schema?.toJsonSchema?.());
|
|
165
|
+
return enumToOpenApi(
|
|
166
|
+
// @ts-ignore
|
|
167
|
+
schema.toJSONSchema?.() ?? schema?.toJsonSchema?.()
|
|
168
|
+
);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.warn(error);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
var enumToOpenApi = (_schema) => {
|
|
174
|
+
if (!_schema || typeof _schema !== "object") return _schema;
|
|
175
|
+
if (Kind in _schema) {
|
|
176
|
+
const schema2 = _schema;
|
|
177
|
+
if (schema2[Kind] === "Union" && schema2.anyOf && Array.isArray(schema2.anyOf) && schema2.anyOf.length > 0 && schema2.anyOf.every(
|
|
178
|
+
(item) => item && typeof item === "object" && item.const !== void 0
|
|
179
|
+
))
|
|
180
|
+
return {
|
|
181
|
+
type: "string",
|
|
182
|
+
enum: schema2.anyOf.map((item) => item.const)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const schema = _schema;
|
|
186
|
+
if (schema.type === "object" && schema.properties) {
|
|
187
|
+
const properties = {};
|
|
188
|
+
for (const [key, value] of Object.entries(schema.properties))
|
|
189
|
+
properties[key] = enumToOpenApi(value);
|
|
190
|
+
return {
|
|
191
|
+
...schema,
|
|
192
|
+
properties
|
|
193
|
+
};
|
|
160
194
|
}
|
|
161
|
-
if (
|
|
162
|
-
return
|
|
163
|
-
|
|
195
|
+
if (schema.type === "array" && schema.items)
|
|
196
|
+
return {
|
|
197
|
+
...schema,
|
|
198
|
+
items: enumToOpenApi(schema.items)
|
|
199
|
+
};
|
|
200
|
+
return schema;
|
|
164
201
|
};
|
|
165
202
|
function toOpenAPISchema(app, exclude, references, vendors) {
|
|
166
203
|
let {
|
|
@@ -233,16 +270,24 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
233
270
|
definitions
|
|
234
271
|
);
|
|
235
272
|
if (params && params.type === "object" && params.properties)
|
|
236
|
-
for (const [
|
|
237
|
-
params.properties
|
|
238
|
-
))
|
|
273
|
+
for (const [name, schema] of Object.entries(params.properties))
|
|
239
274
|
parameters.push({
|
|
240
|
-
name
|
|
275
|
+
name,
|
|
241
276
|
in: "path",
|
|
242
277
|
required: true,
|
|
243
278
|
// Path parameters are always required
|
|
244
|
-
schema
|
|
279
|
+
schema
|
|
245
280
|
});
|
|
281
|
+
} else {
|
|
282
|
+
for (const match of route.path.matchAll(/:([^/]+)/g)) {
|
|
283
|
+
const name = match[1].replace("?", "");
|
|
284
|
+
parameters.push({
|
|
285
|
+
name,
|
|
286
|
+
in: "path",
|
|
287
|
+
required: true,
|
|
288
|
+
schema: { type: "string" }
|
|
289
|
+
});
|
|
290
|
+
}
|
|
246
291
|
}
|
|
247
292
|
if (hooks.query) {
|
|
248
293
|
const query = unwrapReference(
|
|
@@ -251,32 +296,28 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
251
296
|
);
|
|
252
297
|
if (query && query.type === "object" && query.properties) {
|
|
253
298
|
const required = query.required || [];
|
|
254
|
-
for (const [
|
|
255
|
-
query.properties
|
|
256
|
-
))
|
|
299
|
+
for (const [name, schema] of Object.entries(query.properties))
|
|
257
300
|
parameters.push({
|
|
258
|
-
name
|
|
301
|
+
name,
|
|
259
302
|
in: "query",
|
|
260
|
-
required: required.includes(
|
|
261
|
-
schema
|
|
303
|
+
required: required.includes(name),
|
|
304
|
+
schema
|
|
262
305
|
});
|
|
263
306
|
}
|
|
264
307
|
}
|
|
265
308
|
if (hooks.headers) {
|
|
266
309
|
const headers = unwrapReference(
|
|
267
|
-
unwrapSchema(hooks.
|
|
310
|
+
unwrapSchema(hooks.headers, vendors),
|
|
268
311
|
definitions
|
|
269
312
|
);
|
|
270
313
|
if (headers && headers.type === "object" && headers.properties) {
|
|
271
314
|
const required = headers.required || [];
|
|
272
|
-
for (const [
|
|
273
|
-
headers.properties
|
|
274
|
-
))
|
|
315
|
+
for (const [name, schema] of Object.entries(headers.properties))
|
|
275
316
|
parameters.push({
|
|
276
|
-
name
|
|
317
|
+
name,
|
|
277
318
|
in: "header",
|
|
278
|
-
required: required.includes(
|
|
279
|
-
schema
|
|
319
|
+
required: required.includes(name),
|
|
320
|
+
schema
|
|
280
321
|
});
|
|
281
322
|
}
|
|
282
323
|
}
|
|
@@ -287,14 +328,12 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
287
328
|
);
|
|
288
329
|
if (cookie && cookie.type === "object" && cookie.properties) {
|
|
289
330
|
const required = cookie.required || [];
|
|
290
|
-
for (const [
|
|
291
|
-
cookie.properties
|
|
292
|
-
))
|
|
331
|
+
for (const [name, schema] of Object.entries(cookie.properties))
|
|
293
332
|
parameters.push({
|
|
294
|
-
name
|
|
333
|
+
name,
|
|
295
334
|
in: "cookie",
|
|
296
|
-
required: required.includes(
|
|
297
|
-
schema
|
|
335
|
+
required: required.includes(name),
|
|
336
|
+
schema
|
|
298
337
|
});
|
|
299
338
|
}
|
|
300
339
|
}
|
|
@@ -342,6 +381,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
342
381
|
} else {
|
|
343
382
|
operation.requestBody = {
|
|
344
383
|
description,
|
|
384
|
+
required: true,
|
|
345
385
|
content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
|
|
346
386
|
"text/plain": {
|
|
347
387
|
schema: body
|
|
@@ -356,8 +396,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
356
396
|
"multipart/form-data": {
|
|
357
397
|
schema: body
|
|
358
398
|
}
|
|
359
|
-
}
|
|
360
|
-
required: true
|
|
399
|
+
}
|
|
361
400
|
};
|
|
362
401
|
}
|
|
363
402
|
}
|
|
@@ -369,7 +408,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
369
408
|
for (let [status, schema] of Object.entries(hooks.response)) {
|
|
370
409
|
const response = unwrapSchema(schema, vendors);
|
|
371
410
|
if (!response) continue;
|
|
372
|
-
const { type, description, $ref, ...
|
|
411
|
+
const { type, description, $ref, ..._options } = unwrapReference(response, definitions);
|
|
373
412
|
operation.responses[status] = {
|
|
374
413
|
description: description ?? `Response for status ${status}`,
|
|
375
414
|
content: type === "void" || type === "null" || type === "undefined" ? { type, description } : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
|
|
@@ -408,7 +447,7 @@ function toOpenAPISchema(app, exclude, references, vendors) {
|
|
|
408
447
|
}
|
|
409
448
|
}
|
|
410
449
|
for (let path of getPossiblePath(route.path)) {
|
|
411
|
-
const operationId = toOperationId(route.method, path);
|
|
450
|
+
const operationId = hooks.detail?.operationId ?? toOperationId(route.method, path);
|
|
412
451
|
path = path.replace(/:([^/]+)/g, "{$1}");
|
|
413
452
|
if (!paths[path]) paths[path] = {};
|
|
414
453
|
const current = paths[path];
|
|
@@ -454,6 +493,7 @@ var withHeaders = (schema, headers) => Object.assign(schema, {
|
|
|
454
493
|
// Annotate the CommonJS export names for ESM import in node:
|
|
455
494
|
0 && (module.exports = {
|
|
456
495
|
capitalize,
|
|
496
|
+
enumToOpenApi,
|
|
457
497
|
getLoosePath,
|
|
458
498
|
getPossiblePath,
|
|
459
499
|
toOpenAPISchema,
|
package/dist/gen/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AdditionalReference } from '../types';
|
|
2
|
-
interface OpenAPIGeneratorOptions {
|
|
1
|
+
import type { AdditionalReference } from '../types';
|
|
2
|
+
export interface OpenAPIGeneratorOptions {
|
|
3
3
|
/**
|
|
4
4
|
* Path to tsconfig.json
|
|
5
5
|
* @default tsconfig.json
|
|
@@ -52,6 +52,8 @@ interface OpenAPIGeneratorOptions {
|
|
|
52
52
|
*/
|
|
53
53
|
silent?: boolean;
|
|
54
54
|
}
|
|
55
|
+
export declare function extractRootObjects(code: string): string[];
|
|
56
|
+
export declare function declarationToJSONSchema(declaration: string): AdditionalReference;
|
|
55
57
|
/**
|
|
56
58
|
* Auto generate OpenAPI schema from Elysia instance
|
|
57
59
|
*
|
|
@@ -64,6 +66,6 @@ export declare const fromTypes: (
|
|
|
64
66
|
* Path to file where Elysia instance is
|
|
65
67
|
*
|
|
66
68
|
* The path must export an Elysia instance
|
|
69
|
+
* or a literal TypeScript declaration
|
|
67
70
|
*/
|
|
68
|
-
targetFilePath
|
|
69
|
-
export {};
|
|
71
|
+
targetFilePath?: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug, compilerOptions, tmpRoot, silent }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
|
package/dist/gen/index.mjs
CHANGED
|
@@ -4,16 +4,6 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
// src/gen/index.ts
|
|
8
|
-
import {
|
|
9
|
-
readFileSync,
|
|
10
|
-
mkdirSync,
|
|
11
|
-
writeFileSync,
|
|
12
|
-
rmSync,
|
|
13
|
-
existsSync,
|
|
14
|
-
readdirSync
|
|
15
|
-
} from "fs";
|
|
16
|
-
|
|
17
7
|
// node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
|
|
18
8
|
function IsObject(value) {
|
|
19
9
|
return value !== null && typeof value === "object";
|
|
@@ -8298,11 +8288,9 @@ function TypeBox(...args) {
|
|
|
8298
8288
|
}
|
|
8299
8289
|
|
|
8300
8290
|
// src/gen/index.ts
|
|
8301
|
-
import { tmpdir } from "os";
|
|
8302
|
-
import { join } from "path";
|
|
8303
|
-
import { spawnSync } from "child_process";
|
|
8304
8291
|
var matchRoute = /: Elysia<(.*)>/gs;
|
|
8305
|
-
var
|
|
8292
|
+
var numberKey = /(\d+):/g;
|
|
8293
|
+
var join = (...parts) => parts.join("/").replace(/\/{1,}/g, "/");
|
|
8306
8294
|
function extractRootObjects(code) {
|
|
8307
8295
|
const results = [];
|
|
8308
8296
|
let i = 0;
|
|
@@ -8312,7 +8300,9 @@ function extractRootObjects(code) {
|
|
|
8312
8300
|
let keyEnd = colonIdx - 1;
|
|
8313
8301
|
while (keyEnd >= 0 && /\s/.test(code[keyEnd])) keyEnd--;
|
|
8314
8302
|
let keyStart = keyEnd;
|
|
8315
|
-
while (keyStart >= 0 &&
|
|
8303
|
+
while (keyStart >= 0 && !/[\s{};,\n]/.test(code[keyStart])) {
|
|
8304
|
+
keyStart--;
|
|
8305
|
+
}
|
|
8316
8306
|
const braceIdx = code.indexOf("{", colonIdx);
|
|
8317
8307
|
if (braceIdx === -1) break;
|
|
8318
8308
|
let depth = 0;
|
|
@@ -8332,41 +8322,89 @@ function extractRootObjects(code) {
|
|
|
8332
8322
|
}
|
|
8333
8323
|
return results;
|
|
8334
8324
|
}
|
|
8335
|
-
|
|
8325
|
+
function declarationToJSONSchema(declaration) {
|
|
8326
|
+
const routes = {};
|
|
8327
|
+
for (const route of extractRootObjects(
|
|
8328
|
+
declaration.replace(numberKey, '"$1":')
|
|
8329
|
+
)) {
|
|
8330
|
+
let schema = TypeBox(route.replaceAll(/readonly/g, ""));
|
|
8331
|
+
if (schema.type !== "object") continue;
|
|
8332
|
+
const paths = [];
|
|
8333
|
+
while (true) {
|
|
8334
|
+
const keys = Object.keys(schema.properties);
|
|
8335
|
+
if (keys.length !== 1) break;
|
|
8336
|
+
paths.push(keys[0]);
|
|
8337
|
+
schema = schema.properties[keys[0]];
|
|
8338
|
+
if (!schema?.properties) break;
|
|
8339
|
+
}
|
|
8340
|
+
const method = paths.pop();
|
|
8341
|
+
if (!method) continue;
|
|
8342
|
+
const path = "/" + paths.join("/");
|
|
8343
|
+
schema = schema.properties;
|
|
8344
|
+
if (schema?.response?.type === "object") {
|
|
8345
|
+
const responseSchema = {};
|
|
8346
|
+
for (const key in schema.response.properties)
|
|
8347
|
+
responseSchema[key] = schema.response.properties[key];
|
|
8348
|
+
schema.response = responseSchema;
|
|
8349
|
+
}
|
|
8350
|
+
if (!routes[path]) routes[path] = {};
|
|
8351
|
+
routes[path][method.toLowerCase()] = schema;
|
|
8352
|
+
}
|
|
8353
|
+
return routes;
|
|
8354
|
+
}
|
|
8355
|
+
var fromTypes = (targetFilePath = "src/index.ts", {
|
|
8336
8356
|
tsconfigPath = "tsconfig.json",
|
|
8337
8357
|
instanceName,
|
|
8338
8358
|
projectRoot = process.cwd(),
|
|
8339
8359
|
overrideOutputPath,
|
|
8340
8360
|
debug = false,
|
|
8341
8361
|
compilerOptions,
|
|
8342
|
-
tmpRoot
|
|
8362
|
+
tmpRoot,
|
|
8343
8363
|
silent = false
|
|
8344
8364
|
} = {}) => () => {
|
|
8365
|
+
if (targetFilePath.trimStart().startsWith("{") && targetFilePath.trimEnd().endsWith("}"))
|
|
8366
|
+
return declarationToJSONSchema(targetFilePath);
|
|
8367
|
+
if (typeof process === "undefined" || typeof process.getBuiltinModule !== "function")
|
|
8368
|
+
throw new Error(
|
|
8369
|
+
"[@elysiajs/openapi/gen] `fromTypes` from file path is only available in Node.js/Bun environment or environments"
|
|
8370
|
+
);
|
|
8371
|
+
const fs = process.getBuiltinModule("fs");
|
|
8372
|
+
if (!fs)
|
|
8373
|
+
throw new Error(
|
|
8374
|
+
"[@elysiajs/openapi/gen] `fromTypes` require `fs` module which is not available in this environment"
|
|
8375
|
+
);
|
|
8345
8376
|
try {
|
|
8346
8377
|
if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
|
|
8347
8378
|
throw new Error("Only .ts files are supported");
|
|
8348
8379
|
if (targetFilePath.startsWith("./"))
|
|
8349
8380
|
targetFilePath = targetFilePath.slice(2);
|
|
8350
8381
|
let src = targetFilePath.startsWith("/") ? targetFilePath : join(projectRoot, targetFilePath);
|
|
8351
|
-
if (!existsSync(src))
|
|
8382
|
+
if (!fs.existsSync(src))
|
|
8352
8383
|
throw new Error(
|
|
8353
8384
|
`Couldn't find "${targetFilePath}" from ${projectRoot}`
|
|
8354
8385
|
);
|
|
8355
8386
|
let targetFile;
|
|
8387
|
+
if (!tmpRoot) {
|
|
8388
|
+
const os = process.getBuiltinModule("os");
|
|
8389
|
+
tmpRoot = join(
|
|
8390
|
+
os && typeof os.tmpdir === "function" ? os.tmpdir() : projectRoot,
|
|
8391
|
+
".ElysiaAutoOpenAPI"
|
|
8392
|
+
);
|
|
8393
|
+
}
|
|
8356
8394
|
if (targetFilePath.endsWith(".d.ts")) targetFile = targetFilePath;
|
|
8357
8395
|
else {
|
|
8358
|
-
if (existsSync(tmpRoot))
|
|
8359
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
8360
|
-
mkdirSync(tmpRoot, { recursive: true });
|
|
8396
|
+
if (fs.existsSync(tmpRoot))
|
|
8397
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
8398
|
+
fs.mkdirSync(tmpRoot, { recursive: true });
|
|
8361
8399
|
const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : join(projectRoot, tsconfigPath);
|
|
8362
|
-
let extendsRef = existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
|
|
8400
|
+
let extendsRef = fs.existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
|
|
8363
8401
|
let distDir = join(tmpRoot, "dist");
|
|
8364
8402
|
if (typeof process !== "undefined" && process.platform === "win32") {
|
|
8365
8403
|
extendsRef = extendsRef.replace(/\\/g, "/");
|
|
8366
8404
|
src = src.replace(/\\/g, "/");
|
|
8367
8405
|
distDir = distDir.replace(/\\/g, "/");
|
|
8368
8406
|
}
|
|
8369
|
-
writeFileSync(
|
|
8407
|
+
fs.writeFileSync(
|
|
8370
8408
|
join(tmpRoot, "tsconfig.json"),
|
|
8371
8409
|
`{
|
|
8372
8410
|
${extendsRef}
|
|
@@ -8384,6 +8422,16 @@ var fromTypes = (targetFilePath, {
|
|
|
8384
8422
|
"include": ["${src}"]
|
|
8385
8423
|
}`
|
|
8386
8424
|
);
|
|
8425
|
+
const child_process = process.getBuiltinModule("child_process");
|
|
8426
|
+
if (!child_process)
|
|
8427
|
+
throw new Error(
|
|
8428
|
+
"[@elysiajs/openapi/gen] `fromTypes` declaration generation require `child_process` module which is not available in this environment"
|
|
8429
|
+
);
|
|
8430
|
+
const { spawnSync } = child_process;
|
|
8431
|
+
if (typeof spawnSync !== "function")
|
|
8432
|
+
throw new Error(
|
|
8433
|
+
"[@elysiajs/openapi/gen] `fromTypes` declaration generation require child_process.spawnSync which is not available in this environment"
|
|
8434
|
+
);
|
|
8387
8435
|
spawnSync(`tsc`, {
|
|
8388
8436
|
shell: true,
|
|
8389
8437
|
cwd: tmpRoot,
|
|
@@ -8396,7 +8444,7 @@ var fromTypes = (targetFilePath, {
|
|
|
8396
8444
|
// remove leading like src or something similar
|
|
8397
8445
|
fileName.slice(fileName.indexOf("/") + 1)
|
|
8398
8446
|
);
|
|
8399
|
-
let existed = existsSync(targetFile);
|
|
8447
|
+
let existed = fs.existsSync(targetFile);
|
|
8400
8448
|
if (!existed && !overrideOutputPath) {
|
|
8401
8449
|
targetFile = join(
|
|
8402
8450
|
tmpRoot,
|
|
@@ -8404,16 +8452,16 @@ var fromTypes = (targetFilePath, {
|
|
|
8404
8452
|
// use original file name as-is eg. in monorepo
|
|
8405
8453
|
fileName
|
|
8406
8454
|
);
|
|
8407
|
-
existed = existsSync(targetFile);
|
|
8455
|
+
existed = fs.existsSync(targetFile);
|
|
8408
8456
|
}
|
|
8409
8457
|
if (!existed) {
|
|
8410
|
-
rmSync(join(tmpRoot, "tsconfig.json"));
|
|
8458
|
+
fs.rmSync(join(tmpRoot, "tsconfig.json"));
|
|
8411
8459
|
console.warn(
|
|
8412
8460
|
"[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
|
|
8413
8461
|
);
|
|
8414
8462
|
console.warn("Couldn't find generated declaration file");
|
|
8415
|
-
if (existsSync(join(tmpRoot, "dist"))) {
|
|
8416
|
-
const tempFiles = readdirSync(join(tmpRoot, "dist"), {
|
|
8463
|
+
if (fs.existsSync(join(tmpRoot, "dist"))) {
|
|
8464
|
+
const tempFiles = fs.readdirSync(join(tmpRoot, "dist"), {
|
|
8417
8465
|
recursive: true
|
|
8418
8466
|
}).filter((x) => x.toString().endsWith(".d.ts")).map((x) => `- ${x}`).join("\n");
|
|
8419
8467
|
if (tempFiles) {
|
|
@@ -8431,9 +8479,9 @@ var fromTypes = (targetFilePath, {
|
|
|
8431
8479
|
return;
|
|
8432
8480
|
}
|
|
8433
8481
|
}
|
|
8434
|
-
const declaration = readFileSync(targetFile, "utf8");
|
|
8435
|
-
if (!debug && existsSync(tmpRoot))
|
|
8436
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
8482
|
+
const declaration = fs.readFileSync(targetFile, "utf8");
|
|
8483
|
+
if (!debug && fs.existsSync(tmpRoot))
|
|
8484
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
8437
8485
|
let instance = declaration.match(
|
|
8438
8486
|
instanceName ? new RegExp(`${instanceName}: Elysia<(.*)`, "gs") : matchRoute
|
|
8439
8487
|
)?.[0];
|
|
@@ -8446,35 +8494,7 @@ var fromTypes = (targetFilePath, {
|
|
|
8446
8494
|
3
|
|
8447
8495
|
)
|
|
8448
8496
|
);
|
|
8449
|
-
|
|
8450
|
-
instance.replace(matchStatus, '"$1":')
|
|
8451
|
-
);
|
|
8452
|
-
const routes = {};
|
|
8453
|
-
for (const route of routesString) {
|
|
8454
|
-
let schema = TypeBox(route.replaceAll(/readonly/g, ""));
|
|
8455
|
-
if (schema.type !== "object") continue;
|
|
8456
|
-
const paths = [];
|
|
8457
|
-
while (true) {
|
|
8458
|
-
const keys = Object.keys(schema.properties);
|
|
8459
|
-
if (keys.length !== 1) break;
|
|
8460
|
-
paths.push(keys[0]);
|
|
8461
|
-
schema = schema.properties[keys[0]];
|
|
8462
|
-
if (!schema?.properties) break;
|
|
8463
|
-
}
|
|
8464
|
-
const method = paths.pop();
|
|
8465
|
-
if (!method) continue;
|
|
8466
|
-
const path = "/" + paths.join("/");
|
|
8467
|
-
schema = schema.properties;
|
|
8468
|
-
if (schema?.response?.type === "object") {
|
|
8469
|
-
const responseSchema = {};
|
|
8470
|
-
for (const key in schema.response.properties)
|
|
8471
|
-
responseSchema[key] = schema.response.properties[key];
|
|
8472
|
-
schema.response = responseSchema;
|
|
8473
|
-
}
|
|
8474
|
-
if (!routes[path]) routes[path] = {};
|
|
8475
|
-
routes[path][method.toLowerCase()] = schema;
|
|
8476
|
-
}
|
|
8477
|
-
return routes;
|
|
8497
|
+
return declarationToJSONSchema(instance.slice(2));
|
|
8478
8498
|
} catch (error) {
|
|
8479
8499
|
console.warn(
|
|
8480
8500
|
"[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
|
|
@@ -8482,10 +8502,12 @@ var fromTypes = (targetFilePath, {
|
|
|
8482
8502
|
console.warn(error);
|
|
8483
8503
|
return;
|
|
8484
8504
|
} finally {
|
|
8485
|
-
if (!debug && existsSync(tmpRoot))
|
|
8486
|
-
rmSync(tmpRoot, { recursive: true, force: true });
|
|
8505
|
+
if (!debug && tmpRoot && fs.existsSync(tmpRoot))
|
|
8506
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
8487
8507
|
}
|
|
8488
8508
|
};
|
|
8489
8509
|
export {
|
|
8510
|
+
declarationToJSONSchema,
|
|
8511
|
+
extractRootObjects,
|
|
8490
8512
|
fromTypes
|
|
8491
8513
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare const openapi: <const Enabled extends boolean = true, const Path
|
|
|
33
33
|
standaloneSchema: {};
|
|
34
34
|
response: {};
|
|
35
35
|
}>;
|
|
36
|
+
export { fromTypes } from './gen';
|
|
36
37
|
export { toOpenAPISchema, withHeaders } from './openapi';
|
|
37
38
|
export type { ElysiaOpenAPIConfig };
|
|
38
39
|
export default openapi;
|