@n42/cli 0.2.0 → 0.2.24
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/eslint.config.js +1 -0
- package/package.json +1 -1
- package/src/assets/download.svg +5 -0
- package/src/assets/node42-logo.svg +22 -0
- package/src/assets/wrapper-light.css +196 -0
- package/src/assets/wrapper.html.template +28 -0
- package/src/assets/wrapper.js +47 -0
- package/src/auth.js +3 -3
- package/src/cli.js +15 -15
- package/src/discover.js +25 -5
- package/src/utils.js +17 -7
- package/test/auth.test.js +1 -1
package/eslint.config.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 18V13.5862H6.5V16.5H17.5V13.5862H19V18H5Z" fill="#1F2328"/>
|
|
4
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.75 11.1287L14.5253 9.35331L15.586 10.414L12 14L8.41393 10.414L9.47459 9.35331L11.25 11.1287V6H12.75V11.1287Z" fill="#1F2328"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
|
+
|
|
4
|
+
<svg
|
|
5
|
+
version="1.1"
|
|
6
|
+
id="svg2"
|
|
7
|
+
width="512"
|
|
8
|
+
height="512"
|
|
9
|
+
viewBox="0 0 512 512"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs
|
|
13
|
+
id="defs6" />
|
|
14
|
+
<g
|
|
15
|
+
id="g8"
|
|
16
|
+
style="fill:#800000">
|
|
17
|
+
<path
|
|
18
|
+
style="fill:#1f2933;stroke-width:0.912989;fill-opacity:1"
|
|
19
|
+
d="m 250.68278,504.43224 c -6.75028,-0.86235 -10.40179,-2.51239 -26.3886,-11.92466 -7.18686,-4.23127 -22.51642,-13.16255 -34.06573,-19.84729 -17.61184,-10.1937 -90.544282,-52.7204 -115.949676,-67.60997 -4.017154,-2.35436 -11.743692,-6.86653 -17.170137,-10.02703 -16.284811,-9.4848 -23.240148,-18.04125 -25.20828,-31.01095 -1.118138,-7.36878 -1.234179,-204.26795 -0.126175,-214.14802 1.591615,-14.19281 8.942732,-23.64927 26.074433,-33.542 5.521577,-3.18841 16.612757,-9.63032 24.647065,-14.31534 8.034307,-4.685016 16.867478,-9.829712 19.62928,-11.432657 17.1769,-9.969498 73.75066,-42.991708 84.45153,-49.294531 47.47308,-27.961746 51.8264,-30.43697 56.37802,-32.055582 2.13356,-0.7587307 7.16605,-1.6087879 11.18321,-1.8890209 8.43903,-0.5887139 15.57532,1.3129793 24.19422,6.4473399 11.55324,6.882426 111.15984,65.007391 126.44904,73.788753 6.52788,3.749301 15.97732,9.214337 20.99877,12.144522 5.02144,2.930186 15.69117,9.125136 23.71051,13.766556 8.52175,4.9322 16.48887,10.2859 19.17278,12.88365 5.33504,5.16375 9.89879,13.28156 11.34032,20.17152 0.70738,3.3811 1.00748,36.23792 0.99634,109.10225 -0.0173,113.56626 0.0429,112.1513 -5.14415,121.02986 -4.93927,8.45458 -10.50629,12.50751 -43.35365,31.56272 -17.25514,10.00989 -39.58978,22.99615 -49.63267,28.85833 -10.04288,5.86218 -22.16282,12.91081 -26.93319,15.66363 -4.77036,2.75282 -24.69636,14.37995 -44.27999,25.83807 -19.58362,11.45813 -37.80671,21.84456 -40.49573,23.08097 -5.83374,2.6824 -13.25232,3.68189 -20.47754,2.75888 z m 14.85899,-29.89157 c 2.26422,-1.42476 15.20959,-9.0542 28.76748,-16.95432 13.5579,-7.90012 28.1429,-16.42086 32.41113,-18.93499 4.26823,-2.51413 10.4309,-6.11089 13.69484,-7.99281 3.26394,-1.88191 11.89169,-6.91401 19.17279,-11.18242 7.28109,-4.26842 21.24982,-12.40258 31.04164,-18.0759 53.01967,-30.71936 58.89622,-34.32123 60.94205,-37.3528 l 2.05422,-3.04409 -0.0155,-104.63052 -0.0146,-104.63054 -2.03926,-3.52865 c -1.67451,-2.89764 -4.56978,-4.99685 -16.1905,-11.73906 -7.78324,-4.51573 -20.31402,-11.7971 -27.84618,-16.1808 -7.53217,-4.38371 -23.14428,-13.44247 -34.6936,-20.13058 C 361.27694,93.475073 335.39369,78.371241 315.30792,66.599109 295.22215,54.826977 274.54248,42.706959 269.35314,39.665745 257.47369,32.703707 254.7286,32.500567 245.65467,37.91202 c -3.36875,2.008997 -17.01228,9.996331 -30.3191,17.749611 -13.30683,7.75329 -30.3569,17.719374 -37.88907,22.146844 -7.53216,4.427469 -19.44667,11.391863 -26.47669,15.476414 -88.881545,51.641631 -89.2094,51.842921 -90.999955,55.875931 -1.619188,3.6468 -1.681179,8.27351 -1.451745,108.35075 0.23966,104.52557 0.240025,104.54166 2.153377,107.11876 1.073676,1.44611 8.888227,6.62152 17.803296,11.7907 8.739318,5.06728 45.675957,26.59849 82.081407,47.84713 73.96101,43.1686 89.06095,51.89982 91.7382,53.04588 2.93773,1.25756 8.78762,0.0329 13.24729,-2.77337 z m -28.29436,-75.06372 c -7.2811,-3.52372 -17.34681,-8.2419 -22.36825,-10.48486 -10.24337,-4.57547 -13.7466,-7.39987 -15.06505,-12.14599 -0.53337,-1.91984 -0.90422,-20.32266 -0.90724,-45.01664 l -0.009,-41.76926 h -55.28124 c -60.895308,0 -59.490583,0.12764 -61.482452,-5.58644 -1.409747,-4.0439 -1.3861,-60.58499 0.02739,-64.80577 1.678074,-5.01204 4.780869,-8.45119 12.83736,-14.22883 37.757152,-27.07736 65.494042,-46.8543 111.203142,-79.28991 5.77465,-4.09776 16.25122,-11.54944 23.28122,-16.55931 31.1481,-22.197349 31.90278,-22.648895 37.6947,-22.554255 4.14971,0.06783 7.6418,1.108571 17.08468,5.091788 6.52787,2.753613 17.10713,7.203213 23.50947,9.887997 6.40234,2.68479 11.64062,5.17413 11.64062,5.53185 0,0.35772 -2.15695,2.08594 -4.7932,3.84051 -5.48095,3.64782 -50.20301,34.30436 -61.85504,42.40107 -4.26823,2.96588 -18.76276,12.96271 -32.2099,22.2152 -13.44724,9.25249 -35.63289,24.59365 -49.30143,34.09147 -13.66865,9.49782 -26.50218,18.39808 -28.51907,19.77836 -6.05585,4.14437 -6.98975,5.6617 -7.51536,12.21021 l -0.47995,5.97854 h 32.07962 32.07971 l 0.0676,-18.48804 c 0.0375,-10.16842 0.34529,-20.28648 0.68474,-22.48456 l 0.61709,-3.99652 25.44192,-17.23049 c 13.9931,-9.47677 25.59949,-17.23048 25.79195,-17.23048 0.19254,0 0.35003,17.8625 0.35003,39.69445 v 39.69444 l 16.35493,0.24884 16.35502,0.24885 -12.92501,10.04288 c -12.04625,9.36017 -13.14256,10.471 -16.12668,16.34057 l -3.20175,6.29768 -0.25848,62.40478 c -0.14214,34.32263 -0.55298,62.37639 -0.91298,62.3417 -0.35999,-0.0347 -6.61177,-2.94611 -13.89286,-6.46983 z m 33.78061,-83.68734 c 0,-27.3488 0.63005,-31.48088 5.67669,-37.22868 3.31416,-3.77461 1.63736,-2.67278 50.92866,-33.46574 20.83898,-13.01842 39.11767,-24.87028 40.61945,-26.33749 2.45247,-2.39614 2.73121,-3.24747 2.73897,-8.36483 l 0.009,-5.6972 -48.63422,-0.23626 -48.63412,-0.23626 0.24568,-20.306 0.24578,-20.30601 h 71.21318 c 80.74068,0 75.84852,-0.4478 80.42525,7.36184 l 2.30237,3.92877 -0.27928,26.76582 c -0.26541,25.42998 -0.37798,26.94809 -2.25618,30.41778 -2.83922,5.24508 -7.70764,9.47403 -18.10888,15.73043 -5.02143,3.02042 -15.29257,9.35994 -22.82473,14.08782 -7.53216,4.7279 -23.8556,14.94877 -36.27426,22.71308 -12.41867,7.7643 -22.58709,14.42505 -22.59649,14.80165 -0.009,0.37661 23.19568,0.68474 51.56683,0.68474 28.37115,0 51.59541,0.30814 51.60956,0.68475 0.0137,0.3766 -1.29535,9.4152 -2.91006,20.08577 l -2.93571,19.40102 h -76.0636 -76.06352 z"
|
|
20
|
+
id="path170" />
|
|
21
|
+
</g>
|
|
22
|
+
</svg>
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: transparent;
|
|
3
|
+
--card: #ffffff;
|
|
4
|
+
--border: #e5e7eb;
|
|
5
|
+
--border-soft: #f1f5f9;
|
|
6
|
+
--border-strong: #d1d5db;
|
|
7
|
+
--text-light: #9ca3af;
|
|
8
|
+
--text: #111827;
|
|
9
|
+
--muted: #6b7280;
|
|
10
|
+
--brand-soft: #eaf3ff; /* Soft, light blue */
|
|
11
|
+
--brand: #3f9cff; /* Main brand color */
|
|
12
|
+
--brand-strong: #0b3a82; /* Strong blue for contrast */
|
|
13
|
+
--brand-hover: #1e6fd0; /* Slightly darker hover state */
|
|
14
|
+
--brand-active: #1666c1; /* Active state */
|
|
15
|
+
--brand-button: #1d72d2; /* Darker shade of the brand color */
|
|
16
|
+
--shadow-soft: 0 2px 4px rgba(0, 0, 0, 0.04);
|
|
17
|
+
--shadow-form: 0 3px 8px rgba(0, 0, 0, 0.05);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
margin: 0;
|
|
22
|
+
height: 100vh;
|
|
23
|
+
background: #fff;
|
|
24
|
+
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
|
25
|
+
overflow-y: auto;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#page {
|
|
29
|
+
min-height: calc(100vh - 56px);
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
padding-top: 32px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#app-shell {
|
|
36
|
+
width: 100%;
|
|
37
|
+
max-width: 1450px;
|
|
38
|
+
height: 100%;
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#app-header {
|
|
44
|
+
height: 62px;
|
|
45
|
+
display: flex;
|
|
46
|
+
justify-content: space-between;
|
|
47
|
+
align-items: center;
|
|
48
|
+
padding: 0 16px;
|
|
49
|
+
position: fixed;
|
|
50
|
+
top: 0;
|
|
51
|
+
left: 0;
|
|
52
|
+
right: 0;
|
|
53
|
+
z-index: 100;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.header-left {
|
|
57
|
+
gap: 16px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.header-right {
|
|
61
|
+
gap: 16px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#appBtn {
|
|
65
|
+
display: flex;
|
|
66
|
+
width: 34px;
|
|
67
|
+
height: 34px;
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#timeline {
|
|
72
|
+
flex: 1;
|
|
73
|
+
overflow-y: auto;
|
|
74
|
+
padding: 24px 16px 24px 16px;
|
|
75
|
+
background: var(--bg);
|
|
76
|
+
min-height: 0; /* for flex scroll containers */
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.bubble {
|
|
80
|
+
position: relative;
|
|
81
|
+
background: #ffffff;
|
|
82
|
+
border-radius: 12px;
|
|
83
|
+
padding: 16px;
|
|
84
|
+
margin-bottom: 64px;
|
|
85
|
+
border: 1px solid var(--border);
|
|
86
|
+
}
|
|
87
|
+
.bubble.info {
|
|
88
|
+
width: 50%;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.bubble svg {
|
|
92
|
+
width: 100%;
|
|
93
|
+
height: auto;
|
|
94
|
+
max-width: 100%;
|
|
95
|
+
display: block;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.bubble-time {
|
|
99
|
+
position: absolute;
|
|
100
|
+
bottom: -24px;
|
|
101
|
+
left: 10px;
|
|
102
|
+
font-size: 0.65rem;
|
|
103
|
+
color: var(--text-light);
|
|
104
|
+
cursor: pointer;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.bubble-time:hover {
|
|
108
|
+
color: var(--text);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.bubble-link {
|
|
112
|
+
position: absolute;
|
|
113
|
+
bottom: 14px;
|
|
114
|
+
right: 21px;
|
|
115
|
+
display: inline-flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: 2px;
|
|
118
|
+
font-size: 0.7rem;
|
|
119
|
+
text-decoration: none;
|
|
120
|
+
color: var(--text);
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.bubble-link img {
|
|
125
|
+
width: 24px;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.bubble-link:hover {
|
|
129
|
+
color: var(--text);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.bubble-close {
|
|
133
|
+
position: absolute;
|
|
134
|
+
top: 10px;
|
|
135
|
+
right: 10px;
|
|
136
|
+
border: none;
|
|
137
|
+
background: #f6f6f6;
|
|
138
|
+
border-radius: 999px;
|
|
139
|
+
padding: 4px;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
line-height: 1;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.material-icons.bubble-close {
|
|
145
|
+
font-size: 14px;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.bubble-close:hover {
|
|
149
|
+
background: #fee2e2;;
|
|
150
|
+
color: #991b1b;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.bubble-info {
|
|
154
|
+
display: flex;
|
|
155
|
+
gap: 8px;
|
|
156
|
+
align-items: flex-start;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.bubble-info-icon {
|
|
160
|
+
font-size: 20px;
|
|
161
|
+
line-height: 1;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.bubble-info-icon.error {
|
|
165
|
+
color: #ef4444;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.bubble-info-icon.warning {
|
|
169
|
+
color: #f59e0b;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.bubble-info-icon.info {
|
|
173
|
+
color: #1f7fe5;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.bubble-info-header {
|
|
177
|
+
font-weight: 600;
|
|
178
|
+
margin-bottom: 2px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.bubble-info-body {
|
|
182
|
+
font-size: 0.9rem;
|
|
183
|
+
line-height: 1.3;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.bubble-info-body a {
|
|
187
|
+
color: var(--text);
|
|
188
|
+
font-weight: 600;
|
|
189
|
+
text-decoration: underline;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.bubble-info-body a:hover {
|
|
193
|
+
color: var(--brand-active);
|
|
194
|
+
font-weight: 600;
|
|
195
|
+
text-decoration: none;
|
|
196
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Node42</title>
|
|
6
|
+
<link rel="stylesheet" href="../../assets/wrapper-light.css">
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app-header">
|
|
10
|
+
<div class="header-left">
|
|
11
|
+
<img id="appBtn" src="../../assets/node42-logo.svg" alt="Node42" onclick="window.open('https://www.node42.dev', '_blank');">
|
|
12
|
+
</div>
|
|
13
|
+
<div class="header-right"></div>
|
|
14
|
+
</div>
|
|
15
|
+
<div id="page">
|
|
16
|
+
<div id="app-shell">
|
|
17
|
+
<div id="timeline"></div>
|
|
18
|
+
<div id="bubble" class="bubble" data-uuid="/--UUID--/">
|
|
19
|
+
<!-- SVG -->
|
|
20
|
+
<div class="bubble-time"><!-- TIME --></div>
|
|
21
|
+
<a id="link" class="bubble-link" title="Download discovery PlantUML diagram (SVG)"><img src="../../assets/download.svg" alt="Download">Download</a>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<script src="../../assets/wrapper.js" defer></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
function formatSvg() {
|
|
2
|
+
const bubble = document.getElementById("bubble");
|
|
3
|
+
const svgEl = bubble.querySelector("svg");
|
|
4
|
+
if (svgEl) {
|
|
5
|
+
svgEl.removeAttribute("width");
|
|
6
|
+
svgEl.removeAttribute("height");
|
|
7
|
+
svgEl.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
8
|
+
svgEl.style.removeProperty('width');
|
|
9
|
+
svgEl.style.removeProperty('height');
|
|
10
|
+
|
|
11
|
+
const svgTitleEl = svgEl.querySelector("title");
|
|
12
|
+
if (svgTitleEl) {
|
|
13
|
+
svgTitleEl.remove();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function addDownloadLinkListener() {
|
|
19
|
+
const bubble = document.getElementById("bubble");
|
|
20
|
+
const svgEl = bubble.querySelector("svg");
|
|
21
|
+
const svg = new XMLSerializer().serializeToString(svgEl);
|
|
22
|
+
const refId = bubble.dataset.uuid;
|
|
23
|
+
|
|
24
|
+
const linkEl = document.getElementById("link");
|
|
25
|
+
linkEl.addEventListener("click", (e) => {
|
|
26
|
+
e.preventDefault();
|
|
27
|
+
|
|
28
|
+
const blob = new Blob([svg], { type: "image/svg+xml" });
|
|
29
|
+
const url = URL.createObjectURL(blob);
|
|
30
|
+
|
|
31
|
+
const a = document.createElement("a");
|
|
32
|
+
a.href = url;
|
|
33
|
+
a.id = `discovery-${refId}`;
|
|
34
|
+
a.download = `discovery${refId ? "-" + refId : ""}.svg`;
|
|
35
|
+
|
|
36
|
+
document.body.appendChild(a);
|
|
37
|
+
a.click();
|
|
38
|
+
document.body.removeChild(a);
|
|
39
|
+
|
|
40
|
+
URL.revokeObjectURL(url);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
45
|
+
formatSvg();
|
|
46
|
+
addDownloadLinkListener();
|
|
47
|
+
});
|
package/src/auth.js
CHANGED
|
@@ -2,15 +2,14 @@ const fs = require("fs");
|
|
|
2
2
|
const { NODE42_DIR, TOKENS_FILE, API_URL, EP_SIGNIN, EP_REFRESH, EP_ME } = require("./config");
|
|
3
3
|
const { handleError } = require("./errors");
|
|
4
4
|
const { getUserWithIndex } = require("./user");
|
|
5
|
-
const {
|
|
5
|
+
const { ask, startSpinner } = require("./utils");
|
|
6
6
|
|
|
7
7
|
const db = require("./db");
|
|
8
|
-
const pkg = require("../package.json");
|
|
9
8
|
const C = require("./colors");
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
async function login() {
|
|
13
|
-
|
|
12
|
+
console.log(`${C.BOLD}Sign in to your account${C.RESET}`);
|
|
14
13
|
let user = getUserWithIndex(0);
|
|
15
14
|
|
|
16
15
|
const username = await ask("Username", user.userMail ?? "");
|
|
@@ -65,6 +64,7 @@ function logout() {
|
|
|
65
64
|
fs.unlinkSync(TOKENS_FILE);
|
|
66
65
|
}
|
|
67
66
|
db.clear("user");
|
|
67
|
+
console.log(`${C.RED}Sign out complete${C.RESET}\n`);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function loadTokens() {
|
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 {
|
|
7
|
+
const { 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();
|
|
@@ -19,7 +19,7 @@ const path = require("path");
|
|
|
19
19
|
|
|
20
20
|
program
|
|
21
21
|
.name("n42")
|
|
22
|
-
.description("Node42
|
|
22
|
+
.description("Node42 CLI for eDelivery path discovery and diagnostics")
|
|
23
23
|
.version(pkg.version);
|
|
24
24
|
|
|
25
25
|
program
|
|
@@ -65,7 +65,7 @@ program
|
|
|
65
65
|
|
|
66
66
|
program
|
|
67
67
|
.command("me")
|
|
68
|
-
.description("Returns identity and
|
|
68
|
+
.description("Returns identity and service usage for the authenticated user.")
|
|
69
69
|
.action(async () => {
|
|
70
70
|
const stopSpinner = startSpinner();
|
|
71
71
|
|
|
@@ -73,13 +73,12 @@ program
|
|
|
73
73
|
stopSpinner();
|
|
74
74
|
|
|
75
75
|
if (!authenticated) {
|
|
76
|
-
console.error("Not authenticated");
|
|
77
76
|
process.exit(1);
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
const user = getUserWithIndex(0);
|
|
81
80
|
const currentMonth = new Date().toISOString().slice(0, 7);
|
|
82
|
-
console.log(`Node42
|
|
81
|
+
console.log(`Node42 Account\n
|
|
83
82
|
${C.BOLD}User${C.RESET}
|
|
84
83
|
ID : ${C.CYAN}${user.id}${C.RESET}
|
|
85
84
|
Name : ${user.userName}
|
|
@@ -100,7 +99,7 @@ program
|
|
|
100
99
|
|
|
101
100
|
program
|
|
102
101
|
.command("usage <service>")
|
|
103
|
-
.description("Returns usage for the authenticated user.")
|
|
102
|
+
.description("Returns service usage for the authenticated user.")
|
|
104
103
|
.option("-m, --month <yyyy-mm>", "Show usage for a specific month")
|
|
105
104
|
.action((service, options) => {
|
|
106
105
|
const user = getUserWithIndex(0);
|
|
@@ -110,14 +109,13 @@ program
|
|
|
110
109
|
usage = 0;
|
|
111
110
|
}
|
|
112
111
|
|
|
113
|
-
clearScreen(`Node42 CLI v${pkg.version}\n`);
|
|
114
112
|
console.log(`${C.BOLD}${capitalize(service)} usage${C.RESET}`);
|
|
115
113
|
console.log(` • ${currentMonth}: ${C.RED}${usage}${C.RESET}\n`);
|
|
116
114
|
});
|
|
117
115
|
|
|
118
116
|
program
|
|
119
117
|
.command("history [participantId]")
|
|
120
|
-
.description("Show local
|
|
118
|
+
.description("Show local history with filtering")
|
|
121
119
|
.option("--today", "Show only today's artefacts")
|
|
122
120
|
.option("--day <yyyy-mm-dd>", "Show artefacts for a specific day")
|
|
123
121
|
.option("--last <n>", "Show only last N results", parseInt)
|
|
@@ -156,15 +154,13 @@ program
|
|
|
156
154
|
}
|
|
157
155
|
|
|
158
156
|
if (!artefacts.length) {
|
|
159
|
-
clearScreen(`Node42 CLI v${pkg.version}`);
|
|
160
157
|
const filter = dayFilter !== null ? ` (${dayFilter})` : ``;
|
|
161
|
-
console.log(
|
|
158
|
+
console.log(`${C.RED}No artefacts found.${C.RESET}${C.DIM}${filter}${C.RESET}\n`);
|
|
162
159
|
return;
|
|
163
160
|
}
|
|
164
161
|
|
|
165
162
|
// ---- OUTPUT ----
|
|
166
|
-
|
|
167
|
-
console.log(`Found ${C.RED}${artefacts.length}${C.RESET} artefact(s)${filterInfo}\n`);
|
|
163
|
+
console.log(`${C.BOLD}Found ${artefacts.length} artefact(s)${filterInfo}${C.RESET}\n`);
|
|
168
164
|
|
|
169
165
|
const DATE = "DATE".padEnd(19);
|
|
170
166
|
const PID = "PID".padEnd(15);
|
|
@@ -176,7 +172,13 @@ program
|
|
|
176
172
|
const iso = d.toISOString(); // 2026-01-30T16:53:28.123Z
|
|
177
173
|
const date = iso.slice(0, 10); // 2026-01-30
|
|
178
174
|
const time = iso.slice(11, 19); // 16:53:28
|
|
179
|
-
|
|
175
|
+
|
|
176
|
+
let file;
|
|
177
|
+
if (item.file.includes(".svg")) {
|
|
178
|
+
file = path.join(ARTEFACTS_DIR, `${item.file.replace(".svg", ".html")}`);
|
|
179
|
+
} else {
|
|
180
|
+
file = path.join(ARTEFACTS_DIR, `${item.file}`);
|
|
181
|
+
}
|
|
180
182
|
const link = `\u001B]8;;file://${file}\u0007Open\u001B]8;;\u0007`
|
|
181
183
|
|
|
182
184
|
let pid = item.participantId;
|
|
@@ -208,8 +210,6 @@ discover
|
|
|
208
210
|
.option("--reverse-lookup", "Enable reverse lookup", false)
|
|
209
211
|
.option("--probe-endpoints", "Probe resolved endpoints", false)
|
|
210
212
|
.action((participantId, options) => {
|
|
211
|
-
clearScreen(`Node42 CLI v${pkg.version}`);
|
|
212
|
-
|
|
213
213
|
try { validateEnv(options.env); }
|
|
214
214
|
catch (e) {
|
|
215
215
|
console.error(e.message);
|
package/src/discover.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const pkg = require("../package.json");
|
|
4
3
|
const db = require("./db");
|
|
5
4
|
const C = require("./colors");
|
|
6
5
|
|
|
7
6
|
const { fetchWithAuth } = require("./auth");
|
|
8
|
-
const { API_URL, EP_DISCOVER, DEFAULT_OUTPUT, DEFAULT_FORMAT, ARTEFACTS_DIR } = require("./config");
|
|
7
|
+
const { API_URL, EP_DISCOVER, DEFAULT_OUTPUT, DEFAULT_FORMAT, NODE42_DIR, ARTEFACTS_DIR } = require("./config");
|
|
9
8
|
const { getUserWithIndex, setUserUsage } = require("./user");
|
|
10
|
-
const {
|
|
9
|
+
const { startSpinner, buildDocLabel, promptForDocument, getShortId, getArtefactExt } = require("./utils");
|
|
11
10
|
const { handleError } = require("./errors");
|
|
12
11
|
|
|
13
12
|
const DEFAULT_DISCOVERY_INPUT = {
|
|
@@ -35,6 +34,27 @@ const DEFAULT_DISCOVERY_INPUT = {
|
|
|
35
34
|
const discoveryInput = DEFAULT_DISCOVERY_INPUT;
|
|
36
35
|
let docSelected = false;
|
|
37
36
|
|
|
37
|
+
function wrapSvg(id, svg) {
|
|
38
|
+
let html;
|
|
39
|
+
|
|
40
|
+
const now = new Date();
|
|
41
|
+
const timeText = now.toLocaleTimeString([], {
|
|
42
|
+
hour: "2-digit",
|
|
43
|
+
minute: "2-digit"
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const templateFile = path.join(NODE42_DIR, "assets/wrapper.html.template");
|
|
47
|
+
const template = fs.readFileSync(templateFile, "utf8");
|
|
48
|
+
|
|
49
|
+
html = template.replace("<!-- SVG -->", svg);
|
|
50
|
+
html = html.replace("<!-- TIME -->", `${timeText} • ${id}`);
|
|
51
|
+
html = html.replace("/--UUID--/", id);
|
|
52
|
+
|
|
53
|
+
const htmlFile = path.join(ARTEFACTS_DIR, `${id}.html`);
|
|
54
|
+
fs.writeFileSync(htmlFile, html);
|
|
55
|
+
return htmlFile;
|
|
56
|
+
}
|
|
57
|
+
|
|
38
58
|
async function processSupportedDocuments(encodedDocs, onDone) {
|
|
39
59
|
if (encodedDocs && !docSelected) {
|
|
40
60
|
const docs = JSON.parse(Buffer.from(encodedDocs, "base64").toString("utf8"))
|
|
@@ -88,7 +108,6 @@ async function runDiscovery(participantId, options) {
|
|
|
88
108
|
}
|
|
89
109
|
};
|
|
90
110
|
|
|
91
|
-
clearScreen(`Node42 CLI v${pkg.version}\n`);
|
|
92
111
|
const stopSpinner = startSpinner();
|
|
93
112
|
|
|
94
113
|
const url = `${API_URL}/${EP_DISCOVER}?output=${output}&format=${format}`;
|
|
@@ -153,7 +172,8 @@ async function runDiscovery(participantId, options) {
|
|
|
153
172
|
const file = path.join(ARTEFACTS_DIR, `${fileName}`);
|
|
154
173
|
fs.writeFileSync(file, svg);
|
|
155
174
|
|
|
156
|
-
const
|
|
175
|
+
const htmlFile = wrapSvg(fileId, svg);
|
|
176
|
+
const link = `\u001B]8;;file://${htmlFile}\u0007Open\u001B]8;;\u0007`;
|
|
157
177
|
|
|
158
178
|
console.log(`${C.BOLD}Discovery completed${C.RESET}`);
|
|
159
179
|
console.log(`PID : ${participantId}`);
|
package/src/utils.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
const inquirer = require("inquirer");
|
|
3
3
|
const readline = require("readline");
|
|
4
|
+
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
4
8
|
const config = require("./config");
|
|
5
9
|
const pkg = require("../package.json");
|
|
6
10
|
const db = require("./db");
|
|
7
11
|
const C = require("./colors");
|
|
8
12
|
|
|
9
13
|
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
function writeHeader(text, clearScreen=false) {
|
|
15
|
+
if (clearScreen) {
|
|
16
|
+
process.stdout.write("\x1Bc");
|
|
17
|
+
}
|
|
18
|
+
if (text && text.length > 0) {
|
|
13
19
|
process.stdout.write(text + "\n");
|
|
20
|
+
} else {
|
|
21
|
+
process.stdout.write(`Node42 CLI v${pkg.version}`);
|
|
14
22
|
}
|
|
15
23
|
}
|
|
16
24
|
|
|
@@ -115,6 +123,10 @@ function createAppDirs(force=false) {
|
|
|
115
123
|
fs.mkdirSync(config.TRANSACTIONS_DIR, { recursive: true });
|
|
116
124
|
fs.mkdirSync(config.VALIDATIONS_DIR, { recursive: true });
|
|
117
125
|
|
|
126
|
+
const wrapperSrc = path.join(__dirname, "assets");
|
|
127
|
+
const wrapperDest = path.join(config.NODE42_DIR, "assets");
|
|
128
|
+
fs.cpSync(wrapperSrc, wrapperDest, { recursive: true });
|
|
129
|
+
|
|
118
130
|
if (!fs.existsSync(config.CONFIG_FILE) || force) {
|
|
119
131
|
fs.writeFileSync(
|
|
120
132
|
config.CONFIG_FILE,
|
|
@@ -141,8 +153,6 @@ function cleanAppDirs(options) {
|
|
|
141
153
|
return;
|
|
142
154
|
}
|
|
143
155
|
|
|
144
|
-
clearScreen(`Node42 CLI v${pkg.version}\n`);
|
|
145
|
-
|
|
146
156
|
const removed = [];
|
|
147
157
|
|
|
148
158
|
if ((all || tokens) && fs.existsSync(config.TOKENS_FILE)) {
|
|
@@ -252,4 +262,4 @@ function getArtefactExt(output, format) {
|
|
|
252
262
|
}
|
|
253
263
|
}
|
|
254
264
|
|
|
255
|
-
module.exports = {
|
|
265
|
+
module.exports = { writeHeader, startSpinner, ask, buildDocLabel, promptForDocument, validateEnv, validateId, getShortId, capitalize, createAppDirs, cleanAppDirs, getArtefactExt };
|
package/test/auth.test.js
CHANGED
|
@@ -30,7 +30,7 @@ describe("auth", () => {
|
|
|
30
30
|
utils = require("../src/utils");
|
|
31
31
|
user = require("../src/user");
|
|
32
32
|
|
|
33
|
-
sinon.stub(utils, "
|
|
33
|
+
//sinon.stub(utils, "writeHeader");
|
|
34
34
|
sinon.stub(utils, "ask")
|
|
35
35
|
.onFirstCall().resolves("user")
|
|
36
36
|
.onSecondCall().resolves("secret");
|