dobo 2.0.0 → 2.0.1

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.
Files changed (139) hide show
  1. package/.github/FUNDING.yml +13 -0
  2. package/.github/workflows/repo-lockdown.yml +24 -0
  3. package/.jsdoc.conf.json +45 -0
  4. package/LICENSE +1 -1
  5. package/README.md +38 -19
  6. package/docs/Dobo.html +26 -0
  7. package/docs/data/search.json +1 -0
  8. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  9. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  10. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  11. package/docs/global.html +7 -0
  12. package/docs/index.html +3 -0
  13. package/docs/index.js.html +578 -0
  14. package/docs/lib_collect-connections.js.html +39 -0
  15. package/docs/lib_collect-drivers.js.html +52 -0
  16. package/docs/lib_collect-features.js.html +36 -0
  17. package/docs/lib_collect-schemas.js.html +94 -0
  18. package/docs/lib_index.js.html +6 -0
  19. package/docs/method_model_create.js.html +35 -0
  20. package/docs/method_model_drop.js.html +34 -0
  21. package/docs/method_model_exists.js.html +40 -0
  22. package/docs/method_record_count.js.html +69 -0
  23. package/docs/method_record_create.js.html +114 -0
  24. package/docs/method_record_find-all.js.html +44 -0
  25. package/docs/method_record_find-one.js.html +73 -0
  26. package/docs/method_record_find.js.html +118 -0
  27. package/docs/method_record_get.js.html +92 -0
  28. package/docs/method_record_remove.js.html +75 -0
  29. package/docs/method_record_update.js.html +107 -0
  30. package/docs/method_record_upsert.js.html +54 -0
  31. package/docs/method_sanitize_body.js.html +88 -0
  32. package/docs/method_sanitize_date.js.html +30 -0
  33. package/docs/method_sanitize_id.js.html +20 -0
  34. package/docs/method_validate.js.html +249 -0
  35. package/docs/module-Lib.html +3 -0
  36. package/docs/scripts/core.js +726 -0
  37. package/docs/scripts/core.min.js +23 -0
  38. package/docs/scripts/resize.js +90 -0
  39. package/docs/scripts/search.js +265 -0
  40. package/docs/scripts/search.min.js +6 -0
  41. package/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
  42. package/docs/scripts/third-party/fuse.js +9 -0
  43. package/docs/scripts/third-party/hljs-line-num-original.js +369 -0
  44. package/docs/scripts/third-party/hljs-line-num.js +1 -0
  45. package/docs/scripts/third-party/hljs-original.js +5171 -0
  46. package/docs/scripts/third-party/hljs.js +1 -0
  47. package/docs/scripts/third-party/popper.js +5 -0
  48. package/docs/scripts/third-party/tippy.js +1 -0
  49. package/docs/scripts/third-party/tocbot.js +672 -0
  50. package/docs/scripts/third-party/tocbot.min.js +1 -0
  51. package/docs/static/bitcoin.jpeg +0 -0
  52. package/docs/static/home.md +25 -0
  53. package/docs/static/logo-ecosystem.png +0 -0
  54. package/docs/static/logo.png +0 -0
  55. package/docs/styles/clean-jsdoc-theme-base.css +1159 -0
  56. package/docs/styles/clean-jsdoc-theme-dark.css +412 -0
  57. package/docs/styles/clean-jsdoc-theme-light.css +482 -0
  58. package/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
  59. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
  60. package/docs/styles/clean-jsdoc-theme.min.css +1 -0
  61. package/extend/bajo/intl/en-US.json +3 -2
  62. package/extend/bajo/intl/id.json +3 -2
  63. package/extend/bajoCli/applet/connection.js +5 -5
  64. package/extend/bajoCli/applet/lib/post-process.js +22 -16
  65. package/extend/bajoCli/applet/model-clear.js +4 -4
  66. package/extend/bajoCli/applet/model-rebuild.js +13 -13
  67. package/extend/bajoCli/applet/record-create.js +10 -8
  68. package/extend/bajoCli/applet/record-find.js +6 -5
  69. package/extend/bajoCli/applet/record-get.js +5 -5
  70. package/extend/bajoCli/applet/record-remove.js +5 -5
  71. package/extend/bajoCli/applet/record-update.js +9 -9
  72. package/extend/bajoCli/applet/schema.js +4 -4
  73. package/extend/bajoCli/applet/stat-count.js +4 -4
  74. package/extend/dobo/feature/created-at.js +1 -1
  75. package/extend/dobo/feature/removed-at.js +3 -3
  76. package/extend/dobo/feature/updated-at.js +2 -2
  77. package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +3 -3
  78. package/index.js +230 -72
  79. package/lib/add-fixtures.js +5 -5
  80. package/lib/build-bulk-action.js +2 -2
  81. package/lib/check-unique.js +2 -2
  82. package/lib/collect-connections.js +14 -3
  83. package/lib/collect-drivers.js +14 -6
  84. package/lib/{collect-feature.js → collect-features.js} +12 -4
  85. package/lib/collect-schemas.js +17 -9
  86. package/lib/exec-feature-hook.js +1 -1
  87. package/lib/exec-validation.js +5 -5
  88. package/lib/generic-prop-sanitizer.js +6 -5
  89. package/lib/handle-attachment-upload.js +2 -2
  90. package/lib/index.js +3 -0
  91. package/lib/mem-db/conn-sanitizer.js +1 -1
  92. package/lib/mem-db/instantiate.js +4 -4
  93. package/lib/mem-db/method/record/find.js +1 -1
  94. package/lib/mem-db/method/record/get.js +1 -1
  95. package/lib/mem-db/method/record/remove.js +1 -1
  96. package/lib/mem-db/method/record/update.js +1 -1
  97. package/lib/mem-db/start.js +1 -1
  98. package/lib/merge-attachment-info.js +2 -2
  99. package/lib/multi-rel-rows.js +2 -2
  100. package/lib/resolve-method.js +3 -3
  101. package/lib/sanitize-schema.js +8 -7
  102. package/lib/single-rel-rows.js +2 -2
  103. package/method/attachment/copy-uploaded.js +2 -2
  104. package/method/attachment/create.js +3 -3
  105. package/method/attachment/find.js +2 -2
  106. package/method/attachment/get-path.js +3 -3
  107. package/method/attachment/get.js +1 -1
  108. package/method/attachment/pre-check.js +1 -1
  109. package/method/attachment/remove.js +1 -1
  110. package/method/bulk/create.js +6 -6
  111. package/method/model/clear.js +5 -5
  112. package/method/model/create.js +18 -5
  113. package/method/model/drop.js +17 -5
  114. package/method/model/exists.js +18 -5
  115. package/method/record/clear.js +5 -5
  116. package/method/record/count.js +27 -5
  117. package/method/record/create.js +46 -6
  118. package/method/record/find-all.js +16 -0
  119. package/method/record/find-one.js +20 -6
  120. package/method/record/find.js +69 -6
  121. package/method/record/get.js +48 -6
  122. package/method/record/remove.js +36 -5
  123. package/method/record/update.js +47 -6
  124. package/method/record/upsert.js +18 -2
  125. package/method/sanitize/body.js +18 -3
  126. package/method/sanitize/date.js +20 -7
  127. package/method/sanitize/id.js +10 -0
  128. package/method/stat/aggregate.js +4 -4
  129. package/method/stat/histogram.js +4 -4
  130. package/method/validate.js +96 -7
  131. package/package.json +41 -36
  132. package/wiki/APPLETS.md +57 -0
  133. package/wiki/CONFIG.md +25 -0
  134. package/wiki/CONTRIBUTING.md +5 -0
  135. package/wiki/DEV-GUIDE.md +1 -0
  136. package/wiki/ECOSYSTEM.md +20 -0
  137. package/wiki/GETTING-STARTED.md +166 -0
  138. package/wiki/USER-GUIDE.md +1 -0
  139. /package/{docs/query-language.md → wiki/QUERY-LANGUAGE.md} +0 -0
