goods-exporter 1.3.3 → 1.3.4
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/dist/bundle.d.ts +734 -0
- package/dist/cjs/index.cjs +1060 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/esm/index.mjs +1049 -0
- package/dist/esm/index.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1049 @@
|
|
|
1
|
+
import { once } from 'events';
|
|
2
|
+
import { PassThrough } from 'stream';
|
|
3
|
+
import pkg from 'exceljs';
|
|
4
|
+
import { JsonStreamStringify } from 'json-stream-stringify';
|
|
5
|
+
import { XMLBuilder } from 'fast-xml-parser';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
|
|
8
|
+
const buildCategoryPaths = (categories) => {
|
|
9
|
+
const idToCategory = /* @__PURE__ */ new Map();
|
|
10
|
+
categories.forEach((category) => {
|
|
11
|
+
idToCategory.set(category.id, category);
|
|
12
|
+
});
|
|
13
|
+
const categoryPaths = /* @__PURE__ */ new Map();
|
|
14
|
+
categories.forEach((category) => {
|
|
15
|
+
const path = [];
|
|
16
|
+
let currentCategory = category;
|
|
17
|
+
while (currentCategory) {
|
|
18
|
+
path.unshift(currentCategory);
|
|
19
|
+
if (currentCategory.parentId !== void 0) {
|
|
20
|
+
currentCategory = idToCategory.get(currentCategory.parentId);
|
|
21
|
+
} else {
|
|
22
|
+
currentCategory = void 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
categoryPaths.set(category.id, path);
|
|
26
|
+
});
|
|
27
|
+
return categoryPaths;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const writeWithDrain = (stream) => {
|
|
31
|
+
return async (chunk) => {
|
|
32
|
+
const canWrite = stream.write(chunk);
|
|
33
|
+
if (!canWrite) {
|
|
34
|
+
await once(stream, "drain");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const delay = async (ms) => await new Promise((resolve) => setTimeout(resolve, ms));
|
|
40
|
+
|
|
41
|
+
const urlQueryEncode = (inputUrl) => {
|
|
42
|
+
try {
|
|
43
|
+
const url = new URL(inputUrl);
|
|
44
|
+
url.search = url.search.replace(/^\?/, "").replace(/,/g, "%2C");
|
|
45
|
+
return url.toString();
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("Invalid URL:", error);
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
var __defProp$b = Object.defineProperty;
|
|
53
|
+
var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
54
|
+
var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
55
|
+
class CSVStream {
|
|
56
|
+
constructor({ delimiter, lineSeparator, emptyFieldValue }) {
|
|
57
|
+
__publicField$b(this, "stream", new PassThrough());
|
|
58
|
+
__publicField$b(this, "delimiter", ";");
|
|
59
|
+
__publicField$b(this, "lineSeparator", "\n");
|
|
60
|
+
__publicField$b(this, "emptyFieldValue", "");
|
|
61
|
+
__publicField$b(this, "columns", /* @__PURE__ */ new Set());
|
|
62
|
+
__publicField$b(this, "writer", writeWithDrain(this.stream));
|
|
63
|
+
if (delimiter !== void 0) this.delimiter = delimiter;
|
|
64
|
+
if (lineSeparator !== void 0) this.lineSeparator = lineSeparator;
|
|
65
|
+
if (emptyFieldValue !== void 0) this.emptyFieldValue = emptyFieldValue;
|
|
66
|
+
}
|
|
67
|
+
get writableStream() {
|
|
68
|
+
return this.stream;
|
|
69
|
+
}
|
|
70
|
+
setColumns(columns) {
|
|
71
|
+
this.columns = columns;
|
|
72
|
+
this.stream.write(
|
|
73
|
+
Array.from(this.columns).join(this.delimiter) + this.lineSeparator
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
async addRow(items) {
|
|
77
|
+
const data = Array.from(this.columns).map(
|
|
78
|
+
(key) => items[key] === void 0 ? this.emptyFieldValue : items[key] + ""
|
|
79
|
+
).join(this.delimiter) + this.lineSeparator;
|
|
80
|
+
await this.writer(data);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class FormatterAbstract {
|
|
85
|
+
}
|
|
86
|
+
var Extension = /* @__PURE__ */ ((Extension2) => {
|
|
87
|
+
Extension2["CSV"] = "csv";
|
|
88
|
+
Extension2["YML"] = "yml";
|
|
89
|
+
Extension2["XML"] = "xml";
|
|
90
|
+
Extension2["XLSX"] = "xlsx";
|
|
91
|
+
Extension2["JSON"] = "json";
|
|
92
|
+
return Extension2;
|
|
93
|
+
})(Extension || {});
|
|
94
|
+
|
|
95
|
+
var __defProp$a = Object.defineProperty;
|
|
96
|
+
var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
97
|
+
var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
98
|
+
class CSVFormatter {
|
|
99
|
+
constructor() {
|
|
100
|
+
__publicField$a(this, "formatterName", "CSV");
|
|
101
|
+
__publicField$a(this, "fileExtension", Extension.CSV);
|
|
102
|
+
}
|
|
103
|
+
async format(writableStream, products, categories, _, __) {
|
|
104
|
+
const mappedCategories = {};
|
|
105
|
+
categories?.forEach(({ id, name }) => mappedCategories[id] = name);
|
|
106
|
+
const csvStream = new CSVStream({
|
|
107
|
+
delimiter: ";",
|
|
108
|
+
emptyFieldValue: "",
|
|
109
|
+
lineSeparator: "\n"
|
|
110
|
+
});
|
|
111
|
+
csvStream.writableStream.pipe(writableStream);
|
|
112
|
+
const columns = /* @__PURE__ */ new Set([
|
|
113
|
+
"url",
|
|
114
|
+
"productId",
|
|
115
|
+
"parentId",
|
|
116
|
+
"variantId",
|
|
117
|
+
"title",
|
|
118
|
+
"description",
|
|
119
|
+
"vendor",
|
|
120
|
+
"vendorCode",
|
|
121
|
+
"category",
|
|
122
|
+
"images",
|
|
123
|
+
"videos",
|
|
124
|
+
"timeDeliveryMin",
|
|
125
|
+
"timeDeliveryMax",
|
|
126
|
+
"price",
|
|
127
|
+
"oldPrice",
|
|
128
|
+
"purchasePrice",
|
|
129
|
+
"currency",
|
|
130
|
+
"saleDate",
|
|
131
|
+
"countryOfOrigin",
|
|
132
|
+
"tags",
|
|
133
|
+
"codesTN",
|
|
134
|
+
"params",
|
|
135
|
+
"properties",
|
|
136
|
+
"sizes",
|
|
137
|
+
"keywords",
|
|
138
|
+
"relatedProducts"
|
|
139
|
+
]);
|
|
140
|
+
products.forEach((product) => {
|
|
141
|
+
Object.entries(product).forEach(([key, value]) => {
|
|
142
|
+
if (value) columns.add(key);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
csvStream.setColumns(columns);
|
|
146
|
+
for (const product of products) {
|
|
147
|
+
const row = {
|
|
148
|
+
...product,
|
|
149
|
+
category: mappedCategories[product.categoryId],
|
|
150
|
+
images: product.images?.join(","),
|
|
151
|
+
videos: product.videos?.join(","),
|
|
152
|
+
tags: product.tags?.join(","),
|
|
153
|
+
codesTN: product.codesTN?.join(", "),
|
|
154
|
+
params: product.params?.map(({ key, value }) => `${key}=${value}`).join(", "),
|
|
155
|
+
properties: product.properties?.map(({ key, value }) => `${key}=${value}`).join(", "),
|
|
156
|
+
sizes: product.sizes?.map(({ name, value }) => `${name}=${value}`).join(", "),
|
|
157
|
+
keywords: product.keywords?.join(","),
|
|
158
|
+
relatedProducts: product.relatedProducts?.join(","),
|
|
159
|
+
timeDeliveryMin: product.timeDelivery?.min,
|
|
160
|
+
timeDeliveryMax: product.timeDelivery?.max
|
|
161
|
+
};
|
|
162
|
+
await csvStream.addRow(row);
|
|
163
|
+
}
|
|
164
|
+
csvStream.writableStream.end();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
var __defProp$9 = Object.defineProperty;
|
|
169
|
+
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
170
|
+
var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
171
|
+
const { stream: stream$2 } = pkg;
|
|
172
|
+
class ExcelFormatter {
|
|
173
|
+
constructor() {
|
|
174
|
+
__publicField$9(this, "formatterName", "Excel");
|
|
175
|
+
__publicField$9(this, "fileExtension", Extension.XLSX);
|
|
176
|
+
}
|
|
177
|
+
async format(writableStream, products, categories, _, __) {
|
|
178
|
+
const mappedCategories = {};
|
|
179
|
+
categories?.forEach(({ id, name }) => mappedCategories[id] = name);
|
|
180
|
+
const columns = /* @__PURE__ */ new Set([
|
|
181
|
+
"url",
|
|
182
|
+
"productId",
|
|
183
|
+
"parentId",
|
|
184
|
+
"variantId",
|
|
185
|
+
"title",
|
|
186
|
+
"description",
|
|
187
|
+
"vendor",
|
|
188
|
+
"vendorCode",
|
|
189
|
+
"category",
|
|
190
|
+
"images",
|
|
191
|
+
"videos",
|
|
192
|
+
"timeDeliveryMin",
|
|
193
|
+
"timeDeliveryMax",
|
|
194
|
+
"price",
|
|
195
|
+
"oldPrice",
|
|
196
|
+
"purchasePrice",
|
|
197
|
+
"currency",
|
|
198
|
+
"saleDate",
|
|
199
|
+
"countryOfOrigin",
|
|
200
|
+
"tags",
|
|
201
|
+
"codesTN",
|
|
202
|
+
"params",
|
|
203
|
+
"properties",
|
|
204
|
+
"sizes",
|
|
205
|
+
"keywords",
|
|
206
|
+
"relatedProducts"
|
|
207
|
+
]);
|
|
208
|
+
products.forEach((product) => {
|
|
209
|
+
Object.entries(product).forEach(([key, value]) => {
|
|
210
|
+
if (value) columns.add(key);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
const workbook = new stream$2.xlsx.WorkbookWriter({
|
|
214
|
+
stream: writableStream
|
|
215
|
+
});
|
|
216
|
+
const worksheet = workbook.addWorksheet("products");
|
|
217
|
+
worksheet.columns = Array.from(columns).map((column) => ({
|
|
218
|
+
key: column,
|
|
219
|
+
header: column
|
|
220
|
+
}));
|
|
221
|
+
products.forEach((product) => {
|
|
222
|
+
const row = {
|
|
223
|
+
...product,
|
|
224
|
+
category: mappedCategories[product.categoryId],
|
|
225
|
+
images: product.images?.join(","),
|
|
226
|
+
videos: product.videos?.join(","),
|
|
227
|
+
tags: product.tags?.join(","),
|
|
228
|
+
keywords: product.keywords?.join(","),
|
|
229
|
+
relatedProducts: product.relatedProducts?.join(","),
|
|
230
|
+
codesTN: product.codesTN?.join(", "),
|
|
231
|
+
params: product.params?.map(({ key, value }) => `${key}=${value}`).join(", "),
|
|
232
|
+
properties: product.properties?.map(({ key, value }) => `${key}=${value}`).join(", "),
|
|
233
|
+
sizes: product.sizes?.map(({ name, value }) => `${name}=${value}`).join(", "),
|
|
234
|
+
timeDeliveryMin: product.timeDelivery?.min,
|
|
235
|
+
timeDeliveryMax: product.timeDelivery?.max
|
|
236
|
+
};
|
|
237
|
+
worksheet.addRow(row).commit();
|
|
238
|
+
});
|
|
239
|
+
worksheet.commit();
|
|
240
|
+
await workbook.commit();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
var __defProp$8 = Object.defineProperty;
|
|
245
|
+
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
246
|
+
var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
247
|
+
const { stream: stream$1 } = pkg;
|
|
248
|
+
class InsalesFormatter {
|
|
249
|
+
constructor() {
|
|
250
|
+
__publicField$8(this, "formatterName", "Insales");
|
|
251
|
+
__publicField$8(this, "fileExtension", Extension.XLSX);
|
|
252
|
+
}
|
|
253
|
+
async format(writableStream, products, categories, _, __) {
|
|
254
|
+
const mappedCategories = {};
|
|
255
|
+
categories?.forEach(
|
|
256
|
+
(category) => mappedCategories[category.id] = category
|
|
257
|
+
);
|
|
258
|
+
const getParams = (product) => {
|
|
259
|
+
const properties = {};
|
|
260
|
+
product.params?.forEach(
|
|
261
|
+
(p) => properties[`\u0421\u0432\u043E\u0439\u0441\u0442\u0432\u043E: ${p.key}`] = p.value
|
|
262
|
+
);
|
|
263
|
+
return properties;
|
|
264
|
+
};
|
|
265
|
+
const getProperties = (product) => {
|
|
266
|
+
const properties = {};
|
|
267
|
+
product.properties?.forEach(
|
|
268
|
+
(p) => properties[`\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: ${p.key}`] = p.value
|
|
269
|
+
);
|
|
270
|
+
return properties;
|
|
271
|
+
};
|
|
272
|
+
const getCategories = (product) => {
|
|
273
|
+
const categories2 = {};
|
|
274
|
+
const categoryList = new Array();
|
|
275
|
+
function addCategory(categoryId) {
|
|
276
|
+
if (categoryId === void 0) return;
|
|
277
|
+
const category = mappedCategories[categoryId];
|
|
278
|
+
if (category) {
|
|
279
|
+
categoryList.push(category.name);
|
|
280
|
+
addCategory(category.parentId);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
addCategory(product.categoryId);
|
|
284
|
+
categoryList.forEach((name, i) => {
|
|
285
|
+
const index = categoryList.length - 1 - i;
|
|
286
|
+
const key = index === 0 ? "\u041A\u043E\u0440\u043D\u0435\u0432\u0430\u044F" : `\u041F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F ${index}`;
|
|
287
|
+
categories2[key] = name;
|
|
288
|
+
});
|
|
289
|
+
return categories2;
|
|
290
|
+
};
|
|
291
|
+
const workbook = new stream$1.xlsx.WorkbookWriter({
|
|
292
|
+
stream: writableStream
|
|
293
|
+
});
|
|
294
|
+
const worksheet = workbook.addWorksheet("products");
|
|
295
|
+
const columns = /* @__PURE__ */ new Set([
|
|
296
|
+
"\u0412\u043D\u0435\u0448\u043D\u0438\u0439 ID",
|
|
297
|
+
"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0442\u043E\u0432\u0430\u0440",
|
|
298
|
+
"\u0410\u0440\u0442\u0438\u043A\u0443\u043B",
|
|
299
|
+
"\u041A\u043E\u0440\u043D\u0435\u0432\u0430\u044F",
|
|
300
|
+
"\u041F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F 1",
|
|
301
|
+
"\u041F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F 2",
|
|
302
|
+
"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438\u043B\u0438 \u0443\u0441\u043B\u0443\u0433\u0438",
|
|
303
|
+
"\u0412\u0440\u0435\u043C\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438: \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435",
|
|
304
|
+
"\u0412\u0440\u0435\u043C\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438: \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435",
|
|
305
|
+
"\u0421\u0442\u0430\u0440\u0430\u044F \u0446\u0435\u043D\u0430",
|
|
306
|
+
"\u0426\u0435\u043D\u0430 \u043F\u0440\u043E\u0434\u0430\u0436\u0438",
|
|
307
|
+
"C\u0435\u0431\u0435\u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C",
|
|
308
|
+
"\u041A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438",
|
|
309
|
+
"\u041E\u0441\u0442\u0430\u0442\u043E\u043A",
|
|
310
|
+
"\u0428\u0442\u0440\u0438\u0445-\u043A\u043E\u0434",
|
|
311
|
+
"\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435",
|
|
312
|
+
"\u041F\u043E\u043B\u043D\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435",
|
|
313
|
+
"\u0413\u0430\u0431\u0430\u0440\u0438\u0442\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430",
|
|
314
|
+
"\u0412\u0435\u0441",
|
|
315
|
+
"\u0420\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0430\u0439\u0442\u0435",
|
|
316
|
+
"\u041D\u0414\u0421",
|
|
317
|
+
"\u0412\u0430\u043B\u044E\u0442\u0430 \u0441\u043A\u043B\u0430\u0434\u0430",
|
|
318
|
+
"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430",
|
|
319
|
+
"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F",
|
|
320
|
+
"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0432\u0438\u0434\u0435\u043E",
|
|
321
|
+
"\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B",
|
|
322
|
+
"\u0421\u0432\u043E\u0439\u0441\u0442\u0432\u0430",
|
|
323
|
+
"\u0420\u0430\u0437\u043C\u0435\u0440\u043D\u0430\u044F \u0441\u0435\u0442\u043A\u0430",
|
|
324
|
+
"\u0421\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u0432\u0430\u0440\u044B",
|
|
325
|
+
"\u041A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430"
|
|
326
|
+
]);
|
|
327
|
+
products.forEach((product) => {
|
|
328
|
+
Object.keys({
|
|
329
|
+
...getParams(product),
|
|
330
|
+
...getProperties(product)
|
|
331
|
+
}).forEach((key) => {
|
|
332
|
+
columns.add(key);
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
worksheet.columns = Array.from(columns).map((column) => ({
|
|
336
|
+
header: column,
|
|
337
|
+
key: column
|
|
338
|
+
}));
|
|
339
|
+
for (const product of products) {
|
|
340
|
+
const externalId = `${product.productId}-${product.variantId}`;
|
|
341
|
+
const row = {
|
|
342
|
+
"\u0412\u043D\u0435\u0448\u043D\u0438\u0439 ID": externalId,
|
|
343
|
+
"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0442\u043E\u0432\u0430\u0440": product.url,
|
|
344
|
+
\u0410\u0440\u0442\u0438\u043A\u0443\u043B: externalId,
|
|
345
|
+
// TODO: product.vendorCode,
|
|
346
|
+
"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438\u043B\u0438 \u0443\u0441\u043B\u0443\u0433\u0438": product.title,
|
|
347
|
+
"\u0412\u0440\u0435\u043C\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438: \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435": product.timeDelivery?.min,
|
|
348
|
+
"\u0412\u0440\u0435\u043C\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438: \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435": product.timeDelivery?.max,
|
|
349
|
+
"\u0421\u0442\u0430\u0440\u0430\u044F \u0446\u0435\u043D\u0430": product.oldPrice,
|
|
350
|
+
"\u0426\u0435\u043D\u0430 \u043F\u0440\u043E\u0434\u0430\u0436\u0438": product.price,
|
|
351
|
+
C\u0435\u0431\u0435\u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C: product.purchasePrice,
|
|
352
|
+
...getCategories(product),
|
|
353
|
+
\u041E\u0441\u0442\u0430\u0442\u043E\u043A: product.count,
|
|
354
|
+
"\u0428\u0442\u0440\u0438\u0445-\u043A\u043E\u0434": product.barcode,
|
|
355
|
+
"\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": void 0,
|
|
356
|
+
"\u041F\u043E\u043B\u043D\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": product.description,
|
|
357
|
+
"\u0413\u0430\u0431\u0430\u0440\u0438\u0442\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430": product.dimensions,
|
|
358
|
+
\u0412\u0435\u0441: product.weight,
|
|
359
|
+
"\u0420\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0430\u0439\u0442\u0435": product.available,
|
|
360
|
+
\u041D\u0414\u0421: product.vat?.toString(),
|
|
361
|
+
"\u0412\u0430\u043B\u044E\u0442\u0430 \u0441\u043A\u043B\u0430\u0434\u0430": product.currency.toString(),
|
|
362
|
+
"\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430": product.parentId === void 0 ? product.images?.join(" ") : void 0,
|
|
363
|
+
\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: product.parentId === void 0 ? void 0 : product.images?.join(" "),
|
|
364
|
+
"\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0432\u0438\u0434\u0435\u043E": product.videos ? product.videos[0] : void 0,
|
|
365
|
+
"\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0410\u0440\u0442\u0438\u043A\u0443\u043B": product.vendorCode,
|
|
366
|
+
// TODO: брать из обычных параметров
|
|
367
|
+
...getParams(product),
|
|
368
|
+
...getProperties(product),
|
|
369
|
+
"\u0420\u0430\u0437\u043C\u0435\u0440\u043D\u0430\u044F \u0441\u0435\u0442\u043A\u0430": JSON.stringify(product.sizes),
|
|
370
|
+
"\u0421\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u0432\u0430\u0440\u044B": product.relatedProducts?.join(","),
|
|
371
|
+
"\u041A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430": product.keywords?.join(",")
|
|
372
|
+
};
|
|
373
|
+
worksheet.addRow(row).commit();
|
|
374
|
+
}
|
|
375
|
+
worksheet.commit();
|
|
376
|
+
await workbook.commit();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
var __defProp$7 = Object.defineProperty;
|
|
381
|
+
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
382
|
+
var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
383
|
+
class JSONFormatter {
|
|
384
|
+
constructor() {
|
|
385
|
+
__publicField$7(this, "formatterName", "JSON");
|
|
386
|
+
__publicField$7(this, "fileExtension", Extension.JSON);
|
|
387
|
+
}
|
|
388
|
+
async format(writableStream, products, categories, brands, _) {
|
|
389
|
+
const stream = new JsonStreamStringify({
|
|
390
|
+
categories,
|
|
391
|
+
brands,
|
|
392
|
+
products
|
|
393
|
+
});
|
|
394
|
+
stream.pipe(writableStream);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
var __defProp$6 = Object.defineProperty;
|
|
399
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
400
|
+
var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
401
|
+
class SimpleJSONFormatter {
|
|
402
|
+
constructor() {
|
|
403
|
+
__publicField$6(this, "formatterName", "JSON");
|
|
404
|
+
__publicField$6(this, "fileExtension", Extension.JSON);
|
|
405
|
+
}
|
|
406
|
+
async format(writableStream, products, categories, brands, _) {
|
|
407
|
+
const groupedProduct = /* @__PURE__ */ new Map();
|
|
408
|
+
products.forEach((product) => {
|
|
409
|
+
if (product.parentId !== void 0) return;
|
|
410
|
+
groupedProduct.set(product.variantId, {
|
|
411
|
+
...product,
|
|
412
|
+
children: []
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
products.forEach((product) => {
|
|
416
|
+
if (product.parentId === void 0) return;
|
|
417
|
+
const parent = groupedProduct.get(product.parentId);
|
|
418
|
+
if (!parent) return;
|
|
419
|
+
parent.children.push(product);
|
|
420
|
+
});
|
|
421
|
+
const stream = new JsonStreamStringify({
|
|
422
|
+
categories,
|
|
423
|
+
brands,
|
|
424
|
+
products: Array.from(groupedProduct.values())
|
|
425
|
+
});
|
|
426
|
+
stream.pipe(writableStream);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
var __defProp$5 = Object.defineProperty;
|
|
431
|
+
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
432
|
+
var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
433
|
+
const { stream } = pkg;
|
|
434
|
+
class TgShopFormatter {
|
|
435
|
+
constructor() {
|
|
436
|
+
__publicField$5(this, "formatterName", "TgShop");
|
|
437
|
+
__publicField$5(this, "fileExtension", Extension.XLSX);
|
|
438
|
+
}
|
|
439
|
+
async format(writableStream, products, categories, _, __) {
|
|
440
|
+
const getParameter = (product, key) => product.params?.find((value) => value.key === key);
|
|
441
|
+
const convertProduct = (product) => ({
|
|
442
|
+
"category id": product.categoryId,
|
|
443
|
+
"group id": product.parentId,
|
|
444
|
+
"id product": product.variantId,
|
|
445
|
+
"name product": product.title,
|
|
446
|
+
price: product.price,
|
|
447
|
+
picture: product.images?.join(", "),
|
|
448
|
+
vendorCode: product.vendorCode,
|
|
449
|
+
oldprice: product.oldPrice,
|
|
450
|
+
description: product.description,
|
|
451
|
+
shortDescription: "",
|
|
452
|
+
quantityInStock: product.count,
|
|
453
|
+
color: getParameter(product, "color")?.value,
|
|
454
|
+
size: getParameter(product, "size")?.value,
|
|
455
|
+
priority: void 0
|
|
456
|
+
});
|
|
457
|
+
const workbook = new stream.xlsx.WorkbookWriter({
|
|
458
|
+
stream: writableStream
|
|
459
|
+
});
|
|
460
|
+
const categoryWorksheet = workbook.addWorksheet("categories");
|
|
461
|
+
const productsWorksheet = workbook.addWorksheet("offers");
|
|
462
|
+
categoryWorksheet.columns = [
|
|
463
|
+
{
|
|
464
|
+
header: "id",
|
|
465
|
+
key: "id"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
header: "parentId",
|
|
469
|
+
key: "parentId"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
header: "name",
|
|
473
|
+
key: "name"
|
|
474
|
+
}
|
|
475
|
+
];
|
|
476
|
+
const columns = [
|
|
477
|
+
"category id",
|
|
478
|
+
"group id",
|
|
479
|
+
"id product",
|
|
480
|
+
"name product",
|
|
481
|
+
"price",
|
|
482
|
+
"picture",
|
|
483
|
+
"vendorCode",
|
|
484
|
+
"oldprice",
|
|
485
|
+
"description",
|
|
486
|
+
"shortDescription",
|
|
487
|
+
"quantityInStock",
|
|
488
|
+
"color",
|
|
489
|
+
"size",
|
|
490
|
+
"priority"
|
|
491
|
+
];
|
|
492
|
+
productsWorksheet.columns = columns.map((column) => ({
|
|
493
|
+
header: column,
|
|
494
|
+
key: column
|
|
495
|
+
}));
|
|
496
|
+
categories?.forEach((category) => {
|
|
497
|
+
categoryWorksheet.addRow(category).commit();
|
|
498
|
+
});
|
|
499
|
+
products.forEach((product) => {
|
|
500
|
+
productsWorksheet.addRow(convertProduct(product)).commit();
|
|
501
|
+
});
|
|
502
|
+
categoryWorksheet.commit();
|
|
503
|
+
productsWorksheet.commit();
|
|
504
|
+
await workbook.commit();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
var __defProp$4 = Object.defineProperty;
|
|
509
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
510
|
+
var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
511
|
+
class TildaFormatter {
|
|
512
|
+
constructor() {
|
|
513
|
+
__publicField$4(this, "formatterName", "Tilda");
|
|
514
|
+
__publicField$4(this, "fileExtension", Extension.CSV);
|
|
515
|
+
}
|
|
516
|
+
async format(writableStream, products, categories, _, __) {
|
|
517
|
+
const mappedCategories = {};
|
|
518
|
+
categories?.forEach(({ id, name }) => mappedCategories[id] = name);
|
|
519
|
+
const csvStream = new CSVStream({
|
|
520
|
+
delimiter: ";",
|
|
521
|
+
emptyFieldValue: "",
|
|
522
|
+
lineSeparator: "\n"
|
|
523
|
+
});
|
|
524
|
+
csvStream.writableStream.pipe(writableStream);
|
|
525
|
+
const columns = /* @__PURE__ */ new Set([
|
|
526
|
+
"SKU",
|
|
527
|
+
"Brand",
|
|
528
|
+
"Category",
|
|
529
|
+
"Title",
|
|
530
|
+
"Text",
|
|
531
|
+
"Photo",
|
|
532
|
+
"Price",
|
|
533
|
+
"Price Old",
|
|
534
|
+
"Quantity",
|
|
535
|
+
"Editions",
|
|
536
|
+
"External ID",
|
|
537
|
+
"Parent UID"
|
|
538
|
+
]);
|
|
539
|
+
csvStream.setColumns(columns);
|
|
540
|
+
for (const product of products) {
|
|
541
|
+
const row = {
|
|
542
|
+
SKU: product.vendorCode,
|
|
543
|
+
Brand: product.vendor,
|
|
544
|
+
Category: mappedCategories[product.categoryId],
|
|
545
|
+
Title: product.title,
|
|
546
|
+
Text: product.description,
|
|
547
|
+
Photo: product.images?.join(";"),
|
|
548
|
+
Price: product.price,
|
|
549
|
+
"Price Old": product.oldPrice,
|
|
550
|
+
Quantity: product.count,
|
|
551
|
+
Editions: product.params?.map(({ key, value }) => `${key}:${value}`).join(";"),
|
|
552
|
+
"External ID": product.variantId,
|
|
553
|
+
"Parent UID": product.parentId
|
|
554
|
+
};
|
|
555
|
+
await csvStream.addRow(row);
|
|
556
|
+
}
|
|
557
|
+
csvStream.writableStream.end();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
var __defProp$3 = Object.defineProperty;
|
|
562
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
563
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
564
|
+
class WooCommerceFormatter {
|
|
565
|
+
constructor() {
|
|
566
|
+
__publicField$3(this, "formatterName", "WooCommerce");
|
|
567
|
+
__publicField$3(this, "fileExtension", Extension.CSV);
|
|
568
|
+
__publicField$3(this, "DEFAULT_COLUMNS", [
|
|
569
|
+
"ID",
|
|
570
|
+
"Type",
|
|
571
|
+
"SKU",
|
|
572
|
+
"Name",
|
|
573
|
+
"Parent",
|
|
574
|
+
"Short description",
|
|
575
|
+
"Description",
|
|
576
|
+
"Stock",
|
|
577
|
+
"Regular price",
|
|
578
|
+
"Position",
|
|
579
|
+
"Categories",
|
|
580
|
+
"Tags",
|
|
581
|
+
"Images",
|
|
582
|
+
"SizeGrid"
|
|
583
|
+
]);
|
|
584
|
+
}
|
|
585
|
+
formatKeyAttribute(key) {
|
|
586
|
+
const keyWithoutInvalidCharacters = key.replaceAll(",", "").replaceAll(";", "");
|
|
587
|
+
return keyWithoutInvalidCharacters.length >= 28 ? keyWithoutInvalidCharacters.slice(0, 24) + "..." : keyWithoutInvalidCharacters;
|
|
588
|
+
}
|
|
589
|
+
formatValueAttribute(value) {
|
|
590
|
+
return value.replaceAll(",", "").replaceAll(";", "");
|
|
591
|
+
}
|
|
592
|
+
formatProducts(products) {
|
|
593
|
+
const formatParams = (params) => {
|
|
594
|
+
return params?.map(({ key, value }) => {
|
|
595
|
+
const formatedKey = this.formatKeyAttribute(key);
|
|
596
|
+
const formatedValue = this.formatValueAttribute(value);
|
|
597
|
+
return { key: formatedKey, value: formatedValue };
|
|
598
|
+
});
|
|
599
|
+
};
|
|
600
|
+
return products.map((product) => {
|
|
601
|
+
const params = formatParams(product.params);
|
|
602
|
+
const properties = formatParams(product.properties);
|
|
603
|
+
return { ...product, params, properties };
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
createAttribute(data) {
|
|
607
|
+
if (!data?.name || data.id === void 0) return;
|
|
608
|
+
const attributeStartName = "Attribute";
|
|
609
|
+
const attribute = {};
|
|
610
|
+
attribute[`${attributeStartName} ${data.id} name`] = data.name;
|
|
611
|
+
if (data.values !== void 0)
|
|
612
|
+
attribute[`${attributeStartName} ${data.id} value(s)`] = data.values;
|
|
613
|
+
if (data.visible !== void 0)
|
|
614
|
+
attribute[`${attributeStartName} ${data.id} visible`] = data.visible;
|
|
615
|
+
if (data.global !== void 0)
|
|
616
|
+
attribute[`${attributeStartName} ${data.id} global`] = data.global;
|
|
617
|
+
return attribute;
|
|
618
|
+
}
|
|
619
|
+
extractAttributes(products) {
|
|
620
|
+
const formatedProducts = this.formatProducts(products);
|
|
621
|
+
const paramsMap = /* @__PURE__ */ new Map();
|
|
622
|
+
const propertiesMap = /* @__PURE__ */ new Map();
|
|
623
|
+
const uniqueAttributes = /* @__PURE__ */ new Map();
|
|
624
|
+
const genderTitle = "\u041F\u043E\u043B";
|
|
625
|
+
formatedProducts.forEach((product) => {
|
|
626
|
+
product.params?.forEach(({ key }) => {
|
|
627
|
+
if (!uniqueAttributes.has(key)) {
|
|
628
|
+
uniqueAttributes.set(key, uniqueAttributes.size);
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
uniqueAttributes.set(genderTitle, uniqueAttributes.size);
|
|
632
|
+
product.properties?.forEach(({ key }) => {
|
|
633
|
+
if (!uniqueAttributes.has(key)) {
|
|
634
|
+
uniqueAttributes.set(key, uniqueAttributes.size);
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
formatedProducts.forEach((product) => {
|
|
639
|
+
const paramAttributes = paramsMap.get(product.variantId) ?? {};
|
|
640
|
+
const propertyAttributes = propertiesMap.get(product.variantId) ?? {};
|
|
641
|
+
product.params?.forEach(({ key, value }) => {
|
|
642
|
+
const index = uniqueAttributes.get(key);
|
|
643
|
+
if (index === void 0) {
|
|
644
|
+
console.error(`\u041D\u0435 \u043D\u0430\u0448\u043B\u043E\u0441\u044C \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043A\u043B\u044E\u0447\u0430 \u0434\u043B\u044F \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 - ${key}`);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
const attribute = this.createAttribute({
|
|
648
|
+
name: key,
|
|
649
|
+
id: index,
|
|
650
|
+
values: value,
|
|
651
|
+
visible: 0,
|
|
652
|
+
global: 0
|
|
653
|
+
});
|
|
654
|
+
if (!attribute) return;
|
|
655
|
+
Object.entries(attribute).forEach(
|
|
656
|
+
([key2, value2]) => paramAttributes[key2] = value2
|
|
657
|
+
);
|
|
658
|
+
});
|
|
659
|
+
const genderIndex = uniqueAttributes.get(genderTitle);
|
|
660
|
+
const genderAttribute = this.createAttribute({
|
|
661
|
+
name: genderTitle,
|
|
662
|
+
id: genderIndex,
|
|
663
|
+
values: product.gender,
|
|
664
|
+
global: 0
|
|
665
|
+
});
|
|
666
|
+
if (genderAttribute) {
|
|
667
|
+
Object.entries(genderAttribute).forEach(
|
|
668
|
+
([key, value]) => propertyAttributes[key] = value
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
product.properties?.forEach(({ key, value }) => {
|
|
672
|
+
const index = uniqueAttributes.get(key);
|
|
673
|
+
if (index === void 0) {
|
|
674
|
+
console.error(`\u041D\u0435 \u043D\u0430\u0448\u043B\u043E\u0441\u044C \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043A\u043B\u044E\u0447\u0430 \u0434\u043B\u044F \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 - ${key}`);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
if (paramAttributes[`Attribute ${index} name`]) {
|
|
678
|
+
console.warn(`\u0414\u0430\u043D\u043D\u043E\u0435 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u043E \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u0445 - ${key}`);
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const attribute = this.createAttribute({
|
|
682
|
+
name: key,
|
|
683
|
+
id: index,
|
|
684
|
+
values: value,
|
|
685
|
+
global: 0
|
|
686
|
+
});
|
|
687
|
+
if (!attribute) return;
|
|
688
|
+
Object.entries(attribute).forEach(
|
|
689
|
+
([key2, value2]) => propertyAttributes[key2] = value2
|
|
690
|
+
);
|
|
691
|
+
});
|
|
692
|
+
paramsMap.set(product.variantId, paramAttributes);
|
|
693
|
+
propertiesMap.set(product.variantId, propertyAttributes);
|
|
694
|
+
});
|
|
695
|
+
return { params: paramsMap, properties: propertiesMap };
|
|
696
|
+
}
|
|
697
|
+
removeVisibleFromAttributes(params) {
|
|
698
|
+
Object.entries(params).forEach(([key]) => {
|
|
699
|
+
if (key.includes("visible")) params[key] = "";
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
async format(writableStream, products, categories, _, __) {
|
|
703
|
+
const categoryPaths = buildCategoryPaths(categories ?? []);
|
|
704
|
+
const csvStream = new CSVStream({
|
|
705
|
+
delimiter: ";",
|
|
706
|
+
emptyFieldValue: "",
|
|
707
|
+
lineSeparator: "\n"
|
|
708
|
+
});
|
|
709
|
+
csvStream.writableStream.pipe(writableStream);
|
|
710
|
+
const columns = new Set(this.DEFAULT_COLUMNS);
|
|
711
|
+
const attributes = this.extractAttributes(products);
|
|
712
|
+
const variationsByParentId = /* @__PURE__ */ new Map();
|
|
713
|
+
const imagesByParentId = /* @__PURE__ */ new Map();
|
|
714
|
+
const sizesByParentId = /* @__PURE__ */ new Map();
|
|
715
|
+
const variations = products.map((product, index) => {
|
|
716
|
+
const pathsArray = categoryPaths.get(product.categoryId)?.map((category) => category.name);
|
|
717
|
+
const price = product.price ? product.price : "";
|
|
718
|
+
let row = {
|
|
719
|
+
ID: product.variantId,
|
|
720
|
+
Type: "variation",
|
|
721
|
+
SKU: product.variantId,
|
|
722
|
+
Name: product.title,
|
|
723
|
+
Parent: product.parentId ?? 0,
|
|
724
|
+
"Short description": "",
|
|
725
|
+
Description: product.description,
|
|
726
|
+
Stock: product.count ?? 0,
|
|
727
|
+
"Regular price": price,
|
|
728
|
+
Position: index + 1,
|
|
729
|
+
Categories: pathsArray?.join(" > "),
|
|
730
|
+
Tags: product.keywords?.join(","),
|
|
731
|
+
Images: "",
|
|
732
|
+
SizeGrid: ""
|
|
733
|
+
};
|
|
734
|
+
const productParams = attributes.params.get(product.variantId) ?? {};
|
|
735
|
+
if (!imagesByParentId.has(row.Parent)) {
|
|
736
|
+
const images = product.images?.map(urlQueryEncode).join(",");
|
|
737
|
+
imagesByParentId.set(row.Parent, images);
|
|
738
|
+
}
|
|
739
|
+
if (!sizesByParentId.has(row.Parent)) {
|
|
740
|
+
sizesByParentId.set(
|
|
741
|
+
row.Parent,
|
|
742
|
+
product.sizes ? JSON.stringify(product.sizes) : ""
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
this.removeVisibleFromAttributes(productParams);
|
|
746
|
+
row = { ...row, ...productParams };
|
|
747
|
+
if (variationsByParentId.has(row.Parent)) {
|
|
748
|
+
variationsByParentId.get(row.Parent)?.push(row);
|
|
749
|
+
} else {
|
|
750
|
+
variationsByParentId.set(row.Parent, [row]);
|
|
751
|
+
}
|
|
752
|
+
return row;
|
|
753
|
+
});
|
|
754
|
+
const parentProducts = /* @__PURE__ */ new Map();
|
|
755
|
+
variations.forEach((product) => {
|
|
756
|
+
const currentParent = parentProducts.get(product.Parent);
|
|
757
|
+
let row = {
|
|
758
|
+
...product,
|
|
759
|
+
Type: "variable",
|
|
760
|
+
ID: product.Parent,
|
|
761
|
+
SKU: product.Parent,
|
|
762
|
+
Position: 0,
|
|
763
|
+
Parent: "",
|
|
764
|
+
"Regular price": "",
|
|
765
|
+
Images: imagesByParentId.get(product.Parent) ?? "",
|
|
766
|
+
SizeGrid: sizesByParentId.get(product.Parent) ?? ""
|
|
767
|
+
};
|
|
768
|
+
row.Stock = (currentParent?.Stock || 0) + (product?.Stock || 0);
|
|
769
|
+
const productParams = attributes.params.get(product.SKU) ?? {};
|
|
770
|
+
const productProperties = attributes.properties.get(product.SKU) ?? {};
|
|
771
|
+
Object.entries(productParams).forEach(([key]) => {
|
|
772
|
+
if (key.includes("visible")) productParams[key] = 0;
|
|
773
|
+
});
|
|
774
|
+
if (currentParent) {
|
|
775
|
+
Object.entries(productParams).forEach(([key, value]) => {
|
|
776
|
+
if (key.includes("value(s)")) {
|
|
777
|
+
productParams[key] = currentParent[key] + `, ${value}`;
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
Object.keys({ ...row, ...productParams, ...productProperties }).forEach(
|
|
782
|
+
(item) => columns.add(item)
|
|
783
|
+
);
|
|
784
|
+
row = { ...row, ...productParams, ...productProperties };
|
|
785
|
+
parentProducts.set(product.Parent, row);
|
|
786
|
+
});
|
|
787
|
+
const variableProducts = Array.from(parentProducts.values());
|
|
788
|
+
csvStream.setColumns(columns);
|
|
789
|
+
for (const parentProduct of variableProducts) {
|
|
790
|
+
await csvStream.addRow(parentProduct);
|
|
791
|
+
for (const variationProduct of variationsByParentId.get(
|
|
792
|
+
parentProduct.ID
|
|
793
|
+
) ?? []) {
|
|
794
|
+
await csvStream.addRow(variationProduct);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
csvStream.writableStream.end();
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
var __defProp$2 = Object.defineProperty;
|
|
802
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
803
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
804
|
+
class YMLFormatter {
|
|
805
|
+
constructor() {
|
|
806
|
+
__publicField$2(this, "formatterName", "YMl");
|
|
807
|
+
__publicField$2(this, "fileExtension", Extension.YML);
|
|
808
|
+
}
|
|
809
|
+
async format(writableStream, products, categories, brands, options) {
|
|
810
|
+
const result = new PassThrough();
|
|
811
|
+
result.pipe(writableStream);
|
|
812
|
+
const builder = new XMLBuilder({
|
|
813
|
+
ignoreAttributes: false,
|
|
814
|
+
cdataPropName: "__cdata",
|
|
815
|
+
format: true,
|
|
816
|
+
indentBy: " "
|
|
817
|
+
});
|
|
818
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().replace(/.\d+Z/, "");
|
|
819
|
+
result.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n');
|
|
820
|
+
result.write('<yml_catalog date="' + date + '">\n');
|
|
821
|
+
result.write("<shop>\n");
|
|
822
|
+
const resultWriter = writeWithDrain(result);
|
|
823
|
+
if (options?.shopName) {
|
|
824
|
+
await resultWriter(builder.build({ name: options.shopName }));
|
|
825
|
+
await resultWriter("\n");
|
|
826
|
+
}
|
|
827
|
+
if (options?.companyName) {
|
|
828
|
+
await resultWriter(builder.build({ company: options.companyName }));
|
|
829
|
+
await resultWriter("\n");
|
|
830
|
+
}
|
|
831
|
+
if (categories) {
|
|
832
|
+
await resultWriter(
|
|
833
|
+
builder.build({
|
|
834
|
+
// tagname: "categories",
|
|
835
|
+
categories: { category: this.getCategories(categories) }
|
|
836
|
+
})
|
|
837
|
+
);
|
|
838
|
+
await resultWriter("\n");
|
|
839
|
+
}
|
|
840
|
+
if (brands) {
|
|
841
|
+
await resultWriter(
|
|
842
|
+
builder.build({ brands: { brand: this.getBrands(brands) } })
|
|
843
|
+
);
|
|
844
|
+
await resultWriter("\n");
|
|
845
|
+
}
|
|
846
|
+
await resultWriter("<offers>\n");
|
|
847
|
+
const offerStream = new PassThrough();
|
|
848
|
+
const offerWriter = writeWithDrain(offerStream);
|
|
849
|
+
offerStream.pipe(result, { end: false });
|
|
850
|
+
for (const product of products) {
|
|
851
|
+
const offer = builder.build({ offer: this.getOffer(product) });
|
|
852
|
+
await offerWriter(offer + "\n");
|
|
853
|
+
}
|
|
854
|
+
offerStream.end();
|
|
855
|
+
offerStream.on("end", () => {
|
|
856
|
+
result.write("</offers>\n");
|
|
857
|
+
result.write("</shop>\n");
|
|
858
|
+
result.write("</yml_catalog>\n");
|
|
859
|
+
result.end();
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
getBrands(brands) {
|
|
863
|
+
if (!brands) return [];
|
|
864
|
+
return brands.map((brand) => ({
|
|
865
|
+
"@_id": brand.id,
|
|
866
|
+
"@_url": brand.coverURL ?? "",
|
|
867
|
+
"#text": brand.name
|
|
868
|
+
}));
|
|
869
|
+
}
|
|
870
|
+
getCategories(categories) {
|
|
871
|
+
if (!categories) return [];
|
|
872
|
+
return categories.map((cat) => ({
|
|
873
|
+
"@_id": cat.id,
|
|
874
|
+
"@_parentId": cat.parentId ?? "",
|
|
875
|
+
"#text": cat.name
|
|
876
|
+
}));
|
|
877
|
+
}
|
|
878
|
+
getOffer(product) {
|
|
879
|
+
const result = {
|
|
880
|
+
"@_id": product.variantId,
|
|
881
|
+
name: product.title,
|
|
882
|
+
price: product.price,
|
|
883
|
+
oldprice: product.oldPrice,
|
|
884
|
+
purchase_price: product.purchasePrice,
|
|
885
|
+
additional_expenses: product.additionalExpenses,
|
|
886
|
+
cofinance_price: product.cofinancePrice,
|
|
887
|
+
currencyId: product.currency,
|
|
888
|
+
categoryId: product.categoryId,
|
|
889
|
+
vendorId: product.vendorId,
|
|
890
|
+
vendor: product.vendor,
|
|
891
|
+
vendorCode: product.vendorCode,
|
|
892
|
+
picture: product.images,
|
|
893
|
+
video: product.videos,
|
|
894
|
+
available: product.available,
|
|
895
|
+
"time-delivery": product.timeDelivery ? {
|
|
896
|
+
"@_min": product.timeDelivery.min,
|
|
897
|
+
"@_max": product.timeDelivery.max,
|
|
898
|
+
"#text": `${product.timeDelivery.min}-${product.timeDelivery.max}`
|
|
899
|
+
} : void 0,
|
|
900
|
+
series: product.seriesName,
|
|
901
|
+
"min-quantity": product.minQuantity,
|
|
902
|
+
"step-quantity": product.stepQuantity,
|
|
903
|
+
size: product.sizes?.map((size) => ({
|
|
904
|
+
"#text": size.value,
|
|
905
|
+
"@_name": size.name,
|
|
906
|
+
"@_delimiter": size.delimiter
|
|
907
|
+
})),
|
|
908
|
+
keyword: product.keywords,
|
|
909
|
+
saleDate: product.saleDate,
|
|
910
|
+
property: product.properties?.map((property) => ({
|
|
911
|
+
"#text": property.value,
|
|
912
|
+
"@_name": property.key
|
|
913
|
+
})),
|
|
914
|
+
param: product.params?.map((param) => ({
|
|
915
|
+
"#text": param.value,
|
|
916
|
+
"@_name": param.key
|
|
917
|
+
})),
|
|
918
|
+
description: {
|
|
919
|
+
__cdata: product.description
|
|
920
|
+
},
|
|
921
|
+
country_of_origin: product.countryOfOrigin,
|
|
922
|
+
barcode: product.barcode,
|
|
923
|
+
vat: product.vat,
|
|
924
|
+
count: product.count,
|
|
925
|
+
"set-ids": product.tags?.join(", "),
|
|
926
|
+
adult: product.adult,
|
|
927
|
+
downloadable: product.downloadable,
|
|
928
|
+
"period-of-validity-days": product.validityPeriod,
|
|
929
|
+
"comment-validity-days": product.validityComment,
|
|
930
|
+
"service-life-days": product.serviceLifePeriod,
|
|
931
|
+
"comment-life-days": product.serviceLifeComment,
|
|
932
|
+
"warranty-days": product.warrantyPeriod,
|
|
933
|
+
"comment-warranty": product.warrantyComment,
|
|
934
|
+
manufacturer_warranty: product.manufacturerWarranty,
|
|
935
|
+
certificate: product.certificate,
|
|
936
|
+
url: product.url,
|
|
937
|
+
weight: product.weight,
|
|
938
|
+
dimensions: product.dimensions,
|
|
939
|
+
boxCount: product.boxCount,
|
|
940
|
+
disabled: product.disabled,
|
|
941
|
+
age: product.age != null && {
|
|
942
|
+
"@_unit": product.age.unit,
|
|
943
|
+
"#text": product.age.value
|
|
944
|
+
},
|
|
945
|
+
"tn-ved-codes": product.codesTN?.length != null && {
|
|
946
|
+
"tn-ved-code": product.codesTN
|
|
947
|
+
},
|
|
948
|
+
relatedProduct: product.relatedProducts,
|
|
949
|
+
gender: product.gender
|
|
950
|
+
};
|
|
951
|
+
if (product.parentId !== void 0) {
|
|
952
|
+
return {
|
|
953
|
+
...result,
|
|
954
|
+
"@_group_id": product.parentId
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
return result;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
var __defProp$1 = Object.defineProperty;
|
|
962
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
963
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
964
|
+
class XMLFormatter extends YMLFormatter {
|
|
965
|
+
constructor() {
|
|
966
|
+
super(...arguments);
|
|
967
|
+
__publicField$1(this, "formatterName", "XML");
|
|
968
|
+
__publicField$1(this, "fileExtension", Extension.XML);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
const Formatters = {
|
|
973
|
+
TildaFormatter,
|
|
974
|
+
CSVFormatter,
|
|
975
|
+
InsalesFormatter,
|
|
976
|
+
YMLFormatter,
|
|
977
|
+
TgShopFormatter,
|
|
978
|
+
ExcelFormatter,
|
|
979
|
+
JSONFormatter,
|
|
980
|
+
SimpleJSONFormatter,
|
|
981
|
+
XMLFormatter,
|
|
982
|
+
WooCommerceFormatter
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
var __defProp = Object.defineProperty;
|
|
986
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
987
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
988
|
+
class GoodsExporter {
|
|
989
|
+
constructor(context) {
|
|
990
|
+
this.context = context;
|
|
991
|
+
__publicField(this, "_context");
|
|
992
|
+
__publicField(this, "formatter", new Formatters.YMLFormatter());
|
|
993
|
+
__publicField(this, "exporter", () => {
|
|
994
|
+
return fs.createWriteStream(
|
|
995
|
+
`${this.formatter.formatterName}.output.${this.formatter.fileExtension}`
|
|
996
|
+
);
|
|
997
|
+
});
|
|
998
|
+
__publicField(this, "transformers", new Array());
|
|
999
|
+
this._context = context;
|
|
1000
|
+
}
|
|
1001
|
+
setContext(context) {
|
|
1002
|
+
this._context = context;
|
|
1003
|
+
}
|
|
1004
|
+
setTransformers(transformers) {
|
|
1005
|
+
this.transformers = transformers;
|
|
1006
|
+
}
|
|
1007
|
+
setFormatter(formatter) {
|
|
1008
|
+
this.formatter = formatter;
|
|
1009
|
+
}
|
|
1010
|
+
setExporter(exporter) {
|
|
1011
|
+
this.exporter = exporter;
|
|
1012
|
+
}
|
|
1013
|
+
async export(products, categories, brands, option) {
|
|
1014
|
+
let transformedProducts = products;
|
|
1015
|
+
for (const transformer of this.transformers)
|
|
1016
|
+
transformedProducts = await transformer(
|
|
1017
|
+
transformedProducts,
|
|
1018
|
+
this._context
|
|
1019
|
+
);
|
|
1020
|
+
const writableStream = this.exporter();
|
|
1021
|
+
await this.formatter.format(
|
|
1022
|
+
writableStream,
|
|
1023
|
+
transformedProducts,
|
|
1024
|
+
categories,
|
|
1025
|
+
brands,
|
|
1026
|
+
option
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
var Vat = /* @__PURE__ */ ((Vat2) => {
|
|
1032
|
+
Vat2["NO_VAT"] = "NO_VAT";
|
|
1033
|
+
Vat2["VAT_0"] = "VAT_0";
|
|
1034
|
+
Vat2["VAT_10"] = "VAT_10";
|
|
1035
|
+
Vat2["VAT_20"] = "VAT_20";
|
|
1036
|
+
return Vat2;
|
|
1037
|
+
})(Vat || {});
|
|
1038
|
+
var Currency = /* @__PURE__ */ ((Currency2) => {
|
|
1039
|
+
Currency2["RUR"] = "RUR";
|
|
1040
|
+
Currency2["BYN"] = "BYN";
|
|
1041
|
+
Currency2["EUR"] = "EUR";
|
|
1042
|
+
Currency2["USD"] = "USD";
|
|
1043
|
+
Currency2["UAN"] = "UAN";
|
|
1044
|
+
Currency2["KZT"] = "KZT";
|
|
1045
|
+
return Currency2;
|
|
1046
|
+
})(Currency || {});
|
|
1047
|
+
|
|
1048
|
+
export { Currency, Extension, FormatterAbstract, Formatters, GoodsExporter, Vat, buildCategoryPaths, delay, urlQueryEncode, writeWithDrain };
|
|
1049
|
+
//# sourceMappingURL=index.mjs.map
|