@lark-apaas/fullstack-cli 1.1.68-alpha.20261019123412 → 1.1.68-alpha.20261020063206

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.
Files changed (2) hide show
  1. package/dist/index.js +184 -42
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -7786,8 +7786,140 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
7786
7786
  return { lines: collected.reverse(), totalLinesCount };
7787
7787
  }
7788
7788
 
7789
+ // src/commands/read-logs/std-level.ts
7790
+ var STD_LEVEL_SCAN_LINES = 2e3;
7791
+ var ANSI_PATTERN = /\u001b\[[0-?]*[ -/]*[@-~]/g;
7792
+ var TRANSIENT_CONNECTION_ERROR_PATTERN = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENETUNREACH|socket hang up|proxy error(?!.*ENOTFOUND)|\[Proxy\] (?:Error:\s*$|Error during|Connection error|Non-connection error|Headers already sent|Service (?:recovered|did not recover))/i;
7793
+ var ERROR_PATTERNS = [
7794
+ /compiled with errors/i,
7795
+ /failed to compile/i,
7796
+ /\[vite\].*(?:internal server error|pre-transform error)/i,
7797
+ /\berror:\s*\S+/i,
7798
+ /\b(?:uncaught|unhandled|fatal|exception)\b/i,
7799
+ /\beaddrinuse\b/i,
7800
+ /\b(?:cannot find module|module not found)\b/i,
7801
+ /\bts\d{3,5}:/i,
7802
+ /\b(?:syntax|type|reference|range)error\b/i,
7803
+ /\bENOTFOUND\b/i,
7804
+ /\berror\b/i
7805
+ ];
7806
+ var WARN_PATTERNS = [
7807
+ /compiled with warnings/i,
7808
+ /(?:^|[\s)])[\w$.-]*Warning\s*:/i,
7809
+ /\bWARN(?:ING)?S?\b(?:\s|:|\])/,
7810
+ /\[vite\].*\bwarn(?:ing)?s?\b/i,
7811
+ /\bdeprecated\b/i,
7812
+ /\bdeprecation\b/i
7813
+ ];
7814
+ var IGNORE_PATTERNS = [/\b0\s+errors?\b/i, /Server Error \d{3}/i];
7815
+ function comparableText(line) {
7816
+ return line.replace(ANSI_PATTERN, "");
7817
+ }
7818
+ function contentWithoutTimestamp(line) {
7819
+ return comparableText(line).replace(/^\[[^\]]+\]\s?/, "");
7820
+ }
7821
+ function isTransientStdLine(line) {
7822
+ return TRANSIENT_CONNECTION_ERROR_PATTERN.test(comparableText(line));
7823
+ }
7824
+ function classifyStdLine(line) {
7825
+ const text = contentWithoutTimestamp(line).trim();
7826
+ if (!text || isTransientStdLine(text) || IGNORE_PATTERNS.some((pattern) => pattern.test(text))) {
7827
+ return void 0;
7828
+ }
7829
+ if (WARN_PATTERNS.some((pattern) => pattern.test(text))) return "warn";
7830
+ if (ERROR_PATTERNS.some((pattern) => pattern.test(text))) return "error";
7831
+ return void 0;
7832
+ }
7833
+ function isDiagnosticContinuation(line) {
7834
+ const content = contentWithoutTimestamp(line);
7835
+ if (!content.trim()) return true;
7836
+ return /^\s+/.test(content) || /^\s*(?:Plugin|File|Location|Caused by):/i.test(content) || /^\s*(?:at\s+|\.\.\.\s+\d+\s+more)/.test(content) || /^\s*(?:>?\s*\d+\s*\||\||\^|~)/.test(content) || /^\s*(?:Error|AggregateError)\s*\{?$/i.test(content);
7837
+ }
7838
+ function summarizeStack(lines) {
7839
+ const result = [];
7840
+ let stackLines = 0;
7841
+ for (const line of lines) {
7842
+ const content = contentWithoutTimestamp(line);
7843
+ const isStack = /^\s*at\s+/.test(content);
7844
+ if (isStack) {
7845
+ if (stackLines >= 3) continue;
7846
+ stackLines += 1;
7847
+ }
7848
+ result.push(line);
7849
+ }
7850
+ return result;
7851
+ }
7852
+ function normalizeRequestedStdLevels(levels) {
7853
+ if (!levels?.length) return void 0;
7854
+ const normalized = new Set(
7855
+ levels.map((level) => level.trim().toLowerCase()).filter(Boolean)
7856
+ );
7857
+ if (normalized.has("info")) return void 0;
7858
+ const supported = /* @__PURE__ */ new Set();
7859
+ if (normalized.has("error")) supported.add("error");
7860
+ if (normalized.has("warn") || normalized.has("warning"))
7861
+ supported.add("warn");
7862
+ return supported;
7863
+ }
7864
+ function extractStdDiagnosticBlocks(lines, requestedLevels) {
7865
+ const blocks = [];
7866
+ for (let index = 0; index < lines.length; index += 1) {
7867
+ const line = lines[index] ?? "";
7868
+ const level = classifyStdLine(line);
7869
+ if (!level || !requestedLevels.has(level)) continue;
7870
+ const blockLines = [line];
7871
+ let next = index + 1;
7872
+ while (next < lines.length) {
7873
+ const candidate = lines[next] ?? "";
7874
+ if (isDiagnosticContinuation(candidate)) {
7875
+ blockLines.push(candidate);
7876
+ next += 1;
7877
+ continue;
7878
+ }
7879
+ const candidateLevel = classifyStdLine(candidate);
7880
+ if (candidateLevel) break;
7881
+ break;
7882
+ }
7883
+ while (blockLines.length > 1 && !contentWithoutTimestamp(blockLines[blockLines.length - 1] ?? "").trim()) {
7884
+ blockLines.pop();
7885
+ }
7886
+ blocks.push({ level, lines: summarizeStack(blockLines) });
7887
+ index = next - 1;
7888
+ }
7889
+ return blocks;
7890
+ }
7891
+ function paginateStdDiagnosticBlocks(blocks, maxLines, offset) {
7892
+ let skippedLines = 0;
7893
+ let selectedLines = 0;
7894
+ const selected = [];
7895
+ for (let index = blocks.length - 1; index >= 0; index -= 1) {
7896
+ const block = blocks[index];
7897
+ if (!block) continue;
7898
+ if (skippedLines < offset) {
7899
+ skippedLines += block.lines.length;
7900
+ continue;
7901
+ }
7902
+ if (selectedLines >= maxLines) break;
7903
+ selected.unshift(block);
7904
+ selectedLines += block.lines.length;
7905
+ }
7906
+ return selected.flatMap((block) => block.lines);
7907
+ }
7908
+ function hasErrorInStdLines(lines) {
7909
+ return lines.some((line) => classifyStdLine(line) === "error");
7910
+ }
7911
+
7789
7912
  // src/commands/read-logs/index.ts
7790
- var LOG_TYPES = ["server", "trace", "server-std", "client-std", "dev", "dev-std", "install-dep-std", "browser"];
7913
+ var LOG_TYPES = [
7914
+ "server",
7915
+ "trace",
7916
+ "server-std",
7917
+ "client-std",
7918
+ "dev",
7919
+ "dev-std",
7920
+ "install-dep-std",
7921
+ "browser"
7922
+ ];
7791
7923
  function normalizeObjectKey(key) {
7792
7924
  return key.toLowerCase().replace(/_/g, "");
7793
7925
  }
@@ -7810,7 +7942,9 @@ function formatIsoWithLocalOffset(date, includeMilliseconds) {
7810
7942
  return `${year}-${month}-${day}T${hour}:${minute}:${second}${msPart}${sign}${offsetHH}:${offsetMM}`;
7811
7943
  }
7812
7944
  function formatLocalDateTimeStringWithOffset(input) {
7813
- const match = input.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
7945
+ const match = input.match(
7946
+ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/
7947
+ );
7814
7948
  if (!match) return input;
7815
7949
  const year = Number(match[1]);
7816
7950
  const month = Number(match[2]);
@@ -7886,35 +8020,6 @@ function sanitizeStructuredLog(value) {
7886
8020
  }
7887
8021
  return sanitized;
7888
8022
  }
7889
- var TRANSIENT_CONNECTION_ERROR_PATTERN = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENETUNREACH|socket hang up|proxy error|\[Proxy\] (?:Error:\s*$|Error during|Connection error|Non-connection error|Headers already sent|Service (?:recovered|did not recover))/i;
7890
- function hasErrorInStdLines(lines) {
7891
- const filtered = lines.filter((line) => !TRANSIENT_CONNECTION_ERROR_PATTERN.test(line));
7892
- const combined = filtered.join("\n");
7893
- if (!combined) return false;
7894
- const strong = [
7895
- /compiled with errors/i,
7896
- /failed to compile/i,
7897
- /error: \w+/i,
7898
- /uncaught/i,
7899
- /unhandled/i,
7900
- /eaddrinuse/i,
7901
- /cannot find module/i,
7902
- /module not found/i,
7903
- /ts\d{3,5}:/i
7904
- ];
7905
- if (strong.some((re) => re.test(combined))) return true;
7906
- const weakLine = /\b(error|fatal|exception)\b/i;
7907
- const ignorePatterns = [
7908
- /\b0\s+errors?\b/i,
7909
- /Server Error \d{3}/i
7910
- ];
7911
- return filtered.some((line) => {
7912
- const text = line.trim();
7913
- if (!text) return false;
7914
- if (ignorePatterns.some((re) => re.test(text))) return false;
7915
- return weakLine.test(text);
7916
- });
7917
- }
7918
8023
  function hasErrorInLogObject(value) {
7919
8024
  if (!value || typeof value !== "object") return false;
7920
8025
  const obj = value;
@@ -7924,8 +8029,10 @@ function hasErrorInLogObject(value) {
7924
8029
  const level = typeof rawLevel === "string" ? rawLevel.toLowerCase() : "";
7925
8030
  if (level === "error" || level === "fatal") return true;
7926
8031
  if (level === "err") return true;
7927
- if (typeof rawLevel === "number" && Number.isFinite(rawLevel) && rawLevel >= 50) return true;
7928
- if (level === "warn" && typeof obj.stack === "string" && obj.stack.length > 0) return true;
8032
+ if (typeof rawLevel === "number" && Number.isFinite(rawLevel) && rawLevel >= 50)
8033
+ return true;
8034
+ if (level === "warn" && typeof obj.stack === "string" && obj.stack.length > 0)
8035
+ return true;
7929
8036
  if (typeof obj.stack === "string" && obj.stack.length > 0) return true;
7930
8037
  const statusCode = obj.statusCode;
7931
8038
  const status_code = obj.status_code;
@@ -7952,10 +8059,35 @@ async function readLatestLogLinesMeta(options) {
7952
8059
  throw new Error(`Log file not found: ${filePath}`);
7953
8060
  }
7954
8061
  if (options.type === "server-std") {
7955
- return readServerStdSegment(filePath, maxLines, offset);
8062
+ const requestedLevels = normalizeRequestedStdLevels(levels);
8063
+ if (!requestedLevels)
8064
+ return readServerStdSegment(filePath, maxLines, offset);
8065
+ const segment = readServerStdSegment(filePath, STD_LEVEL_SCAN_LINES, 0);
8066
+ const blocks = extractStdDiagnosticBlocks(segment.lines, requestedLevels);
8067
+ return {
8068
+ lines: paginateStdDiagnosticBlocks(blocks, maxLines, offset),
8069
+ totalLinesCount: blocks.reduce(
8070
+ (sum, block) => sum + block.lines.length,
8071
+ 0
8072
+ ),
8073
+ allLines: blocks.flatMap((block) => block.lines)
8074
+ };
7956
8075
  }
7957
8076
  if (options.type === "client-std") {
7958
- return readClientStdSegment(filePath, maxLines, offset);
8077
+ const requestedLevels = normalizeRequestedStdLevels(levels);
8078
+ if (!requestedLevels)
8079
+ return readClientStdSegment(filePath, maxLines, offset);
8080
+ const segment = readClientStdSegment(filePath, STD_LEVEL_SCAN_LINES, 0);
8081
+ const scanLines = segment.allLines.slice(-STD_LEVEL_SCAN_LINES);
8082
+ const blocks = extractStdDiagnosticBlocks(scanLines, requestedLevels);
8083
+ return {
8084
+ lines: paginateStdDiagnosticBlocks(blocks, maxLines, offset),
8085
+ totalLinesCount: blocks.reduce(
8086
+ (sum, block) => sum + block.lines.length,
8087
+ 0
8088
+ ),
8089
+ allLines: blocks.flatMap((block) => block.lines)
8090
+ };
7959
8091
  }
7960
8092
  if (options.type === "dev") {
7961
8093
  return readDevSegment(filePath, maxLines, offset);
@@ -7987,15 +8119,16 @@ async function readLogsJsonResult(options) {
7987
8119
  const linesForErrorCheck = allLines ?? lines;
7988
8120
  const stackTracePattern = /\bat\s+\S+\s+\([^)]+:\d+:\d+\)/;
7989
8121
  const linesToFilter = allLines ?? lines;
7990
- const filteredLines = linesToFilter.filter((line) => !stackTracePattern.test(line));
8122
+ const stdLevelFilteringActive = (options.type === "server-std" || options.type === "client-std") && Boolean(normalizeRequestedStdLevels(options.levels));
8123
+ const filteredLines = stdLevelFilteringActive ? linesToFilter : linesToFilter.filter((line) => !stackTracePattern.test(line));
7991
8124
  const maxLines = options.maxLines ?? 30;
7992
8125
  const offset = options.offset ?? 0;
7993
8126
  const endExclusive = Math.max(0, filteredLines.length - offset);
7994
8127
  const start = Math.max(0, endExclusive - maxLines);
7995
- const paginatedLogs = filteredLines.slice(start, endExclusive);
8128
+ const paginatedLogs = stdLevelFilteringActive ? lines : filteredLines.slice(start, endExclusive);
7996
8129
  return {
7997
8130
  hasError: hasErrorInStdLines(linesForErrorCheck),
7998
- totalLinesCount: filteredLines.length,
8131
+ totalLinesCount: stdLevelFilteringActive ? totalLinesCount : filteredLines.length,
7999
8132
  logs: paginatedLogs
8000
8133
  };
8001
8134
  }
@@ -8059,19 +8192,25 @@ function parseLogType(input) {
8059
8192
  if (LOG_TYPES.includes(value)) {
8060
8193
  return value;
8061
8194
  }
8062
- throw new Error(`Invalid --type: ${String(input)}. Expected one of: ${LOG_TYPES.join(", ")}`);
8195
+ throw new Error(
8196
+ `Invalid --type: ${String(input)}. Expected one of: ${LOG_TYPES.join(", ")}`
8197
+ );
8063
8198
  }
8064
8199
  function parsePositiveInt(input, flagName) {
8065
8200
  const value = typeof input === "number" ? input : Number.parseInt(String(input), 10);
8066
8201
  if (!Number.isFinite(value) || value <= 0) {
8067
- throw new Error(`Invalid ${flagName}: ${String(input)}. Expected a positive integer.`);
8202
+ throw new Error(
8203
+ `Invalid ${flagName}: ${String(input)}. Expected a positive integer.`
8204
+ );
8068
8205
  }
8069
8206
  return value;
8070
8207
  }
8071
8208
  function parseNonNegativeInt(input, flagName) {
8072
8209
  const value = typeof input === "number" ? input : Number.parseInt(String(input), 10);
8073
8210
  if (!Number.isFinite(value) || value < 0) {
8074
- throw new Error(`Invalid ${flagName}: ${String(input)}. Expected a non-negative integer.`);
8211
+ throw new Error(
8212
+ `Invalid ${flagName}: ${String(input)}. Expected a non-negative integer.`
8213
+ );
8075
8214
  }
8076
8215
  return value;
8077
8216
  }
@@ -8084,7 +8223,10 @@ var readLogsCommand = {
8084
8223
  name: "read-logs",
8085
8224
  description: "Read latest logs from log files",
8086
8225
  register(program) {
8087
- program.command(this.name).description(this.description).option("--dir <path>", "Logs directory", "/tmp").option("--type <type>", `Log type: ${LOG_TYPES.join("|")}`, "server-std").option("--max-lines <lines>", "Max lines to return", "30").option("--offset <lines>", "Skip latest N lines for pagination", "0").option("--trace-id <id>", "Filter structured logs by trace id").option("--level <levels>", "Filter structured logs by level (comma-separated)").action(async (rawOptions) => {
8226
+ program.command(this.name).description(this.description).option("--dir <path>", "Logs directory", "/tmp").option("--type <type>", `Log type: ${LOG_TYPES.join("|")}`, "server-std").option("--max-lines <lines>", "Max lines to return", "30").option("--offset <lines>", "Skip latest N lines for pagination", "0").option("--trace-id <id>", "Filter structured logs by trace id").option(
8227
+ "--level <levels>",
8228
+ "Filter structured logs or std diagnostic blocks by level (comma-separated)"
8229
+ ).action(async (rawOptions) => {
8088
8230
  try {
8089
8231
  const logDir = typeof rawOptions.dir === "string" ? rawOptions.dir : "/tmp";
8090
8232
  const type = parseLogType(rawOptions.type);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.68-alpha.20261019123412",
3
+ "version": "1.1.68-alpha.20261020063206",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@lark-apaas/http-client": "0.1.8-alpha.20261019123410",
34
+ "@lark-apaas/http-client": "^0.1.7",
35
35
  "@lydell/node-pty": "1.1.0",
36
36
  "@vercel/nft": "^0.30.3",
37
37
  "commander": "^13.0.0",