goods-exporter 0.4.6 → 0.5.1

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.
@@ -1,40 +1,47 @@
1
- import { json2csv } from 'json-2-csv';
2
- import xlsx from 'xlsx';
1
+ import { PassThrough } from 'stream';
2
+ import { stream } from 'exceljs';
3
+ import { JsonStreamStringify } from 'json-stream-stringify';
3
4
  import { XMLBuilder } from 'fast-xml-parser';
4
- import * as fs from 'fs';
5
+ import xml from 'xml';
6
+ import fs from 'fs';
5
7
 
6
- const getParams = (product, option) => {
7
- const params = {};
8
- if (option?.splitParams === false) {
9
- return params;
10
- }
11
- product.params?.forEach(
12
- ({ key, value }) => params[`Param [${key}]`] = value
13
- );
14
- return params;
8
+ var __defProp$8 = Object.defineProperty;
9
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField$8 = (obj, key, value) => {
11
+ __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
12
+ return value;
15
13
  };
16
- const getProperties = (product, option) => {
17
- const properties = {};
18
- if (option?.splitParams === false) {
19
- return properties;
14
+ class CSVStream {
15
+ constructor({ delimiter, lineSeparator, emptyFieldValue }) {
16
+ __publicField$8(this, "stream", new PassThrough());
17
+ __publicField$8(this, "delimiter", ";");
18
+ __publicField$8(this, "lineSeparator", "\n");
19
+ __publicField$8(this, "emptyFieldValue", "");
20
+ __publicField$8(this, "columns", /* @__PURE__ */ new Set());
21
+ if (delimiter !== void 0)
22
+ this.delimiter = delimiter;
23
+ if (lineSeparator !== void 0)
24
+ this.lineSeparator = lineSeparator;
25
+ if (emptyFieldValue !== void 0)
26
+ this.emptyFieldValue = emptyFieldValue;
20
27
  }
21
- product.properties?.forEach(
22
- ({ key, value }) => properties[`Property [${key}]`] = value
23
- );
24
- return properties;
25
- };
26
- const getSizes = (product, _) => {
27
- const sizes = {};
28
- product.sizes?.forEach(
29
- ({ name, value }) => sizes[`Size [${name}]`] = value
30
- );
31
- return sizes;
32
- };
33
- const UTILS = {
34
- getSizes,
35
- getParams,
36
- getProperties
37
- };
28
+ getWritableStream() {
29
+ return this.stream;
30
+ }
31
+ setColumns(columns) {
32
+ this.columns = columns;
33
+ this.stream.write(
34
+ Array.from(this.columns).join(this.delimiter) + this.lineSeparator
35
+ );
36
+ }
37
+ addRow(items) {
38
+ this.stream.write(
39
+ Array.from(this.columns).map(
40
+ (key) => items[key] === void 0 ? this.emptyFieldValue : items[key] + ""
41
+ ).join(this.delimiter) + this.lineSeparator
42
+ );
43
+ }
44
+ }
38
45
 
39
46
  class FormatterAbstract {
40
47
  }
@@ -57,25 +64,64 @@ class CSVFormatter {
57
64
  __publicField$7(this, "formatterName", "CSV");
58
65
  __publicField$7(this, "fileExtension", Extension.CSV);
59
66
  }
60
- async format(products, categories, _, options) {
67
+ async format(products, categories, _, __) {
61
68
  const mappedCategories = {};
62
69
  categories?.forEach(({ id, name }) => mappedCategories[id] = name);
63
- const data = products.map((product) => ({
64
- ...product,
65
- category: mappedCategories[product.categoryId],
66
- images: product.images?.join(","),
67
- videos: product.videos?.join(","),
68
- tags: product.tags?.join(","),
69
- codesTN: product.codesTN?.join(", "),
70
- params: product.params?.map(({ key, value }) => `${key}=${value}`).join(","),
71
- ...UTILS.getParams(product, options),
72
- ...UTILS.getProperties(product, options),
73
- ...UTILS.getSizes(product, options),
74
- sizes: void 0,
75
- keywords: product.keywords?.join(","),
76
- relatedProducts: product.relatedProducts?.join(",")
77
- }));
78
- return json2csv(data, { emptyFieldValue: "" });
70
+ const csvStream = new CSVStream({
71
+ delimiter: ";",
72
+ emptyFieldValue: "",
73
+ lineSeparator: "\n"
74
+ });
75
+ const columns = /* @__PURE__ */ new Set([
76
+ "url",
77
+ "productId",
78
+ "parentId",
79
+ "variantId",
80
+ "title",
81
+ "description",
82
+ "vendor",
83
+ "vendorCode",
84
+ "category",
85
+ "images",
86
+ "videos",
87
+ "price",
88
+ "oldPrice",
89
+ "purchasePrice",
90
+ "currency",
91
+ "saleDate",
92
+ "countryOfOrigin",
93
+ "tags",
94
+ "codesTN",
95
+ "params",
96
+ "properties",
97
+ "sizes",
98
+ "keywords",
99
+ "relatedProducts"
100
+ ]);
101
+ products.forEach((product) => {
102
+ Object.entries(product).forEach(([key, value]) => {
103
+ if (value)
104
+ columns.add(key);
105
+ });
106
+ });
107
+ csvStream.setColumns(columns);
108
+ products.forEach((product) => {
109
+ const row = {
110
+ ...product,
111
+ category: mappedCategories[product.categoryId],
112
+ images: product.images?.join(","),
113
+ videos: product.videos?.join(","),
114
+ tags: product.tags?.join(","),
115
+ codesTN: product.codesTN?.join(", "),
116
+ params: product.params?.map(({ key, value }) => `${key}=${value}`).join(", "),
117
+ properties: product.properties?.map(({ key, value }) => `${key}=${value}`).join(", "),
118
+ sizes: product.sizes?.map(({ name, value }) => `${name}=${value}`).join(", "),
119
+ keywords: product.keywords?.join(","),
120
+ relatedProducts: product.relatedProducts?.join(",")
121
+ };
122
+ csvStream.addRow(row);
123
+ });
124
+ return csvStream.getWritableStream();
79
125
  }
80
126
  }
81
127
 
@@ -85,34 +131,71 @@ var __publicField$6 = (obj, key, value) => {
85
131
  __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
86
132
  return value;
87
133
  };
88
- const { writeXLSX, utils } = xlsx;
89
134
  class ExcelFormatter {
90
135
  constructor() {
91
136
  __publicField$6(this, "formatterName", "Excel");
92
137
  __publicField$6(this, "fileExtension", Extension.XLSX);
93
138
  }
94
- async format(products, categories, _, options) {
139
+ async format(products, categories, _, __) {
95
140
  const mappedCategories = {};
96
141
  categories?.forEach(({ id, name }) => mappedCategories[id] = name);
97
- const data = products.map((product) => ({
98
- ...product,
99
- category: mappedCategories[product.categoryId],
100
- images: product.images?.join(","),
101
- videos: product.videos?.join(","),
102
- tags: product.tags?.join(","),
103
- keywords: product.keywords?.join(","),
104
- relatedProducts: product.relatedProducts?.join(","),
105
- codesTN: product.codesTN?.join(", "),
106
- params: product.params?.map(({ key, value }) => `${key}=${value}`).join(","),
107
- sizes: void 0,
108
- ...UTILS.getParams(product, options),
109
- ...UTILS.getProperties(product, options),
110
- ...UTILS.getSizes(product, options)
142
+ const columns = /* @__PURE__ */ new Set([
143
+ "url",
144
+ "productId",
145
+ "parentId",
146
+ "variantId",
147
+ "title",
148
+ "description",
149
+ "vendor",
150
+ "vendorCode",
151
+ "category",
152
+ "images",
153
+ "videos",
154
+ "price",
155
+ "oldPrice",
156
+ "purchasePrice",
157
+ "currency",
158
+ "saleDate",
159
+ "countryOfOrigin",
160
+ "tags",
161
+ "codesTN",
162
+ "params",
163
+ "properties",
164
+ "sizes",
165
+ "keywords",
166
+ "relatedProducts"
167
+ ]);
168
+ products.forEach((product) => {
169
+ Object.entries(product).forEach(([key, value]) => {
170
+ if (value)
171
+ columns.add(key);
172
+ });
173
+ });
174
+ const workbook = new stream.xlsx.WorkbookWriter({});
175
+ const worksheet = workbook.addWorksheet("products");
176
+ worksheet.columns = Array.from(columns).map((column) => ({
177
+ key: column,
178
+ header: column
111
179
  }));
112
- const workBook = utils.book_new();
113
- const productsWorkSheet = utils.json_to_sheet(data);
114
- utils.book_append_sheet(workBook, productsWorkSheet, "products");
115
- return writeXLSX(workBook, { type: "buffer" });
180
+ products.forEach((product) => {
181
+ const row = {
182
+ ...product,
183
+ category: mappedCategories[product.categoryId],
184
+ images: product.images?.join(","),
185
+ videos: product.videos?.join(","),
186
+ tags: product.tags?.join(","),
187
+ keywords: product.keywords?.join(","),
188
+ relatedProducts: product.relatedProducts?.join(","),
189
+ codesTN: product.codesTN?.join(", "),
190
+ params: product.params?.map(({ key, value }) => `${key}=${value}`).join(", "),
191
+ properties: product.properties?.map(({ key, value }) => `${key}=${value}`).join(", "),
192
+ sizes: product.sizes?.map(({ name, value }) => `${name}=${value}`).join(", ")
193
+ };
194
+ worksheet.addRow(row).commit();
195
+ });
196
+ worksheet.commit();
197
+ await workbook.commit();
198
+ return workbook.stream;
116
199
  }
117
200
  }
118
201
 
@@ -166,41 +249,91 @@ class InsalesFormatter {
166
249
  });
167
250
  return categories2;
168
251
  };
169
- const data = products.map((product) => ({
170
- "\u0412\u043D\u0435\u0448\u043D\u0438\u0439 ID": product.productId,
171
- "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0442\u043E\u0432\u0430\u0440": product.url,
172
- \u0410\u0440\u0442\u0438\u043A\u0443\u043B: product.vendorCode,
173
- "\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,
174
- "\u0421\u0442\u0430\u0440\u0430\u044F \u0446\u0435\u043D\u0430": product.oldPrice,
175
- "\u0426\u0435\u043D\u0430 \u043F\u0440\u043E\u0434\u0430\u0436\u0438": product.price,
176
- "\u0426\u0435\u043D\u0430 \u0437\u0430\u043A\u0443\u043F\u043A\u0438": product.purchasePrice,
177
- ...getCategories(product),
178
- \u041E\u0441\u0442\u0430\u0442\u043E\u043A: product.count,
179
- "\u0428\u0442\u0440\u0438\u0445-\u043A\u043E\u0434": product.barcode,
180
- "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": void 0,
181
- "\u041F\u043E\u043B\u043D\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": product.description,
182
- "\u0413\u0430\u0431\u0430\u0440\u0438\u0442\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430": product.dimensions,
183
- \u0412\u0435\u0441: product.weight,
184
- "\u0420\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0430\u0439\u0442\u0435": product.available,
185
- \u041D\u0414\u0421: product.vat.toString(),
186
- "\u0412\u0430\u043B\u044E\u0442\u0430 \u0441\u043A\u043B\u0430\u0434\u0430": product.currency.toString(),
187
- "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430": product.images?.join(" "),
188
- \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: product.images?.join(" "),
189
- "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0432\u0438\u0434\u0435\u043E": product.videos ? product.videos[0] : void 0,
190
- ...getParams(product),
191
- ...getProperties(product),
192
- "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0411\u0440\u0435\u043D\u0434": product.vendor,
193
- "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u044F": product.seriesName,
194
- "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041F\u043E\u043B": product.gender,
195
- "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0414\u0430\u0442\u0430 \u0432\u044B\u0445\u043E\u0434\u0430": product.saleDate,
196
- "\u0420\u0430\u0437\u043C\u0435\u0440\u043D\u0430\u044F \u0441\u0435\u0442\u043A\u0430": product.sizes,
197
- "\u0421\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u0432\u0430\u0440\u044B": product.relatedProducts?.join(","),
198
- "\u041A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430": product.keywords?.join(",")
252
+ const workbook = new stream.xlsx.WorkbookWriter({});
253
+ const worksheet = workbook.addWorksheet("products");
254
+ const columns = /* @__PURE__ */ new Set([
255
+ "\u0412\u043D\u0435\u0448\u043D\u0438\u0439 ID",
256
+ "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0442\u043E\u0432\u0430\u0440",
257
+ "\u0410\u0440\u0442\u0438\u043A\u0443\u043B",
258
+ "\u041A\u043E\u0440\u043D\u0435\u0432\u0430\u044F",
259
+ "\u041F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F 1",
260
+ "\u041F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F 2",
261
+ "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438\u043B\u0438 \u0443\u0441\u043B\u0443\u0433\u0438",
262
+ "\u0421\u0442\u0430\u0440\u0430\u044F \u0446\u0435\u043D\u0430",
263
+ "\u0426\u0435\u043D\u0430 \u043F\u0440\u043E\u0434\u0430\u0436\u0438",
264
+ "C\u0435\u0431\u0435\u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C",
265
+ "\u041A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438",
266
+ "\u041E\u0441\u0442\u0430\u0442\u043E\u043A",
267
+ "\u0428\u0442\u0440\u0438\u0445-\u043A\u043E\u0434",
268
+ "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435",
269
+ "\u041F\u043E\u043B\u043D\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435",
270
+ "\u0413\u0430\u0431\u0430\u0440\u0438\u0442\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430",
271
+ "\u0412\u0435\u0441",
272
+ "\u0420\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0430\u0439\u0442\u0435",
273
+ "\u041D\u0414\u0421",
274
+ "\u0412\u0430\u043B\u044E\u0442\u0430 \u0441\u043A\u043B\u0430\u0434\u0430",
275
+ "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430",
276
+ "\u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F",
277
+ "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0432\u0438\u0434\u0435\u043E",
278
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B",
279
+ "\u0421\u0432\u043E\u0439\u0441\u0442\u0432\u0430",
280
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0411\u0440\u0435\u043D\u0434",
281
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u044F",
282
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041F\u043E\u043B",
283
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0414\u0430\u0442\u0430 \u0432\u044B\u0445\u043E\u0434\u0430",
284
+ "\u0420\u0430\u0437\u043C\u0435\u0440\u043D\u0430\u044F \u0441\u0435\u0442\u043A\u0430",
285
+ "\u0421\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u0432\u0430\u0440\u044B",
286
+ "\u041A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430"
287
+ ]);
288
+ products.forEach((product) => {
289
+ Object.keys({
290
+ ...getParams(product),
291
+ ...getProperties(product)
292
+ }).forEach((key) => {
293
+ columns.add(key);
294
+ });
295
+ });
296
+ worksheet.columns = Array.from(columns).map((column) => ({
297
+ header: column,
298
+ key: column
199
299
  }));
200
- const workBook = xlsx.utils.book_new();
201
- const productsWorkSheet = xlsx.utils.json_to_sheet(data);
202
- xlsx.utils.book_append_sheet(workBook, productsWorkSheet, "products");
203
- return xlsx.write(workBook, { bookType: "xlsx", type: "buffer" });
300
+ products.forEach((product) => {
301
+ const row = {
302
+ "\u0412\u043D\u0435\u0448\u043D\u0438\u0439 ID": product.productId,
303
+ "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0442\u043E\u0432\u0430\u0440": product.url,
304
+ \u0410\u0440\u0442\u0438\u043A\u0443\u043B: product.vendorCode,
305
+ "\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,
306
+ "\u0421\u0442\u0430\u0440\u0430\u044F \u0446\u0435\u043D\u0430": product.oldPrice,
307
+ "\u0426\u0435\u043D\u0430 \u043F\u0440\u043E\u0434\u0430\u0436\u0438": product.price,
308
+ C\u0435\u0431\u0435\u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C: product.purchasePrice,
309
+ ...getCategories(product),
310
+ \u041E\u0441\u0442\u0430\u0442\u043E\u043A: product.count,
311
+ "\u0428\u0442\u0440\u0438\u0445-\u043A\u043E\u0434": product.barcode,
312
+ "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": void 0,
313
+ "\u041F\u043E\u043B\u043D\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435": product.description,
314
+ "\u0413\u0430\u0431\u0430\u0440\u0438\u0442\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430": product.dimensions,
315
+ \u0412\u0435\u0441: product.weight,
316
+ "\u0420\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u0441\u0430\u0439\u0442\u0435": product.available,
317
+ \u041D\u0414\u0421: product.vat.toString(),
318
+ "\u0412\u0430\u043B\u044E\u0442\u0430 \u0441\u043A\u043B\u0430\u0434\u0430": product.currency.toString(),
319
+ "\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,
320
+ \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F: product.parentId === void 0 ? void 0 : product.images?.join(" "),
321
+ "\u0421\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u0432\u0438\u0434\u0435\u043E": product.videos ? product.videos[0] : void 0,
322
+ ...getParams(product),
323
+ ...getProperties(product),
324
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0411\u0440\u0435\u043D\u0434": product.vendor,
325
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u044F": product.seriesName,
326
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u041F\u043E\u043B": product.gender,
327
+ "\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440: \u0414\u0430\u0442\u0430 \u0432\u044B\u0445\u043E\u0434\u0430": product.saleDate,
328
+ "\u0420\u0430\u0437\u043C\u0435\u0440\u043D\u0430\u044F \u0441\u0435\u0442\u043A\u0430": JSON.stringify(product.sizes),
329
+ "\u0421\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u0442\u043E\u0432\u0430\u0440\u044B": product.relatedProducts?.join(","),
330
+ "\u041A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430": product.keywords?.join(",")
331
+ };
332
+ worksheet.addRow(row).commit();
333
+ });
334
+ worksheet.commit();
335
+ await workbook.commit();
336
+ return workbook.stream;
204
337
  }
205
338
  }
206
339
 
@@ -216,12 +349,11 @@ class JSONFormatter {
216
349
  __publicField$4(this, "fileExtension", Extension.JSON);
217
350
  }
218
351
  async format(products, categories, brands, _) {
219
- const result = {
352
+ return new JsonStreamStringify({
220
353
  categories,
221
354
  brands,
222
355
  products
223
- };
224
- return JSON.stringify(result);
356
+ });
225
357
  }
226
358
  }
227
359
 
@@ -238,7 +370,7 @@ class TgShopFormatter {
238
370
  }
239
371
  async format(products, categories, _, __) {
240
372
  const getParameter = (product, key) => product.params?.find((value) => value.key === key);
241
- const productsData = products.map((product) => ({
373
+ const convertProduct = (product) => ({
242
374
  "category id": product.categoryId,
243
375
  "group id": product.parentId,
244
376
  "id product": product.variantId,
@@ -248,18 +380,59 @@ class TgShopFormatter {
248
380
  vendorCode: product.vendorCode,
249
381
  oldprice: product.oldPrice,
250
382
  description: product.description,
251
- shortDescription: product.description,
383
+ shortDescription: "",
252
384
  quantityInStock: product.count,
253
385
  color: getParameter(product, "color")?.value,
254
386
  size: getParameter(product, "size")?.value,
255
387
  priority: void 0
388
+ });
389
+ const workbook = new stream.xlsx.WorkbookWriter({});
390
+ const categoryWorksheet = workbook.addWorksheet("categories");
391
+ const productsWorksheet = workbook.addWorksheet("offers");
392
+ categoryWorksheet.columns = [
393
+ {
394
+ header: "id",
395
+ key: "id"
396
+ },
397
+ {
398
+ header: "parentId",
399
+ key: "parentId"
400
+ },
401
+ {
402
+ header: "name",
403
+ key: "name"
404
+ }
405
+ ];
406
+ const columns = [
407
+ "category id",
408
+ "group id",
409
+ "id product",
410
+ "name product",
411
+ "price",
412
+ "picture",
413
+ "vendorCode",
414
+ "oldprice",
415
+ "description",
416
+ "shortDescription",
417
+ "quantityInStock",
418
+ "color",
419
+ "size",
420
+ "priority"
421
+ ];
422
+ productsWorksheet.columns = columns.map((column) => ({
423
+ header: column,
424
+ key: column
256
425
  }));
257
- const workBook = xlsx.utils.book_new();
258
- const productsWorkSheet = xlsx.utils.json_to_sheet(productsData);
259
- const categoriesWorkSheet = xlsx.utils.json_to_sheet(categories ?? []);
260
- xlsx.utils.book_append_sheet(workBook, categoriesWorkSheet, "categories");
261
- xlsx.utils.book_append_sheet(workBook, productsWorkSheet, "offers");
262
- return xlsx.write(workBook, { bookType: "xlsx", type: "buffer" });
426
+ categories?.forEach((category) => {
427
+ categoryWorksheet.addRow(category).commit();
428
+ });
429
+ products.forEach((product) => {
430
+ productsWorksheet.addRow(convertProduct(product)).commit();
431
+ });
432
+ categoryWorksheet.commit();
433
+ productsWorksheet.commit();
434
+ await workbook.commit();
435
+ return workbook.stream;
263
436
  }
264
437
  }
265
438
 
@@ -277,21 +450,44 @@ class TildaFormatter {
277
450
  async format(products, categories, _, __) {
278
451
  const mappedCategories = {};
279
452
  categories?.forEach(({ id, name }) => mappedCategories[id] = name);
280
- const data = products.map((product) => ({
281
- SKU: product.vendorCode,
282
- Brand: product.vendor,
283
- Category: mappedCategories[product.categoryId],
284
- Title: product.title,
285
- Text: product.description,
286
- Photo: product.images?.join(";"),
287
- Price: product.price,
288
- "Price Old": product.oldPrice,
289
- Quantity: product.count,
290
- Editions: product.params?.map(({ key, value }) => `${key}:${value}`).join(";"),
291
- "External ID": product.variantId,
292
- "Parent UID": product.parentId
293
- }));
294
- return json2csv(data, { emptyFieldValue: "", delimiter: { field: ";" } });
453
+ const csvStream = new CSVStream({
454
+ delimiter: ";",
455
+ emptyFieldValue: "",
456
+ lineSeparator: "\n"
457
+ });
458
+ const columns = /* @__PURE__ */ new Set([
459
+ "SKU",
460
+ "Brand",
461
+ "Category",
462
+ "Title",
463
+ "Text",
464
+ "Photo",
465
+ "Price",
466
+ "Price Old",
467
+ "Quantity",
468
+ "Editions",
469
+ "External ID",
470
+ "Parent UID"
471
+ ]);
472
+ csvStream.setColumns(columns);
473
+ products.forEach((product) => {
474
+ const row = {
475
+ SKU: product.vendorCode,
476
+ Brand: product.vendor,
477
+ Category: mappedCategories[product.categoryId],
478
+ Title: product.title,
479
+ Text: product.description,
480
+ Photo: product.images?.join(";"),
481
+ Price: product.price,
482
+ "Price Old": product.oldPrice,
483
+ Quantity: product.count,
484
+ Editions: product.params?.map(({ key, value }) => `${key}:${value}`).join(";"),
485
+ "External ID": product.variantId,
486
+ "Parent UID": product.parentId
487
+ };
488
+ csvStream.addRow(row);
489
+ });
490
+ return csvStream.getWritableStream();
295
491
  }
296
492
  }
297
493
 
@@ -305,51 +501,57 @@ class YMLFormatter {
305
501
  constructor() {
306
502
  __publicField$1(this, "formatterName", "YMl");
307
503
  __publicField$1(this, "fileExtension", Extension.YML);
308
- __publicField$1(this, "builder", new XMLBuilder({
309
- ignoreAttributes: false,
310
- processEntities: false,
311
- format: true,
312
- cdataPropName: "__cdata"
313
- }));
314
504
  }
315
505
  async format(products, categories, brands, options) {
316
- const offers = { offer: products.map(this.getOffers) };
317
- const result = {
318
- "?xml": {
319
- "@_version": "1.0",
320
- "@_encoding": "UTF-8",
321
- "@_standalone": "yes"
322
- },
323
- yml_catalog: {
324
- "@_date": (/* @__PURE__ */ new Date()).toISOString().replace(/.\d+Z/, ""),
325
- shop: {
326
- name: options?.shopName,
327
- company: options?.companyName,
328
- categories: this.getCategories(categories),
329
- brands: this.getBrands(brands),
330
- offers
331
- }
506
+ const result = new PassThrough();
507
+ const builder = new XMLBuilder({
508
+ ignoreAttributes: false,
509
+ cdataPropName: "__cdata"
510
+ });
511
+ const ymlCatalog = xml.element({
512
+ _attr: { date: (/* @__PURE__ */ new Date()).toISOString().replace(/.\d+Z/, "") }
513
+ });
514
+ const stream = xml(
515
+ { yml_catalog: ymlCatalog },
516
+ {
517
+ stream: true,
518
+ declaration: { standalone: "yes", encoding: "UTF-8" }
332
519
  }
333
- };
334
- return this.builder.build(result);
520
+ );
521
+ const shop = xml.element();
522
+ const streamShop = xml({ shop }, { stream: true });
523
+ shop.push({ name: options?.shopName });
524
+ shop.push({ company: options?.companyName });
525
+ shop.push({ categories: this.getCategories(categories) });
526
+ shop.push({ brands: this.getBrands(brands) });
527
+ streamShop.pipe(result, { end: false });
528
+ const offers = xml.element();
529
+ const streamOffers = xml({ offers }, { stream: true });
530
+ streamOffers.pipe(result, { end: false });
531
+ products.forEach((product) => {
532
+ result.write(builder.build({ offer: this.getOffers(product) }));
533
+ });
534
+ stream.pipe(result, { end: false });
535
+ offers.close();
536
+ shop.close();
537
+ ymlCatalog.close();
538
+ return result;
335
539
  }
336
540
  getBrands(brands) {
337
- return {
338
- brand: brands?.map((brand) => ({
339
- "@_id": brand.id,
340
- "@_url": brand.coverURL,
341
- "#text": brand.name
342
- }))
343
- };
541
+ return brands?.map((brand) => ({
542
+ brand: [
543
+ { _attr: { id: brand.id, url: brand.coverURL ?? "" } },
544
+ brand.name
545
+ ]
546
+ }));
344
547
  }
345
548
  getCategories(categories) {
346
- return {
347
- category: categories?.map((cat) => ({
348
- "@_id": cat.id,
349
- "@_parentId": cat.parentId,
350
- "#text": cat.name
351
- }))
352
- };
549
+ return categories?.map((cat) => ({
550
+ category: [
551
+ { _attr: { id: cat.id, parentId: cat.parentId ?? "" } },
552
+ cat.name
553
+ ]
554
+ }));
353
555
  }
354
556
  getOffers(product) {
355
557
  const result = {
@@ -447,10 +649,10 @@ var __publicField = (obj, key, value) => {
447
649
  class GoodsExporter {
448
650
  constructor() {
449
651
  __publicField(this, "formatter", new Formatters.YMLFormatter());
450
- __publicField(this, "exporter", (data) => {
451
- const filename = `${this.formatter.formatterName}.output.${this.formatter.fileExtension}`;
452
- fs.writeFileSync(filename, data);
453
- return data;
652
+ __publicField(this, "exporter", () => {
653
+ return fs.createWriteStream(
654
+ `${this.formatter.formatterName}.output.${this.formatter.fileExtension}`
655
+ );
454
656
  });
455
657
  __publicField(this, "transformers", new Array());
456
658
  }
@@ -467,16 +669,13 @@ class GoodsExporter {
467
669
  let transformedProducts = products;
468
670
  for (const transformer of this.transformers)
469
671
  transformedProducts = await transformer(transformedProducts);
470
- const data = await this.formatter.format(
672
+ const stream = await this.formatter.format(
471
673
  transformedProducts,
472
674
  categories,
473
675
  brands,
474
676
  option
475
677
  );
476
- if (typeof data === "string") {
477
- return await this.exporter(Buffer.from(data, "utf-8"));
478
- }
479
- return await this.exporter(data);
678
+ stream.pipe(this.exporter());
480
679
  }
481
680
  }
482
681