@naturalcycles/db-lib 8.11.0 → 8.13.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/adapter/cachedb/cache.db.d.ts +3 -3
  3. package/dist/adapter/cachedb/cache.db.js +4 -4
  4. package/dist/adapter/file/file.db.d.ts +2 -2
  5. package/dist/adapter/file/file.db.js +20 -18
  6. package/dist/adapter/file/inMemory.persistence.plugin.js +1 -1
  7. package/dist/adapter/file/localFile.persistence.plugin.js +9 -9
  8. package/dist/adapter/inmemory/inMemory.db.d.ts +3 -4
  9. package/dist/adapter/inmemory/inMemory.db.js +25 -23
  10. package/dist/adapter/inmemory/queryInMemory.js +1 -1
  11. package/dist/base.common.db.d.ts +3 -3
  12. package/dist/base.common.db.js +10 -4
  13. package/dist/common.db.d.ts +3 -3
  14. package/dist/commondao/common.dao.d.ts +7 -7
  15. package/dist/commondao/common.dao.js +56 -48
  16. package/dist/commondao/common.dao.model.d.ts +20 -27
  17. package/dist/db.model.js +2 -2
  18. package/dist/getDB.js +3 -3
  19. package/dist/index.d.ts +2 -4
  20. package/dist/index.js +1 -5
  21. package/dist/kv/commonKeyValueDao.js +4 -4
  22. package/dist/model.util.js +2 -2
  23. package/dist/pipeline/dbPipelineBackup.d.ts +0 -1
  24. package/dist/pipeline/dbPipelineBackup.js +14 -25
  25. package/dist/pipeline/dbPipelineCopy.js +11 -11
  26. package/dist/pipeline/dbPipelineRestore.js +20 -20
  27. package/dist/query/dbQuery.js +2 -2
  28. package/dist/testing/daoTest.js +23 -23
  29. package/dist/testing/dbTest.js +17 -17
  30. package/dist/testing/keyValueDBTest.js +18 -14
  31. package/dist/testing/keyValueDaoTest.js +18 -14
  32. package/dist/testing/test.model.d.ts +4 -2
  33. package/dist/testing/test.model.js +39 -8
  34. package/dist/testing/timeSeriesTest.util.js +1 -1
  35. package/dist/transaction/dbTransaction.util.js +2 -2
  36. package/dist/validation/index.js +9 -9
  37. package/package.json +1 -1
  38. package/readme.md +5 -4
  39. package/src/adapter/cachedb/cache.db.ts +9 -5
  40. package/src/adapter/file/file.db.ts +7 -4
  41. package/src/adapter/inmemory/inMemory.db.ts +20 -7
  42. package/src/base.common.db.ts +10 -4
  43. package/src/common.db.ts +3 -3
  44. package/src/commondao/common.dao.model.ts +24 -29
  45. package/src/commondao/common.dao.ts +35 -24
  46. package/src/index.ts +0 -7
  47. package/src/pipeline/dbPipelineBackup.ts +2 -15
  48. package/src/pipeline/dbPipelineRestore.ts +1 -1
  49. package/src/testing/dbTest.ts +1 -1
  50. package/src/testing/keyValueDBTest.ts +10 -6
  51. package/src/testing/keyValueDaoTest.ts +10 -6
  52. package/src/testing/test.model.ts +38 -4
  53. package/dist/schema/common.schema.d.ts +0 -38
  54. package/dist/schema/common.schema.js +0 -18
  55. package/dist/schema/commonSchemaGenerator.d.ts +0 -35
  56. package/dist/schema/commonSchemaGenerator.js +0 -151
  57. package/src/schema/common.schema.ts +0 -49
  58. package/src/schema/commonSchemaGenerator.ts +0 -200
@@ -29,10 +29,10 @@ function mergeDBOperations(ops) {
29
29
  }
30
30
  });
31
31
  const resultOps = [];
