dobo-extra 1.0.3 → 1.0.5

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/bajo/init.js CHANGED
@@ -5,15 +5,15 @@ async function handler ({ item }) {
5
5
  const { getSchema } = this.app.dobo
6
6
  const { has } = this.app.bajo.lib._
7
7
  for (const f of ['source', 'destination']) {
8
- if (!has(item, f)) throw this.error('Task must have %s model', f)
8
+ if (!has(item, f)) throw this.error('taskMustHaveModel%s', f)
9
9
  const key = `${f}Field`
10
10
  item[key] = item[key] ?? 'createdAt'
11
11
  const schema = getSchema(item[f])
12
12
  const prop = schema.properties.find(p => p.name === item[key])
13
- if (!prop) throw this.error('Unknown field \'%s@%s\'', item[key], item[f])
14
- if (!types.includes(prop.type)) throw this.error('\'%s@%s (%s)\' is not supported (must be one of %s)', item[key], item[f], prop.type, join(types))
13
+ if (!prop) throw this.error('unknownField%s%s', item[key], item[f])
14
+ if (!types.includes(prop.type)) throw this.error('isNotSupported%s%s%s%s', item[key], item[f], prop.type, join(types))
15
15
  }
16
- if (item.source === item.destination) throw this.error('Source & destination must be different')
16
+ if (item.source === item.destination) throw this.error('sourceDestMustBeDifferent')
17
17
  item.maxAge = item.maxAge ?? 1 // in days, less then 1 is ignored
18
18
  }
19
19
 
