@elysiajs/openapi 1.4.3 → 1.4.5

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.
@@ -8315,6 +8315,35 @@ var import_child_process = require("child_process");
8315
8315
  var matchRoute = /: Elysia<(.*)>/gs;
8316
8316
  var matchStatus = /(\d{3}):/g;
8317
8317
  var wrapStatusInQuote = (value) => value.replace(matchStatus, '"$1":');
8318
+ function extractRootObjects(code) {
8319
+ const results = [];
8320
+ let i = 0;
8321
+ while (i < code.length) {
8322
+ const colonIdx = code.indexOf(":", i);
8323
+ if (colonIdx === -1) break;
8324
+ let keyEnd = colonIdx - 1;
8325
+ while (keyEnd >= 0 && /\s/.test(code[keyEnd])) keyEnd--;
8326
+ let keyStart = keyEnd;
8327
+ while (keyStart >= 0 && /\w/.test(code[keyStart])) keyStart--;
8328
+ const braceIdx = code.indexOf("{", colonIdx);
8329
+ if (braceIdx === -1) break;
8330
+ let depth = 0;
8331
+ let end = braceIdx;
8332
+ for (; end < code.length; end++) {
8333
+ if (code[end] === "{") depth++;
8334
+ else if (code[end] === "}") {
8335
+ depth--;
8336
+ if (depth === 0) {
8337
+ end++;
8338
+ break;
8339
+ }
8340
+ }
8341
+ }
8342
+ results.push(`{${code.slice(keyStart + 1, end)};}`);
8343
+ i = end;
8344
+ }
8345
+ return results;
8346
+ }
8318
8347
  var fromTypes = (targetFilePath, {
8319
8348
  tsconfigPath = "tsconfig.json",
8320
8349
  instanceName,
@@ -8322,7 +8351,8 @@ var fromTypes = (targetFilePath, {
8322
8351
  overrideOutputPath,
8323
8352
  debug = false,
8324
8353
  compilerOptions,
8325
- tmpRoot = (0, import_path2.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI")
8354
+ tmpRoot = (0, import_path2.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI"),
8355
+ silent = false
8326
8356
  } = {}) => () => {
8327
8357
  try {
8328
8358
  if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
@@ -8369,7 +8399,7 @@ var fromTypes = (targetFilePath, {
8369
8399
  (0, import_child_process.spawnSync)(`tsc`, {
8370
8400
  shell: true,
8371
8401
  cwd: tmpRoot,
8372
- stdio: debug ? "inherit" : void 0
8402
+ stdio: silent ? void 0 : "inherit"
8373
8403
  });
8374
8404
  const fileName = targetFilePath.replace(/.tsx$/, ".ts").replace(/.ts$/, ".d.ts");
8375
8405
  targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : (0, import_path2.join)(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? (0, import_path2.join)(
@@ -8405,7 +8435,7 @@ var fromTypes = (targetFilePath, {
8405
8435
  console.warn(tempFiles);
8406
8436
  }
8407
8437
  } else {
8408
- console.log(
8438
+ console.warn(
8409
8439
  "reason: root folder doesn't exists",
8410
8440
  (0, import_path2.join)(tmpRoot, "dist")
8411
8441
  );
@@ -8414,7 +8444,7 @@ var fromTypes = (targetFilePath, {
8414
8444
  }
8415
8445
  }
8416
8446
  const declaration = (0, import_fs.readFileSync)(targetFile, "utf8");
8417
- if ((0, import_fs.existsSync)(tmpRoot))
8447
+ if (!debug && (0, import_fs.existsSync)(tmpRoot))
8418
8448
  (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
8419
8449
  let instance = declaration.match(
8420
8450
  instanceName ? new RegExp(`${instanceName}: Elysia<(.*)`, "gs") : matchRoute
@@ -8434,8 +8464,8 @@ var fromTypes = (targetFilePath, {
8434
8464
  instance.slice(3, instance.indexOf("}, {", 4))
8435
8465
  );
8436
8466
  const routes = {};
8437
- for (const route of routesString.slice(1).split("} & {")) {
8438
- let schema = TypeBox(`{${route}}`);
8467
+ for (const route of extractRootObjects(routesString)) {
8468
+ let schema = TypeBox(route);
8439
8469
  if (schema.type !== "object") continue;
8440
8470
  const paths = [];
8441
8471
  while (true) {
@@ -8446,6 +8476,7 @@ var fromTypes = (targetFilePath, {
8446
8476
  if (!schema?.properties) break;
8447
8477
  }
8448
8478
  const method = paths.pop();
8479
+ if (!method) continue;
8449
8480
  const path = "/" + paths.join("/");
8450
8481
  schema = schema.properties;
8451
8482
  if (schema?.response?.type === "object") {
package/dist/cjs/index.js CHANGED
@@ -340,7 +340,8 @@ openapi({
340
340
  zod: zodToJsonSchema
341
341
  }
342
342
  })`,
343
- valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
343
+ valibot: `import openapi from '@elysiajs/openapi'
344
+ import { toJsonSchema } from '@valibot/to-json-schema'
344
345
 
345
346
  openapi({
346
347
  mapJsonSchema: {
@@ -357,9 +358,10 @@ openapi({
357
358
  };
358
359
  var warned = {};
359
360
  var unwrapReference = (schema, definitions) => {
360
- if (!schema?.$ref) return schema;
361
- const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
362
- if (schema.$ref && definitions[name]) schema = definitions[name];
361
+ const ref = schema?.$ref;
362
+ if (!ref) return schema;
363
+ const name = ref.slice(ref.lastIndexOf("/") + 1);
364
+ if (ref && definitions[name]) schema = definitions[name];
363
365
  return schema;
364
366
  };
365
367
  var unwrapSchema = (schema, mapJsonSchema) => {
@@ -418,11 +420,12 @@ var unwrapSchema = (schema, mapJsonSchema) => {
418
420
  return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
419
421
  };
420
422
  function toOpenAPISchema(app, exclude, references, vendors) {
421
- const {
422
- methods: excludeMethods = ["OPTIONS"],
423
+ let {
424
+ methods: excludeMethods = ["options"],
423
425
  staticFile: excludeStaticFile = true,
424
426
  tags: excludeTags
425
427
  } = exclude ?? {};
428
+ excludeMethods = excludeMethods.map((method) => method.toLowerCase());
426
429
  const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
427
430
  const paths = /* @__PURE__ */ Object.create(null);
428
431
  const definitions = app.getGlobalDefinitions?.().type;
@@ -488,7 +491,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
488
491
  });
489
492
  }
490
493
  if (hooks.query) {
491
- const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
494
+ const query = unwrapReference(
495
+ unwrapSchema(hooks.query, vendors),
496
+ definitions
497
+ );
492
498
  if (query && query.type === "object" && query.properties) {
493
499
  const required = query.required || [];
494
500
  for (const [queryName, querySchema] of Object.entries(
@@ -503,7 +509,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
503
509
  }
504
510
  }
505
511
  if (hooks.headers) {
506
- const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
512
+ const headers = unwrapReference(
513
+ unwrapSchema(hooks.query, vendors),
514
+ definitions
515
+ );
507
516
  if (headers && headers.type === "object" && headers.properties) {
508
517
  const required = headers.required || [];
509
518
  for (const [headerName, headerSchema] of Object.entries(
@@ -518,7 +527,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
518
527
  }
519
528
  }
520
529
  if (hooks.cookie) {
521
- const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
530
+ const cookie = unwrapReference(
531
+ unwrapSchema(hooks.cookie, vendors),
532
+ definitions
533
+ );
522
534
  if (cookie && cookie.type === "object" && cookie.properties) {
523
535
  const required = cookie.required || [];
524
536
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -536,8 +548,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
536
548
  if (hooks.body && method !== "get" && method !== "head") {
537
549
  const body = unwrapSchema(hooks.body, vendors);
538
550
  if (body) {
539
- const { type: _type, description, ...options } = body;
540
- const type = _type;
551
+ const { type, description, $ref, ...options } = unwrapReference(
552
+ body,
553
+ definitions
554
+ );
541
555
  if (hooks.parse) {
542
556
  const content = {};
543
557
  const parsers = hooks.parse;
@@ -575,7 +589,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
575
589
  operation.requestBody = {
576
590
  description,
577
591
  content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
578
- "text/plain": body
592
+ "text/plain": {
593
+ schema: body
594
+ }
579
595
  } : {
580
596
  "application/json": {
581
597
  schema: body
@@ -598,11 +614,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
598
614
  for (let [status, schema] of Object.entries(hooks.response)) {
599
615
  const response = unwrapSchema(schema, vendors);
600
616
  if (!response) continue;
601
- const { type: _type, description, ...options } = response;
602
- const type = _type;
617
+ const { type, description, $ref, ...options } = unwrapReference(response, definitions);
603
618
  operation.responses[status] = {
604
619
  description: description ?? `Response for status ${status}`,
605
- ...options,
606
620
  content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
607
621
  "text/plain": {
608
622
  schema: response
@@ -617,7 +631,11 @@ function toOpenAPISchema(app, exclude, references, vendors) {
617
631
  } else {
618
632
  const response = unwrapSchema(hooks.response, vendors);
619
633
  if (response) {
620
- const { type: _type, description, ...options } = response;
634
+ const {
635
+ type: _type,
636
+ description,
637
+ ...options
638
+ } = unwrapReference(response, definitions);
621
639
  const type = _type;
622
640
  operation.responses["200"] = {
623
641
  description: description ?? `Response for status 200`,
@@ -83,7 +83,8 @@ openapi({
83
83
  zod: zodToJsonSchema
84
84
  }
85
85
  })`,
86
- valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
86
+ valibot: `import openapi from '@elysiajs/openapi'
87
+ import { toJsonSchema } from '@valibot/to-json-schema'
87
88
 
88
89
  openapi({
89
90
  mapJsonSchema: {
@@ -100,9 +101,10 @@ openapi({
100
101
  };
101
102
  var warned = {};
102
103
  var unwrapReference = (schema, definitions) => {
103
- if (!schema?.$ref) return schema;
104
- const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
105
- if (schema.$ref && definitions[name]) schema = definitions[name];
104
+ const ref = schema?.$ref;
105
+ if (!ref) return schema;
106
+ const name = ref.slice(ref.lastIndexOf("/") + 1);
107
+ if (ref && definitions[name]) schema = definitions[name];
106
108
  return schema;
107
109
  };
108
110
  var unwrapSchema = (schema, mapJsonSchema) => {
@@ -161,11 +163,12 @@ var unwrapSchema = (schema, mapJsonSchema) => {
161
163
  return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
162
164
  };
163
165
  function toOpenAPISchema(app, exclude, references, vendors) {
164
- const {
165
- methods: excludeMethods = ["OPTIONS"],
166
+ let {
167
+ methods: excludeMethods = ["options"],
166
168
  staticFile: excludeStaticFile = true,
167
169
  tags: excludeTags
168
170
  } = exclude ?? {};
171
+ excludeMethods = excludeMethods.map((method) => method.toLowerCase());
169
172
  const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
170
173
  const paths = /* @__PURE__ */ Object.create(null);
171
174
  const definitions = app.getGlobalDefinitions?.().type;
@@ -231,7 +234,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
231
234
  });
232
235
  }
233
236
  if (hooks.query) {
234
- const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
237
+ const query = unwrapReference(
238
+ unwrapSchema(hooks.query, vendors),
239
+ definitions
240
+ );
235
241
  if (query && query.type === "object" && query.properties) {
236
242
  const required = query.required || [];
237
243
  for (const [queryName, querySchema] of Object.entries(
@@ -246,7 +252,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
246
252
  }
247
253
  }
248
254
  if (hooks.headers) {
249
- const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
255
+ const headers = unwrapReference(
256
+ unwrapSchema(hooks.query, vendors),
257
+ definitions
258
+ );
250
259
  if (headers && headers.type === "object" && headers.properties) {
251
260
  const required = headers.required || [];
252
261
  for (const [headerName, headerSchema] of Object.entries(
@@ -261,7 +270,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
261
270
  }
262
271
  }
263
272
  if (hooks.cookie) {
264
- const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
273
+ const cookie = unwrapReference(
274
+ unwrapSchema(hooks.cookie, vendors),
275
+ definitions
276
+ );
265
277
  if (cookie && cookie.type === "object" && cookie.properties) {
266
278
  const required = cookie.required || [];
267
279
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -279,8 +291,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
279
291
  if (hooks.body && method !== "get" && method !== "head") {
280
292
  const body = unwrapSchema(hooks.body, vendors);
281
293
  if (body) {
282
- const { type: _type, description, ...options } = body;
283
- const type = _type;
294
+ const { type, description, $ref, ...options } = unwrapReference(
295
+ body,
296
+ definitions
297
+ );
284
298
  if (hooks.parse) {
285
299
  const content = {};
286
300
  const parsers = hooks.parse;
@@ -318,7 +332,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
318
332
  operation.requestBody = {
319
333
  description,
320
334
  content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
321
- "text/plain": body
335
+ "text/plain": {
336
+ schema: body
337
+ }
322
338
  } : {
323
339
  "application/json": {
324
340
  schema: body
@@ -341,11 +357,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
341
357
  for (let [status, schema] of Object.entries(hooks.response)) {
342
358
  const response = unwrapSchema(schema, vendors);
343
359
  if (!response) continue;
344
- const { type: _type, description, ...options } = response;
345
- const type = _type;
360
+ const { type, description, $ref, ...options } = unwrapReference(response, definitions);
346
361
  operation.responses[status] = {
347
362
  description: description ?? `Response for status ${status}`,
348
- ...options,
349
363
  content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
350
364
  "text/plain": {
351
365
  schema: response
@@ -360,7 +374,11 @@ function toOpenAPISchema(app, exclude, references, vendors) {
360
374
  } else {
361
375
  const response = unwrapSchema(hooks.response, vendors);
362
376
  if (response) {
363
- const { type: _type, description, ...options } = response;
377
+ const {
378
+ type: _type,
379
+ description,
380
+ ...options
381
+ } = unwrapReference(response, definitions);
364
382
  const type = _type;
365
383
  operation.responses["200"] = {
366
384
  description: description ?? `Response for status 200`,
@@ -46,6 +46,11 @@ interface OpenAPIGeneratorOptions {
46
46
  * ! be careful that the folder will be removed after the process ends
47
47
  */
48
48
  tmpRoot?: string;
49
+ /**
50
+ * disable log
51
+ * @default false
52
+ */
53
+ silent?: boolean;
49
54
  }
50
55
  /**
51
56
  * Auto generate OpenAPI schema from Elysia instance
@@ -60,5 +65,5 @@ export declare const fromTypes: (
60
65
  *
61
66
  * The path must export an Elysia instance
62
67
  */
63
- targetFilePath: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug, compilerOptions, tmpRoot }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
68
+ targetFilePath: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug, compilerOptions, tmpRoot, silent }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
64
69
  export {};
@@ -8304,6 +8304,35 @@ import { spawnSync } from "child_process";
8304
8304
  var matchRoute = /: Elysia<(.*)>/gs;
8305
8305
  var matchStatus = /(\d{3}):/g;
8306
8306
  var wrapStatusInQuote = (value) => value.replace(matchStatus, '"$1":');
8307
+ function extractRootObjects(code) {
8308
+ const results = [];
8309
+ let i = 0;
8310
+ while (i < code.length) {
8311
+ const colonIdx = code.indexOf(":", i);
8312
+ if (colonIdx === -1) break;
8313
+ let keyEnd = colonIdx - 1;
8314
+ while (keyEnd >= 0 && /\s/.test(code[keyEnd])) keyEnd--;
8315
+ let keyStart = keyEnd;
8316
+ while (keyStart >= 0 && /\w/.test(code[keyStart])) keyStart--;
8317
+ const braceIdx = code.indexOf("{", colonIdx);
8318
+ if (braceIdx === -1) break;
8319
+ let depth = 0;
8320
+ let end = braceIdx;
8321
+ for (; end < code.length; end++) {
8322
+ if (code[end] === "{") depth++;
8323
+ else if (code[end] === "}") {
8324
+ depth--;
8325
+ if (depth === 0) {
8326
+ end++;
8327
+ break;
8328
+ }
8329
+ }
8330
+ }
8331
+ results.push(`{${code.slice(keyStart + 1, end)};}`);
8332
+ i = end;
8333
+ }
8334
+ return results;
8335
+ }
8307
8336
  var fromTypes = (targetFilePath, {
8308
8337
  tsconfigPath = "tsconfig.json",
8309
8338
  instanceName,
@@ -8311,7 +8340,8 @@ var fromTypes = (targetFilePath, {
8311
8340
  overrideOutputPath,
8312
8341
  debug = false,
8313
8342
  compilerOptions,
8314
- tmpRoot = join(tmpdir(), ".ElysiaAutoOpenAPI")
8343
+ tmpRoot = join(tmpdir(), ".ElysiaAutoOpenAPI"),
8344
+ silent = false
8315
8345
  } = {}) => () => {
8316
8346
  try {
8317
8347
  if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
@@ -8358,7 +8388,7 @@ var fromTypes = (targetFilePath, {
8358
8388
  spawnSync(`tsc`, {
8359
8389
  shell: true,
8360
8390
  cwd: tmpRoot,
8361
- stdio: debug ? "inherit" : void 0
8391
+ stdio: silent ? void 0 : "inherit"
8362
8392
  });
8363
8393
  const fileName = targetFilePath.replace(/.tsx$/, ".ts").replace(/.ts$/, ".d.ts");
8364
8394
  targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : join(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? join(
@@ -8394,7 +8424,7 @@ var fromTypes = (targetFilePath, {
8394
8424
  console.warn(tempFiles);
8395
8425
  }
8396
8426
  } else {
8397
- console.log(
8427
+ console.warn(
8398
8428
  "reason: root folder doesn't exists",
8399
8429
  join(tmpRoot, "dist")
8400
8430
  );
@@ -8403,7 +8433,7 @@ var fromTypes = (targetFilePath, {
8403
8433
  }
8404
8434
  }
8405
8435
  const declaration = readFileSync(targetFile, "utf8");
8406
- if (existsSync(tmpRoot))
8436
+ if (!debug && existsSync(tmpRoot))
8407
8437
  rmSync(tmpRoot, { recursive: true, force: true });
8408
8438
  let instance = declaration.match(
8409
8439
  instanceName ? new RegExp(`${instanceName}: Elysia<(.*)`, "gs") : matchRoute
@@ -8423,8 +8453,8 @@ var fromTypes = (targetFilePath, {
8423
8453
  instance.slice(3, instance.indexOf("}, {", 4))
8424
8454
  );
8425
8455
  const routes = {};
8426
- for (const route of routesString.slice(1).split("} & {")) {
8427
- let schema = TypeBox(`{${route}}`);
8456
+ for (const route of extractRootObjects(routesString)) {
8457
+ let schema = TypeBox(route);
8428
8458
  if (schema.type !== "object") continue;
8429
8459
  const paths = [];
8430
8460
  while (true) {
@@ -8435,6 +8465,7 @@ var fromTypes = (targetFilePath, {
8435
8465
  if (!schema?.properties) break;
8436
8466
  }
8437
8467
  const method = paths.pop();
8468
+ if (!method) continue;
8438
8469
  const path = "/" + paths.join("/");
8439
8470
  schema = schema.properties;
8440
8471
  if (schema?.response?.type === "object") {
package/dist/index.mjs CHANGED
@@ -313,7 +313,8 @@ openapi({
313
313
  zod: zodToJsonSchema
314
314
  }
315
315
  })`,
316
- valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
316
+ valibot: `import openapi from '@elysiajs/openapi'
317
+ import { toJsonSchema } from '@valibot/to-json-schema'
317
318
 
318
319
  openapi({
319
320
  mapJsonSchema: {
@@ -330,9 +331,10 @@ openapi({
330
331
  };
331
332
  var warned = {};
332
333
  var unwrapReference = (schema, definitions) => {
333
- if (!schema?.$ref) return schema;
334
- const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
335
- if (schema.$ref && definitions[name]) schema = definitions[name];
334
+ const ref = schema?.$ref;
335
+ if (!ref) return schema;
336
+ const name = ref.slice(ref.lastIndexOf("/") + 1);
337
+ if (ref && definitions[name]) schema = definitions[name];
336
338
  return schema;
337
339
  };
338
340
  var unwrapSchema = (schema, mapJsonSchema) => {
@@ -391,11 +393,12 @@ var unwrapSchema = (schema, mapJsonSchema) => {
391
393
  return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
392
394
  };
393
395
  function toOpenAPISchema(app, exclude, references, vendors) {
394
- const {
395
- methods: excludeMethods = ["OPTIONS"],
396
+ let {
397
+ methods: excludeMethods = ["options"],
396
398
  staticFile: excludeStaticFile = true,
397
399
  tags: excludeTags
398
400
  } = exclude ?? {};
401
+ excludeMethods = excludeMethods.map((method) => method.toLowerCase());
399
402
  const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
400
403
  const paths = /* @__PURE__ */ Object.create(null);
401
404
  const definitions = app.getGlobalDefinitions?.().type;
@@ -461,7 +464,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
461
464
  });
462
465
  }
463
466
  if (hooks.query) {
464
- const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
467
+ const query = unwrapReference(
468
+ unwrapSchema(hooks.query, vendors),
469
+ definitions
470
+ );
465
471
  if (query && query.type === "object" && query.properties) {
466
472
  const required = query.required || [];
467
473
  for (const [queryName, querySchema] of Object.entries(
@@ -476,7 +482,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
476
482
  }
477
483
  }
478
484
  if (hooks.headers) {
479
- const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
485
+ const headers = unwrapReference(
486
+ unwrapSchema(hooks.query, vendors),
487
+ definitions
488
+ );
480
489
  if (headers && headers.type === "object" && headers.properties) {
481
490
  const required = headers.required || [];
482
491
  for (const [headerName, headerSchema] of Object.entries(
@@ -491,7 +500,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
491
500
  }
492
501
  }
493
502
  if (hooks.cookie) {
494
- const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
503
+ const cookie = unwrapReference(
504
+ unwrapSchema(hooks.cookie, vendors),
505
+ definitions
506
+ );
495
507
  if (cookie && cookie.type === "object" && cookie.properties) {
496
508
  const required = cookie.required || [];
497
509
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -509,8 +521,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
509
521
  if (hooks.body && method !== "get" && method !== "head") {
510
522
  const body = unwrapSchema(hooks.body, vendors);
511
523
  if (body) {
512
- const { type: _type, description, ...options } = body;
513
- const type = _type;
524
+ const { type, description, $ref, ...options } = unwrapReference(
525
+ body,
526
+ definitions
527
+ );
514
528
  if (hooks.parse) {
515
529
  const content = {};
516
530
  const parsers = hooks.parse;
@@ -548,7 +562,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
548
562
  operation.requestBody = {
549
563
  description,
550
564
  content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
551
- "text/plain": body
565
+ "text/plain": {
566
+ schema: body
567
+ }
552
568
  } : {
553
569
  "application/json": {
554
570
  schema: body
@@ -571,11 +587,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
571
587
  for (let [status, schema] of Object.entries(hooks.response)) {
572
588
  const response = unwrapSchema(schema, vendors);
573
589
  if (!response) continue;
574
- const { type: _type, description, ...options } = response;
575
- const type = _type;
590
+ const { type, description, $ref, ...options } = unwrapReference(response, definitions);
576
591
  operation.responses[status] = {
577
592
  description: description ?? `Response for status ${status}`,
578
- ...options,
579
593
  content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
580
594
  "text/plain": {
581
595
  schema: response
@@ -590,7 +604,11 @@ function toOpenAPISchema(app, exclude, references, vendors) {
590
604
  } else {
591
605
  const response = unwrapSchema(hooks.response, vendors);
592
606
  if (response) {
593
- const { type: _type, description, ...options } = response;
607
+ const {
608
+ type: _type,
609
+ description,
610
+ ...options
611
+ } = unwrapReference(response, definitions);
594
612
  const type = _type;
595
613
  operation.responses["200"] = {
596
614
  description: description ?? `Response for status 200`,
package/dist/openapi.mjs CHANGED
@@ -54,7 +54,8 @@ openapi({
54
54
  zod: zodToJsonSchema
55
55
  }
56
56
  })`,
57
- valibot: `import { toJsonSchema } from '@valibot/to-json-schema'
57
+ valibot: `import openapi from '@elysiajs/openapi'
58
+ import { toJsonSchema } from '@valibot/to-json-schema'
58
59
 
59
60
  openapi({
60
61
  mapJsonSchema: {
@@ -71,9 +72,10 @@ openapi({
71
72
  };
72
73
  var warned = {};
73
74
  var unwrapReference = (schema, definitions) => {
74
- if (!schema?.$ref) return schema;
75
- const name = schema.$ref.slice(schema.$ref.lastIndexOf("/") + 1);
76
- if (schema.$ref && definitions[name]) schema = definitions[name];
75
+ const ref = schema?.$ref;
76
+ if (!ref) return schema;
77
+ const name = ref.slice(ref.lastIndexOf("/") + 1);
78
+ if (ref && definitions[name]) schema = definitions[name];
77
79
  return schema;
78
80
  };
79
81
  var unwrapSchema = (schema, mapJsonSchema) => {
@@ -132,11 +134,12 @@ var unwrapSchema = (schema, mapJsonSchema) => {
132
134
  return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
133
135
  };
134
136
  function toOpenAPISchema(app, exclude, references, vendors) {
135
- const {
136
- methods: excludeMethods = ["OPTIONS"],
137
+ let {
138
+ methods: excludeMethods = ["options"],
137
139
  staticFile: excludeStaticFile = true,
138
140
  tags: excludeTags
139
141
  } = exclude ?? {};
142
+ excludeMethods = excludeMethods.map((method) => method.toLowerCase());
140
143
  const excludePaths = Array.isArray(exclude?.paths) ? exclude.paths : typeof exclude?.paths !== "undefined" ? [exclude.paths] : [];
141
144
  const paths = /* @__PURE__ */ Object.create(null);
142
145
  const definitions = app.getGlobalDefinitions?.().type;
@@ -202,7 +205,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
202
205
  });
203
206
  }
204
207
  if (hooks.query) {
205
- const query = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
208
+ const query = unwrapReference(
209
+ unwrapSchema(hooks.query, vendors),
210
+ definitions
211
+ );
206
212
  if (query && query.type === "object" && query.properties) {
207
213
  const required = query.required || [];
208
214
  for (const [queryName, querySchema] of Object.entries(
@@ -217,7 +223,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
217
223
  }
218
224
  }
219
225
  if (hooks.headers) {
220
- const headers = unwrapReference(unwrapSchema(hooks.query, vendors), definitions);
226
+ const headers = unwrapReference(
227
+ unwrapSchema(hooks.query, vendors),
228
+ definitions
229
+ );
221
230
  if (headers && headers.type === "object" && headers.properties) {
222
231
  const required = headers.required || [];
223
232
  for (const [headerName, headerSchema] of Object.entries(
@@ -232,7 +241,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
232
241
  }
233
242
  }
234
243
  if (hooks.cookie) {
235
- const cookie = unwrapReference(unwrapSchema(hooks.cookie, vendors), definitions);
244
+ const cookie = unwrapReference(
245
+ unwrapSchema(hooks.cookie, vendors),
246
+ definitions
247
+ );
236
248
  if (cookie && cookie.type === "object" && cookie.properties) {
237
249
  const required = cookie.required || [];
238
250
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -250,8 +262,10 @@ function toOpenAPISchema(app, exclude, references, vendors) {
250
262
  if (hooks.body && method !== "get" && method !== "head") {
251
263
  const body = unwrapSchema(hooks.body, vendors);
252
264
  if (body) {
253
- const { type: _type, description, ...options } = body;
254
- const type = _type;
265
+ const { type, description, $ref, ...options } = unwrapReference(
266
+ body,
267
+ definitions
268
+ );
255
269
  if (hooks.parse) {
256
270
  const content = {};
257
271
  const parsers = hooks.parse;
@@ -289,7 +303,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
289
303
  operation.requestBody = {
290
304
  description,
291
305
  content: type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
292
- "text/plain": body
306
+ "text/plain": {
307
+ schema: body
308
+ }
293
309
  } : {
294
310
  "application/json": {
295
311
  schema: body
@@ -312,11 +328,9 @@ function toOpenAPISchema(app, exclude, references, vendors) {
312
328
  for (let [status, schema] of Object.entries(hooks.response)) {
313
329
  const response = unwrapSchema(schema, vendors);
314
330
  if (!response) continue;
315
- const { type: _type, description, ...options } = response;
316
- const type = _type;
331
+ const { type, description, $ref, ...options } = unwrapReference(response, definitions);
317
332
  operation.responses[status] = {
318
333
  description: description ?? `Response for status ${status}`,
319
- ...options,
320
334
  content: type === "void" || type === "null" || type === "undefined" ? response : type === "string" || type === "number" || type === "integer" || type === "boolean" ? {
321
335
  "text/plain": {
322
336
  schema: response
@@ -331,7 +345,11 @@ function toOpenAPISchema(app, exclude, references, vendors) {
331
345
  } else {
332
346
  const response = unwrapSchema(hooks.response, vendors);
333
347
  if (response) {
334
- const { type: _type, description, ...options } = response;
348
+ const {
349
+ type: _type,
350
+ description,
351
+ ...options
352
+ } = unwrapReference(response, definitions);
335
353
  const type = _type;
336
354
  operation.responses["200"] = {
337
355
  description: description ?? `Response for status 200`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elysiajs/openapi",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "Plugin for Elysia to auto-generate API documentation",
5
5
  "author": {
6
6
  "name": "saltyAom",