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 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 (alreadyImported.has(absolutePath)) {
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 === "" || trimmed.match(/^[a-zA-Z_][a-zA-Z0-9_]*\s*[=:]\s*.+$/) || trimmed.startsWith("{") || trimmed.startsWith('"') || trimmed.startsWith("[")) {
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 bodyLines = contentLines.slice(1);
28327
- const resolvedBodyLines = bodyLines.map((line2) => substituteVariables(line2, runtimeVariables));
28328
- requestText += "\n\n" + resolvedBodyLines.join("\n");
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.16",
5
+ "version": "1.3.17",
6
6
  "publisher": "Norn-PeterKrustanov",
7
7
  "author": {
8
8
  "name": "Peter Krastanov"