@n42/cli 0.1.40 → 0.1.63

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.
@@ -0,0 +1,142 @@
1
+ const { expect } = require("chai");
2
+ const sinon = require("sinon");
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const db = require("../src/db");
7
+
8
+ describe("db", () => {
9
+ const TEST_DB = path.join(os.tmpdir(), "test-db.json");
10
+
11
+ beforeEach(() => {
12
+ // override DB path for tests
13
+ db.setSource(TEST_DB);
14
+ if (fs.existsSync(TEST_DB)) fs.unlinkSync(TEST_DB);
15
+ });
16
+
17
+ afterEach(() => {
18
+ if (fs.existsSync(TEST_DB)) fs.unlinkSync(TEST_DB);
19
+ if (fs.existsSync(TEST_DB + ".tmp")) fs.unlinkSync(TEST_DB + ".tmp");
20
+ });
21
+
22
+ describe("load()", () => {
23
+ it("returns default structure when file missing", () => {
24
+ const dbObj = db.load();
25
+ expect(dbObj).to.have.property("user");
26
+ expect(dbObj).to.have.property("artefacts");
27
+ expect(dbObj).to.have.property("usage");
28
+ });
29
+ });
30
+
31
+ describe("insert() & getCollection()", () => {
32
+ it("inserts and retrieves artefact", () => {
33
+ db.insert("artefacts", {
34
+ id: "1",
35
+ participantId: "0007:123"
36
+ });
37
+
38
+ const artefacts = db.get("artefacts");
39
+ expect(artefacts.length).to.equal(1);
40
+ expect(artefacts[0].id).to.equal("1");
41
+ });
42
+ });
43
+
44
+ describe("find()", () => {
45
+ it("filters by predicate", () => {
46
+ db.insert("artefacts", { id: "1", participantId: "A" });
47
+ db.insert("artefacts", { id: "2", participantId: "B" });
48
+
49
+ const result = db.find("artefacts", x => x.participantId === "A");
50
+ expect(result.length).to.equal(1);
51
+ expect(result[0].id).to.equal("1");
52
+ });
53
+ });
54
+
55
+ describe("indexBy()", () => {
56
+ it("indexes by key", () => {
57
+ const list = [
58
+ { id: "1", participantId: "A" },
59
+ { id: "2", participantId: "A" },
60
+ { id: "3", participantId: "B" }
61
+ ];
62
+
63
+ const idx = db.indexBy(list, "participantId");
64
+
65
+ expect(idx["A"].length).to.equal(2);
66
+ expect(idx["B"].length).to.equal(1);
67
+ });
68
+ });
69
+
70
+ describe("indexByFn()", () => {
71
+ it("groups by derived key", () => {
72
+ const list = [
73
+ { id: 1, date: "2026-01-01" },
74
+ { id: 2, date: "2026-01-01" },
75
+ { id: 3, date: "2026-01-02" }
76
+ ];
77
+
78
+ const idx = db.indexByFn(list, x => x.date);
79
+ expect(idx["2026-01-01"].length).to.equal(2);
80
+ });
81
+ });
82
+
83
+ describe("save()", () => {
84
+ it("writes file atomically", () => {
85
+ db.save({ artefacts: [] });
86
+ expect(fs.existsSync(TEST_DB)).to.be.true;
87
+ });
88
+
89
+ it("doesn't corrupt original file if rename fails", () => {
90
+ const original = { artefacts: [{ id: 1 }] };
91
+ db.save(original);
92
+
93
+ // stub rename to simulate crash
94
+ const stub = sinon.stub(fs, "renameSync").throws(new Error("fail"));
95
+
96
+ try {
97
+ db.save({ artefacts: [{ id: 2 }] });
98
+ } catch (e) {
99
+ // expected
100
+ }
101
+
102
+ stub.restore();
103
+
104
+ // original file should still be valid JSON
105
+ const content = JSON.parse(fs.readFileSync(TEST_DB, "utf8"));
106
+ expect(content.artefacts[0].id).to.equal(1);
107
+ });
108
+ });
109
+
110
+ describe("upsert()", () => {
111
+ it("inserts new item if id does not exist", () => {
112
+ db.upsert("artefacts", { id: "1", name: "A" });
113
+
114
+ const list = db.get("artefacts");
115
+ expect(list.length).to.equal(1);
116
+ expect(list[0].name).to.equal("A");
117
+ });
118
+
119
+ it("updates existing item if id exists", () => {
120
+ db.upsert("artefacts", { id: "1", name: "A" });
121
+ db.upsert("artefacts", { id: "1", name: "B" });
122
+
123
+ const list = db.get("artefacts");
124
+
125
+ expect(list.length).to.equal(1); // no duplicate
126
+ expect(list[0].name).to.equal("B"); // updated
127
+ });
128
+
129
+ it("adds createdAt on insert and updatedAt on update", () => {
130
+ db.upsert("artefacts", { id: "1" });
131
+ let item = db.get("artefacts")[0];
132
+
133
+ expect(item.createdAt).to.exist;
134
+
135
+ db.upsert("artefacts", { id: "1", value: 2 });
136
+ item = db.get("artefacts")[0];
137
+
138
+ expect(item.updatedAt).to.exist;
139
+ });
140
+
141
+ });
142
+ });
@@ -1,27 +1,29 @@
1
1
  const { buildDocLabel } = require("../src/utils");
