opencroc 0.3.1 → 0.4.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/README.en.md +1 -1
- package/README.ja.md +1 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/cli/index.js +103 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +102 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,7 +29,8 @@ import * as fs2 from "fs";
|
|
|
29
29
|
import * as path3 from "path";
|
|
30
30
|
import {
|
|
31
31
|
Project as Project2,
|
|
32
|
-
SyntaxKind as SyntaxKind2
|
|
32
|
+
SyntaxKind as SyntaxKind2,
|
|
33
|
+
Node
|
|
33
34
|
} from "ts-morph";
|
|
34
35
|
function parseControllerFile(filePath) {
|
|
35
36
|
const absolutePath = path3.resolve(filePath);
|
|
@@ -40,6 +41,7 @@ function parseControllerFile(filePath) {
|
|
|
40
41
|
const endpoints = [];
|
|
41
42
|
endpoints.push(...extractRouterCalls(sourceFile));
|
|
42
43
|
endpoints.push(...extractBaseCrudRoutes(sourceFile));
|
|
44
|
+
endpoints.push(...extractNestControllerRoutes(sourceFile));
|
|
43
45
|
return deduplicateEndpoints(endpoints);
|
|
44
46
|
} catch {
|
|
45
47
|
return [];
|
|
@@ -132,6 +134,49 @@ function extractBaseCrudRoutes(sourceFile) {
|
|
|
132
134
|
}
|
|
133
135
|
return endpoints;
|
|
134
136
|
}
|
|
137
|
+
function extractNestControllerRoutes(sourceFile) {
|
|
138
|
+
const endpoints = [];
|
|
139
|
+
for (const cls of sourceFile.getClasses()) {
|
|
140
|
+
const controllerDecorator = cls.getDecorators().find((d) => d.getName().toLowerCase() === "controller");
|
|
141
|
+
if (!controllerDecorator) continue;
|
|
142
|
+
const controllerBasePath = normalizeRoutePath(extractDecoratorPath(controllerDecorator, sourceFile) ?? "");
|
|
143
|
+
for (const methodDecl of cls.getMethods()) {
|
|
144
|
+
const requestMapping = extractRequestMapping(methodDecl, sourceFile);
|
|
145
|
+
if (requestMapping) {
|
|
146
|
+
const fullPath2 = joinRoutePath(controllerBasePath, normalizeRoutePath(requestMapping.path));
|
|
147
|
+
endpoints.push({
|
|
148
|
+
method: requestMapping.method,
|
|
149
|
+
path: fullPath2,
|
|
150
|
+
pathParams: extractPathParams(fullPath2),
|
|
151
|
+
queryParams: [],
|
|
152
|
+
bodyFields: [],
|
|
153
|
+
responseFields: [],
|
|
154
|
+
relatedTables: [],
|
|
155
|
+
description: extractMethodDescription(methodDecl)
|
|
156
|
+
});
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const httpDecorator = methodDecl.getDecorators().find((d) => NEST_HTTP_DECORATORS.has(d.getName().toLowerCase()));
|
|
160
|
+
if (!httpDecorator) continue;
|
|
161
|
+
const methodName = httpDecorator.getName().toLowerCase();
|
|
162
|
+
const method = METHOD_MAP[methodName];
|
|
163
|
+
if (!method) continue;
|
|
164
|
+
const methodPath = normalizeRoutePath(extractDecoratorPath(httpDecorator, sourceFile) ?? "");
|
|
165
|
+
const fullPath = joinRoutePath(controllerBasePath, methodPath);
|
|
166
|
+
endpoints.push({
|
|
167
|
+
method,
|
|
168
|
+
path: fullPath,
|
|
169
|
+
pathParams: extractPathParams(fullPath),
|
|
170
|
+
queryParams: [],
|
|
171
|
+
bodyFields: [],
|
|
172
|
+
responseFields: [],
|
|
173
|
+
relatedTables: [],
|
|
174
|
+
description: extractMethodDescription(methodDecl)
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return endpoints;
|
|
179
|
+
}
|
|
135
180
|
function inferRelatedTables(servicePaths) {
|
|
136
181
|
const tables = /* @__PURE__ */ new Set();
|
|
137
182
|
for (const sp of servicePaths) {
|
|
@@ -164,6 +209,60 @@ function resolveRoutePath(node, sourceFile) {
|
|
|
164
209
|
}
|
|
165
210
|
return null;
|
|
166
211
|
}
|
|
212
|
+
function extractDecoratorPath(decorator, sourceFile) {
|
|
213
|
+
const args = decorator.getArguments();
|
|
214
|
+
if (args.length === 0) return "";
|
|
215
|
+
const firstArg = args[0];
|
|
216
|
+
if (firstArg.getKind() === SyntaxKind2.ObjectLiteralExpression) {
|
|
217
|
+
return extractPathFromObjectLiteral(firstArg, sourceFile);
|
|
218
|
+
}
|
|
219
|
+
return resolveRoutePath(firstArg, sourceFile);
|
|
220
|
+
}
|
|
221
|
+
function extractPathFromObjectLiteral(node, sourceFile) {
|
|
222
|
+
const pathProp = node.getProperty("path");
|
|
223
|
+
if (!pathProp || !Node.isPropertyAssignment(pathProp)) return null;
|
|
224
|
+
const initializer = pathProp.getInitializer();
|
|
225
|
+
if (!initializer) return null;
|
|
226
|
+
return resolveRoutePath(initializer, sourceFile);
|
|
227
|
+
}
|
|
228
|
+
function extractRequestMapping(methodDecl, sourceFile) {
|
|
229
|
+
const decorator = methodDecl.getDecorators().find((d) => d.getName().toLowerCase() === "requestmapping");
|
|
230
|
+
if (!decorator) return null;
|
|
231
|
+
const args = decorator.getArguments();
|
|
232
|
+
if (args.length === 0) return null;
|
|
233
|
+
const firstArg = args[0];
|
|
234
|
+
if (firstArg.getKind() !== SyntaxKind2.ObjectLiteralExpression) return null;
|
|
235
|
+
const obj = firstArg;
|
|
236
|
+
const methodProp = obj.getProperty("method");
|
|
237
|
+
let method = "GET";
|
|
238
|
+
if (methodProp && Node.isPropertyAssignment(methodProp)) {
|
|
239
|
+
const init = methodProp.getInitializer();
|
|
240
|
+
const methodText = init?.getText() || "";
|
|
241
|
+
const normalized = methodText.replace(/['"`]/g, "").split(".").pop()?.toUpperCase();
|
|
242
|
+
if (normalized && ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(normalized)) {
|
|
243
|
+
method = normalized;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const pathValue = extractPathFromObjectLiteral(obj, sourceFile) ?? "";
|
|
247
|
+
return { method, path: pathValue };
|
|
248
|
+
}
|
|
249
|
+
function normalizeRoutePath(routePath) {
|
|
250
|
+
const cleaned = routePath.trim();
|
|
251
|
+
if (!cleaned || cleaned === "/") return "";
|
|
252
|
+
return `/${cleaned.replace(/^\/+|\/+$/g, "")}`;
|
|
253
|
+
}
|
|
254
|
+
function joinRoutePath(basePath, childPath) {
|
|
255
|
+
const joined = `${basePath}${childPath}`.replace(/\/+/g, "/");
|
|
256
|
+
return joined || "/";
|
|
257
|
+
}
|
|
258
|
+
function extractMethodDescription(methodDecl) {
|
|
259
|
+
const docs = methodDecl.getJsDocs();
|
|
260
|
+
if (docs.length > 0) {
|
|
261
|
+
const desc = docs[0].getDescription().trim();
|
|
262
|
+
if (desc) return desc;
|
|
263
|
+
}
|
|
264
|
+
return "";
|
|
265
|
+
}
|
|
167
266
|
function resolveTemplateLiteral(node, sourceFile) {
|
|
168
267
|
let result = node.getText().slice(1, -1);
|
|
169
268
|
result = result.replace(/\$\{([^}]+)\}/g, (_match, expr) => {
|
|
@@ -240,7 +339,7 @@ function createControllerParser() {
|
|
|
240
339
|
}
|
|
241
340
|
};
|
|
242
341
|
}
|
|
243
|
-
var HTTP_METHODS, METHOD_MAP;
|
|
342
|
+
var HTTP_METHODS, METHOD_MAP, NEST_HTTP_DECORATORS;
|
|
244
343
|
var init_controller_parser = __esm({
|
|
245
344
|
"src/parsers/controller-parser.ts"() {
|
|
246
345
|
"use strict";
|
|
@@ -253,6 +352,7 @@ var init_controller_parser = __esm({
|
|
|
253
352
|
delete: "DELETE",
|
|
254
353
|
patch: "PATCH"
|
|
255
354
|
};
|
|
355
|
+
NEST_HTTP_DECORATORS = /* @__PURE__ */ new Set(["get", "post", "put", "delete", "patch"]);
|
|
256
356
|
}
|
|
257
357
|
});
|
|
258
358
|
|