@@ -0,0 +1,37 @@
1
+ {
2
+ "archiveError%s": "Archive error: %s",
3
+ "dirNotExists%s": "Directory '%s' doesn't exist",
4
+ "unsupportedFormat%s": "Unsupported format '%s'",
5
+ "sourceFileNotExists%s": "Source file '%s' doesn't exist",
6
+ "taskMissingModel%s": "Task must have %s model",
7
+ "unknownField%s%s": "Unknown field '%s@%s'",
8
+ "isNotSupported%s%s%s%s": "'%s@%s (%s)' is not supported (must be one of %s)",
9
+ "sourceDestMustBeDifferent": "Source & destination must be different",
10
+ "autoArchiveDisabled": "Automatic archiving is disabled",
11
+ "copying%s%s": "Copying %s -> %s...",
12
+ "notFoundSkipped": "No record found, skipped",
13
+ "recordsArchivedContinue%d": "%d records will be archived. Continue?",
14
+ "taskCancelled%s%s": "Task %s -> %s cancelled",
15
+ "recordsArchived%d": "%d records will be archived",
16
+ "milestoneCopied%s": "Milestone #%s records copied",
17
+ "id%s": "ID #%s",
18
+ "maxReached%d": "Max of %d records reached",
19
+ "removing%s": "Removing %s...",
20
+ "milestoneRemoved%s": "Milestone #%s records removed",
21
+ "archivingEnded%s%s%s%s": "Archiving %s -> %s ended, moved: %s, error: %s",
22
+ "manuallyRunTaskContinue": "You're about to manually run task archiver. Continue?",
23
+ "nothingToArchive": "Nothing to archive",
24
+ "archiveDisabled%s%s": "Archive %s -> %s is disabled",
25
+ "batch%d%s": "Batch #%d (%s)",
26
+ "noSchemaFound": "Batch #%d (%s)",
27
+ "chooseModel": "Please choose model:",
28
+ "enterDestFile": "Please enter destination file:",
29
+ "enterQueryIfAny": "Please enter a query (if any):",
30
+ "exporting": "Exporting...",
31
+ "exported%d%s": "%d records successfully exported to '%s'",
32
+ "enterSourceFile": "Please enter source file:",
33
+ "aboutToReplaceAllRecords": "You're about to replace ALL records with the new ones. Are you really sure?",
34
+ "importing": "Importing...",
35
+ "recordsImported%d%s": "%d records successfully imported from '%s'",
36
+ "aborted": "Aborted!"
37
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "archiveError%s": "Archive error: %s",
3
+ "dirNotExists%s": "Directory '%s' doesn't exist",
4
+ "unsupportedFormat%s": "Unsupported format '%s'",
5
+ "sourceFileNotExists%s": "Source file '%s' doesn't exist",
6
+ "taskMissingModel%s": "Task must have %s model",
7
+ "unknownField%s%s": "Unknown field '%s@%s'",
8
+ "isNotSupported%s%s%s%s": "'%s@%s (%s)' is not supported (must be one of %s)",
9
+ "sourceDestMustBeDifferent": "Source & destination must be different",
10
+ "autoArchiveDisabled": "Automatic archiving is disabled",
11
+ "copying%s%s": "Copying %s -> %s...",
12
+ "notFoundSkipped": "No record found, skipped",
13
+ "recordsArchivedContinue%d": "%d records will be archived. Continue?",
14
+ "taskCancelled%s%s": "Task %s -> %s cancelled",
15
+ "recordsArchived%d": "%d records will be archived",
16
+ "milestoneCopied%s": "Milestone #%s records copied",
17
+ "id%s": "ID #%s",
18
+ "maxReached%d": "Max of %d records reached",
19
+ "removing%s": "Removing %s...",
20
+ "milestoneRemoved%s": "Milestone #%s records removed",
21
+ "archivingEnded%s%s%s%s": "Archiving %s -> %s ended, moved: %s, error: %s",
22
+ "manuallyRunTaskContinue": "You're about to manually run task archiver. Continue?",
23
+ "nothingToArchive": "Nothing to archive",
24
+ "archiveDisabled%s%s": "Archive %s -> %s is disabled",
25
+ "batch%d%s": "Batch #%d (%s)",
26
+ "noSchemaFound": "Batch #%d (%s)",
27
+ "chooseModel": "Please choose model:",
28
+ "enterDestFile": "Please enter destination file:",
29
+ "enterQueryIfAny": "Please enter a query (if any):",
30
+ "exporting": "Exporting...",
31
+ "exported%d%s": "%d records successfully exported to '%s'",
32
+ "enterSourceFile": "Please enter source file:",
33
+ "aboutToReplaceAllRecords": "You're about to replace ALL records with the new ones. Are you really sure?",
34
+ "importing": "Importing...",
35
+ "recordsImported%d%s": "%d records successfully imported from '%s'",
36
+ "aborted": "Aborted!"
37
+ }
@@ -21,7 +21,7 @@ async function getFile (dest, ensureDir) {
21
21
  const dir = path.dirname(file)
22
22
  if (!fs.existsSync(dir)) {
23
23
  if (ensureDir) fs.ensureDirSync(dir)
24
- else throw this.error('Directory \'%s\' doesn\'t exist', dir)
24
+ else throw this.error('dirNotExists%s', dir)
25
25
  }
26
26
  let compress = false
27
27
  let ext = path.extname(file)
@@ -30,7 +30,7 @@ async function getFile (dest, ensureDir) {
30
30
  ext = path.extname(path.basename(file).replace('.gz', ''))
31
31
  // file = file.slice(0, file.length - 3)
32
32
  }
33
- if (!supportedExt.includes(ext)) throw this.error('Unsupported format \'%s\'', ext.slice(1))
33
+ if (!supportedExt.includes(ext)) throw this.error('unsupportedFormat%s', ext.slice(1))
34
34
  return { file, ext, compress }
35
35
  }
36
36
 
