@n42/cli 0.3.50 → 0.3.67

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n42/cli",
3
- "version": "0.3.50",
3
+ "version": "0.3.67",
4
4
  "description": "Node42 CLI – Command-line interface for Peppol eDelivery path discovery, diagnostics, and tooling",
5
5
  "keywords": [
6
6
  "node42",
@@ -64,7 +64,7 @@ function addSvgClickListener() {
64
64
  else {
65
65
  if (!url.startsWith("#")) {
66
66
  terminal.open({
67
- url: decodeURIComponent(url),
67
+ url: url,
68
68
  method: "GET"
69
69
  });
70
70
  }
@@ -178,9 +178,8 @@ document.addEventListener("DOMContentLoaded", () => {
178
178
 
179
179
  terminal = new Terminal({
180
180
  title: "Terminal",
181
- brand: "curl",
182
181
  theme: "light",
183
- pkgVersion: "0.3.19"
182
+ pkgVersion: "0.3.65"
184
183
  });
185
184
 
186
185
  addSvgClickListener();
@@ -150,4 +150,5 @@
150
150
  .cm-json-number { color: #f59e0b; }
151
151
  .cm-json-boolean { color: #ec4899; }
152
152
  .cm-json-null { color: #94a3b8; }
153
- .cm-json-step { color: #4cb56f; }
153
+ .cm-json-step { color: #4cb56f; }
154
+ .cm-json-error { color: #ef4444; }
@@ -2,7 +2,6 @@ class Terminal {
2
2
  constructor(opts = {}) {
3
3
  this.opts = {
4
4
  title: "Request",
5
- brand: "curl",
6
5
  ...opts,
7
6
  };
8
7
 
@@ -13,6 +12,8 @@ class Terminal {
13
12
  this._history = [];
14
13
  this._historyIndex = -1;
15
14
 
15
+ this.runningFromFile = window.location.protocol === "file:";
16
+
16
17
  // ---- reusable events ----
17
18
  this.enterEvent = new KeyboardEvent("keydown", {
18
19
  key: "Enter",
@@ -29,11 +30,21 @@ class Terminal {
29
30
  which: 27,
30
31
  bubbles: true
31
32
  });
33
+
34
+ // ---- colors ----
35
+ this.colorBlue="#3f9cff";
36
+ this.colorBrown="#a07c4f";
37
+ this.colorOrange="#f59e0b";
38
+ this.colorPink="#ec4899";
39
+ this.colorGray="#94a3b8";
40
+ this.colorGreen="#4cb56f";
41
+ this.colorRed="#ef4444";
32
42
  }
33
43
 
34
44
  async openAndRun(req) {
35
45
  this.open(req);
36
- try { await this.run(req); }
46
+
47
+ try { await this.httpRequest(req); }
37
48
  catch (e) {
38
49
  // errors already printed by run(); rethrow if you want
39
50
  }
@@ -53,7 +64,7 @@ class Terminal {
53
64
  this.overlay.classList.remove("hidden");
54
65
  this.dialog.classList.remove("hidden");
55
66
 
56
- this.input.value = `curl -X ${req.method} ${req.url}`;
67
+ this.input.value = `request -X ${req.method} ${req.url}`;
57
68
  this.input.focus();
58
69
 
59
70
  // prevent background scroll
@@ -114,14 +125,14 @@ class Terminal {
114
125
  this._setBusy(false);
115
126
  }
116
127
 
117
- async run(req) {
128
+ async httpRequest(req) {
118
129
  const normalized = this._normalizeReq(req);
119
130
  this._resetTerminal();
120
131
 
121
- const cmd = `$ ${this.opts.brand} ${this._toCurlArgs(normalized)}`;
132
+ const cmd = `$ request ${this._getReqArgs(normalized)}`;
122
133
  this._addHistory(cmd)
123
134
 
124
- this._printLine(cmd);
135
+ this._printColoredLine(cmd, this.colorBlue);
125
136
  this._printLine("");
126
137
 
127
138
  this._setBusy(true);
@@ -164,7 +175,7 @@ class Terminal {
164
175
  if (normalized.body) this._printLine(`> (body ${this._byteLen(normalized.body)} bytes)`);
165
176
  this._printLine("");
166
177
 
167
- this.title.textContent = `Terminal [${normalized.method}]: curl`;
178
+ this.title.textContent = `Terminal [${normalized.method}]: request`;
168
179
 
169
180
  const res = await fetch(normalized.url, fetchInit);
170
181
 
@@ -275,8 +286,6 @@ class Terminal {
275
286
  }
276
287
 
277
288
  _handleCommand(cmd) {
278
- this._printLine(`$ ${cmd}`);
279
-
280
289
  if (cmd === "clear") {
281
290
  this._addHistory(cmd);
282
291
  this._resetTerminal();
@@ -289,9 +298,21 @@ class Terminal {
289
298
  return;
290
299
  }
291
300
 
292
- if (cmd.startsWith("curl ")) {
293
- // Parse: curl [-X METHOD] <url>
294
- const m = cmd.match(/^curl\s+(?:-X\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+)?(https?:\/\/\S+)$/i);
301
+ if (cmd.startsWith("request ")) {
302
+ if (this.runningFromFile) {
303
+ this._addHistory(cmd);
304
+
305
+ this._printColoredLine(`$ ${cmd}`, this.colorBlue);
306
+
307
+ this._printLine("");
308
+ this._printColoredLine("[error]: CORS has blocked this request (the script is running from file://).", this.colorRed);
309
+ this._printLine("Use the arrow keys to reselect the URL, then click the top-right button to open it in a browser tab instead.");
310
+ this._printLine("");
311
+
312
+ return;
313
+ }
314
+ // Parse: request [METHOD] <url>
315
+ const m = cmd.match(/^request\s+(?:-X\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+)?(https?:\/\/\S+)$/i);
295
316
 
296
317
  if (m) {
297
318
  const method = m[1] ? m[1].toUpperCase() : "GET";
@@ -309,12 +330,12 @@ class Terminal {
309
330
  this._resetTerminal();
310
331
  this._printHtml(this._jsonHighlight(discoveryTrace));
311
332
  } else {
312
- this._printLine("[error]: Discovery trace missing");
333
+ this._printColoredLine("[error]: Discovery trace missing", this.colorRed);
313
334
  }
314
335
  return;
315
336
  }
316
337
 
317
- this._printLine("[error]: Unknown command");
338
+ this._printColoredLine("[error]: Unknown command", this.colorRed);
318
339
  }
319
340
 
320
341
  _createImgEl(src, size, alt) {
@@ -447,13 +468,13 @@ class Terminal {
447
468
  btnDownload.prepend(downloadImg);
448
469
  btnDownload.addEventListener("click", () => this._download());
449
470
 
450
- const openExtImg = this._createImgEl("../../assets/open-external-light.svg", 24, "Open");
451
- const btnOpenExt = document.createElement("button");
452
- btnOpenExt.className = "cm-btn";
453
- btnOpenExt.type = "button";
454
- btnOpenExt.title = "Open";
455
- btnOpenExt.prepend(openExtImg);
456
- btnOpenExt.addEventListener("click", () => this._openExt());
471
+ const openUrlImg = this._createImgEl("../../assets/open-external-light.svg", 24, "Open");
472
+ const btnOpenUrl = document.createElement("button");
473
+ btnOpenUrl.className = "cm-btn";
474
+ btnOpenUrl.type = "button";
475
+ btnOpenUrl.title = "Open URL";
476
+ btnOpenUrl.prepend(openUrlImg);
477
+ btnOpenUrl.addEventListener("click", () => this._openUrl());
457
478
 
458
479
  const themeImg = this._createImgEl("../../assets/theme-light.svg", 24, "Theme");
459
480
  const btnTheme = document.createElement("button");
@@ -463,7 +484,7 @@ class Terminal {
463
484
  btnTheme.prepend(themeImg);
464
485
  btnTheme.addEventListener("click", () => this._toggleTheme());
465
486
 
466
- head.append(title, spacer, btnTheme, btnCopy, btnDownload, btnOpenExt);
487
+ head.append(title, spacer, btnTheme, btnCopy, btnDownload, btnOpenUrl);
467
488
 
468
489
  // Body
469
490
  const body = document.createElement("div");
@@ -513,7 +534,7 @@ class Terminal {
513
534
 
514
535
  this.btnCopy = btnCopy;
515
536
  this.btnDownload = btnDownload;
516
- this.btnOpenExt = btnOpenExt;
537
+ this.btnOpenUrl = btnOpenUrl;
517
538
  this.btnTheme = btnTheme;
518
539
 
519
540
  // Close when clicking outside (optional)
@@ -562,7 +583,7 @@ class Terminal {
562
583
  this.statusEl.textContent = isBusy ? "Running…" : "Ready";
563
584
  }
564
585
 
565
- _openExt() {
586
+ _openUrl() {
566
587
  const url = this.input.value.replace(/^.*?(?=https?:\/\/)/, "")
567
588
  window.open(url, '_blank');
568
589
  }
@@ -582,7 +603,7 @@ class Terminal {
582
603
  this._printLine("");
583
604
 
584
605
  this._printLine("Available commands:");
585
- this._printLine(" curl [-X METHOD] <url> – send HTTP request to a URL");
606
+ this._printLine(" request [-X METHOD] <url> – send HTTP request to a URL");
586
607
  this._printLine(" trace – output discovery trace");
587
608
  this._printLine(" clear – clear terminal output");
588
609
  this._printLine(" help – show this help text");
@@ -601,13 +622,22 @@ class Terminal {
601
622
  this._printLine("");
602
623
 
603
624
  this._printLine("Examples:");
604
- this._printLine(" curl https://api.node42.dev/health");
605
- this._printLine(" curl -X POST https://api.node42.dev/health");
625
+ this._printLine(" request https://api.node42.dev/health");
626
+ this._printLine(" request -X POST https://api.node42.dev/health");
606
627
  this._printLine("");
607
628
  }
608
629
 
609
630
  _printLine(s) {
610
- this.term.textContent += `${s}\n`;
631
+ const html = s.replace(/\r?\n/g, "<br>");
632
+ this.term.innerHTML += `${html}<br>`;
633
+ this._scrollToBottom();
634
+ }
635
+
636
+ _printColoredLine(s, color="#111827") {
637
+ const html = this.term.innerHTML;
638
+ this.term.innerHTML =
639
+ `${html}<span style="color:${color};">${s}</span><br>`;
640
+
611
641
  this._scrollToBottom();
612
642
  }
613
643
 
@@ -617,8 +647,13 @@ class Terminal {
617
647
  }
618
648
 
619
649
  _printRaw(s) {
620
- this.term.textContent += s;
621
- if (!s.endsWith("\n")) this.term.textContent += "\n";
650
+ const html = s.replace(/\r?\n/g, "<br>");
651
+ this.term.innerHTML += html;
652
+
653
+ if (!s.endsWith("\n")) {
654
+ this.term.innerHTML += "<br>";
655
+ }
656
+
622
657
  this._scrollToBottom();
623
658
  }
624
659
 
@@ -653,14 +688,14 @@ class Terminal {
653
688
  const url = URL.createObjectURL(blob);
654
689
  const a = document.createElement("a");
655
690
  a.href = url;
656
- a.download = `curl-output-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}.txt`;
691
+ a.download = `request-output-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}.txt`;
657
692
  document.body.appendChild(a);
658
693
  a.click();
659
694
  a.remove();
660
695
  URL.revokeObjectURL(url);
661
696
  }
662
697
 
663
- _toCurlArgs(req) {
698
+ _getReqArgs(req) {
664
699
  // Presentational: escapes minimally for display (not execution-safe for all shells).
665
700
  const parts = [];
666
701
  parts.push(`-X ${req.method}`);