swagger-autogen-ast 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Anthony Greco
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # swagger-autogen-ast
2
+
3
+ A zero-config OpenAPI 3.0 generator for Express. The AST-based spiritual successor to `swagger-autogen` with automatic type inference.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
7
+
8
+ ## Overview
9
+
10
+ **swagger-autogen-ast** automates the creation of OpenAPI 3.0 specifications by statically analyzing your TypeScript source code.
11
+
12
+ Unlike other tools that require extensive JSDoc decorators, this library uses the **TypeScript Compiler API (AST)** to crawl your route files. It follows your `router.use()` imports to build a complete path map and automatically infers request bodies, query parameters, and response schemas directly from your TypeScript interfaces and logic.
13
+
14
+ ## Features
15
+
16
+ - **AST-Powered Crawling:** Recursively follows imports in `router.use()` and controller functions to analyze code across files.
17
+ - **Deep Schema Inference:** Converts TypeScript Interfaces, Enums, Unions, Intersections, and `Date` objects into OpenAPI Schemas.
18
+ - **Request Body & Query Detection:**
19
+ - Infers schema from `req.body` and `req.query` type assertions (`as MyType`).
20
+ - Infers schema from Express Generics: `Request<{}, {}, MyBodyType>`.
21
+ - **Response Body Inference:** automatically generates schemas from `res.json(data)` and `res.send(data)` calls.
22
+ - **Smart Path Resolution:** Resolves paths from string literals (`"/users"`) as well as constants and variables (`USER_ROUTE`).
23
+ - **Automatic Status Codes:** Scans controller logic to automatically register response codes.
24
+ - **Comment Overrides:** Supports JSDoc and `#swagger` inline comments for when you need manual control.
25
+
26
+ ## Installation
27
+
28
+ **Note**: Not published to npm yet!
29
+
30
+ ```bash
31
+ npm install swagger-autogen-ast --save-dev
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ There are two ways to use this generator:
37
+
38
+ ### 1. Via Command Line (Recommended)
39
+
40
+ The easiest way is to run the tool directly against your project. The generator will automatically find your `tsconfig.json`.
41
+
42
+ ```bash
43
+ npx swagger-autogen-ast <entryFile> <outputFile>
44
+ ```
45
+
46
+ **Example:**
47
+
48
+ ```bash
49
+ npx swagger-autogen-ast ./src/index.ts ./swagger.json
50
+ ```
51
+
52
+ ### 2. Via Programmatic Script
53
+
54
+ For more control over the configuration, such as defining API info and servers, you can create a generator script (e.g., `generate-swagger.ts`):
55
+
56
+ ```typescript
57
+ import { generateOpenApi } from "swagger-autogen-ast";
58
+
59
+ const options = {
60
+ // Point to your main application entry file (e.g., app.ts or index.ts)
61
+ entryFile: "./src/index.ts",
62
+ outputFile: "./swagger.json",
63
+ // Optional: Auto-detected if not provided
64
+ tsconfigPath: "./tsconfig.json",
65
+ info: {
66
+ title: "My API",
67
+ version: "1.0.0",
68
+ description: "Generated via AST analysis",
69
+ },
70
+ servers: [
71
+ {
72
+ url: "http://localhost:3000",
73
+ description: "Local server",
74
+ },
75
+ ],
76
+ };
77
+
78
+ generateOpenApi(options);
79
+ ```
80
+
81
+ Then run the script:
82
+
83
+ ```bash
84
+ npx tsx generate-swagger.ts
85
+ ```
86
+
87
+ ## Automatic Inference
88
+
89
+ The primary goal of this library is to minimize documentation overhead. It reads your code so you don't have to write YAML.
90
+
91
+ ### 1. Request Body & Query Params via Generics
92
+
93
+ The cleanest way to document your API is using standard Express generics. The generator reads the **3rd (Body)** and **4th (Query)** generic arguments.
94
+
95
+ ```typescript
96
+ import { Request, Response } from "express";
97
+
98
+ interface CreateUserBody {
99
+ username: string;
100
+ email: string;
101
+ }
102
+
103
+ interface UserQuery {
104
+ includeProfile?: string;
105
+ }
106
+
107
+ // AST automatically detects:
108
+ // 1. Body schema from CreateUserBody
109
+ // 2. Query parameters from UserQuery
110
+ router.post(
111
+ "/users",
112
+ (req: Request<{}, {}, CreateUserBody, UserQuery>, res) => {
113
+ // ...
114
+ },
115
+ );
116
+ ```
117
+
118
+ ### 2. Request & Query via Type Assertion
119
+
120
+ If you don't use generics, the generator detects type assertions (`as Type`) on `req.body` and `req.query` within the function body.
121
+
122
+ ```typescript
123
+ router.put("/users/:id", (req, res) => {
124
+ // Infers request body schema
125
+ const payload = req.body as UpdateUser;
126
+
127
+ // Infers query parameters
128
+ const { filter } = req.query as UserSearchQuery;
129
+
130
+ res.send("Updated");
131
+ });
132
+ ```
133
+
134
+ ### 3. Response Bodies & Status Codes
135
+
136
+ The analyzer scans the function body for response methods. It matches standard Express patterns to generate the `responses` object, **including the schema of the data sent back**.
137
+
138
+ ```typescript
139
+ router.get("/admin", (req, res) => {
140
+ if (!isAdmin) {
141
+ return res.status(403).send(); // Adds '403: Forbidden' to spec
142
+ }
143
+
144
+ try {
145
+ const user: UserProfile = await getUser();
146
+ // Adds '200: OK' with schema generated from 'UserProfile'
147
+ return res.status(200).json(user);
148
+ } catch (e) {
149
+ return res.sendStatus(500); // Adds '500: Internal Server Error'
150
+ }
151
+ });
152
+ ```
153
+
154
+ ## Manual Overrides
155
+
156
+ You can control specific endpoint details using JSDoc (above the route) or inline `#swagger` comments (inside the handler).
157
+
158
+ ### Inline Configuration (`#swagger`)
159
+
160
+ This is useful for adding tags or descriptions directly inside the handler logic, keeping related code together.
161
+
162
+ ```typescript
163
+ // Works with imported handlers too!
164
+ router.post("/upload", (req, res) => {
165
+ // #swagger.tags = ["File Operations"]
166
+ // #swagger.summary = "Upload a file"
167
+ // #swagger.description = "Accepts multipart/form-data."
168
+ // #swagger.deprecated = true
169
+ // #swagger.operationId = "uploadFileHandler"
170
+
171
+ res.status(200).send();
172
+ });
173
+ ```
174
+
175
+ ### JSDoc Support
176
+
177
+ Standard JSDoc tags placed above the route definition are also parsed.
178
+
179
+ ```typescript
180
+ /**
181
+ * @summary Get User
182
+ * @description Fetch a user by their unique ID
183
+ * @tags Users, Public
184
+ */
185
+ router.get("/user/:id", handler);
186
+ ```
187
+
188
+ ## How It Works
189
+
190
+ 1. **Entry Point:** The generator starts at your `entryFile`.
191
+ 2. **Recursive Crawl:** It looks for `router.use()` calls. If a router is imported from another file, the analyzer jumps to that file, appending the path prefix.
192
+ 3. **Controller Navigation:** If a route handler is defined in a separate file (e.g., `import { handler } from './controllers'`), the analyzer jumps to that file to scan for logic and types.
193
+ 4. **Circular Safety:** It maintains a stack of visited files to handle circular dependencies gracefully.
194
+ 5. **AST Analysis:** inside every route handler:
195
+ - It extracts JSDoc comments.
196
+ - It scans the function body for `#swagger` comments.
197
+ - It scans for `res.status`, `res.json`, and `res.send` calls to infer responses.
198
+ - It analyzes `req` usage for type assertions.
199
+ 6. **Schema Generation:** When a TypeScript type is encountered, `SchemaBuilder` recursively generates a JSON schema, handling:
200
+ - Primitive types & Dates
201
+ - Arrays, Tuples, & Enums
202
+ - Nested Objects
203
+ - Union Types (`string | number` becomes `oneOf` / `enum`)
204
+ - Intersection Types (`TypeA & TypeB` becomes `allOf`)
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * -------------------------------------------------------------------------
4
+ * Types & Interfaces
5
+ * -------------------------------------------------------------------------
6
+ */
7
+ interface GeneratorOptions {
8
+ entryFile: string;
9
+ outputFile: string;
10
+ tsconfigPath?: string | undefined;
11
+ info?: OpenApiInfo | undefined;
12
+ servers?: OpenApiServer[] | undefined;
13
+ }
14
+ interface OpenApiInfo {
15
+ title: string;
16
+ version: string;
17
+ description?: string | undefined;
18
+ }
19
+ interface OpenApiServer {
20
+ url: string;
21
+ description?: string | undefined;
22
+ }
23
+ /**
24
+ * -------------------------------------------------------------------------
25
+ * Main Logic
26
+ * -------------------------------------------------------------------------
27
+ */
28
+ export declare function generateOpenApi(options: GeneratorOptions): void;
29
+ export {};
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAOA;;;;GAIG;AAEH,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;CACvC;AAED,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AA+5BD;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,QA4BxD"}
package/dist/index.js ADDED
@@ -0,0 +1,806 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import ts from "typescript";
5
+ import { fileURLToPath } from "url";
6
+ /**
7
+ * -------------------------------------------------------------------------
8
+ * AST & Schema Analysis
9
+ * -------------------------------------------------------------------------
10
+ */
11
+ class SchemaBuilder {
12
+ typeChecker;
13
+ definitions = {};
14
+ constructor(typeChecker) {
15
+ this.typeChecker = typeChecker;
16
+ }
17
+ generateSchema(nodeOrType) {
18
+ const type = "kind" in nodeOrType
19
+ ? this.typeChecker.getTypeAtLocation(nodeOrType)
20
+ : nodeOrType;
21
+ return this.typeToSchema(type);
22
+ }
23
+ typeToSchema(type, depth = 0) {
24
+ if (depth > 10)
25
+ return {};
26
+ // Unwrap Promise<T> to T
27
+ const unwrappedPromise = this.unwrapPromise(type);
28
+ if (unwrappedPromise) {
29
+ return this.typeToSchema(unwrappedPromise, depth);
30
+ }
31
+ const typeNodeString = this.typeChecker.typeToString(type);
32
+ // Primitives
33
+ if (typeNodeString === "string")
34
+ return { type: "string" };
35
+ if (typeNodeString === "number")
36
+ return { type: "number" };
37
+ if (typeNodeString === "boolean")
38
+ return { type: "boolean" };
39
+ if (typeNodeString === "any")
40
+ return {};
41
+ if (typeNodeString === "void")
42
+ return {};
43
+ if (typeNodeString === "undefined" || typeNodeString === "null") {
44
+ return { type: "string", format: "nullable" };
45
+ }
46
+ // Handle Date objects explicitly
47
+ const symbol = type.getSymbol();
48
+ if (symbol && symbol.getName() === "Date") {
49
+ return { type: "string", format: "date-time" };
50
+ }
51
+ // Handle Arrays
52
+ if (this.isArrayType(type)) {
53
+ const typeArgs = type.typeArguments;
54
+ const elementType = typeArgs && typeArgs.length > 0 ? typeArgs[0] : null;
55
+ return {
56
+ type: "array",
57
+ items: elementType ? this.typeToSchema(elementType, depth + 1) : {},
58
+ };
59
+ }
60
+ // Handle Enums (Check flags instead of isEnum method)
61
+ const flags = type.getFlags();
62
+ if (flags & ts.TypeFlags.Enum || flags & ts.TypeFlags.EnumLiteral) {
63
+ if (symbol &&
64
+ symbol.valueDeclaration &&
65
+ ts.isEnumDeclaration(symbol.valueDeclaration)) {
66
+ const enumValues = [];
67
+ symbol.valueDeclaration.members.forEach((member) => {
68
+ if (member.initializer) {
69
+ if (ts.isStringLiteral(member.initializer)) {
70
+ enumValues.push(member.initializer.text);
71
+ }
72
+ else if (ts.isNumericLiteral(member.initializer)) {
73
+ enumValues.push(Number(member.initializer.text));
74
+ }
75
+ }
76
+ });
77
+ if (enumValues.length > 0) {
78
+ const isString = typeof enumValues[0] === "string";
79
+ return { type: isString ? "string" : "number", enum: enumValues };
80
+ }
81
+ }
82
+ }
83
+ // Handle Unions
84
+ if (type.isUnion()) {
85
+ const types = type.types.map((t) => this.typeToSchema(t, depth + 1));
86
+ const isAllLiteral = type.types.every((t) => t.isStringLiteral());
87
+ if (isAllLiteral) {
88
+ return {
89
+ type: "string",
90
+ enum: type.types.map((t) => t.value),
91
+ };
92
+ }
93
+ return { anyOf: types };
94
+ }
95
+ // Handle Intersections
96
+ if (type.isIntersection()) {
97
+ const types = type.types.map((t) => this.typeToSchema(t, depth + 1));
98
+ return { allOf: types };
99
+ }
100
+ // Handle Objects / Interfaces / Classes / Type Aliases
101
+ if (type.isClassOrInterface() ||
102
+ type.aliasSymbol ||
103
+ type.getFlags() & ts.TypeFlags.Object) {
104
+ const objectSymbol = type.getSymbol() || type.aliasSymbol;
105
+ if (objectSymbol) {
106
+ const name = objectSymbol.getName();
107
+ // Treat complex library types as generic objects to prevent recursion hell
108
+ if (name === "ReactElement" ||
109
+ name === "CSSProperties" ||
110
+ name === "ReactPortal" ||
111
+ name === "Element" || // DOM Element
112
+ name === "HTMLElement" ||
113
+ name === "Buffer" ||
114
+ name === "Readable") {
115
+ return { type: "object", description: name };
116
+ }
117
+ // Filter out internal/standard types
118
+ if (name !== "Object" &&
119
+ name !== "Promise" &&
120
+ name !== "__type" &&
121
+ name !== "Array" &&
122
+ name !== "Request" &&
123
+ name !== "Response" &&
124
+ name !== "Function") {
125
+ if (this.definitions[name]) {
126
+ return { $ref: `#/components/schemas/${name}` };
127
+ }
128
+ // Reserve to prevent cycles
129
+ this.definitions[name] = {};
130
+ const definition = this.extractObjectDefinition(type, depth);
131
+ this.definitions[name] = definition;
132
+ return { $ref: `#/components/schemas/${name}` };
133
+ }
134
+ }
135
+ return this.extractObjectDefinition(type, depth);
136
+ }
137
+ return { type: "object" };
138
+ }
139
+ extractObjectDefinition(type, depth) {
140
+ const props = type.getProperties();
141
+ const properties = {};
142
+ const required = [];
143
+ for (const prop of props) {
144
+ const propName = prop.getName();
145
+ // Skip internal symbols
146
+ if (propName.startsWith("__")) {
147
+ continue;
148
+ }
149
+ const declaration = prop.valueDeclaration ||
150
+ (prop.declarations && prop.declarations.length > 0
151
+ ? prop.declarations[0]
152
+ : undefined);
153
+ if (!declaration)
154
+ continue;
155
+ // Check parent symbol to exclude standard Object methods (toString, valueOf, etc.)
156
+ // We look at the declaration's parent (Interface/Class Declaration)
157
+ if (declaration.parent) {
158
+ const parentNode = declaration.parent;
159
+ if (ts.isInterfaceDeclaration(parentNode) ||
160
+ ts.isClassDeclaration(parentNode)) {
161
+ const parentName = parentNode.name?.text;
162
+ if (parentName === "Object" || parentName === "Function") {
163
+ continue;
164
+ }
165
+ }
166
+ }
167
+ const propType = this.typeChecker.getTypeOfSymbolAtLocation(prop, declaration);
168
+ // Skip Functions/Methods
169
+ if (propType.getCallSignatures().length > 0) {
170
+ continue;
171
+ }
172
+ const typeStr = this.typeChecker.typeToString(propType);
173
+ if (typeStr === "Function" || typeStr.includes("=>")) {
174
+ continue;
175
+ }
176
+ const isOptional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0;
177
+ if (!isOptional)
178
+ required.push(propName);
179
+ properties[propName] = this.typeToSchema(propType, depth + 1);
180
+ const docComment = ts.displayPartsToString(prop.getDocumentationComment(this.typeChecker));
181
+ if (docComment) {
182
+ properties[propName].description = docComment;
183
+ }
184
+ }
185
+ return {
186
+ type: "object",
187
+ properties: Object.keys(properties).length > 0 ? properties : undefined,
188
+ required: required.length > 0 ? required : undefined,
189
+ };
190
+ }
191
+ isArrayType(type) {
192
+ if (this.typeChecker.isTupleType(type))
193
+ return true;
194
+ const symbol = type.getSymbol();
195
+ if (!symbol)
196
+ return false;
197
+ const name = symbol.getName();
198
+ return name === "Array" || name === "ReadonlyArray";
199
+ }
200
+ unwrapPromise(type) {
201
+ const symbol = type.getSymbol();
202
+ if (symbol && symbol.getName() === "Promise") {
203
+ const typeArgs = type.typeArguments;
204
+ if (typeArgs && typeArgs.length > 0) {
205
+ return typeArgs[0];
206
+ }
207
+ }
208
+ return null;
209
+ }
210
+ }
211
+ /**
212
+ * -------------------------------------------------------------------------
213
+ * Route Analysis
214
+ * -------------------------------------------------------------------------
215
+ */
216
+ class RouteAnalyzer {
217
+ program;
218
+ checker;
219
+ schemaBuilder;
220
+ paths = {};
221
+ constructor(options) {
222
+ const compilerOptions = options.tsconfigPath
223
+ ? this.loadTsConfig(options.tsconfigPath)
224
+ : {
225
+ allowJs: true,
226
+ module: ts.ModuleKind.CommonJS,
227
+ target: ts.ScriptTarget.ES2020,
228
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
229
+ esModuleInterop: true,
230
+ };
231
+ console.log(`Using TS Config: ${options.tsconfigPath || "Default"}`);
232
+ // createProgram will resolve imported files automatically
233
+ this.program = ts.createProgram([options.entryFile], compilerOptions);
234
+ this.checker = this.program.getTypeChecker();
235
+ this.schemaBuilder = new SchemaBuilder(this.checker);
236
+ }
237
+ loadTsConfig(configPath) {
238
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
239
+ if (configFile.error) {
240
+ console.error("Error reading tsconfig:", configFile.error);
241
+ return {};
242
+ }
243
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
244
+ return parsedConfig.options;
245
+ }
246
+ analyze(entryFile) {
247
+ const entrySourceFile = this.program.getSourceFile(entryFile);
248
+ if (!entrySourceFile) {
249
+ throw new Error("Entry file not found in program.");
250
+ }
251
+ // Start stack with entry file to prevent immediate self-recursion
252
+ this.visitNode(entrySourceFile, "", new Set([entrySourceFile.fileName]));
253
+ return {
254
+ paths: this.paths,
255
+ schemas: this.schemaBuilder.definitions,
256
+ };
257
+ }
258
+ visitNode(node, basePath, stack) {
259
+ if (ts.isCallExpression(node)) {
260
+ this.handleCallExpression(node, basePath, stack);
261
+ }
262
+ ts.forEachChild(node, (n) => this.visitNode(n, basePath, stack));
263
+ }
264
+ handleCallExpression(node, basePath, stack) {
265
+ const propAccess = node.expression;
266
+ if (!ts.isPropertyAccessExpression(propAccess))
267
+ return;
268
+ const methodName = propAccess.name.text.toLowerCase();
269
+ const args = node.arguments;
270
+ if (args.length < 2)
271
+ return;
272
+ // Handle router.use()
273
+ if (methodName === "use") {
274
+ const pathArg = args[0];
275
+ const handlerArg = args[1];
276
+ if (!pathArg || !handlerArg)
277
+ return;
278
+ const usePath = this.resolvePathValue(pathArg) || "/";
279
+ // Follow the router import
280
+ const targetSourceFile = this.resolveHandlerSourceFile(handlerArg);
281
+ if (targetSourceFile) {
282
+ const fileName = targetSourceFile.fileName;
283
+ if (stack.has(fileName))
284
+ return;
285
+ const newBasePath = path.join(basePath, usePath).replace(/\\/g, "/");
286
+ const nextStack = new Set(stack).add(fileName);
287
+ this.visitNode(targetSourceFile, newBasePath, nextStack);
288
+ }
289
+ return;
290
+ }
291
+ const validMethods = [
292
+ "get",
293
+ "post",
294
+ "put",
295
+ "delete",
296
+ "patch",
297
+ "options",
298
+ "head",
299
+ ];
300
+ if (!validMethods.includes(methodName))
301
+ return;
302
+ // Extract Path
303
+ const pathArg = args[0];
304
+ if (!pathArg)
305
+ return;
306
+ // Resolve path, even if it is a variable/constant
307
+ const routePath = this.resolvePathValue(pathArg);
308
+ if (!routePath)
309
+ return; // Could not resolve path
310
+ let fullPath = path.join(basePath, routePath).replace(/\\/g, "/");
311
+ if (!fullPath.startsWith("/"))
312
+ fullPath = "/" + fullPath;
313
+ // Replace :param with {param}
314
+ const openApiPath = fullPath.replace(/:([a-zA-Z0-9_]+)/g, "{$1}");
315
+ // Extract Handler
316
+ // We grab the last argument that looks like a function or identifier
317
+ const handlerArg = args[args.length - 1];
318
+ if (!handlerArg)
319
+ return;
320
+ // Resolve the actual handler definition (following imports)
321
+ const handlerNode = this.resolveHandlerNode(handlerArg);
322
+ if (handlerNode) {
323
+ if (ts.isFunctionExpression(handlerNode) ||
324
+ ts.isArrowFunction(handlerNode) ||
325
+ ts.isFunctionDeclaration(handlerNode)) {
326
+ this.addOperation(openApiPath, methodName, handlerNode, node);
327
+ }
328
+ }
329
+ }
330
+ resolvePathValue(node) {
331
+ // 1. Literal string
332
+ if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
333
+ return node.text;
334
+ }
335
+ // 2. Variable / Constant
336
+ if (ts.isIdentifier(node)) {
337
+ const type = this.checker.getTypeAtLocation(node);
338
+ if (type.isStringLiteral()) {
339
+ return type.value;
340
+ }
341
+ }
342
+ return undefined;
343
+ }
344
+ /**
345
+ * Given a node (identifier or expression), follows imports/aliases to find
346
+ * the original SourceFile where it is defined.
347
+ */
348
+ resolveHandlerSourceFile(node) {
349
+ let symbol = this.checker.getSymbolAtLocation(node);
350
+ if (!symbol)
351
+ return undefined;
352
+ if (symbol.flags & ts.SymbolFlags.Alias) {
353
+ symbol = this.checker.getAliasedSymbol(symbol);
354
+ }
355
+ const decl = symbol.declarations?.[0];
356
+ if (!decl)
357
+ return undefined;
358
+ const sourceFile = decl.getSourceFile();
359
+ if (sourceFile.isDeclarationFile ||
360
+ sourceFile.fileName.includes("node_modules")) {
361
+ return undefined;
362
+ }
363
+ return sourceFile;
364
+ }
365
+ /**
366
+ * Follows imports to find the actual Function/ArrowFunction declaration.
367
+ */
368
+ resolveHandlerNode(node) {
369
+ if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
370
+ return node;
371
+ }
372
+ if (ts.isIdentifier(node)) {
373
+ let symbol = this.checker.getSymbolAtLocation(node);
374
+ if (symbol) {
375
+ if (symbol.flags & ts.SymbolFlags.Alias) {
376
+ symbol = this.checker.getAliasedSymbol(symbol);
377
+ }
378
+ const decl = symbol.valueDeclaration ||
379
+ (symbol.declarations && symbol.declarations[0]);
380
+ if (decl) {
381
+ if (ts.isFunctionDeclaration(decl) ||
382
+ ts.isFunctionExpression(decl) ||
383
+ ts.isArrowFunction(decl)) {
384
+ return decl;
385
+ }
386
+ // Handle: const handler = (req, res) => ...
387
+ if (ts.isVariableDeclaration(decl) && decl.initializer) {
388
+ if (ts.isArrowFunction(decl.initializer) ||
389
+ ts.isFunctionExpression(decl.initializer)) {
390
+ return decl.initializer;
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ return undefined;
397
+ }
398
+ addOperation(routePath, method, handler, callNode) {
399
+ if (!this.paths[routePath])
400
+ this.paths[routePath] = {};
401
+ const operation = {
402
+ responses: {
403
+ "200": { description: "OK" },
404
+ },
405
+ parameters: [],
406
+ tags: [],
407
+ };
408
+ // 1. Extract JSDoc from the `router.get(...)` call itself
409
+ const callJSDoc = this.extractJSDoc(callNode);
410
+ this.mergeMetadata(operation, callJSDoc);
411
+ // 2. Extract JSDoc from the handler function definition (follow imports)
412
+ const handlerJSDoc = this.extractJSDoc(handler);
413
+ this.mergeMetadata(operation, handlerJSDoc);
414
+ // 3. Scan Function Body for #swagger comments
415
+ if (handler.body && ts.isBlock(handler.body)) {
416
+ this.scanSwaggerComments(handler.body, operation);
417
+ }
418
+ // 4. Path Parameters
419
+ const pathParams = routePath.match(/{([^}]+)}/g);
420
+ if (pathParams) {
421
+ pathParams.forEach((p) => {
422
+ const paramName = p.replace(/[{}]/g, "");
423
+ if (!operation.parameters.some((ex) => ex.name === paramName && ex.in === "path")) {
424
+ operation.parameters.push({
425
+ name: paramName,
426
+ in: "path",
427
+ required: true,
428
+ schema: { type: "string" },
429
+ });
430
+ }
431
+ });
432
+ }
433
+ // 5. Types (Request<Params, Res, Body, Query>)
434
+ if (handler.parameters.length >= 2) {
435
+ const reqParam = handler.parameters[0];
436
+ if (!reqParam)
437
+ return;
438
+ const reqType = this.checker.getTypeAtLocation(reqParam);
439
+ if (reqType.typeArguments) {
440
+ const typeArgs = reqType.typeArguments;
441
+ // Index 2: Request Body
442
+ if (typeArgs[2]) {
443
+ const bodySchema = this.schemaBuilder.generateSchema(typeArgs[2]);
444
+ if (this.isValidSchema(bodySchema)) {
445
+ operation.requestBody = {
446
+ content: {
447
+ "application/json": { schema: bodySchema },
448
+ },
449
+ };
450
+ }
451
+ }
452
+ // Index 3: Query Params
453
+ if (typeArgs[3]) {
454
+ const queryProps = typeArgs[3].getProperties();
455
+ queryProps.forEach((prop) => {
456
+ const propName = prop.getName();
457
+ if (!operation.parameters.some((p) => p.name === propName && p.in === "query")) {
458
+ operation.parameters.push({
459
+ name: propName,
460
+ in: "query",
461
+ schema: { type: "string" }, // Defaults to string, refinement hard without deep analysis
462
+ });
463
+ }
464
+ });
465
+ }
466
+ }
467
+ }
468
+ // 6. Analyze Function Body for usage (recursive)
469
+ if (handler.body) {
470
+ this.scanBodyUsage(handler.body, operation, handler.parameters[0]?.name?.getText(), handler.parameters[1]?.name?.getText());
471
+ }
472
+ this.paths[routePath][method] = operation;
473
+ }
474
+ isValidSchema(schema) {
475
+ return ((Object.keys(schema).length > 0 &&
476
+ schema.type !== "object" &&
477
+ Object.keys(schema).length > 1) ||
478
+ Object.keys(schema.properties || {}).length > 0 ||
479
+ !!schema.$ref ||
480
+ !!schema.allOf ||
481
+ !!schema.anyOf ||
482
+ !!schema.oneOf);
483
+ }
484
+ scanBodyUsage(node, operation, reqName, resName, visited = new Set()) {
485
+ if ((!reqName && !resName) || visited.has(node))
486
+ return;
487
+ visited.add(node);
488
+ const visit = (n) => {
489
+ // 1. Detect Response Status: res.status(404) or res.sendStatus(500)
490
+ if (resName && ts.isCallExpression(n)) {
491
+ const propAccess = n.expression;
492
+ if (ts.isPropertyAccessExpression(propAccess)) {
493
+ const expressionText = propAccess.expression.getText();
494
+ const methodText = propAccess.name.text;
495
+ // Check simple: res.sendStatus(code)
496
+ if (expressionText === resName && methodText === "sendStatus") {
497
+ const arg = n.arguments[0];
498
+ if (arg && ts.isNumericLiteral(arg)) {
499
+ this.addResponse(operation, arg.text);
500
+ }
501
+ }
502
+ // Check chain: res.status(code)
503
+ if (expressionText === resName && methodText === "status") {
504
+ const arg = n.arguments[0];
505
+ if (arg && ts.isNumericLiteral(arg)) {
506
+ this.addResponse(operation, arg.text);
507
+ }
508
+ }
509
+ // Check response body: res.json(data) or res.send(data)
510
+ if ((methodText === "json" || methodText === "send") &&
511
+ n.arguments.length > 0) {
512
+ const arg = n.arguments[0];
513
+ if (arg) {
514
+ const responseType = this.checker.getTypeAtLocation(arg);
515
+ const schema = this.schemaBuilder.generateSchema(responseType);
516
+ if (!operation.responses["200"]) {
517
+ operation.responses["200"] = { description: "OK" };
518
+ }
519
+ if (!operation.responses["200"].content) {
520
+ operation.responses["200"].content = {
521
+ "application/json": { schema },
522
+ };
523
+ }
524
+ }
525
+ }
526
+ }
527
+ }
528
+ // 2. Handle Casts: const body = req.body as Type; including chained `as` expressions
529
+ if (ts.isAsExpression(n) || ts.isTypeAssertionExpression(n)) {
530
+ // Determine the effective type node (the one after the outermost `as`)
531
+ let typeNode = n.type;
532
+ // Walk down nested as-expressions to find the underlying expression
533
+ let expr = n.expression;
534
+ while (ts.isAsExpression(expr) || ts.isTypeAssertionExpression(expr)) {
535
+ expr = expr.expression;
536
+ }
537
+ if (ts.isPropertyAccessExpression(expr)) {
538
+ // req.body as Type
539
+ if (reqName &&
540
+ expr.expression.getText() === reqName &&
541
+ expr.name.text === "body") {
542
+ let schema = {};
543
+ try {
544
+ const t = typeNode
545
+ ? this.checker.getTypeFromTypeNode(typeNode)
546
+ : this.checker.getTypeAtLocation(n);
547
+ schema = this.schemaBuilder.generateSchema(t);
548
+ }
549
+ catch (e) {
550
+ schema = this.schemaBuilder.generateSchema(n.type);
551
+ }
552
+ if (this.isValidSchema(schema)) {
553
+ operation.requestBody = {
554
+ content: { "application/json": { schema: schema } },
555
+ };
556
+ }
557
+ }
558
+ // req.query as Type (support chained as: req.query as unknown as MyQuery)
559
+ if (reqName &&
560
+ expr.expression.getText() === reqName &&
561
+ expr.name.text === "query") {
562
+ let queryType;
563
+ if (typeNode) {
564
+ try {
565
+ queryType = this.checker.getTypeFromTypeNode(typeNode);
566
+ }
567
+ catch (e) {
568
+ queryType = this.checker.getTypeAtLocation(n.type);
569
+ }
570
+ }
571
+ else {
572
+ queryType = this.checker.getTypeAtLocation(n);
573
+ }
574
+ if (queryType) {
575
+ const props = queryType.getProperties();
576
+ props.forEach((prop) => {
577
+ const propName = prop.getName();
578
+ if (!operation.parameters.some((p) => p.name === propName && p.in === "query")) {
579
+ operation.parameters.push({
580
+ name: propName,
581
+ in: "query",
582
+ schema: { type: "string" },
583
+ required: !((prop.getFlags() & ts.SymbolFlags.Optional) !==
584
+ 0),
585
+ });
586
+ }
587
+ });
588
+ }
589
+ }
590
+ }
591
+ }
592
+ ts.forEachChild(n, visit);
593
+ };
594
+ visit(node);
595
+ }
596
+ addResponse(operation, code) {
597
+ if (!operation.responses[code]) {
598
+ const descriptions = {
599
+ "200": "OK",
600
+ "201": "Created",
601
+ "204": "No Content",
602
+ "400": "Bad Request",
603
+ "401": "Unauthorized",
604
+ "403": "Forbidden",
605
+ "404": "Not Found",
606
+ "500": "Internal Server Error",
607
+ };
608
+ operation.responses[code] = {
609
+ description: descriptions[code] || "Status " + code,
610
+ };
611
+ }
612
+ }
613
+ scanSwaggerComments(body, operation) {
614
+ const sourceFile = body.getSourceFile();
615
+ const fullText = sourceFile.getFullText();
616
+ const visitStatement = (node) => {
617
+ const ranges = ts.getLeadingCommentRanges(fullText, node.pos);
618
+ if (ranges) {
619
+ for (const range of ranges) {
620
+ const comment = fullText.substring(range.pos, range.end);
621
+ this.parseSwaggerComment(comment, operation);
622
+ }
623
+ }
624
+ };
625
+ body.statements.forEach(visitStatement);
626
+ }
627
+ parseSwaggerComment(comment, operation) {
628
+ const content = comment
629
+ .replace(/^\/\//, "")
630
+ .replace(/^\/\*/, "")
631
+ .replace(/\*\/$/, "")
632
+ .trim();
633
+ const match = content.match(/#swagger\.([\w\.]+)\s*=\s*(.+)/);
634
+ if (match) {
635
+ const keyPath = match[1];
636
+ const valueStr = match[2];
637
+ if (!keyPath || !valueStr)
638
+ return;
639
+ try {
640
+ const value = new Function(`return ${valueStr}`)();
641
+ if (keyPath === "tags") {
642
+ // Merge tags instead of replacing so JSDoc + inline tags both apply
643
+ const existing = operation.tags || [];
644
+ if (Array.isArray(value)) {
645
+ operation.tags = Array.from(new Set([...existing, ...value]));
646
+ }
647
+ else if (typeof value === "string") {
648
+ operation.tags = Array.from(new Set([...existing, value]));
649
+ }
650
+ }
651
+ else if (keyPath === "description")
652
+ operation.description = value;
653
+ else if (keyPath === "summary")
654
+ operation.summary = value;
655
+ else if (keyPath === "deprecated")
656
+ operation.deprecated = !!value;
657
+ else if (keyPath === "operationId")
658
+ operation.operationId = value;
659
+ else
660
+ this.setDeepValue(operation, keyPath, value);
661
+ }
662
+ catch (e) {
663
+ console.warn(`Failed to parse swagger comment: ${content}`, e);
664
+ }
665
+ }
666
+ }
667
+ setDeepValue(obj, path, value) {
668
+ const parts = path.split(".");
669
+ let current = obj;
670
+ for (let i = 0; i < parts.length - 1; i++) {
671
+ const part = parts[i];
672
+ if (part && !current[part])
673
+ current[part] = {};
674
+ if (part)
675
+ current = current[part];
676
+ }
677
+ const lastPart = parts[parts.length - 1];
678
+ if (lastPart)
679
+ current[lastPart] = value;
680
+ }
681
+ mergeMetadata(op, meta) {
682
+ if (meta.summary)
683
+ op.summary = meta.summary;
684
+ if (meta.description)
685
+ op.description = meta.description;
686
+ if (meta.tags && meta.tags.length)
687
+ op.tags = meta.tags;
688
+ if (meta.deprecated)
689
+ op.deprecated = true;
690
+ if (meta.operationId)
691
+ op.operationId = meta.operationId;
692
+ }
693
+ extractJSDoc(node) {
694
+ let tags = ts.getJSDocTags(node);
695
+ // If no tags on the node, check the parent (ExpressionStatement or VariableDeclaration)
696
+ if (tags.length === 0) {
697
+ if (node.parent && ts.isExpressionStatement(node.parent)) {
698
+ tags = ts.getJSDocTags(node.parent);
699
+ }
700
+ else if (node.parent && ts.isVariableDeclaration(node.parent)) {
701
+ // Handle const handler = () => {}
702
+ if (node.parent.parent &&
703
+ ts.isVariableDeclarationList(node.parent.parent)) {
704
+ tags = ts.getJSDocTags(node.parent.parent.parent);
705
+ }
706
+ }
707
+ }
708
+ const result = { tags: [] };
709
+ tags.forEach((tag) => {
710
+ const comment = ts.getTextOfJSDocComment(tag.comment);
711
+ const tagName = tag.tagName.text;
712
+ if (tagName === "summary")
713
+ result.summary = comment;
714
+ if (tagName === "description")
715
+ result.description = comment;
716
+ if (tagName === "deprecated")
717
+ result.deprecated = true;
718
+ if (tagName === "operationId")
719
+ result.operationId = comment;
720
+ if (tagName === "tags" && comment) {
721
+ result.tags = comment.split(",").map((t) => t.trim());
722
+ }
723
+ });
724
+ return result;
725
+ }
726
+ }
727
+ /**
728
+ * -------------------------------------------------------------------------
729
+ * Main Logic
730
+ * -------------------------------------------------------------------------
731
+ */
732
+ export function generateOpenApi(options) {
733
+ if (!fs.existsSync(options.entryFile)) {
734
+ throw new Error(`Entry file not found: ${options.entryFile}`);
735
+ }
736
+ console.log("🔍 Analyzing AST...");
737
+ const analyzer = new RouteAnalyzer(options);
738
+ const { paths, schemas } = analyzer.analyze(options.entryFile);
739
+ const doc = {
740
+ openapi: "3.0.0",
741
+ info: options.info || {
742
+ title: "Auto Generated API",
743
+ version: "1.0.0",
744
+ },
745
+ servers: options.servers || [],
746
+ paths: paths,
747
+ components: {
748
+ schemas: schemas,
749
+ },
750
+ };
751
+ console.log(`✅ Found ${Object.keys(paths).length} paths.`);
752
+ console.log(`✅ Generated ${Object.keys(schemas).length} schemas.`);
753
+ fs.writeFileSync(options.outputFile, JSON.stringify(doc, null, 2));
754
+ console.log(`💾 Swagger file saved to: ${options.outputFile}`);
755
+ }
756
+ /**
757
+ * -------------------------------------------------------------------------
758
+ * CLI Execution Check
759
+ * -------------------------------------------------------------------------
760
+ */
761
+ const isMain = () => {
762
+ if (import.meta && import.meta.url) {
763
+ const entryFile = process.argv[1];
764
+ const currentFile = fileURLToPath(import.meta.url);
765
+ return (entryFile === currentFile ||
766
+ entryFile === currentFile.replace(/\//g, "\\"));
767
+ }
768
+ return false;
769
+ };
770
+ /** Helper to find tsconfig recursively. */
771
+ const findTsConfig = (startDir) => {
772
+ let dir = startDir;
773
+ while (dir !== path.parse(dir).root) {
774
+ const tsconfig = path.join(dir, "tsconfig.json");
775
+ if (fs.existsSync(tsconfig))
776
+ return tsconfig;
777
+ dir = path.dirname(dir);
778
+ }
779
+ return undefined;
780
+ };
781
+ if (isMain()) {
782
+ const args = process.argv.slice(2);
783
+ if (args.length < 2) {
784
+ console.log("Usage: npx ts-node swagger-generator.ts <entryFile> <outputFile> [tsconfigPath]");
785
+ process.exit(1);
786
+ }
787
+ const entryFile = path.resolve(process.cwd(), args[0]);
788
+ const outputFile = path.resolve(process.cwd(), args[1]);
789
+ // Auto-detect tsconfig if not provided
790
+ let tsconfigPath = args[2] ? path.resolve(process.cwd(), args[2]) : undefined;
791
+ if (!tsconfigPath) {
792
+ tsconfigPath = findTsConfig(path.dirname(entryFile));
793
+ }
794
+ generateOpenApi({
795
+ entryFile,
796
+ outputFile,
797
+ tsconfigPath,
798
+ info: {
799
+ title: "My API",
800
+ version: "1.0.0",
801
+ description: "Generated via AST analysis",
802
+ },
803
+ servers: [{ url: "http://localhost:3000" }],
804
+ });
805
+ }
806
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "swagger-autogen-ast",
3
+ "version": "1.0.0",
4
+ "description": "A zero-config OpenAPI 3.0 generator for Express. The AST-based spiritual successor to swagger-autogen with automatic type inference.",
5
+ "homepage": "https://github.com/anthfgreco/swagger-autogen-ast#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/anthfgreco/swagger-autogen-ast/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/anthfgreco/swagger-autogen-ast.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": "Anthony Greco",
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "bin": {
19
+ "swagger-autogen-ast": "./dist/index.js"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "prepublishOnly": "npm run build",
28
+ "prettier": "prettier src --write",
29
+ "sort-package-json": "npx sort-package-json",
30
+ "test": "vitest run",
31
+ "test:slow": "cross-env RUN_SLOW_TESTS=1 vitest run",
32
+ "test:watch": "vitest watch",
33
+ "test:watch:slow": "cross-env RUN_SLOW_TESTS=1 vitest watch"
34
+ },
35
+ "dependencies": {
36
+ "ora": "^9.0.0",
37
+ "typescript": "^5.9.3"
38
+ },
39
+ "devDependencies": {
40
+ "@types/express": "^5.0.6",
41
+ "@types/node": "^25.0.2",
42
+ "cross-env": "^10.1.0",
43
+ "dotenv": "^17.2.3",
44
+ "express": "^5.2.1",
45
+ "prettier": "^3.7.4",
46
+ "prettier-plugin-organize-imports": "^4.2.0",
47
+ "vitest": "^4.0.15"
48
+ }
49
+ }