@nasl/cli 0.2.2 → 0.2.3
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/nasl.mjs +76 -2
- package/dist/bin/nasl.mjs.map +1 -1
- package/dist/bin/naslc.mjs +12 -2
- package/dist/bin/naslc.mjs.map +1 -1
- package/dist/index.mjs +75 -1
- package/dist/index.mjs.map +1 -1
- package/out/commands/check.d.ts.map +1 -1
- package/out/commands/check.js +8 -0
- package/out/commands/check.js.map +1 -1
- package/out/services/compose.d.ts.map +1 -1
- package/out/services/compose.js +11 -1
- package/out/services/compose.js.map +1 -1
- package/out/types/api.d.ts +4 -0
- package/out/types/api.d.ts.map +1 -1
- package/out/utils/errorMapper.d.ts +14 -0
- package/out/utils/errorMapper.d.ts.map +1 -0
- package/out/utils/errorMapper.js +60 -0
- package/out/utils/errorMapper.js.map +1 -0
- package/package.json +1 -1
package/dist/bin/nasl.mjs
CHANGED
|
@@ -29326,7 +29326,10 @@ function validateNormalFile(file, nameFromPath, namespace, errors) {
|
|
|
29326
29326
|
function composeToString(files) {
|
|
29327
29327
|
files.sort((a, b) => sorter(a.path, b.path));
|
|
29328
29328
|
const errors = [];
|
|
29329
|
+
let currentLine = 1;
|
|
29329
29330
|
const result = files.map((file) => {
|
|
29331
|
+
// 记录这个文件的开始行号
|
|
29332
|
+
file.startLine = currentLine;
|
|
29330
29333
|
const arr = file.path.split('.');
|
|
29331
29334
|
const ext = arr.pop();
|
|
29332
29335
|
const nameFromPath = arr.pop();
|
|
@@ -29352,7 +29355,14 @@ function composeToString(files) {
|
|
|
29352
29355
|
else if (isThemeCss) {
|
|
29353
29356
|
content = ` $theme\`${content}\`;`;
|
|
29354
29357
|
}
|
|
29355
|
-
|
|
29358
|
+
const fileContent = `namespace ${namespace} {\n${content}\n}\n`;
|
|
29359
|
+
// 计算这个文件占用的行数(末尾 \n 导致 split 多一个空元素,减 1 得到实际行数)
|
|
29360
|
+
const lineCount = fileContent.split('\n').length - 1;
|
|
29361
|
+
// 记录这个文件的结束行号
|
|
29362
|
+
file.endLine = currentLine + lineCount - 1;
|
|
29363
|
+
// +1 是 join('\n') 在文件之间插入的换行符
|
|
29364
|
+
currentLine = file.endLine + 2;
|
|
29365
|
+
return fileContent;
|
|
29356
29366
|
})
|
|
29357
29367
|
.join('\n');
|
|
29358
29368
|
if (errors.length > 0) {
|
|
@@ -38312,6 +38322,63 @@ async function tryCompile(entry, options) {
|
|
|
38312
38322
|
}
|
|
38313
38323
|
}
|
|
38314
38324
|
|
|
38325
|
+
/**
|
|
38326
|
+
* 将错误信息中的行号映射回原始文件
|
|
38327
|
+
* 直接替换错误头中的文件路径和行号,并调整代码片段中的行号
|
|
38328
|
+
*/
|
|
38329
|
+
function mapErrorToSourceFile(options) {
|
|
38330
|
+
const { errorMessage, collectedFiles } = options;
|
|
38331
|
+
// 构建行号到文件的映射
|
|
38332
|
+
const lineToFileMap = new Map();
|
|
38333
|
+
collectedFiles.forEach((file) => {
|
|
38334
|
+
if (file.startLine !== undefined && file.endLine !== undefined) {
|
|
38335
|
+
for (let i = file.startLine; i <= file.endLine; i++) {
|
|
38336
|
+
const lineInFile = i - file.startLine;
|
|
38337
|
+
lineToFileMap.set(i, { file, lineInFile });
|
|
38338
|
+
}
|
|
38339
|
+
}
|
|
38340
|
+
});
|
|
38341
|
+
// 处理单个错误块:替换路径、行号,调整代码片段行号
|
|
38342
|
+
function processBlock(block) {
|
|
38343
|
+
// 匹配错误头: 可选的 "N. " 前缀 + "filepath: message (line:col)"
|
|
38344
|
+
const headerMatch = block.match(/^((?:\d+\.\s+)?)(.*?):\s+(.*?)\((\d+):(\d+)\)/);
|
|
38345
|
+
if (!headerMatch)
|
|
38346
|
+
return block;
|
|
38347
|
+
const [fullHeader, prefix, , message, lineStr, colStr] = headerMatch;
|
|
38348
|
+
const originalLine = parseInt(lineStr, 10);
|
|
38349
|
+
const fileInfo = lineToFileMap.get(originalLine);
|
|
38350
|
+
if (!fileInfo)
|
|
38351
|
+
return block;
|
|
38352
|
+
const { file, lineInFile } = fileInfo;
|
|
38353
|
+
const lineOffset = originalLine - lineInFile;
|
|
38354
|
+
// 替换错误头中的路径和行号
|
|
38355
|
+
let mapped = block.replace(fullHeader, `${prefix}${file.path}: ${message}(${lineInFile}:${colStr})`);
|
|
38356
|
+
// 收集代码片段中所有行号并计算映射后的值
|
|
38357
|
+
const snippetNumbers = [];
|
|
38358
|
+
const collectRegex = /^([> ]*?)(\d+)(\s*\|)/gm;
|
|
38359
|
+
let m;
|
|
38360
|
+
while ((m = collectRegex.exec(mapped)) !== null) {
|
|
38361
|
+
snippetNumbers.push(parseInt(m[2], 10) - lineOffset);
|
|
38362
|
+
}
|
|
38363
|
+
// 替换代码片段中的行号,保持对齐
|
|
38364
|
+
if (snippetNumbers.length > 0) {
|
|
38365
|
+
const maxWidth = Math.max(...snippetNumbers.map((n) => String(n).length));
|
|
38366
|
+
let idx = 0;
|
|
38367
|
+
mapped = mapped.replace(/^([> ]*?)(\d+)(\s*\|)/gm, (fullMatch, lead) => {
|
|
38368
|
+
const newNum = snippetNumbers[idx++];
|
|
38369
|
+
if (newNum <= 0)
|
|
38370
|
+
return fullMatch;
|
|
38371
|
+
const paddedNum = String(newNum).padStart(maxWidth);
|
|
38372
|
+
return lead.includes('>') ? `> ${paddedNum} |` : ` ${paddedNum} |`;
|
|
38373
|
+
});
|
|
38374
|
+
}
|
|
38375
|
+
return mapped;
|
|
38376
|
+
}
|
|
38377
|
+
// 按编号前缀分割为独立错误块,分别处理
|
|
38378
|
+
const parts = errorMessage.split(/(?=^\d+\.\s)/m);
|
|
38379
|
+
return parts.map(processBlock).join('');
|
|
38380
|
+
}
|
|
38381
|
+
|
|
38315
38382
|
/**
|
|
38316
38383
|
* 检查命令 - 检查 NASL 代码的语法和语义
|
|
38317
38384
|
*/
|
|
@@ -38333,6 +38400,13 @@ async function check(entry, options) {
|
|
|
38333
38400
|
}
|
|
38334
38401
|
if (!result && fullNaturalTS) {
|
|
38335
38402
|
result = (await checkApi(fullNaturalTS, config)).trim();
|
|
38403
|
+
// 如果有错误,尝试映射回原始文件
|
|
38404
|
+
if (result) {
|
|
38405
|
+
result = mapErrorToSourceFile({
|
|
38406
|
+
errorMessage: result,
|
|
38407
|
+
collectedFiles,
|
|
38408
|
+
});
|
|
38409
|
+
}
|
|
38336
38410
|
}
|
|
38337
38411
|
const checkResult = {
|
|
38338
38412
|
success: !result,
|
|
@@ -38765,7 +38839,7 @@ async function transform(transformType, entry, options) {
|
|
|
38765
38839
|
await transformFn(entry, options);
|
|
38766
38840
|
}
|
|
38767
38841
|
|
|
38768
|
-
var version = "0.2.
|
|
38842
|
+
var version = "0.2.3";
|
|
38769
38843
|
var pkg = {
|
|
38770
38844
|
version: version};
|
|
38771
38845
|
|