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

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