@elysiajs/openapi 1.4.9 → 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.
@@ -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
@@ -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
- if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
117
- return mapJsonSchema[vendor](schema);
118
- switch (vendor) {
119
- case "zod":
120
- if (warned.zod4 || warned.zod3) break;
121
- console.warn(
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
- "For Zod v4, please provide z.toJSONSchema as follows:\n"
124
+ "[@elysiajs/openapi] Zod doesn't provide JSON Schema method on the schema"
128
125
  );
129
- console.warn(warnings.zod4);
130
- } else {
131
- warned.zod3 = true;
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
- "For Zod v3, please install zod-to-json-schema package and use it like this:\n"
144
+ "[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
134
145
  );
135
- console.warn(warnings.zod3);
136
- }
137
- break;
138
- case "valibot":
139
- if (warned.valibot) break;
140
- warned.valibot = true;
141
- console.warn(
142
- "[@elysiajs/openapi] Valibot require a separate package for JSON Schema conversion"
143
- );
144
- console.warn(
145
- "Please install @valibot/to-json-schema package and use it like this:\n"
146
- );
147
- console.warn(warnings.valibot);
148
- break;
149
- case "effect":
150
- if (warned.effect) break;
151
- warned.effect = true;
152
- console.warn(
153
- "[@elysiajs/openapi] Effect Schema doesn't provide JSON Schema method on the schema"
154
- );
155
- console.warn(
156
- "please provide JSONSchema from 'effect' package as follows:\n"
157
- );
158
- console.warn(warnings.effect);
159
- break;
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 (vendor === "arktype")
162
- return schema?.toJsonSchema?.();
163
- return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
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 [paramName, paramSchema] of Object.entries(
237
- params.properties
238
- ))
273
+ for (const [name, schema] of Object.entries(params.properties))
239
274
  parameters.push({
240
- name: paramName,
275
+ name,
241
276
  in: "path",
242
277
  required: true,
243
278
  // Path parameters are always required
244
- schema: paramSchema
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 [queryName, querySchema] of Object.entries(
255
- query.properties
256
- ))
299
+ for (const [name, schema] of Object.entries(query.properties))
257
300
  parameters.push({
258
- name: queryName,
301
+ name,
259
302
  in: "query",
260
- required: required.includes(queryName),
261
- schema: querySchema
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.query, vendors),
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 [headerName, headerSchema] of Object.entries(
273
- headers.properties
274
- ))
315
+ for (const [name, schema] of Object.entries(headers.properties))
275
316
  parameters.push({
276
- name: headerName,
317
+ name,
277
318
  in: "header",
278
- required: required.includes(headerName),
279
- schema: headerSchema
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 [cookieName, cookieSchema] of Object.entries(
291
- cookie.properties
292
- ))
331
+ for (const [name, schema] of Object.entries(cookie.properties))
293
332
  parameters.push({
294
- name: cookieName,
333
+ name,
295
334
  in: "cookie",
296
- required: required.includes(cookieName),
297
- schema: cookieSchema
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, ...options } = unwrapReference(response, definitions);
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,
@@ -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: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug, compilerOptions, tmpRoot, silent }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
69
- export {};
71
+ targetFilePath?: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug, compilerOptions, tmpRoot, silent }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
@@ -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 matchStatus = /(\d{3}):/g;
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;
@@ -8334,41 +8322,89 @@ function extractRootObjects(code) {
8334
8322
  }
8335
8323
  return results;
8336
8324
  }
