@naturalcycles/db-lib 10.10.1 → 10.12.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.
@@ -2,9 +2,6 @@ import type { Transform } from 'node:stream';
2
2
  import type { JsonSchemaObject, JsonSchemaRootObject } from '@naturalcycles/js-lib/json-schema';
3
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log';
4
4
  import type { AsyncIndexedMapper, BaseDBEntity, StringMap, UnixTimestampMillis, Unsaved } from '@naturalcycles/js-lib/types';
5
- import { ZodType } from '@naturalcycles/js-lib/zod';
6
- import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv';
7
- import { type ObjectSchema } from '@naturalcycles/nodejs-lib/joi';
8
5
  import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream';
9
6
  import type { CommonDBTransactionOptions, DBTransaction, RunQueryResult } from '../db.model.js';
10
7
  import type { DBQuery } from '../query/dbQuery.js';
@@ -163,8 +160,7 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
163
160
  * Does NOT mutate the object.
164
161
  * Validates (unless `skipValidation=true` passed).
165
162
  */
166
- validateAndConvert<T>(obj: Partial<T>, schema: ObjectSchema<T> | AjvSchema<T> | ZodType<T> | undefined, op?: 'load' | 'save', // this is to skip validation if validateOnLoad/Save is false
167
- opt?: CommonDaoOptions): any;
163
+ private validateAndConvert;
168
164
  getTableSchema(): Promise<JsonSchemaRootObject<DBM>>;
169
165
  createTable(schema: JsonSchemaObject<DBM>, opt?: CommonDaoCreateOptions): Promise<void>;
170
166
  /**
@@ -8,10 +8,7 @@ import { _deepCopy, _filterUndefinedValues, _objectAssignExact, } from '@natural
8
8
  import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
9
9
  import { _truncate } from '@naturalcycles/js-lib/string/string.util.js';
10
10
  import { _passthroughPredicate, _typeCast, SKIP } from '@naturalcycles/js-lib/types';
11
- import { ZodType, zSafeValidate } from '@naturalcycles/js-lib/zod';
12
11
  import { stringId } from '@naturalcycles/nodejs-lib';
13
- import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv';
14
- import { getValidationResult, } from '@naturalcycles/nodejs-lib/joi';
15
12
  import { _pipeline, transformChunk, transformLogProgress, transformMap, transformNoOp, writableVoid, } from '@naturalcycles/nodejs-lib/stream';
16
13
  import { DBLibError } from '../cnst.js';
17
14
  import { RunnableDBQuery } from '../query/dbQuery.js';
@@ -57,7 +54,7 @@ export class CommonDao {
57
54
  const bm = this.cfg.hooks.beforeCreate(part);
58
55
  // First assignIdCreatedUpdated, then validate!
59
56
  this.assignIdCreatedUpdated(bm, opt);
60
- return this.validateAndConvert(bm, this.cfg.bmSchema, undefined, opt);
57
+ return this.validateAndConvert(bm, undefined, opt);
61
58
  }
62
59
  // GET
63
60
  // overrides are disabled now, as they obfuscate errors when ID branded type is used
@@ -592,7 +589,7 @@ export class CommonDao {
592
589
  // We compare with convertedBM, to account for cases when some extra property is assigned to bm,
593
590
  // which should be removed post-validation, but it breaks the "equality check"
594
591
  // Post-validation the equality check should work as intended
595
- const convertedBM = this.validateAndConvert(bm, this.cfg.bmSchema, 'save', opt);
592
+ const convertedBM = this.validateAndConvert(bm, 'save', opt);
596
593
  if (_deepJsonEquals(convertedBM, opt.skipIfEquals)) {
597
594
  // Skipping the save operation
598
595
  return bm;
@@ -901,7 +898,7 @@ export class CommonDao {
901
898
  // DBM > BM
902
899
  const bm = ((await this.cfg.hooks.beforeDBMToBM?.(dbm)) || dbm);
903
900
  // Validate/convert BM
904
- return this.validateAndConvert(bm, this.cfg.bmSchema, 'load', opt);
901
+ return this.validateAndConvert(bm, 'load', opt);
905
902
  }
906
903
  async dbmsToBM(dbms, opt = {}) {
907
904
  return await pMap(dbms, async (dbm) => await this.dbmToBM(dbm, opt));
@@ -910,7 +907,7 @@ export class CommonDao {
910
907
  if (bm === undefined)
911
908
  return;
912
909
  // bm gets assigned to the new reference
913
- bm = this.validateAndConvert(bm, this.cfg.bmSchema, 'save', opt);
910
+ bm = this.validateAndConvert(bm, 'save', opt);
914
911
  // BM > DBM
915
912
  return ((await this.cfg.hooks.beforeBMToDBM?.(bm)) || bm);
916
913
  }
@@ -941,58 +938,26 @@ export class CommonDao {
941
938
  * Does NOT mutate the object.
942
939
  * Validates (unless `skipValidation=true` passed).
943
940
  */
