closer-cli 2.48.0 → 2.48.2

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/helpers.js CHANGED
@@ -1,57 +1,32 @@
1
+ /* eslint-disable max-len */
1
2
  /* eslint-disable no-console */
2
3
  /* eslint-disable no-param-reassign */
3
4
  /* eslint-disable implicit-arrow-linebreak */
4
- import {
5
- readdirSync,
6
- existsSync,
7
- mkdirSync,
8
- copyFileSync,
9
- createWriteStream,
10
- createReadStream,
11
- rename,
12
- statSync
13
- } from 'fs'
5
+ import { readdirSync, existsSync, mkdirSync, createWriteStream } from 'fs'
14
6
  import path from 'path'
15
- import WebSocket from 'ws'
16
- import chalk from 'chalk'
17
- import { parse } from 'csv-parse/sync'
18
- import { stringify } from 'csv-stringify/sync'
19
7
  import got from 'got'
20
8
  import slugify from 'slugify'
21
- import { deleteAsync } from 'del'
22
- import eventStream from 'event-stream'
23
9
 
24
- const { split, mapSync } = eventStream
25
10
  const { stream } = got
26
11
 
27
- export function createSocketConnection(endpoint, secret) {
28
- const protocol = endpoint.includes('localhost') || endpoint.includes('127.0.0.1') ? 'ws' : 'wss'
29
- const url = `${protocol}://${endpoint}/import`
30
- const socket = new WebSocket(url, {
31
- headers: { 'x-closer-secret': secret }
32
- })
33
-
34
- return socket
35
- }
36
-
37
- export const ALLOWED_CSV_FILES = {
38
- product: 'products.csv',
39
- localizedProduct: 'localizedProducts.csv',
40
- localizedFilter: 'localizedFilters.csv',
41
- localizedVariant: 'localizedVariants.csv',
42
- price: 'prices.csv',
43
- group: 'groups.csv',
44
- lookup: 'lookups.csv',
45
- user: 'users.csv',
46
- customer: 'customers.csv',
47
- label: 'labels.csv',
48
- filterPosition: 'filterPosition.csv',
49
- fieldConfiguration: 'fieldConfigurations.csv',
50
- stockAvailability: 'stockAvailability.csv',
51
- configuration: 'configurations.csv',
52
- userCustomer: 'userCustomers.csv',
53
- team: 'teams.csv'
54
- }
12
+ export const CsvType = [
13
+ 'products',
14
+ 'localizedProducts',
15
+ 'localizedFilters',
16
+ 'localizedVariants',
17
+ 'prices',
18
+ 'groups',
19
+ 'lookups',
20
+ 'users',
21
+ 'customers',
22
+ 'labels',
23
+ 'filterPosition',
24
+ 'fieldConfigurations',
25
+ 'stockAvailability',
26
+ 'configurations',
27
+ 'userCustomers',
28
+ 'teams'
29
+ ]
55
30
 
