closer-cli 2.7.0 → 2.11.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,41 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.11.0](https://code.hfarm.dev/closer/closer/compare/v2.10.0...v2.11.0) (2022-05-18)
7
+
8
+
9
+ ### Features
10
+
11
+ * **#PJX-445:** Multilingua ([f24f066](https://code.hfarm.dev/closer/closer/commits/f24f0668b7c0c8338c8d91db68afc871efb534ed)), closes [#PJX-445](https://code.hfarm.dev/closer/closer/issues/PJX-445)
12
+
13
+
14
+
15
+
16
+
17
+ # [2.9.0](https://code.hfarm.dev/closer/closer/compare/v2.8.0...v2.9.0) (2022-05-09)
18
+
19
+
20
+ ### Features
21
+
22
+ * **#PJX-442:** Import ad hoc disponibilità incrementale non bloccante ([aad991b](https://code.hfarm.dev/closer/closer/commits/aad991ba97e76977c6a6a2d73ef614026324b0d3)), closes [#PJX-442](https://code.hfarm.dev/closer/closer/issues/PJX-442)
23
+
24
+
25
+
26
+
27
+
28
+ # [2.8.0](https://code.hfarm.dev/closer/closer/compare/v2.7.1...v2.8.0) (2022-04-27)
29
+
30
+
31
+ ### Features
32
+
33
+ * **#PJX-433:** [Import FTP] Cambiare il valore di default del separatore csv ([ef27bf1](https://code.hfarm.dev/closer/closer/commits/ef27bf17847f17b94ba5ec82846a9c94f521be22)), closes [#PJX-433](https://code.hfarm.dev/closer/closer/issues/PJX-433)
34
+ * **#PJX-437:** [Import] Archiviare anche il file csv sorgente ([9a729c5](https://code.hfarm.dev/closer/closer/commits/9a729c54982537e3bb6eca4bffc1f23c6bcc8aaf)), closes [#PJX-437](https://code.hfarm.dev/closer/closer/issues/PJX-437)
35
+ * **#PJX-439:** Anagrafiche con zero righe ([571ec16](https://code.hfarm.dev/closer/closer/commits/571ec169766cd784e6b7e905fa801f238da31fb6)), closes [#PJX-439](https://code.hfarm.dev/closer/closer/issues/PJX-439)
36
+
37
+
38
+
39
+
40
+
6
41
  # [2.6.0](https://code.hfarm.dev/closer/closer/compare/v2.5.1...v2.6.0) (2022-04-19)
7
42
 
8
43
 
@@ -19,7 +19,8 @@ const {
19
19
  callBeforeDataImportProcess,
20
20
  callAfterDataImportProcess,
21
21
  getExecutionTime,
22
- getArchiveFolder
22
+ getArchiveFolder,
23
+ renameWithTimestamp
23
24
  } = require('../../helpers')
24
25
 
25
26
  exports.command = 'multiple [options]'
@@ -274,9 +275,9 @@ exports.handler = async argv => {
274
275
 
275
276
  report.result = reportRows
276
277
 
277
- // const message = getDataImportMessageReport(report)
278
-
279
278
  await callAfterDataImportProcess(spinner, ws, report)
280
279
 
280
+ await renameWithTimestamp(argv.out)
281
+
281
282
  process.exit()
282
283
  }
@@ -14,7 +14,8 @@ const {
14
14
  ALLOWED_CSV_FILES,
15
15
  download,
16
16
  validateCsvFromFile,
17
- getArchiveFolder
17
+ getArchiveFolder,
18
+ renameWithTimestamp
18
19
  } = require('../../helpers')
19
20
 
20
21
  exports.command = 'single [options]'
@@ -213,5 +214,7 @@ exports.handler = async argv => {
213
214
 
214
215
  await callAfterDataImportProcess(spinner, ws, report)
215
216
 
217
+ await renameWithTimestamp(argv.out)
218
+
216
219
  process.exit()
217
220
  }
package/helpers.js CHANGED
@@ -23,6 +23,9 @@ exports.createSocketConnection = (endpoint, adminSecret) => {
23
23
 
24
24
  exports.ALLOWED_CSV_FILES = {
25
25
  product: 'products.csv',
26
+ localizedProduct: 'localizedProducts.csv',
27
+ localizedFilter: 'localizedFilters.csv',
28
+ localizedVariant: 'localizedVariants.csv',
26
29
  price: 'prices.csv',
27
30
  group: 'groups.csv',
28
31
  lookup: 'lookups.csv',
@@ -36,13 +39,15 @@ exports.ALLOWED_CSV_FILES = {
36
39
  userCustomer: 'userCustomers.csv'
37
40
  }
38
41
 
39
- exports.getCsvFilesFromDir = dir =>
42
+ const getCsvFilesFromDir = dir =>
40
43
  fs.readdirSync(dir).filter(file => path.extname(file).toLowerCase() === '.csv')
41
44
 
45
+ exports.getCsvFilesFromDir = getCsvFilesFromDir
46
+
42
47
  exports.getGoogleSheetCsvUrl = (docId, sheet) =>
43
48
  `https://docs.google.com/spreadsheets/d/${docId}/gviz/tq?tqx=out:csv&sheet=${sheet}`
44
49
 
45
- exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter = ',') =>
50
+ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter = ';') =>
46
51
  new Promise(resolve => {
47
52
  const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
48
53
 
@@ -54,6 +59,9 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
54
59
  fs.mkdirSync(outputDir, { recursive: true })
55
60
  }
56
61
 
62
+ const filename = path.basename(file)
63
+ fs.copyFileSync(file, path.resolve(outputDir, filename))
64
+
57
65
  const errorCsvFile = path.resolve(outputDir, `${csvType}_errors.csv`)
58
66
  const errorFileStream = fs.createWriteStream(errorCsvFile)
59
67
 
@@ -66,8 +74,6 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
66
74
  let countFailed = 0
67
75
  let countSkipped = 0
68
76
 
69
- const filename = path.basename(file)
70
-
71
77
  spinner.start('Loading...')
72
78
 
73
79
  const importRowSuccess = () => {
@@ -247,20 +253,29 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';') =>
247
253
  }
248
254
 
249
255
  if (lineNumber === 1) {
250
- const rows = parse(`${header}\n${line}`, {
251
- columns: true,
252
- skip_empty_lines: true,
253
- skipLinesWithEmptyValues: true,
254
- delimiter
255
- })
256
-
257
- const packet = {
258
- csvColumns: Object.keys(rows[0]),
259
- csvType,
260
- type: 'validateCsvHeaderRequest'
256
+ if (line === '') {
257
+ resolve({
258
+ csvType,
259
+ executionTime: this.getExecutionTime(hrstart),
260
+ inputFile: filename
261
+ })
262
+ } else {
263
+ const rows = parse(`${header}\n${line}`, {
264
+ columns: true,
265
+ skip_empty_lines: true,
266
+ skipLinesWithEmptyValues: true,
267
+ delimiter
268
+ })
269
+
270
+ const packet = {
271
+ csvColumns: Object.keys(rows[0]),
272
+ csvType,
273
+ type: 'validateCsvHeaderRequest'
274
+ }
275
+
276
+ socket.send(JSON.stringify(packet))
261
277
  }
262
278
 
263
- socket.send(JSON.stringify(packet))
264
279
  readStream.destroy()
265
280
  }
266
281
 
@@ -420,7 +435,6 @@ exports.refreshOrders = (spinner, ws) =>
420
435
  const { type, payload } = JSON.parse(packet)
421
436
  switch (type) {
422
437
  case 'refreshDraftOrdersResponse': {
423
- console.log(JSON.stringify({ type, payload }))
424
438
  spinner.text = this.printRefreshedOrders({
425
439
  ...payload,
426
440
  executionTime: this.getExecutionTime(hrstart)
@@ -710,11 +724,32 @@ exports.flushMedia = (spinner, ws) =>
710
724
  })
711
725
 
712
726
  exports.getArchiveFolder = instanceEndpoint => {
713
- const date = new Date()
714
727
  const prefix = 'closer'
715
728
  const instance = slugify(instanceEndpoint.split('/')[0], { lower: true })
729
+ const ts = getTimestampForFilename()
730
+ return `${prefix}_${instance}/${ts}`
731
+ }
732
+
733
+ exports.renameWithTimestamp = dirPath => {
734
+ const ts = getTimestampForFilename()
735
+
736
+ const files = getCsvFilesFromDir(dirPath).map(filename => {
737
+ const oldPath = path.resolve(dirPath, filename)
738
+ const [name, ext] = oldPath.split('.')
739
+ const newPath = `${name}_${ts}.${ext}`
740
+ return {
741
+ oldPath,
742
+ newPath
743
+ }
744
+ })
745
+
746
+ files.forEach(file => fs.rename(file.oldPath, file.newPath, () => {}))
747
+ }
748
+
749
+ const getTimestampForFilename = () => {
750
+ const date = new Date()
716
751
  const [isoDateString, isoTimeString] = date.toISOString().split('T')
717
752
  const dateString = isoDateString.split('-').join('')
718
753
  const timeString = isoTimeString.split(':').join('').split('.')[0]
719
- return `${prefix}_${instance}/${dateString}_${timeString}`.split(':').join('')
754
+ return `${dateString}_${timeString}`.split(':').join('')
720
755
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "closer-cli",
3
- "version": "2.7.0",
3
+ "version": "2.11.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,213 +0,0 @@
1
- /* eslint-disable no-await-in-loop */
2
- /* eslint-disable no-restricted-syntax */
3
- /* eslint-disable no-console */
4
- const fs = require('fs')
5
- const chalk = require('chalk')
6
- const path = require('path')
7
-
8
- const Ora = require('ora')
9
- const prompts = require('prompts')
10
- const {
11
- importCsvFromFile,
12
- getExecutionTime,
13
- callAfterDataImportProcess,
14
- ALLOWED_CSV_FILES,
15
- download,
16
- validateCsvFromFile,
17
- getArchiveFolder,
18
- getGoogleSheetCsvUrl
19
- } = require('../helpers')
20
-
21
- exports.command = 'import:stock'
22
-
23
- exports.desc = 'Import Stock Availability from CSV file'
24
-
25
- exports.builder = yargs => {
26
- yargs
27
- .usage(`Usage: ${chalk.cyan('$0 import:stock')} [options]`)
28
- .option('fromFile', {
29
- alias: 'f',
30
- describe: 'File to import',
31
- type: 'string'
32
- })
33
- .option('fromUrl', {
34
- alias: 'u',
35
- describe: 'Remote URL file to import',
36
- type: 'string'
37
- })
38
- .option('fromDir', {
39
- alias: 'd',
40
- describe: 'Directory path that contains file to import',
41
- type: 'string'
42
- })
43
- .option('fromGoogleDocId', {
44
- alias: 'g',
45
- describe: 'Google Doc ID that contains sheet to import',
46
- type: 'string'
47
- })
48
- // .conflicts('fromFile', 'fromUrl', 'fromDir', 'fromGoogleDocId')
49
- .check(argv => {
50
- if (!argv.fromFile && !argv.fromUrl && !argv.fromDir && !argv.fromGoogleDocId) {
51
- throw new Error(
52
- 'Missing required argument: fromFile OR fromUrl OR fromDir OR fromGoogleDocId'
53
- )
54
- }
55
-
56
- if (argv.fromFile) {
57
- fs.accessSync(argv.fromFile, fs.constants.F_OK)
58
- }
59
-
60
- if (argv.fromDir) {
61
- fs.accessSync(argv.fromDir, fs.constants.F_OK)
62
- }
63
-
64
- return true
65
- })
66
- }
67
-
68
- exports.handler = async argv => {
69
- // eslint-disable-next-line no-param-reassign
70
- argv.out = argv.out || getArchiveFolder(argv.endpoint)
71
-
72
- const spinner = new Ora()
73
- const hrstart = process.hrtime()
74
-
75
- const report = {
76
- start: new Date(),
77
- end: null,
78
- time: null,
79
- endpoint: argv.endpoint,
80
- mode: null,
81
- type: [],
82
- result: []
83
- }
84
-
85
- const ws = {
86
- endpoint: argv.endpoint,
87
- adminSecret: argv['admin-secret']
88
- }
89
-
90
- const interactive = !argv.nonInteractive
91
-
92
- const csvType = 'stockAvailability'
93
-
94
- let file
95
- if (argv.fromDir) {
96
- file = {
97
- file: path.resolve(argv.fromDir, ALLOWED_CSV_FILES.stockAvailability),
98
- csvType
99
- }
100
- } else if (argv.fromGoogleDocId) {
101
- file = {
102
- url: getGoogleSheetCsvUrl(argv.fromGoogleDocId, csvType),
103
- csvType
104
- }
105
- } else if (argv.fromFile) {
106
- file = {
107
- file: argv.fromFile,
108
- csvType
109
- }
110
- } else if (argv.fromUrl) {
111
- file = {
112
- url: argv.fromUrl,
113
- csvType
114
- }
115
- }
116
-
117
- let mode
118
- if (interactive && !argv.mode) {
119
- const answers = await prompts(
120
- [
121
- {
122
- type: 'select',
123
- name: 'mode',
124
- message: 'Import Mode',
125
- choices: [
126
- {
127
- title: 'Incremental',
128
- value: 'incremental'
129
- },
130
- {
131
- title: 'Full',
132
- description: 'Before starting, all database records will be logically deleted',
133
- value: 'full'
134
- }
135
- ],
136
- hint: ' '
137
- }
138
- ],
139
- { onCancel: () => process.exit() }
140
- )
141
-
142
- mode = answers.mode
143
- } else {
144
- mode = argv.mode
145
- }
146
-
147
- if (interactive) {
148
- console.log('')
149
- const { confirmed } = await prompts(
150
- [
151
- {
152
- type: 'confirm',
153
- name: 'confirmed',
154
- message: 'Continue?',
155
- initial: false
156
- }
157
- ],
158
- { onCancel: () => process.exit() }
159
- )
160
-
161
- if (!confirmed) {
162
- process.exit()
163
- }
164
-
165
- console.log('')
166
- }
167
-
168
- let filepath = argv.fromFile
169
-
170
- if (argv.fromUrl || argv.fromGoogleDocId) {
171
- spinner.start('Downloading file...')
172
- filepath = await download(file.url, argv.out, `${csvType}.csv`)
173
- spinner.succeed('Downloaded file')
174
- }
175
-
176
- const validation = await validateCsvFromFile(filepath, csvType, ws, argv.csvDelimiter)
177
-
178
- if (validation.error) {
179
- console.log(`ERROR => [${chalk.red(validation.inputFile)}] ${validation.error}`)
180
- process.exit()
181
- }
182
-
183
- const csvReport = await importCsvFromFile(
184
- filepath,
185
- csvType,
186
- argv.out,
187
- spinner,
188
- ws,
189
- argv.csvDelimiter
190
- )
191
-
192
- //
193
- // Report
194
- //
195
-
196
- report.end = new Date()
197
- report.time = getExecutionTime(hrstart)
198
- report.mode = mode
199
- report.type = [csvType]
200
-
201
- const reportRows = []
202
-
203
- reportRows.push({
204
- type: 'import.csv',
205
- payload: csvReport
206
- })
207
-
208
- report.result = reportRows
209
-
210
- await callAfterDataImportProcess(spinner, ws, report)
211
-
212
- process.exit()
213
- }