32
- js_lib_1._stringMapEntries(saveMapByTable).forEach(([table, saveMap]) => {
32
+ (0, js_lib_1._stringMapEntries)(saveMapByTable).forEach(([table, saveMap]) => {
33
33
  const rowsToSave = [];
34
34
  const idsToDelete = [];
35
- js_lib_1._stringMapEntries(saveMap).forEach(([id, r]) => {
35
+ (0, js_lib_1._stringMapEntries)(saveMap).forEach(([id, r]) => {
36
36
  if (r === null) {
37
37
  idsToDelete.push(id);
38
38
  }
@@ -3,30 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.dbQuerySchema = exports.dbQueryOrderSchema = exports.dbQueryFilterSchema = exports.dbQueryFilterOperatorSchema = exports.commonDBSaveOptionsSchema = exports.commonDBOptionsSchema = void 0;
4
4
  const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
5
5
  const dbQuery_1 = require("../query/dbQuery");
6
- exports.commonDBOptionsSchema = nodejs_lib_1.objectSchema({
6
+ exports.commonDBOptionsSchema = (0, nodejs_lib_1.objectSchema)({
7
7
  onlyCache: nodejs_lib_1.booleanSchema.optional(),
8
8
  skipCache: nodejs_lib_1.booleanSchema.optional(),
9
9
  });
10
- exports.commonDBSaveOptionsSchema = nodejs_lib_1.objectSchema({
11
- excludeFromIndexes: nodejs_lib_1.arraySchema(nodejs_lib_1.stringSchema).optional(),
10
+ exports.commonDBSaveOptionsSchema = (0, nodejs_lib_1.objectSchema)({
11
+ excludeFromIndexes: (0, nodejs_lib_1.arraySchema)(nodejs_lib_1.stringSchema).optional(),
12
12
  }).concat(exports.commonDBOptionsSchema);
13
13
  exports.dbQueryFilterOperatorSchema = nodejs_lib_1.stringSchema.valid(...dbQuery_1.DBQueryFilterOperatorValues);
14
- exports.dbQueryFilterSchema = nodejs_lib_1.objectSchema({
14
+ exports.dbQueryFilterSchema = (0, nodejs_lib_1.objectSchema)({
15
15
  name: nodejs_lib_1.stringSchema,
16
16
  op: exports.dbQueryFilterOperatorSchema,
17
17
  val: nodejs_lib_1.anySchema,
18
18
  });
19
- exports.dbQueryOrderSchema = nodejs_lib_1.objectSchema({
19
+ exports.dbQueryOrderSchema = (0, nodejs_lib_1.objectSchema)({
20
20
  name: nodejs_lib_1.stringSchema,
21
21
  descending: nodejs_lib_1.booleanSchema.optional(),
22
22
  });
23
- exports.dbQuerySchema = nodejs_lib_1.objectSchema({
23
+ exports.dbQuerySchema = (0, nodejs_lib_1.objectSchema)({
24
24
  table: nodejs_lib_1.stringSchema,
25
- _filters: nodejs_lib_1.arraySchema(exports.dbQueryFilterSchema).optional(),
25
+ _filters: (0, nodejs_lib_1.arraySchema)(exports.dbQueryFilterSchema).optional(),
26
26
  _limitValue: nodejs_lib_1.integerSchema.min(0).optional(),
27
27
  _offsetValue: nodejs_lib_1.integerSchema.min(0).optional(),
28
- _orders: nodejs_lib_1.arraySchema(exports.dbQueryOrderSchema).optional(),
28
+ _orders: (0, nodejs_lib_1.arraySchema)(exports.dbQueryOrderSchema).optional(),
29
29
  _startCursor: nodejs_lib_1.stringSchema.optional(),
30
30
  _endCursor: nodejs_lib_1.stringSchema.optional(),
31
- _selectedFieldNames: nodejs_lib_1.arraySchema(nodejs_lib_1.stringSchema).optional(),
31
+ _selectedFieldNames: (0, nodejs_lib_1.arraySchema)(nodejs_lib_1.stringSchema).optional(),
32
32
  });
package/package.json CHANGED
@@ -42,7 +42,7 @@
42
42
  "engines": {
43
43
  "node": ">=12.13"
44
44
  },
45
- "version": "8.11.0",
45
+ "version": "8.13.0",
46
46
  "description": "Lowest Common Denominator API to supported Databases",
47
47
  "keywords": [
48
48
  "db",
package/readme.md CHANGED
@@ -216,19 +216,20 @@ await db.getTables()
216
216
 
217
217
  ###### getTableSchema
218
218
 
219
- `getTableSchema(table: string): Promise<CommonSchema>`
219
+ `getTableSchema(table: string): Promise<JsonSchemaObject>`
220
220
 
221
221
  ```typescript
222
222
  await db.getTableSchema('table1')
223
- // todo: describe CommonSchema example
224
223
  ```
225
224
 
225
+ Returns a JsonSchema, generated from the table.
226
+
226
227
  ###### createTable
227
228
 
228
- `createTable(schema: CommonSchema): Promise<void>`
229
+ `createTable(table: string, schema: JsonSchemaObject): Promise<void>`
229
230
 
230
231
  Applicable to Relational DBs, like MySQL. Will invoke smth like `create table Table1 ... ;`. Takes a
231
- `CommonSchema` as an argument.
232
+ `JsonSchema` as an argument.
232
233
 
233
234
  # DBQuery
234
235
 
@@ -1,10 +1,10 @@
1
+ import { JsonSchemaObject } from '@naturalcycles/js-lib'
1
2
  import { Debug, IDebugger } from '@naturalcycles/nodejs-lib'
2
3
  import { Readable } from 'stream'
3
4
  import { BaseCommonDB } from '../../base.common.db'
4
5
  import { CommonDB } from '../../common.db'
5
6
  import { ObjectWithId, RunQueryResult } from '../../db.model'
6
7
  import { DBQuery } from '../../query/dbQuery'
7
- import { CommonSchema } from '../../schema/common.schema'
8
8
  import {
9
9
  CacheDBCfg,
10
10
  CacheDBCreateOptions,
@@ -45,17 +45,21 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
45
45
 
46
46
  override async getTableSchema<ROW extends ObjectWithId>(
47
47
  table: string,
48
- ): Promise<CommonSchema<ROW>> {
48
+ ): Promise<JsonSchemaObject<ROW>> {
49
49
  return await this.cfg.downstreamDB.getTableSchema<ROW>(table)
50
50
  }
51
51
 
52
- override async createTable(schema: CommonSchema, opt: CacheDBCreateOptions = {}): Promise<void> {
52
+ override async createTable(
53
+ table: string,
54
+ schema: JsonSchemaObject,
55
+ opt: CacheDBCreateOptions = {},
56
+ ): Promise<void> {
53
57
  if (!opt.onlyCache && !this.cfg.onlyCache) {
54
- await this.cfg.downstreamDB.createTable(schema, opt)
58
+ await this.cfg.downstreamDB.createTable(table, schema, opt)
55
59
  }
56
60
 
57
61
  if (!opt.skipCache && !this.cfg.skipCache) {
58
- await this.cfg.cacheDB.createTable(schema, opt)
62
+ await this.cfg.cacheDB.createTable(table, schema, opt)
59
63
  }
60
64
  }
61
65
 
@@ -1,4 +1,6 @@
1
1
  import {
2
+ generateJsonSchemaFromData,
3
+ JsonSchemaObject,
2
4
  pMap,
3
5
  StringMap,
4
6
  _by,
@@ -12,8 +14,6 @@ import {
12
14
  import { Debug, readableCreate, ReadableTyped } from '@naturalcycles/nodejs-lib'
13
15
  import { dimGrey } from '@naturalcycles/nodejs-lib/dist/colors'
14
16
  import { BaseCommonDB, DBSaveBatchOperation, ObjectWithId, queryInMemory } from '../..'
15
- import { CommonSchema } from '../..'
16
- import { CommonSchemaGenerator } from '../..'
17
17
  import { CommonDB } from '../../common.db'
18
18
  import {
19
19
  CommonDBOptions,
@@ -213,9 +213,12 @@ export class FileDB extends BaseCommonDB implements CommonDB {
213
213
 
214
214
  override async getTableSchema<ROW extends ObjectWithId>(
215
215
  table: string,
216
- ): Promise<CommonSchema<ROW>> {
216
+ ): Promise<JsonSchemaObject<ROW>> {
217
217
  const rows = await this.loadFile(table)
218
- return CommonSchemaGenerator.generateFromRows({ table }, rows)
218
+ return {
219
+ ...generateJsonSchemaFromData(rows),
220
+ $id: `${table}.schema.json`,
221
+ } as JsonSchemaObject<ROW>
219
222
  }
220
223
 
221
224
  // wrapper, to handle logging
@@ -1,4 +1,12 @@
1
- import { pMap, StringMap, _by, _since, _sortObjectDeep } from '@naturalcycles/js-lib'
1
+ import {
2
+ generateJsonSchemaFromData,
3
+ JsonSchemaObject,
4
+ pMap,
5
+ StringMap,
6
+ _by,
7
+ _since,
8
+ _sortObjectDeep,
9
+ } from '@naturalcycles/js-lib'
2
10
  import {
3
11
  bufferReviver,
4
12
  Debug,
@@ -14,8 +22,6 @@ import * as fs from 'fs-extra'
14
22
  import { Readable } from 'stream'
15
23
  import { createGzip, createUnzip } from 'zlib'
16
24
  import { CommonDB, DBTransaction, ObjectWithId, queryInMemory } from '../..'
17
- import { CommonSchema } from '../..'
18
- import { CommonSchemaGenerator } from '../..'
19
25
  import {
20
26
  CommonDBCreateOptions,
21
27
  CommonDBOptions,
@@ -105,13 +111,20 @@ export class InMemoryDB implements CommonDB {
105
111
  return Object.keys(this.data).filter(t => t.startsWith(this.cfg.tablesPrefix))
106
112
  }
107
113
 
108
- async getTableSchema<ROW extends ObjectWithId>(_table: string): Promise<CommonSchema<ROW>> {
114
+ async getTableSchema<ROW extends ObjectWithId>(_table: string): Promise<JsonSchemaObject<ROW>> {
109
115
  const table = this.cfg.tablesPrefix + _table
110
- return CommonSchemaGenerator.generateFromRows({ table }, Object.values(this.data[table] || {}))
116
+ return {
117
+ ...generateJsonSchemaFromData(Object.values(this.data[table] || {})),
118
+ $id: `${table}.schema.json`,
119
+ } as JsonSchemaObject<ROW>
111
120
  }
112
121
 
113
- async createTable(schema: CommonSchema, opt: CommonDBCreateOptions = {}): Promise<void> {
114
- const table = this.cfg.tablesPrefix + schema.table
122
+ async createTable(
123
+ _table: string,
124
+ _schema: JsonSchemaObject,
125
+ opt: CommonDBCreateOptions = {},
126
+ ): Promise<void> {
127
+ const table = this.cfg.tablesPrefix + _table
115
128
  if (opt.dropIfExists) {
116
129
  this.data[table] = {}
117
130
  } else {
@@ -1,9 +1,9 @@
1
+ import { JsonSchemaObject } from '@naturalcycles/js-lib'
1
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
2
3
  import { Readable } from 'stream'
3
4
  import { CommonDB } from './common.db'
4
5
  import { CommonDBSaveOptions, ObjectWithId, RunQueryResult } from './db.model'
5
6
  import { DBQuery } from './query/dbQuery'
6
- import { CommonSchema } from './schema/common.schema'
7
7
  import { DBTransaction } from './transaction/dbTransaction'
8
8
  import { commitDBTransactionSimple } from './transaction/dbTransaction.util'
9
9
 
@@ -18,11 +18,17 @@ export class BaseCommonDB implements CommonDB {
18
18
  return []
19
19
  }
20
20
 
21
- async getTableSchema<ROW>(table: string): Promise<CommonSchema<ROW>> {
22
- return { table, fields: [] }
21
+ async getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaObject<ROW>> {
22
+ return {
23
+ $id: `${table}.schema.json`,
24
+ type: 'object',
25
+ additionalProperties: true,
26
+ properties: {} as any,
27
+ required: [],
28
+ }
23
29
  }
24
30
 
25
- async createTable(_schema: CommonSchema): Promise<void> {}
31
+ async createTable(_table: string, _schema: JsonSchemaObject): Promise<void> {}
26
32
 
27
33
  async deleteByIds(_table: string, _ids: string[]): Promise<number> {
28
34
  return 0
package/src/common.db.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { JsonSchemaObject } from '@naturalcycles/js-lib'
1
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
2
3
  import {
3
4
  CommonDBCreateOptions,
@@ -8,7 +9,6 @@ import {
8
9
  RunQueryResult,
9
10
  } from './db.model'
10
11
  import { DBQuery } from './query/dbQuery'
11
- import { CommonSchema } from './schema/common.schema'
12
12
  import { DBTransaction } from './transaction/dbTransaction'
13
13
 
14
14
  export interface CommonDB {
@@ -25,13 +25,13 @@ export interface CommonDB {
25
25
  */
26
26
  getTables(): Promise<string[]>
27
27
 
28
- getTableSchema<ROW extends ObjectWithId>(table: string): Promise<CommonSchema<ROW>>
28
+ getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaObject<ROW>>
29
29
 
30
30
  /**
31
31
  * Will do like `create table ...` for mysql.
32
32
  * Caution! dropIfExists defaults to false. If set to true - will actually DROP the table!
33
33
  */
34
- createTable(schema: CommonSchema, opt?: CommonDBCreateOptions): Promise<void>
34
+ createTable(table: string, schema: JsonSchemaObject, opt?: CommonDBCreateOptions): Promise<void>
35
35
 
36
36
  // GET
37
37
  /**
@@ -1,8 +1,11 @@
1
1
  import { ErrorMode } from '@naturalcycles/js-lib'
2
2
  import {
3
+ AjvSchema,
4
+ AjvValidationError,
3
5
  JoiValidationError,
4
6
  ObjectSchemaTyped,
5
7
  TransformLogProgressOptions,
8
+ TransformMapOptions,
6
9
  } from '@naturalcycles/nodejs-lib'
7
10
  import { CommonDB } from '../common.db'
8
11
  import {
@@ -16,11 +19,11 @@ import {
16
19
  export type CommonDaoCreateIdHook<BM, DBM> = (obj: DBM | BM) => string
17
20
  export type CommonDaoParseNaturalIdHook<DBM> = (id: string) => Partial<DBM>
18
21
  export type CommonDaoBeforeCreateHook<BM> = (bm: Partial<BM>) => BM
19
- export type CommonDaoBeforeDBMValidateHook<DBM> = (dbm: DBM) => DBM
20
- export type CommonDaoBeforeDBMToBMHook<BM, DBM> = (dbm: DBM) => BM
21
- export type CommonDaoBeforeBMToDBMHook<BM, DBM> = (bm: BM) => DBM
22
- export type CommonDaoBeforeTMToBMHook<BM, TM> = (tm: TM) => BM
23
- export type CommonDaoBeforeBMToTMHook<BM, TM> = (bm: BM) => TM
22
+ export type CommonDaoBeforeDBMValidateHook<DBM> = (dbm: Partial<DBM>) => Partial<DBM>
23
+ export type CommonDaoBeforeDBMToBMHook<BM, DBM> = (dbm: DBM) => Partial<BM>
24
+ export type CommonDaoBeforeBMToDBMHook<BM, DBM> = (bm: BM) => Partial<DBM>
25
+ export type CommonDaoBeforeTMToBMHook<BM, TM> = (tm: TM) => Partial<BM>
26
+ export type CommonDaoBeforeBMToTMHook<BM, TM> = (bm: BM) => Partial<TM>
24
27
  export type CommonDaoAnonymizeHook<DBM> = (dbm: DBM) => DBM
25
28
 
26
29
  interface CommonDaoHooks<BM, DBM, TM> {
@@ -33,6 +36,14 @@ interface CommonDaoHooks<BM, DBM, TM> {
33
36
  beforeTMToBM: CommonDaoBeforeTMToBMHook<BM, TM>
34
37
  beforeBMToTM: CommonDaoBeforeBMToTMHook<BM, TM>
35
38
  anonymize: CommonDaoAnonymizeHook<DBM>
39
+
40
+ /**
41
+ * If hook is defined - allows to prevent or modify the error thrown.
42
+ * Return `false` to prevent throwing an error.
43
+ * Return original `err` to pass the error through (will be thrown in CommonDao).
44
+ * Return modified/new `Error` if needed.
45
+ */
46
+ onValidationError: (err: JoiValidationError | AjvValidationError) => Error | false
36
47
  }
37
48
 
38
49
  export enum CommonDaoLogLevel {
@@ -48,9 +59,13 @@ export enum CommonDaoLogLevel {
48
59
  export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId, TM> {
49
60
  db: CommonDB
50
61
  table: string
51
- dbmSchema?: ObjectSchemaTyped<DBM>
52
- bmSchema?: ObjectSchemaTyped<BM>
53
- tmSchema?: ObjectSchemaTyped<TM>
62
+
63
+ /**
64
+ * Joi or AjvSchema are supported.
65
+ */
66
+ dbmSchema?: ObjectSchemaTyped<DBM> | AjvSchema<DBM>
67
+ bmSchema?: ObjectSchemaTyped<BM> | AjvSchema<BM>
68
+ tmSchema?: ObjectSchemaTyped<TM> | AjvSchema<TM>
54
69
 
55
70
  excludeFromIndexes?: string[]
56
71
 
@@ -70,22 +85,6 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends Obje
70
85
  */
71
86
  logStarted?: boolean
72
87
 
73
- /**
74
- * @default false
75
- */
76
- throwOnEntityValidationError?: boolean
77
-
78
- /**
79
- * @default to throwOnEntityValidationError setting
80
- */
81
- throwOnDaoCreateObject?: boolean
82
-
83
- /**
84
- * Called when validation error occurs.
85
- * Called ONLY when error is NOT thrown (when throwOnEntityValidationError is off)
86
- */
87
- onValidationError?: (err: JoiValidationError) => any
88
-
89
88
  // Hooks are designed with inspiration from got/ky interface
90
89
  hooks?: Partial<CommonDaoHooks<BM, DBM, TM>>
91
90
 
@@ -127,11 +126,6 @@ export interface CommonDaoOptions extends CommonDBOptions {
127
126
  */
128
127
  raw?: boolean
129
128
 
130
- /**
131
- * @default inherited from CommonDaoCfg.throwOnEntityValidationError
132
- */
133
- throwOnError?: boolean
134
-
135
129
  /**
136
130
  * @default false
137
131
  */
@@ -170,6 +164,7 @@ export interface CommonDaoSaveOptions extends CommonDaoOptions, CommonDBSaveOpti
170
164
 
171
165
  export interface CommonDaoStreamForEachOptions<IN>
172
166
  extends CommonDaoStreamOptions,
167
+ TransformMapOptions<IN, any>,
173
168
  TransformLogProgressOptions<IN> {}
174
169
 
175
170
  export interface CommonDaoStreamOptions extends CommonDaoOptions {
@@ -2,14 +2,18 @@ import {
2
2
  AppError,
3
3
  AsyncMapper,
4
4
  ErrorMode,
5
+ JsonSchemaObject,
5
6
  _filterNullishValues,
6
7
  _passthroughPredicate,
7
8
  _since,
8
9
  _truncate,
9
10
  } from '@naturalcycles/js-lib'
10
11
  import {
12
+ AjvSchema,
13
+ AjvValidationError,
11
14
  Debug,
12
15
  getValidationResult,
16
+ JoiValidationError,
13
17
  ObjectSchemaTyped,
14
18
  ReadableTyped,
15
19
  stringId,
@@ -24,7 +28,6 @@ import {
24
28
  import { DBLibError } from '../cnst'
25
29
  import { DBModelType, ObjectWithId, RunQueryResult, Saved } from '../db.model'
26
30
  import { DBQuery, RunnableDBQuery } from '../query/dbQuery'
27
- import { CommonSchema } from '../schema/common.schema'
28
31
  import {
29
32
  CommonDaoCfg,
30
33
  CommonDaoCreateOptions,
@@ -66,6 +69,7 @@ export class CommonDao<
66
69
  beforeTMToBM: tm => tm as any,
67
70
  beforeBMToTM: bm => bm as any,
68
71
  anonymize: dbm => dbm,
72
+ onValidationError: err => err,
69
73
  ...cfg.hooks,
70
74
  },
71
75
  }
@@ -73,10 +77,6 @@ export class CommonDao<
73
77
 
74
78
  // CREATE
75
79
  create(input: Partial<BM>, opt: CommonDaoOptions = {}): Saved<BM> {
76
- if (opt.throwOnError === undefined) {
77
- opt.throwOnError = this.cfg.throwOnDaoCreateObject
78
- }
79
-
80
80
  let bm = this.cfg.hooks!.beforeCreate!(input)
81
81
  bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
82
82
 
@@ -804,7 +804,7 @@ export class CommonDao<
804
804
  // tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
805
805
 
806
806
  // TM > BM
807
- const bm = this.cfg.hooks!.beforeTMToBM!(tm)
807
+ const bm = this.cfg.hooks!.beforeTMToBM!(tm) as BM
808
808
 
809
809
  // Validate/convert BM
810
810
  return this.validateAndConvert<BM>(bm, this.cfg.bmSchema, DBModelType.BM, opt)
@@ -818,11 +818,12 @@ export class CommonDao<
818
818
  /**
819
819
  * Returns *converted value*.
820
820
  * Validates (unless `skipValidation=true` passed).
821
- * Throws only if `throwOnError=true` passed OR if `env().throwOnEntityValidationError`
821
+ *
822
+ * Does NOT mutate the object.
822
823
  */
823
- validateAndConvert<IN = any, OUT = IN>(
824
+ validateAndConvert<IN, OUT = IN>(
824
825
  obj: IN,
825
- schema?: ObjectSchemaTyped<IN>,
826
+ schema?: ObjectSchemaTyped<IN> | AjvSchema<IN>,
826
827
  modelType?: DBModelType,
827
828
  opt: CommonDaoOptions = {},
828
829
  ): OUT {
@@ -844,32 +845,42 @@ export class CommonDao<
844
845
 
845
846
  // This will Convert and Validate
846
847
  const table = opt.table || this.cfg.table
847
- const { value, error } = getValidationResult<IN, OUT>(obj, schema, table + (modelType || ''))
848
+ const objectName = table + (modelType || '')
849
+
850
+ let error: JoiValidationError | AjvValidationError | undefined
851
+ let convertedValue: any
852
+
853
+ if (schema instanceof AjvSchema) {
854
+ // Ajv schema
855
+ convertedValue = obj // because Ajv mutates original object
856
+
857
+ error = schema.getValidationError(obj, {
858
+ objectName,
859
+ })
860
+ } else {
861
+ // Joi
862
+ const vr = getValidationResult<IN, OUT>(obj, schema, objectName)
863
+ error = vr.error
864
+ convertedValue = vr.value
865
+ }
848
866
 
849
867
  // If we care about validation and there's an error
850
868
  if (error && !opt.skipValidation) {
851
- if (
852
- opt.throwOnError ||
853
- (this.cfg.throwOnEntityValidationError && opt.throwOnError === undefined)
854
- ) {
855
- throw error
856
- } else {
857
- // capture by Sentry and ignore the error
858
- // It will still *convert* the value and return.
859
- this.cfg.onValidationError?.(error)
860
- }
869
+ const processedError = this.cfg.hooks!.onValidationError!(error)
870
+
871
+ if (processedError) throw processedError
861
872
  }
862
873
 
863
- return value // converted value
874
+ return convertedValue
864
875
  }
865
876
 
866
- async getTableSchema(): Promise<CommonSchema> {
877
+ async getTableSchema(): Promise<JsonSchemaObject<DBM>> {
867
878
  return await this.cfg.db.getTableSchema<DBM>(this.cfg.table)
868
879
  }
869
880
 
870
- async createTable(schema: CommonSchema, opt?: CommonDaoCreateOptions): Promise<void> {
881
+ async createTable(schema: JsonSchemaObject<DBM>, opt?: CommonDaoCreateOptions): Promise<void> {
871
882
  this.requireWriteAccess()
872
- await this.cfg.db.createTable(schema, opt)
883
+ await this.cfg.db.createTable(this.cfg.table, schema as any, opt)
873
884
  }
874
885
 
875
886
  /**
package/src/index.ts CHANGED
@@ -67,8 +67,6 @@ import {
67
67
  DBQueryOrder,
68
68
  RunnableDBQuery,
69
69
  } from './query/dbQuery'
70
- import { CommonSchema, CommonSchemaField, DATA_TYPE } from './schema/common.schema'
71
- import { CommonSchemaGenerator, CommonSchemaGeneratorCfg } from './schema/commonSchemaGenerator'
72
70
  import { DBTransaction, RunnableDBTransaction } from './transaction/dbTransaction'
73
71
  import { commitDBTransactionSimple, mergeDBOperations } from './transaction/dbTransaction.util'
74
72
 
@@ -110,9 +108,6 @@ export type {
110
108
  DBPipelineBackupOptions,
111
109
  DBPipelineRestoreOptions,
112
110
  DBPipelineCopyOptions,
113
- CommonSchema,
114
- CommonSchemaField,
115
- CommonSchemaGeneratorCfg,
116
111
  CommonDBAdapter,
117
112
  DBOperation,
118
113
  DBSaveBatchOperation,
@@ -143,7 +138,6 @@ export {
143
138
  dbPipelineBackup,
144
139
  dbPipelineRestore,
145
140
  dbPipelineCopy,
146
- DATA_TYPE,
147
141
  getDB,
148
142
  DBLibError,
149
143
  BaseCommonDB,
@@ -151,6 +145,5 @@ export {
151
145
  RunnableDBTransaction,
152
146
  mergeDBOperations,
153
147
  commitDBTransactionSimple,
154
- CommonSchemaGenerator,
155
148
  CommonKeyValueDao,
156
149
  }
@@ -15,7 +15,6 @@ import * as fs from 'fs-extra'
15
15
  import { createGzip, ZlibOptions } from 'zlib'
16
16
  import { CommonDB } from '../common.db'
17
17
  import { DBQuery } from '../index'
18
- import { CommonSchemaGenerator } from '../schema/commonSchemaGenerator'
19
18
 
20
19
  export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
21
20
  /**
@@ -102,7 +101,7 @@ export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
102
101
  * @default false
103
102
  * If true - will use CommonSchemaGenerator to detect schema from input data.
104
103
  */
105
- emitSchemaFromData?: boolean
104
+ // emitSchemaFromData?: boolean
106
105
 
107
106
  /**
108
107
  * @default false
@@ -140,7 +139,6 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
140
139
  transformMapOptions,
141
140
  errorMode = ErrorMode.SUPPRESS,
142
141
  emitSchemaFromDB = false,
143
- emitSchemaFromData = false,
144
142
  sortObjects = false,
145
143
  } = opt
146
144
  const strict = errorMode !== ErrorMode.SUPPRESS
@@ -193,10 +191,6 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
193
191
  console.log(`>> ${grey(schemaFilePath)} saved (generated from DB)`)
194
192
  }
195
193
 
196
- const schemaGen = emitSchemaFromData
197
- ? new CommonSchemaGenerator({ table, sortedFields: true })
198
- : undefined
199
-
200
194
  await _pipeline([
201
195
  db.streamQuery(q),
202
196
  transformLogProgress({
@@ -210,9 +204,8 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
210
204
  ...transformMapOptions,
211
205
  metric: table,
212
206
  }),
213
- transformTap(row => {
207
+ transformTap(() => {
214
208
  rows++
215
- if (schemaGen) schemaGen.add(row)
216
209
  }),
217
210
  transformToNDJson({ strict, sortObjects }),
218
211
  ...(gzip ? [createGzip(zlibOptions)] : []), // optional gzip
@@ -229,12 +222,6 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
229
222
 
230
223
  console.log(`>> ${grey(filePath)}\n` + stats.toPretty())
231
224
 
232
- if (schemaGen) {
233
- const schema = schemaGen.generate()
234
- await fs.writeJson(schemaFilePath, schema, { spaces: 2 })
235
- console.log(`>> ${grey(schemaFilePath)} saved (generated from data)`)
236
- }
237
-
238
225
  statsPerTable[table] = stats
239
226
  },
240
227
  { concurrency, errorMode },
@@ -179,7 +179,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
179
179
  }
180
180
 
181
181
  const schema = await fs.readJson(schemaFilePath)
182
- await db.createTable(schema, { dropIfExists: true })
182
+ await db.createTable(table, schema, { dropIfExists: true })
183
183
  })
184
184
  }
185
185
 
@@ -97,7 +97,7 @@ export function runCommonDBTest(
97
97
  // CREATE TABLE, DROP
98
98
  if (createTable) {
99
99
  test('createTable, dropIfExists=true', async () => {
100
- await db.createTable(getTestItemSchema(), { dropIfExists: true })
100
+ await db.createTable(TEST_TABLE, getTestItemSchema(), { dropIfExists: true })
101
101
  })
102
102
  }
103
103
 
@@ -41,8 +41,10 @@ export function runCommonKeyValueDBTest(db: CommonKeyValueDB): void {
41
41
 
42
42
  test('streamIds limited', async () => {
43
43
  const idsLimited = await readableToArray(db.streamIds(TEST_TABLE, 2))
44
- idsLimited.sort()
45
- expect(idsLimited).toEqual(testIds.slice(0, 2))
44
+ // Order is non-deterministic, so, cannot compare values
45
+ // idsLimited.sort()
46
+ // expect(idsLimited).toEqual(testIds.slice(0, 2))
47
+ expect(idsLimited.length).toBe(2)
46
48
  })
47
49
 
48
50
  test('streamValues', async () => {
@@ -53,8 +55,9 @@ export function runCommonKeyValueDBTest(db: CommonKeyValueDB): void {
53
55
 
54
56
  test('streamValues limited', async () => {
55
57
  const valuesLimited = await readableToArray(db.streamValues(TEST_TABLE, 2))
56
- valuesLimited.sort()
57
- expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
58
+ // valuesLimited.sort()
59
+ // expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
60
+ expect(valuesLimited.length).toBe(2)
58
61
  })
59
62
 
60
63
  test('streamEntries', async () => {
@@ -65,8 +68,9 @@ export function runCommonKeyValueDBTest(db: CommonKeyValueDB): void {
65
68
 
66
69
  test('streamEntries limited', async () => {
67
70
  const entriesLimited = await readableToArray(db.streamEntries(TEST_TABLE, 2))
68
- entriesLimited.sort()
69
- expect(entriesLimited).toEqual(testEntries.slice(0, 2))
71
+ // entriesLimited.sort()
72
+ // expect(entriesLimited).toEqual(testEntries.slice(0, 2))
73
+ expect(entriesLimited.length).toBe(2)
70
74
  })
71
75
 
72
76
  test('deleteByIds should clear', async () => {