8337
- var fromTypes = (targetFilePath, {
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", {
8338
8356
  tsconfigPath = "tsconfig.json",
8339
8357
  instanceName,
8340
8358
  projectRoot = process.cwd(),
8341
8359
  overrideOutputPath,
8342
8360
  debug = false,
8343
8361
  compilerOptions,
8344
- tmpRoot = join(tmpdir(), ".ElysiaAutoOpenAPI"),
8362
+ tmpRoot,
8345
8363
  silent = false
8346
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
+ );
8347
8376
  try {
8348
8377
  if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
8349
8378
  throw new Error("Only .ts files are supported");
8350
8379
  if (targetFilePath.startsWith("./"))
8351
8380
  targetFilePath = targetFilePath.slice(2);
8352
8381
  let src = targetFilePath.startsWith("/") ? targetFilePath : join(projectRoot, targetFilePath);
8353
- if (!existsSync(src))
8382
+ if (!fs.existsSync(src))
8354
8383
  throw new Error(
8355
8384
  `Couldn't find "${targetFilePath}" from ${projectRoot}`
8356
8385
  );
8357
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
+ }
8358
8394
  if (targetFilePath.endsWith(".d.ts")) targetFile = targetFilePath;
8359
8395
  else {
8360
- if (existsSync(tmpRoot))
8361
- rmSync(tmpRoot, { recursive: true, force: true });
8362
- mkdirSync(tmpRoot, { recursive: true });
8396
+ if (fs.existsSync(tmpRoot))
8397
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
8398
+ fs.mkdirSync(tmpRoot, { recursive: true });
8363
8399
  const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : join(projectRoot, tsconfigPath);
8364
- let extendsRef = existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
8400
+ let extendsRef = fs.existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
8365
8401
  let distDir = join(tmpRoot, "dist");
8366
8402
  if (typeof process !== "undefined" && process.platform === "win32") {
8367
8403
  extendsRef = extendsRef.replace(/\\/g, "/");
8368
8404
  src = src.replace(/\\/g, "/");
8369
8405
  distDir = distDir.replace(/\\/g, "/");
8370
8406
  }
8371
- writeFileSync(
8407
+ fs.writeFileSync(
8372
8408
  join(tmpRoot, "tsconfig.json"),
8373
8409
  `{
8374
8410
  ${extendsRef}
@@ -8386,6 +8422,16 @@ var fromTypes = (targetFilePath, {
8386
8422
  "include": ["${src}"]
8387
8423
  }`
8388
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
+ );
8389
8435
  spawnSync(`tsc`, {
8390
8436
  shell: true,
8391
8437
  cwd: tmpRoot,
@@ -8398,7 +8444,7 @@ var fromTypes = (targetFilePath, {
8398
8444
  // remove leading like src or something similar
8399
8445
  fileName.slice(fileName.indexOf("/") + 1)
8400
8446
  );
8401
- let existed = existsSync(targetFile);
8447
+ let existed = fs.existsSync(targetFile);
8402
8448
  if (!existed && !overrideOutputPath) {
8403
8449
  targetFile = join(
8404
8450
  tmpRoot,
@@ -8406,16 +8452,16 @@ var fromTypes = (targetFilePath, {
8406
8452
  // use original file name as-is eg. in monorepo
8407
8453
  fileName
8408
8454
  );
8409
- existed = existsSync(targetFile);
8455
+ existed = fs.existsSync(targetFile);
8410
8456
  }
8411
8457
  if (!existed) {
8412
- rmSync(join(tmpRoot, "tsconfig.json"));
8458
+ fs.rmSync(join(tmpRoot, "tsconfig.json"));
8413
8459
  console.warn(
8414
8460
  "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
8415
8461
  );
8416
8462
  console.warn("Couldn't find generated declaration file");
8417
- if (existsSync(join(tmpRoot, "dist"))) {
8418
- const tempFiles = readdirSync(join(tmpRoot, "dist"), {
8463
+ if (fs.existsSync(join(tmpRoot, "dist"))) {
8464
+ const tempFiles = fs.readdirSync(join(tmpRoot, "dist"), {
8419
8465
  recursive: true
8420
8466
  }).filter((x) => x.toString().endsWith(".d.ts")).map((x) => `- ${x}`).join("\n");
8421
8467
  if (tempFiles) {
@@ -8433,9 +8479,9 @@ var fromTypes = (targetFilePath, {
8433
8479
  return;
8434
8480
  }
8435
8481
  }
8436
- const declaration = readFileSync(targetFile, "utf8");
8437
- if (!debug && existsSync(tmpRoot))
8438
- 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 });
8439
8485
  let instance = declaration.match(
8440
8486
  instanceName ? new RegExp(`${instanceName}: Elysia<(.*)`, "gs") : matchRoute
8441
8487
  )?.[0];
@@ -8448,34 +8494,7 @@ var fromTypes = (targetFilePath, {
8448
8494
  3
8449
8495
  )
8450
8496
  );
8451
- const routes = {};
8452
- for (const route of extractRootObjects(
8453
- instance.slice(2).replace(matchStatus, '"$1":')
8454
- )) {
8455
- let schema = TypeBox(route.replaceAll(/readonly/g, ""));
8456
- if (schema.type !== "object") continue;
8457
- const paths = [];
8458
- while (true) {
8459
- const keys = Object.keys(schema.properties);
8460
- if (keys.length !== 1) break;
8461
- paths.push(keys[0]);
8462
- schema = schema.properties[keys[0]];
8463
- if (!schema?.properties) break;
8464
- }
8465
- const method = paths.pop();
8466
- if (!method) continue;
8467
- const path = "/" + paths.join("/");
8468
- schema = schema.properties;
8469
- if (schema?.response?.type === "object") {
8470
- const responseSchema = {};
8471
- for (const key in schema.response.properties)
8472
- responseSchema[key] = schema.response.properties[key];
8473
- schema.response = responseSchema;
8474
- }
8475
- if (!routes[path]) routes[path] = {};
8476
- routes[path][method.toLowerCase()] = schema;
8477
- }
8478
- return routes;
8497
+ return declarationToJSONSchema(instance.slice(2));
8479
8498
  } catch (error) {
8480
8499
  console.warn(
8481
8500
  "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
@@ -8483,10 +8502,12 @@ var fromTypes = (targetFilePath, {
8483
8502
  console.warn(error);
8484
8503
  return;
8485
8504
  } finally {
8486
- if (!debug && existsSync(tmpRoot))
8487
- rmSync(tmpRoot, { recursive: true, force: true });
8505
+ if (!debug && tmpRoot && fs.existsSync(tmpRoot))
8506
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
8488
8507
  }
8489
8508
  };
8490
8509
  export {
8510
+ declarationToJSONSchema,
8511
+ extractRootObjects,
8491
8512
  fromTypes
8492
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;