norn-cli 1.3.16 → 1.3.17
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/CHANGELOG.md +13 -0
- package/dist/cli.js +22 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the "Norn" extension will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.3.17] - 2026-02-14
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Import Resolution**: Improved duplicate import handling while preserving circular import detection
|
|
9
|
+
- Re-importing already loaded files is now treated as a no-op instead of a false circular error
|
|
10
|
+
- True cycles are still detected via active import stack tracking
|
|
11
|
+
- **Sequence Var-Request Parsing**: Fixed multi-line `var x = METHOD ...` request collection
|
|
12
|
+
- Headers and JSON/form bodies are now preserved until the next real command boundary
|
|
13
|
+
- Body-only shorthand continues to parse correctly
|
|
14
|
+
- **Syntax Highlighting**: Improved `var` request URL/header/body highlighting in `.norn` files
|
|
15
|
+
- Better distinction between endpoint captures and raw URL captures
|
|
16
|
+
- Header groups and body lines now color consistently in URL-style var requests
|
|
17
|
+
|
|
5
18
|
## [1.3.16] - 2026-02-13
|
|
6
19
|
|
|
7
20
|
### Fixed
|
package/dist/cli.js
CHANGED
|
@@ -20273,7 +20273,7 @@ function extractImports(text) {
|
|
|
20273
20273
|
}
|
|
20274
20274
|
return imports;
|
|
20275
20275
|
}
|
|
20276
|
-
async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__PURE__ */ new Set()) {
|
|
20276
|
+
async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__PURE__ */ new Set(), importStack = /* @__PURE__ */ new Set()) {
|
|
20277
20277
|
const imports = extractImports(text);
|
|
20278
20278
|
const errors = [];
|
|
20279
20279
|
const importedContents = [];
|
|
@@ -20287,7 +20287,7 @@ async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__
|
|
|
20287
20287
|
for (const imp of imports) {
|
|
20288
20288
|
const path5 = await import("path");
|
|
20289
20289
|
const absolutePath = path5.resolve(baseDir, imp.path);
|
|
20290
|
-
if (
|
|
20290
|
+
if (importStack.has(absolutePath)) {
|
|
20291
20291
|
errors.push({
|
|
20292
20292
|
path: imp.path,
|
|
20293
20293
|
error: `Circular import detected`,
|
|
@@ -20295,9 +20295,13 @@ async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__
|
|
|
20295
20295
|
});
|
|
20296
20296
|
continue;
|
|
20297
20297
|
}
|
|
20298
|
+
if (alreadyImported.has(absolutePath)) {
|
|
20299
|
+
continue;
|
|
20300
|
+
}
|
|
20298
20301
|
try {
|
|
20299
20302
|
const content = await readFile2(absolutePath);
|
|
20300
20303
|
alreadyImported.add(absolutePath);
|
|
20304
|
+
importStack.add(absolutePath);
|
|
20301
20305
|
resolvedPaths.push(absolutePath);
|
|
20302
20306
|
if (imp.path.endsWith(".nornapi")) {
|
|
20303
20307
|
const apiDef = parseNornApiFile(content);
|
|
@@ -20330,7 +20334,7 @@ async function resolveImports(text, baseDir, readFile2, alreadyImported = /* @__
|
|
|
20330
20334
|
continue;
|
|
20331
20335
|
}
|
|
20332
20336
|
const importDir = path5.dirname(absolutePath);
|
|
20333
|
-
const nestedResult = await resolveImports(content, importDir, readFile2, alreadyImported);
|
|
20337
|
+
const nestedResult = await resolveImports(content, importDir, readFile2, alreadyImported, importStack);
|
|
20334
20338
|
errors.push(...nestedResult.errors);
|
|
20335
20339
|
resolvedPaths.push(...nestedResult.resolvedPaths);
|
|
20336
20340
|
for (const group of nestedResult.headerGroups) {
|
|
@@ -20404,6 +20408,8 @@ end sequence`);
|
|
|
20404
20408
|
error: error.message || "Failed to read file",
|
|
20405
20409
|
lineNumber: imp.lineNumber
|
|
20406
20410
|
});
|
|
20411
|
+
} finally {
|
|
20412
|
+
importStack.delete(absolutePath);
|
|
20407
20413
|
}
|
|
20408
20414
|
}
|
|
20409
20415
|
return {
|
|
@@ -27570,6 +27576,7 @@ function extractStepsFromSequence(content) {
|
|
|
27570
27576
|
const lines = content.split("\n");
|
|
27571
27577
|
const steps = [];
|
|
27572
27578
|
const methodRegex = /^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+/i;
|
|
27579
|
+
const stepBoundaryRegex = /^(###|(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+|(test\s+)?sequence\s+|end\s+sequence|end\s+if|endif\b|var\s+|run\s+|print\s+|assert\s+|if\s+|wait\s+|import\s+|return\s+|\[)/i;
|
|
27573
27580
|
let currentRequest = [];
|
|
27574
27581
|
let currentRequestStartLine = -1;
|
|
27575
27582
|
let inRequest = false;
|
|
@@ -27819,11 +27826,11 @@ function extractStepsFromSequence(content) {
|
|
|
27819
27826
|
currentRequestStartLine = lineIdx;
|
|
27820
27827
|
inRequest = true;
|
|
27821
27828
|
} else if (inVarRequest) {
|
|
27822
|
-
if (trimmed
|
|
27823
|
-
currentVarRequest.push(trimmed);
|
|
27824
|
-
} else {
|
|
27829
|
+
if (trimmed !== "" && stepBoundaryRegex.test(trimmed)) {
|
|
27825
27830
|
savePendingVarRequest();
|
|
27826
27831
|
lineIdx--;
|
|
27832
|
+
} else {
|
|
27833
|
+
currentVarRequest.push(trimmed);
|
|
27827
27834
|
}
|
|
27828
27835
|
} else if (inRequest) {
|
|
27829
27836
|
if (trimmed.match(/^var\s+[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*\$\d+/)) {
|
|
@@ -28323,9 +28330,15 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
28323
28330
|
}
|
|
28324
28331
|
const contentLines = step.content.split("\n");
|
|
28325
28332
|
if (contentLines.length > 1) {
|
|
28326
|
-
const
|
|
28327
|
-
const
|
|
28328
|
-
|
|
28333
|
+
const extraLines = contentLines.slice(1).map((line2) => substituteVariables(line2, runtimeVariables));
|
|
28334
|
+
const hasExplicitBlank = extraLines.some((line2) => line2.trim() === "");
|
|
28335
|
+
const firstNonEmpty = extraLines.find((line2) => line2.trim() !== "");
|
|
28336
|
+
const startsWithHeader = firstNonEmpty ? /^[A-Za-z0-9\-_]+\s*:/.test(firstNonEmpty.trim()) : false;
|
|
28337
|
+
if (hasExplicitBlank || startsWithHeader) {
|
|
28338
|
+
requestText += "\n" + extraLines.join("\n");
|
|
28339
|
+
} else {
|
|
28340
|
+
requestText += "\n\n" + extraLines.join("\n");
|
|
28341
|
+
}
|
|
28329
28342
|
}
|
|
28330
28343
|
const requestParsed = parserHttpRequest(requestText, runtimeVariables);
|
|
28331
28344
|
const retryOpts = parsed.retryCount ? {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "norn-cli",
|
|
3
3
|
"displayName": "Norn - REST Client",
|
|
4
4
|
"description": "A powerful REST client for making HTTP requests with sequences, variables, scripts, and cookie support",
|
|
5
|
-
"version": "1.3.
|
|
5
|
+
"version": "1.3.17",
|
|
6
6
|
"publisher": "Norn-PeterKrustanov",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Peter Krastanov"
|