@elysiajs/openapi 1.3.7 → 1.3.9

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.
@@ -31,29 +31,32 @@ var import_child_process = require("child_process");
31
31
  var matchRoute = /: Elysia<(.*)>/gs;
32
32
  var matchStatus = /(\d{3}):/g;
33
33
  var wrapStatusInQuote = (value) => value.replace(matchStatus, '"$1":');
34
- var exec = (command, cwd) => (0, import_child_process.spawnSync)(command, {
35
- shell: true,
36
- cwd,
37
- stdio: "inherit"
38
- });
39
34
  var fromTypes = (targetFilePath, {
40
35
  tsconfigPath = "tsconfig.json",
41
36
  instanceName,
42
37
  projectRoot = process.cwd(),
43
- overrideOutputPath
38
+ overrideOutputPath,
39
+ debug = false
44
40
  } = {}) => () => {
45
- if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
46
- throw new Error("Only .ts files are supported");
47
41
  const tmpRoot = (0, import_path.join)((0, import_os.tmpdir)(), ".ElysiaAutoOpenAPI");
48
- if ((0, import_fs.existsSync)(tmpRoot))
49
- (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
50
- (0, import_fs.mkdirSync)(tmpRoot, { recursive: true });
51
- const extendsRef = (0, import_fs.existsSync)((0, import_path.join)(projectRoot, "tsconfig.json")) ? `"extends": "${(0, import_path.join)(projectRoot, "tsconfig.json")}",` : "";
52
- if (!(0, import_path.join)(projectRoot, targetFilePath))
53
- throw new Error("Target file does not exist");
54
- (0, import_fs.writeFileSync)(
55
- (0, import_path.join)(tmpRoot, tsconfigPath),
56
- `{
42
+ try {
43
+ if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
44
+ throw new Error("Only .ts files are supported");
45
+ if (targetFilePath.startsWith("./"))
46
+ targetFilePath = targetFilePath.slice(2);
47
+ const src = targetFilePath.startsWith("/") ? targetFilePath : (0, import_path.join)(projectRoot, targetFilePath);
48
+ if (!(0, import_fs.existsSync)(src))
49
+ throw new Error(
50
+ `Couldn't find "${targetFilePath}" from ${projectRoot}`
51
+ );
52
+ if ((0, import_fs.existsSync)(tmpRoot))
53
+ (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
54
+ (0, import_fs.mkdirSync)(tmpRoot, { recursive: true });
55
+ const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : (0, import_path.join)(projectRoot, tsconfigPath);
56
+ const extendsRef = (0, import_fs.existsSync)(tsconfig) ? `"extends": "${(0, import_path.join)(projectRoot, "tsconfig.json")}",` : "";
57
+ (0, import_fs.writeFileSync)(
58
+ (0, import_path.join)(tmpRoot, "tsconfig.json"),
59
+ `{
57
60
  ${extendsRef}
58
61
  "compilerOptions": {
59
62
  "lib": ["ESNext"],
@@ -66,20 +69,49 @@ var fromTypes = (targetFilePath, {
66
69
  "skipDefaultLibCheck": true,
67
70
  "outDir": "./dist"
68
71
  },
69
- "include": ["${(0, import_path.join)(projectRoot, targetFilePath)}"]
72
+ "include": ["${src}"]
70
73
  }`
71
- );
72
- exec(`tsc`, tmpRoot);
73
- try {
74
+ );
75
+ (0, import_child_process.spawnSync)(`tsc`, {
76
+ shell: true,
77
+ cwd: tmpRoot,
78
+ stdio: debug ? "inherit" : void 0
79
+ });
74
80
  const fileName = targetFilePath.replace(/.tsx$/, ".ts").replace(/.ts$/, ".d.ts");
75
- let targetFile = overrideOutputPath?.(tmpRoot) ?? (0, import_path.join)(tmpRoot, "dist", fileName);
76
- {
77
- const _targetFile = (0, import_path.join)(
81
+ let targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : (0, import_path.join)(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? (0, import_path.join)(
82
+ tmpRoot,
83
+ "dist",
84
+ // remove leading like src or something similar
85
+ fileName.slice(fileName.indexOf("/") + 1)
86
+ );
87
+ let existed = (0, import_fs.existsSync)(targetFile);
88
+ if (!existed && overrideOutputPath) {
89
+ targetFile = (0, import_path.join)(
78
90
  tmpRoot,
79
91
  "dist",
80
- fileName.slice(fileName.indexOf("/") + 1)
92
+ // use original file name as-is eg. in monorepo
93
+ fileName
94
+ );
95
+ existed = (0, import_fs.existsSync)(targetFile);
96
+ }
97
+ if (!existed) {
98
+ (0, import_fs.rmSync)((0, import_path.join)(tmpRoot, "tsconfig.json"));
99
+ console.warn(
100
+ "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
81
101
  );
82
- if ((0, import_fs.existsSync)(_targetFile)) targetFile = _targetFile;
102
+ console.warn("Couldn't find generated declaration file");
103
+ if ((0, import_fs.existsSync)((0, import_path.join)(tmpRoot, "dist"))) {
104
+ const tempFiles = (0, import_fs.readdirSync)((0, import_path.join)(tmpRoot, "dist"), {
105
+ recursive: true
106
+ }).filter((x) => x.toString().endsWith(".d.ts")).map((x) => `- ${x}`).join("\n");
107
+ if (tempFiles) {
108
+ console.warn(
109
+ "You can override with `overrideOutputPath` with one of the following:"
110
+ );
111
+ console.warn(tempFiles);
112
+ }
113
+ }
114
+ return;
83
115
  }
84
116
  const declaration = (0, import_fs.readFileSync)(targetFile, "utf8");
85
117
  if ((0, import_fs.existsSync)(tmpRoot))
@@ -133,7 +165,8 @@ var fromTypes = (targetFilePath, {
133
165
  console.warn(error);
134
166
  return;
135
167
  } finally {
136
- (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
168
+ if (!debug && (0, import_fs.existsSync)(tmpRoot))
169
+ (0, import_fs.rmSync)(tmpRoot, { recursive: true, force: true });
137
170
  }
138
171
  };
139
172
  // Annotate the CommonJS export names for ESM import in node:
package/dist/cjs/index.js CHANGED
@@ -347,6 +347,7 @@ function toOpenAPISchema(app, exclude, references) {
347
347
  const hooks = route.hooks ?? {};
348
348
  if (references)
349
349
  for (const reference of references) {
350
+ if (!reference) continue;
350
351
  const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
351
352
  if (!refer) continue;
352
353
  if (!hooks.body && isValidSchema(refer.body))
@@ -89,6 +89,7 @@ function toOpenAPISchema(app, exclude, references) {
89
89
  const hooks = route.hooks ?? {};
90
90
  if (references)
91
91
  for (const reference of references) {
92
+ if (!reference) continue;
92
93
  const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
93
94
  if (!refer) continue;
94
95
  if (!hooks.body && isValidSchema(refer.body))
@@ -24,7 +24,13 @@ interface OpenAPIGeneratorOptions {
24
24
  * Under any circumstance, that Elysia failed to find a correct schema,
25
25
  * Put your own schema in this path
26
26
  */
27
- overrideOutputPath?(tempDir: string): string;
27
+ overrideOutputPath?: string | ((tempDir: string) => string);
28
+ /**
29
+ * don't remove temporary files
30
+ * for debugging purpose
31
+ * @default false
32
+ */
33
+ debug?: boolean;
28
34
  }
29
35
  /**
30
36
  * Auto generate OpenAPI schema from Elysia instance
@@ -39,5 +45,5 @@ export declare const fromTypes: (
39
45
  *
40
46
  * The path must export an Elysia instance
41
47
  */
42
- targetFilePath: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
48
+ targetFilePath: string, { tsconfigPath, instanceName, projectRoot, overrideOutputPath, debug }?: OpenAPIGeneratorOptions) => () => AdditionalReference | undefined;
43
49
  export {};
@@ -4,7 +4,8 @@ import {
4
4
  mkdirSync,
5
5
  writeFileSync,
6
6
  rmSync,
7
- existsSync
7
+ existsSync,
8
+ readdirSync
8
9
  } from "fs";
9
10
  import { TypeBox } from "@sinclair/typemap";
10
11
  import { tmpdir } from "os";
@@ -13,29 +14,32 @@ import { spawnSync } from "child_process";
13
14
  var matchRoute = /: Elysia<(.*)>/gs;
14
15
  var matchStatus = /(\d{3}):/g;
15
16
  var wrapStatusInQuote = (value) => value.replace(matchStatus, '"$1":');
16
- var exec = (command, cwd) => spawnSync(command, {
17
- shell: true,
18
- cwd,
19
- stdio: "inherit"
20
- });
21
17
  var fromTypes = (targetFilePath, {
22
18
  tsconfigPath = "tsconfig.json",
23
19
  instanceName,
24
20
  projectRoot = process.cwd(),
25
- overrideOutputPath
21
+ overrideOutputPath,
22
+ debug = false
26
23
  } = {}) => () => {
27
- if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
28
- throw new Error("Only .ts files are supported");
29
24
  const tmpRoot = join(tmpdir(), ".ElysiaAutoOpenAPI");
30
- if (existsSync(tmpRoot))
31
- rmSync(tmpRoot, { recursive: true, force: true });
32
- mkdirSync(tmpRoot, { recursive: true });
33
- const extendsRef = existsSync(join(projectRoot, "tsconfig.json")) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
34
- if (!join(projectRoot, targetFilePath))
35
- throw new Error("Target file does not exist");
36
- writeFileSync(
37
- join(tmpRoot, tsconfigPath),
38
- `{
25
+ try {
26
+ if (!targetFilePath.endsWith(".ts") && !targetFilePath.endsWith(".tsx"))
27
+ throw new Error("Only .ts files are supported");
28
+ if (targetFilePath.startsWith("./"))
29
+ targetFilePath = targetFilePath.slice(2);
30
+ const src = targetFilePath.startsWith("/") ? targetFilePath : join(projectRoot, targetFilePath);
31
+ if (!existsSync(src))
32
+ throw new Error(
33
+ `Couldn't find "${targetFilePath}" from ${projectRoot}`
34
+ );
35
+ if (existsSync(tmpRoot))
36
+ rmSync(tmpRoot, { recursive: true, force: true });
37
+ mkdirSync(tmpRoot, { recursive: true });
38
+ const tsconfig = tsconfigPath.startsWith("/") ? tsconfigPath : join(projectRoot, tsconfigPath);
39
+ const extendsRef = existsSync(tsconfig) ? `"extends": "${join(projectRoot, "tsconfig.json")}",` : "";
40
+ writeFileSync(
41
+ join(tmpRoot, "tsconfig.json"),
42
+ `{
39
43
  ${extendsRef}
40
44
  "compilerOptions": {
41
45
  "lib": ["ESNext"],
@@ -48,20 +52,49 @@ var fromTypes = (targetFilePath, {
48
52
  "skipDefaultLibCheck": true,
49
53
  "outDir": "./dist"
50
54
  },
51
- "include": ["${join(projectRoot, targetFilePath)}"]
55
+ "include": ["${src}"]
52
56
  }`
53
- );
54
- exec(`tsc`, tmpRoot);
55
- try {
57
+ );
58
+ spawnSync(`tsc`, {
59
+ shell: true,
60
+ cwd: tmpRoot,
61
+ stdio: debug ? "inherit" : void 0
62
+ });
56
63
  const fileName = targetFilePath.replace(/.tsx$/, ".ts").replace(/.ts$/, ".d.ts");
57
- let targetFile = overrideOutputPath?.(tmpRoot) ?? join(tmpRoot, "dist", fileName);
58
- {
59
- const _targetFile = join(
64
+ let targetFile = (overrideOutputPath ? typeof overrideOutputPath === "string" ? overrideOutputPath.startsWith("/") ? overrideOutputPath : join(tmpRoot, "dist", overrideOutputPath) : overrideOutputPath(tmpRoot) : void 0) ?? join(
65
+ tmpRoot,
66
+ "dist",
67
+ // remove leading like src or something similar
68
+ fileName.slice(fileName.indexOf("/") + 1)
69
+ );
70
+ let existed = existsSync(targetFile);
71
+ if (!existed && overrideOutputPath) {
72
+ targetFile = join(
60
73
  tmpRoot,
61
74
  "dist",
62
- fileName.slice(fileName.indexOf("/") + 1)
75
+ // use original file name as-is eg. in monorepo
76
+ fileName
63
77
  );
64
- if (existsSync(_targetFile)) targetFile = _targetFile;
78
+ existed = existsSync(targetFile);
79
+ }
80
+ if (!existed) {
81
+ rmSync(join(tmpRoot, "tsconfig.json"));
82
+ console.warn(
83
+ "[@elysiajs/openapi/gen] Failed to generate OpenAPI schema"
84
+ );
85
+ console.warn("Couldn't find generated declaration file");
86
+ if (existsSync(join(tmpRoot, "dist"))) {
87
+ const tempFiles = readdirSync(join(tmpRoot, "dist"), {
88
+ recursive: true
89
+ }).filter((x) => x.toString().endsWith(".d.ts")).map((x) => `- ${x}`).join("\n");
90
+ if (tempFiles) {
91
+ console.warn(
92
+ "You can override with `overrideOutputPath` with one of the following:"
93
+ );
94
+ console.warn(tempFiles);
95
+ }
96
+ }
97
+ return;
65
98
  }
66
99
  const declaration = readFileSync(targetFile, "utf8");
67
100
  if (existsSync(tmpRoot))
@@ -115,7 +148,8 @@ var fromTypes = (targetFilePath, {
115
148
  console.warn(error);
116
149
  return;
117
150
  } finally {
118
- rmSync(tmpRoot, { recursive: true, force: true });
151
+ if (!debug && existsSync(tmpRoot))
152
+ rmSync(tmpRoot, { recursive: true, force: true });
119
153
  }
120
154
  };
121
155
  export {
package/dist/index.mjs CHANGED
@@ -320,6 +320,7 @@ function toOpenAPISchema(app, exclude, references) {
320
320
  const hooks = route.hooks ?? {};
321
321
  if (references)
322
322
  for (const reference of references) {
323
+ if (!reference) continue;
323
324
  const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
324
325
  if (!refer) continue;
325
326
  if (!hooks.body && isValidSchema(refer.body))
package/dist/openapi.mjs CHANGED
@@ -61,6 +61,7 @@ function toOpenAPISchema(app, exclude, references) {
61
61
  const hooks = route.hooks ?? {};
62
62
  if (references)
63
63
  for (const reference of references) {
64
+ if (!reference) continue;
64
65
  const refer = reference[route.path]?.[method] ?? reference[getLoosePath(route.path)]?.[method];
65
66
  if (!refer) continue;
66
67
  if (!hooks.body && isValidSchema(refer.body))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elysiajs/openapi",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "Plugin for Elysia to auto-generate API documentation",
5
5
  "author": {
6
6
  "name": "saltyAom",