2
2
  const { expect } = require("chai");
3
3
 
4
- describe("buildDocLabel", () => {
5
- it("formats wildcard invoice", () => {
6
- const doc = {
7
- scheme: "peppol-doctype-wildcard",
8
- value: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##*"
9
- };
4
+ describe("utils", () => {
5
+ describe("buildDocLabel()", () => {
6
+ it("formats wildcard invoice", () => {
7
+ const doc = {
8
+ scheme: "peppol-doctype-wildcard",
9
+ value: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##*"
10
+ };
10
11
 
11
- expect(buildDocLabel(doc)).to.equal("Any Invoice (Wildcard)");
12
- });
12
+ expect(buildDocLabel(doc)).to.equal("Any Invoice (Wildcard)");
13
+ });
13
14
 
14
- it("formats BIS invoice", () => {
15
- const doc = {
16
- scheme: "busdox-docid-qns",
17
- value: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017"
18
- };
15
+ it("formats BIS invoice", () => {
16
+ const doc = {
17
+ scheme: "busdox-docid-qns",
18
+ value: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017"
19
+ };
19
20
 
20
- expect(buildDocLabel(doc)).to.equal("Invoice (BIS 3)");
21
- });
21
+ expect(buildDocLabel(doc)).to.equal("Invoice (BIS 3)");
22
+ });
22
23
 
23
- it("falls back on unknown value", () => {
24
- const doc = { scheme: "busdox-docid-qns", value: "unknown" };
25
- expect(buildDocLabel(doc)).to.equal("Document");
24
+ it("falls back on 'unknown' value", () => {
25
+ const doc = { scheme: "busdox-docid-qns", value: "unknown" };
26
+ expect(buildDocLabel(doc)).to.equal("Document");
27
+ });
26
28
  });
27
29
  });
package/src/signin.js DELETED
@@ -1,58 +0,0 @@
1
- const fs = require("fs");
2
-
3
- const { NODE42_DIR, TOKENS_FILE, API_URL, EP_SIGNIN } = require("./config");
4
- const { checkAuth } = require("./auth");
5
- const { getUserInfo } = require("./user");
6
- const { clearScreen, ask, startSpinner } = require("./utils");
7
-
8
-
9
- async function signin() {
10
- clearScreen("Sign in to Node42");
11
-
12
- const username = await ask("Username: ");
13
- const password = await ask("Password: ", true);
14
-
15
- let stopSpinner = startSpinner();
16
-
17
- const res = await fetch(`${API_URL}/${EP_SIGNIN}`, {
18
- method: "POST",
19
- headers: { "Content-Type": "application/json" },
20
- body: JSON.stringify({ username, password })
21
- });
22
-
23
- if (!res.ok) {
24
- stopSpinner();
25
-
26
- console.error("Login failed: ", res.status);
27
- process.exit(1);
28
- }
29
-
30
- const tokens = await res.json();
31
-
32
- const { accessToken, refreshToken, idToken } = tokens;
33
- if (!accessToken || !refreshToken || !idToken) {
34
- stopSpinner();
35
-
36
- console.error("Invalid auth response");
37
- process.exit(1);
38
- }
39
-
40
- fs.mkdirSync(NODE42_DIR, { recursive: true });
41
- fs.writeFileSync(
42
- TOKENS_FILE,
43
- JSON.stringify({ accessToken, refreshToken, idToken }, null, 2)
44
- );
45
-
46
- stopSpinner();
47
- stopSpinner = startSpinner();
48
-
49
- checkAuth();
50
- const user = getUserInfo();
51
- console.log(
52
- `Authenticated as ${user.userName} <${user.userMail}> (${user.role})`
53
- );
54
-
55
- stopSpinner();
56
- }
57
-
58
- module.exports = { signin };