@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.
- package/dist/index.js +186 -42
- 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 = [
|
|
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(
|
|
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)
|
|
7928
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
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",
|