closer-cli 2.33.0 → 2.37.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/.eslintrc.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "rules": {
3
+ "semi": "off",
4
+ "comma-dangle": "off",
5
+ "arrow-parens": "off",
6
+ "no-use-before-define": "off",
7
+ "object-curly-newline": "off",
8
+ "import/prefer-default-export": "off",
9
+ "operator-linebreak": "off",
10
+ "import/extensions": "off"
11
+ },
12
+ "parserOptions": {
13
+ "ecmaVersion": 2020
14
+ }
15
+ }
package/CHANGELOG.md CHANGED
@@ -3,6 +3,55 @@
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.37.0](https://code.hfarm.dev/closer/closer/compare/v2.36.1...v2.37.0) (2022-11-14)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **PJX-621:** Fine tuning report mail ([719ce9c](https://code.hfarm.dev/closer/closer/commits/719ce9cf5f6e78db4deeb452a0974ed4877c07dc))
12
+
13
+
14
+
15
+
16
+
17
+ ## [2.36.1](https://code.hfarm.dev/closer/closer/compare/v2.36.0...v2.36.1) (2022-11-09)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **PJX-619:** Import: link csv file inviati via mail non corrispondono ([af27d64](https://code.hfarm.dev/closer/closer/commits/af27d64b49145014d46afce1786ba72a3c78ebe3))
23
+
24
+
25
+
26
+
27
+
28
+ # [2.36.0](https://code.hfarm.dev/closer/closer/compare/v2.35.0...v2.36.0) (2022-11-09)
29
+
30
+
31
+ ### Features
32
+
33
+ * **PJX-560:** AdminJS R&D ([dbfa216](https://code.hfarm.dev/closer/closer/commits/dbfa2165f4d05475c32b4e750bee205d77180643))
34
+
35
+
36
+
37
+
38
+
39
+ # [2.35.0](https://code.hfarm.dev/closer/closer/compare/v2.34.0...v2.35.0) (2022-11-04)
40
+
41
+ **Note:** Version bump only for package closer-cli
42
+
43
+
44
+
45
+
46
+
47
+ # [2.34.0](https://code.hfarm.dev/closer/closer/compare/v2.33.2...v2.34.0) (2022-11-04)
48
+
49
+ **Note:** Version bump only for package closer-cli
50
+
51
+
52
+
53
+
54
+
6
55
  # [2.33.0](https://code.hfarm.dev/closer/closer/compare/v2.32.3...v2.33.0) (2022-10-27)
7
56
 
8
57
 
@@ -1,11 +1,13 @@
1
- const { ALLOWED_CSV_FILES } = require('../helpers')
1
+ import { ALLOWED_CSV_FILES, getHumanTimestamp } from '../helpers.js'
2
+ import * as ImportDataMultipleCmd from './importData_cmds/multiple.js'
3
+ import * as ImportDataSingleCmd from './importData_cmds/single.js'
2
4
 
3
- exports.command = 'import:data <command>'
4
- exports.desc = 'Import CSV data to Closer'
5
+ export const command = 'import:data <command>'
6
+ export const desc = 'Import CSV data to Closer'
5
7
 
6
- exports.builder = yargs => {
8
+ export function builder(yargs) {
7
9
  yargs
8
- .commandDir('importData_cmds')
10
+ // .commandDir('importData_cmds')
9
11
  .option('type', {
10
12
  alias: 't',
11
13
  describe: 'CSV type to consider during import',
@@ -35,7 +37,25 @@ exports.builder = yargs => {
35
37
  type: 'string',
36
38
  default: ';'
37
39
  })
40
+ .option('n', {
41
+ alias: 'name',
42
+ describe: 'Define import process name',
43
+ type: 'string',
44
+ default: getHumanTimestamp(new Date())
45
+ })
38
46
  .implies('non-interactive', ['type', 'mode'])
47
+ .command(
48
+ ImportDataMultipleCmd.command,
49
+ ImportDataMultipleCmd.desc,
50
+ ImportDataMultipleCmd.builder,
51
+ ImportDataMultipleCmd.handler
52
+ )
53
+ .command(
54
+ ImportDataSingleCmd.command,
55
+ ImportDataSingleCmd.desc,
56
+ ImportDataSingleCmd.builder,
57
+ ImportDataSingleCmd.handler
58
+ )
39
59
  }
40
60
 
41
- exports.handler = () => {}
61
+ export function handler() {}
@@ -1,13 +1,16 @@
1
1
  /* eslint-disable no-console */
2
2
  /* eslint-disable no-await-in-loop */
3
3
  /* eslint-disable no-restricted-syntax */
4
- const fs = require('fs')
5
- const path = require('path')
6
- const chalk = require('chalk')
7
- const prompts = require('prompts')
8
- const Ora = require('ora')
9
-
10
- const {
4
+ import { accessSync, constants, existsSync, mkdirSync } from 'fs'
5
+ import path from 'path'
6
+ import chalk from 'chalk'
7
+ import prompts from 'prompts'
8
+ import Ora from 'ora'
9
+ import move from 'mv'
10
+ import { promisify } from 'util'
11
+ import { deleteAsync } from 'del'
12
+
13
+ import {
11
14
  getCsvFilesFromDir,
12
15
  ALLOWED_CSV_FILES,
13
16
  getGoogleSheetCsvUrl,
@@ -19,18 +22,20 @@ const {
19
22
  callAfterDataImportProcess,
20
23
  getExecutionTime,
21
24
  getArchiveFolder,
22
- renameWithTimestamp,
23
25
  sendImportErrorMail,
24
- deleteRowsBeforeImportDate
25
- } = require('../../helpers')
26
+ deleteRowsBeforeImportDate,
27
+ readImportDir
28
+ } from '../../helpers.js'
29
+
30
+ const mv = promisify(move)
26
31
 
27
- exports.command = 'multiple [options]'
32
+ export const command = 'multiple [options]'
28
33
 
29
- exports.desc = 'Import different CSV files'
34
+ export const desc = 'Import different CSV files'
30
35
 
31
- exports.builder = yargs => {
36
+ export function builder(yargs) {
32
37
  yargs
33
- .usage(`Usage: ${chalk.cyan('$0 import multiple')} [options]`)
38
+ .usage(`Usage: ${chalk.cyan('$0 import:data multiple')} [options]`)
34
39
  .option('fromDir', {
35
40
  alias: 'd',
36
41
  describe: 'Directory path that contains files to import',
@@ -48,18 +53,20 @@ exports.builder = yargs => {
48
53
  }
49
54
 
50
55
  if (argv.fromDir) {
51
- fs.accessSync(argv.fromDir, fs.constants.F_OK)
56
+ accessSync(argv.fromDir, constants.F_OK)
52
57
  }
53
58
 
54
59
  return true
55
60
  })
56
61
  }
57
62
 
58
- exports.handler = async argv => {
63
+ export async function handler(argv) {
59
64
  // eslint-disable-next-line no-param-reassign
60
65
  argv.out = argv.out || getArchiveFolder(argv.endpoint)
61
66
 
67
+ const spinner = new Ora()
62
68
  const hrstart = process.hrtime()
69
+
63
70
  const importProcess = {
64
71
  importProcessStart: new Date(),
65
72
  importProcessEnd: null,
@@ -71,8 +78,17 @@ exports.handler = async argv => {
71
78
  result: []
72
79
  }
73
80
 
81
+ const dirPathTemp = path.resolve(argv.out, `${importProcess.name}_temp`)
82
+ const dirPathFinal = path.resolve(argv.out, importProcess.name)
83
+ const dirPathOriginal = path.resolve(dirPathTemp, '_original')
84
+
74
85
  const interactive = !argv.nonInteractive
75
86
 
87
+ const ws = {
88
+ endpoint: argv.endpoint,
89
+ secret: argv.secret
90
+ }
91
+
76
92
  let csvChoices = []
77
93
 
78
94
  if (argv.fromDir) {
@@ -157,27 +173,39 @@ exports.handler = async argv => {
157
173
 
158
174
  importProcess.mode = mode
159
175
 
160
- const spinner = new Ora()
161
-
162
176
  const validations = []
163
177
  const csvReports = []
164
178
 
165
- const ws = {
166
- endpoint: argv.endpoint,
167
- adminSecret: argv['admin-secret']
168
- }
169
-
170
179
  let parsedFiles = [...files]
171
180
 
181
+ if (!existsSync(dirPathFinal) && !existsSync(dirPathOriginal)) {
182
+ mkdirSync(dirPathOriginal, { recursive: true })
183
+ } else {
184
+ console.log('')
185
+ console.log(`ERROR => directory "${dirPathFinal}" already exists, change the import name.`)
186
+ process.exit(1)
187
+ }
188
+
172
189
  if (argv.fromGoogleDocId) {
173
190
  parsedFiles = []
174
191
  console.log('')
175
192
  spinner.start('Downloading Google sheets...')
176
193
  for (const item of files) {
177
- const filepath = await download(item.url, argv.out, `${item.csvType}.csv`)
194
+ const filepath = await download(
195
+ item.url,
196
+ dirPathOriginal,
197
+ `${importProcess.name}_${item.csvType}.csv`
198
+ )
178
199
  parsedFiles.push({ file: filepath, csvType: item.csvType })
179
200
  }
180
201
  spinner.succeed('Google sheets downloaded')
202
+ } else {
203
+ for (const file of files) {
204
+ parsedFiles = []
205
+ const dst = path.resolve(dirPathOriginal, `${importProcess.name}_${file.csvType}.csv`)
206
+ await mv(file.file, dst)
207
+ parsedFiles.push({ file: dst, csvType: file.csvType })
208
+ }
181
209
  }
182
210
 
183
211
  //
@@ -242,7 +270,7 @@ exports.handler = async argv => {
242
270
  const csvReport = await importCsvFromFile({
243
271
  file: item.file,
244
272
  csvType: item.csvType,
245
- outputDir: argv.out,
273
+ outputDir: dirPathTemp,
246
274
  spinner,
247
275
  ws,
248
276
  delimiter: argv.csvDelimiter,
@@ -268,7 +296,7 @@ exports.handler = async argv => {
268
296
  }
269
297
 
270
298
  //
271
- // Refresh Orders of type Draft
299
+ // Refresh Orders of type Draft, Template
272
300
  //
273
301
  // eslint-disable-next-line no-unused-vars
274
302
  const refreshedOrders = await refreshOrders(spinner, ws, importProcess)
@@ -298,7 +326,18 @@ exports.handler = async argv => {
298
326
 
299
327
  await callAfterDataImportProcess(spinner, ws, importProcess)
300
328
 
301
- await renameWithTimestamp(argv.out)
329
+ await deleteAsync(path.resolve(dirPathTemp, '_processing'))
330
+
331
+ const reportFiles = await readImportDir(dirPathTemp)
332
+
333
+ for (const reportFile of reportFiles) {
334
+ const { filename, size } = reportFile
335
+ if ((filename.includes('skipped') || filename.includes('errors')) && size === 0) {
336
+ await deleteAsync(path.resolve(dirPathTemp, filename))
337
+ }
338
+ }
339
+
340
+ await mv(dirPathTemp, dirPathFinal)
302
341
 
303
342
  process.exit()
304
343
  }
@@ -1,31 +1,39 @@
1
- /* eslint-disable no-restricted-syntax */
2
1
  /* eslint-disable no-console */
3
- const fs = require('fs')
4
- const chalk = require('chalk')
5
-
6
- const Ora = require('ora')
7
- const prompts = require('prompts')
8
- const {
2
+ /* eslint-disable no-await-in-loop */
3
+ /* eslint-disable no-restricted-syntax */
4
+ import { accessSync, constants, existsSync, mkdirSync } from 'fs'
5
+ import path from 'path'
6
+ import chalk from 'chalk'
7
+ import prompts from 'prompts'
8
+ import Ora from 'ora'
9
+ import move from 'mv'
10
+ import { promisify } from 'util'
11
+ import { deleteAsync } from 'del'
12
+
13
+ import {
14
+ ALLOWED_CSV_FILES,
9
15
  importCsvFromFile,
10
- getExecutionTime,
16
+ validateCsvFromFile,
11
17
  refreshOrders,
12
- callAfterDataImportProcess,
13
- callBeforeDataImportProcess,
14
- ALLOWED_CSV_FILES,
15
18
  download,
16
- validateCsvFromFile,
19
+ callBeforeDataImportProcess,
20
+ callAfterDataImportProcess,
21
+ getExecutionTime,
17
22
  getArchiveFolder,
18
- renameWithTimestamp,
19
- sendImportErrorMail
20
- } = require('../../helpers')
23
+ sendImportErrorMail,
24
+ deleteRowsBeforeImportDate,
25
+ readImportDir
26
+ } from '../../helpers.js'
27
+
28
+ const mv = promisify(move)
21
29
 
22
- exports.command = 'single [options]'
30
+ export const command = 'single [options]'
23
31
 
24
- exports.desc = 'Import only one CSV file'
32
+ export const desc = 'Import only one CSV file'
25
33
 
26
- exports.builder = yargs => {
34
+ export function builder(yargs) {
27
35
  yargs
28
- .usage(`Usage: ${chalk.cyan('$0 import single')} [options]`)
36
+ .usage(`Usage: ${chalk.cyan('$0 import:data single')} [options]`)
29
37
  .option('fromFile', {
30
38
  alias: 'f',
31
39
  describe: 'File to import',
@@ -43,14 +51,14 @@ exports.builder = yargs => {
43
51
  }
44
52
 
45
53
  if (argv.fromFile) {
46
- fs.accessSync(argv.fromFile, fs.constants.F_OK)
54
+ accessSync(argv.fromFile, constants.F_OK)
47
55
  }
48
56
 
49
57
  return true
50
58
  })
51
59
  }
52
60
 
53
- exports.handler = async argv => {
61
+ export async function handler(argv) {
54
62
  // eslint-disable-next-line no-param-reassign
55
63
  argv.out = argv.out || getArchiveFolder(argv.endpoint)
56
64
 
@@ -68,13 +76,17 @@ exports.handler = async argv => {
68
76
  result: []
69
77
  }
70
78
 
79
+ const dirPathTemp = path.resolve(argv.out, `${importProcess.name}_temp`)
80
+ const dirPathFinal = path.resolve(argv.out, importProcess.name)
81
+ const dirPathOriginal = path.resolve(dirPathTemp, '_original')
82
+
83
+ const interactive = !argv.nonInteractive
84
+
71
85
  const ws = {
72
86
  endpoint: argv.endpoint,
73
- adminSecret: argv['admin-secret']
87
+ secret: argv.secret
74
88
  }
75
89
 
76
- const interactive = !argv.nonInteractive
77
-
78
90
  let type
79
91
  if (interactive && !argv.type) {
80
92
  const answers = await prompts(
@@ -99,6 +111,8 @@ exports.handler = async argv => {
99
111
  type = argv.type[0]
100
112
  }
101
113
 
114
+ importProcess.type = [type]
115
+
102
116
  let mode
103
117
  if (interactive && !argv.mode) {
104
118
  const answers = await prompts(
@@ -129,6 +143,16 @@ exports.handler = async argv => {
129
143
  mode = argv.mode
130
144
  }
131
145
 
146
+ importProcess.mode = mode
147
+
148
+ if (!existsSync(dirPathFinal) && !existsSync(dirPathOriginal)) {
149
+ mkdirSync(dirPathOriginal, { recursive: true })
150
+ } else {
151
+ console.log('')
152
+ console.log(`ERROR => directory "${dirPathFinal}" already exists, change the import name.`)
153
+ process.exit(1)
154
+ }
155
+
132
156
  if (interactive) {
133
157
  console.log('')
134
158
  const { confirmed } = await prompts(
@@ -150,16 +174,19 @@ exports.handler = async argv => {
150
174
  console.log('')
151
175
  }
152
176
 
153
- let csvReport
154
-
155
- let filepath = argv.fromFile
177
+ let filepath = null
156
178
 
157
179
  if (argv.fromUrl) {
158
180
  spinner.start('Downloading file...')
159
- filepath = await download(argv.fromUrl, argv.out, `${type}.csv`)
181
+ filepath = await download(argv.fromUrl, dirPathOriginal, `${importProcess.name}_${type}.csv`)
160
182
  spinner.succeed('Downloaded file')
161
183
  }
162
184
 
185
+ if (argv.fromFile) {
186
+ filepath = path.resolve(dirPathOriginal, `${importProcess.name}_${type}.csv`)
187
+ await mv(argv.fromFile, filepath)
188
+ }
189
+
163
190
  const validation = await validateCsvFromFile(filepath, type, ws, argv.csvDelimiter, importProcess)
164
191
 
165
192
  if (validation.error) {
@@ -167,9 +194,6 @@ exports.handler = async argv => {
167
194
  process.exit(1)
168
195
  }
169
196
 
170
- importProcess.mode = mode
171
- importProcess.type = [type]
172
-
173
197
  //
174
198
  // Call ImportService.beforeImportProcess (import flag)
175
199
  //
@@ -181,25 +205,44 @@ exports.handler = async argv => {
181
205
  }
182
206
  }
183
207
 
184
- if (argv.fromFile) {
185
- csvReport = await importCsvFromFile({
186
- file: argv.fromFile,
187
- csvType: type,
188
- outputDir: argv.out,
208
+ const partitionsForCsvType = new Map()
209
+
210
+ const csvReport = await importCsvFromFile({
211
+ file: filepath,
212
+ csvType: type,
213
+ outputDir: dirPathTemp,
214
+ spinner,
215
+ ws,
216
+ delimiter: argv.csvDelimiter,
217
+ importProcess
218
+ })
219
+
220
+ if (csvReport.countFailed > 0 || csvReport.countSkipped > 0) {
221
+ sendImportErrorMail(ws, importProcess, csvReport)
222
+ }
223
+
224
+ partitionsForCsvType.set(csvReport.csvType, Array.from(csvReport.partitions))
225
+
226
+ //
227
+ // Import FULL?
228
+ //
229
+ if (mode === 'full') {
230
+ await deleteRowsBeforeImportDate(
231
+ importProcess,
232
+ Object.fromEntries(partitionsForCsvType),
189
233
  spinner,
190
- ws,
191
- delimiter: argv.csvDelimiter,
192
- importProcess
193
- })
194
- if (csvReport.countFailed > 0 || csvReport.countSkipped > 0) {
195
- sendImportErrorMail(ws, importProcess, csvReport)
196
- }
234
+ ws
235
+ )
197
236
  }
198
237
 
238
+ //
239
+ // Refresh Orders of type Draft, Template
240
+ //
241
+
199
242
  const refreshedOrders = await refreshOrders(spinner, ws, importProcess)
200
243
 
201
244
  //
202
- // Report
245
+ // importProcess
203
246
  //
204
247
 
205
248
  importProcess.importProcessEnd = new Date()
@@ -221,7 +264,18 @@ exports.handler = async argv => {
221
264
 
222
265
  await callAfterDataImportProcess(spinner, ws, importProcess)
223
266
 
224
- await renameWithTimestamp(argv.out)
267
+ await deleteAsync(path.resolve(dirPathTemp, '_processing'))
268
+
269
+ const reportFiles = await readImportDir(dirPathTemp)
270
+
271
+ for (const reportFile of reportFiles) {
272
+ const { filename, size } = reportFile
273
+ if ((filename.includes('skipped') || filename.includes('errors')) && size === 0) {
274
+ await deleteAsync(path.resolve(dirPathTemp, filename))
275
+ }
276
+ }
277
+
278
+ await mv(dirPathTemp, dirPathFinal)
225
279
 
226
280
  process.exit()
227
281
  }
@@ -1,16 +1,16 @@
1
- const chalk = require('chalk')
2
- const Ora = require('ora')
3
- const {
1
+ import chalk from 'chalk'
2
+ import Ora from 'ora'
3
+ import {
4
4
  importMedia,
5
5
  flushMedia,
6
6
  getExecutionTime,
7
7
  callAfterMediaImportProcess
8
- } = require('../helpers')
8
+ } from '../helpers.js'
9
9
 
10
- exports.command = 'import:media'
11
- exports.desc = 'Import media (images, 360, videos) to Closer'
10
+ export const command = 'import:media'
11
+ export const desc = 'Import media (images, 360, videos) to Closer'
12
12
 
13
- exports.builder = yargs => {
13
+ export function builder(yargs) {
14
14
  yargs
15
15
  .usage(`Usage: ${chalk.cyan('$0 import:media')} [options]`)
16
16
 
@@ -25,7 +25,7 @@ exports.builder = yargs => {
25
25
  })
26
26
  }
27
27
 
28
- exports.handler = async argv => {
28
+ export async function handler(argv) {
29
29
  const spinner = new Ora()
30
30
  const hrstart = process.hrtime()
31
31
 
@@ -41,11 +41,15 @@ exports.handler = async argv => {
41
41
 
42
42
  const ws = {
43
43
  endpoint: argv.endpoint,
44
- adminSecret: argv['admin-secret']
44
+ secret: argv.secret
45
45
  }
46
46
 
47
47
  if (argv.flush) {
48
- await flushMedia(spinner, ws)
48
+ try {
49
+ await flushMedia(spinner, ws)
50
+ } catch (e) {
51
+ process.exit(1)
52
+ }
49
53
  }
50
54
 
51
55
  const result = await importMedia(argv.reprocess, spinner, ws)
package/helpers.js CHANGED
@@ -1,27 +1,40 @@
1
1
  /* eslint-disable no-console */
2
2
  /* eslint-disable no-param-reassign */
3
3
  /* eslint-disable implicit-arrow-linebreak */
4
- const fs = require('fs')
5
- const path = require('path')
6
- const WebSocket = require('ws')
7
- const chalk = require('chalk')
8
- const es = require('event-stream')
9
- const { parse } = require('csv-parse/sync')
10
- const { stringify } = require('csv-stringify/sync')
11
- const got = require('got')
12
- const { createWriteStream } = require('fs')
13
- const slugify = require('slugify')
14
-
15
- exports.createSocketConnection = (endpoint, adminSecret) => {
4
+ import {
5
+ readdirSync,
6
+ existsSync,
7
+ mkdirSync,
8
+ copyFileSync,
9
+ createWriteStream,
10
+ createReadStream,
11
+ rename,
12
+ statSync
13
+ } from 'fs'
14
+ 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
+ import got from 'got'
20
+ import slugify from 'slugify'
21
+ import { deleteAsync } from 'del'
22
+ import eventStream from 'event-stream'
23
+
24
+ const { split, mapSync } = eventStream
25
+ const { stream } = got
26
+
27
+ export function createSocketConnection(endpoint, secret) {
16
28
  const protocol = endpoint.includes('localhost') || endpoint.includes('127.0.0.1') ? 'ws' : 'wss'
17
- const socket = new WebSocket(`${protocol}://${endpoint}/import`, {
18
- headers: { 'x-closer-admin-secret': adminSecret }
29
+ const url = `${protocol}://${endpoint}/import`
30
+ const socket = new WebSocket(url, {
31
+ headers: { 'x-closer-secret': secret }
19
32
  })
20
33
 
21
34
  return socket
22
35
  }
23
36
 
24
- exports.ALLOWED_CSV_FILES = {
37
+ export const ALLOWED_CSV_FILES = {
25
38
  product: 'products.csv',
26
39
  localizedProduct: 'localizedProducts.csv',
27
40
  localizedFilter: 'localizedFilters.csv',
@@ -40,15 +53,15 @@ exports.ALLOWED_CSV_FILES = {
40
53
  team: 'teams.csv'
41
54
  }
42
55
 
43
- const getCsvFilesFromDir = dir =>
44
- fs.readdirSync(dir).filter(file => path.extname(file).toLowerCase() === '.csv')
45
-
46
- exports.getCsvFilesFromDir = getCsvFilesFromDir
56
+ export function getCsvFilesFromDir(dir) {
57
+ return readdirSync(dir).filter(file => path.extname(file).toLowerCase() === '.csv')
58
+ }
47
59
 
48
- exports.getGoogleSheetCsvUrl = (docId, sheet) =>
49
- `https://docs.google.com/spreadsheets/d/${docId}/gviz/tq?tqx=out:csv&sheet=${sheet}`
60
+ export function getGoogleSheetCsvUrl(docId, sheet) {
61
+ return `https://docs.google.com/spreadsheets/d/${docId}/gviz/tq?tqx=out:csv&sheet=${sheet}`
62
+ }
50
63
 
51
- exports.importCsvFromFile = ({
64
+ export function importCsvFromFile({
52
65
  file,
53
66
  csvType,
54
67
  outputDir,
@@ -56,27 +69,31 @@ exports.importCsvFromFile = ({
56
69
  ws,
57
70
  delimiter = ';',
58
71
  importProcess
59
- }) =>
60
- new Promise(resolve => {
61
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
72
+ }) {
73
+ return new Promise(resolve => {
74
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
62
75
 
63
76
  const hrstart = process.hrtime()
64
77
  const importFileStart = new Date()
65
78
 
66
79
  let readStream = null
67
80
 
68
- if (!fs.existsSync(outputDir)) {
69
- fs.mkdirSync(outputDir, { recursive: true })
81
+ const dirPathProcessing = path.resolve(outputDir, '_processing')
82
+
83
+ if (!existsSync(dirPathProcessing)) {
84
+ mkdirSync(dirPathProcessing, { recursive: true })
70
85
  }
71
86
 
72
87
  const filename = path.basename(file)
73
- fs.copyFileSync(file, path.resolve(outputDir, filename))
88
+ const filepath = path.resolve(dirPathProcessing, filename)
74
89
 
75
- const errorCsvFile = path.resolve(outputDir, `${csvType}_errors.csv`)
76
- const errorFileStream = fs.createWriteStream(errorCsvFile)
90
+ copyFileSync(file, filepath)
77
91
 
78
- const skippedCsvFile = path.resolve(outputDir, `${csvType}_skipped.csv`)
79
- const skippedFileStream = fs.createWriteStream(skippedCsvFile)
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)
80
97
 
81
98
  let header = ''
82
99
  let lineNumber = 0
@@ -92,14 +109,14 @@ exports.importCsvFromFile = ({
92
109
 
93
110
  countImported += 1
94
111
 
95
- spinner.text = this.printImportProcessResult({
112
+ spinner.text = printImportProcessResult({
96
113
  csvType,
97
114
  countImported,
98
115
  countFailed,
99
116
  countSkipped,
100
117
  importFileStart,
101
118
  importFileEnd: new Date(),
102
- executionTime: this.getExecutionTime(hrstart),
119
+ executionTime: getExecutionTime(hrstart),
103
120
  name: filename
104
121
  })
105
122
 
@@ -111,14 +128,14 @@ exports.importCsvFromFile = ({
111
128
 
112
129
  countFailed += 1
113
130
 
114
- spinner.text = this.printImportProcessResult({
131
+ spinner.text = printImportProcessResult({
115
132
  csvType,
116
133
  countImported,
117
134
  countFailed,
118
135
  countSkipped,
119
136
  importFileStart,
120
137
  importFileEnd: new Date(),
121
- executionTime: this.getExecutionTime(hrstart),
138
+ executionTime: getExecutionTime(hrstart),
122
139
  name: filename
123
140
  })
124
141
 
@@ -137,14 +154,14 @@ exports.importCsvFromFile = ({
137
154
  partitions.add(csvRow.Partition || '')
138
155
 
139
156
  spinner.fail(
140
- this.printImportProcessResult({
157
+ printImportProcessResult({
141
158
  csvType,
142
159
  countImported,
143
160
  countFailed,
144
161
  countSkipped,
145
162
  importFileStart,
146
163
  importFileEnd: new Date(),
147
- executionTime: this.getExecutionTime(hrstart),
164
+ executionTime: getExecutionTime(hrstart),
148
165
  name: filename,
149
166
  fatalError: errorMessage
150
167
  })
@@ -155,7 +172,7 @@ exports.importCsvFromFile = ({
155
172
  countImported,
156
173
  countFailed,
157
174
  countSkipped,
158
- executionTime: this.getExecutionTime(hrstart),
175
+ executionTime: getExecutionTime(hrstart),
159
176
  importFileStart,
160
177
  importFileEnd: new Date(),
161
178
  inputFile: file,
@@ -178,6 +195,8 @@ exports.importCsvFromFile = ({
178
195
  errorFileStream.end()
179
196
  skippedFileStream.end()
180
197
 
198
+ deleteAsync(filepath)
199
+
181
200
  resolve({
182
201
  csvType,
183
202
  countImported,
@@ -185,18 +204,17 @@ exports.importCsvFromFile = ({
185
204
  countSkipped,
186
205
  importFileStart,
187
206
  importFileEnd: new Date(),
188
- executionTime: this.getExecutionTime(hrstart),
207
+ executionTime: getExecutionTime(hrstart),
189
208
  inputFile: file,
190
209
  partitions
191
210
  })
192
211
  }
193
212
 
194
213
  socket.on('open', () => {
195
- readStream = fs
196
- .createReadStream(file)
197
- .pipe(es.split())
214
+ readStream = createReadStream(file)
215
+ .pipe(split())
198
216
  .pipe(
199
- es.mapSync(line => {
217
+ mapSync(line => {
200
218
  readStream.pause()
201
219
 
202
220
  if (lineNumber === 0) {
@@ -261,9 +279,10 @@ exports.importCsvFromFile = ({
261
279
  importFatal(e.message)
262
280
  })
263
281
  })
282
+ }
264
283
 
265
- exports.sendImportErrorMail = (ws, importProcess, csvReport) => {
266
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
284
+ export function sendImportErrorMail(ws, importProcess, csvReport) {
285
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
267
286
 
268
287
  socket.on('open', () => {
269
288
  socket.send(
@@ -275,9 +294,9 @@ exports.sendImportErrorMail = (ws, importProcess, csvReport) => {
275
294
  })
276
295
  }
277
296
 
278
- exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess) =>
279
- new Promise(resolve => {
280
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
297
+ export function validateCsvFromFile(file, csvType, ws, delimiter, importProcess) {
298
+ return new Promise(resolve => {
299
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
281
300
  const hrstart = process.hrtime()
282
301
 
283
302
  let readStream = null
@@ -287,11 +306,10 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess
287
306
  const filename = path.basename(file)
288
307
 
289
308
  socket.on('open', () => {
290
- readStream = fs
291
- .createReadStream(file)
292
- .pipe(es.split())
309
+ readStream = createReadStream(file)
310
+ .pipe(split())
293
311
  .pipe(
294
- es.mapSync(line => {
312
+ mapSync(line => {
295
313
  readStream.pause()
296
314
 
297
315
  if (lineNumber === 0) {
@@ -303,7 +321,7 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess
303
321
  if (line === '') {
304
322
  resolve({
305
323
  csvType,
306
- executionTime: this.getExecutionTime(hrstart),
324
+ executionTime: getExecutionTime(hrstart),
307
325
  inputFile: filename
308
326
  })
309
327
  } else {
@@ -335,7 +353,7 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess
335
353
  .on('error', e => {
336
354
  resolve({
337
355
  csvType,
338
- executionTime: this.getExecutionTime(hrstart),
356
+ executionTime: getExecutionTime(hrstart),
339
357
  inputFile: filename,
340
358
  error: e.message
341
359
  })
@@ -348,7 +366,7 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess
348
366
  case 'validateCsvHeaderResponse': {
349
367
  const result = {
350
368
  csvType,
351
- executionTime: this.getExecutionTime(hrstart),
369
+ executionTime: getExecutionTime(hrstart),
352
370
  inputFile: filename
353
371
  }
354
372
 
@@ -367,38 +385,32 @@ exports.validateCsvFromFile = (file, csvType, ws, delimiter = ';', importProcess
367
385
  socket.on('error', e => {
368
386
  resolve({
369
387
  csvType,
370
- executionTime: this.getExecutionTime(hrstart),
388
+ executionTime: getExecutionTime(hrstart),
371
389
  inputFile: file,
372
390
  error: e.message
373
391
  })
374
392
  })
375
393
  })
376
-
377
- exports.importCsvFromUrl = async (url, csvType, outputDir, importProcess, spinner, ws) => {
378
- spinner.start('Downloading file...')
379
- const file = await this.download(url, outputDir, `${csvType}.csv`)
380
- spinner.succeed('Downloaded file')
381
- return this.importCsvFromFile({ file, csvType, outputDir, spinner, ws, importProcess })
382
394
  }
383
395
 
384
- exports.getExecutionTime = importProcessStart => {
396
+ export function getExecutionTime(importProcessStart) {
385
397
  const hrend = process.hrtime(importProcessStart)
386
398
  return ((hrend[0] * 1e9 + hrend[1]) / 1e9).toFixed(1)
387
399
  }
388
400
 
389
- exports.printValidationProcessHeader = () => {
401
+ export function printValidationProcessHeader() {
390
402
  console.log('\n=== Validation Process Result ===\n')
391
403
  }
392
404
 
393
- exports.printImportProcessHeader = () => {
405
+ export function printImportProcessHeader() {
394
406
  console.log('\n=== Import Process Result ===\n')
395
407
  }
396
408
 
397
- exports.printValidationProcessResult = ({
409
+ export function printValidationProcessResult({
398
410
  inputFile,
399
411
  error
400
412
  // eslint-disable-next-line consistent-return
401
- }) => {
413
+ }) {
402
414
  let message = ''
403
415
  const filename = path.basename(inputFile)
404
416
 
@@ -411,7 +423,7 @@ exports.printValidationProcessResult = ({
411
423
  console.log(message)
412
424
  }
413
425
 
414
- exports.printImportProcessResult = ({
426
+ export function printImportProcessResult({
415
427
  countImported,
416
428
  countFailed,
417
429
  countSkipped,
@@ -419,7 +431,7 @@ exports.printImportProcessResult = ({
419
431
  name,
420
432
  fatalError
421
433
  // eslint-disable-next-line consistent-return
422
- }) => {
434
+ }) {
423
435
  let message = ''
424
436
 
425
437
  if (fatalError) {
@@ -427,19 +439,19 @@ exports.printImportProcessResult = ({
427
439
  return message
428
440
  }
429
441
 
430
- message = `[${this.colorByResult(
442
+ message = `[${colorByResult(
431
443
  name,
432
444
  countImported,
433
445
  countFailed,
434
446
  countSkipped
435
- )}] imported ${this.colorGreaterThanZero(countImported, 'green')} items`
447
+ )}] imported ${colorGreaterThanZero(countImported, 'green')} items`
436
448
 
437
449
  if (countFailed) {
438
- message += `, failed ${this.colorGreaterThanZero(countFailed, 'red')} items`
450
+ message += `, failed ${colorGreaterThanZero(countFailed, 'red')} items`
439
451
  }
440
452
 
441
453
  if (countSkipped) {
442
- message += `, skipped ${this.colorGreaterThanZero(countSkipped, 'red')} items`
454
+ message += `, skipped ${colorGreaterThanZero(countSkipped, 'red')} items`
443
455
  }
444
456
 
445
457
  message += ` ${chalk.gray(`[${executionTime}s]`)}`
@@ -447,7 +459,7 @@ exports.printImportProcessResult = ({
447
459
  return message
448
460
  }
449
461
 
450
- exports.colorByResult = (value, countImported, countFailed, countSkipped) => {
462
+ export function colorByResult(value, countImported, countFailed, countSkipped) {
451
463
  let color = 'green'
452
464
 
453
465
  if (countImported > 0 && (countFailed > 0 || countSkipped > 0)) {
@@ -461,7 +473,7 @@ exports.colorByResult = (value, countImported, countFailed, countSkipped) => {
461
473
  return chalk[color](value)
462
474
  }
463
475
 
464
- exports.colorGreaterThanZero = (value, color) => {
476
+ export function colorGreaterThanZero(value, color) {
465
477
  if (value > 0) {
466
478
  return chalk[color](value)
467
479
  }
@@ -469,11 +481,11 @@ exports.colorGreaterThanZero = (value, color) => {
469
481
  return value
470
482
  }
471
483
 
472
- exports.refreshOrders = (spinner, ws, importProcess) =>
473
- new Promise(resolve => {
484
+ export function refreshOrders(spinner, ws, importProcess) {
485
+ return new Promise(resolve => {
474
486
  const hrstart = process.hrtime()
475
487
 
476
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
488
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
477
489
 
478
490
  spinner.start('Refreshing orders (draft, template)...')
479
491
 
@@ -485,9 +497,9 @@ exports.refreshOrders = (spinner, ws, importProcess) =>
485
497
  const { type, payload } = JSON.parse(packet)
486
498
  switch (type) {
487
499
  case 'refreshOrdersResponse': {
488
- spinner.text = this.printRefreshedOrders({
500
+ spinner.text = printRefreshedOrders({
489
501
  ...payload,
490
- executionTime: this.getExecutionTime(hrstart)
502
+ executionTime: getExecutionTime(hrstart)
491
503
  })
492
504
  spinner.succeed()
493
505
  resolve({
@@ -495,7 +507,7 @@ exports.refreshOrders = (spinner, ws, importProcess) =>
495
507
  refreshed: payload.refreshed,
496
508
  errored: payload.errored,
497
509
  name: importProcess.name,
498
- executionTime: this.getExecutionTime(hrstart)
510
+ executionTime: getExecutionTime(hrstart)
499
511
  })
500
512
  break
501
513
  }
@@ -508,13 +520,14 @@ exports.refreshOrders = (spinner, ws, importProcess) =>
508
520
  resolve({ error: e.message })
509
521
  })
510
522
  })
523
+ }
511
524
 
512
525
  // eslint-disable-next-line consistent-return
513
- exports.printRefreshedOrders = ({ refreshed, errored, executionTime }) => {
526
+ export function printRefreshedOrders({ refreshed, errored, executionTime }) {
514
527
  let message = ''
515
528
 
516
- const stringRefreshed = this.colorGreaterThanZero(refreshed.length, 'green')
517
- const stringErrored = this.colorGreaterThanZero(errored.length, 'red')
529
+ const stringRefreshed = colorGreaterThanZero(refreshed.length, 'green')
530
+ const stringErrored = colorGreaterThanZero(errored.length, 'red')
518
531
 
519
532
  message += `Refreshed ${stringRefreshed} orders (draft, template)`
520
533
 
@@ -527,9 +540,9 @@ exports.printRefreshedOrders = ({ refreshed, errored, executionTime }) => {
527
540
  return message
528
541
  }
529
542
 
530
- exports.deleteRowsBeforeImportDate = (importProcess, partitionsForCsvType, spinner, ws) =>
531
- new Promise(resolve => {
532
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
543
+ export function deleteRowsBeforeImportDate(importProcess, partitionsForCsvType, spinner, ws) {
544
+ return new Promise(resolve => {
545
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
533
546
 
534
547
  spinner.start('Deleting old database records for chosen partitions...')
535
548
 
@@ -559,17 +572,18 @@ exports.deleteRowsBeforeImportDate = (importProcess, partitionsForCsvType, spinn
559
572
  resolve({ error: e.message })
560
573
  })
561
574
  })
575
+ }
562
576
 
563
- exports.download = async (url, destPath, fileName) =>
564
- new Promise((resolve, reject) => {
577
+ export async function download(url, destPath, fileName) {
578
+ return new Promise((resolve, reject) => {
565
579
  const filePath = path.resolve(destPath, fileName)
566
580
 
567
581
  const dirname = path.dirname(filePath)
568
- if (!fs.existsSync(dirname)) {
569
- fs.mkdirSync(dirname, { recursive: true })
582
+ if (!existsSync(dirname)) {
583
+ mkdirSync(dirname, { recursive: true })
570
584
  }
571
585
 
572
- const downloadStream = got.stream(url)
586
+ const downloadStream = stream(url)
573
587
  const fileWriterStream = createWriteStream(filePath)
574
588
 
575
589
  downloadStream
@@ -585,10 +599,11 @@ exports.download = async (url, destPath, fileName) =>
585
599
 
586
600
  downloadStream.pipe(fileWriterStream)
587
601
  })
602
+ }
588
603
 
589
- exports.callBeforeDataImportProcess = (spinner, ws, importProcess) =>
590
- new Promise((resolve, reject) => {
591
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
604
+ export function callBeforeDataImportProcess(spinner, ws, importProcess) {
605
+ return new Promise((resolve, reject) => {
606
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
592
607
 
593
608
  spinner.start('Executing tasks before start...')
594
609
 
@@ -620,10 +635,11 @@ exports.callBeforeDataImportProcess = (spinner, ws, importProcess) =>
620
635
  resolve({ error: e.message })
621
636
  })
622
637
  })
638
+ }
623
639
 
624
- exports.callAfterDataImportProcess = (spinner, ws, importProcess) =>
625
- new Promise(resolve => {
626
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
640
+ export function callAfterDataImportProcess(spinner, ws, importProcess) {
641
+ return new Promise(resolve => {
642
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
627
643
 
628
644
  spinner.start('Executing tasks after the end process...')
629
645
 
@@ -650,10 +666,11 @@ exports.callAfterDataImportProcess = (spinner, ws, importProcess) =>
650
666
  resolve({ error: e.message })
651
667
  })
652
668
  })
669
+ }
653
670
 
654
- exports.callAfterMediaImportProcess = (spinner, ws, report) =>
655
- new Promise(resolve => {
656
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
671
+ export function callAfterMediaImportProcess(spinner, ws, report) {
672
+ return new Promise(resolve => {
673
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
657
674
 
658
675
  spinner.start('Executing tasks after the end process...')
659
676
 
@@ -678,11 +695,12 @@ exports.callAfterMediaImportProcess = (spinner, ws, report) =>
678
695
  resolve({ error: e.message })
679
696
  })
680
697
  })
698
+ }
681
699
 
682
- exports.importMedia = (reprocess, spinner, ws) =>
683
- new Promise(resolve => {
700
+ export function importMedia(reprocess, spinner, ws) {
701
+ return new Promise(resolve => {
684
702
  const hrstart = process.hrtime()
685
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
703
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
686
704
 
687
705
  let countAssetImported = 0
688
706
  let countAssetSkipped = 0
@@ -690,11 +708,11 @@ exports.importMedia = (reprocess, spinner, ws) =>
690
708
  let countProductAssetImported = 0
691
709
 
692
710
  const updateSpinnerText = () => {
693
- spinner.text = this.printImportProcessResult({
711
+ spinner.text = printImportProcessResult({
694
712
  countImported: countAssetImported,
695
713
  countSkipped: countAssetSkipped,
696
714
  countFailed: countAssetFailed,
697
- executionTime: this.getExecutionTime(hrstart),
715
+ executionTime: getExecutionTime(hrstart),
698
716
  name: 'Asset'
699
717
  })
700
718
  }
@@ -729,10 +747,10 @@ exports.importMedia = (reprocess, spinner, ws) =>
729
747
  break
730
748
  case 'import.images.productAssets.end':
731
749
  spinner.succeed(
732
- this.printImportProcessResult({
750
+ printImportProcessResult({
733
751
  countImported: payload.count,
734
752
  countFailed: 0,
735
- executionTime: this.getExecutionTime(hrstart),
753
+ executionTime: getExecutionTime(hrstart),
736
754
  name: 'ProductAsset'
737
755
  })
738
756
  )
@@ -754,10 +772,11 @@ exports.importMedia = (reprocess, spinner, ws) =>
754
772
  resolve({ error: e.message })
755
773
  })
756
774
  })
775
+ }
757
776
 
758
- exports.flushMedia = (spinner, ws) =>
759
- new Promise(resolve => {
760
- const socket = this.createSocketConnection(ws.endpoint, ws.adminSecret)
777
+ export function flushMedia(spinner, ws) {
778
+ return new Promise((resolve, reject) => {
779
+ const socket = createSocketConnection(ws.endpoint, ws.secret)
761
780
 
762
781
  spinner.start('Flushing... ')
763
782
 
@@ -779,18 +798,22 @@ exports.flushMedia = (spinner, ws) =>
779
798
  })
780
799
 
781
800
  socket.on('error', e => {
782
- resolve({ error: e.message })
801
+ spinner.fail(e.message)
802
+ reject(e)
783
803
  })
784
804
  })
805
+ }
785
806
 
786
- exports.getArchiveFolder = instanceEndpoint => {
807
+ export function getArchiveFolder(instanceEndpoint) {
787
808
  const prefix = 'closer'
788
- const instance = slugify(instanceEndpoint.split('/')[0], { lower: true })
789
- const ts = getTimestampForFilename()
790
- return `${prefix}_${instance}/${ts}`
809
+ const instance = slugify(instanceEndpoint.split('/')[0], {
810
+ lower: true,
811
+ remove: /[*+~.()'"!:@]/g
812
+ })
813
+ return `${prefix}_${instance}`
791
814
  }
792
815
 
793
- exports.renameWithTimestamp = dirPath => {
816
+ export function renameWithTimestamp(dirPath) {
794
817
  const ts = getTimestampForFilename()
795
818
 
796
819
  const files = getCsvFilesFromDir(dirPath).map(filename => {
@@ -803,7 +826,7 @@ exports.renameWithTimestamp = dirPath => {
803
826
  }
804
827
  })
805
828
 
806
- files.forEach(file => fs.rename(file.oldPath, file.newPath, () => {}))
829
+ files.forEach(file => rename(file.oldPath, file.newPath, () => {}))
807
830
  }
808
831
 
809
832
  const getTimestampForFilename = () => {
@@ -813,3 +836,26 @@ const getTimestampForFilename = () => {
813
836
  const timeString = isoTimeString.split(':').join('').split('.')[0]
814
837
  return `${dateString}_${timeString}`.split(':').join('')
815
838
  }
839
+
840
+ export function getHumanTimestamp(date) {
841
+ const [isoDateString, isoTimeString] = date.toISOString().split('T')
842
+ const dateString = isoDateString.split('-').join('')
843
+ const timeString = isoTimeString.split(':').join('').split('.')[0]
844
+ return `${dateString}_${timeString}`.split(':').join('')
845
+ }
846
+
847
+ export async function readImportDir(dirpath) {
848
+ const allFiles = readdirSync(dirpath)
849
+ const csvFiles = allFiles.filter(file => path.extname(file) === '.csv')
850
+
851
+ if (csvFiles.length === 0) {
852
+ return []
853
+ }
854
+
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
+ })
859
+
860
+ return files
861
+ }
package/index.js CHANGED
@@ -1,32 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- /* eslint-disable no-unused-expressions */
4
- /* eslint-disable no-console */
3
+ import chalk from 'chalk'
4
+ import pkg from './package.json' assert { type: 'json' }
5
+ import yargs from 'yargs'
5
6
 
6
- const chalk = require('chalk')
7
- const packageJson = require('./package.json')
7
+ import * as ImportData from './cmds/importData.js'
8
+ import * as ImportMedia from './cmds/importMedia.js'
8
9
 
9
- console.log(chalk.bold(`\n 👜 Closer CLI (${packageJson.version})\n`))
10
+ console.log(chalk.bold(`\n 👜 Closer CLI (${pkg.version})\n`))
10
11
 
11
- require('yargs/yargs')(process.argv.slice(2))
12
+ yargs(process.argv.slice(2))
12
13
  .scriptName('closer')
13
14
  .usage(`Usage: ${chalk.cyan('$0')} <command> [options]`)
14
- .commandDir('cmds')
15
15
  .option('e', {
16
16
  alias: 'endpoint',
17
17
  describe: 'Closer URL',
18
18
  demandOption: true
19
19
  })
20
20
  .option('s', {
21
- alias: 'admin-secret',
22
- describe: 'Admin Secret for Closer',
23
- demandOption: true
24
- })
25
- .option('n', {
26
- alias: 'name',
27
- describe: 'Attach string name label to import process',
28
- type: 'string',
21
+ alias: 'secret',
22
+ describe: 'Closer Secret',
29
23
  demandOption: true
30
24
  })
25
+ .command(ImportData.command, ImportData.desc, ImportData.builder, ImportData.handler)
26
+ .command(ImportMedia.command, ImportMedia.desc, ImportMedia.builder, ImportMedia.handler)
31
27
  .help()
32
28
  .version().argv
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "closer-cli",
3
- "version": "2.33.0",
3
+ "version": "2.37.0",
4
4
  "description": "",
5
- "main": "index.js",
5
+ "exports": "./index.js",
6
+ "type": "module",
6
7
  "bin": {
7
8
  "closer": "./index.js"
8
9
  },
@@ -11,14 +12,17 @@
11
12
  "author": "Francesco Pasqua <cesconix@me.com>",
12
13
  "license": "ISC",
13
14
  "dependencies": {
14
- "chalk": "^4.1.2",
15
+ "chalk": "^5.1.2",
15
16
  "csv-parse": "^5.3.1",
16
17
  "csv-stringify": "^6.2.0",
18
+ "del": "^7.0.0",
17
19
  "event-stream": "^4.0.1",
18
- "got": "^11.8.5",
19
- "ora": "^5.4.1",
20
+ "got": "^12.5.2",
21
+ "mv": "^2.1.1",
22
+ "ora": "^6.1.2",
20
23
  "prompts": "^2.4.2",
21
24
  "require-directory": "^2.1.1",
25
+ "rimraf": "^3.0.2",
22
26
  "slugify": "^1.6.3",
23
27
  "ws": "^8.0.0",
24
28
  "yargs": "^17.0.1"