@lark-apaas/devtool-kits 1.2.19 → 1.2.20
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/dist/bin/generate-api-routes.cjs +189 -0
- package/dist/bin/generate-api-routes.cjs.map +1 -0
- package/dist/bin/generate-api-routes.d.cts +1 -0
- package/dist/bin/generate-api-routes.d.ts +1 -0
- package/dist/bin/generate-api-routes.js +43 -0
- package/dist/bin/generate-api-routes.js.map +1 -0
- package/dist/bin/generate-page-routes.cjs +227 -0
- package/dist/bin/generate-page-routes.cjs.map +1 -0
- package/dist/bin/generate-page-routes.d.cts +1 -0
- package/dist/bin/generate-page-routes.d.ts +1 -0
- package/dist/bin/generate-page-routes.js +43 -0
- package/dist/bin/generate-page-routes.js.map +1 -0
- package/dist/chunk-7QVYU63E.js +7 -0
- package/dist/chunk-7QVYU63E.js.map +1 -0
- package/dist/chunk-LSHFHCDF.js +350 -0
- package/dist/chunk-LSHFHCDF.js.map +1 -0
- package/dist/chunk-YPNLFWHQ.js +189 -0
- package/dist/chunk-YPNLFWHQ.js.map +1 -0
- package/dist/index.cjs +332 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.js +67 -271
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { RequestHandler, Router, Application } from 'express';
|
|
3
|
+
import * as t from '@babel/types';
|
|
4
|
+
import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 标准化基础路径,确保以 '/' 开头且不包含 trailing slash
|
|
@@ -171,6 +172,15 @@ interface OpenapiMiddlewareOptions {
|
|
|
171
172
|
serverDir?: string;
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Scan serverDir for NestJS controller files and extract all parameterized API routes.
|
|
177
|
+
* Synchronous — safe to call at preset config time (before bundling).
|
|
178
|
+
*/
|
|
179
|
+
declare function parseApiRoutes(serverDir: string): Array<{
|
|
180
|
+
method: string;
|
|
181
|
+
path: string;
|
|
182
|
+
}>;
|
|
183
|
+
|
|
174
184
|
/**
|
|
175
185
|
* Creates OpenAPI middleware that serves enhanced openapi.json
|
|
176
186
|
* Supports both rspack/webpack and Vite dev servers
|
|
@@ -271,4 +281,30 @@ declare function getQueryParam(req: AnyRequest, key: string): string | undefined
|
|
|
271
281
|
*/
|
|
272
282
|
declare function registerMiddlewares(server: ExpressApp | ViteMiddleware, middlewares: Middleware[], options?: Partial<MiddlewareContext>): Promise<void>;
|
|
273
283
|
|
|
274
|
-
|
|
284
|
+
interface PageRouteInfo {
|
|
285
|
+
path?: string;
|
|
286
|
+
index?: boolean;
|
|
287
|
+
[key: string]: unknown;
|
|
288
|
+
}
|
|
289
|
+
interface ParseRoutesOptions {
|
|
290
|
+
/** If true, prefix all routes with basePath. Default: true */
|
|
291
|
+
applyBasePath?: boolean;
|
|
292
|
+
}
|
|
293
|
+
declare function routeParserLog(level: 'log' | 'warn' | 'error' | 'info', message: string, ...args: unknown[]): void;
|
|
294
|
+
declare function calculateFileHash(filePath: string): string | null;
|
|
295
|
+
declare function isRouteComponent(openingElement: t.JSXOpeningElement): boolean;
|
|
296
|
+
declare function evaluateTemplateLiteral(templateLiteral: t.TemplateLiteral): string;
|
|
297
|
+
declare function extractPageRouteInfo(openingElement: t.JSXOpeningElement): PageRouteInfo;
|
|
298
|
+
declare function buildFullPath(routeStack: PageRouteInfo[], currentRoute: PageRouteInfo): string | null;
|
|
299
|
+
/**
|
|
300
|
+
* Parse routes from the app file at build time.
|
|
301
|
+
* @param appPath - Path to app.tsx (relative to cwd or absolute)
|
|
302
|
+
* @param basePath - Normalized base path prefix (e.g., '/my_plugin', or '' for no prefix)
|
|
303
|
+
* @param options - Parse options
|
|
304
|
+
* @returns Array of route definitions
|
|
305
|
+
*/
|
|
306
|
+
declare function parseRoutesFromFile(appPath: string, basePath: string, options?: ParseRoutesOptions): Array<{
|
|
307
|
+
path: string;
|
|
308
|
+
}>;
|
|
309
|
+
|
|
310
|
+
export { type GlobalMiddleware, type Middleware, type MiddlewareContext, type Options, type PageRouteInfo, type ParseRoutesOptions, type RouteInfo, type RouteMiddleware, buildFullPath, calculateFileHash, createCollectLogsMiddleware, createDevLogsMiddleware, createOpenapiMiddleware, evaluateTemplateLiteral, extractPageRouteInfo, getQuery, getQueryParam, handleDevProxyError, isRouteComponent, normalizeBasePath, parseAndGenerateNestResourceTemplate, parseApiRoutes, parseRoutesFromFile, postprocessDrizzleSchema, registerMiddlewares, routeParserLog, sendError, sendJson, sendSuccess };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { RequestHandler, Router, Application } from 'express';
|
|
3
|
+
import * as t from '@babel/types';
|
|
4
|
+
import { IncomingMessage as IncomingMessage$1, ServerResponse as ServerResponse$1 } from 'http';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 标准化基础路径,确保以 '/' 开头且不包含 trailing slash
|
|
@@ -171,6 +172,15 @@ interface OpenapiMiddlewareOptions {
|
|
|
171
172
|
serverDir?: string;
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Scan serverDir for NestJS controller files and extract all parameterized API routes.
|
|
177
|
+
* Synchronous — safe to call at preset config time (before bundling).
|
|
178
|
+
*/
|
|
179
|
+
declare function parseApiRoutes(serverDir: string): Array<{
|
|
180
|
+
method: string;
|
|
181
|
+
path: string;
|
|
182
|
+
}>;
|
|
183
|
+
|
|
174
184
|
/**
|
|
175
185
|
* Creates OpenAPI middleware that serves enhanced openapi.json
|
|
176
186
|
* Supports both rspack/webpack and Vite dev servers
|
|
@@ -271,4 +281,30 @@ declare function getQueryParam(req: AnyRequest, key: string): string | undefined
|
|
|
271
281
|
*/
|
|
272
282
|
declare function registerMiddlewares(server: ExpressApp | ViteMiddleware, middlewares: Middleware[], options?: Partial<MiddlewareContext>): Promise<void>;
|
|
273
283
|
|
|
274
|
-
|
|
284
|
+
interface PageRouteInfo {
|
|
285
|
+
path?: string;
|
|
286
|
+
index?: boolean;
|
|
287
|
+
[key: string]: unknown;
|
|
288
|
+
}
|
|
289
|
+
interface ParseRoutesOptions {
|
|
290
|
+
/** If true, prefix all routes with basePath. Default: true */
|
|
291
|
+
applyBasePath?: boolean;
|
|
292
|
+
}
|
|
293
|
+
declare function routeParserLog(level: 'log' | 'warn' | 'error' | 'info', message: string, ...args: unknown[]): void;
|
|
294
|
+
declare function calculateFileHash(filePath: string): string | null;
|
|
295
|
+
declare function isRouteComponent(openingElement: t.JSXOpeningElement): boolean;
|
|
296
|
+
declare function evaluateTemplateLiteral(templateLiteral: t.TemplateLiteral): string;
|
|
297
|
+
declare function extractPageRouteInfo(openingElement: t.JSXOpeningElement): PageRouteInfo;
|
|
298
|
+
declare function buildFullPath(routeStack: PageRouteInfo[], currentRoute: PageRouteInfo): string | null;
|
|
299
|
+
/**
|
|
300
|
+
* Parse routes from the app file at build time.
|
|
301
|
+
* @param appPath - Path to app.tsx (relative to cwd or absolute)
|
|
302
|
+
* @param basePath - Normalized base path prefix (e.g., '/my_plugin', or '' for no prefix)
|
|
303
|
+
* @param options - Parse options
|
|
304
|
+
* @returns Array of route definitions
|
|
305
|
+
*/
|
|
306
|
+
declare function parseRoutesFromFile(appPath: string, basePath: string, options?: ParseRoutesOptions): Array<{
|
|
307
|
+
path: string;
|
|
308
|
+
}>;
|
|
309
|
+
|
|
310
|
+
export { type GlobalMiddleware, type Middleware, type MiddlewareContext, type Options, type PageRouteInfo, type ParseRoutesOptions, type RouteInfo, type RouteMiddleware, buildFullPath, calculateFileHash, createCollectLogsMiddleware, createDevLogsMiddleware, createOpenapiMiddleware, evaluateTemplateLiteral, extractPageRouteInfo, getQuery, getQueryParam, handleDevProxyError, isRouteComponent, normalizeBasePath, parseAndGenerateNestResourceTemplate, parseApiRoutes, parseRoutesFromFile, postprocessDrizzleSchema, registerMiddlewares, routeParserLog, sendError, sendJson, sendSuccess };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
enhanceOpenApiWithSourceInfo,
|
|
3
|
+
parseApiRoutes,
|
|
4
|
+
transformOpenapiPaths
|
|
5
|
+
} from "./chunk-LSHFHCDF.js";
|
|
6
|
+
import {
|
|
7
|
+
buildFullPath,
|
|
8
|
+
calculateFileHash,
|
|
9
|
+
evaluateTemplateLiteral,
|
|
10
|
+
extractPageRouteInfo,
|
|
11
|
+
isRouteComponent,
|
|
12
|
+
parseRoutesFromFile,
|
|
13
|
+
routeParserLog
|
|
14
|
+
} from "./chunk-YPNLFWHQ.js";
|
|
15
|
+
import {
|
|
16
|
+
__name
|
|
17
|
+
} from "./chunk-7QVYU63E.js";
|
|
3
18
|
|
|
4
19
|
// src/utils/index.ts
|
|
5
20
|
function normalizeBasePath(basePath) {
|
|
@@ -1329,246 +1344,19 @@ function handleDevProxyError(err, req, res, options) {
|
|
|
1329
1344
|
__name(handleDevProxyError, "handleDevProxyError");
|
|
1330
1345
|
|
|
1331
1346
|
// src/middlewares/index.ts
|
|
1332
|
-
import
|
|
1347
|
+
import path4 from "path";
|
|
1333
1348
|
|
|
1334
1349
|
// src/middlewares/openapi/router.ts
|
|
1335
1350
|
import express from "express";
|
|
1336
1351
|
|
|
1337
1352
|
// src/middlewares/openapi/controller.ts
|
|
1338
|
-
import
|
|
1353
|
+
import fs3 from "fs/promises";
|
|
1339
1354
|
import crypto from "crypto";
|
|
1340
|
-
|
|
1341
|
-
// src/middlewares/openapi/services.ts
|
|
1342
|
-
import { promises as fs4 } from "fs";
|
|
1343
|
-
import path4 from "path";
|
|
1344
|
-
import ts from "typescript";
|
|
1345
|
-
|
|
1346
|
-
// src/middlewares/openapi/utils.ts
|
|
1347
|
-
import path3 from "path";
|
|
1348
|
-
import { promises as fs3 } from "fs";
|
|
1349
|
-
async function findControllerFiles(dir) {
|
|
1350
|
-
const files = [];
|
|
1351
|
-
async function scan(currentDir) {
|
|
1352
|
-
const entries = await fs3.readdir(currentDir, {
|
|
1353
|
-
withFileTypes: true
|
|
1354
|
-
});
|
|
1355
|
-
for (const entry of entries) {
|
|
1356
|
-
const fullPath = path3.join(currentDir, entry.name);
|
|
1357
|
-
if (entry.isDirectory()) {
|
|
1358
|
-
await scan(fullPath);
|
|
1359
|
-
} else if (entry.isFile() && entry.name.endsWith(".controller.ts")) {
|
|
1360
|
-
files.push(fullPath);
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
__name(scan, "scan");
|
|
1365
|
-
await scan(dir);
|
|
1366
|
-
return files;
|
|
1367
|
-
}
|
|
1368
|
-
__name(findControllerFiles, "findControllerFiles");
|
|
1369
|
-
async function buildSourceMap(controllerFiles, processFile) {
|
|
1370
|
-
const sourceMap = /* @__PURE__ */ new Map();
|
|
1371
|
-
const concurrency = 10;
|
|
1372
|
-
const results = [];
|
|
1373
|
-
for (let i = 0; i < controllerFiles.length; i += concurrency) {
|
|
1374
|
-
const batch = controllerFiles.slice(i, i + concurrency);
|
|
1375
|
-
const batchResults = await Promise.all(batch.map((filePath) => processFile(filePath)));
|
|
1376
|
-
results.push(...batchResults);
|
|
1377
|
-
}
|
|
1378
|
-
for (const metadata of results) {
|
|
1379
|
-
for (const [operationId, info] of metadata.entries()) {
|
|
1380
|
-
sourceMap.set(operationId, info);
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
return sourceMap;
|
|
1384
|
-
}
|
|
1385
|
-
__name(buildSourceMap, "buildSourceMap");
|
|
1386
|
-
function findSourceInfo(operationId, sourceMap) {
|
|
1387
|
-
const directMatch = sourceMap.get(operationId);
|
|
1388
|
-
if (directMatch) {
|
|
1389
|
-
return directMatch;
|
|
1390
|
-
}
|
|
1391
|
-
for (const [key, value] of sourceMap.entries()) {
|
|
1392
|
-
const [className, methodName] = key.split("_");
|
|
1393
|
-
if (!className || !methodName) continue;
|
|
1394
|
-
const camelCaseId = className.charAt(0).toLowerCase() + className.slice(1) + methodName.charAt(0).toUpperCase() + methodName.slice(1);
|
|
1395
|
-
if (operationId === camelCaseId) {
|
|
1396
|
-
return value;
|
|
1397
|
-
}
|
|
1398
|
-
if (operationId === methodName) {
|
|
1399
|
-
return value;
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
return void 0;
|
|
1403
|
-
}
|
|
1404
|
-
__name(findSourceInfo, "findSourceInfo");
|
|
1405
|
-
function enhanceOpenApiPaths(openapi, sourceMap) {
|
|
1406
|
-
let enhancedCount = 0;
|
|
1407
|
-
if (!openapi.paths) {
|
|
1408
|
-
return enhancedCount;
|
|
1409
|
-
}
|
|
1410
|
-
for (const pathItem of Object.values(openapi.paths)) {
|
|
1411
|
-
if (!pathItem || typeof pathItem !== "object") continue;
|
|
1412
|
-
for (const operation of Object.values(pathItem)) {
|
|
1413
|
-
if (operation && typeof operation === "object" && "operationId" in operation) {
|
|
1414
|
-
const sourceInfo = findSourceInfo(operation.operationId, sourceMap);
|
|
1415
|
-
if (sourceInfo) {
|
|
1416
|
-
operation["x-source"] = {
|
|
1417
|
-
file: sourceInfo.file,
|
|
1418
|
-
line: sourceInfo.line
|
|
1419
|
-
};
|
|
1420
|
-
enhancedCount++;
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
return enhancedCount;
|
|
1426
|
-
}
|
|
1427
|
-
__name(enhanceOpenApiPaths, "enhanceOpenApiPaths");
|
|
1428
|
-
function transformOpenapiPaths(openapi, basePath) {
|
|
1429
|
-
if (basePath === "/" || !openapi.paths) {
|
|
1430
|
-
return openapi;
|
|
1431
|
-
}
|
|
1432
|
-
const newPaths = {};
|
|
1433
|
-
Object.keys(openapi.paths).forEach((key) => {
|
|
1434
|
-
const staticApiKey = key.startsWith(basePath) ? key.slice(basePath.length) : key;
|
|
1435
|
-
newPaths[staticApiKey] = openapi.paths[key];
|
|
1436
|
-
});
|
|
1437
|
-
return {
|
|
1438
|
-
...openapi,
|
|
1439
|
-
paths: newPaths,
|
|
1440
|
-
basePath
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
__name(transformOpenapiPaths, "transformOpenapiPaths");
|
|
1444
|
-
|
|
1445
|
-
// src/middlewares/openapi/services.ts
|
|
1446
|
-
async function enhanceOpenApiWithSourceInfo(options = {}) {
|
|
1447
|
-
const startTime = Date.now();
|
|
1448
|
-
const openapiPath = options.openapiPath || path4.resolve(__dirname, "../client/src/api/gen/openapi.json");
|
|
1449
|
-
const serverDir = options.serverDir || path4.resolve(__dirname, "../server");
|
|
1450
|
-
const writeFile2 = options.writeFile !== false;
|
|
1451
|
-
let openapi;
|
|
1452
|
-
if (options.openapiData) {
|
|
1453
|
-
openapi = JSON.parse(JSON.stringify(options.openapiData));
|
|
1454
|
-
} else {
|
|
1455
|
-
const openapiContent = await fs4.readFile(openapiPath, "utf-8");
|
|
1456
|
-
openapi = JSON.parse(openapiContent);
|
|
1457
|
-
}
|
|
1458
|
-
const controllerFiles = await findControllerFiles(serverDir);
|
|
1459
|
-
const sourceMap = await buildSourceMap(controllerFiles, processControllerFile);
|
|
1460
|
-
const enhanced = enhanceOpenApiPaths(openapi, sourceMap);
|
|
1461
|
-
if (writeFile2) {
|
|
1462
|
-
await fs4.writeFile(openapiPath, JSON.stringify(openapi, null, 2) + "\n", "utf-8");
|
|
1463
|
-
}
|
|
1464
|
-
const duration = Date.now() - startTime;
|
|
1465
|
-
return {
|
|
1466
|
-
openapi,
|
|
1467
|
-
stats: {
|
|
1468
|
-
duration,
|
|
1469
|
-
controllersFound: controllerFiles.length,
|
|
1470
|
-
endpointsExtracted: sourceMap.size,
|
|
1471
|
-
endpointsEnhanced: enhanced
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
|
-
}
|
|
1475
|
-
__name(enhanceOpenApiWithSourceInfo, "enhanceOpenApiWithSourceInfo");
|
|
1476
|
-
async function processControllerFile(filePath) {
|
|
1477
|
-
const relativePath = path4.relative(process.cwd(), filePath);
|
|
1478
|
-
const content = await fs4.readFile(filePath, "utf-8");
|
|
1479
|
-
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
1480
|
-
return extractControllerMetadata(sourceFile, relativePath);
|
|
1481
|
-
}
|
|
1482
|
-
__name(processControllerFile, "processControllerFile");
|
|
1483
|
-
function extractControllerMetadata(sourceFile, filePath) {
|
|
1484
|
-
const metadata = /* @__PURE__ */ new Map();
|
|
1485
|
-
let controllerPath = "";
|
|
1486
|
-
let className = "";
|
|
1487
|
-
function getDecorators(node) {
|
|
1488
|
-
if ("modifiers" in node && Array.isArray(node.modifiers)) {
|
|
1489
|
-
return node.modifiers.filter((mod) => mod.kind === ts.SyntaxKind.Decorator);
|
|
1490
|
-
}
|
|
1491
|
-
if ("decorators" in node && Array.isArray(node.decorators)) {
|
|
1492
|
-
return node.decorators;
|
|
1493
|
-
}
|
|
1494
|
-
return [];
|
|
1495
|
-
}
|
|
1496
|
-
__name(getDecorators, "getDecorators");
|
|
1497
|
-
function visit(node) {
|
|
1498
|
-
if (ts.isClassDeclaration(node)) {
|
|
1499
|
-
const decorators = getDecorators(node);
|
|
1500
|
-
if (node.name) {
|
|
1501
|
-
className = node.name.getText(sourceFile);
|
|
1502
|
-
}
|
|
1503
|
-
for (const decorator of decorators) {
|
|
1504
|
-
if (ts.isCallExpression(decorator.expression)) {
|
|
1505
|
-
const expression = decorator.expression;
|
|
1506
|
-
const decoratorName = expression.expression.getText(sourceFile);
|
|
1507
|
-
if (decoratorName === "Controller") {
|
|
1508
|
-
if (expression.arguments.length > 0) {
|
|
1509
|
-
const arg = expression.arguments[0];
|
|
1510
|
-
if (ts.isStringLiteral(arg)) {
|
|
1511
|
-
controllerPath = arg.text;
|
|
1512
|
-
}
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
if (ts.isMethodDeclaration(node) && node.name) {
|
|
1519
|
-
const methodName = node.name.getText(sourceFile);
|
|
1520
|
-
let httpMethod = "";
|
|
1521
|
-
let routePath = "";
|
|
1522
|
-
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
1523
|
-
const decorators = getDecorators(node);
|
|
1524
|
-
for (const decorator of decorators) {
|
|
1525
|
-
if (ts.isCallExpression(decorator.expression)) {
|
|
1526
|
-
const decoratorName = decorator.expression.expression.getText(sourceFile);
|
|
1527
|
-
if ([
|
|
1528
|
-
"Get",
|
|
1529
|
-
"Post",
|
|
1530
|
-
"Put",
|
|
1531
|
-
"Delete",
|
|
1532
|
-
"Patch",
|
|
1533
|
-
"Options",
|
|
1534
|
-
"Head",
|
|
1535
|
-
"All"
|
|
1536
|
-
].includes(decoratorName)) {
|
|
1537
|
-
httpMethod = decoratorName.toLowerCase();
|
|
1538
|
-
if (decorator.expression.arguments.length > 0) {
|
|
1539
|
-
const arg = decorator.expression.arguments[0];
|
|
1540
|
-
if (ts.isStringLiteral(arg)) {
|
|
1541
|
-
routePath = arg.text;
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
if (httpMethod && methodName && className) {
|
|
1548
|
-
const operationId = `${className}_${methodName}`;
|
|
1549
|
-
metadata.set(operationId, {
|
|
1550
|
-
file: filePath,
|
|
1551
|
-
line: line + 1,
|
|
1552
|
-
method: httpMethod,
|
|
1553
|
-
controllerPath,
|
|
1554
|
-
routePath
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
ts.forEachChild(node, visit);
|
|
1559
|
-
}
|
|
1560
|
-
__name(visit, "visit");
|
|
1561
|
-
visit(sourceFile);
|
|
1562
|
-
return metadata;
|
|
1563
|
-
}
|
|
1564
|
-
__name(extractControllerMetadata, "extractControllerMetadata");
|
|
1565
|
-
|
|
1566
|
-
// src/middlewares/openapi/controller.ts
|
|
1567
1355
|
function createOpenapiHandler(openapiFilePath, enableEnhancement, serverDir) {
|
|
1568
1356
|
let cache = null;
|
|
1569
1357
|
return async (_req, res, context) => {
|
|
1570
1358
|
try {
|
|
1571
|
-
const fileBuffer = await
|
|
1359
|
+
const fileBuffer = await fs3.readFile(openapiFilePath, "utf-8");
|
|
1572
1360
|
const currentHash = crypto.createHash("md5").update(fileBuffer).digest("hex");
|
|
1573
1361
|
if (cache && cache.fileHash === currentHash) {
|
|
1574
1362
|
return res.json(cache.data);
|
|
@@ -1640,7 +1428,7 @@ __name(createOpenapiMiddleware, "createOpenapiMiddleware");
|
|
|
1640
1428
|
import express2 from "express";
|
|
1641
1429
|
|
|
1642
1430
|
// src/middlewares/dev-logs/utils.ts
|
|
1643
|
-
import { promises as
|
|
1431
|
+
import { promises as fs4 } from "fs";
|
|
1644
1432
|
import { isAbsolute, join as join2, relative } from "path";
|
|
1645
1433
|
|
|
1646
1434
|
// src/middlewares/dev-logs/helper/path-matcher.ts
|
|
@@ -1673,8 +1461,8 @@ function hasSpecialPatterns(pattern) {
|
|
|
1673
1461
|
return /[{*]/.test(pattern);
|
|
1674
1462
|
}
|
|
1675
1463
|
__name(hasSpecialPatterns, "hasSpecialPatterns");
|
|
1676
|
-
function normalizePathForMatching(
|
|
1677
|
-
return
|
|
1464
|
+
function normalizePathForMatching(path5) {
|
|
1465
|
+
return path5.replace(/\/+/g, "/").replace(/\/+$/, "");
|
|
1678
1466
|
}
|
|
1679
1467
|
__name(normalizePathForMatching, "normalizePathForMatching");
|
|
1680
1468
|
|
|
@@ -1692,7 +1480,7 @@ function getRelativePath(filePath) {
|
|
|
1692
1480
|
__name(getRelativePath, "getRelativePath");
|
|
1693
1481
|
async function fileExists(filePath) {
|
|
1694
1482
|
try {
|
|
1695
|
-
await
|
|
1483
|
+
await fs4.access(filePath);
|
|
1696
1484
|
return true;
|
|
1697
1485
|
} catch {
|
|
1698
1486
|
return false;
|
|
@@ -1775,9 +1563,9 @@ __name(serializeError, "serializeError");
|
|
|
1775
1563
|
import { join as join4 } from "path";
|
|
1776
1564
|
|
|
1777
1565
|
// src/middlewares/dev-logs/services/file-reader.ts
|
|
1778
|
-
import { promises as
|
|
1566
|
+
import { promises as fs5 } from "fs";
|
|
1779
1567
|
async function readFileReverse(filePath, chunkSize, processLine) {
|
|
1780
|
-
const handle = await
|
|
1568
|
+
const handle = await fs5.open(filePath, "r");
|
|
1781
1569
|
try {
|
|
1782
1570
|
const stats = await handle.stat();
|
|
1783
1571
|
let position = stats.size;
|
|
@@ -2223,7 +2011,7 @@ __name(readLogsBySource, "readLogsBySource");
|
|
|
2223
2011
|
// src/middlewares/dev-logs/services/trigger.service.ts
|
|
2224
2012
|
import { createReadStream as createReadStream3 } from "fs";
|
|
2225
2013
|
import { createInterface as createInterface3 } from "readline";
|
|
2226
|
-
async function readTriggerList(filePath, trigger,
|
|
2014
|
+
async function readTriggerList(filePath, trigger, path5, limit, triggerID) {
|
|
2227
2015
|
if (!await fileExists(filePath)) {
|
|
2228
2016
|
return void 0;
|
|
2229
2017
|
}
|
|
@@ -2249,7 +2037,7 @@ async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
|
|
|
2249
2037
|
if (alreadyAdded) {
|
|
2250
2038
|
return false;
|
|
2251
2039
|
}
|
|
2252
|
-
const isAutomationTrigger = builder.path?.endsWith(
|
|
2040
|
+
const isAutomationTrigger = builder.path?.endsWith(path5);
|
|
2253
2041
|
if (!isAutomationTrigger) {
|
|
2254
2042
|
return false;
|
|
2255
2043
|
}
|
|
@@ -2332,7 +2120,7 @@ async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
|
|
|
2332
2120
|
};
|
|
2333
2121
|
}
|
|
2334
2122
|
__name(readTriggerList, "readTriggerList");
|
|
2335
|
-
async function readTriggerDetail(filePath,
|
|
2123
|
+
async function readTriggerDetail(filePath, path5, instanceID) {
|
|
2336
2124
|
const exists = await fileExists(filePath);
|
|
2337
2125
|
if (!exists) {
|
|
2338
2126
|
return void 0;
|
|
@@ -2348,7 +2136,7 @@ async function readTriggerDetail(filePath, path7, instanceID) {
|
|
|
2348
2136
|
for await (const line of rl) {
|
|
2349
2137
|
const entry = parseLogLine(line);
|
|
2350
2138
|
if (!entry) continue;
|
|
2351
|
-
const isAutomationTrigger = entry.path?.endsWith(
|
|
2139
|
+
const isAutomationTrigger = entry.path?.endsWith(path5);
|
|
2352
2140
|
const hasInstanceID = entry.instance_id === instanceID && entry.trigger;
|
|
2353
2141
|
if (!isAutomationTrigger || !hasInstanceID) continue;
|
|
2354
2142
|
matches.push(entry);
|
|
@@ -2602,16 +2390,16 @@ function createGetTriggerListHandler(logDir) {
|
|
|
2602
2390
|
});
|
|
2603
2391
|
}
|
|
2604
2392
|
const triggerID = typeof req.query.triggerID === "string" ? req.query.triggerID.trim() : void 0;
|
|
2605
|
-
const
|
|
2393
|
+
const path5 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
|
|
2606
2394
|
const limit = parseLimit(req.query.limit, 10, 200);
|
|
2607
2395
|
try {
|
|
2608
|
-
const result = await readTriggerList(traceLogPath, trigger,
|
|
2396
|
+
const result = await readTriggerList(traceLogPath, trigger, path5, limit, triggerID);
|
|
2609
2397
|
if (!result) {
|
|
2610
2398
|
return handleNotFound(res, traceLogPath);
|
|
2611
2399
|
}
|
|
2612
2400
|
res.json({
|
|
2613
2401
|
file: getRelativePath(traceLogPath),
|
|
2614
|
-
path:
|
|
2402
|
+
path: path5,
|
|
2615
2403
|
...result
|
|
2616
2404
|
});
|
|
2617
2405
|
} catch (error) {
|
|
@@ -2629,9 +2417,9 @@ function createGetTriggerDetailHandler(logDir) {
|
|
|
2629
2417
|
message: "instanceID is required"
|
|
2630
2418
|
});
|
|
2631
2419
|
}
|
|
2632
|
-
const
|
|
2420
|
+
const path5 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
|
|
2633
2421
|
try {
|
|
2634
|
-
const result = await readTriggerDetail(traceLogPath,
|
|
2422
|
+
const result = await readTriggerDetail(traceLogPath, path5, instanceID);
|
|
2635
2423
|
if (!result) {
|
|
2636
2424
|
return handleNotFound(res, traceLogPath);
|
|
2637
2425
|
}
|
|
@@ -2739,8 +2527,8 @@ function createHealthCheckHandler(options = {}) {
|
|
|
2739
2527
|
__name(createHealthCheckHandler, "createHealthCheckHandler");
|
|
2740
2528
|
|
|
2741
2529
|
// src/middlewares/dev-logs/sse/log-watcher.ts
|
|
2742
|
-
import * as
|
|
2743
|
-
import * as
|
|
2530
|
+
import * as fs6 from "fs";
|
|
2531
|
+
import * as path3 from "path";
|
|
2744
2532
|
function mapPinoLevelToServerLogLevel2(pinoLevel) {
|
|
2745
2533
|
if (typeof pinoLevel === "string") {
|
|
2746
2534
|
const lower = pinoLevel.toLowerCase();
|
|
@@ -2957,13 +2745,13 @@ var LogWatcher = class {
|
|
|
2957
2745
|
* Watch a single log file
|
|
2958
2746
|
*/
|
|
2959
2747
|
watchFile(config) {
|
|
2960
|
-
const filePath =
|
|
2961
|
-
if (!
|
|
2748
|
+
const filePath = path3.join(this.logDir, config.fileName);
|
|
2749
|
+
if (!fs6.existsSync(filePath)) {
|
|
2962
2750
|
this.log(`File not found, skipping: ${config.fileName}`);
|
|
2963
2751
|
return;
|
|
2964
2752
|
}
|
|
2965
2753
|
try {
|
|
2966
|
-
const stats =
|
|
2754
|
+
const stats = fs6.statSync(filePath);
|
|
2967
2755
|
this.filePositions.set(config.fileName, stats.size);
|
|
2968
2756
|
this.log(`Initialized position for ${config.fileName}: ${stats.size} bytes`);
|
|
2969
2757
|
} catch (error) {
|
|
@@ -2971,7 +2759,7 @@ var LogWatcher = class {
|
|
|
2971
2759
|
this.filePositions.set(config.fileName, 0);
|
|
2972
2760
|
}
|
|
2973
2761
|
try {
|
|
2974
|
-
const watcher =
|
|
2762
|
+
const watcher = fs6.watch(filePath, (eventType) => {
|
|
2975
2763
|
if (eventType === "change") {
|
|
2976
2764
|
this.handleFileChange(config);
|
|
2977
2765
|
}
|
|
@@ -3006,10 +2794,10 @@ var LogWatcher = class {
|
|
|
3006
2794
|
* Handle file change event - read new content
|
|
3007
2795
|
*/
|
|
3008
2796
|
handleFileChange(config) {
|
|
3009
|
-
const filePath =
|
|
2797
|
+
const filePath = path3.join(this.logDir, config.fileName);
|
|
3010
2798
|
const lastPosition = this.filePositions.get(config.fileName) || 0;
|
|
3011
2799
|
try {
|
|
3012
|
-
const stats =
|
|
2800
|
+
const stats = fs6.statSync(filePath);
|
|
3013
2801
|
const currentSize = stats.size;
|
|
3014
2802
|
if (currentSize < lastPosition) {
|
|
3015
2803
|
this.log(`File ${config.fileName} was truncated, resetting position`);
|
|
@@ -3022,11 +2810,11 @@ var LogWatcher = class {
|
|
|
3022
2810
|
}
|
|
3023
2811
|
const readSize = currentSize - lastPosition;
|
|
3024
2812
|
const buffer = Buffer.alloc(readSize);
|
|
3025
|
-
const fd =
|
|
2813
|
+
const fd = fs6.openSync(filePath, "r");
|
|
3026
2814
|
try {
|
|
3027
|
-
|
|
2815
|
+
fs6.readSync(fd, buffer, 0, readSize, lastPosition);
|
|
3028
2816
|
} finally {
|
|
3029
|
-
|
|
2817
|
+
fs6.closeSync(fd);
|
|
3030
2818
|
}
|
|
3031
2819
|
this.filePositions.set(config.fileName, currentSize);
|
|
3032
2820
|
const content = buffer.toString("utf8");
|
|
@@ -3257,8 +3045,8 @@ __name(createSSEHandler, "createSSEHandler");
|
|
|
3257
3045
|
|
|
3258
3046
|
// src/middlewares/dev-logs/api-list-handler.ts
|
|
3259
3047
|
var SERVER_PORT = process.env.SERVER_PORT || "3000";
|
|
3260
|
-
function extractModuleFromPath(
|
|
3261
|
-
const segments =
|
|
3048
|
+
function extractModuleFromPath(path5) {
|
|
3049
|
+
const segments = path5.split("/").filter(Boolean);
|
|
3262
3050
|
let startIndex = 0;
|
|
3263
3051
|
if (segments[0] === "api") {
|
|
3264
3052
|
startIndex = 1;
|
|
@@ -3273,8 +3061,8 @@ function extractModuleFromPath(path7) {
|
|
|
3273
3061
|
return moduleName;
|
|
3274
3062
|
}
|
|
3275
3063
|
__name(extractModuleFromPath, "extractModuleFromPath");
|
|
3276
|
-
function generateRouteId(method,
|
|
3277
|
-
const cleanPath =
|
|
3064
|
+
function generateRouteId(method, path5) {
|
|
3065
|
+
const cleanPath = path5.replace(/[/:]/g, "_").replace(/^_+|_+$/g, "");
|
|
3278
3066
|
return `${method.toLowerCase()}_${cleanPath}`;
|
|
3279
3067
|
}
|
|
3280
3068
|
__name(generateRouteId, "generateRouteId");
|
|
@@ -3432,11 +3220,11 @@ import express3 from "express";
|
|
|
3432
3220
|
|
|
3433
3221
|
// src/middlewares/collect-logs/controller.ts
|
|
3434
3222
|
import { join as join7 } from "path";
|
|
3435
|
-
import
|
|
3223
|
+
import fs8 from "fs";
|
|
3436
3224
|
|
|
3437
3225
|
// src/middlewares/collect-logs/utils.ts
|
|
3438
3226
|
import { isAbsolute as isAbsolute2, join as join6 } from "path";
|
|
3439
|
-
import
|
|
3227
|
+
import fs7 from "fs";
|
|
3440
3228
|
function resolveLogDir2(provided) {
|
|
3441
3229
|
if (!provided) {
|
|
3442
3230
|
return join6(process.cwd(), "logs");
|
|
@@ -3445,8 +3233,8 @@ function resolveLogDir2(provided) {
|
|
|
3445
3233
|
}
|
|
3446
3234
|
__name(resolveLogDir2, "resolveLogDir");
|
|
3447
3235
|
function ensureDir(dir) {
|
|
3448
|
-
if (!
|
|
3449
|
-
|
|
3236
|
+
if (!fs7.existsSync(dir)) {
|
|
3237
|
+
fs7.mkdirSync(dir, {
|
|
3450
3238
|
recursive: true
|
|
3451
3239
|
});
|
|
3452
3240
|
}
|
|
@@ -3478,7 +3266,7 @@ function collectLogsHandler(logDir, fileName) {
|
|
|
3478
3266
|
...logContent,
|
|
3479
3267
|
server_time: (/* @__PURE__ */ new Date()).toISOString()
|
|
3480
3268
|
}) + "\n";
|
|
3481
|
-
await
|
|
3269
|
+
await fs8.promises.appendFile(filePath, logLine);
|
|
3482
3270
|
res.json({
|
|
3483
3271
|
success: true
|
|
3484
3272
|
});
|
|
@@ -3506,7 +3294,7 @@ function collectLogsBatchHandler(logDir, fileName) {
|
|
|
3506
3294
|
server_time: (/* @__PURE__ */ new Date()).toISOString()
|
|
3507
3295
|
}) + "\n");
|
|
3508
3296
|
}
|
|
3509
|
-
await
|
|
3297
|
+
await fs8.promises.appendFile(filePath, logLines.join(""));
|
|
3510
3298
|
res.json({
|
|
3511
3299
|
success: true
|
|
3512
3300
|
});
|
|
@@ -3525,7 +3313,7 @@ function handleError2(res, error, message = "Failed to collect logs") {
|
|
|
3525
3313
|
__name(handleError2, "handleError");
|
|
3526
3314
|
|
|
3527
3315
|
// src/middlewares/collect-logs/router.ts
|
|
3528
|
-
var DEFAULT_BODY_SIZE_LIMIT = "
|
|
3316
|
+
var DEFAULT_BODY_SIZE_LIMIT = "20mb";
|
|
3529
3317
|
function getBodySizeLimit() {
|
|
3530
3318
|
return process.env.BODY_SIZE_LIMIT || DEFAULT_BODY_SIZE_LIMIT;
|
|
3531
3319
|
}
|
|
@@ -3672,7 +3460,7 @@ function isGlobalMiddleware(middleware) {
|
|
|
3672
3460
|
}
|
|
3673
3461
|
__name(isGlobalMiddleware, "isGlobalMiddleware");
|
|
3674
3462
|
function computeMountPath(basePath, mountPath) {
|
|
3675
|
-
const routePath =
|
|
3463
|
+
const routePath = path4.posix.join(basePath, mountPath);
|
|
3676
3464
|
return routePath.startsWith("/") ? routePath : `/${routePath}`;
|
|
3677
3465
|
}
|
|
3678
3466
|
__name(computeMountPath, "computeMountPath");
|
|
@@ -3680,7 +3468,7 @@ function logMiddlewareRegistration(middleware, fullMountPath) {
|
|
|
3680
3468
|
if (middleware.routes && middleware.routes.length > 0) {
|
|
3681
3469
|
console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);
|
|
3682
3470
|
middleware.routes.forEach((route) => {
|
|
3683
|
-
const routePath = route.path === "/" ? fullMountPath :
|
|
3471
|
+
const routePath = route.path === "/" ? fullMountPath : path4.posix.join(fullMountPath, route.path);
|
|
3684
3472
|
console.log(` ${route.method} ${routePath} - ${route.description}`);
|
|
3685
3473
|
});
|
|
3686
3474
|
} else {
|
|
@@ -3749,16 +3537,24 @@ async function registerMiddlewares(server, middlewares, options) {
|
|
|
3749
3537
|
}
|
|
3750
3538
|
__name(registerMiddlewares, "registerMiddlewares");
|
|
3751
3539
|
export {
|
|
3540
|
+
buildFullPath,
|
|
3541
|
+
calculateFileHash,
|
|
3752
3542
|
createCollectLogsMiddleware,
|
|
3753
3543
|
createDevLogsMiddleware,
|
|
3754
3544
|
createOpenapiMiddleware,
|
|
3545
|
+
evaluateTemplateLiteral,
|
|
3546
|
+
extractPageRouteInfo,
|
|
3755
3547
|
getQuery,
|
|
3756
3548
|
getQueryParam,
|
|
3757
3549
|
handleDevProxyError,
|
|
3550
|
+
isRouteComponent,
|
|
3758
3551
|
normalizeBasePath,
|
|
3759
3552
|
parseAndGenerateNestResourceTemplate,
|
|
3553
|
+
parseApiRoutes,
|
|
3554
|
+
parseRoutesFromFile,
|
|
3760
3555
|
postprocessDrizzleSchema,
|
|
3761
3556
|
registerMiddlewares,
|
|
3557
|
+
routeParserLog,
|
|
3762
3558
|
sendError,
|
|
3763
3559
|
sendJson,
|
|
3764
3560
|
sendSuccess
|