multicloud_rule_manager 1.1.60 → 1.1.61

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,219 @@
1
+ import fs from "fs";
2
+ import XLSX from "xlsx";
3
+ import { getAlias } from "../utils/aliasManager.js";
4
+
5
+ export default {
6
+ command: "retrieveproduct <alias> <productName>",
7
+ describe: "Recupera struttura prodotto e genera Excel",
8
+ handler: async (argv) => {
9
+ try {
10
+ console.log("🔹 Retrieve in corso..");
11
+
12
+ const cred = getAlias(argv.alias);
13
+
14
+ // =========================
15
+ // 🔐 TOKEN
16
+ // =========================
17
+ const loginResp = await fetch(
18
+ `https://login-eon-no-prod.bit2win.cloud/auth/realms/${cred.realm}/protocol/openid-connect/token`,
19
+ {
20
+ method: "POST",
21
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
22
+ body: new URLSearchParams({
23
+ client_id: cred.clientId,
24
+ client_secret: cred.clientSecret,
25
+ username: cred.username,
26
+ password: cred.password,
27
+ grant_type: "password"
28
+ })
29
+ }
30
+ );
31
+
32
+ const { access_token } = await loginResp.json();
33
+
34
+ if (!access_token) {
35
+ throw new Error("Token non ricevuto");
36
+ }
37
+
38
+ const headers = {
39
+ Authorization: `Bearer ${access_token}`,
40
+ Accept: "application/json"
41
+ };
42
+
43
+ // =========================
44
+ // 📦 PRODUCTS
45
+ // =========================
46
+ const productsResp = await fetch(
47
+ `https://${cred.realm}.bit2win.cloud/api/data/v1/products/`,
48
+ { headers }
49
+ );
50
+
51
+ const products = await productsResp.json();
52
+
53
+ const product = products.find(p => p.name === argv.productName);
54
+
55
+ if (!product) {
56
+ throw new Error(`Prodotto "${argv.productName}" non trovato`);
57
+ }
58
+
59
+ const rootGuid = product.guid;
60
+
61
+ // =========================
62
+ // 🌳 STRUCTURE
63
+ // =========================
64
+ const structResp = await fetch(
65
+ `https://${cred.realm}.bit2win.cloud/api/data/v1/products_structure/`,
66
+ { headers }
67
+ );
68
+
69
+ const structure = await structResp.json();
70
+
71
+ // =========================
72
+ // 📂 HELPERS
73
+ // =========================
74
+ const sortByName = arr =>
75
+ arr.sort((a, b) => (a.name || "").localeCompare(b.name || ""));
76
+
77
+ const getCategories = () =>
78
+ sortByName(
79
+ structure.filter(
80
+ e => e.parent_guid === rootGuid && e.type === "category"
81
+ )
82
+ );
83
+
84
+ const getChildren = (categoryGuid) =>
85
+ sortByName(
86
+ structure.filter(e => e.parent_guid === categoryGuid)
87
+ );
88
+
89
+ // =========================
90
+ // 📡 FAMILIES
91
+ // =========================
92
+ const getFamilies = async (productId) => {
93
+ const resp = await fetch(
94
+ `https://${cred.realm}.bit2win.cloud/api/catalog/v1/products/${productId}/families`,
95
+ { headers }
96
+ );
97
+
98
+ const data = await resp.json();
99
+
100
+ return sortByName(
101
+ (data || []).map(f => ({
102
+ name: f.name,
103
+ visible: f.visible,
104
+ visible_web: f.visible_web,
105
+ attributes: sortByName(
106
+ (f.attributes || []).map(a => ({
107
+ name: a.name,
108
+ value_default: a.value_default,
109
+ read_only: a.read_only,
110
+ required: a.required,
111
+ visible: a.visible,
112
+ domains: sortByName(
113
+ (a.domains || []).map(d => ({
114
+ value: d.value,
115
+ visible: d.visible,
116
+ default: d.default
117
+ }))
118
+ )
119
+ }))
120
+ )
121
+ }))
122
+ );
123
+ };
124
+
125
+ // =========================
126
+ // 📊 DATASET 1
127
+ // =========================
128
+ const rows1 = [];
129
+
130
+ const categories = getCategories();
131
+
132
+ for (const cat of categories) {
133
+ const children = getChildren(cat.guid);
134
+
135
+ if (children.length === 0) {
136
+ rows1.push({
137
+ product: product.name,
138
+ category: cat.name,
139
+ child: ""
140
+ });
141
+ }
142
+
143
+ for (const child of children) {
144
+ rows1.push({
145
+ product: product.name,
146
+ category: cat.name,
147
+ child: child.name
148
+ });
149
+ }
150
+ }
151
+
152
+ // =========================
153
+ // 📊 DATASET 2
154
+ // =========================
155
+ const rows2 = [];
156
+
157
+ for (const cat of categories) {
158
+ const children = getChildren(cat.guid);
159
+
160
+ for (const child of children) {
161
+ if (!child.product_id) continue;
162
+
163
+ const families = await getFamilies(child.product_id);
164
+
165
+ for (const f of families) {
166
+ for (const attr of f.attributes) {
167
+ for (const dom of attr.domains) {
168
+ rows2.push({
169
+ product: product.name,
170
+ category: cat.name,
171
+ child: child.name,
172
+ family: f.name,
173
+ family_visible: f.visible,
174
+ family_visible_web: f.visible_web,
175
+ attribute: attr.name,
176
+ attr_default: attr.value_default,
177
+ attr_required: attr.required,
178
+ attr_visible: attr.visible,
179
+ domain_value: dom.value,
180
+ domain_visible: dom.visible,
181
+ domain_default: dom.default
182
+ });
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ // =========================
190
+ // 🔤 SORT GLOBALE
191
+ // =========================
192
+ const sortRows = (rows) =>
193
+ rows.sort((a, b) =>
194
+ Object.values(a).join("|").localeCompare(Object.values(b).join("|"))
195
+ );
196
+
197
+ const sorted1 = sortRows(rows1);
198
+ const sorted2 = sortRows(rows2);
199
+
200
+ // =========================
201
+ // 📁 EXCEL
202
+ // =========================
203
+ const writeExcel = (fileName, data) => {
204
+ const ws = XLSX.utils.json_to_sheet(data);
205
+ const wb = XLSX.utils.book_new();
206
+ XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
207
+ XLSX.writeFile(wb, fileName);
208
+ };
209
+
210
+ writeExcel("product_structure.xlsx", sorted1);
211
+ writeExcel("product_details.xlsx", sorted2);
212
+
213
+ console.log("✅ Excel generati con successo");
214
+
215
+ } catch (err) {
216
+ console.error("❌ Errore:", err.message);
217
+ }
218
+ }
219
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multicloud_rule_manager",
3
- "version": "1.1.60",
3
+ "version": "1.1.61",
4
4
  "description": "CLI interna per retrieve/upload con token",
5
5
  "main": "index.js",
6
6
  "type": "module",