@e22m4u/js-repository 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,6 @@
15
15
  - [Источник данных](#источник-данных)
16
16
  - [Модель](#модель)
17
17
  - [Свойства](#свойства)
18
- - [Пустые значения](#пустые-значения)
19
18
  - [Репозиторий](#репозиторий)
20
19
  - [create](#repositorycreate)
21
20
  - [replaceById](#repositoryreplacebyid)
@@ -390,7 +389,7 @@ dbs.defineModel({
390
389
  - `columnName: string` переопределение названия колонки;
391
390
  - `columnType: string` тип колонки (определяется адаптером);
392
391
  - `required: boolean` объявить свойство обязательным;
393
- - `default: any` значение по умолчанию;
392
+ - `default: any` значение по умолчанию (заменяет `undefined` и `null`);
394
393
  - `unique: boolean | string` проверять значение на уникальность;
395
394
 
396
395
  **Параметр `unique`**
@@ -399,15 +398,19 @@ dbs.defineModel({
399
398
  строгая проверка на уникальность. В этом режиме любое значение данного свойства
400
399
  не может быть представлено более одного раза.
401
400
 
402
- Режим `"sparse"` проверяет только значения с полезной нагрузкой, исключая
403
- [пустые значения](#пустые-значения), список которых отличается в зависимости
404
- от типа свойства. Например, для типа `string` пустым значением будет
405
- `undefined`, `null` и `""` (пустая строка).
406
-
407
401
  - `unique: true | 'strict'` строгая проверка на уникальность;
408
- - `unique: 'sparse'` исключить из проверки [пустые значения](#пустые-значения);
402
+ - `unique: 'sparse'` исключить из проверки ложные значения;
409
403
  - `unique: false | 'nonUnique'` не проверять на уникальность (по умолчанию);
410
404
 
405
+ Режим `"sparse"` исключает из проверки на уникальность ложные значения с точки
406
+ зрения JavaScript. Указанные ниже значения будут проигнорированы при проверке
407
+ в данном режиме.
408
+
409
+ - `""` пустая строка;
410
+ - `0` число ноль;
411
+ - `false` логическое отрицание;
412
+ - `undefined` и `null`;
413
+
411
414
  В качестве значений параметра `unique` можно использовать предопределенные
412
415
  константы как эквивалент строковых значений `strict`, `sparse` и `nonUnique`.
413
416
 
@@ -471,25 +474,6 @@ dbs.defineModel({
471
474
  });
472
475
  ```
473
476
 
474
- ## Пустые значения
475
-
476
- Разные типы свойств имеют свои наборы пустых значений. Эти наборы используются
477
- для определения наличия полезной нагрузки в значении свойства. Например,
478
- параметр `default` в определении свойства устанавливает значение по умолчанию,
479
- только если входящее значение является пустым. Параметр `required` исключает
480
- пустые значения выбрасывая ошибку. А параметр `unique` в режиме `sparse`
481
- наоборот допускает дублирование пустых значений уникального свойства,
482
- поскольку они не участвуют в проверке.
483
-
484
- | тип свойства | пустые значения |
485
- |--------------------|----------------------------|
486
- | `DataType.ANY` | *значения остальных типов* |
487
- | `DataType.STRING` | `undefined`, `null`, `""` |
488
- | `DataType.NUMBER` | `undefined`, `null` |
489
- | `DataType.BOOLEAN` | `undefined`, `null` |
490
- | `DataType.ARRAY` | `undefined`, `null` |
491
- | `DataType.OBJECT` | `undefined`, `null` |
492
-
493
477
  ## Репозиторий
494
478
 
495
479
  Репозиторий выполняет операции чтения и записи данных определенной модели.
@@ -1758,13 +1758,12 @@ var init_definition_registry = __esm({
1758
1758
  });
1759
1759
 
1760
1760
  // src/definition/model/model-definition-utils.js
1761
- var import_js_service7, import_js_empty_values, DEFAULT_PRIMARY_KEY_PROPERTY_NAME, _ModelDefinitionUtils, ModelDefinitionUtils;
1761
+ var import_js_service7, DEFAULT_PRIMARY_KEY_PROPERTY_NAME, _ModelDefinitionUtils, ModelDefinitionUtils;
1762
1762
  var init_model_definition_utils = __esm({
1763
1763
  "src/definition/model/model-definition-utils.js"() {
1764
1764
  "use strict";
1765
1765
  import_js_service7 = require("@e22m4u/js-service");
1766
1766
  init_properties();
1767
- import_js_empty_values = require("@e22m4u/js-empty-values");
1768
1767
  init_errors();
1769
1768
  init_definition_registry();
1770
1769
  init_utils();
@@ -1865,7 +1864,7 @@ var init_model_definition_utils = __esm({
1865
1864
  return propDef.default instanceof Function ? propDef.default() : propDef.default;
1866
1865
  }
1867
1866
  /**
1868
- * Set default values for empty properties.
1867
+ * Set default values to empty properties.
1869
1868
  *
1870
1869
  * @param {string} modelName
1871
1870
  * @param {object} modelData
@@ -1876,13 +1875,12 @@ var init_model_definition_utils = __esm({
1876
1875
  const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName);
1877
1876
  const propNames = onlyProvidedProperties ? Object.keys(modelData) : Object.keys(propDefs);
1878
1877
  const extendedData = cloneDeep(modelData);
1879
- const blankValuesService = this.getService(import_js_empty_values.BlankValuesService);
1880
1878
  propNames.forEach((propName) => {
1881
1879
  const propDef = propDefs[propName];
1882
1880
  const propValue = extendedData[propName];
1883
- const propType = propDef != null ? this.getDataTypeFromPropertyDefinition(propDef) : DataType.ANY;
1884
- const isBlank = blankValuesService.isBlankOf(propType, propValue);
1885
- if (!isBlank) return;
1881
+ if (propValue != null) {
1882
+ return;
1883
+ }
1886
1884
  if (propDef && typeof propDef === "object" && propDef.default !== void 0) {
1887
1885
  extendedData[propName] = this.getDefaultPropertyValue(
1888
1886
  modelName,
@@ -2171,13 +2169,12 @@ var init_model_definition_utils = __esm({
2171
2169
  });
2172
2170
 
2173
2171
  // src/definition/model/properties/required-property-validator.js
2174
- var import_js_service8, import_js_empty_values2, _RequiredPropertyValidator, RequiredPropertyValidator;
2172
+ var import_js_service8, _RequiredPropertyValidator, RequiredPropertyValidator;
2175
2173
  var init_required_property_validator = __esm({
2176
2174
  "src/definition/model/properties/required-property-validator.js"() {
2177
2175
  "use strict";
2178
2176
  init_data_type();
2179
2177
  import_js_service8 = require("@e22m4u/js-service");
2180
- import_js_empty_values2 = require("@e22m4u/js-empty-values");
2181
2178
  init_errors();
2182
2179
  init_model_definition_utils();
2183
2180
  _RequiredPropertyValidator = class _RequiredPropertyValidator extends import_js_service8.Service {
@@ -2212,23 +2209,19 @@ var init_required_property_validator = __esm({
2212
2209
  ModelDefinitionUtils
2213
2210
  ).getPropertiesDefinitionInBaseModelHierarchy(modelName);
2214
2211
  const propNames = Object.keys(isPartial ? modelData : propDefs);
2215
- const blankValuesService = this.getService(import_js_empty_values2.BlankValuesService);
2216
2212
  for (const propName of propNames) {
2217
2213
  const propDef = propDefs[propName];
2218
2214
  if (!propDef || typeof propDef !== "object") {
2219
2215
  continue;
2220
2216
  }
2221
2217
  const propValue = modelData[propName];
2222
- if (propDef.required) {
2223
- const propType = propDef.type || DataType.ANY;
2224
- if (blankValuesService.isBlankOf(propType, propValue)) {
2225
- throw new InvalidArgumentError(
2226
- "Property %v of the model %v is required, but %v was given.",
2227
- propName,
2228
- modelName,
2229
- propValue
2230
- );
2231
- }
2218
+ if (propDef.required && propValue == null) {
2219
+ throw new InvalidArgumentError(
2220
+ "Property %v of the model %v is required, but %v was given.",
2221
+ propName,
2222
+ modelName,
2223
+ propValue
2224
+ );
2232
2225
  }
2233
2226
  if (propDef.type === DataType.OBJECT && propDef.model && propValue !== null && typeof propValue === "object" && !Array.isArray(propValue)) {
2234
2227
  this.validate(propDef.model, propValue);
@@ -2248,14 +2241,12 @@ var init_required_property_validator = __esm({
2248
2241
  });
2249
2242
 
2250
2243
  // src/definition/model/properties/property-uniqueness-validator.js
2251
- var import_js_service9, import_js_empty_values3, _PropertyUniquenessValidator, PropertyUniquenessValidator;
2244
+ var import_js_service9, _PropertyUniquenessValidator, PropertyUniquenessValidator;
2252
2245
  var init_property_uniqueness_validator = __esm({
2253
2246
  "src/definition/model/properties/property-uniqueness-validator.js"() {
2254
2247
  "use strict";
2255
- init_data_type();
2256
2248
  import_js_service9 = require("@e22m4u/js-service");
2257
2249
  init_utils();
2258
- import_js_empty_values3 = require("@e22m4u/js-empty-values");
2259
2250
  init_property_uniqueness();
2260
2251
  init_errors();
2261
2252
  init_model_definition_utils();
@@ -2307,17 +2298,14 @@ var init_property_uniqueness_validator = __esm({
2307
2298
  propValue
2308
2299
  ), "createError");
2309
2300
  let willBeReplaced = void 0;
2310
- const blankValuesService = this.getService(import_js_empty_values3.BlankValuesService);
2311
2301
  for (const propName of propNames) {
2312
2302
  const propDef = propDefs[propName];
2313
2303
  if (!propDef || typeof propDef === "string" || !propDef.unique || propDef.unique === PropertyUniqueness.NON_UNIQUE) {
2314
2304
  continue;
2315
2305
  }
2316
2306
  const propValue = modelData[propName];
2317
- if (propDef.unique === PropertyUniqueness.SPARSE) {
2318
- const propType = propDef.type || DataType.ANY;
2319
- const isBlank = blankValuesService.isBlankOf(propType, propValue);
2320
- if (isBlank) continue;
2307
+ if (propDef.unique === PropertyUniqueness.SPARSE && !propValue) {
2308
+ continue;
2321
2309
  }
2322
2310
  if (methodName === "create") {
2323
2311
  const count = await countMethod({ [propName]: propValue });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-repository",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Реализация репозитория для работы с базами данных",
5
5
  "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
6
6
  "license": "MIT",
@@ -39,7 +39,6 @@
39
39
  "prepare": "husky"
40
40
  },
41
41
  "dependencies": {
42
- "@e22m4u/js-empty-values": "~0.4.0",
43
42
  "@e22m4u/js-format": "~0.3.2",
44
43
  "@e22m4u/js-service": "~0.5.1"
45
44
  },
@@ -1,6 +1,5 @@
1
1
  import {Service} from '@e22m4u/js-service';
2
2
  import {DataType} from './properties/index.js';
3
- import {BlankValuesService} from '@e22m4u/js-empty-values';
4
3
  import {InvalidArgumentError} from '../../errors/index.js';
5
4
  import {DefinitionRegistry} from '../definition-registry.js';
6
5
  import {cloneDeep, excludeObjectKeys} from '../../utils/index.js';
@@ -121,7 +120,7 @@ export class ModelDefinitionUtils extends Service {
121
120
  }
122
121
 
123
122
  /**
124
- * Set default values for empty properties.
123
+ * Set default values to empty properties.
125
124
  *
126
125
  * @param {string} modelName
127
126
  * @param {object} modelData
@@ -139,16 +138,14 @@ export class ModelDefinitionUtils extends Service {
139
138
  ? Object.keys(modelData)
140
139
  : Object.keys(propDefs);
141
140
  const extendedData = cloneDeep(modelData);
142
- const blankValuesService = this.getService(BlankValuesService);
143
141
  propNames.forEach(propName => {
144
142
  const propDef = propDefs[propName];
145
143
  const propValue = extendedData[propName];
146
- const propType =
147
- propDef != null
148
- ? this.getDataTypeFromPropertyDefinition(propDef)
149
- : DataType.ANY;
150
- const isBlank = blankValuesService.isBlankOf(propType, propValue);
151
- if (!isBlank) return;
144
+ // если значение свойства не является undefined и null,
145
+ // то свойство пропускается (остается исходное значение)
146
+ if (propValue != null) {
147
+ return;
148
+ }
152
149
  if (
153
150
  propDef &&
154
151
  typeof propDef === 'object' &&
@@ -4,7 +4,6 @@ import {createSandbox} from '@e22m4u/js-spy';
4
4
  import {DataType} from './properties/index.js';
5
5
  import {RelationType} from './relations/index.js';
6
6
  import {DatabaseSchema} from '../../database-schema.js';
7
- import {BlankValuesService} from '@e22m4u/js-empty-values';
8
7
  import {InvalidArgumentError} from '../../errors/index.js';
9
8
 
10
9
  import {
@@ -480,7 +479,7 @@ describe('ModelDefinitionUtils', function () {
480
479
  expect(result).to.be.eql({foo: 'string'});
481
480
  });
482
481
 
483
- it('sets a default value if a property has a blank value', function () {
482
+ it('sets a default value if a property value is undefined', function () {
484
483
  const dbs = new DatabaseSchema();
485
484
  dbs.defineModel({
486
485
  name: 'model',
@@ -491,12 +490,9 @@ describe('ModelDefinitionUtils', function () {
491
490
  },
492
491
  },
493
492
  });
494
- dbs
495
- .getService(BlankValuesService)
496
- .setBlankValuesOf(DataType.STRING, ['blank']);
497
493
  const result = dbs
498
494
  .getService(ModelDefinitionUtils)
499
- .setDefaultValuesToEmptyProperties('model', {foo: 'blank'});
495
+ .setDefaultValuesToEmptyProperties('model', {foo: undefined});
500
496
  expect(result).to.be.eql({foo: 'placeholder'});
501
497
  });
502
498
 
@@ -1,7 +1,5 @@
1
- import {DataType} from './data-type.js';
2
1
  import {Service} from '@e22m4u/js-service';
3
2
  import {isPlainObject} from '../../../utils/index.js';
4
- import {BlankValuesService} from '@e22m4u/js-empty-values';
5
3
  import {PropertyUniqueness} from './property-uniqueness.js';
6
4
  import {InvalidArgumentError} from '../../../errors/index.js';
7
5
  import {ModelDefinitionUtils} from '../model-definition-utils.js';
@@ -70,7 +68,6 @@ export class PropertyUniquenessValidator extends Service {
70
68
  propValue,
71
69
  );
72
70
  let willBeReplaced = undefined;
73
- const blankValuesService = this.getService(BlankValuesService);
74
71
  for (const propName of propNames) {
75
72
  const propDef = propDefs[propName];
76
73
  if (
@@ -81,12 +78,11 @@ export class PropertyUniquenessValidator extends Service {
81
78
  ) {
82
79
  continue;
83
80
  }
84
- // sparse
81
+ // в режиме "sparse" проверка на уникальность
82
+ // должна игнорировать ложные значения
85
83
  const propValue = modelData[propName];
86
- if (propDef.unique === PropertyUniqueness.SPARSE) {
87
- const propType = propDef.type || DataType.ANY;
88
- const isBlank = blankValuesService.isBlankOf(propType, propValue);
89
- if (isBlank) continue;
84
+ if (propDef.unique === PropertyUniqueness.SPARSE && !propValue) {
85
+ continue;
90
86
  }
91
87
  // create
92
88
  if (methodName === 'create') {
@@ -2,7 +2,6 @@ import {expect} from 'chai';
2
2
  import {DataType} from './data-type.js';
3
3
  import {format} from '@e22m4u/js-format';
4
4
  import {DatabaseSchema} from '../../../database-schema.js';
5
- import {BlankValuesService} from '@e22m4u/js-empty-values';
6
5
  import {PropertyUniqueness} from './property-uniqueness.js';
7
6
  import {PropertyUniquenessValidator} from './property-uniqueness-validator.js';
8
7
  import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '../model-definition-utils.js';
@@ -1862,7 +1861,7 @@ describe('PropertyUniquenessValidator', function () {
1862
1861
  expect(invoked).to.be.eq(1);
1863
1862
  });
1864
1863
 
1865
- it('skips uniqueness checking for blank values', async function () {
1864
+ it('skips uniqueness checking for undefined value', async function () {
1866
1865
  const dbs = new DatabaseSchema();
1867
1866
  dbs.defineModel({
1868
1867
  name: 'model',
@@ -1879,10 +1878,34 @@ describe('PropertyUniquenessValidator', function () {
1879
1878
  });
1880
1879
  const puv = dbs.getService(PropertyUniquenessValidator);
1881
1880
  let invoked = 0;
1882
- dbs
1883
- .getService(BlankValuesService)
1884
- .setBlankValuesOf(DataType.STRING, ['val2']);
1885
- const modelData = {foo: 'val1', bar: 'val2'};
1881
+ const modelData = {foo: 'val1', bar: undefined};
1882
+ const countMethod = where => {
1883
+ if (invoked === 0) expect(where).to.be.eql({foo: 'val1'});
1884
+ invoked++;
1885
+ return 0;
1886
+ };
1887
+ await puv.validate(countMethod, 'create', 'model', modelData);
1888
+ expect(invoked).to.be.eql(1);
1889
+ });
1890
+
1891
+ it('skips uniqueness checking for an empty string', async function () {
1892
+ const dbs = new DatabaseSchema();
1893
+ dbs.defineModel({
1894
+ name: 'model',
1895
+ properties: {
1896
+ foo: {
1897
+ type: DataType.STRING,
1898
+ unique: PropertyUniqueness.SPARSE,
1899
+ },
1900
+ bar: {
1901
+ type: DataType.STRING,
1902
+ unique: PropertyUniqueness.SPARSE,
1903
+ },
1904
+ },
1905
+ });
1906
+ const puv = dbs.getService(PropertyUniquenessValidator);
1907
+ let invoked = 0;
1908
+ const modelData = {foo: 'val1', bar: ''};
1886
1909
  const countMethod = where => {
1887
1910
  if (invoked === 0) expect(where).to.be.eql({foo: 'val1'});
1888
1911
  invoked++;
@@ -1976,7 +1999,7 @@ describe('PropertyUniquenessValidator', function () {
1976
1999
  expect(invoked).to.be.eq(1);
1977
2000
  });
1978
2001
 
1979
- it('skips uniqueness checking for blank values', async function () {
2002
+ it('skips uniqueness checking for undefined value', async function () {
1980
2003
  const dbs = new DatabaseSchema();
1981
2004
  dbs.defineModel({
1982
2005
  name: 'model',
@@ -1993,11 +2016,46 @@ describe('PropertyUniquenessValidator', function () {
1993
2016
  });
1994
2017
  const puv = dbs.getService(PropertyUniquenessValidator);
1995
2018
  let invoked = 0;
1996
- dbs
1997
- .getService(BlankValuesService)
1998
- .setBlankValuesOf(DataType.STRING, ['val2']);
1999
2019
  const idValue = 1;
2000
- const modelData = {foo: 'val1', bar: 'val2'};
2020
+ const modelData = {foo: 'val1', bar: undefined};
2021
+ const countMethod = where => {
2022
+ if (invoked === 0)
2023
+ expect(where).to.be.eql({
2024
+ [DEF_PK]: {neq: idValue},
2025
+ foo: 'val1',
2026
+ });
2027
+ invoked++;
2028
+ return 0;
2029
+ };
2030
+ await puv.validate(
2031
+ countMethod,
2032
+ 'replaceById',
2033
+ 'model',
2034
+ modelData,
2035
+ idValue,
2036
+ );
2037
+ expect(invoked).to.be.eql(1);
2038
+ });
2039
+
2040
+ it('skips uniqueness checking for an empty string', async function () {
2041
+ const dbs = new DatabaseSchema();
2042
+ dbs.defineModel({
2043
+ name: 'model',
2044
+ properties: {
2045
+ foo: {
2046
+ type: DataType.STRING,
2047
+ unique: PropertyUniqueness.SPARSE,
2048
+ },
2049
+ bar: {
2050
+ type: DataType.STRING,
2051
+ unique: PropertyUniqueness.SPARSE,
2052
+ },
2053
+ },
2054
+ });
2055
+ const puv = dbs.getService(PropertyUniquenessValidator);
2056
+ let invoked = 0;
2057
+ const idValue = 1;
2058
+ const modelData = {foo: 'val1', bar: ''};
2001
2059
  const countMethod = where => {
2002
2060
  if (invoked === 0)
2003
2061
  expect(where).to.be.eql({
@@ -2241,7 +2299,7 @@ describe('PropertyUniquenessValidator', function () {
2241
2299
  expect(invoked).to.be.eq(3);
2242
2300
  });
2243
2301
 
2244
- it('skips uniqueness checking for blank values', async function () {
2302
+ it('skips uniqueness checking for undefined value', async function () {
2245
2303
  const dbs = new DatabaseSchema();
2246
2304
  dbs.defineModel({
2247
2305
  name: 'model',
@@ -2257,12 +2315,54 @@ describe('PropertyUniquenessValidator', function () {
2257
2315
  },
2258
2316
  });
2259
2317
  const puv = dbs.getService(PropertyUniquenessValidator);
2260
- dbs
2261
- .getService(BlankValuesService)
2262
- .setBlankValuesOf(DataType.STRING, ['val2']);
2263
2318
  let invoked = 0;
2264
2319
  const idValue = 1;
2265
- const modelData = {[DEF_PK]: idValue, foo: 'val1', bar: 'val2'};
2320
+ const modelData = {
2321
+ [DEF_PK]: idValue,
2322
+ foo: 'val1',
2323
+ bar: undefined,
2324
+ };
2325
+ const countMethod = where => {
2326
+ if (invoked === 0) {
2327
+ expect(where).to.be.eql({[DEF_PK]: idValue});
2328
+ } else if (invoked === 1) {
2329
+ expect(where).to.be.eql({foo: 'val1'});
2330
+ }
2331
+ invoked++;
2332
+ return 0;
2333
+ };
2334
+ await puv.validate(
2335
+ countMethod,
2336
+ 'replaceOrCreate',
2337
+ 'model',
2338
+ modelData,
2339
+ );
2340
+ expect(invoked).to.be.eql(2);
2341
+ });
2342
+
2343
+ it('skips uniqueness checking for an empty string', async function () {
2344
+ const dbs = new DatabaseSchema();
2345
+ dbs.defineModel({
2346
+ name: 'model',
2347
+ properties: {
2348
+ foo: {
2349
+ type: DataType.STRING,
2350
+ unique: PropertyUniqueness.SPARSE,
2351
+ },
2352
+ bar: {
2353
+ type: DataType.STRING,
2354
+ unique: PropertyUniqueness.SPARSE,
2355
+ },
2356
+ },
2357
+ });
2358
+ const puv = dbs.getService(PropertyUniquenessValidator);
2359
+ let invoked = 0;
2360
+ const idValue = 1;
2361
+ const modelData = {
2362
+ [DEF_PK]: idValue,
2363
+ foo: 'val1',
2364
+ bar: undefined,
2365
+ };
2266
2366
  const countMethod = where => {
2267
2367
  if (invoked === 0) {
2268
2368
  expect(where).to.be.eql({[DEF_PK]: idValue});
@@ -2420,7 +2520,7 @@ describe('PropertyUniquenessValidator', function () {
2420
2520
  expect(invoked).to.be.eq(3);
2421
2521
  });
2422
2522
 
2423
- it('skips uniqueness checking for blank values', async function () {
2523
+ it('skips uniqueness checking for undefined value', async function () {
2424
2524
  const dbs = new DatabaseSchema();
2425
2525
  dbs.defineModel({
2426
2526
  name: 'model',
@@ -2436,12 +2536,58 @@ describe('PropertyUniquenessValidator', function () {
2436
2536
  },
2437
2537
  });
2438
2538
  const puv = dbs.getService(PropertyUniquenessValidator);
2439
- dbs
2440
- .getService(BlankValuesService)
2441
- .setBlankValuesOf(DataType.STRING, ['val2']);
2442
2539
  let invoked = 0;
2443
2540
  const idValue = 1;
2444
- const modelData = {[DEF_PK]: idValue, foo: 'val1', bar: 'val2'};
2541
+ const modelData = {
2542
+ [DEF_PK]: idValue,
2543
+ foo: 'val1',
2544
+ bar: undefined,
2545
+ };
2546
+ const countMethod = where => {
2547
+ invoked++;
2548
+ if (invoked === 1) {
2549
+ expect(where).to.be.eql({[DEF_PK]: idValue});
2550
+ return 1;
2551
+ } else if (invoked === 2) {
2552
+ expect(where).to.be.eql({
2553
+ [DEF_PK]: {neq: idValue},
2554
+ foo: 'val1',
2555
+ });
2556
+ return 0;
2557
+ }
2558
+ };
2559
+ await puv.validate(
2560
+ countMethod,
2561
+ 'replaceOrCreate',
2562
+ 'model',
2563
+ modelData,
2564
+ );
2565
+ expect(invoked).to.be.eql(2);
2566
+ });
2567
+
2568
+ it('skips uniqueness checking for an empty string', async function () {
2569
+ const dbs = new DatabaseSchema();
2570
+ dbs.defineModel({
2571
+ name: 'model',
2572
+ properties: {
2573
+ foo: {
2574
+ type: DataType.STRING,
2575
+ unique: PropertyUniqueness.SPARSE,
2576
+ },
2577
+ bar: {
2578
+ type: DataType.STRING,
2579
+ unique: PropertyUniqueness.SPARSE,
2580
+ },
2581
+ },
2582
+ });
2583
+ const puv = dbs.getService(PropertyUniquenessValidator);
2584
+ let invoked = 0;
2585
+ const idValue = 1;
2586
+ const modelData = {
2587
+ [DEF_PK]: idValue,
2588
+ foo: 'val1',
2589
+ bar: '',
2590
+ };
2445
2591
  const countMethod = where => {
2446
2592
  invoked++;
2447
2593
  if (invoked === 1) {
@@ -2558,7 +2704,7 @@ describe('PropertyUniquenessValidator', function () {
2558
2704
  await expect(promise2).not.to.be.rejected;
2559
2705
  });
2560
2706
 
2561
- it('skips uniqueness checking for blank values', async function () {
2707
+ it('skips uniqueness checking for undefined value', async function () {
2562
2708
  const dbs = new DatabaseSchema();
2563
2709
  dbs.defineModel({
2564
2710
  name: 'model',
@@ -2574,11 +2720,35 @@ describe('PropertyUniquenessValidator', function () {
2574
2720
  },
2575
2721
  });
2576
2722
  const puv = dbs.getService(PropertyUniquenessValidator);
2577
- dbs
2578
- .getService(BlankValuesService)
2579
- .setBlankValuesOf(DataType.STRING, ['val2']);
2580
2723
  let invoked = 0;
2581
- const modelData = {foo: 'val1', bar: 'val2'};
2724
+ const modelData = {foo: 'val1', bar: undefined};
2725
+ const countMethod = where => {
2726
+ if (invoked === 0) expect(where).to.be.eql({foo: 'val1'});
2727
+ invoked++;
2728
+ return 0;
2729
+ };
2730
+ await puv.validate(countMethod, 'patch', 'model', modelData);
2731
+ expect(invoked).to.be.eql(1);
2732
+ });
2733
+
2734
+ it('skips uniqueness checking for an empty string', async function () {
2735
+ const dbs = new DatabaseSchema();
2736
+ dbs.defineModel({
2737
+ name: 'model',
2738
+ properties: {
2739
+ foo: {
2740
+ type: DataType.STRING,
2741
+ unique: PropertyUniqueness.SPARSE,
2742
+ },
2743
+ bar: {
2744
+ type: DataType.STRING,
2745
+ unique: PropertyUniqueness.SPARSE,
2746
+ },
2747
+ },
2748
+ });
2749
+ const puv = dbs.getService(PropertyUniquenessValidator);
2750
+ let invoked = 0;
2751
+ const modelData = {foo: 'val1', bar: ''};
2582
2752
  const countMethod = where => {
2583
2753
  if (invoked === 0) expect(where).to.be.eql({foo: 'val1'});
2584
2754
  invoked++;
@@ -2697,7 +2867,7 @@ describe('PropertyUniquenessValidator', function () {
2697
2867
  await expect(promise2).not.to.be.rejected;
2698
2868
  });
2699
2869
 
2700
- it('skips uniqueness checking for blank values', async function () {
2870
+ it('skips uniqueness checking for undefined value', async function () {
2701
2871
  const dbs = new DatabaseSchema();
2702
2872
  dbs.defineModel({
2703
2873
  name: 'model',
@@ -2714,10 +2884,38 @@ describe('PropertyUniquenessValidator', function () {
2714
2884
  });
2715
2885
  const puv = dbs.getService(PropertyUniquenessValidator);
2716
2886
  let invoked = 0;
2717
- dbs
2718
- .getService(BlankValuesService)
2719
- .setBlankValuesOf(DataType.STRING, ['val2']);
2720
- const modelData = {foo: 'val1', bar: 'val2'};
2887
+ const modelData = {foo: 'val1', bar: undefined};
2888
+ const countMethod = where => {
2889
+ if (invoked === 0)
2890
+ expect(where).to.be.eql({
2891
+ [DEF_PK]: {neq: 1},
2892
+ foo: 'val1',
2893
+ });
2894
+ invoked++;
2895
+ return 0;
2896
+ };
2897
+ await puv.validate(countMethod, 'patchById', 'model', modelData, 1);
2898
+ expect(invoked).to.be.eql(1);
2899
+ });
2900
+
2901
+ it('skips uniqueness checking for an empty string', async function () {
2902
+ const dbs = new DatabaseSchema();
2903
+ dbs.defineModel({
2904
+ name: 'model',
2905
+ properties: {
2906
+ foo: {
2907
+ type: DataType.STRING,
2908
+ unique: PropertyUniqueness.SPARSE,
2909
+ },
2910
+ bar: {
2911
+ type: DataType.STRING,
2912
+ unique: PropertyUniqueness.SPARSE,
2913
+ },
2914
+ },
2915
+ });
2916
+ const puv = dbs.getService(PropertyUniquenessValidator);
2917
+ let invoked = 0;
2918
+ const modelData = {foo: 'val1', bar: ''};
2721
2919
  const countMethod = where => {
2722
2920
  if (invoked === 0)
2723
2921
  expect(where).to.be.eql({
@@ -1,6 +1,5 @@
1
1
  import {DataType} from './data-type.js';
2
2
  import {Service} from '@e22m4u/js-service';
3
- import {BlankValuesService} from '@e22m4u/js-empty-values';
4
3
  import {InvalidArgumentError} from '../../../errors/index.js';
5
4
  import {ModelDefinitionUtils} from '../model-definition-utils.js';
6
5
 
@@ -44,7 +43,6 @@ export class RequiredPropertyValidator extends Service {
44
43
  ModelDefinitionUtils,
45
44
  ).getPropertiesDefinitionInBaseModelHierarchy(modelName);
46
45
  const propNames = Object.keys(isPartial ? modelData : propDefs);
47
- const blankValuesService = this.getService(BlankValuesService);
48
46
  for (const propName of propNames) {
49
47
  const propDef = propDefs[propName];
50
48
  if (!propDef || typeof propDef !== 'object') {
@@ -52,16 +50,13 @@ export class RequiredPropertyValidator extends Service {
52
50
  }
53
51
  // проверка основного значения
54
52
  const propValue = modelData[propName];
55
- if (propDef.required) {
56
- const propType = propDef.type || DataType.ANY;
57
- if (blankValuesService.isBlankOf(propType, propValue)) {
58
- throw new InvalidArgumentError(
59
- 'Property %v of the model %v is required, but %v was given.',
60
- propName,
61
- modelName,
62
- propValue,
63
- );
64
- }
53
+ if (propDef.required && propValue == null) {
54
+ throw new InvalidArgumentError(
55
+ 'Property %v of the model %v is required, but %v was given.',
56
+ propName,
57
+ modelName,
58
+ propValue,
59
+ );
65
60
  }
66
61
  // проверка вложенного объекта
67
62
  if (
@@ -1,9 +1,8 @@
1
1
  import {expect} from 'chai';
2
+ import {DataType} from './data-type.js';
2
3
  import {format} from '@e22m4u/js-format';
3
4
  import {DatabaseSchema} from '../../../database-schema.js';
4
5
  import {RequiredPropertyValidator} from './required-property-validator.js';
5
- import {DataType} from './data-type.js';
6
- import {BlankValuesService} from '@e22m4u/js-empty-values';
7
6
 
8
7
  describe('RequiredPropertyValidator', function () {
9
8
  describe('validate', function () {
@@ -84,11 +83,9 @@ describe('RequiredPropertyValidator', function () {
84
83
  S.validate('model', {foo: 'bar'});
85
84
  });
86
85
 
87
- it('should not throw an error if a required property is not blank', function () {
86
+ it('should not throw an error if a required property is defined', function () {
88
87
  const dbs = new DatabaseSchema();
89
88
  const S = dbs.getService(RequiredPropertyValidator);
90
- const blankValues = S.getService(BlankValuesService);
91
- blankValues.setBlankValues([undefined]);
92
89
  dbs.defineModel({
93
90
  name: 'model',
94
91
  properties: {
@@ -101,11 +98,9 @@ describe('RequiredPropertyValidator', function () {
101
98
  S.validate('model', {foo: 'bar'});
102
99
  });
103
100
 
104
- it('should throw an error if a required property is blank', function () {
101
+ it('should throw an error if a required property is undefined', function () {
105
102
  const dbs = new DatabaseSchema();
106
103
  const S = dbs.getService(RequiredPropertyValidator);
107
- const blankValues = S.getService(BlankValuesService);
108
- blankValues.setBlankValues([undefined]);
109
104
  dbs.defineModel({
110
105
  name: 'model',
111
106
  properties: {
@@ -126,8 +121,6 @@ describe('RequiredPropertyValidator', function () {
126
121
  it('should not throw an error if no data is provided for an embedded model', function () {
127
122
  const dbs = new DatabaseSchema();
128
123
  const S = dbs.getService(RequiredPropertyValidator);
129
- const blankValues = S.getService(BlankValuesService);
130
- blankValues.setBlankValues([undefined]);
131
124
  dbs.defineModel({
132
125
  name: 'modelA',
133
126
  properties: {
@@ -151,8 +144,6 @@ describe('RequiredPropertyValidator', function () {
151
144
  it('should throw an error if an embedded model is required but not provided', function () {
152
145
  const dbs = new DatabaseSchema();
153
146
  const S = dbs.getService(RequiredPropertyValidator);
154
- const blankValues = S.getService(BlankValuesService);
155
- blankValues.setBlankValues([undefined]);
156
147
  dbs.defineModel({
157
148
  name: 'modelA',
158
149
  properties: {
@@ -181,8 +172,6 @@ describe('RequiredPropertyValidator', function () {
181
172
  it('should allow a model data to have properties without a specified schema', function () {
182
173
  const dbs = new DatabaseSchema();
183
174
  const S = dbs.getService(RequiredPropertyValidator);
184
- const blankValues = S.getService(BlankValuesService);
185
- blankValues.setBlankValues([undefined]);
186
175
  dbs.defineModel({
187
176
  name: 'modelA',
188
177
  properties: {
@@ -206,8 +195,6 @@ describe('RequiredPropertyValidator', function () {
206
195
  it('should allow omit a model data when its model has a required property', function () {
207
196
  const dbs = new DatabaseSchema();
208
197
  const S = dbs.getService(RequiredPropertyValidator);
209
- const blankValues = S.getService(BlankValuesService);
210
- blankValues.setBlankValues([undefined]);
211
198
  dbs.defineModel({
212
199
  name: 'modelA',
213
200
  properties: {
@@ -232,8 +219,6 @@ describe('RequiredPropertyValidator', function () {
232
219
  it('should allow omit an optional property for an embedded model', function () {
233
220
  const dbs = new DatabaseSchema();
234
221
  const S = dbs.getService(RequiredPropertyValidator);
235
- const blankValues = S.getService(BlankValuesService);
236
- blankValues.setBlankValues([undefined]);
237
222
  dbs.defineModel({
238
223
  name: 'modelA',
239
224
  properties: {
@@ -257,8 +242,6 @@ describe('RequiredPropertyValidator', function () {
257
242
  it('should throw an error if a required property is not provided', function () {
258
243
  const dbs = new DatabaseSchema();
259
244
  const S = dbs.getService(RequiredPropertyValidator);
260
- const blankValues = S.getService(BlankValuesService);
261
- blankValues.setBlankValues([undefined]);
262
245
  dbs.defineModel({
263
246
  name: 'modelA',
264
247
  properties: {
@@ -289,8 +272,6 @@ describe('RequiredPropertyValidator', function () {
289
272
  it('should allow omit an optional array', function () {
290
273
  const dbs = new DatabaseSchema();
291
274
  const S = dbs.getService(RequiredPropertyValidator);
292
- const blankValues = S.getService(BlankValuesService);
293
- blankValues.setBlankValues([undefined]);
294
275
  dbs.defineModel({
295
276
  name: 'modelA',
296
277
  properties: {
@@ -315,8 +296,6 @@ describe('RequiredPropertyValidator', function () {
315
296
  it('should allow a required array to be empty', function () {
316
297
  const dbs = new DatabaseSchema();
317
298
  const S = dbs.getService(RequiredPropertyValidator);
318
- const blankValues = S.getService(BlankValuesService);
319
- blankValues.setBlankValues([undefined]);
320
299
  dbs.defineModel({
321
300
  name: 'modelA',
322
301
  properties: {
@@ -339,11 +318,9 @@ describe('RequiredPropertyValidator', function () {
339
318
  S.validate('modelA', {array: []});
340
319
  });
341
320
 
342
- it('should allow omit an optional array even if the item model has a required property', function () {
321
+ it('should allow omit an optional array even if an item model has a required property', function () {
343
322
  const dbs = new DatabaseSchema();
344
323
  const S = dbs.getService(RequiredPropertyValidator);
345
- const blankValues = S.getService(BlankValuesService);
346
- blankValues.setBlankValues([undefined]);
347
324
  dbs.defineModel({
348
325
  name: 'modelA',
349
326
  properties: {
@@ -366,11 +343,9 @@ describe('RequiredPropertyValidator', function () {
366
343
  S.validate('modelA', {});
367
344
  });
368
345
 
369
- it('should allow an empty array even if the item model has a required property', function () {
346
+ it('should allow an empty array even if an item model has a required property', function () {
370
347
  const dbs = new DatabaseSchema();
371
348
  const S = dbs.getService(RequiredPropertyValidator);
372
- const blankValues = S.getService(BlankValuesService);
373
- blankValues.setBlankValues([undefined]);
374
349
  dbs.defineModel({
375
350
  name: 'modelA',
376
351
  properties: {
@@ -396,8 +371,6 @@ describe('RequiredPropertyValidator', function () {
396
371
  it('should throw an error when a required array is not provided', function () {
397
372
  const dbs = new DatabaseSchema();
398
373
  const S = dbs.getService(RequiredPropertyValidator);
399
- const blankValues = S.getService(BlankValuesService);
400
- blankValues.setBlankValues([undefined]);
401
374
  dbs.defineModel({
402
375
  name: 'modelA',
403
376
  properties: {
@@ -427,8 +400,6 @@ describe('RequiredPropertyValidator', function () {
427
400
  it('should allow omit an optional property of the item model', function () {
428
401
  const dbs = new DatabaseSchema();
429
402
  const S = dbs.getService(RequiredPropertyValidator);
430
- const blankValues = S.getService(BlankValuesService);
431
- blankValues.setBlankValues([undefined]);
432
403
  dbs.defineModel({
433
404
  name: 'modelA',
434
405
  properties: {
@@ -454,8 +425,6 @@ describe('RequiredPropertyValidator', function () {
454
425
  it('should allow an item date to have properties without a specified schema', function () {
455
426
  const dbs = new DatabaseSchema();
456
427
  const S = dbs.getService(RequiredPropertyValidator);
457
- const blankValues = S.getService(BlankValuesService);
458
- blankValues.setBlankValues([undefined]);
459
428
  dbs.defineModel({
460
429
  name: 'modelA',
461
430
  properties: {
@@ -480,11 +449,9 @@ describe('RequiredPropertyValidator', function () {
480
449
  });
481
450
 
482
451
  describe('isPartial', function () {
483
- it('should throw an error if a required property is blank', function () {
452
+ it('should throw an error if a required property is undefined', function () {
484
453
  const dbs = new DatabaseSchema();
485
454
  const S = dbs.getService(RequiredPropertyValidator);
486
- const blankValues = S.getService(BlankValuesService);
487
- blankValues.setBlankValues([undefined]);
488
455
  dbs.defineModel({
489
456
  name: 'model',
490
457
  properties: {
@@ -501,11 +468,9 @@ describe('RequiredPropertyValidator', function () {
501
468
  );
502
469
  });
503
470
 
504
- it('should not validate a required but not provided properties', function () {
471
+ it('should not validate required but not provided properties', function () {
505
472
  const dbs = new DatabaseSchema();
506
473
  const S = dbs.getService(RequiredPropertyValidator);
507
- const blankValues = S.getService(BlankValuesService);
508
- blankValues.setBlankValues([undefined]);
509
474
  dbs.defineModel({
510
475
  name: 'model',
511
476
  properties: {
@@ -521,8 +486,6 @@ describe('RequiredPropertyValidator', function () {
521
486
  it('should validate not provided properties of an embedded model', function () {
522
487
  const dbs = new DatabaseSchema();
523
488
  const S = dbs.getService(RequiredPropertyValidator);
524
- const blankValues = S.getService(BlankValuesService);
525
- blankValues.setBlankValues([undefined]);
526
489
  dbs.defineModel({
527
490
  name: 'modelA',
528
491
  properties: {
@@ -551,8 +514,6 @@ describe('RequiredPropertyValidator', function () {
551
514
  it('should validate not provided properties of an item model', function () {
552
515
  const dbs = new DatabaseSchema();
553
516
  const S = dbs.getService(RequiredPropertyValidator);
554
- const blankValues = S.getService(BlankValuesService);
555
- blankValues.setBlankValues([undefined]);
556
517
  dbs.defineModel({
557
518
  name: 'modelA',
558
519
  properties: {