@@ -1,18 +1,19 @@
1
1
  const conns = []
2
2
 
3
3
  async function postProcess ({ handler, params, path, processMsg, noConfirmation } = {}) {
4
- const { saveAsDownload, importPkg } = this.app.bajo
5
- const { prettyPrint } = this.app.bajoCli.helper
6
- const { find, get } = this.lib._
7
- const [stripAnsi, confirm] = await importPkg('bajoCli:strip-ansi', 'bajoCli:@inquirer/confirm')
8
- if (!noConfirmation && this.config.confirmation === false) noConfirmation = true
9
- params.push({ fields: this.config.fields, dataOnly: !this.config.full })
4
+ const { importPkg, generateId } = this.app.bajo
5
+ const { writeOutput } = this.app.bajoCli
6
+ const { find, get, isEmpty } = this.app.lib._
7
+ const [confirm] = await importPkg('bajoCli:strip-ansi', 'bajoCli:@inquirer/confirm')
8
+ const { confirmation, fields, full } = this.app.bajo.config
9
+ if (!noConfirmation && confirmation === false) noConfirmation = true
10
+ params.push({ fields, dataOnly: !full })
10
11
 
11
12
  const schema = find(this.schemas, { name: params[0] })
12
- if (!schema) return this.print.fatal('notFound%s', this.print.write('field.schema'))
13
+ if (!schema) return this.print.fatal('notFound%s', this.t('field.schema'))
13
14
  let cont = true
14
15
  if (!noConfirmation) {
15
- const answer = await confirm({ message: this.print.write('sureContinue'), default: false })
16
+ const answer = await confirm({ message: this.print.buildText('sureContinue'), default: false })
16
17
  if (!answer) {
17
18
  this.print.fail('aborted')
18
19
  cont = false
@@ -27,21 +28,26 @@ async function postProcess ({ handler, params, path, processMsg, noConfirmation
27
28
  }
28
29
  try {
29
30
  const resp = await this[handler](...params)
31
+ if (isEmpty(resp)) {
32
+ spin.warn('noResultFound')
33
+ return false
34
+ }
30
35
  spin.succeed('done')
31
- const result = this.config.pretty ? (await prettyPrint(resp)) : JSON.stringify(resp, null, 2)
32
- if (this.config.save) {
33
- const id = resp.id ?? get(resp, 'data.id') ?? get(resp, 'oldData.id')
36
+ let actionPath = path
37
+ if (this.app.bajo.config.save) {
38
+ const id = resp.id ?? get(resp, 'data.id') ?? get(resp, 'oldData.id') ?? generateId()
34
39
  const base = path === 'recordFind' ? params[0] : (params[0] + '/' + id)
35
- const file = `/${path}/${base}.${this.config.pretty ? 'txt' : 'json'}`
36
- await saveAsDownload(file, stripAnsi(result))
37
- } else console.log(result)
40
+ actionPath += `/${base}`
41
+ }
42
+ await writeOutput(resp, actionPath, true)
43
+ return true
38
44
  } catch (err) {
39
- if (this.config.log.applet) {
45
+ if (this.app.bajo.config.log.applet) {
40
46
  spin.stop()
41
47
  console.error(err)
42
48
  } else spin.fail('error%s', err.message)
49
+ return false
43
50
  }
44
- process.exit()
45
51
  }
46
52
 
47
53
  export default postProcess
@@ -1,11 +1,11 @@
1
1
  import postProcess from './lib/post-process.js'
2
2
 
3
- async function modelClear (...args) {
3
+ async function modelClear (path, ...args) {
4
4
  const { print } = this.app.bajo
5
- const { isEmpty } = this.lib._
6
- if (isEmpty(this.schemas)) return print.fail('notFound%s', 'schema', { exit: this.app.bajo.applet })
5
+ const { isEmpty } = this.app.lib._
6
+ if (isEmpty(this.schemas)) return print.fail('notFound%s', 'schema', { exit: this.app.applet })
7
7
  const [schema] = args
8
- await postProcess.call(this, { handler: 'modelClear', params: [schema], path: 'modelClear', processMsg: 'Clear records' })
8
+ await postProcess.call(this, { handler: path, params: [schema], path, processMsg: 'Clear records' })
9
9
  }
10
10
 
11
11
  export default modelClear
@@ -1,29 +1,29 @@
1
- import addFixtures from '../../lib/add-fixtures.js'
1
+ import addFixtures from '../../../lib/add-fixtures.js'
2
2
 
3
- async function modelRebuild (...args) {
3
+ async function modelRebuild (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { outmatch } = this.lib
6
- const { isEmpty, map, trim, without } = this.lib._
5
+ const { outmatch } = this.app.lib
6
+ const { isEmpty, map, trim, without } = this.app.lib._
7
7
  const [input, confirm, boxen] = await importPkg('bajoCli:@inquirer/input',
8
8
  'bajoCli:@inquirer/confirm', 'bajoCli:boxen')
9
9
  const schemas = map(this.schemas, 'name')
10
10
  let names = args.join(' ')
11
- if (isEmpty(schemas)) return this.print.fail('notFound%s', 'schema', { exit: this.app.bajo.applet })
11
+ if (isEmpty(schemas)) return this.print.fail('notFound%s', 'schema', { exit: this.app.applet })
12
12
  if (isEmpty(names)) {
13
13
  names = await input({
14
- message: this.print.write('enterSchemaName'),
14
+ message: this.print.buildText('enterSchemaName'),
15
15
  default: '*'
16
16
  })
17
17
  }
18
18
  const isMatch = outmatch(map(names.split(' '), m => trim(m)))
19
19
  names = schemas.filter(isMatch)
20
- if (names.length === 0) return this.print.fail('No schema matched', true, { exit: this.app.bajo.applet })
21
- console.log(boxen(names.join(' '), { title: this.print.write('schema%d', names.length), padding: 0.5, borderStyle: 'round' }))
20
+ if (names.length === 0) return this.print.fail('No schema matched', true, { exit: this.app.applet })
21
+ console.log(boxen(names.join(' '), { title: this.t('schema%d', names.length), padding: 0.5, borderStyle: 'round' }))
22
22
  const answer = await confirm({
23
- message: this.print.write('schemasWillBeRebuiltContinue'),
23
+ message: this.print.buildText('schemasWillBeRebuiltContinue'),
24
24
  default: false
25
25
  })
26
- if (!answer) return this.print.fail('aborted', { exit: this.app.bajo.applet })
26
+ if (!answer) return this.print.fail('aborted', { exit: this.app.applet })
27
27
  /*
28
28
  const conns = []
29
29
  for (const s of names) {
@@ -36,7 +36,7 @@ async function modelRebuild (...args) {
36
36
  const skipped = []
37
37
  for (const s of names) {
38
38
  const { schema, instance } = this.getInfo(s)
39
- const spin = this.print.spinner({ showCounter: true }).start('rebuilding%s', schema.name)
39
+ const spin = this.print.spinner().start('rebuilding%s', schema.name)
40
40
  if (!instance) {
41
41
  spin.warn('clientInstanceNotConnected%s', schema.connection, schema.name)
42
42
  skipped.push(schema.name)
@@ -80,7 +80,7 @@ async function modelRebuild (...args) {
80
80
  if (result.failed > 0) this.print.fatal('cantContinueAddFixture')
81
81
  for (const s of without(names, ...skipped)) {
82
82
  const { schema, connection } = this.getInfo(s)
83
- const spin = this.print.spinner({ showCounter: true }).start('addingFixture%s', schema.name)
83
+ const spin = this.print.spinner().start('addingFixture%s', schema.name)
84
84
  if (connection.memory) {
85
85
  spin.warn('memoryDbSkipped%s', schema.name)
86
86
  continue
@@ -95,7 +95,7 @@ async function modelRebuild (...args) {
95
95
  result.failed++
96
96
  }
97
97
  }
98
- process.exit()
98
+ this.app.exit()
99
99
  }
100
100
 
101
101
  export default modelRebuild
@@ -2,27 +2,27 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function createRecord (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map, isPlainObject } = this.lib._
5
+ const { isEmpty, map, isPlainObject } = this.app.lib._
6
6
  const [input, select, boxen] = await importPkg('bajoCli:@inquirer/input',
7
7
  'bajoCli:@inquirer/select', 'bajoCli:boxen')
8
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
8
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
9
9
  let [schema, body] = args
10
10
  if (isEmpty(schema)) {
11
11
  schema = await select({
12
- message: this.print.write('selectSchema'),
12
+ message: this.print.buildText('selectSchema'),
13
13
  choices: map(this.schemas, s => ({ value: s.name }))
14
14
  })
15
15
  }
16
16
  if (isEmpty(body)) {
17
17
  body = await input({
18
- message: this.print.write('enterJsonPayload'),
18
+ message: this.print.buildText('enterJsonPayload'),
19
19
  validate: text => {
20
- if (isEmpty(text)) return this.print.write('payloadRequired')
20
+ if (isEmpty(text)) return this.t('payloadRequired')
21
21
  try {
22
22
  const parsed = JSON.parse(text)
23
23
  if (!isPlainObject(parsed)) throw new Error()
24
24
  } catch (err) {
25
- return this.print.write('payloadMustBeJson')
25
+ return this.t('payloadMustBeJson')
26
26
  }
27
27
  return true
28
28
  }
@@ -32,10 +32,12 @@ async function createRecord (path, ...args) {
32
32
  try {
33
33
  payload = JSON.parse(body)
34
34
  } catch (err) {
35
- return this.print.fail('invalidPayloadSyntax', { exit: this.app.bajo.applet })
35
+ return this.print.fail('invalidPayloadSyntax', { exit: this.app.applet })
36
36
  }
37
37
  console.log(boxen(JSON.stringify(payload, null, 2), { title: schema, padding: 0.5, borderStyle: 'round' }))
38
- await postProcess.call(this, { handler: 'recordCreate', params: [schema, payload], path, processMsg: 'Creating record' })
38
+ const result = await postProcess.call(this, { handler: 'recordCreate', params: [schema, payload], path, processMsg: 'Creating record' })
39
+ if (!result) await createRecord.call(this, path, ...args)
40
+ this.app.exit()
39
41
  }
40
42
 
41
43
  export default createRecord
@@ -2,26 +2,27 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function findRecord (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map, pick } = this.lib._
5
+ const { isEmpty, map, pick } = this.app.lib._
6
6
  const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
7
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
8
8
  let [schema, query] = args
9
9
  if (isEmpty(schema)) {
10
10
  schema = await select({
11
- message: this.print.write('selectSchema'),
11
+ message: this.print.buildText('selectSchema'),
12
12
  choices: map(this.schemas, s => ({ value: s.name }))
13
13
  })
14
14
  }
15
15
  if (isEmpty(query)) {
16
16
  query = await input({
17
- message: this.print.write('enterQueryIfAny')
17
+ message: this.print.buildText('enterQueryIfAny')
18
18
  })
19
19
  }
20
20
  if (isEmpty(query)) query = {}
21
21
  const filter = pick(this.app.bajo.config, ['page', 'offset', 'pageSize', 'sort', 'limit'])
22
22
  filter.pageSize = filter.pageSize ?? filter.limit
23
23
  filter.query = query
24
- await postProcess.call(this, { noConfirmation: true, handler: 'recordFind', params: [schema, filter], path, processMsg: 'Finding record(s)' })
24
+ const resp = await postProcess.call(this, { noConfirmation: true, handler: 'recordFind', params: [schema, filter], path, processMsg: 'Finding record(s)' })
25
+ if (!resp) await findRecord.call(this, path, ...args)
25
26
  }
26
27
 
27
28
  export default findRecord
@@ -2,20 +2,20 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function getRecord (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map } = this.lib._
5
+ const { isEmpty, map } = this.app.lib._
6
6
  const [input, select] = await importPkg('bajoCli:@inquirer/input', 'bajoCli:@inquirer/select')
7
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
8
8
  let [schema, id] = args
9
9
  if (isEmpty(schema)) {
10
10
  schema = await select({
11
- message: this.print.write('Please select a schema:'),
11
+ message: this.print.buildText('Please select a schema:'),
12
12
  choices: map(this.schemas, s => ({ value: s.name }))
13
13
  })
14
14
  }
15
15
  if (isEmpty(id)) {
16
16
  id = await input({
17
- message: this.print.write('Enter record ID:'),
18
- validate: text => isEmpty(text) ? this.print.write('ID is required') : true
17
+ message: this.print.buildText('Enter record ID:'),
18
+ validate: text => isEmpty(text) ? this.t('ID is required') : true
19
19
  })
20
20
  }
21
21
  await postProcess.call(this, { noConfirmation: true, handler: 'recordGet', params: [schema, id], path, processMsg: 'Getting record' })
@@ -2,20 +2,20 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function removeRecord (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map } = this.lib._
5
+ const { isEmpty, map } = this.app.lib._
6
6
  const [input, select] = await importPkg('bajoCli:@inquirer/input', 'bajoCli:@inquirer/select')
7
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
8
8
  let [schema, id] = args
9
9
  if (isEmpty(schema)) {
10
10
  schema = await select({
11
- message: this.print.write('Please select a schema:'),
11
+ message: this.print.buildText('Please select a schema:'),
12
12
  choices: map(this.schemas, s => ({ value: s.name }))
13
13
  })
14
14
  }
15
15
  if (isEmpty(id)) {
16
16
  id = await input({
17
- message: this.print.write('Enter record ID:'),
18
- validate: text => isEmpty(text) ? this.print.write('ID is required') : true
17
+ message: this.print.buildText('Enter record ID:'),
18
+ validate: text => isEmpty(text) ? this.t('ID is required') : true
19
19
  })
20
20
  }
21
21
  await postProcess.call(this, { handler: 'recordRemove', params: [schema, id], path, processMsg: 'Removing record' })
@@ -2,33 +2,33 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function updateRecord (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map, isPlainObject } = this.lib._
5
+ const { isEmpty, map, isPlainObject } = this.app.lib._
6
6
  const [input, select, boxen] = await importPkg('bajoCli:@inquirer/input',
7
7
  'bajoCli:@inquirer/select', 'bajoCli:boxen')
8
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
8
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
9
9
  let [schema, id, body] = args
10
10
  if (isEmpty(schema)) {
11
11
  schema = await select({
12
- message: this.print.write('selectSchema'),
12
+ message: this.print.buildText('selectSchema'),
13
13
  choices: map(this.schemas, s => ({ value: s.name }))
14
14
  })
15
15
  }
16
16
  if (isEmpty(id)) {
17
17
  id = await input({
18
- message: this.print.write('enterRecordId'),
19
- validate: text => isEmpty(text) ? this.print.write('idIsRequired') : true
18
+ message: this.print.buildText('enterRecordId'),
19
+ validate: text => isEmpty(text) ? this.t('idIsRequired') : true
20
20
  })
21
21
  }
22
22
  if (isEmpty(body)) {
23
23
  body = await input({
24
- message: this.print.write('enterJsonPayload'),
24
+ message: this.print.buildText('enterJsonPayload'),
25
25
  validate: text => {
26
- if (isEmpty(text)) return this.print.write('payloadRequired')
26
+ if (isEmpty(text)) return this.t('payloadRequired')
27
27
  try {
28
28
  const parsed = JSON.parse(text)
29
29
  if (!isPlainObject(parsed)) throw new Error()
30
30
  } catch (err) {
31
- return this.print.write('payloadMustBeJson')
31
+ return this.t('payloadMustBeJson')
32
32
  }
33
33
  return true
34
34
  }
@@ -38,7 +38,7 @@ async function updateRecord (path, ...args) {
38
38
  try {
39
39
  payload = JSON.parse(body)
40
40
  } catch (err) {
41
- return this.print.fail('invalidPayloadSyntax', { exit: this.app.bajo.applet })
41
+ return this.print.fail('invalidPayloadSyntax', { exit: this.app.applet })
42
42
  }
43
43
  console.log(boxen(JSON.stringify(payload, null, 2), { title: schema, padding: 0.5, borderStyle: 'round' }))
44
44
  await postProcess.call(this, { handler: 'recordUpdate', params: [schema, id, payload], path, processMsg: 'Updating record' })
@@ -1,20 +1,20 @@
1
1
  async function schema (path, ...args) {
2
2
  const { importPkg } = this.app.bajo
3
- const { isEmpty, map, find } = this.lib._
3
+ const { isEmpty, map, find } = this.app.lib._
4
4
  const { getOutputFormat, writeOutput } = this.app.bajoCli
5
5
  const select = await importPkg('bajoCli:@inquirer/select')
6
6
  const format = getOutputFormat()
7
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
8
8
  let name = args[0]
9
9
  if (isEmpty(name)) {
10
10
  const choices = map(this.schemas, s => ({ value: s.name }))
11
11
  name = await select({
12
- message: this.print.write('selectSchema'),
12
+ message: this.print.buildText('selectSchema'),
13
13
  choices
14
14
  })
15
15
  }
16
16
  const result = find(this.schemas, { name })
17
- if (!result) return this.print.fail('cantFindSchema%s', this.print.write('schema'), name, { exit: this.app.bajo.applet })
17
+ if (!result) return this.print.fail('cantFindSchema%s', this.t('schema'), name, { exit: this.app.applet })
18
18
  this.print.info('done')
19
19
  await writeOutput(result, path, format)
20
20
  }
@@ -2,19 +2,19 @@ import postProcess from './lib/post-process.js'
2
2
 
3
3
  async function statCount (path, ...args) {
4
4
  const { importPkg } = this.app.bajo
5
- const { isEmpty, map } = this.lib._
5
+ const { isEmpty, map } = this.app.lib._
6
6
  const [select, input] = await importPkg('bajoCli:@inquirer/select', 'bajoCli:@inquirer/input')
7
- if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.print.write('field.schema'), { exit: this.app.bajo.applet })
7
+ if (isEmpty(this.schemas)) return this.print.fail('notFound%s', this.t('field.schema'), { exit: this.app.applet })
8
8
  let [schema, query] = args
9
9
  if (isEmpty(schema)) {
10
10
  schema = await select({
11
- message: this.print.write('selectSchema'),
11
+ message: this.print.buildText('selectSchema'),
12
12
  choices: map(this.schemas, s => ({ value: s.name }))
13
13
  })
14
14
  }
15
15
  if (isEmpty(query)) {
16
16
  query = await input({
17
- message: this.print.write('enterQueryIfAny')
17
+ message: this.print.buildText('enterQueryIfAny')
18
18
  })
19
19
  }
20
20
  const filter = { query }
@@ -8,7 +8,7 @@ async function createdAt (opts = {}) {
8
8
  },
9
9
  hook: {
10
10
  beforeCreate: async function ({ body }) {
11
- const { isSet } = this.lib.aneka
11
+ const { isSet } = this.app.lib.aneka
12
12
  const now = new Date()
13
13
  if (opts.overwrite || !isSet(body[opts.fieldName])) body[opts.fieldName] = now
14
14
  }
@@ -1,6 +1,6 @@
1
1
  async function beforeFind ({ filter = {}, options }, opts) {
2
2
  filter.query = filter.query ?? {}
3
- const { isEmpty, set } = this.lib._
3
+ const { isEmpty, set } = this.app.lib._
4
4
  const q = { $and: [] }
5
5
  if (!isEmpty(filter.query)) {
6
6
  if (filter.query.$and) q.$and.push(...filter.query.$and)
@@ -17,7 +17,7 @@ async function afterFind ({ records }, opts) {
17
17
  }
18
18
 
19
19
  async function afterGet ({ schema, id, record }, opts) {
20
- const { isEmpty } = this.lib._
20
+ const { isEmpty } = this.app.lib._
21
21
  if (!isEmpty(record.data[opts.fieldName])) throw this.error('recordNotFound%s%s', id, schema.name, { statusCode: 404 })
22
22
  delete record.data[opts.fieldName]
23
23
  }
@@ -70,7 +70,7 @@ async function removedAt (opts = {}) {
70
70
  beforeRemove: async function ({ schema, id, options }) {
71
71
  const { recordUpdate, recordGet } = this.app.dobo
72
72
  await recordGet(schema.name, id, options)
73
- const { set } = this.lib._
73
+ const { set } = this.app.lib._
74
74
  const body = set({}, opts.fieldName, new Date())
75
75
  const record = await recordUpdate(schema.name, id, body, { dataOnly: false, noValidation: true, noFeatureHook: true })
76
76
  options.record = { oldData: record.oldData }
@@ -9,12 +9,12 @@ async function updatedAt (opts = {}) {
9
9
  },
10
10
  hook: {
11
11
  beforeCreate: async function ({ body }) {
12
- const { isSet } = this.lib.aneka
12
+ const { isSet } = this.app.lib.aneka
13
13
  const now = new Date()
14
14
  if (opts.overwrite || !isSet(body[opts.fieldName])) body[opts.fieldName] = now
15
15
  },
16
16
  beforeUpdate: async function ({ body }) {
17
- const { isSet } = this.lib.aneka
17
+ const { isSet } = this.app.lib.aneka
18
18
  const now = new Date()
19
19
  if (opts.overwrite || !isSet(body[opts.fieldName])) body[opts.fieldName] = now
20
20
  }
@@ -1,10 +1,10 @@
1
1
  import path from 'path'
2
2
 
3
3
  async function attachment (req, reply) {
4
- const { isString, isEmpty, find } = this.lib._
5
- const { pascalCase } = this.lib.aneka
4
+ const { isString, isEmpty, find } = this.app.lib._
5
+ const { pascalCase } = this.app.lib.aneka
6
6
  const { routePath } = this.app.waibu
7
- const { fs } = this.lib
7
+ const { fs } = this.app.lib
8
8
  const items = await this.listAttachments({
9
9
  model: req.params.model,
10
10
  id: req.params.id,