closer-cli 2.16.6 → 2.17.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/cmds/importData_cmds/multiple.js +52 -31
- package/cmds/importData_cmds/single.js +29 -22
- package/helpers.js +91 -32
- package/index.js +6 -0
- package/package.json +1 -1
- package/cmds/exportData.js +0 -84
|
@@ -14,13 +14,14 @@ const {
|
|
|
14
14
|
importCsvFromFile,
|
|
15
15
|
validateCsvFromFile,
|
|
16
16
|
refreshOrders,
|
|
17
|
-
truncateTablesByCsvTypes,
|
|
18
17
|
download,
|
|
19
18
|
callBeforeDataImportProcess,
|
|
20
19
|
callAfterDataImportProcess,
|
|
21
20
|
getExecutionTime,
|
|
22
21
|
getArchiveFolder,
|
|
23
|
-
renameWithTimestamp
|
|
22
|
+
renameWithTimestamp,
|
|
23
|
+
sendImportErrorMail,
|
|
24
|
+
deleteRowsBeforeImportDate
|
|
24
25
|
} = require('../../helpers')
|
|
25
26
|
|
|
26
27
|
exports.command = 'multiple [options]'
|
|
@@ -59,12 +60,13 @@ exports.handler = async argv => {
|
|
|
59
60
|
argv.out = argv.out || getArchiveFolder(argv.endpoint)
|
|
60
61
|
|
|
61
62
|
const hrstart = process.hrtime()
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const importProcess = {
|
|
64
|
+
importProcessStart: new Date(),
|
|
65
|
+
importProcessEnd: null,
|
|
65
66
|
time: null,
|
|
66
67
|
endpoint: argv.endpoint,
|
|
67
68
|
mode: null,
|
|
69
|
+
name: argv.name,
|
|
68
70
|
type: [],
|
|
69
71
|
result: []
|
|
70
72
|
}
|
|
@@ -121,6 +123,8 @@ exports.handler = async argv => {
|
|
|
121
123
|
})
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
importProcess.type = files.map(f => f.csvType)
|
|
127
|
+
|
|
124
128
|
let mode
|
|
125
129
|
if (interactive && !argv.mode) {
|
|
126
130
|
const answers = await prompts(
|
|
@@ -151,6 +155,8 @@ exports.handler = async argv => {
|
|
|
151
155
|
mode = argv.mode
|
|
152
156
|
}
|
|
153
157
|
|
|
158
|
+
importProcess.mode = mode
|
|
159
|
+
|
|
154
160
|
const spinner = new Ora()
|
|
155
161
|
|
|
156
162
|
const validations = []
|
|
@@ -178,7 +184,13 @@ exports.handler = async argv => {
|
|
|
178
184
|
// Validate CSV headers sequentially
|
|
179
185
|
//
|
|
180
186
|
for (const item of parsedFiles) {
|
|
181
|
-
const validation = await validateCsvFromFile(
|
|
187
|
+
const validation = await validateCsvFromFile(
|
|
188
|
+
item.file,
|
|
189
|
+
item.csvType,
|
|
190
|
+
ws,
|
|
191
|
+
argv.csvDelimiter,
|
|
192
|
+
importProcess
|
|
193
|
+
)
|
|
182
194
|
validations.push(validation)
|
|
183
195
|
}
|
|
184
196
|
|
|
@@ -215,67 +227,76 @@ exports.handler = async argv => {
|
|
|
215
227
|
//
|
|
216
228
|
if (!argv.skipTasksBeforeImport) {
|
|
217
229
|
try {
|
|
218
|
-
await callBeforeDataImportProcess(spinner, ws)
|
|
230
|
+
await callBeforeDataImportProcess(spinner, ws, importProcess)
|
|
219
231
|
} catch (e) {
|
|
220
232
|
process.exit()
|
|
221
233
|
}
|
|
222
234
|
}
|
|
223
235
|
|
|
224
236
|
//
|
|
225
|
-
// Import
|
|
237
|
+
// Import CSV files sequentially
|
|
226
238
|
//
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
239
|
+
const partitionsForCsvType = new Map()
|
|
240
|
+
|
|
241
|
+
for (const item of parsedFiles) {
|
|
242
|
+
const csvReport = await importCsvFromFile({
|
|
243
|
+
file: item.file,
|
|
244
|
+
csvType: item.csvType,
|
|
245
|
+
outputDir: argv.out,
|
|
246
|
+
spinner,
|
|
247
|
+
ws,
|
|
248
|
+
delimiter: argv.csvDelimiter,
|
|
249
|
+
importProcess
|
|
250
|
+
})
|
|
251
|
+
csvReports.push(csvReport)
|
|
252
|
+
if (csvReport.countFailed > 0 || csvReport.countSkipped > 0) {
|
|
253
|
+
sendImportErrorMail(ws, importProcess, csvReport)
|
|
254
|
+
}
|
|
255
|
+
partitionsForCsvType.set(csvReport.csvType, Array.from(csvReport.partitions))
|
|
230
256
|
}
|
|
231
257
|
|
|
232
258
|
//
|
|
233
|
-
// Import
|
|
259
|
+
// Import FULL?
|
|
234
260
|
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
argv.out,
|
|
261
|
+
if (mode === 'full') {
|
|
262
|
+
await deleteRowsBeforeImportDate(
|
|
263
|
+
importProcess,
|
|
264
|
+
Object.fromEntries(partitionsForCsvType),
|
|
240
265
|
spinner,
|
|
241
|
-
ws
|
|
242
|
-
argv.csvDelimiter
|
|
266
|
+
ws
|
|
243
267
|
)
|
|
244
|
-
csvReports.push(csvReport)
|
|
245
268
|
}
|
|
246
269
|
|
|
247
270
|
//
|
|
248
271
|
// Refresh Orders of type Draft
|
|
249
272
|
//
|
|
250
273
|
// eslint-disable-next-line no-unused-vars
|
|
251
|
-
const refreshedOrders = await refreshOrders(spinner, ws)
|
|
274
|
+
const refreshedOrders = await refreshOrders(spinner, ws, importProcess.name)
|
|
252
275
|
|
|
253
276
|
//
|
|
254
|
-
//
|
|
277
|
+
// importProcess
|
|
255
278
|
//
|
|
256
279
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
report.mode = mode
|
|
260
|
-
report.type = files.map(f => f.csvType)
|
|
280
|
+
importProcess.importProcessEnd = new Date()
|
|
281
|
+
importProcess.time = getExecutionTime(hrstart)
|
|
261
282
|
|
|
262
|
-
const
|
|
283
|
+
const importProcessRows = []
|
|
263
284
|
|
|
264
285
|
csvReports.forEach(csvReport => {
|
|
265
|
-
|
|
286
|
+
importProcessRows.push({
|
|
266
287
|
type: 'import.csv',
|
|
267
288
|
payload: csvReport
|
|
268
289
|
})
|
|
269
290
|
})
|
|
270
291
|
|
|
271
|
-
|
|
292
|
+
importProcessRows.push({
|
|
272
293
|
type: 'refreshed.orders',
|
|
273
294
|
payload: refreshedOrders
|
|
274
295
|
})
|
|
275
296
|
|
|
276
|
-
|
|
297
|
+
importProcess.result = importProcessRows
|
|
277
298
|
|
|
278
|
-
await callAfterDataImportProcess(spinner, ws,
|
|
299
|
+
await callAfterDataImportProcess(spinner, ws, importProcess)
|
|
279
300
|
|
|
280
301
|
await renameWithTimestamp(argv.out)
|
|
281
302
|
|
|
@@ -15,7 +15,8 @@ const {
|
|
|
15
15
|
download,
|
|
16
16
|
validateCsvFromFile,
|
|
17
17
|
getArchiveFolder,
|
|
18
|
-
renameWithTimestamp
|
|
18
|
+
renameWithTimestamp,
|
|
19
|
+
sendImportErrorMail
|
|
19
20
|
} = require('../../helpers')
|
|
20
21
|
|
|
21
22
|
exports.command = 'single [options]'
|
|
@@ -56,12 +57,13 @@ exports.handler = async argv => {
|
|
|
56
57
|
const spinner = new Ora()
|
|
57
58
|
const hrstart = process.hrtime()
|
|
58
59
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
const importProcess = {
|
|
61
|
+
importProcessStart: new Date(),
|
|
62
|
+
importProcessEnd: null,
|
|
62
63
|
time: null,
|
|
63
64
|
endpoint: argv.endpoint,
|
|
64
65
|
mode: null,
|
|
66
|
+
name: argv.name,
|
|
65
67
|
type: [],
|
|
66
68
|
result: []
|
|
67
69
|
}
|
|
@@ -158,61 +160,66 @@ exports.handler = async argv => {
|
|
|
158
160
|
spinner.succeed('Downloaded file')
|
|
159
161
|
}
|
|
160
162
|
|
|
161
|
-
const validation = await validateCsvFromFile(filepath, type, ws, argv.csvDelimiter)
|
|
163
|
+
const validation = await validateCsvFromFile(filepath, type, ws, argv.csvDelimiter, importProcess)
|
|
162
164
|
|
|
163
165
|
if (validation.error) {
|
|
164
166
|
console.log(`ERROR => [${chalk.red(validation.inputFile)}] ${validation.error}`)
|
|
165
167
|
process.exit()
|
|
166
168
|
}
|
|
167
169
|
|
|
170
|
+
importProcess.mode = mode
|
|
171
|
+
importProcess.type = [type]
|
|
172
|
+
|
|
168
173
|
//
|
|
169
174
|
// Call ImportService.beforeImportProcess (import flag)
|
|
170
175
|
//
|
|
171
176
|
if (!argv.skipTasksBeforeImport) {
|
|
172
177
|
try {
|
|
173
|
-
await callBeforeDataImportProcess(spinner, ws)
|
|
178
|
+
await callBeforeDataImportProcess(spinner, ws, importProcess)
|
|
174
179
|
} catch (e) {
|
|
175
180
|
process.exit()
|
|
176
181
|
}
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
if (argv.fromFile) {
|
|
180
|
-
csvReport = await importCsvFromFile(
|
|
181
|
-
argv.fromFile,
|
|
182
|
-
type,
|
|
183
|
-
argv.out,
|
|
185
|
+
csvReport = await importCsvFromFile({
|
|
186
|
+
file: argv.fromFile,
|
|
187
|
+
csvType: type,
|
|
188
|
+
outputDir: argv.out,
|
|
184
189
|
spinner,
|
|
185
190
|
ws,
|
|
186
|
-
argv.csvDelimiter
|
|
187
|
-
|
|
191
|
+
delimiter: argv.csvDelimiter,
|
|
192
|
+
importProcess
|
|
193
|
+
})
|
|
194
|
+
if (csvReport.countFailed > 0 || csvReport.countSkipped > 0) {
|
|
195
|
+
sendImportErrorMail(ws, importProcess, csvReport)
|
|
196
|
+
}
|
|
188
197
|
}
|
|
189
198
|
|
|
190
|
-
const refreshedOrders = await refreshOrders(spinner, ws)
|
|
199
|
+
const refreshedOrders = await refreshOrders(spinner, ws, importProcess)
|
|
191
200
|
|
|
192
201
|
//
|
|
193
202
|
// Report
|
|
194
203
|
//
|
|
195
204
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
report.mode = mode
|
|
199
|
-
report.type = [type]
|
|
205
|
+
importProcess.importProcessEnd = new Date()
|
|
206
|
+
importProcess.time = getExecutionTime(hrstart)
|
|
200
207
|
|
|
201
|
-
const
|
|
208
|
+
const importProcessRows = []
|
|
202
209
|
|
|
203
|
-
|
|
210
|
+
importProcessRows.push({
|
|
204
211
|
type: 'import.csv',
|
|
205
212
|
payload: csvReport
|
|
206
213
|
})
|
|
207
214
|
|
|
208
|
-
|
|
215
|
+
importProcessRows.push({
|
|
209
216
|
type: 'refreshed.orders',
|
|
210
217
|
payload: refreshedOrders
|
|
211
218
|
})
|
|
212
219
|
|
|
213
|
-
|
|
220
|
+
importProcess.result = importProcessRows
|
|
214
221
|
|
|
215
|
-
await callAfterDataImportProcess(spinner, ws,
|
|
222
|
+
await callAfterDataImportProcess(spinner, ws, importProcess)
|
|
216
223
|
|
|
217
224
|
await renameWithTimestamp(argv.out)
|
|
218
225
|
|
package/helpers.js
CHANGED
|
@@ -47,11 +47,20 @@ exports.getCsvFilesFromDir = getCsvFilesFromDir
|
|
|
47
47
|
exports.getGoogleSheetCsvUrl = (docId, sheet) =>
|
|
48
48
|
`https://docs.google.com/spreadsheets/d/${docId}/gviz/tq?tqx=out:csv&sheet=${sheet}`
|
|
49
49
|
|
|
50
|
-
exports.importCsvFromFile = (
|
|
50
|
+
exports.importCsvFromFile = ({
|
|
51
|
+
file,
|
|
52
|
+
csvType,
|
|
53
|
+
outputDir,
|
|
54
|
+
spinner,
|
|
55
|
+
ws,
|
|
56
|
+
delimiter = ';',
|
|
57
|
+
importProcess
|
|
58
|
+
}) =>
|
|
51
59
|
new Promise(resolve => {
|
|
52
60
|
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
53
61
|
|
|
54
62
|
const hrstart = process.hrtime()
|
|
63
|
+
const importFileStart = new Date()
|
|
55
64
|
|
|
56
65
|
let readStream = null
|
|
57
66
|
|
|
@@ -73,16 +82,22 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
73
82
|
let countImported = 0
|
|
74
83
|
let countFailed = 0
|
|
75
84
|
let countSkipped = 0
|
|
85
|
+
const partitions = new Set()
|
|
76
86
|
|
|
77
87
|
spinner.start('Loading...')
|
|
78
88
|
|
|
79
|
-
const importRowSuccess =
|
|
89
|
+
const importRowSuccess = csvRow => {
|
|
90
|
+
partitions.add(csvRow.Partition)
|
|
91
|
+
|
|
80
92
|
countImported += 1
|
|
81
93
|
|
|
82
94
|
spinner.text = this.printImportProcessResult({
|
|
95
|
+
csvType,
|
|
83
96
|
countImported,
|
|
84
97
|
countFailed,
|
|
85
98
|
countSkipped,
|
|
99
|
+
importFileStart,
|
|
100
|
+
importFileEnd: new Date(),
|
|
86
101
|
executionTime: this.getExecutionTime(hrstart),
|
|
87
102
|
name: filename
|
|
88
103
|
})
|
|
@@ -91,12 +106,17 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
91
106
|
}
|
|
92
107
|
|
|
93
108
|
const importRowError = csvRow => {
|
|
109
|
+
partitions.add(csvRow.Partition)
|
|
110
|
+
|
|
94
111
|
countFailed += 1
|
|
95
112
|
|
|
96
113
|
spinner.text = this.printImportProcessResult({
|
|
114
|
+
csvType,
|
|
97
115
|
countImported,
|
|
98
116
|
countFailed,
|
|
99
117
|
countSkipped,
|
|
118
|
+
importFileStart,
|
|
119
|
+
importFileEnd: new Date(),
|
|
100
120
|
executionTime: this.getExecutionTime(hrstart),
|
|
101
121
|
name: filename
|
|
102
122
|
})
|
|
@@ -112,12 +132,17 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
112
132
|
readStream.resume()
|
|
113
133
|
}
|
|
114
134
|
|
|
115
|
-
const importFatal = errorMessage => {
|
|
135
|
+
const importFatal = (csvRow, errorMessage) => {
|
|
136
|
+
partitions.add(csvRow.Partition)
|
|
137
|
+
|
|
116
138
|
spinner.fail(
|
|
117
139
|
this.printImportProcessResult({
|
|
140
|
+
csvType,
|
|
118
141
|
countImported,
|
|
119
142
|
countFailed,
|
|
120
143
|
countSkipped,
|
|
144
|
+
importFileStart,
|
|
145
|
+
importFileEnd: new Date(),
|
|
121
146
|
executionTime: this.getExecutionTime(hrstart),
|
|
122
147
|
name: filename,
|
|
123
148
|
fatalError: errorMessage
|
|
@@ -130,8 +155,11 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
130
155
|
countFailed,
|
|
131
156
|
countSkipped,
|
|
132
157
|
executionTime: this.getExecutionTime(hrstart),
|
|
158
|
+
importFileStart,
|
|
159
|
+
importFileEnd: new Date(),
|
|
133
160
|
inputFile: file,
|
|
134
|
-
fatalError: `FATAL: ${errorMessage}
|
|
161
|
+
fatalError: `FATAL: ${errorMessage}`,
|
|
162
|
+
partitions
|
|
135
163
|
})
|
|
136
164
|
|
|
137
165
|
readStream.destroy()
|
|
@@ -154,8 +182,11 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
154
182
|
countImported,
|
|
155
183
|
countFailed,
|
|
156
184
|
countSkipped,
|
|
185
|
+
importFileStart,
|
|
186
|
+
importFileEnd: new Date(),
|
|
157
187
|
executionTime: this.getExecutionTime(hrstart),
|
|
158
|
-
inputFile: file
|
|
188
|
+
inputFile: file,
|
|
189
|
+
partitions
|
|
159
190
|
})
|
|
160
191
|
}
|
|
161
192
|
|
|
@@ -181,10 +212,13 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
181
212
|
|
|
182
213
|
if (rows.length > 0) {
|
|
183
214
|
const packet = {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
215
|
+
type: 'importCsvRow',
|
|
216
|
+
payload: {
|
|
217
|
+
csvRow: rows[0],
|
|
218
|
+
csvType,
|
|
219
|
+
lineNumber,
|
|
220
|
+
importProcess
|
|
221
|
+
}
|
|
188
222
|
}
|
|
189
223
|
socket.send(JSON.stringify(packet))
|
|
190
224
|
} else {
|
|
@@ -209,13 +243,13 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
209
243
|
|
|
210
244
|
switch (type) {
|
|
211
245
|
case 'importRowSuccess':
|
|
212
|
-
importRowSuccess()
|
|
246
|
+
importRowSuccess(payload.csvRow)
|
|
213
247
|
break
|
|
214
248
|
case 'importRowError':
|
|
215
249
|
importRowError(payload.csvRow)
|
|
216
250
|
break
|
|
217
251
|
case 'importRowFatal':
|
|
218
|
-
importFatal(payload.error)
|
|
252
|
+
importFatal(payload.csvRow, payload.error)
|
|
219
253
|
break
|
|
220
254
|
default:
|
|
221
255
|
break
|
|
@@ -227,10 +261,22 @@ exports.importCsvFromFile = (file, csvType, outputDir, spinner, ws, delimiter =
|
|
|
227
261
|
})
|
|
228
262
|
})
|
|
229
263
|
|
|
230
|
-
exports.
|
|
264
|
+
exports.sendImportErrorMail = (ws, importProcess, csvReport) => {
|
|
265
|
+
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
266
|
+
|
|
267
|
+
socket.on('open', () => {
|
|
268
|
+
socket.send(
|
|
269
|
+
JSON.stringify({
|
|
270
|
+
type: 'sendImportErrorMail',
|
|
271
|
+
payload: { csvReport, importProcess }
|
|
272
|
+
})
|
|
273
|
+
)
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess) =>
|
|
231
278
|
new Promise(resolve => {
|
|
232
279
|
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
233
|
-
|
|
234
280
|
const hrstart = process.hrtime()
|
|
235
281
|
|
|
236
282
|
let readStream = null
|
|
@@ -268,9 +314,12 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';') =>
|
|
|
268
314
|
})
|
|
269
315
|
|
|
270
316
|
const packet = {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
317
|
+
type: 'validateCsvHeaderRequest',
|
|
318
|
+
payload: {
|
|
319
|
+
csvColumns: Object.keys(rows[0]),
|
|
320
|
+
csvType,
|
|
321
|
+
importProcess
|
|
322
|
+
}
|
|
274
323
|
}
|
|
275
324
|
|
|
276
325
|
socket.send(JSON.stringify(packet))
|
|
@@ -324,15 +373,15 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';') =>
|
|
|
324
373
|
})
|
|
325
374
|
})
|
|
326
375
|
|
|
327
|
-
exports.importCsvFromUrl = async (url, csvType, outputDir, spinner, ws) => {
|
|
376
|
+
exports.importCsvFromUrl = async (url, csvType, outputDir, importProcess, spinner, ws) => {
|
|
328
377
|
spinner.start('Downloading file...')
|
|
329
|
-
const
|
|
378
|
+
const file = await this.download(url, outputDir, `${csvType}.csv`)
|
|
330
379
|
spinner.succeed('Downloaded file')
|
|
331
|
-
return this.importCsvFromFile(
|
|
380
|
+
return this.importCsvFromFile({ file, csvType, outputDir, spinner, ws, importProcess })
|
|
332
381
|
}
|
|
333
382
|
|
|
334
|
-
exports.getExecutionTime =
|
|
335
|
-
const hrend = process.hrtime(
|
|
383
|
+
exports.getExecutionTime = importProcessStart => {
|
|
384
|
+
const hrend = process.hrtime(importProcessStart)
|
|
336
385
|
return ((hrend[0] * 1e9 + hrend[1]) / 1e9).toFixed(1)
|
|
337
386
|
}
|
|
338
387
|
|
|
@@ -419,7 +468,7 @@ exports.colorGreaterThanZero = (value, color) => {
|
|
|
419
468
|
return value
|
|
420
469
|
}
|
|
421
470
|
|
|
422
|
-
exports.refreshOrders = (spinner, ws) =>
|
|
471
|
+
exports.refreshOrders = (spinner, ws, importProcess) =>
|
|
423
472
|
new Promise(resolve => {
|
|
424
473
|
const hrstart = process.hrtime()
|
|
425
474
|
|
|
@@ -428,7 +477,7 @@ exports.refreshOrders = (spinner, ws) =>
|
|
|
428
477
|
spinner.start('Refreshing draft orders...')
|
|
429
478
|
|
|
430
479
|
socket.on('open', () => {
|
|
431
|
-
socket.send(JSON.stringify({ type: 'refreshDraftOrdersRequest' }))
|
|
480
|
+
socket.send(JSON.stringify({ type: 'refreshDraftOrdersRequest', payload: { importProcess } }))
|
|
432
481
|
})
|
|
433
482
|
|
|
434
483
|
socket.on('message', packet => {
|
|
@@ -444,6 +493,7 @@ exports.refreshOrders = (spinner, ws) =>
|
|
|
444
493
|
totalCount: payload.totalCount,
|
|
445
494
|
refreshed: payload.refreshed,
|
|
446
495
|
errored: payload.errored,
|
|
496
|
+
name: importProcess.name,
|
|
447
497
|
executionTime: this.getExecutionTime(hrstart)
|
|
448
498
|
})
|
|
449
499
|
break
|
|
@@ -476,20 +526,25 @@ exports.printRefreshedOrders = ({ refreshed, errored, executionTime }) => {
|
|
|
476
526
|
return message
|
|
477
527
|
}
|
|
478
528
|
|
|
479
|
-
exports.
|
|
529
|
+
exports.deleteRowsBeforeImportDate = (importProcess, partitionsForCsvType, spinner, ws) =>
|
|
480
530
|
new Promise(resolve => {
|
|
481
531
|
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
482
532
|
|
|
483
|
-
spinner.start('Deleting database records...')
|
|
533
|
+
spinner.start('Deleting old database records for chosen partitions...')
|
|
484
534
|
|
|
485
535
|
socket.on('open', () => {
|
|
486
|
-
socket.send(
|
|
536
|
+
socket.send(
|
|
537
|
+
JSON.stringify({
|
|
538
|
+
type: 'deleteRowsBeforeImportDateRequest',
|
|
539
|
+
payload: { importProcess, partitionsForCsvType }
|
|
540
|
+
})
|
|
541
|
+
)
|
|
487
542
|
})
|
|
488
543
|
|
|
489
544
|
socket.on('message', packet => {
|
|
490
545
|
const { type } = JSON.parse(packet)
|
|
491
546
|
switch (type) {
|
|
492
|
-
case '
|
|
547
|
+
case 'deleteRowsBeforeImportDateResponse': {
|
|
493
548
|
spinner.succeed('Database records deleted (soft)')
|
|
494
549
|
resolve()
|
|
495
550
|
break
|
|
@@ -530,14 +585,16 @@ exports.download = async (url, destPath, fileName) =>
|
|
|
530
585
|
downloadStream.pipe(fileWriterStream)
|
|
531
586
|
})
|
|
532
587
|
|
|
533
|
-
exports.callBeforeDataImportProcess = (spinner, ws) =>
|
|
588
|
+
exports.callBeforeDataImportProcess = (spinner, ws, importProcess) =>
|
|
534
589
|
new Promise((resolve, reject) => {
|
|
535
590
|
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
536
591
|
|
|
537
592
|
spinner.start('Executing tasks before start...')
|
|
538
593
|
|
|
539
594
|
socket.on('open', () => {
|
|
540
|
-
socket.send(
|
|
595
|
+
socket.send(
|
|
596
|
+
JSON.stringify({ type: 'callBeforeDataImportProcessRequest', payload: { importProcess } })
|
|
597
|
+
)
|
|
541
598
|
})
|
|
542
599
|
|
|
543
600
|
socket.on('message', packet => {
|
|
@@ -563,14 +620,16 @@ exports.callBeforeDataImportProcess = (spinner, ws) =>
|
|
|
563
620
|
})
|
|
564
621
|
})
|
|
565
622
|
|
|
566
|
-
exports.callAfterDataImportProcess = (spinner, ws,
|
|
623
|
+
exports.callAfterDataImportProcess = (spinner, ws, importProcess) =>
|
|
567
624
|
new Promise(resolve => {
|
|
568
625
|
const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
|
|
569
626
|
|
|
570
627
|
spinner.start('Executing tasks after the end process...')
|
|
571
628
|
|
|
572
629
|
socket.on('open', () => {
|
|
573
|
-
socket.send(
|
|
630
|
+
socket.send(
|
|
631
|
+
JSON.stringify({ type: 'callAfterDataImportProcessRequest', payload: { importProcess } })
|
|
632
|
+
)
|
|
574
633
|
})
|
|
575
634
|
|
|
576
635
|
socket.on('message', packet => {
|
|
@@ -725,7 +784,7 @@ exports.flushMedia = (spinner, ws) =>
|
|
|
725
784
|
|
|
726
785
|
exports.getArchiveFolder = instanceEndpoint => {
|
|
727
786
|
const prefix = 'closer'
|
|
728
|
-
const instance = slugify(instanceEndpoint.split('/')[0]
|
|
787
|
+
const instance = slugify(instanceEndpoint.split('/')[0], { lower: true })
|
|
729
788
|
const ts = getTimestampForFilename()
|
|
730
789
|
return `${prefix}_${instance}/${ts}`
|
|
731
790
|
}
|
package/index.js
CHANGED
|
@@ -22,5 +22,11 @@ require('yargs/yargs')(process.argv.slice(2))
|
|
|
22
22
|
describe: 'Admin Secret for Closer',
|
|
23
23
|
demandOption: true
|
|
24
24
|
})
|
|
25
|
+
.option('n', {
|
|
26
|
+
alias: 'name',
|
|
27
|
+
describe: 'Attach string name label to import process',
|
|
28
|
+
type: 'string',
|
|
29
|
+
demandOption: true
|
|
30
|
+
})
|
|
25
31
|
.help()
|
|
26
32
|
.version().argv
|
package/package.json
CHANGED
package/cmds/exportData.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
/* eslint-disable no-await-in-loop */
|
|
3
|
-
/* eslint-disable no-restricted-syntax */
|
|
4
|
-
|
|
5
|
-
const chalk = require('chalk')
|
|
6
|
-
const Ora = require('ora')
|
|
7
|
-
const prompts = require('prompts')
|
|
8
|
-
const { ALLOWED_CSV_FILES, exportCsv } = require('../helpers')
|
|
9
|
-
|
|
10
|
-
exports.command = 'export:data'
|
|
11
|
-
exports.desc = 'Export data from Closer'
|
|
12
|
-
|
|
13
|
-
exports.builder = yargs => {
|
|
14
|
-
yargs.usage(`Usage: ${chalk.cyan('$0 export:data')} [options]`)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
exports.handler = async argv => {
|
|
18
|
-
const interactive = !argv.nonInteractive
|
|
19
|
-
|
|
20
|
-
const csvChoices = Object.keys(ALLOWED_CSV_FILES).map(csvType => ({
|
|
21
|
-
title: csvType,
|
|
22
|
-
csvType,
|
|
23
|
-
value: csvType
|
|
24
|
-
}))
|
|
25
|
-
|
|
26
|
-
let csvTypes
|
|
27
|
-
if (interactive && !argv.type) {
|
|
28
|
-
const answers = await prompts(
|
|
29
|
-
[
|
|
30
|
-
{
|
|
31
|
-
instructions: false,
|
|
32
|
-
name: 'csvTypes',
|
|
33
|
-
type: 'multiselect',
|
|
34
|
-
message: 'Select CSV type',
|
|
35
|
-
choices: csvChoices,
|
|
36
|
-
min: 1
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
{ onCancel: () => process.exit() }
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
csvTypes = answers.csvTypes
|
|
43
|
-
} else {
|
|
44
|
-
csvTypes = argv.type.map(type => {
|
|
45
|
-
const choice = csvChoices.find(csvChoice => csvChoice.csvType === type)
|
|
46
|
-
return choice.value
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const spinner = new Ora()
|
|
51
|
-
// const hrstart = process.hrtime()
|
|
52
|
-
|
|
53
|
-
const ws = {
|
|
54
|
-
endpoint: argv.endpoint,
|
|
55
|
-
adminSecret: argv['admin-secret']
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (interactive) {
|
|
59
|
-
console.log('')
|
|
60
|
-
const { confirmed } = await prompts(
|
|
61
|
-
[
|
|
62
|
-
{
|
|
63
|
-
type: 'confirm',
|
|
64
|
-
name: 'confirmed',
|
|
65
|
-
message: 'Continue?',
|
|
66
|
-
initial: false
|
|
67
|
-
}
|
|
68
|
-
],
|
|
69
|
-
{ onCancel: () => process.exit() }
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
if (!confirmed) {
|
|
73
|
-
process.exit()
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log('')
|
|
78
|
-
|
|
79
|
-
for (const csvType of csvTypes) {
|
|
80
|
-
await exportCsv(csvType, argv.out, spinner, ws, argv.csvDelimiter)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
process.exit()
|
|
84
|
-
}
|