@n42/cli 0.1.71 → 0.1.88

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.1.71",
3
+ "version": "0.1.88",
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
@@ -1,14 +1,14 @@
1
1
  const fs = require("fs");
2
- const { NODE42_DIR, TOKENS_FILE, API_URL, EP_SIGNIN, EP_REFRESH } = require("./config");
2
+ const { NODE42_DIR, TOKENS_FILE, API_URL, EP_SIGNIN, EP_REFRESH, EP_ME } = require("./config");
3
3
  const { handleError } = require("./errors");
4
- const { getUser } = require("./user");
4
+ const { getUserWithIndex } = require("./user");
5
5
  const { clearScreen, ask, startSpinner } = require("./utils");
6
6
  const db = require("./db");
7
7
 
8
8
 
9
9
  async function login() {
10
10
  clearScreen("Sign in to Node42");
11
- let user = getUser();
11
+ let user = getUserWithIndex(0);
12
12
 
13
13
  const username = await ask("Username", user.userMail ?? "");
14
14
  const password = await ask("Password", null, true);
@@ -24,17 +24,16 @@ async function login() {
24
24
 
25
25
  if (!res.ok) {
26
26
  stopSpinner();
27
-
27
+
28
28
  console.error(`Login failed (${res.status}) – Invalid credentials`);
29
29
  process.exit(1);
30
30
  }
31
31
 
32
32
  const tokens = await res.json();
33
-
33
+ stopSpinner();
34
+
34
35
  const { accessToken, refreshToken, idToken } = tokens;
35
36
  if (!accessToken || !refreshToken || !idToken) {
36
- stopSpinner();
37
-
38
37
  console.error("Invalid auth response");
39
38
  process.exit(1);
40
39
  }
@@ -45,13 +44,17 @@ async function login() {
45
44
  JSON.stringify({ accessToken, refreshToken, idToken }, null, 2)
46
45
  );
47
46
 
48
- stopSpinner();
49
47
  stopSpinner = startSpinner();
50
48
 
51
- await checkAuth();
52
- user = getUser();
49
+ const authenticated = await checkAuth();
53
50
  stopSpinner();
54
-
51
+
52
+ if (!authenticated) {
53
+ console.error("Not authenticated");
54
+ process.exit(1);
55
+ }
56
+
57
+ user = getUserWithIndex(0);
55
58
  console.log(
56
59
  `Authenticated as ${user.userName} <${user.userMail}> (${user.role})`
57
60
  );
@@ -61,14 +64,12 @@ function logout() {
61
64
  if (fs.existsSync(TOKENS_FILE)) {
62
65
  fs.unlinkSync(TOKENS_FILE);
63
66
  }
64
-
65
- let user = getUser();
66
- db.delete("user", user.id);
67
+ db.clear("user");
67
68
  }
68
69
 
69
- function loadAuth() {
70
+ function loadTokens() {
70
71
  if (!fs.existsSync(TOKENS_FILE)) {
71
- console.error("Not logged in. Run: n42 login");
72
+ console.error("Tokens missing...\nRun: n42 login");
72
73
  process.exit(1);
73
74
  }
74
75
  return JSON.parse(fs.readFileSync(TOKENS_FILE, "utf8"));
@@ -77,10 +78,10 @@ function loadAuth() {
77
78
  async function checkAuth() {
78
79
  if (!fs.existsSync(TOKENS_FILE)) {
79
80
  handleError({ code: "N42E-9033", message: "Token missing..."})
80
- process.exit(1);
81
+ return false;
81
82
  }
82
83
 
83
- const res = await fetchWithAuth(`${API_URL}/users/me`, {
84
+ const res = await fetchWithAuth(`${API_URL}/${EP_ME}`, {
84
85
  method: "GET",
85
86
  headers: {
86
87
  "Content-Type": "application/json"
@@ -93,25 +94,22 @@ async function checkAuth() {
93
94
 
94
95
  if (!res.ok) {
95
96
  const err = await res.json();
96
- await handleError(err);
97
+ handleError(err);
97
98
  return false;
98
99
  }
99
100
 
100
- const auth = await res.json();
101
- //console.log(auth);
102
- if (auth) {
103
-
101
+ const userInfo = await res.json();
102
+ //console.log(userInfo);
103
+
104
+ if (userInfo) {
104
105
  db.upsert("user", {
105
- id: auth.sub,
106
- userName: auth.userName,
107
- userMail: auth.userMail,
108
- role: auth.role,
109
- rateLimits: auth.rateLimits,
110
- serviceUsage: auth.serviceUsage,
106
+ id: userInfo.sub,
107
+ userName: userInfo.userName,
108
+ userMail: userInfo.userMail,
109
+ role: userInfo.role,
110
+ rateLimits: userInfo.rateLimits,
111
+ serviceUsage: userInfo.serviceUsage,
111
112
  })
112
-
113
- db.replace("serviceUsage", auth.serviceUsage);
114
- db.replace("rateLimits", auth.rateLimits);
115
113
  return true;
116
114
  }
117
115
 
@@ -119,7 +117,7 @@ async function checkAuth() {
119
117
  }
120
118
 
121
119
  async function refreshSession() {
122
- const { refreshToken } = loadAuth();
120
+ const { refreshToken } = loadTokens();
123
121
  if (!refreshToken) {
124
122
  return false;
125
123
  }
@@ -160,7 +158,7 @@ async function refreshSession() {
160
158
  }
161
159
 
162
160
  async function fetchWithAuth(url, options = {}) {
163
- let { accessToken } = loadAuth();
161
+ let { accessToken } = loadTokens();
164
162
  if (!accessToken) {
165
163
  handleError({ code: "N42E-9032" });
166
164
  return;
@@ -183,7 +181,7 @@ async function fetchWithAuth(url, options = {}) {
183
181
  return res;
184
182
  }
185
183
 
186
- accessToken = loadAuth().accessToken;
184
+ accessToken = loadTokens().accessToken;
187
185
  return fetch(url, {
188
186
  ...options,
189
187
  headers: {
@@ -193,4 +191,4 @@ async function fetchWithAuth(url, options = {}) {
193
191
  });
194
192
  }
195
193
 
196
- module.exports = { login, logout, loadAuth, checkAuth, fetchWithAuth };
194
+ module.exports = { login, logout, loadTokens, checkAuth, fetchWithAuth };
package/src/cli.js CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  const { Command } = require("commander");
4
4
  const { login, logout, checkAuth } = require("./auth");
5
- const { getUser, getUserUsage } = require("./user");
5
+ const { getUserWithIndex, getUserUsage } = require("./user");
6
6
  const { runDiscovery } = require("./discover");
7
- const { clearScreen, startSpinner, validateEnv, validateId, createAppDirs, getArtefactExt } = require("./utils");
7
+ const { clearScreen, startSpinner, validateEnv, validateId, createAppDirs, getArtefactExt, cleanAppDirs } = require("./utils");
8
8
  const { NODE42_DIR, ARTEFACTS_DIR, DEFAULT_OUTPUT, DEFAULT_FORMAT } = require("./config");
9
9
 
10
10
  createAppDirs();
@@ -18,7 +18,7 @@ const path = require("path");
18
18
 
19
19
  program
20
20
  .name("n42")
21
- .description("Command-line interface for eDelivery path discovery and diagnostics")
21
+ .description("Node42 Command-line interface for eDelivery path discovery and diagnostics")
22
22
  .version(pkg.version);
23
23
 
24
24
  program
@@ -50,16 +50,34 @@ program
50
50
  .description("Terminate user session and delete all local tokens")
51
51
  .action(logout);
52
52
 
53
+ program
54
+ .command("clean")
55
+ .description("Remove locally stored artefacts and cache")
56
+ .option("--tokens", "Remove stored authentication tokens")
57
+ .option("--artefacts", "Remove artefacts")
58
+ .option("--transactions", "Remove transactions")
59
+ .option("--validations", "Remove validations")
60
+ .option("--db", "Remove local database")
61
+ .option("--all", "Wipe all local data")
62
+ .action((options)=> {
63
+ cleanAppDirs(options);
64
+ });
65
+
53
66
  program
54
67
  .command("me")
55
68
  .description("Returns identity and billing status for the authenticated user.")
56
69
  .action(async () => {
57
70
  const stopSpinner = startSpinner();
58
71
 
59
- await checkAuth();
60
- const user = getUser();
72
+ const authenticated = await checkAuth();
61
73
  stopSpinner();
74
+
75
+ if (!authenticated) {
76
+ console.error("Not authenticated");
77
+ process.exit(1);
78
+ }
62
79
 
80
+ const user = getUserWithIndex(0);
63
81
  const currentMonth = new Date().toISOString().slice(0, 7);
64
82
  console.log(`Node42 CLI v${pkg.version}
65
83
  User
@@ -71,7 +89,7 @@ program
71
89
  Rate Limits
72
90
  Discovery : ${user.rateLimits.discovery}
73
91
  Transactions : ${user.rateLimits.transactions}
74
- Validation : ${user.rateLimits.validation}
92
+ Validation : ${user.rateLimits.validation}
75
93
 
76
94
  Usage (Current Month)
77
95
  Discovery : ${user.serviceUsage.discovery[currentMonth] ?? 0}
@@ -83,25 +101,31 @@ program
83
101
  program
84
102
  .command("usage <service>")
85
103
  .description("Returns usage for the authenticated user.")
86
- .action((service) => {
87
- const userUsage = getUserUsage();
88
- const currentMonth = new Date().toISOString().slice(0, 7);
89
-
90
- const usage =
91
- userUsage?.serviceUsage?.[service]?.[currentMonth] ?? 0;
104
+ .option("-m, --month <yyyy-mm>", "Show usage for a specific month")
105
+ .action((service, options) => {
106
+ const user = getUserWithIndex(0);
107
+ const currentMonth = options.month ? options.month : new Date().toISOString().slice(0, 7);
108
+ let usage = getUserUsage(user.id, service, currentMonth);
109
+ if (!usage) {
110
+ usage = 0;
111
+ }
92
112
 
93
113
  clearScreen(`Node42 CLI v${pkg.version}`);
94
114
  console.log(`Usage for ${service} (${currentMonth}): ${usage}`);
95
115
  });
96
116
 
97
117
  program
98
- .command("history <participantId>")
118
+ .command("history [participantId]")
99
119
  .description("Show local discovery history for a participant")
100
120
  .option("--today", "Show only today's artefacts")
101
121
  .option("--day <yyyy-mm-dd>", "Show artefacts for a specific day")
102
122
  .option("--last <n>", "Show only last N results", parseInt)
103
123
  .action((participantId, options) => {
104
- let artefacts = db.artefactsByParticipant(participantId) ?? [];
124
+ let artefacts = participantId
125
+ ? db.artefactsByParticipant(participantId)
126
+ : db.get("artefacts");
127
+
128
+ artefacts ??= [];
105
129
 
106
130
  // newest first
107
131
  artefacts.sort((a, b) => b.createdAt - a.createdAt);
@@ -140,13 +164,23 @@ program
140
164
  clearScreen(`Node42 CLI v${pkg.version}`);
141
165
  console.log(`Found ${artefacts.length} artefact(s)${filterInfo}\n`);
142
166
 
167
+ const DATE = "DATE".padEnd(19);
168
+ const PID = "PID".padEnd(15);
169
+ const FILE = "FILE";
170
+ console.log(`${DATE} ${PID} ${FILE}`);
171
+
143
172
  for (const item of artefacts) {
144
173
  const d = new Date(item.createdAt);
145
174
  const dt = d.toISOString().slice(0, 19).replace("T", " ");
146
- const ext = getArtefactExt(item.output, item.format);
147
- const file = path.join(ARTEFACTS_DIR, `${item.id}.${ext}`);
148
-
149
- console.log(`${dt} ${file}`);
175
+ const file = path.join(ARTEFACTS_DIR, `${item.file}`);
176
+
177
+ let pid = item.participantId;
178
+ if (!participantId) {
179
+ pid = pid.length > 15 ? pid.substring(0, 12) + "..." : pid
180
+ console.log(`${dt} ${pid.padEnd(15)} ${file}`);
181
+ } else {
182
+ console.log(`${dt} ${file}`);
183
+ }
150
184
  }
151
185
 
152
186
  console.log("");
@@ -159,7 +193,7 @@ const discover = program
159
193
 
160
194
  discover
161
195
  .command("peppol <participantId>")
162
- .description("Resolve the Peppol eDelivery message path")
196
+ .description("Resolve and validate the full (Peppol) eDelivery path:\nSML/SMK (BDXR DNS) lookup, SMP resolution, endpoint discovery, and TLS diagnostics.")
163
197
  .option("-e, --env <environment>", "Environment", "TEST")
164
198
  .option("-o, --output <type>", "Result type (json | plantuml)", DEFAULT_OUTPUT)
165
199
  .option("-f, --format <format>", "When output=plantuml (svg | text)", DEFAULT_FORMAT)
@@ -3,17 +3,24 @@ _n42_completions()
3
3
  local cur prev words cword
4
4
  _init_completion || return
5
5
 
6
- local commands="login logout me usage history discover"
6
+ local commands="login logout me usage history discover clean"
7
7
 
8
8
  if [[ $cword -eq 1 ]]; then
9
9
  COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
10
10
  return
11
11
  fi
12
12
 
13
+ # discover peppol
13
14
  if [[ ${words[1]} == "discover" && $cword -eq 2 ]]; then
14
15
  COMPREPLY=( $(compgen -W "peppol" -- "$cur") )
15
16
  return
16
17
  fi
18
+
19
+ # usage discovery|validation|transactions
20
+ if [[ ${words[1]} == "usage" && $cword -eq 2 ]]; then
21
+ COMPREPLY=( $(compgen -W "discovery validation transactions" -- "$cur") )
22
+ return
23
+ fi
17
24
  }
18
25
 
19
26
  complete -F _n42_completions n42
package/src/config.js CHANGED
@@ -12,7 +12,7 @@ const config = {
12
12
 
13
13
  ARTEFACTS_DIR: null,
14
14
  TRANSACTIONS_DIR: null,
15
- VALIDATION_DIR: null,
15
+ VALIDATIONS_DIR: null,
16
16
 
17
17
  DATABASE_FILE: null,
18
18
  TOKENS_FILE: null,
@@ -23,12 +23,13 @@ const config = {
23
23
 
24
24
  EP_SIGNIN: "auth/signin",
25
25
  EP_REFRESH: "auth/refresh",
26
+ EP_ME: "users/me",
26
27
  EP_DISCOVER: "discover/peppol"
27
28
  };
28
29
 
29
30
  config.ARTEFACTS_DIR = path.join(config.NODE42_DIR, "artefacts", "discovery");
30
31
  config.TRANSACTIONS_DIR = path.join(config.NODE42_DIR, "artefacts", "transactions");
31
- config.VALIDATION_DIR = path.join(config.NODE42_DIR, "artefacts", "validation");
32
+ config.VALIDATIONS_DIR = path.join(config.NODE42_DIR, "artefacts", "validations");
32
33
 
33
34
  config.DATABASE_FILE = path.join(config.NODE42_DIR, "db.json");
34
35
  config.TOKENS_FILE = path.join(config.NODE42_DIR, "tokens.json");
package/src/db.js CHANGED
@@ -13,7 +13,6 @@ function load() {
13
13
  if (!fs.existsSync(DATABASE_FILE)) return {
14
14
  user: [],
15
15
  artefacts: [],
16
- usage: [],
17
16
  };
18
17
  return JSON.parse(fs.readFileSync(DATABASE_FILE, "utf8"));
19
18
  }
@@ -91,6 +90,12 @@ function remove(collection, keyValue, key = "id") {
91
90
  save(db);
92
91
  }
93
92
 
93
+ function clear(collection) {
94
+ const db = load();
95
+ db[collection] = [];
96
+ save(db);
97
+ }
98
+
94
99
  function get(collection) {
95
100
  const db = load();
96
101
  return db[collection] ?? [];
@@ -154,4 +159,4 @@ function artefactsByParticipant(pid) {
154
159
  return idx[pid] ?? [];
155
160
  }
156
161
 
157
- module.exports = { setSource, load, save, insert, update, upsert, replace, set, remove, get, find, indexBy, indexByFn, indexByMap, artefactsByParticipant };
162
+ module.exports = { setSource, load, save, insert, update, upsert, replace, set, remove, clear, get, find, indexBy, indexByFn, indexByMap, artefactsByParticipant };
package/src/discover.js CHANGED
@@ -5,8 +5,8 @@ const db = require("./db");
5
5
 
6
6
  const { fetchWithAuth } = require("./auth");
7
7
  const { API_URL, EP_DISCOVER, DEFAULT_OUTPUT, DEFAULT_FORMAT, ARTEFACTS_DIR } = require("./config");
8
- const { getUserUsage } = require("./user");
9
- const { clearScreen, startSpinner, buildDocLabel, promptForDocument } = require("./utils");
8
+ const { getUserWithIndex, setUserUsage } = require("./user");
9
+ const { clearScreen, startSpinner, buildDocLabel, promptForDocument, getShortId, getArtefactExt } = require("./utils");
10
10
  const { handleError } = require("./errors");
11
11
 
12
12
  const DEFAULT_DISCOVERY_INPUT = {
@@ -115,17 +115,25 @@ async function runDiscovery(participantId, options) {
115
115
  const serviceUsage = res.headers.get("X-Node42-ServiceUsage");
116
116
  const rateLimit = res.headers.get("X-Node42-RateLimit");
117
117
  const encodedDocs = res.headers.get("X-Node42-Documents");
118
-
119
- const userUsage = getUserUsage();
120
118
  const currentMonth = new Date().toISOString().slice(0, 7);
121
- userUsage.serviceUsage.discovery[currentMonth] = serviceUsage;
122
-
123
- db.replace("serviceUsage", userUsage);
119
+
120
+ const user = getUserWithIndex(0);
121
+ setUserUsage(
122
+ user.id,
123
+ "discovery",
124
+ currentMonth,
125
+ serviceUsage
126
+ );
127
+
128
+ const fileId = getShortId(refId);
129
+ const fileExt = getArtefactExt(output, format);
130
+ const fileName = `${fileId}.${fileExt}`;
124
131
 
125
132
  db.insert("artefacts", {
126
133
  id: refId,
127
134
  participantId,
128
135
  options,
136
+ file: fileName,
129
137
  createdAt: Date.now()
130
138
  });
131
139
 
@@ -142,7 +150,7 @@ async function runDiscovery(participantId, options) {
142
150
  await runDiscovery(participantId, options);
143
151
  });
144
152
 
145
- const file = path.join(ARTEFACTS_DIR, `${refId}.svg`);
153
+ const file = path.join(ARTEFACTS_DIR, `${fileName}`);
146
154
  fs.writeFileSync(file, svg);
147
155
 
148
156
  console.log(`Discovery completed`);
@@ -159,7 +167,7 @@ async function runDiscovery(participantId, options) {
159
167
  await runDiscovery(participantId, options);
160
168
  });
161
169
 
162
- const file = path.join(ARTEFACTS_DIR, `${refId}.puml`);
170
+ const file = path.join(ARTEFACTS_DIR, `${fileName}`);
163
171
  fs.writeFileSync(file, text);
164
172
 
165
173
  console.log(`Discovery completed`);
@@ -176,7 +184,7 @@ async function runDiscovery(participantId, options) {
176
184
  await runDiscovery(participantId, options);
177
185
  });
178
186
 
179
- const file = path.join(ARTEFACTS_DIR, `${refId}.json`);
187
+ const file = path.join(ARTEFACTS_DIR, `${fileName}`);
180
188
  fs.writeFileSync(file, JSON.stringify(json, null, 2));
181
189
 
182
190
  console.log(`Discovery completed`);
package/src/errors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { WWW_URL } = require("./config");
2
2
 
3
3
 
4
- async function handleError(err) {
4
+ function handleError(err) {
5
5
  //console.log(err);
6
6
 
7
7
  const code = err.code?.startsWith("N42E-")
@@ -16,9 +16,9 @@ async function handleError(err) {
16
16
  //console.log(url);
17
17
 
18
18
  if (message) {
19
- console.error(`${err.message}\nSee details: ${url}\n`);
19
+ console.error(`\r${err.message}\nSee details: ${url}\n`);
20
20
  } else {
21
- console.error(`See details: ${url}\n`);
21
+ console.error(`\rSee details: ${url}\n`);
22
22
  }
23
23
  }
24
24
 
package/src/user.js CHANGED
@@ -1,8 +1,8 @@
1
1
  const db = require("./db");
2
2
 
3
- function getUser() {
3
+ function getUserWithIndex(index) {
4
4
  const users = db.get("user");
5
- return users.length ? users[0] : {
5
+ return users.length ? users[index] : {
6
6
  "id": "n/a",
7
7
  "userName": "n/a",
8
8
  "userMail": "n/a",
@@ -10,18 +10,43 @@ function getUser() {
10
10
  };
11
11
  }
12
12
 
13
- function getUserUsage() {
14
- const usage = db.get("serviceUsage");
13
+ function getUserWithId(userId) {
14
+ const database = db.load();
15
15
 
16
- if (usage && usage.serviceUsage) return usage;
17
-
18
- return {
19
- serviceUsage: {
20
- discovery: {},
21
- validation: {},
22
- transactions: {}
16
+ const u = database.user.find(x => x.id === userId);
17
+ if (!u) {
18
+ return {
19
+ "id": "n/a",
20
+ "userName": "n/a",
21
+ "userMail": "n/a",
22
+ "role": "n/a"
23
23
  }
24
- };
24
+ }
25
+ return u;
26
+ }
27
+
28
+ function getUserUsage(userId, service, month) {
29
+ const database = db.load();
30
+
31
+ const u = database.user.find(x => x.id === userId);
32
+ if (!u) return;
33
+
34
+ u.serviceUsage[service] ??= {};
35
+ const usage = u.serviceUsage[service][month];
36
+ return usage;
37
+ }
38
+
39
+
40
+ function setUserUsage(userId, service, month, value) {
41
+ const database = db.load();
42
+
43
+ const u = database.user.find(x => x.id === userId);
44
+ if (!u) return;
45
+
46
+ u.serviceUsage[service] ??= {};
47
+ u.serviceUsage[service][month] = value;
48
+
49
+ db.save(database);
25
50
  }
26
51
 
27
- module.exports = { getUser, getUserUsage };
52
+ module.exports = { getUserWithIndex, getUserWithId, getUserUsage, setUserUsage };
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 db = require("./db");
5
6
 
6
7
 
7
8
  function clearScreen(text) {
@@ -97,11 +98,15 @@ function validateId(type, id) {
97
98
  }
98
99
  }
99
100
 
101
+ function getShortId(id) {
102
+ return id.slice(0, 8);
103
+ }
104
+
100
105
  function createAppDirs(force=false) {
101
106
  fs.mkdirSync(config.NODE42_DIR, { recursive: true });
102
107
  fs.mkdirSync(config.ARTEFACTS_DIR, { recursive: true });
103
108
  fs.mkdirSync(config.TRANSACTIONS_DIR, { recursive: true });
104
- fs.mkdirSync(config.VALIDATION_DIR, { recursive: true });
109
+ fs.mkdirSync(config.VALIDATIONS_DIR, { recursive: true });
105
110
 
106
111
  if (!fs.existsSync(config.CONFIG_FILE) || force) {
107
112
  fs.writeFileSync(
@@ -114,6 +119,67 @@ function createAppDirs(force=false) {
114
119
  }
115
120
  }
116
121
 
122
+ function cleanAppDirs(options) {
123
+ const {
124
+ tokens,
125
+ artefacts,
126
+ transactions,
127
+ validations,
128
+ db: dbFlag,
129
+ all
130
+ } = options;
131
+
132
+ if ((all || tokens) && fs.existsSync(config.TOKENS_FILE)) {
133
+ fs.unlinkSync(config.TOKENS_FILE);
134
+ console.log("Tokens removed");
135
+ }
136
+
137
+ if ((all || dbFlag) && fs.existsSync(config.DATABASE_FILE)) {
138
+ fs.unlinkSync(config.DATABASE_FILE);
139
+ console.log("Database removed");
140
+ }
141
+
142
+ if (all || artefacts) {
143
+ try {
144
+ db.clear("artefacts");
145
+ } catch {}
146
+
147
+ if (fs.existsSync(config.ARTEFACTS_DIR)) {
148
+ fs.rmSync(config.ARTEFACTS_DIR, { recursive: true, force: true });
149
+ fs.mkdirSync(config.ARTEFACTS_DIR, { recursive: true });
150
+ }
151
+
152
+ console.log("Artefacts removed");
153
+ }
154
+
155
+ if (all || transactions) {
156
+ try {
157
+ db.clear("transactions");
158
+ } catch {}
159
+
160
+ if (fs.existsSync(config.TRANSACTIONS_DIR)) {
161
+ fs.rmSync(config.TRANSACTIONS_DIR, { recursive: true, force: true });
162
+ fs.mkdirSync(config.TRANSACTIONS_DIR, { recursive: true });
163
+ }
164
+
165
+ console.log("Transactions removed");
166
+ }
167
+
168
+ if (all || validations) {
169
+ try {
170
+ db.clear("validations");
171
+ } catch {}
172
+
173
+ if (fs.existsSync(config.VALIDATIONS_DIR)) {
174
+ fs.rmSync(config.VALIDATIONS_DIR, { recursive: true, force: true });
175
+ fs.mkdirSync(config.VALIDATIONS_DIR, { recursive: true });
176
+ }
177
+
178
+ console.log("Transactions removed");
179
+ }
180
+
181
+ }
182
+
117
183
  function buildDocLabel({ scheme, value }) {
118
184
  // 1. Document name (after :: before ##)
119
185
  const docMatch = value.match(/::([^#]+)##/);
@@ -163,4 +229,4 @@ function getArtefactExt(output, format) {
163
229
  }
164
230
  }
165
231
 
166
- module.exports = { clearScreen, startSpinner, ask, buildDocLabel, promptForDocument, validateEnv, validateId, createAppDirs, getArtefactExt };
232
+ module.exports = { clearScreen, startSpinner, ask, buildDocLabel, promptForDocument, validateEnv, validateId, getShortId, createAppDirs, cleanAppDirs, getArtefactExt };
package/test/auth.test.js CHANGED
@@ -17,6 +17,8 @@ describe("auth", () => {
17
17
  beforeEach(() => {
18
18
  sinon.restore();
19
19
 
20
+ global.fetch = sinon.stub();
21
+
20
22
  db.setSource(TEST_DB);
21
23
  if (fs.existsSync(TEST_DB)) fs.unlinkSync(TEST_DB);
22
24
 
@@ -34,14 +36,17 @@ describe("auth", () => {
34
36
  .onSecondCall().resolves("secret");
35
37
 
36
38
  sinon.stub(utils, "startSpinner").callsFake(() => () => {});
37
- sinon.stub(user, "getUser").returns({
39
+ sinon.stub(user, "getUserWithIndex")
40
+ .withArgs(0)
41
+ .returns({
42
+ id: "1",
38
43
  userName: "User",
39
44
  userMail: "user@test.com",
40
- role: "user"
45
+ role: "user",
41
46
  });
42
47
 
43
- sinon.stub(fs, "mkdirSync");
44
- sinon.stub(fs, "writeFileSync");
48
+ sinon.spy(fs, "mkdirSync");
49
+ sinon.spy(fs, "writeFileSync");
45
50
 
46
51
  sinon.stub(console, "log");
47
52
  sinon.stub(console, "error");
@@ -52,7 +57,7 @@ describe("auth", () => {
52
57
  auth = require("../src/auth");
53
58
  login = auth.login;
54
59
 
55
- sinon.stub(auth, "checkAuth").returns(true);
60
+ sinon.stub(auth, "checkAuth").resolves(true);
56
61
  });
57
62
 
58
63
  afterEach(() => {
@@ -62,7 +67,7 @@ describe("auth", () => {
62
67
 
63
68
  it("logs in successfully and writes tokens", async () => {
64
69
  // mock fetch
65
- global.fetch = sinon.stub().resolves({
70
+ global.fetch.resolves({
66
71
  ok: true,
67
72
  json: async () => ({
68
73
  accessToken: "a",
@@ -78,7 +83,7 @@ describe("auth", () => {
78
83
  });
79
84
 
80
85
  it("exits on http error", async () => {
81
- global.fetch = sinon.stub().resolves({
86
+ global.fetch.resolves({
82
87
  ok: false,
83
88
  status: 401,
84
89
  json: async () => ({})
package/test/db.test.js CHANGED
@@ -24,7 +24,6 @@ describe("db", () => {
24
24
  const dbObj = db.load();
25
25
  expect(dbObj).to.have.property("user");
26
26
  expect(dbObj).to.have.property("artefacts");
27
- expect(dbObj).to.have.property("usage");
28
27
  });
29
28
  });
30
29