56
31
  export function getCsvFilesFromDir(dir) {
57
32
  return readdirSync(dir).filter(file => path.extname(file).toLowerCase() === '.csv')
@@ -61,519 +36,6 @@ export function getGoogleSheetCsvUrl(docId, sheet) {
61
36
  return `https://docs.google.com/spreadsheets/d/${docId}/gviz/tq?tqx=out:csv&sheet=${sheet}`
62
37
  }
63
38
 
64
- export function importCsvFromFile({
65
- file,
66
- csvType,
67
- outputDir,
68
- spinner,
69
- ws,
70
- delimiter = ';',
71
- importProcess
72
- }) {
73
- return new Promise(resolve => {
74
- const socket = createSocketConnection(ws.endpoint, ws.secret)
75
-
76
- const hrstart = process.hrtime()
77
- const importFileStart = new Date()
78
-
79
- let readStream = null
80
-
81
- const dirPathProcessing = path.resolve(outputDir, '_processing')
82
-
83
- if (!existsSync(dirPathProcessing)) {
84
- mkdirSync(dirPathProcessing, { recursive: true })
85
- }
86
-
87
- const filename = path.basename(file)
88
- const filepath = path.resolve(dirPathProcessing, filename)
89
-
90
- copyFileSync(file, filepath)
91
-
92
- const errorCsvFile = path.resolve(outputDir, `${importProcess.name}_${csvType}_errors.csv`)
93
- const errorFileStream = createWriteStream(errorCsvFile)
94
-
95
- const skippedCsvFile = path.resolve(outputDir, `${importProcess.name}_${csvType}_skipped.csv`)
96
- const skippedFileStream = createWriteStream(skippedCsvFile)
97
-
98
- let header = ''
99
- let lineNumber = 0
100
- let countImported = 0
101
- let countFailed = 0
102
- let countSkipped = 0
103
- const partitions = new Set()
104
-
105
- spinner.start('Loading...')
106
-
107
- const importRowSuccess = csvRow => {
108
- partitions.add(csvRow.Partition || '')
109
-
110
- countImported += 1
111
-
112
- spinner.text = printImportProcessResult({
113
- csvType,
114
- countImported,
115
- countFailed,
116
- countSkipped,
117
- importFileStart,
118
- importFileEnd: new Date(),
119
- executionTime: getExecutionTime(hrstart),
120
- name: filename
121
- })
122
-
123
- readStream.resume()
124
- }
125
-
126
- const importRowError = csvRow => {
127
- partitions.add(csvRow.Partition || '')
128
-
129
- countFailed += 1
130
-
131
- spinner.text = printImportProcessResult({
132
- csvType,
133
- countImported,
134
- countFailed,
135
- countSkipped,
136
- importFileStart,
137
- importFileEnd: new Date(),
138
- executionTime: getExecutionTime(hrstart),
139
- name: filename
140
- })
141
-
142
- errorFileStream.write(
143
- stringify([csvRow], {
144
- header: countFailed === 1,
145
- quoted: true,
146
- delimiter: ';'
147
- })
148
- )
149
-
150
- readStream.resume()
151
- }
152
-
153
- const importFatal = (csvRow, errorMessage) => {
154
- partitions.add(csvRow.Partition || '')
155
-
156
- spinner.fail(
157
- printImportProcessResult({
158
- csvType,
159
- countImported,
160
- countFailed,
161
- countSkipped,
162
- importFileStart,
163
- importFileEnd: new Date(),
164
- executionTime: getExecutionTime(hrstart),
165
- name: filename,
166
- fatalError: errorMessage
167
- })
168
- )
169
-
170
- resolve({
171
- csvType,
172
- countImported,
173
- countFailed,
174
- countSkipped,
175
- executionTime: getExecutionTime(hrstart),
176
- importFileStart,
177
- importFileEnd: new Date(),
178
- inputFile: file,
179
- fatalError: `FATAL: ${errorMessage}`,
180
- partitions
181
- })
182
-
183
- readStream.destroy()
184
- errorFileStream.end()
185
- skippedFileStream.end()
186
- }
187
-
188
- const importSuccess = () => {
189
- if (countFailed > 0 || countSkipped > 0) {
190
- spinner.warn()
191
- } else {
192
- spinner.succeed()
193
- }
194
-
195
- errorFileStream.end()
196
- skippedFileStream.end()
197
-
198
- deleteAsync(filepath)
199
-
200
- resolve({
201
- csvType,
202
- countImported,
203
- countFailed,
204
- countSkipped,
205
- importFileStart,
206
- importFileEnd: new Date(),
207
- executionTime: getExecutionTime(hrstart),
208
- inputFile: file,
209
- partitions
210
- })
211
- }
212
-
213
- socket.on('open', () => {
214
- readStream = createReadStream(file)
215
- .pipe(split())
216
- .pipe(
217
- mapSync(line => {
218
- readStream.pause()
219
-
220
- if (lineNumber === 0) {
221
- header = line
222
- readStream.resume()
223
- } else {
224
- try {
225
- const rows = parse(`${header}\n${line}`, {
226
- columns: true,
227
- skip_empty_lines: true,
228
- skipLinesWithEmptyValues: true,
229
- delimiter
230
- })
231
-
232
- if (rows.length > 0) {
233
- const packet = {
234
- type: 'importCsvRow',
235
- payload: {
236
- csvRow: rows[0],
237
- csvType,
238
- lineNumber,
239
- importProcess
240
- }
241
- }
242
- socket.send(JSON.stringify(packet))
243
- } else {
244
- readStream.resume()
245
- }
246
- } catch (e) {
247
- countSkipped += 1
248
- skippedFileStream.write(`${line},${e.message}`)
249
- readStream.resume()
250
- }
251
- }
252
-
253
- lineNumber += 1
254
- })
255
- )
256
- .on('error', e => importFatal(e.message))
257
- .on('end', importSuccess)
258
- })
259
-
260
- socket.on('message', packet => {
261
- const { type, payload } = JSON.parse(packet)
262
-
263
- switch (type) {
264
- case 'importRowSuccess':
265
- importRowSuccess(payload.csvRow)
266
- break
267
- case 'importRowError':
268
- importRowError(payload.csvRow)
269
- break
270
- case 'importRowFatal':
271
- importFatal(payload.csvRow, payload.error)
272
- break
273
- default:
274
- break
275
- }
276
- })
277
-
278
- socket.on('error', e => {
279
- importFatal(e.message)
280
- })
281
- })
282
- }
283
-
284
- export function sendImportErrorMail(ws, importProcess, csvReport) {
285
- const socket = createSocketConnection(ws.endpoint, ws.secret)
286
-
287
- socket.on('open', () => {
288
- socket.send(
289
- JSON.stringify({
290
- type: 'sendImportErrorMail',
291
- payload: { csvReport, importProcess }
292
- })
293
- )
294
- })
295
- }
296
-
297
- export function validateCsvFromFile(file, csvType, ws, delimiter, importProcess) {
298
- return new Promise(resolve => {
299
- const socket = createSocketConnection(ws.endpoint, ws.secret)
300
- const hrstart = process.hrtime()
301
-
302
- let readStream = null
303
-
304
- let header = ''
305
- let lineNumber = 0
306
- const filename = path.basename(file)
307
-
308
- socket.on('open', () => {
309
- readStream = createReadStream(file)
310
- .pipe(split())
311
- .pipe(
312
- mapSync(line => {
313
- readStream.pause()
314
-
315
- if (lineNumber === 0) {
316
- header = line
317
- readStream.resume()
318
- }
319
-
320
- if (lineNumber === 1) {
321
- if (line === '') {
322
- resolve({
323
- csvType,
324
- executionTime: getExecutionTime(hrstart),
325
- inputFile: filename
326
- })
327
- } else {
328
- const rows = parse(`${header}\n${line}`, {
329
- columns: true,
330
- skip_empty_lines: true,
331
- skipLinesWithEmptyValues: true,
332
- delimiter
333
- })
334
-
335
- const packet = {
336
- type: 'validateCsvHeaderRequest',
337
- payload: {
338
- csvColumns: Object.keys(rows[0]),
339
- csvType,
340
- importProcess
341
- }
342
- }
343
-
344
- socket.send(JSON.stringify(packet))
345
- }
346
-
347
- readStream.destroy()
348
- }
349
-
350
- lineNumber += 1
351
- })
352
- )
353
- .on('error', e => {
354
- resolve({
355
- csvType,
356
- executionTime: getExecutionTime(hrstart),
357
- inputFile: filename,
358
- error: e.message
359
- })
360
- })
361
- })
362
-
363
- socket.on('message', packet => {
364
- const { type, payload } = JSON.parse(packet)
365
- switch (type) {
366
- case 'validateCsvHeaderResponse': {
367
- const result = {
368
- csvType,
369
- executionTime: getExecutionTime(hrstart),
370
- inputFile: filename
371
- }
372
-
373
- if (payload.error) {
374
- result.error = payload.error
375
- }
376
-
377
- resolve(result)
378
- break
379
- }
380
- default:
381
- break
382
- }
383
- })
384
-
385
- socket.on('error', e => {
386
- resolve({
387
- csvType,
388
- executionTime: getExecutionTime(hrstart),
389
- inputFile: file,
390
- error: e.message
391
- })
392
- })
393
- })
394
- }
395
-
396
- export function getExecutionTime(importProcessStart) {
397
- const hrend = process.hrtime(importProcessStart)
398
- return ((hrend[0] * 1e9 + hrend[1]) / 1e9).toFixed(1)
399
- }
400
-
401
- export function printValidationProcessHeader() {
402
- console.log('\n=== Validation Process Result ===\n')
403
- }
404
-
405
- export function printImportProcessHeader() {
406
- console.log('\n=== Import Process Result ===\n')
407
- }
408
-
409
- export function printValidationProcessResult({
410
- inputFile,
411
- error
412
- // eslint-disable-next-line consistent-return
413
- }) {
414
- let message = ''
415
- const filename = path.basename(inputFile)
416
-
417
- if (error) {
418
- message = `[${chalk.red(filename)}] not valid ${chalk.gray(`[${error}]`)}`
419
- } else {
420
- message = `[${chalk.green(filename)}] valid`
421
- }
422
-
423
- console.log(message)
424
- }
425
-
426
- export function printImportProcessResult({
427
- countImported,
428
- countFailed,
429
- countSkipped,
430
- executionTime,
431
- name,
432
- fatalError
433
- // eslint-disable-next-line consistent-return
434
- }) {
435
- let message = ''
436
-
437
- if (fatalError) {
438
- message = `[${chalk.red(name)}] ${chalk.red(fatalError)}`
439
- return message
440
- }
441
-
442
- message = `[${colorByResult(
443
- name,
444
- countImported,
445
- countFailed,
446
- countSkipped
447
- )}] imported ${colorGreaterThanZero(countImported, 'green')} items`
448
-
449
- if (countFailed) {
450
- message += `, failed ${colorGreaterThanZero(countFailed, 'red')} items`
451
- }
452
-
453
- if (countSkipped) {
454
- message += `, skipped ${colorGreaterThanZero(countSkipped, 'red')} items`
455
- }
456
-
457
- message += ` ${chalk.gray(`[${executionTime}s]`)}`
458
-
459
- return message
460
- }
461
-
462
- export function colorByResult(value, countImported, countFailed, countSkipped) {
463
- let color = 'green'
464
-
465
- if (countImported > 0 && (countFailed > 0 || countSkipped > 0)) {
466
- color = 'yellow'
467
- }
468
-
469
- if (countImported === 0 && (countFailed > 0 || countSkipped > 0)) {
470
- color = 'red'
471
- }
472
-
473
- return chalk[color](value)
474
- }
475
-
476
- export function colorGreaterThanZero(value, color) {
477
- if (value > 0) {
478
- return chalk[color](value)
479
- }
480
-
481
- return value
482
- }
483
-
484
- export function refreshOrders(spinner, ws, importProcess) {
485
- return new Promise(resolve => {
486
- const hrstart = process.hrtime()
487
-
488
- const socket = createSocketConnection(ws.endpoint, ws.secret)
489
-
490
- spinner.start('Refreshing orders (draft, template)...')
491
-
492
- socket.on('open', () => {
493
- socket.send(JSON.stringify({ type: 'refreshOrdersRequest', payload: { importProcess } }))
494
- })
495
-
496
- socket.on('message', packet => {
497
- const { type, payload } = JSON.parse(packet)
498
- switch (type) {
499
- case 'refreshOrdersResponse': {
500
- spinner.text = printRefreshedOrders({
501
- ...payload,
502
- executionTime: getExecutionTime(hrstart)
503
- })
504
- spinner.succeed()
505
- resolve({
506
- totalCount: payload.totalCount,
507
- refreshed: payload.refreshed,
508
- errored: payload.errored,
509
- name: importProcess.name,
510
- executionTime: getExecutionTime(hrstart)
511
- })
512
- break
513
- }
514
- default:
515
- break
516
- }
517
- })
518
-
519
- socket.on('error', e => {
520
- resolve({ error: e.message })
521
- })
522
- })
523
- }
524
-
525
- // eslint-disable-next-line consistent-return
526
- export function printRefreshedOrders({ refreshed, errored, executionTime }) {
527
- let message = ''
528
-
529
- const stringRefreshed = colorGreaterThanZero(refreshed.length, 'green')
530
- const stringErrored = colorGreaterThanZero(errored.length, 'red')
531
-
532
- message += `Refreshed ${stringRefreshed} orders (draft, template)`
533
-
534
- if (errored.length) {
535
- message += `, refresh failed for ${stringErrored} orders.`
536
- }
537
-
538
- message += ` ${chalk.gray(`[${executionTime}s]`)}`
539
-
540
- return message
541
- }
542
-
543
- export function deleteRowsBeforeImportDate(importProcess, partitionsForCsvType, spinner, ws) {
544
- return new Promise(resolve => {
545
- const socket = createSocketConnection(ws.endpoint, ws.secret)
546
-
547
- spinner.start('Deleting old database records for chosen partitions...')
548
-
549
- socket.on('open', () => {
550
- socket.send(
551
- JSON.stringify({
552
- type: 'deleteRowsBeforeImportDateRequest',
553
- payload: { importProcess, partitionsForCsvType }
554
- })
555
- )
556
- })
557
-
558
- socket.on('message', packet => {
559
- const { type } = JSON.parse(packet)
560
- switch (type) {
561
- case 'deleteRowsBeforeImportDateResponse': {
562
- spinner.succeed('Database records deleted (soft)')
563
- resolve()
564
- break
565
- }
566
- default:
567
- break
568
- }
569
- })
570
-
571
- socket.on('error', e => {
572
- resolve({ error: e.message })
573
- })
574
- })
575
- }
576
-
577
39
  export async function download(url, destPath, fileName) {
578
40
  return new Promise((resolve, reject) => {
579
41
  const filePath = path.resolve(destPath, fileName)
@@ -601,210 +63,7 @@ export async function download(url, destPath, fileName) {
601
63
  })
602
64
  }
603
65
 
604
- export function callBeforeDataImportProcess(spinner, ws, importProcess) {
605
- return new Promise((resolve, reject) => {
606
- const socket = createSocketConnection(ws.endpoint, ws.secret)
607
-
608
- spinner.start('Executing tasks before start...')
609
-
610
- socket.on('open', () => {
611
- socket.send(
612
- JSON.stringify({ type: 'callBeforeDataImportProcessRequest', payload: { importProcess } })
613
- )
614
- })
615
-
616
- socket.on('message', packet => {
617
- const { type, payload } = JSON.parse(packet)
618
- switch (type) {
619
- case 'callBeforeDataImportProcessResponse': {
620
- if (payload.error) {
621
- spinner.fail(payload.error)
622
- reject()
623
- } else {
624
- spinner.succeed('Tasks executed before start')
625
- resolve()
626
- }
627
- break
628
- }
629
- default:
630
- break
631
- }
632
- })
633
-
634
- socket.on('error', e => {
635
- resolve({ error: e.message })
636
- })
637
- })
638
- }
639
-
640
- export function callAfterDataImportProcess(spinner, ws, importProcess) {
641
- return new Promise(resolve => {
642
- const socket = createSocketConnection(ws.endpoint, ws.secret)
643
-
644
- spinner.start('Executing tasks after the end process...')
645
-
646
- socket.on('open', () => {
647
- socket.send(
648
- JSON.stringify({ type: 'callAfterDataImportProcessRequest', payload: { importProcess } })
649
- )
650
- })
651
-
652
- socket.on('message', packet => {
653
- const { type } = JSON.parse(packet)
654
- switch (type) {
655
- case 'callAfterDataImportProcessResponse': {
656
- spinner.succeed('Tasks executed after the end process')
657
- resolve()
658
- break
659
- }
660
- default:
661
- break
662
- }
663
- })
664
-
665
- socket.on('error', e => {
666
- resolve({ error: e.message })
667
- })
668
- })
669
- }
670
-
671
- export function callAfterMediaImportProcess(spinner, ws, report) {
672
- return new Promise(resolve => {
673
- const socket = createSocketConnection(ws.endpoint, ws.secret)
674
-
675
- spinner.start('Executing tasks after the end process...')
676
-
677
- socket.on('open', () => {
678
- socket.send(JSON.stringify({ type: 'callAfterMediaImportProcessRequest', payload: report }))
679
- })
680
-
681
- socket.on('message', packet => {
682
- const { type } = JSON.parse(packet)
683
- switch (type) {
684
- case 'callAfterMediaImportProcessResponse': {
685
- spinner.succeed('Tasks executed after the end process')
686
- resolve()
687
- break
688
- }
689
- default:
690
- break
691
- }
692
- })
693
-
694
- socket.on('error', e => {
695
- resolve({ error: e.message })
696
- })
697
- })
698
- }
699
-
700
- export function importMedia(reprocess, spinner, ws) {
701
- return new Promise(resolve => {
702
- const hrstart = process.hrtime()
703
- const socket = createSocketConnection(ws.endpoint, ws.secret)
704
-
705
- let countAssetImported = 0
706
- let countAssetSkipped = 0
707
- let countAssetFailed = 0
708
- let countProductAssetImported = 0
709
-
710
- const updateSpinnerText = () => {
711
- spinner.text = printImportProcessResult({
712
- countImported: countAssetImported,
713
- countSkipped: countAssetSkipped,
714
- countFailed: countAssetFailed,
715
- executionTime: getExecutionTime(hrstart),
716
- name: 'Asset'
717
- })
718
- }
719
-
720
- socket.on('open', () => {
721
- socket.send(JSON.stringify({ type: 'import.images', payload: { reprocess } }))
722
- })
723
-
724
- socket.on('message', packet => {
725
- const { type, payload } = JSON.parse(packet)
726
-
727
- switch (type) {
728
- case 'import.images.start':
729
- spinner.start('[Asset] Importing Assets...')
730
- break
731
- case 'import.images.imageAsset.success':
732
- countAssetImported += 1
733
- updateSpinnerText()
734
- break
735
- case 'import.images.imageAsset.skipped':
736
- countAssetSkipped += 1
737
- updateSpinnerText()
738
- break
739
- case 'import.images.imageAsset.failed':
740
- countAssetFailed += 1
741
- updateSpinnerText()
742
- break
743
- case 'import.images.productAssets.start':
744
- countProductAssetImported = payload.count
745
- spinner.succeed()
746
- spinner.start(`[ProductAsset] Importing ${countProductAssetImported} Product Assets...`)
747
- break
748
- case 'import.images.productAssets.end':
749
- spinner.succeed(
750
- printImportProcessResult({
751
- countImported: payload.count,
752
- countFailed: 0,
753
- executionTime: getExecutionTime(hrstart),
754
- name: 'ProductAsset'
755
- })
756
- )
757
- break
758
- case 'import.images.end':
759
- resolve({
760
- countAssetImported,
761
- countAssetSkipped,
762
- countAssetFailed,
763
- countProductAssetImported
764
- })
765
- break
766
- default:
767
- break
768
- }
769
- })
770
-
771
- socket.on('error', e => {
772
- resolve({ error: e.message })
773
- })
774
- })
775
- }
776
-
777
- export function flushMedia(spinner, ws) {
778
- return new Promise((resolve, reject) => {
779
- const socket = createSocketConnection(ws.endpoint, ws.secret)
780
-
781
- spinner.start('Flushing... ')
782
-
783
- socket.on('open', () => {
784
- socket.send(JSON.stringify({ type: 'flush.media.request' }))
785
- })
786
-
787
- socket.on('message', packet => {
788
- const { type } = JSON.parse(packet)
789
- switch (type) {
790
- case 'flush.media.response': {
791
- spinner.succeed('Flushing completed')
792
- resolve()
793
- break
794
- }
795
- default:
796
- break
797
- }
798
- })
799
-
800
- socket.on('error', e => {
801
- spinner.fail(e.message)
802
- reject(e)
803
- })
804
- })
805
- }
806
-
807
- export function getArchiveFolder(instanceEndpoint) {
66
+ export function getImportDirName(instanceEndpoint) {
808
67
  const prefix = 'closer'
809
68
  const instance = slugify(instanceEndpoint.split('/')[0], {
810
69
  lower: true,
@@ -813,30 +72,6 @@ export function getArchiveFolder(instanceEndpoint) {
813
72
  return `${prefix}_${instance}`
814
73
  }
815
74
 
816
- export function renameWithTimestamp(dirPath) {
817
- const ts = getTimestampForFilename()
818
-
819
- const files = getCsvFilesFromDir(dirPath).map(filename => {
820
- const oldPath = path.resolve(dirPath, filename)
821
- const [name, ext] = oldPath.split('.')
822
- const newPath = `${name}_${ts}.${ext}`
823
- return {
824
- oldPath,
825
- newPath
826
- }
827
- })
828
-
829
- files.forEach(file => rename(file.oldPath, file.newPath, () => {}))
830
- }
831
-
832
- const getTimestampForFilename = () => {
833
- const date = new Date()
834
- const [isoDateString, isoTimeString] = date.toISOString().split('T')
835
- const dateString = isoDateString.split('-').join('')
836
- const timeString = isoTimeString.split(':').join('').split('.')[0]
837
- return `${dateString}_${timeString}`.split(':').join('')
838
- }
839
-
840
75
  export function getHumanTimestamp(date) {
841
76
  const [isoDateString, isoTimeString] = date.toISOString().split('T')
842
77
  const dateString = isoDateString.split('-').join('')
@@ -844,18 +79,52 @@ export function getHumanTimestamp(date) {
844
79
  return `${dateString}_${timeString}`.split(':').join('')
845
80
  }
846
81
 
847
- export async function readImportDir(dirpath) {
848
- const allFiles = readdirSync(dirpath)
849
- const csvFiles = allFiles.filter(file => path.extname(file) === '.csv')
82
+ // export function createSocketConnection(endpoint, secret) {
83
+ // const protocol = endpoint.includes('localhost') || endpoint.includes('127.0.0.1') ? 'ws' : 'wss'
84
+ // const url = `${protocol}://${endpoint}/import`
85
+ // const socket = new WebSocket(url, {
86
+ // headers: { 'x-closer-secret': secret }
87
+ // })
850
88
 
851
- if (csvFiles.length === 0) {
852
- return []
853
- }
89
+ // return socket
90
+ // }
854
91
 
855
- const files = csvFiles.map(file => {
856
- const stat = statSync(path.resolve(dirpath, file))
857
- return { filename: file, mtimeMS: stat.mtimeMs, mtime: stat.mtime, size: stat.size }
858
- })
92
+ // export function colorByResult(value, countImported, countFailed, countSkipped) {
93
+ // let color = 'green'
859
94
 
860
- return files
861
- }
95
+ // if (countImported > 0 && (countFailed > 0 || countSkipped > 0)) {
96
+ // color = 'yellow'
97
+ // }
98
+
99
+ // if (countImported === 0 && (countFailed > 0 || countSkipped > 0)) {
100
+ // color = 'red'
101
+ // }
102
+
103
+ // return chalk[color](value)
104
+ // }
105
+
106
+ // export function colorGreaterThanZero(value, color) {
107
+ // if (value > 0) {
108
+ // return chalk[color](value)
109
+ // }
110
+
111
+ // return value
112
+ // }
113
+
114
+ // eslint-disable-next-line consistent-return
115
+ // export function printRefreshedOrders({ refreshed, errored, executionTime }) {
116
+ // let message = ''
117
+
118
+ // const stringRefreshed = colorGreaterThanZero(refreshed.length, 'green')
119
+ // const stringErrored = colorGreaterThanZero(errored.length, 'red')
120
+
121
+ // message += `Refreshed ${stringRefreshed} orders (draft, template)`
122
+
123
+ // if (errored.length) {
124
+ // message += `, refresh failed for ${stringErrored} orders.`
125
+ // }
126
+
127
+ // message += ` ${chalk.gray(`[${executionTime}s]`)}`
128
+
129
+ // return message
130
+ // }