944
- validateAndConvert(obj, schema, op, // this is to skip validation if validateOnLoad/Save is false
941
+ validateAndConvert(input, op, // this is to skip validation if validateOnLoad/Save is false
945
942
  opt = {}) {
946
- // Kirill 2021-10-18: I realized that there's little reason to keep removing null values
947
- // So, from now on we'll preserve them
948
- // "undefined" values, I believe, are/were not saved to/from DB anyway (due to e.g JSON.stringify removing them)
949
- // But let's keep watching it!
950
- //
951
- // Filter null and undefined values
952
- // obj = _filterNullishValues(obj as any)
953
943
  // We still filter `undefined` values here, because `beforeDBMToBM` can return undefined values
954
944
  // and they can be annoying with snapshot tests
955
- obj = _filterUndefinedValues(obj);
945
+ input = _filterUndefinedValues(input);
956
946
  // Return as is if no schema is passed or if `skipConversion` is set
957
- if ((!schema && !this.cfg.validateBM) ||
947
+ if (!this.cfg.validateBM ||
958
948
  opt.skipValidation ||
959
949
  (op === 'load' && !this.cfg.validateOnLoad) ||
960
950
  (op === 'save' && !this.cfg.validateOnSave)) {
961
- return obj;
962
- }
963
- // This will Convert and Validate
964
- const table = opt.table || this.cfg.table;
965
- const objectName = table;
966
- let error;
967
- let convertedValue;
968
- if (this.cfg.validateBM) {
969
- const [err, value] = this.cfg.validateBM(obj, {
970
- inputName: table,
971
- });
972
- error = err;
973
- convertedValue = value;
974
- }
975
- else if (schema instanceof ZodType) {
976
- // Zod schema
977
- const [err, value] = zSafeValidate(obj, schema);
978
- error = err;
979
- convertedValue = value;
951
+ return input;
980
952
  }
981
- else if (schema instanceof AjvSchema) {
982
- // Ajv schema
983
- const [err, value] = schema.getValidationResult(obj, {
984
- objectName,
985
- });
986
- error = err;
987
- convertedValue = value;
988
- }
989
- else {
990
- // Joi
991
- const [err, value] = getValidationResult(obj, schema, objectName);
992
- error = err;
993
- convertedValue = value;
994
- }
995
- // If we care about validation and there's an error
953
+ const inputName = opt.table || this.cfg.table;
954
+ const [error, convertedValue] = this.cfg.validateBM(input, {
955
+ // Passing `mutateInput` through allows to do opt-in mutation
956
+ // for individual operations, e.g `someDao.save(myObj, { mutateInput: true })`,
957
+ // while still keeping safe non-mutating behavior by default
958
+ mutateInput: opt.mutateInput,
959
+ inputName,
960
+ });
996
961
  if (error) {
997
962
  const processedError = this.cfg.hooks.onValidationError(error);
998
963
  if (processedError)
@@ -1,10 +1,7 @@
1
1
  import type { ValidationFunction } from '@naturalcycles/js-lib';
2
- import type { ErrorMode } from '@naturalcycles/js-lib/error';
2
+ import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error';
3
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log';
4
4
  import type { BaseDBEntity, NumberOfMilliseconds, Promisable, UnixTimestamp } from '@naturalcycles/js-lib/types';
5
- import type { ZodType, ZodValidationError } from '@naturalcycles/js-lib/zod';
6
- import type { AjvSchema, AjvValidationError } from '@naturalcycles/nodejs-lib/ajv';
7
- import type { JoiValidationError, ObjectSchema } from '@naturalcycles/nodejs-lib/joi';
8
5
  import type { TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib/stream';
9
6
  import type { CommonDB } from '../commondb/common.db.js';
10
7
  import type { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model.js';
@@ -79,7 +76,7 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
79
76
  * Return original `err` to pass the error through (will be thrown in CommonDao).
80
77
  * Return modified/new `Error` if needed.
81
78
  */
82
- onValidationError: (err: JoiValidationError | AjvValidationError | ZodValidationError) => Error | false;
79
+ onValidationError: (err: AppError) => Error | false;
83
80
  }
84
81
  export declare enum CommonDaoLogLevel {
85
82
  /**
@@ -102,17 +99,11 @@ export declare enum CommonDaoLogLevel {
102
99
  export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID = BM['id']> {
103
100
  db: CommonDB;
104
101
  table: string;
105
- /**
106
- * Joi, AjvSchema or ZodSchema is supported.
107
- */
108
- bmSchema?: ObjectSchema<BM> | AjvSchema<BM> | ZodType<BM>;
109
102
  /**
110
103
  * Experimental alternative to bmSchema.
111
104
  * "Bring your own validation function".
112
105
  * It removes the knowledge from CommonDao about the validation library used
113
106
  * and abstracts it away.
114
- *
115
- * @experimental
116
107
  */
117
108
  validateBM?: ValidationFunction<BM, any>;
118
109
  excludeFromIndexes?: (keyof DBM)[];
@@ -190,10 +181,22 @@ export interface CommonDaoOptions extends CommonDBOptions {
190
181
  /**
191
182
  * Defaults to false.
192
183
  *
193
- * If set to true - will disable validation (and conversion).
194
- * One possible use case of doing this is - performance (as validation/conversion takes time, especially with Joi).
184
+ * If set to true - will disable validation.
185
+ * One possible use case of doing this is - performance (as validation/transformation takes time, especially with Joi).
195
186
  */
196
187
  skipValidation?: boolean;
188
+ /**
189
+ * Default to false.
190
+ *
191
+ * False ensures that the input is not mutated by the Validation function (`validateBM`).
192
+ *
193
+ * True ensures the opposite - that the Validation function will mutate the input object
194
+ * if it needs to apply transformations, such as:
195
+ * - stripping unknown properties
196
+ * - converting types (e.g. string to number)
197
+ * - applying transformations (which as string trim, toLowerCase, etc)
198
+ */
199
+ mutateInput?: boolean;
197
200
  /**
198
201
  * @default false
199
202
  */
@@ -2,6 +2,7 @@ import { Readable } from 'node:stream';
2
2
  import { _sortBy } from '@naturalcycles/js-lib/array/array.util.js';
3
3
  import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js';
4
4
  import { _deepCopy, _filterObject, _omit, _pick } from '@naturalcycles/js-lib/object';
5
+ import { getJoiValidationFunction } from '@naturalcycles/nodejs-lib/joi';
5
6
  import { _pipeline } from '@naturalcycles/nodejs-lib/stream';
6
7
  import { CommonDao } from '../commondao/common.dao.js';
7
8
  import { CommonDaoLogLevel } from '../commondao/common.dao.model.js';
@@ -14,7 +15,7 @@ export async function runCommonDaoTest(db, quirks = {}) {
14
15
  const dao = new CommonDao({
15
16
  table: TEST_TABLE,
16
17
  db,
17
- bmSchema: testItemBMSchema,
18
+ validateBM: getJoiValidationFunction(testItemBMSchema),
18
19
  logStarted: true,
19
20
  logLevel: CommonDaoLogLevel.DATA_FULL,
20
21
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/db-lib",
3
3
  "type": "module",
4
- "version": "10.10.1",
4
+ "version": "10.12.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@naturalcycles/nodejs-lib": "^15"
@@ -1,5 +1,5 @@
1
1
  import type { ValidationFunction } from '@naturalcycles/js-lib'
2
- import type { ErrorMode } from '@naturalcycles/js-lib/error'
2
+ import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error'
3
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log'
4
4
  import type {
5
5
  BaseDBEntity,
@@ -7,9 +7,6 @@ import type {
7
7
  Promisable,
8
8
  UnixTimestamp,
9
9
  } from '@naturalcycles/js-lib/types'
10
- import type { ZodType, ZodValidationError } from '@naturalcycles/js-lib/zod'
11
- import type { AjvSchema, AjvValidationError } from '@naturalcycles/nodejs-lib/ajv'
12
- import type { JoiValidationError, ObjectSchema } from '@naturalcycles/nodejs-lib/joi'
13
10
  import type {
14
11
  TransformLogProgressOptions,
15
12
  TransformMapOptions,
@@ -96,9 +93,7 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
96
93
  * Return original `err` to pass the error through (will be thrown in CommonDao).
97
94
  * Return modified/new `Error` if needed.
98
95
  */
99
- onValidationError: (
100
- err: JoiValidationError | AjvValidationError | ZodValidationError,
101
- ) => Error | false
96
+ onValidationError: (err: AppError) => Error | false
102
97
  }
103
98
 
104
99
  export enum CommonDaoLogLevel {
@@ -128,18 +123,11 @@ export interface CommonDaoCfg<
128
123
  db: CommonDB
129
124
  table: string
130
125
 
131
- /**
132
- * Joi, AjvSchema or ZodSchema is supported.
133
- */
134
- bmSchema?: ObjectSchema<BM> | AjvSchema<BM> | ZodType<BM>
135
-
136
126
  /**
137
127
  * Experimental alternative to bmSchema.
138
128
  * "Bring your own validation function".
139
129
  * It removes the knowledge from CommonDao about the validation library used
140
130
  * and abstracts it away.
141
- *
142
- * @experimental
143
131
  */
144
132
  validateBM?: ValidationFunction<BM, any>
145
133
 
@@ -233,11 +221,24 @@ export interface CommonDaoOptions extends CommonDBOptions {
233
221
  /**
234
222
  * Defaults to false.
235
223
  *
236
- * If set to true - will disable validation (and conversion).
237
- * One possible use case of doing this is - performance (as validation/conversion takes time, especially with Joi).
224
+ * If set to true - will disable validation.
225
+ * One possible use case of doing this is - performance (as validation/transformation takes time, especially with Joi).
238
226
  */
239
227
  skipValidation?: boolean
240
228
 
229
+ /**
230
+ * Default to false.
231
+ *
232
+ * False ensures that the input is not mutated by the Validation function (`validateBM`).
233
+ *
234
+ * True ensures the opposite - that the Validation function will mutate the input object
235
+ * if it needs to apply transformations, such as:
236
+ * - stripping unknown properties
237
+ * - converting types (e.g. string to number)
238
+ * - applying transformations (which as string trim, toLowerCase, etc)
239
+ */
240
+ mutateInput?: boolean
241
+
241
242
  /**
242
243
  * @default false
243
244
  */
@@ -23,15 +23,7 @@ import type {
23
23
  Unsaved,
24
24
  } from '@naturalcycles/js-lib/types'
25
25
  import { _passthroughPredicate, _typeCast, SKIP } from '@naturalcycles/js-lib/types'
26
- import type { ZodValidationError } from '@naturalcycles/js-lib/zod'
27
- import { ZodType, zSafeValidate } from '@naturalcycles/js-lib/zod'
28
26
  import { stringId } from '@naturalcycles/nodejs-lib'
29
- import { AjvSchema, type AjvValidationError } from '@naturalcycles/nodejs-lib/ajv'
30
- import {
31
- getValidationResult,
32
- type JoiValidationError,
33
- type ObjectSchema,
34
- } from '@naturalcycles/nodejs-lib/joi'
35
27
  import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
36
28
  import {
37
29
  _pipeline,
@@ -102,7 +94,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
102
94
  const bm = this.cfg.hooks!.beforeCreate!(part)
103
95
  // First assignIdCreatedUpdated, then validate!
104
96
  this.assignIdCreatedUpdated(bm, opt)
105
- return this.validateAndConvert(bm, this.cfg.bmSchema, undefined, opt)
97
+ return this.validateAndConvert(bm, undefined, opt)
106
98
  }
107
99
 
108
100
  // GET
@@ -767,7 +759,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
767
759
  // We compare with convertedBM, to account for cases when some extra property is assigned to bm,
768
760
  // which should be removed post-validation, but it breaks the "equality check"
769
761
  // Post-validation the equality check should work as intended
770
- const convertedBM = this.validateAndConvert(bm as Partial<BM>, this.cfg.bmSchema, 'save', opt)
762
+ const convertedBM = this.validateAndConvert(bm as Partial<BM>, 'save', opt)
771
763
  if (_deepJsonEquals(convertedBM, opt.skipIfEquals)) {
772
764
  // Skipping the save operation
773
765
  return bm as BM
@@ -1150,7 +1142,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1150
1142
  const bm = ((await this.cfg.hooks!.beforeDBMToBM?.(dbm)) || dbm) as Partial<BM>
1151
1143
 
1152
1144
  // Validate/convert BM
1153
- return this.validateAndConvert(bm, this.cfg.bmSchema, 'load', opt)
1145
+ return this.validateAndConvert(bm, 'load', opt)
1154
1146
  }
1155
1147
 
1156
1148
  async dbmsToBM(dbms: DBM[], opt: CommonDaoOptions = {}): Promise<BM[]> {
@@ -1167,10 +1159,10 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1167
1159
  if (bm === undefined) return
1168
1160
 
1169
1161
  // bm gets assigned to the new reference
1170
- bm = this.validateAndConvert(bm, this.cfg.bmSchema, 'save', opt)
1162
+ bm = this.validateAndConvert(bm, 'save', opt)
1171
1163
 
1172
1164
  // BM > DBM
1173
- return ((await this.cfg.hooks!.beforeBMToDBM?.(bm!)) || bm) as DBM
1165
+ return ((await this.cfg.hooks!.beforeBMToDBM?.(bm)) || bm) as DBM
1174
1166
  }
1175
1167
 
1176
1168
  async bmsToDBM(bms: BM[], opt: CommonDaoOptions = {}): Promise<DBM[]> {
@@ -1208,69 +1200,37 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1208
1200
  * Does NOT mutate the object.
1209
1201
  * Validates (unless `skipValidation=true` passed).
1210
1202
  */
1211
- validateAndConvert<T>(
1212
- obj: Partial<T>,
1213
- schema: ObjectSchema<T> | AjvSchema<T> | ZodType<T> | undefined,
1203
+ private validateAndConvert(
1204
+ input: Partial<BM>,
1214
1205
  op?: 'load' | 'save', // this is to skip validation if validateOnLoad/Save is false
1215
1206
  opt: CommonDaoOptions = {},
1216
- ): any {
1217
- // Kirill 2021-10-18: I realized that there's little reason to keep removing null values
1218
- // So, from now on we'll preserve them
1219
- // "undefined" values, I believe, are/were not saved to/from DB anyway (due to e.g JSON.stringify removing them)
1220
- // But let's keep watching it!
1221
- //
1222
- // Filter null and undefined values
1223
- // obj = _filterNullishValues(obj as any)
1207
+ ): BM {
1224
1208
  // We still filter `undefined` values here, because `beforeDBMToBM` can return undefined values
1225
1209
  // and they can be annoying with snapshot tests
1226
- obj = _filterUndefinedValues(obj)
1210
+ input = _filterUndefinedValues(input)
1227
1211
 
1228
1212
  // Return as is if no schema is passed or if `skipConversion` is set
1229
1213
  if (
1230
- (!schema && !this.cfg.validateBM) ||
1214
+ !this.cfg.validateBM ||
1231
1215
  opt.skipValidation ||
1232
1216
  (op === 'load' && !this.cfg.validateOnLoad) ||
1233
1217
  (op === 'save' && !this.cfg.validateOnSave)
1234
1218
  ) {
1235
- return obj
1219
+ return input as BM
1236
1220
  }
1237
1221
 
1238
- // This will Convert and Validate
1239
- const table = opt.table || this.cfg.table
1240
- const objectName = table
1222
+ const inputName = opt.table || this.cfg.table
1241
1223
 
1242
- let error: JoiValidationError | AjvValidationError | ZodValidationError | null | undefined
1243
- let convertedValue: any
1244
-
1245
- if (this.cfg.validateBM) {
1246
- const [err, value] = this.cfg.validateBM(obj as any as BM, {
1247
- inputName: table,
1248
- })
1249
- error = err
1250
- convertedValue = value
1251
- } else if (schema instanceof ZodType) {
1252
- // Zod schema
1253
- const [err, value] = zSafeValidate(obj as T, schema)
1254
- error = err
1255
- convertedValue = value
1256
- } else if (schema instanceof AjvSchema) {
1257
- // Ajv schema
1258
- const [err, value] = schema.getValidationResult(obj as T, {
1259
- objectName,
1260
- })
1261
- error = err
1262
- convertedValue = value
1263
- } else {
1264
- // Joi
1265
- const [err, value] = getValidationResult(obj, schema, objectName)
1266
- error = err
1267
- convertedValue = value
1268
- }
1224
+ const [error, convertedValue] = this.cfg.validateBM(input as BM, {
1225
+ // Passing `mutateInput` through allows to do opt-in mutation
1226
+ // for individual operations, e.g `someDao.save(myObj, { mutateInput: true })`,
1227
+ // while still keeping safe non-mutating behavior by default
1228
+ mutateInput: opt.mutateInput,
1229
+ inputName,
1230
+ })
1269
1231
 
1270
- // If we care about validation and there's an error
1271
1232
  if (error) {
1272
1233
  const processedError = this.cfg.hooks!.onValidationError!(error)
1273
-
1274
1234
  if (processedError) throw processedError
1275
1235
  }
1276
1236
 
@@ -2,6 +2,7 @@ import { Readable } from 'node:stream'
2
2
  import { _sortBy } from '@naturalcycles/js-lib/array/array.util.js'
3
3
  import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js'
4
4
  import { _deepCopy, _filterObject, _omit, _pick } from '@naturalcycles/js-lib/object'
5
+ import { getJoiValidationFunction } from '@naturalcycles/nodejs-lib/joi'
5
6
  import { _pipeline } from '@naturalcycles/nodejs-lib/stream'
6
7
  import { CommonDao } from '../commondao/common.dao.js'
7
8
  import { CommonDaoLogLevel } from '../commondao/common.dao.model.js'
@@ -28,7 +29,7 @@ export async function runCommonDaoTest(
28
29
  const dao = new CommonDao({
29
30
  table: TEST_TABLE,
30
31
  db,
31
- bmSchema: testItemBMSchema,
32
+ validateBM: getJoiValidationFunction(testItemBMSchema),
32
33
  logStarted: true,
33
34
  logLevel: CommonDaoLogLevel.DATA_FULL,
34
35
  })