@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.
@@ -20,10 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/gen/index.ts
21
21
  var gen_exports = {};
22
22
  __export(gen_exports, {
23
+ declarationToJSONSchema: () => declarationToJSONSchema,
24
+ extractRootObjects: () => extractRootObjects,
23
25
  fromTypes: () => fromTypes
24
26
  });
25
27
  module.exports = __toCommonJS(gen_exports);
26
- var import_fs = require("fs");
27
28
 
28
29
  // node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
29
30
  function IsObject(value) {
@@ -8309,11 +8310,9 @@ function TypeBox(...args) {
8309
8310
  }
8310
8311
 
8311
8312
  // src/gen/index.ts
8312
- var import_os = require("os");
8313
- var import_path2 = require("path");
8314
- var import_child_process = require("child_process");
8315
8313
  var matchRoute = /: Elysia<(.*)>/gs;
8316
- var matchStatus = /(\d{3}):/g;
8314
+ var numberKey = /(\d+):/g;
8315
+ var join = (...parts) => parts.join("/").replace(/\/{1,}/g, "/");
8317
8316
  function extractRootObjects(code) {
8318
8317
  const results = [];
8319
8318
  let i = 0;
@@ -8323,7 +8322,9 @@ function extractRootObjects(code) {
8323
8322
  let keyEnd = colonIdx - 1;
8324
8323
  while (keyEnd >= 0 && /\s/.test(code[keyEnd])) keyEnd--;
8325
8324
  let keyStart = keyEnd;
8326
- while (keyStart >= 0 && /\w/.test(code[keyStart])) keyStart--;
8325
+ while (keyStart >= 0 && !/[\s{};,\n]/.test(code[keyStart])) {
8326
+ keyStart--;
8327
+ }
8327
8328
  const braceIdx = code.indexOf("{", colonIdx);
8328
8329
  if (braceIdx === -1) break;
8329
8330
  let depth = 0;
@@ -8343,42 +8344,90 @@ function extractRootObjects(code) {
8343
8344
  }
8344
8345
  return results;
8345
8346
  }
8346
- var fromTypes = (targetFilePath, {
8347
+ function declarationToJSONSchema(declaration) {
8348
+ const routes = {};
8349
+ for (const route of extractRootObjects(
8350
+ declaration.replace(numberKey, '"$1":')
8351
+ )) {
8352
+ let schema = TypeBox(route.replaceAll(/readonly/g, ""));
8353
+ if (schema.type !== "object") continue;
8354
+ const paths = [];
8355
+ while (true) {
8356
+ const keys = Object.keys(schema.properties);
8357
+ if (keys.length !== 1) break;
8358
+ paths.push(keys[0]);
8359
+ schema = schema.properties[keys[0]];
8360
+ if (!schema?.properties) break;
8361
+ }
8362
+ const method = paths.pop();
8363
+ if (!method) continue;
8364
+ const path = "/" + paths.join("/");
8365
+ schema = schema.properties;
8366
+ if (schema?.response?.type === "object") {
8367
+ const responseSchema = {};
8368
+ for (const key in schema.response.properties)
8369
+ responseSchema[key] = schema.response.properties[key];
8370
+ schema.response = responseSchema;
8371
+ }
8372
+ if (!routes[path]) routes[path] = {};
8373
+ routes[path][method.toLowerCase()] = schema;
8374
+ }
8375
+ return routes;
8376
+ }
8377
+ var fromTypes = (targetFilePath = "src/index.ts", {
8347
8378
  tsconfigPath = "tsconfig.json",
8348
8379
  instanceName,
8349
8380
  projectRoot = process.cwd(),
8350
8381
  overrideOutputPath,
8351
8382
  debug = false,
8352
8383
  compilerOptions,
8353
- tmpRoot = (0, import_path2.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI"),
8384
+ tmpRoot,
8354
8385
  silent = false
8355
8386
  } = {}) => () => {
8387
+ if (targetFilePath.trimStart().startsWith("{") && targetFilePath.trimEnd().endsWith("}"))
8388
+ return declarationToJSONSchema(targetFilePath);
8389
+ if (typeof process === "undefined" || typeof process.getBuiltinModule !== "function")
8390
+ throw new Error(
8391
+ "[@elysiajs/openapi/gen] `fromTypes` from file path is only available in Node.js/Bun environment or environments"
8392
+ );
8393
+ const fs = process.getBuiltinModule("fs");
8394
+ if (!fs)
8395
+ throw new Error(
8396
+ "[@elysiajs/openapi/gen] `fromTypes` require `fs` module which is not available in this environment"
8397
+ );
8356
8398
  try {
8357
8399
  if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
8358
8400
  throw new Error("Only .ts files are supported");
8359
8401
  if (targetFilePath.startsWith("./"))
8360
8402
  targetFilePath = targetFilePath.slice(2);
8361
- let src = targetFilePath.startsWith("/") ? targetFilePath : (0, import_path2.join)(projectRoot, targetFilePath);
8362
- if (!(0, import_fs.existsSync)(src))
8403
+ let src = targetFilePath.startsWith("/") ? targetFilePath : join(projectRoot, targetFilePath);
8404
+ if (!fs.existsSync(src))
8363
8405
  throw new Error(
8364
8406
  `Couldn't find "${targetFilePath}" from ${projectRoot}`
8365
8407
  );
8366
8408
  let targetFile;
8409
+ if (!tmpRoot) {
8410
+ const os = process.getBuiltinModule("os");
8411
+ tmpRoot = join(
8412
+ os && typeof os.tmpdir === "function" ? os.tmpdir() : projectRoot,
8413
+ ".ElysiaAutoOpenAPI"
8414
+ );
8415
+ }
8367
8416
  if (targetFilePath.endsWith(".d.ts")) targetFile = targetFilePath;
8368
8417
  else {
8369
- if ((0, import_fs.existsSync)(tmpRoot))
8370
- (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
8371
- (0, import_fs.mkdirSync)(tmpRoot, { recursive: true });
8372
- const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : (0, import_path2.join)(projectRoot, tsconfigPath);
8373
- let extendsRef = (0, import_fs.existsSync)(tsconfig) ? `"extends": "${(0, import_path2.join)(projectRoot, "tsconfig.json")}",` : "";
8374
- let distDir = (0, import_path2.join)(tmpRoot, "dist");
8418
+ if (fs.existsSync(tmpRoot))
8419
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
8420
+ fs.mkdirSync(tmpRoot, { recursive: true });
8421
+ const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : join(projectRoot, tsconfigPath);
8422
+ let extendsRef = fs.existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
8423
+ let distDir = join(tmpRoot, "dist");
8375
8424
  if (typeof process !== "undefined" && process.platform === "win32") {
8376
8425
  extendsRef = extendsRef.replace(/\\/g, "/");
8377
8426
  src = src.replace(/\\/g, "/");
8378
8427
  distDir = distDir.replace(/\\/g, "/");
8379
8428
  }
8380
- (0, import_fs.writeFileSync)(
8381
- (0, import_path2.join)(tmpRoot, "tsconfig.json"),
8429
+ fs.writeFileSync(
8430
+ join(tmpRoot, "tsconfig.json"),
8382
8431
  `{
8383
8432
  ${extendsRef}
8384
8433
  "compilerOptions": ${compilerOptions ? JSON.stringify(compilerOptions) : `{
@@ -8395,36 +8444,46 @@ var fromTypes = (targetFilePath, {
8395
8444
  "include": ["${src}"]
8396
8445
  }`
8397
8446
  );
8398
- (0, import_child_process.spawnSync)(`tsc`, {
8447
+ const child_process = process.getBuiltinModule("child_process");
8448
+ if (!child_process)
8449
+ throw new Error(
8450
+ "[@elysiajs/openapi/gen] `fromTypes` declaration generation require `child_process` module which is not available in this environment"
8451
+ );
8452
+ const { spawnSync } = child_process;
8453
+ if (typeof spawnSync !== "function")
8454
+ throw new Error(
8455
+ "[@elysiajs/openapi/gen] `fromTypes` declaration generation require child_process.spawnSync which is not available in this environment"
8456
+ );
8457
+ spawnSync(`tsc`, {
8399
8458
  shell: true,
8400
8459
  cwd: tmpRoot,
8401
8460
  stdio: silent ? void 0 : "inherit"
8402
8461
  });
8403
8462
  const fileName = targetFilePath.replace(/.tsx$/, ".ts").replace(/.ts$/, ".d.ts");
8404
- targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : (0, import_path2.join)(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? (0, import_path2.join)(
8463
+ targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : join(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? join(
8405
8464
  tmpRoot,
8406
8465
  "dist",
8407
8466
  // remove leading like src or something similar
8408
8467
  fileName.slice(fileName.indexOf("/") + 1)
8409
8468
  );
8410
- let existed = (0, import_fs.existsSync)(targetFile);
8469
+ let existed = fs.existsSync(targetFile);
8411
8470
  if (!existed && !overrideOutputPath) {
8412
- targetFile = (0, import_path2.join)(
8471
+ targetFile = join(
8413
8472
  tmpRoot,
8414
8473
  "dist",
8415
8474
  // use original file name as-is eg. in monorepo
8416
8475
  fileName
8417
8476
  );
8418
- existed = (0, import_fs.existsSync)(targetFile);
8477
+ existed = fs.existsSync(targetFile);
8419
8478
  }
8420
8479
  if (!existed) {
8421
- (0, import_fs.rmSync)((0, import_path2.join)(tmpRoot, "tsconfig.json"));
8480
+ fs.rmSync(join(tmpRoot, "tsconfig.json"));
8422
8481
  console.warn(
8423
8482
  "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
8424
8483
  );
8425
8484
  console.warn("Couldn't find generated declaration file");
8426
- if ((0, import_fs.existsSync)((0, import_path2.join)(tmpRoot, "dist"))) {
8427
- const tempFiles = (0, import_fs.readdirSync)((0, import_path2.join)(tmpRoot, "dist"), {
8485
+ if (fs.existsSync(join(tmpRoot, "dist"))) {
8486
+ const tempFiles = fs.readdirSync(join(tmpRoot, "dist"), {
8428
8487
  recursive: true
8429
8488
  }).filter((x) => x.toString().endsWith(".d.ts")).map((x) => `- ${x}`).join("\n");
8430
8489
  if (tempFiles) {
@@ -8436,15 +8495,15 @@ var fromTypes = (targetFilePath, {
8436
8495
  } else {
8437
8496
  console.warn(
8438
8497
  "reason: root folder doesn't exists",
8439
- (0, import_path2.join)(tmpRoot, "dist")
8498
+ join(tmpRoot, "dist")
8440
8499
  );
8441
8500
  }
8442
8501
  return;
8443
8502
  }
8444
8503
  }
8445
- const declaration = (0, import_fs.readFileSync)(targetFile, "utf8");
8446
- if (!debug && (0, import_fs.existsSync)(tmpRoot))
8447
- (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
8504
+ const declaration = fs.readFileSync(targetFile, "utf8");
8505
+ if (!debug && fs.existsSync(tmpRoot))
8506
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
8448
8507
  let instance = declaration.match(
8449
8508
  instanceName ? new RegExp(`${instanceName}: Elysia<(.*)`, "gs") : matchRoute
8450
8509
  )?.[0];
@@ -8457,35 +8516,7 @@ var fromTypes = (targetFilePath, {
8457
8516
  3
8458
8517
  )
8459
8518
  );
8460
- const routesString = extractRootObjects(
8461
- instance.replace(matchStatus, '"$1":')
8462
- );
8463
- const routes = {};
8464
- for (const route of routesString) {
8465
- let schema = TypeBox(route.replaceAll(/readonly/g, ""));
8466
- if (schema.type !== "object") continue;
8467
- const paths = [];
8468
- while (true) {
8469
- const keys = Object.keys(schema.properties);
8470
- if (keys.length !== 1) break;
8471
- paths.push(keys[0]);
8472
- schema = schema.properties[keys[0]];
8473
- if (!schema?.properties) break;
8474
- }
8475
- const method = paths.pop();
8476
- if (!method) continue;
8477
- const path = "/" + paths.join("/");
8478
- schema = schema.properties;
8479
- if (schema?.response?.type === "object") {
8480
- const responseSchema = {};
8481
- for (const key in schema.response.properties)
8482
- responseSchema[key] = schema.response.properties[key];
8483
- schema.response = responseSchema;
8484
- }
8485
- if (!routes[path]) routes[path] = {};
8486
- routes[path][method.toLowerCase()] = schema;
8487
- }
8488
- return routes;
8519
+ return declarationToJSONSchema(instance.slice(2));
8489
8520
  } catch (error) {
8490
8521
  console.warn(
8491
8522
  "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
@@ -8493,11 +8524,13 @@ var fromTypes = (targetFilePath, {
8493
8524
  console.warn(error);
8494
8525
  return;
8495
8526
  } finally {
8496
- if (!debug && (0, import_fs.existsSync)(tmpRoot))
8497
- (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
8527
+ if (!debug && tmpRoot && fs.existsSync(tmpRoot))
8528
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
8498
8529
  }
8499
8530
  };
8500
8531
  // Annotate the CommonJS export names for ESM import in node:
8501
8532
  0 && (module.exports = {
8533
+ declarationToJSONSchema,
8534
+ extractRootObjects,
8502
8535
  fromTypes
8503
8536
  });
@@ -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;