@lark-apaas/devtool-kits 1.2.5-alpha.1 → 1.2.5-alpha.2

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/index.cjs CHANGED
@@ -2136,229 +2136,146 @@ async function readLogFilePage(filePath, page, pageSize) {
2136
2136
  };
2137
2137
  }
2138
2138
  __name(readLogFilePage, "readLogFilePage");
2139
- async function readServerLogs(logDir, options = {}) {
2140
- const limit = options.limit || 100;
2141
- const offset = options.offset || 0;
2142
- const sources = options.sources || [
2143
- "server",
2144
- "trace",
2145
- "server-std",
2146
- "client-std"
2147
- ];
2148
- const allLogs = [];
2149
- const errors = [];
2150
- for (const source of sources) {
2151
- try {
2152
- const logs = await readLogsBySource(logDir, source);
2153
- allLogs.push(...logs);
2154
- } catch (error) {
2155
- const errorMsg = `Failed to read ${source}: ${error instanceof Error ? error.message : String(error)}`;
2156
- errors.push(errorMsg);
2157
- console.warn(`[readServerLogs] ${errorMsg}`);
2158
- }
2159
- }
2160
- if (allLogs.length === 0) {
2161
- if (errors.length > 0) {
2162
- console.warn(`[readServerLogs] No logs found. Errors: ${errors.join(", ")}`);
2163
- }
2139
+ async function readTriggerList(filePath, trigger, path7, limit) {
2140
+ if (!await fileExists(filePath)) {
2164
2141
  return void 0;
2165
2142
  }
2166
- let filteredLogs = allLogs;
2167
- if (options.levels && options.levels.length > 0) {
2168
- filteredLogs = allLogs.filter((log) => options.levels.includes(log.level));
2169
- }
2170
- filteredLogs.sort((a, b) => b.timestamp - a.timestamp);
2171
- const total = filteredLogs.length;
2172
- const paginatedLogs = filteredLogs.slice(offset, offset + limit);
2173
- return {
2174
- logs: paginatedLogs,
2175
- total,
2176
- hasMore: offset + limit < total
2143
+ const config = {
2144
+ maxEntriesPerTrace: 10,
2145
+ chunkSize: 64 * 1024
2177
2146
  };
2178
- }
2179
- __name(readServerLogs, "readServerLogs");
2180
- async function readLogsBySource(logDir, source) {
2181
- const { join: join6 } = await import("path");
2182
- let filePath;
2183
- let parser;
2184
- if (source === "server") {
2185
- filePath = join6(logDir, "server.log");
2186
- parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
2187
- } else if (source === "trace") {
2188
- filePath = join6(logDir, "trace.log");
2189
- parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
2190
- } else if (source === "server-std") {
2191
- filePath = join6(logDir, "server.std.log");
2192
- parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
2193
- } else if (source === "client-std") {
2194
- filePath = join6(logDir, "client.std.log");
2195
- parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
2196
- } else {
2197
- console.warn(`[readLogsBySource] Unknown source: ${source}`);
2198
- return [];
2199
- }
2200
- if (!await fileExists(filePath)) {
2201
- console.warn(`[readLogsBySource] File not found: ${filePath}`);
2202
- return [];
2203
- }
2204
- const logs = [];
2205
- let stream = null;
2206
- let rl = null;
2207
- try {
2208
- stream = (0, import_node_fs7.createReadStream)(filePath, {
2209
- encoding: "utf8"
2210
- });
2211
- rl = (0, import_node_readline.createInterface)({
2212
- input: stream,
2213
- crlfDelay: Infinity
2214
- });
2215
- for await (const line of rl) {
2216
- if (!line.trim()) continue;
2217
- try {
2218
- const log = parser(line);
2219
- if (log) {
2220
- logs.push(log);
2221
- }
2222
- } catch (parseError) {
2147
+ const builders = /* @__PURE__ */ new Map();
2148
+ const completedCalls = [];
2149
+ const createTraceBuilder = /* @__PURE__ */ __name((traceId) => ({
2150
+ traceId,
2151
+ entries: [],
2152
+ method: void 0,
2153
+ path: void 0,
2154
+ startTime: void 0,
2155
+ endTime: void 0,
2156
+ statusCode: void 0,
2157
+ durationMs: void 0,
2158
+ hasCompleted: false
2159
+ }), "createTraceBuilder");
2160
+ const shouldIncludeInCompletedCalls = /* @__PURE__ */ __name((builder) => {
2161
+ const alreadyAdded = completedCalls.some((call) => call.traceId === builder.traceId);
2162
+ if (alreadyAdded) {
2163
+ return false;
2164
+ }
2165
+ if (!builder.hasCompleted) {
2166
+ return false;
2167
+ }
2168
+ const isAutomationTrigger = builder.path === path7;
2169
+ if (!isAutomationTrigger) {
2170
+ return false;
2171
+ }
2172
+ if (trigger && builder.entries.length > 0) {
2173
+ const requestEntry = builder.entries.find((e) => e.request_body?.trigger);
2174
+ if (requestEntry?.request_body?.trigger) {
2175
+ return String(requestEntry.request_body.trigger) === trigger;
2223
2176
  }
2177
+ return false;
2224
2178
  }
2225
- } catch (error) {
2226
- console.error(`[readLogsBySource] Error reading ${filePath}:`, error);
2227
- throw error;
2228
- } finally {
2229
- if (rl) {
2230
- rl.close();
2179
+ return true;
2180
+ }, "shouldIncludeInCompletedCalls");
2181
+ const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
2182
+ if (entry.method && !builder.method) builder.method = String(entry.method);
2183
+ if (entry.path && !builder.path) builder.path = String(entry.path);
2184
+ builder.entries.push(entry);
2185
+ if (builder.entries.length > config.maxEntriesPerTrace) {
2186
+ builder.entries.shift();
2231
2187
  }
2232
- if (stream) {
2233
- stream.close();
2188
+ if (shouldIncludeInCompletedCalls(builder)) {
2189
+ completedCalls.push(builder);
2190
+ if (limit && completedCalls.length > limit) {
2191
+ completedCalls.shift();
2192
+ }
2234
2193
  }
2235
- }
2236
- return logs;
2237
- }
2238
- __name(readLogsBySource, "readLogsBySource");
2239
- function parsePinoLog(line, source) {
2240
- try {
2241
- const pinoLog = JSON.parse(line);
2242
- const id = generateUUID();
2243
- return {
2244
- id,
2245
- level: mapPinoLevelToServerLogLevel(pinoLog.level),
2246
- timestamp: new Date(pinoLog.time).getTime(),
2247
- message: pinoLog.message || pinoLog.msg || "",
2248
- context: pinoLog.context || null,
2249
- traceId: pinoLog.trace_id || null,
2250
- userId: pinoLog.user_id || null,
2251
- appId: pinoLog.app_id || null,
2252
- tenantId: pinoLog.tenant_id || null,
2253
- stack: pinoLog.stack || null,
2254
- meta: {
2255
- pid: pinoLog.pid,
2256
- hostname: pinoLog.hostname,
2257
- path: pinoLog.path,
2258
- method: pinoLog.method,
2259
- statusCode: pinoLog.status_code,
2260
- durationMs: pinoLog.duration_ms,
2261
- ip: pinoLog.ip,
2262
- requestBody: pinoLog.request_body,
2263
- responseBody: pinoLog.response_body
2264
- },
2265
- tags: [
2266
- source
2267
- ]
2268
- };
2269
- } catch (error) {
2270
- return null;
2271
- }
2272
- }
2273
- __name(parsePinoLog, "parsePinoLog");
2274
- function parseStdLog(line, source) {
2275
- const id = generateUUID();
2276
- const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2277
- if (!match) {
2278
- return {
2279
- id,
2280
- level: "log",
2281
- timestamp: Date.now(),
2282
- message: line,
2283
- context: null,
2284
- traceId: null,
2285
- userId: null,
2286
- appId: null,
2287
- tenantId: null,
2288
- stack: null,
2289
- meta: null,
2290
- tags: [
2291
- source
2292
- ]
2293
- };
2294
- }
2295
- const [, timeStr, , content] = match;
2296
- let timestamp;
2297
- try {
2298
- const isoStr = timeStr.replace(" ", "T");
2299
- timestamp = new Date(isoStr).getTime();
2300
- if (isNaN(timestamp)) {
2301
- timestamp = Date.now();
2194
+ }, "updateBuilderMetadata");
2195
+ const handleRequestCompleted = /* @__PURE__ */ __name((builder, entry, message) => {
2196
+ builder.hasCompleted = true;
2197
+ builder.endTime = entry.time;
2198
+ builder.statusCode = extractNumber(message, /status_code:\s*(\d+)/);
2199
+ builder.durationMs = extractNumber(message, /duration_ms:\s*(\d+)/);
2200
+ if (!builder.path && entry.path) {
2201
+ builder.path = String(entry.path);
2302
2202
  }
2303
- } catch (error) {
2304
- timestamp = Date.now();
2305
- }
2306
- const level = extractLogLevel(content);
2203
+ if (shouldIncludeInCompletedCalls(builder)) {
2204
+ completedCalls.push(builder);
2205
+ if (limit && completedCalls.length > limit) {
2206
+ completedCalls.shift();
2207
+ }
2208
+ }
2209
+ }, "handleRequestCompleted");
2210
+ const processLogEntry = /* @__PURE__ */ __name((entry) => {
2211
+ const { trace_id: traceId, message = "" } = entry;
2212
+ if (!traceId) return;
2213
+ let builder = builders.get(traceId);
2214
+ if (!builder) {
2215
+ builder = createTraceBuilder(traceId);
2216
+ builders.set(traceId, builder);
2217
+ }
2218
+ updateBuilderMetadata(builder, entry);
2219
+ if (!builder.hasCompleted && (message.includes("HTTP request completed") || message.includes("HTTP request failed"))) {
2220
+ handleRequestCompleted(builder, entry, message);
2221
+ }
2222
+ if (message.includes("HTTP request started") && !builder.startTime) {
2223
+ builder.startTime = entry.time;
2224
+ }
2225
+ }, "processLogEntry");
2226
+ const processLine = /* @__PURE__ */ __name((line) => {
2227
+ const entry = parseLogLine2(line);
2228
+ if (entry?.trace_id) {
2229
+ processLogEntry(entry);
2230
+ }
2231
+ }, "processLine");
2232
+ await readFileReverse(filePath, config.chunkSize, processLine);
2307
2233
  return {
2308
- id,
2309
- level,
2310
- timestamp,
2311
- message: content,
2312
- context: null,
2313
- traceId: null,
2314
- userId: null,
2315
- appId: null,
2316
- tenantId: null,
2317
- stack: null,
2318
- meta: null,
2319
- tags: [
2320
- source
2321
- ]
2234
+ page: 1,
2235
+ pageSize: completedCalls.length,
2236
+ totalCalls: completedCalls.length,
2237
+ totalPages: 1,
2238
+ calls: completedCalls.map((builder) => ({
2239
+ traceId: builder.traceId,
2240
+ method: builder.method,
2241
+ path: builder.path,
2242
+ startTime: builder.startTime,
2243
+ endTime: builder.endTime,
2244
+ statusCode: builder.statusCode,
2245
+ durationMs: builder.durationMs,
2246
+ entries: builder.entries.slice().reverse()
2247
+ }))
2322
2248
  };
2323
2249
  }
2324
- __name(parseStdLog, "parseStdLog");
2325
- function mapPinoLevelToServerLogLevel(pinoLevel) {
2326
- if (typeof pinoLevel === "string") {
2327
- const lower = pinoLevel.toLowerCase();
2328
- if (lower === "fatal") return "fatal";
2329
- if (lower === "error") return "error";
2330
- if (lower === "warn" || lower === "warning") return "warn";
2331
- if (lower === "info" || lower === "log") return "log";
2332
- if (lower === "debug") return "debug";
2333
- if (lower === "trace" || lower === "verbose") return "verbose";
2334
- return "log";
2335
- }
2336
- if (pinoLevel >= 60) return "fatal";
2337
- if (pinoLevel >= 50) return "error";
2338
- if (pinoLevel >= 40) return "warn";
2339
- if (pinoLevel >= 30) return "log";
2340
- if (pinoLevel >= 20) return "debug";
2341
- return "verbose";
2342
- }
2343
- __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2344
- function extractLogLevel(text) {
2345
- const lower = text.toLowerCase();
2346
- if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2347
- if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2348
- if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2349
- if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2350
- if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2351
- return "log";
2352
- }
2353
- __name(extractLogLevel, "extractLogLevel");
2354
- function generateUUID() {
2355
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2356
- const r = Math.random() * 16 | 0;
2357
- const v = c === "x" ? r : r & 3 | 8;
2358
- return v.toString(16);
2250
+ __name(readTriggerList, "readTriggerList");
2251
+ async function readTriggerDetail(filePath, instanceID) {
2252
+ const exists = await fileExists(filePath);
2253
+ if (!exists) {
2254
+ return void 0;
2255
+ }
2256
+ const matches = [];
2257
+ const stream = (0, import_node_fs7.createReadStream)(filePath, {
2258
+ encoding: "utf8"
2359
2259
  });
2260
+ const rl = (0, import_node_readline.createInterface)({
2261
+ input: stream,
2262
+ crlfDelay: Infinity
2263
+ });
2264
+ for await (const line of rl) {
2265
+ const entry = parseLogLine2(line);
2266
+ if (!entry) continue;
2267
+ const hasInstanceID = entry.message?.includes(`instanceID=${instanceID}`);
2268
+ if (!hasInstanceID) continue;
2269
+ matches.push(entry);
2270
+ }
2271
+ rl.close();
2272
+ stream.close();
2273
+ return {
2274
+ instanceID,
2275
+ entries: matches
2276
+ };
2360
2277
  }
2361
- __name(generateUUID, "generateUUID");
2278
+ __name(readTriggerDetail, "readTriggerDetail");
2362
2279
 
2363
2280
  // src/middlewares/dev-logs/controller.ts
2364
2281
  function handleNotFound(res, filePath, message = "Log file not found") {
@@ -2452,32 +2369,57 @@ function createGetLogFileHandler(logDir) {
2452
2369
  };
2453
2370
  }
2454
2371
  __name(createGetLogFileHandler, "createGetLogFileHandler");
2455
- function createGetServerLogsHandler(logDir) {
2372
+ function createGetTriggerListHandler(logDir) {
2373
+ const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
2456
2374
  return async (req, res) => {
2457
- const limit = parseLimit(req.query.limit, 100, 1e3);
2458
- const offset = parsePositiveInt(req.query.offset, 0);
2459
- const levels = req.query.levels ? String(req.query.levels).split(",").map((l) => l.trim()).filter(Boolean) : void 0;
2460
- const sources = req.query.sources ? String(req.query.sources).split(",").map((s) => s.trim()).filter(Boolean) : void 0;
2375
+ const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
2376
+ if (!trigger) {
2377
+ return res.status(400).json({
2378
+ message: "trigger is required"
2379
+ });
2380
+ }
2381
+ const path7 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
2382
+ const limit = parseLimit(req.query.limit, 10, 200);
2461
2383
  try {
2462
- const result = await readServerLogs(logDir, {
2463
- limit,
2464
- offset,
2465
- levels,
2466
- sources
2384
+ const result = await readTriggerList(traceLogPath, trigger, path7, limit);
2385
+ if (!result) {
2386
+ return handleNotFound(res, traceLogPath);
2387
+ }
2388
+ res.json({
2389
+ file: getRelativePath(traceLogPath),
2390
+ path: path7,
2391
+ ...result
2467
2392
  });
2393
+ } catch (error) {
2394
+ handleError(res, error, "Failed to read trace log");
2395
+ }
2396
+ };
2397
+ }
2398
+ __name(createGetTriggerListHandler, "createGetTriggerListHandler");
2399
+ function createGetTriggerDetailHandler(logDir) {
2400
+ const traceLogPath = (0, import_node_path7.join)(logDir, "server.log");
2401
+ return async (req, res) => {
2402
+ const instanceID = (req.params.instanceID || "").trim();
2403
+ if (!instanceID) {
2404
+ return res.status(400).json({
2405
+ message: "instanceID is required"
2406
+ });
2407
+ }
2408
+ try {
2409
+ const result = await readTriggerDetail(traceLogPath, instanceID);
2468
2410
  if (!result) {
2469
- return res.status(404).json({
2470
- message: "No server log files found",
2471
- hint: "Expected files: server.log, trace.log, server.std.log, client.std.log"
2472
- });
2411
+ return handleNotFound(res, traceLogPath);
2473
2412
  }
2474
- res.json(result);
2413
+ res.json({
2414
+ file: getRelativePath(traceLogPath),
2415
+ ...result
2416
+ });
2475
2417
  } catch (error) {
2476
- handleError(res, error, "Failed to read server logs");
2418
+ handleError(res, error, "Failed to read trace log");
2477
2419
  }
2478
2420
  };
2479
2421
  }
2480
- __name(createGetServerLogsHandler, "createGetServerLogsHandler");
2422
+ __name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
2481
2423
 
2482
2424
  // src/middlewares/dev-logs/health.controller.ts
2483
2425
  var import_node_http2 = __toESM(require("http"), 1);
@@ -2553,7 +2495,8 @@ function createDevLogRouter(options = {}) {
2553
2495
  router.get("/app/trace/:traceId", createGetTraceEntriesHandler(logDir));
2554
2496
  router.get("/trace/recent", createGetRecentTracesHandler(logDir));
2555
2497
  router.get("/files/:fileName", createGetLogFileHandler(logDir));
2556
- router.get("/server-logs", createGetServerLogsHandler(logDir));
2498
+ router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
2499
+ router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
2557
2500
  router.get("/health", createHealthCheckHandler());
2558
2501
  return router;
2559
2502
  }
@@ -2578,8 +2521,13 @@ var DEV_LOGS_ROUTES = [
2578
2521
  },
2579
2522
  {
2580
2523
  method: "GET",
2581
- path: "/server-logs",
2582
- description: "Get server logs in ServerLog format (compatible with frontend)"
2524
+ path: "/trace/trigger/list",
2525
+ description: "Get trigger list (automation trigger) in trace.log"
2526
+ },
2527
+ {
2528
+ method: "GET",
2529
+ path: "/trace/trigger/:instanceID",
2530
+ description: "Get trigger detail (automation trigger) in trace.log by instanceID"
2583
2531
  }
2584
2532
  ];
2585
2533
  function createDevLogsMiddleware(options = {}) {