@n42/cli 0.1.91 → 0.1.98

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/README.md CHANGED
@@ -85,9 +85,11 @@ n42 history <participantId>
85
85
  Example output:
86
86
 
87
87
  ```bash
88
+ Found 2 artefact(s)
89
+
88
90
  DATE PID FILE
89
- 2026-01-30 15:42:18 9915:helger ~/.node42/artefacts/discovery/b91f83e2.svg
90
- 2026-01-30 15:42:10 9915:helger ~/.node42/artefacts/discovery/ba1cbc8d.svg
91
+ 2026-01-30 16:53:28 9930:de81347... 5e0800fc.svg [Open]
92
+ 2026-01-30 16:53:08 9930:de81347... 6eeb73d0.svg [Open]
91
93
  ```
92
94
 
93
95
  #### Available options:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n42/cli",
3
- "version": "0.1.91",
3
+ "version": "0.1.98",
4
4
  "description": "Node42 CLI – Command-line interface for Peppol eDelivery path discovery, diagnostics, and tooling",
5
5
  "keywords": [
6
6
  "node42"
package/src/auth.js CHANGED
@@ -5,16 +5,17 @@ const { getUserWithIndex } = require("./user");
5
5
  const { clearScreen, ask, startSpinner } = require("./utils");
6
6
 
7
7
  const db = require("./db");
8
+ const pkg = require("../package.json");
8
9
  const C = require("./colors");
9
10
 
10
11
 
11
12
  async function login() {
12
- clearScreen("Sign in to Node42");
13
+ clearScreen(`Node42 CLI v${pkg.version}\n\n${C.BOLD}Sign in to your account${C.RESET}`);
13
14
  let user = getUserWithIndex(0);
14
15
 
15
16
  const username = await ask("Username", user.userMail ?? "");
16
17
  const password = await ask("Password", null, true);
17
- //console.log(username + ", " + password);
18
+ console.log();
18
19
 
19
20
  let stopSpinner = startSpinner();
20
21
 
@@ -26,8 +27,7 @@ async function login() {
26
27
 
27
28
  if (!res.ok) {
28
29
  stopSpinner();
29
-
30
- console.error(`[${res.status}] ${C.RED}Login failed${C.RESET} - Invalid credentials`);
30
+ handleError({ code: "N42E-10108", message: "Signin failed: Invalid credentials"});
31
31
  process.exit(1);
32
32
  }
33
33
 
@@ -36,7 +36,7 @@ async function login() {
36
36
 
37
37
  const { accessToken, refreshToken, idToken } = tokens;
38
38
  if (!accessToken || !refreshToken || !idToken) {
39
- console.error(`${C.RED}Invalid auth response`);
39
+ handleError({ code: "N42E-6123", message: "Token missing"})
40
40
  process.exit(1);
41
41
  }
42
42
 
@@ -52,7 +52,7 @@ async function login() {
52
52
  stopSpinner();
53
53
 
54
54
  if (!authenticated) {
55
- console.error(`${C.RED}Not authenticated${C.RESET}`);
55
+ handleError({ code: "N42E-10108", message: "Signin failed: Not authenticated"});
56
56
  process.exit(1);
57
57
  }
58
58
 
@@ -69,8 +69,7 @@ function logout() {
69
69
 
70
70
  function loadTokens() {
71
71
  if (!fs.existsSync(TOKENS_FILE)) {
72
- console.error(`Tokens missing...`);
73
- console.log(`Run: ${C.BLUE}n42 login${C.RESET}\n`);
72
+ handleError({ code: "N42E-9033", message: "Token missing: You are not signed in"})
74
73
  process.exit(1);
75
74
  }
76
75
  return JSON.parse(fs.readFileSync(TOKENS_FILE, "utf8"));
@@ -78,7 +77,7 @@ function loadTokens() {
78
77
 
79
78
  async function checkAuth() {
80
79
  if (!fs.existsSync(TOKENS_FILE)) {
81
- handleError({ code: "N42E-9033", message: "Token missing..."})
80
+ handleError({ code: "N42E-9033", message: "Token missing: You are not signed in"})
82
81
  return false;
83
82
  }
84
83
 
package/src/cli.js CHANGED
@@ -4,7 +4,7 @@ const { Command } = require("commander");
4
4
  const { login, logout, checkAuth } = require("./auth");
5
5
  const { getUserWithIndex, getUserUsage } = require("./user");
6
6
  const { runDiscovery } = require("./discover");
7
- const { clearScreen, startSpinner, validateEnv, validateId, createAppDirs, getArtefactExt, cleanAppDirs } = require("./utils");
7
+ const { clearScreen, startSpinner, validateEnv, validateId, createAppDirs, capitalize, cleanAppDirs } = require("./utils");
8
8
  const { NODE42_DIR, ARTEFACTS_DIR, DEFAULT_OUTPUT, DEFAULT_FORMAT } = require("./config");
9
9
 
10
10
  createAppDirs();
@@ -36,9 +36,8 @@ program
36
36
  const dest = path.join(NODE42_DIR, "completion.bash");
37
37
  fs.copyFileSync(src, dest);
38
38
 
39
- console.log(`${C.DIM}Completion script saved to ${dest}${C.RESET}\n`);
40
- console.log(`Run this once:`);
41
- console.log(`${C.BLUE}source ${dest}${C.RESET}\n`);
39
+ console.log(`${C.DIM}Completion script saved to ${dest}${C.RESET}`);
40
+ console.log(`Run: ${C.BOLD}source ${dest}${C.RESET}\n`);
42
41
  });
43
42
 
44
43
  program
@@ -112,8 +111,8 @@ program
112
111
  }
113
112
 
114
113
  clearScreen(`Node42 CLI v${pkg.version}\n`);
115
- console.log(`Usage ${C.BOLD}${service}${C.RESET}`);
116
- console.log(`${C.DIM}${currentMonth}:${C.RESET} ${C.RED}${usage}${C.RESET}\n`);
114
+ console.log(`${C.BOLD}${capitalize(service)} usage${C.RESET}`);
115
+ console.log(` • ${currentMonth}: ${C.RED}${usage}${C.RESET}\n`);
117
116
  });
118
117
 
119
118
  program
package/src/discover.js CHANGED
@@ -2,6 +2,7 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const pkg = require("../package.json");
4
4
  const db = require("./db");
5
+ const C = require("./colors");
5
6
 
6
7
  const { fetchWithAuth } = require("./auth");
7
8
  const { API_URL, EP_DISCOVER, DEFAULT_OUTPUT, DEFAULT_FORMAT, ARTEFACTS_DIR } = require("./config");
@@ -88,7 +89,7 @@ async function runDiscovery(participantId, options) {
88
89
  }
89
90
  };
90
91
 
91
- clearScreen(`Node42 CLI v${pkg.version}`);
92
+ clearScreen(`Node42 CLI v${pkg.version}\n`);
92
93
  const stopSpinner = startSpinner();
93
94
 
94
95
  const url = `${API_URL}/${EP_DISCOVER}?output=${output}&format=${format}`;
@@ -153,9 +154,12 @@ async function runDiscovery(participantId, options) {
153
154
  const file = path.join(ARTEFACTS_DIR, `${fileName}`);
154
155
  fs.writeFileSync(file, svg);
155
156
 
156
- console.log(`Discovery completed`);
157
- console.log(`Usage : ${serviceUsage} / ${rateLimit}`);
158
- console.log(`Artefact : ${file}\n`);
157
+ const link = `\u001B]8;;file://${file}\u0007Open\u001B]8;;\u0007`;
158
+
159
+ console.log(`${C.BOLD}Discovery completed${C.RESET}`);
160
+ console.log(`PID : ${C.CYAN}${participantId}${C.RESET}`);
161
+ console.log(`Artefact : ${fileName} ${C.BLUE}[${link}]${C.RESET}`);
162
+ console.log(`Usage : ${C.RED}${serviceUsage}${C.RESET} ${C.DIM}(${rateLimit})${C.RESET}\n`);
159
163
  return;
160
164
  }
161
165
 
@@ -170,9 +174,12 @@ async function runDiscovery(participantId, options) {
170
174
  const file = path.join(ARTEFACTS_DIR, `${fileName}`);
171
175
  fs.writeFileSync(file, text);
172
176
 
173
- console.log(`Discovery completed`);
174
- console.log(`Usage : ${serviceUsage} / ${rateLimit}`);
175
- console.log(`Artefact : ${file}\n`);
177
+ const link = `\u001B]8;;file://${file}\u0007Open\u001B]8;;\u0007`;
178
+
179
+ console.log(`${C.BOLD}Discovery completed${C.RESET}`);
180
+ console.log(`PID : ${C.CYAN}${participantId}${C.RESET}`);
181
+ console.log(`Artefact : ${fileName} ${C.BLUE}[${link}]${C.RESET}`);
182
+ console.log(`Usage : ${C.RED}${serviceUsage}${C.RESET} ${C.DIM}(${rateLimit})${C.RESET}\n`);
176
183
  return;
177
184
  }
178
185
 
@@ -187,9 +194,12 @@ async function runDiscovery(participantId, options) {
187
194
  const file = path.join(ARTEFACTS_DIR, `${fileName}`);
188
195
  fs.writeFileSync(file, JSON.stringify(json, null, 2));
189
196
 
190
- console.log(`Discovery completed`);
191
- console.log(`Usage : ${serviceUsage} / ${rateLimit}`);
192
- console.log(`Artefact : ${file}\n`);
197
+ const link = `\u001B]8;;file://${file}\u0007Open\u001B]8;;\u0007`;
198
+
199
+ console.log(`${C.BOLD}Discovery completed${C.RESET}`);
200
+ console.log(`PID : ${C.CYAN}${participantId}${C.RESET}`);
201
+ console.log(`Artefact : ${fileName} ${C.BLUE}[${link}]${C.RESET}`);
202
+ console.log(`Usage : ${C.RED}${serviceUsage}${C.RESET} ${C.DIM}(${rateLimit})${C.RESET}\n`);
193
203
  }
194
204
 
195
205
  module.exports = { runDiscovery };
package/src/errors.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const { WWW_URL } = require("./config");
2
-
2
+ const C = require("./colors");
3
3
 
4
4
  function handleError(err) {
5
5
  //console.log(err);
@@ -16,9 +16,9 @@ function handleError(err) {
16
16
  //console.log(url);
17
17
 
18
18
  if (message) {
19
- console.error(`\r${err.message}\nSee details: ${url}\n`);
19
+ console.error(`\r${C.RED}${err.message}${C.RESET}\nSee details: ${C.BOLD}${url}${C.RESET}\n`);
20
20
  } else {
21
- console.error(`\rSee details: ${url}\n`);
21
+ console.error(`\rSee details: ${C.BOLD}${url}${C.RESET}\n`);
22
22
  }
23
23
  }
24
24
 
package/src/utils.js CHANGED
@@ -2,6 +2,7 @@ const fs = require("fs");
2
2
  const inquirer = require("inquirer");
3
3
  const readline = require("readline");
4
4
  const config = require("./config");
5
+ const pkg = require("../package.json");
5
6
  const db = require("./db");
6
7
  const C = require("./colors");
7
8
 
@@ -54,7 +55,8 @@ function startSpinner(text = "Working") {
54
55
  let i = 0;
55
56
 
56
57
  const timer = setInterval(() => {
57
- process.stdout.write("\r[" + frames[i++ % frames.length] + "] " + text);
58
+ const frame = frames[i++ % frames.length];
59
+ process.stdout.write(`\r[${C.RED_BOLD}${frame}${C.RESET}] ${text}`);
58
60
  }, 120);
59
61
 
60
62
  return () => {
@@ -103,6 +105,10 @@ function getShortId(id) {
103
105
  return id.slice(0, 8);
104
106
  }
105
107
 
108
+ function capitalize(s) {
109
+ return s.charAt(0).toUpperCase() + s.slice(1);
110
+ }
111
+
106
112
  function createAppDirs(force=false) {
107
113
  fs.mkdirSync(config.NODE42_DIR, { recursive: true });
108
114
  fs.mkdirSync(config.ARTEFACTS_DIR, { recursive: true });
@@ -130,14 +136,23 @@ function cleanAppDirs(options) {
130
136
  all
131
137
  } = options;
132
138
 
139
+ if (Object.keys(options).length === 0) {
140
+ console.log(`${C.RED}Nothing to clean${C.RESET}`);
141
+ return;
142
+ }
143
+
144
+ clearScreen(`Node42 CLI v${pkg.version}\n`);
145
+
146
+ const removed = [];
147
+
133
148
  if ((all || tokens) && fs.existsSync(config.TOKENS_FILE)) {
134
149
  fs.unlinkSync(config.TOKENS_FILE);
135
- console.log("Tokens removed");
150
+ removed.push("tokens");
136
151
  }
137
152
 
138
153
  if ((all || dbFlag) && fs.existsSync(config.DATABASE_FILE)) {
139
154
  fs.unlinkSync(config.DATABASE_FILE);
140
- console.log("Database removed");
155
+ removed.push("database");
141
156
  }
142
157
 
143
158
  if (all || artefacts) {
@@ -149,8 +164,7 @@ function cleanAppDirs(options) {
149
164
  fs.rmSync(config.ARTEFACTS_DIR, { recursive: true, force: true });
150
165
  fs.mkdirSync(config.ARTEFACTS_DIR, { recursive: true });
151
166
  }
152
-
153
- console.log("Artefacts removed");
167
+ removed.push("artefacts");
154
168
  }
155
169
 
156
170
  if (all || transactions) {
@@ -162,8 +176,7 @@ function cleanAppDirs(options) {
162
176
  fs.rmSync(config.TRANSACTIONS_DIR, { recursive: true, force: true });
163
177
  fs.mkdirSync(config.TRANSACTIONS_DIR, { recursive: true });
164
178
  }
165
-
166
- console.log("Transactions removed");
179
+ removed.push("transactions");
167
180
  }
168
181
 
169
182
  if (all || validations) {
@@ -175,10 +188,19 @@ function cleanAppDirs(options) {
175
188
  fs.rmSync(config.VALIDATIONS_DIR, { recursive: true, force: true });
176
189
  fs.mkdirSync(config.VALIDATIONS_DIR, { recursive: true });
177
190
  }
191
+ removed.push("validations");
192
+ }
193
+
194
+ if (removed.length === 0) {
195
+ console.log(`${C.RED}Nothing removed${C.RESET}`);
196
+ } else {
197
+ console.log(`${C.BOLD}Removed ${removed.length} item(s)${C.RESET}`);
198
+ for (const r of removed) {
199
+ console.log(` ${C.RED}• ${r}${C.RESET}`);
200
+ }
178
201
 
179
- console.log("Transactions removed");
202
+ console.log();
180
203
  }
181
-
182
204
  }
183
205
 
184
206
  function buildDocLabel({ scheme, value }) {
@@ -230,4 +252,4 @@ function getArtefactExt(output, format) {
230
252
  }
231
253
  }
232
254
 
233
- module.exports = { clearScreen, startSpinner, ask, buildDocLabel, promptForDocument, validateEnv, validateId, getShortId, createAppDirs, cleanAppDirs, getArtefactExt };
255
+ module.exports = { clearScreen, startSpinner, ask, buildDocLabel, promptForDocument, validateEnv, validateId, getShortId, capitalize, createAppDirs, cleanAppDirs, getArtefactExt };
package/test/auth.test.js CHANGED
@@ -95,7 +95,7 @@ describe("auth", () => {
95
95
  // expected
96
96
  }
97
97
 
98
- expect(console.error.calledWithMatch("Login failed")).to.be.true;
98
+ expect(console.error.calledWithMatch("Signin failed")).to.be.true;
99
99
  expect(process.exit.calledWith(1)).to.be.true;
100
100
  expect(fs.writeFileSync.called).to.be.false;
101
101
  });