@@ -20,14 +20,14 @@ async function importFrom (source, dest, { trashOld = true, batch = 1, progressF
20
20
  file = `${getPluginDataDir(this.name)}/import/${source}`
21
21
  fs.ensureDirSync(path.dirname(file))
22
22
  }
23
- if (!fs.existsSync(file)) throw this.error('Source file \'%s\' doesn\'t exist', file)
23
+ if (!fs.existsSync(file)) throw this.error('sourceFileNotExists%s', file)
24
24
  let ext = fileType ? `.${fileType}` : path.extname(file)
25
25
  let decompress = false
26
26
  if (ext === '.gz') {
27
27
  ext = path.extname(path.basename(file, '.gz'))
28
28
  decompress = true
29
29
  }
30
- if (!supportedExt.includes(ext)) throw this.error('Unsupported format \'%s\'', ext.slice(1))
30
+ if (!supportedExt.includes(ext)) throw this.error('unsupportedFormat%s', ext.slice(1))
31
31
  if (trashOld && dest !== false) await this.app.dobo.modelClear(dest)
32
32
  const reader = fs.createReadStream(file)
33
33
  batch = parseInt(batch) || 100
package/bajo/start.js CHANGED
@@ -1,12 +1,12 @@
1
1
  async function start () {
2
2
  if (this.config.archive.checkInterval === false || this.config.archive.checkInterval <= 0) {
3
- this.log.warn('Automatic archiving is disabled')
3
+ this.log.warn('autoArchiveDisabled')
4
4
  return
5
5
  }
6
6
  if (this.config.archive.runEarly) await this.archive()
7
7
  this.archiveIntv = setInterval(() => {
8
8
  this.archive().then().catch(err => {
9
- this.log.error('Archive error: %s', err.message)
9
+ this.log.error('archiveError%s', err.message)
10
10
  })
11
11
  }, this.config.archive.checkInterval * 60 * 1000)
12
12
  }
@@ -7,25 +7,25 @@ async function move (task) {
7
7
  const prompts = await importPkg('bajoCli:@inquirer/prompts')
8
8
  const { confirm } = prompts
9
9
  // get relevant record
10
- this.print.info('Copying %s -> %s...', task.source, task.destination)
10
+ this.print.info('copying%s%s', task.source, task.destination)
11
11
  const mark = dayjs().subtract(task.maxAge, 'day').toDate()
12
12
  const query = set({}, task.sourceField, { $lt: mark })
13
13
  let count = await statAggregate(task.source, { query }, { aggregate: 'count' })
14
14
  count = count[0].count
15
15
  if (count === 0) {
16
- this.print.warn('No record found, skipped')
16
+ this.print.warn('notFoundSkipped')
17
17
  return
18
18
  }
19
19
  if (this.config.prompt !== false) {
20
20
  const answer = await confirm({
21
- message: this.print.write('%d records will be archived. Continue?', count),
21
+ message: this.print.write('recordsArchivedContinue%d', count),
22
22
  default: true
23
23
  })
24
24
  if (!answer) {
25
- this.print.warn('Task %s -> %s cancelled', task.source, task.destination)
25
+ this.print.warn('taskCancelled%s%s', task.source, task.destination)
26
26
  return
27
27
  }
28
- } else this.print.info('%d records will be archived', count)
28
+ } else this.print.info('recordsArchived%d', count)
29
29
  let page = 1
30
30
  let total = 0
31
31
  let affected = 0
@@ -36,7 +36,7 @@ async function move (task) {
36
36
  for (;;) {
37
37
  const results = await recordFind(task.source, { query, page, limit: 100 }, { noCache: true, noHook: true })
38
38
  if (results.length === 0) break
39
- if (this.bajo.config.tool && total % 1000 === 0 && total !== 0) this.print.succeed('Milestone #%s records copied', formatInteger(total))
39
+ if (this.bajo.config.tool && total % 1000 === 0 && total !== 0) this.print.succeed('milestoneCopied%s', formatInteger(total))
40
40
  for (const r of results) {
41
41
  if (task.maxRecords && task.maxRecords < total) {
42
42
  isMax = true
@@ -46,7 +46,7 @@ async function move (task) {
46
46
  try {
47
47
  await recordCreate(task.destination, r, { noSanitize: true, noHook: true, noResult: true, noCheckUnique: true })
48
48
  ids.push(r.id)
49
- spin.setText('ID #%s', r.id)
49
+ spin.setText('id%s', r.id)
50
50
  } catch (err) {
51
51
  error++
52
52
  }
@@ -55,18 +55,18 @@ async function move (task) {
55
55
  affected = total - error
56
56
  page++
57
57
  }
58
- if (isMax) this.print.warn('Max of %d records reached', task.maxRecords)
59
- this.print.info('Removing %s...', task.source)
58
+ if (isMax) this.print.warn('maxReached%d', task.maxRecords)
59
+ this.print.info('removing%s', task.source)
60
60
  for (const idx in ids) {
61
61
  const id = ids[idx]
62
62
  try {
63
63
  await recordRemove(task.source, id, { noHook: true, noResult: true })
64
- spin.setText('ID #%s', id)
65
- if (this.bajo.config.tool && idx % 1000 === 0 && idx !== '0') this.print.succeed('Milestone #%s records removed', formatInteger(idx))
64
+ spin.setText('id%s', id)
65
+ if (this.bajo.config.tool && idx % 1000 === 0 && idx !== '0') this.print.succeed('milestoneRemoved%s', formatInteger(idx))
66
66
  } catch (err) {}
67
67
  }
68
68
  spin.stop()
69
- this.print.info('Archiving %s -> %s ended, moved: %s, error: %s', task.source, task.destination, formatInteger(affected), formatInteger(error))
69
+ this.print.info('archivingEnded%s%s%s%s', task.source, task.destination, formatInteger(affected), formatInteger(error))
70
70
  }
71
71
 
72
72
  async function archive (...args) {
@@ -75,17 +75,17 @@ async function archive (...args) {
75
75
  const { confirm } = prompts
76
76
  if (this.config.prompt !== false) {
77
77
  const answer = await confirm({
78
- message: this.print.write('You\'re about to manually run task archiver. Continue?'),
78
+ message: this.print.write('manuallyRunTaskContinue'),
79
79
  default: false
80
80
  })
81
81
 
82
- if (!answer) this.print.fatal('Aborted!')
82
+ if (!answer) this.print.fatal('aborted')
83
83
  }
84
84
  await this.app.dobo.start()
85
- if (this.archivers.length === 0) this.print.fatal('Nothing to archive')
85
+ if (this.archivers.length === 0) this.print.fatal('nothingToArchive')
86
86
  for (const t of this.archivers.tasks) {
87
87
  if (t.maxAge < 1) {
88
- this.print.warn('Archive %s -> %s is disabled', t.source, t.destination)
88
+ this.print.warn('archiveDisabled%s%s', t.source, t.destination)
89
89
  continue
90
90
  }
91
91
  await move.call(this, t)
@@ -6,7 +6,7 @@ function makeProgress (spin) {
6
6
  const { secToHms } = this.app.bajo
7
7
  return async function ({ batchNo, data, batchStart, batchEnd } = {}) {
8
8
  if (data.length === 0) return
9
- spin.setText('Batch #%d (%s)', batchNo, secToHms(batchEnd.toTime() - batchStart.toTime(), true))
9
+ spin.setText('batch%d%s', batchNo, secToHms(batchEnd.toTime() - batchStart.toTime(), true))
10
10
  }
11
11
  }
12
12
 
@@ -19,37 +19,37 @@ async function exportTo (...args) {
19
19
  const [input, select] = await importPkg('bajoCli:@inquirer/input',
20
20
  'bajoCli:@inquirer/select')
21
21
  const schemas = map(this.app.dobo.schemas, 'name')
22
- if (isEmpty(schemas)) return this.print.fatal('No schema found!')
22
+ if (isEmpty(schemas)) return this.print.fatal('notFound%s', this.print.write('field.schema'))
23
23
  let [model, dest, query] = args
24
24
  if (isEmpty(model)) {
25
25
  model = await select({
26
- message: this.print.write('Please choose model:'),
26
+ message: this.print.write('chooseModel'),
27
27
  choices: map(schemas, s => ({ value: s }))
28
28
  })
29
29
  }
30
30
  if (isEmpty(dest)) {
31
31
  dest = await input({
32
- message: this.print.write('Please enter destination file:'),
32
+ message: this.print.write('enterDestFile'),
33
33
  default: `${model}-${dayjs().format('YYYYMMDD')}.ndjson`,
34
34
  validate: (item) => !isEmpty(item)
35
35
  })
36
36
  }
37
37
  if (isEmpty(query)) {
38
38
  query = await input({
39
- message: this.print.write('Please enter a query (if any):')
39
+ message: this.print.write('enterQueryIfAny')
40
40
  })
41
41
  }
42
- const spin = this.print.spinner().start('Exporting...')
42
+ const spin = this.print.spinner().start('exporting')
43
43
  const progressFn = makeProgress.call(this, spin)
44
44
  const { connection } = getInfo(model)
45
45
  await start(connection.name)
46
46
  try {
47
47
  const filter = { query }
48
48
  const result = await this.exportTo(model, dest, { filter, batch, progressFn })
49
- spin.succeed('%d records successfully exported to \'%s\'', result.count, _path.resolve(result.file))
49
+ spin.succeed('exported%d%s', result.count, _path.resolve(result.file))
50
50
  } catch (err) {
51
51
  console.log(err)
52
- spin.fatal('Error: %s', err.message)
52
+ spin.fatal('error%s', err.message)
53
53
  }
54
54
  }
55
55
 
@@ -5,7 +5,7 @@ const batch = 100
5
5
  function makeProgress (spin) {
6
6
  const { secToHms } = this.app.bajo
7
7
  return async function ({ batchNo, data, batchStart, batchEnd } = {}) {
8
- spin.setText('Batch #%d (%s)', batchNo, secToHms(batchEnd.toTime() - batchStart.toTime(), true))
8
+ spin.setText('batch%d%s', batchNo, secToHms(batchEnd.toTime() - batchStart.toTime(), true))
9
9
  }
10
10
  }
11
11
 
@@ -17,32 +17,32 @@ async function importFrom (...args) {
17
17
  const [input, select, confirm] = await importPkg('bajoCli:@inquirer/input',
18
18
  'bajoCli:@inquirer/select', 'bajoCli:@inquirer/confirm')
19
19
  const schemas = map(this.app.dobo.schemas, 'name')
20
- if (isEmpty(schemas)) return this.print.fatal('No schema found!')
20
+ if (isEmpty(schemas)) return this.print.fatal('notFound%s', this.print.write('field.schema'))
21
21
  let [dest, model] = args
22
22
  if (isEmpty(dest)) {
23
23
  dest = await input({
24
- message: this.print.write('Please enter source file:'),
24
+ message: this.print.write('enterSourceFile'),
25
25
  validate: (item) => !isEmpty(item)
26
26
  })
27
27
  }
28
28
  if (isEmpty(model)) {
29
29
  model = await select({
30
- message: this.print.write('Please choose model:'),
30
+ message: this.print.write('chooseModel'),
31
31
  choices: map(schemas, s => ({ value: s }))
32
32
  })
33
33
  }
34
34
  const answer = await confirm({
35
- message: this.print.write('You\'re about to replace ALL records with the new ones. Are you really sure?'),
35
+ message: this.print.write('aboutToReplaceAllRecords'),
36
36
  default: false
37
37
  })
38
- if (!answer) return this.print.fatal('Aborted!')
39
- const spin = this.print.spinner({ showCounter: true }).start('Importing...')
38
+ if (!answer) return this.print.fatal('aborted')
39
+ const spin = this.print.spinner({ showCounter: true }).start('importing')
40
40
  const progressFn = makeProgress.call(this, spin)
41
41
  const { connection } = getInfo(model)
42
42
  await start(connection.name)
43
43
  try {
44
44
  const result = await importFrom(dest, model, { batch, progressFn })
45
- spin.succeed('%d records successfully imported from \'%s\'', result.count, _path.resolve(result.file))
45
+ spin.succeed('recordsImported%d%s', result.count, _path.resolve(result.file))
46
46
  } catch (err) {
47
47
  spin.fatal('Error: %s', err.message)
48
48
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dobo-extra",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Bajo DB Extra Tools/Utility",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,37 +0,0 @@
1
- {
2
- "Directory '%s' doesn't exist": "",
3
- "Unsupported format '%s'": "",
4
- "Source file '%s' doesn't exist": "",
5
- "Task must have %s model": "",
6
- "Unknown field '%s@%s'": "",
7
- "'%s@%s (%s)' is not supported (must be one of %s)": "",
8
- "Source & destination must be different": "",
9
- "Automatic archiving is disabled": "",
10
- "Archive error: %s": "",
11
- "Copying %s -> %s...": "",
12
- "No record found, skipped": "",
13
- "%d records will be archived. Continue?": "",
14
- "Task %s -> %s cancelled": "",
15
- "%d records will be archived": "",
16
- "Milestone #%s records copied": "",
17
- "ID #%s": "",
18
- "Max of %d records reached": "",
19
- "Removing %s...": "",
20
- "Milestone #%s records removed": "",
21
- "Archiving %s -> %s ended, moved: %s, error: %s": "",
22
- "You're about to manually run task archiver. Continue?": "",
23
- "Nothing to archive": "",
24
- "Archive %s -> %s is disabled": "",
25
- "Batch #%d (%s)": "",
26
- "No schema found!": "",
27
- "Please choose model:": "",
28
- "Please enter destination file:": "",
29
- "Please enter a query (if any):": "",
30
- "Exporting...": "",
31
- "%d records successfully exported to '%s'": "",
32
- "Error: %s": "",
33
- "Please enter source file:": "",
34
- "You're about to replace ALL records with the new ones. Are you really sure?": "",
35
- "Importing...": "",
36
- "%d records successfully imported from '%s'": ""
37
- }