dobo 1.2.10 → 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 (153) 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/{bajo → extend/bajo}/intl/en-US.json +3 -2
  62. package/{bajo → extend/bajo}/intl/id.json +3 -2
  63. package/{bajoCli → extend/bajoCli}/applet/connection.js +5 -5
  64. package/extend/bajoCli/applet/lib/post-process.js +53 -0
  65. package/extend/bajoCli/applet/model-clear.js +11 -0
  66. package/{bajoCli → extend/bajoCli}/applet/model-rebuild.js +13 -13
  67. package/{bajoCli → extend/bajoCli}/applet/record-create.js +10 -8
  68. package/{bajoCli → extend/bajoCli}/applet/record-find.js +6 -5
  69. package/{bajoCli → extend/bajoCli}/applet/record-get.js +5 -5
  70. package/{bajoCli → extend/bajoCli}/applet/record-remove.js +5 -5
  71. package/{bajoCli → extend/bajoCli}/applet/record-update.js +9 -9
  72. package/{bajoCli → extend/bajoCli}/applet/schema.js +4 -4
  73. package/{bajoCli → extend/bajoCli}/applet/stat-count.js +4 -4
  74. package/{dobo → extend/dobo}/feature/created-at.js +1 -1
  75. package/{dobo → extend/dobo}/feature/removed-at.js +3 -3
  76. package/{dobo → extend/dobo}/feature/updated-at.js +2 -2
  77. package/{waibuMpa → extend/waibuMpa}/route/attachment/@model/@id/@field/@file.js +3 -3
  78. package/index.js +230 -72
  79. package/lib/add-fixtures.js +7 -6
  80. package/lib/build-bulk-action.js +2 -2
  81. package/lib/check-unique.js +2 -2
  82. package/lib/collect-connections.js +15 -4
  83. package/lib/collect-drivers.js +15 -6
  84. package/lib/{collect-feature.js → collect-features.js} +13 -4
  85. package/lib/collect-schemas.js +22 -12
  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/{plugin-method → method}/attachment/copy-uploaded.js +2 -2
  104. package/{plugin-method → method}/attachment/create.js +3 -3
  105. package/{plugin-method → method}/attachment/find.js +2 -2
  106. package/{plugin-method → method}/attachment/get-path.js +3 -3
  107. package/{plugin-method → method}/attachment/get.js +1 -1
  108. package/{plugin-method → method}/attachment/pre-check.js +1 -1
  109. package/{plugin-method → method}/attachment/remove.js +1 -1
  110. package/{plugin-method → method}/bulk/create.js +6 -6
  111. package/{plugin-method → method}/model/clear.js +5 -5
  112. package/method/model/create.js +32 -0
  113. package/method/model/drop.js +31 -0
  114. package/method/model/exists.js +37 -0
  115. package/{plugin-method → method}/record/clear.js +5 -5
  116. package/{plugin-method → method}/record/count.js +27 -5
  117. package/{plugin-method → method}/record/create.js +46 -6
  118. package/{plugin-method → method}/record/find-all.js +16 -0
  119. package/{plugin-method → method}/record/find-one.js +20 -6
  120. package/method/record/find.js +115 -0
  121. package/method/record/get.js +89 -0
  122. package/method/record/remove.js +72 -0
  123. package/{plugin-method → method}/record/update.js +47 -6
  124. package/{plugin-method → method}/record/upsert.js +18 -2
  125. package/{plugin-method → method}/sanitize/body.js +18 -3
  126. package/method/sanitize/date.js +27 -0
  127. package/{plugin-method → method}/sanitize/id.js +10 -0
  128. package/{plugin-method → method}/stat/aggregate.js +4 -4
  129. package/{plugin-method → method}/stat/histogram.js +4 -4
  130. package/{plugin-method → 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/bajoCli/applet/lib/post-process.js +0 -47
  140. package/bajoCli/applet/model-clear.js +0 -11
  141. package/plugin-method/model/create.js +0 -19
  142. package/plugin-method/model/drop.js +0 -19
  143. package/plugin-method/model/exists.js +0 -24
  144. package/plugin-method/record/find.js +0 -52
  145. package/plugin-method/record/get.js +0 -47
  146. package/plugin-method/record/remove.js +0 -41
  147. package/plugin-method/sanitize/date.js +0 -14
  148. /package/{bajoCli → extend/bajoCli}/applet.js +0 -0
  149. /package/{dobo → extend/dobo}/feature/dt.js +0 -0
  150. /package/{dobo → extend/dobo}/feature/int-id.js +0 -0
  151. /package/{waibuStatic → extend/waibuStatic}/virtual.json +0 -0
  152. /package/{plugin-method → method}/attachment/update.js +0 -0
  153. /package/{docs/query-language.md → wiki/QUERY-LANGUAGE.md} +0 -0
@@ -0,0 +1,53 @@
1
+ const conns = []
2
+
3
+ async function postProcess ({ handler, params, path, processMsg, noConfirmation } = {}) {
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 })
11
+
12
+ const schema = find(this.schemas, { name: params[0] })
13
+ if (!schema) return this.print.fatal('notFound%s', this.t('field.schema'))
14
+ let cont = true
15
+ if (!noConfirmation) {
16
+ const answer = await confirm({ message: this.print.buildText('sureContinue'), default: false })
17
+ if (!answer) {
18
+ this.print.fail('aborted')
19
+ cont = false
20
+ }
21
+ }
22
+ if (!cont) return
23
+ const spin = this.print.spinner().start(`${processMsg}...`)
24
+ const { connection } = this.getInfo(schema)
25
+ if (!conns.includes(connection.name)) {
26
+ await this.start(connection.name)
27
+ conns.push(connection.name)
28
+ }
29
+ try {
30
+ const resp = await this[handler](...params)
31
+ if (isEmpty(resp)) {
32
+ spin.warn('noResultFound')
33
+ return false
34
+ }
35
+ spin.succeed('done')
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()
39
+ const base = path === 'recordFind' ? params[0] : (params[0] + '/' + id)
40
+ actionPath += `/${base}`
41
+ }
42
+ await writeOutput(resp, actionPath, true)
43
+ return true
44
+ } catch (err) {
45
+ if (this.app.bajo.config.log.applet) {
46
+ spin.stop()
47
+ console.error(err)
48
+ } else spin.fail('error%s', err.message)
49
+ return false
50
+ }
51
+ }
52
+
53
+ export default postProcess
@@ -0,0 +1,11 @@
1
+ import postProcess from './lib/post-process.js'
2
+
3
+ async function modelClear (path, ...args) {
4
+ const { print } = this.app.bajo
5
+ const { isEmpty } = this.app.lib._
6
+ if (isEmpty(this.schemas)) return print.fail('notFound%s', 'schema', { exit: this.app.applet })
7
+ const [schema] = args
8
+ await postProcess.call(this, { handler: path, params: [schema], path, processMsg: 'Clear records' })
9
+ }
10
+
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,