Browse Source

chore: replaces util.format by @e22m4u/format

e22m4u 2 years ago
parent
commit
04251bf685
63 changed files with 1330 additions and 1453 deletions
  1. 3 0
      package.json
  2. 2 2
      src/adapter/adapter-loader.js
  3. 9 9
      src/adapter/adapter.js
  4. 7 7
      src/adapter/builtin/memory-adapter.js
  5. 5 5
      src/adapter/builtin/memory-adapter.spec.js
  6. 1 1
      src/adapter/decorator/data-sanitizing-decorator.js
  7. 1 1
      src/adapter/decorator/data-validation-decorator.js
  8. 1 1
      src/adapter/decorator/default-values-decorator.js
  9. 1 1
      src/adapter/decorator/fields-filtering-decorator.js
  10. 1 1
      src/adapter/decorator/inclusion-decorator.js
  11. 4 4
      src/definition/datasource/datasource-definition-validator.js
  12. 26 26
      src/definition/datasource/datasource-definition-validator.spec.js
  13. 4 4
      src/definition/definition-registry.js
  14. 2 2
      src/definition/model/model-data-sanitizer.js
  15. 6 7
      src/definition/model/model-data-validator.js
  16. 9 9
      src/definition/model/model-data-validator.spec.js
  17. 8 8
      src/definition/model/model-definition-utils.js
  18. 12 12
      src/definition/model/model-definition-utils.spec.js
  19. 12 12
      src/definition/model/model-definition-validator.js
  20. 43 43
      src/definition/model/model-definition-validator.spec.js
  21. 3 3
      src/definition/model/properties/default-values-definition-validator.js
  22. 18 18
      src/definition/model/properties/default-values-definition-validator.spec.js
  23. 4 4
      src/definition/model/properties/primary-keys-definition-validator.js
  24. 5 5
      src/definition/model/properties/primary-keys-definition-validator.spec.js
  25. 34 35
      src/definition/model/properties/properties-definition-validator.js
  26. 70 71
      src/definition/model/properties/properties-definition-validator.spec.js
  27. 52 53
      src/definition/model/relations/relations-definition-validator.js
  28. 207 208
      src/definition/model/relations/relations-definition-validator.spec.js
  29. 2 16
      src/errors/invalid-argument-error.js
  30. 16 16
      src/errors/invalid-argument-error.spec.js
  31. 3 4
      src/errors/invalid-operator-value-error.js
  32. 2 16
      src/errors/not-implemented-error.js
  33. 16 16
      src/errors/not-implemented-error.spec.js
  34. 4 4
      src/filter/fields-clause-tool.js
  35. 21 21
      src/filter/fields-clause-tool.spec.js
  36. 9 9
      src/filter/include-clause-tool.js
  37. 13 13
      src/filter/include-clause-tool.spec.js
  38. 13 13
      src/filter/operator-clause-tool.js
  39. 6 6
      src/filter/operator-clause-tool.spec.js
  40. 3 3
      src/filter/order-clause-tool.js
  41. 21 21
      src/filter/order-clause-tool.spec.js
  42. 5 5
      src/filter/slice-clause-tool.js
  43. 9 9
      src/filter/slice-clause-tool.spec.js
  44. 4 4
      src/filter/where-clause-tool.js
  45. 6 6
      src/filter/where-clause-tool.spec.js
  46. 14 14
      src/relations/belongs-to-resolver.js
  47. 107 107
      src/relations/belongs-to-resolver.spec.js
  48. 26 26
      src/relations/has-many-resolver.js
  49. 187 187
      src/relations/has-many-resolver.spec.js
  50. 26 26
      src/relations/has-one-resolver.js
  51. 187 187
      src/relations/has-one-resolver.spec.js
  52. 7 7
      src/relations/references-many-resolver.js
  53. 56 56
      src/relations/references-many-resolver.spec.js
  54. 1 1
      src/repository/repository-registry.js
  55. 1 1
      src/repository/repository.js
  56. 0 15
      src/utils/array-to-string.js
  57. 0 33
      src/utils/array-to-string.spec.js
  58. 1 1
      src/utils/exclude-object-keys.js
  59. 11 10
      src/utils/exclude-object-keys.spec.js
  60. 0 2
      src/utils/index.js
  61. 3 3
      src/utils/select-object-keys.js
  62. 0 20
      src/utils/value-to-string.js
  63. 0 23
      src/utils/value-to-string.spec.js

+ 3 - 0
package.json

@@ -32,6 +32,9 @@
   "author": "e22m4u <e22m4u@gmail.com>",
   "license": "MIT",
   "homepage": "https://github.com/e22m4u/repository",
+  "dependencies": {
+    "@e22m4u/format": "0.0.2"
+  },
   "devDependencies": {
     "@commitlint/cli": "^17.7.1",
     "@commitlint/config-conventional": "^17.7.0",

+ 2 - 2
src/adapter/adapter-loader.js

@@ -16,7 +16,7 @@ export class AdapterLoader extends Service {
   async loadByName(adapterName, settings = undefined) {
     if (!adapterName || typeof adapterName !== 'string')
       throw new InvalidArgumentError(
-        'The adapter name must be a non-empty String, but %s given.',
+        'The adapter name must be a non-empty String, but %v given.',
         adapterName,
       );
     let adapterCtor;
@@ -37,7 +37,7 @@ export class AdapterLoader extends Service {
       }
     if (!adapterCtor)
       throw new InvalidArgumentError(
-        'The adapter %s is not found.',
+        'The adapter %v is not found.',
         adapterName,
       );
     return new adapterCtor(this._services, settings);

+ 9 - 9
src/adapter/adapter.js

@@ -55,7 +55,7 @@ export class Adapter extends Service {
   create(modelName, modelData, filter = undefined) {
     throw new NotImplementedError(
       '%s.create is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -71,7 +71,7 @@ export class Adapter extends Service {
   replaceById(modelName, id, modelData, filter = undefined) {
     throw new NotImplementedError(
       '%s.replaceById is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -87,7 +87,7 @@ export class Adapter extends Service {
   patchById(modelName, id, modelData, filter = undefined) {
     throw new NotImplementedError(
       '%s.patchById is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -101,7 +101,7 @@ export class Adapter extends Service {
   find(modelName, filter = undefined) {
     throw new NotImplementedError(
       '%s.find is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -116,7 +116,7 @@ export class Adapter extends Service {
   findById(modelName, id, filter = undefined) {
     throw new NotImplementedError(
       '%s.findById is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -130,7 +130,7 @@ export class Adapter extends Service {
   delete(modelName, where = undefined) {
     throw new NotImplementedError(
       '%s.delete is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -144,7 +144,7 @@ export class Adapter extends Service {
   deleteById(modelName, id) {
     throw new NotImplementedError(
       '%s.deleteById is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -158,7 +158,7 @@ export class Adapter extends Service {
   exists(modelName, id) {
     throw new NotImplementedError(
       '%s.exists is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 
@@ -172,7 +172,7 @@ export class Adapter extends Service {
   count(modelName, where = undefined) {
     throw new NotImplementedError(
       '%s.count is not implemented.',
-      new String(this.constructor.name),
+      this.constructor.name,
     );
   }
 }

+ 7 - 7
src/adapter/builtin/memory-adapter.js

@@ -57,13 +57,13 @@ export class MemoryAdapter extends Adapter {
     if (propType !== DataType.ANY && propType !== DataType.NUMBER)
       throw new InvalidArgumentError(
         'The memory adapter able to generate only Number identifiers, ' +
-          'but the primary key %s of the model %s is defined as %s. ' +
-          'Do provide your own value for the %s property, or change the type ' +
+          'but the primary key %v of the model %v is defined as %s. ' +
+          'Do provide your own value for the %v property, or change the type ' +
           'in the primary key definition to a Number that will be ' +
           'generated automatically.',
         propName,
         modelName,
-        new String(capitalize(propType)),
+        capitalize(propType),
         propName,
       );
     const tableName =
@@ -96,7 +96,7 @@ export class MemoryAdapter extends Adapter {
     const table = this._getTableOrCreate(modelName);
     if (table.has(idValue))
       throw new InvalidArgumentError(
-        'The value %s of the primary key %s already exists in the model %s.',
+        'The value %v of the primary key %v already exists in the model %v.',
         idValue,
         pkPropName,
         modelName,
@@ -133,7 +133,7 @@ export class MemoryAdapter extends Adapter {
       this.get(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(modelName);
     if (!isExists)
       throw new InvalidArgumentError(
-        'The value %s of the primary key %s does not exist in the model %s.',
+        'The value %v of the primary key %v does not exist in the model %v.',
         id,
         pkPropName,
         modelName,
@@ -170,7 +170,7 @@ export class MemoryAdapter extends Adapter {
       this.get(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(modelName);
     if (existingTableData == null)
       throw new InvalidArgumentError(
-        'The value %s of the primary key %s does not exist in the model %s.',
+        'The value %v of the primary key %v does not exist in the model %v.',
         id,
         pkPropName,
         modelName,
@@ -242,7 +242,7 @@ export class MemoryAdapter extends Adapter {
       this.get(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(modelName);
     if (!tableData)
       throw new InvalidArgumentError(
-        'The value %s of the primary key %s does not exist in the model %s.',
+        'The value %v of the primary key %v does not exist in the model %v.',
         id,
         pkPropName,
         modelName,

+ 5 - 5
src/adapter/builtin/memory-adapter.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {Schema} from '../../schema.js';
 import {MemoryAdapter} from './memory-adapter.js';
 import {DataType} from '../../definition/index.js';
@@ -391,7 +391,7 @@ describe('MemoryAdapter', function () {
       const promise = adapter.create('model', created);
       await expect(promise).to.be.rejectedWith(
         format(
-          'The value 1 of the primary key "%s" already exists in the model "model".',
+          'The value 1 of the primary key %v already exists in the model "model".',
           DEF_PK,
         ),
       );
@@ -854,7 +854,7 @@ describe('MemoryAdapter', function () {
       const promise = adapter.replaceById('model', 1, {foo: 2});
       await expect(promise).to.be.rejectedWith(
         format(
-          'The value 1 of the primary key "%s" does not exist in the model "model".',
+          'The value 1 of the primary key %v does not exist in the model "model".',
           DEF_PK,
         ),
       );
@@ -1359,7 +1359,7 @@ describe('MemoryAdapter', function () {
       const promise = adapter.patchById('model', 1, {foo: 2});
       await expect(promise).to.be.rejectedWith(
         format(
-          'The value 1 of the primary key "%s" does not exist in the model "model".',
+          'The value 1 of the primary key %v does not exist in the model "model".',
           DEF_PK,
         ),
       );
@@ -2255,7 +2255,7 @@ describe('MemoryAdapter', function () {
       const promise = adapter.findById('model', 1);
       await expect(promise).to.be.rejectedWith(
         format(
-          'The value 1 of the primary key "%s" does not exist in the model "model".',
+          'The value 1 of the primary key %v does not exist in the model "model".',
           DEF_PK,
         ),
       );

+ 1 - 1
src/adapter/decorator/data-sanitizing-decorator.js

@@ -16,7 +16,7 @@ export class DataSanitizingDecorator extends Service {
     if (!adapter || !(adapter instanceof Adapter))
       throw new InvalidArgumentError(
         'A first argument of DataSanitizingDecorator.decorate must be ' +
-          'an Adapter instance, but %s given.',
+          'an Adapter instance, but %v given.',
         adapter,
       );
 

+ 1 - 1
src/adapter/decorator/data-validation-decorator.js

@@ -16,7 +16,7 @@ export class DataValidationDecorator extends Service {
     if (!adapter || !(adapter instanceof Adapter))
       throw new InvalidArgumentError(
         'A first argument of DataValidationDecorator.decorate must be ' +
-          'an Adapter instance, but %s given.',
+          'an Adapter instance, but %v given.',
         adapter,
       );
 

+ 1 - 1
src/adapter/decorator/default-values-decorator.js

@@ -16,7 +16,7 @@ export class DefaultValuesDecorator extends Service {
     if (!adapter || !(adapter instanceof Adapter))
       throw new InvalidArgumentError(
         'A first argument of DefaultValuesDecorator.decorate must be ' +
-          'an Adapter instance, but %s given.',
+          'an Adapter instance, but %v given.',
         adapter,
       );
 

+ 1 - 1
src/adapter/decorator/fields-filtering-decorator.js

@@ -16,7 +16,7 @@ export class FieldsFilteringDecorator extends Service {
     if (!adapter || !(adapter instanceof Adapter))
       throw new InvalidArgumentError(
         'A first argument of FieldsFilteringDecorator.decorate must be ' +
-          'an Adapter instance, but %s given.',
+          'an Adapter instance, but %v given.',
         adapter,
       );
 

+ 1 - 1
src/adapter/decorator/inclusion-decorator.js

@@ -16,7 +16,7 @@ export class InclusionDecorator extends Service {
     if (!adapter || !(adapter instanceof Adapter))
       throw new InvalidArgumentError(
         'A first argument of InclusionDecorator.decorate must be ' +
-          'an Adapter instance, but %s given.',
+          'an Adapter instance, but %v given.',
         adapter,
       );
 

+ 4 - 4
src/definition/datasource/datasource-definition-validator.js

@@ -13,19 +13,19 @@ export class DatasourceDefinitionValidator extends Service {
   validate(datasourceDef) {
     if (!datasourceDef || typeof datasourceDef !== 'object')
       throw new InvalidArgumentError(
-        'The datasource definition should be an Object, but %s given.',
+        'The datasource definition should be an Object, but %v given.',
         datasourceDef,
       );
     if (!datasourceDef.name || typeof datasourceDef.name !== 'string')
       throw new InvalidArgumentError(
         'The datasource definition requires the option "name" ' +
-          'as a non-empty String, but %s given.',
+          'as a non-empty String, but %v given.',
         datasourceDef.name,
       );
     if (!datasourceDef.adapter || typeof datasourceDef.adapter !== 'string')
       throw new InvalidArgumentError(
-        'The datasource %s requires the option "adapter" ' +
-          'as a non-empty String, but %s given.',
+        'The datasource %v requires the option "adapter" ' +
+          'as a non-empty String, but %v given.',
         datasourceDef.name,
         datasourceDef.adapter,
       );

+ 26 - 26
src/definition/datasource/datasource-definition-validator.spec.js

@@ -1,5 +1,5 @@
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {DatasourceDefinitionValidator} from './datasource-definition-validator.js';
 
 const S = new DatasourceDefinitionValidator();
@@ -10,15 +10,15 @@ describe('DatasourceDefinitionValidator', function () {
       const validate = value => () => S.validate(value);
       const error = value =>
         format(
-          'The datasource definition should be an Object, but %s given.',
+          'The datasource definition should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({name: 'datasource', adapter: 'adapter'})();
     });
 
@@ -27,17 +27,17 @@ describe('DatasourceDefinitionValidator', function () {
       const error = value =>
         format(
           'The datasource definition requires the option "name" ' +
-            'as a non-empty String, but %s given.',
+            'as a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('datasource')();
     });
 
@@ -47,17 +47,17 @@ describe('DatasourceDefinitionValidator', function () {
       const error = value =>
         format(
           'The datasource "datasource" requires the option "adapter" ' +
-            'as a non-empty String, but %s given.',
+            'as a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('adapter')();
     });
   });

+ 4 - 4
src/definition/definition-registry.js

@@ -31,7 +31,7 @@ export class DefinitionRegistry extends Service {
     const name = datasourceDef.name;
     if (name in this._datasources)
       throw new InvalidArgumentError(
-        'The datasource %s is already defined.',
+        'The datasource %v is already defined.',
         name,
       );
     this._datasources[name] = datasourceDef;
@@ -56,7 +56,7 @@ export class DefinitionRegistry extends Service {
   getDatasource(name) {
     const datasourceDef = this._datasources[name];
     if (!datasourceDef)
-      throw new InvalidArgumentError('The datasource %s is not defined.', name);
+      throw new InvalidArgumentError('The datasource %v is not defined.', name);
     return datasourceDef;
   }
 
@@ -69,7 +69,7 @@ export class DefinitionRegistry extends Service {
     this.get(ModelDefinitionValidator).validate(modelDef);
     const name = modelDef.name;
     if (name in this._models)
-      throw new InvalidArgumentError('The model %s is already defined.', name);
+      throw new InvalidArgumentError('The model %v is already defined.', name);
     this._models[name] = modelDef;
   }
 
@@ -92,7 +92,7 @@ export class DefinitionRegistry extends Service {
   getModel(name) {
     const modelDef = this._models[name];
     if (!modelDef)
-      throw new InvalidArgumentError('The model %s is not defined.', name);
+      throw new InvalidArgumentError('The model %v is not defined.', name);
     return modelDef;
   }
 }

+ 2 - 2
src/definition/model/model-data-sanitizer.js

@@ -17,13 +17,13 @@ export class ModelDataSanitizer extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'The first argument of ModelDataSanitizer.sanitize ' +
-          'must be a string, but %s given.',
+          'must be a string, but %v given.',
         modelName,
       );
     if (!modelData || typeof modelData !== 'object')
       throw new InvalidArgumentError(
         'The second argument of ModelDataSanitizer.sanitize ' +
-          'must be an Object, but %s given.',
+          'must be an Object, but %v given.',
         modelData,
       );
     return this.get(ModelDefinitionUtils).excludeObjectKeysByRelationNames(

+ 6 - 7
src/definition/model/model-data-validator.js

@@ -19,7 +19,7 @@ export class ModelDataValidator extends Service {
   validate(modelName, modelData, isPartial = false) {
     if (!isPureObject(modelData))
       throw new InvalidArgumentError(
-        'The data of the model %s must be an Object, but %s given.',
+        'The data of the model %v must be an Object, but %v given.',
         modelName,
         modelData,
       );
@@ -55,7 +55,7 @@ export class ModelDataValidator extends Service {
         typeof propDef === 'string' ? false : Boolean(propDef.required);
       if (!isRequired) return;
       throw new InvalidArgumentError(
-        'The property %s of the model %s is required, but %s given.',
+        'The property %v of the model %v is required, but %v given.',
         propName,
         modelName,
         propValue,
@@ -94,16 +94,15 @@ export class ModelDataValidator extends Service {
 
     const createError = expected => {
       const pattern = isArrayValue
-        ? 'The array property %s of the model %s must have %s element, but %s given.'
-        : 'The property %s of the model %s must have %s, but %s given.';
-      const expectedStr = new String(expected);
+        ? 'The array property %v of the model %v must have %s element, but %s given.'
+        : 'The property %v of the model %v must have %s, but %s given.';
       const ctorName = getCtorName(propValue);
-      const givenStr = new String(ctorName ?? typeof propValue);
+      const givenStr = ctorName ?? typeof propValue;
       return new InvalidArgumentError(
         pattern,
         propName,
         modelName,
-        expectedStr,
+        expected,
         givenStr,
       );
     };

+ 9 - 9
src/definition/model/model-data-validator.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {Schema} from '../../schema.js';
 import {DataType} from './properties/index.js';
 import {ModelDataValidator} from './model-data-validator.js';
@@ -24,16 +24,16 @@ describe('ModelDataValidator', function () {
       };
       const error = given =>
         format(
-          'The data of the model "model" must be an Object, but %s given.',
+          'The data of the model "model" must be an Object, but %v given.',
           given,
         );
-      expect(throwable('string')).to.throw(error('"string"'));
-      expect(throwable(10)).to.throw(error('10'));
-      expect(throwable(true)).to.throw(error('true'));
-      expect(throwable(false)).to.throw(error('false'));
-      expect(throwable([])).to.throw(error('Array'));
-      expect(throwable(null)).to.throw(error('null'));
-      expect(throwable(undefined)).to.throw(error('undefined'));
+      expect(throwable('string')).to.throw(error('string'));
+      expect(throwable(10)).to.throw(error(10));
+      expect(throwable(true)).to.throw(error(true));
+      expect(throwable(false)).to.throw(error(false));
+      expect(throwable([])).to.throw(error([]));
+      expect(throwable(null)).to.throw(error(null));
+      expect(throwable(undefined)).to.throw(error(undefined));
     });
 
     it('uses a base model hierarchy to validate a given data', function () {

+ 8 - 8
src/definition/model/model-definition-utils.js

@@ -34,7 +34,7 @@ export class ModelDefinitionUtils extends Service {
       );
       if (isDefaultPrimaryKeyAlreadyInUse)
         throw new InvalidArgumentError(
-          'The property name %s of the model %s is defined as a regular property. ' +
+          'The property name %v of the model %v is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEFAULT_PRIMARY_KEY_PROPERTY_NAME,
@@ -84,7 +84,7 @@ export class ModelDefinitionUtils extends Service {
     const propDef = propDefs[propertyName];
     if (!propDef)
       throw new InvalidArgumentError(
-        'The model %s does not have the property %s.',
+        'The model %v does not have the property %v.',
         modelName,
         propertyName,
       );
@@ -105,7 +105,7 @@ export class ModelDefinitionUtils extends Service {
     const propDef = propDefs[propertyName];
     if (!propDef)
       throw new InvalidArgumentError(
-        'The model %s does not have the property %s.',
+        'The model %v does not have the property %v.',
         modelName,
         propertyName,
       );
@@ -208,7 +208,7 @@ export class ModelDefinitionUtils extends Service {
       const pkPropName = this.getPrimaryKeyAsPropertyName(modelName);
       if (pkPropName === propertyName) return DataType.ANY;
       throw new InvalidArgumentError(
-        'The model %s does not have the property %s.',
+        'The model %v does not have the property %v.',
         modelName,
         propertyName,
       );
@@ -261,7 +261,7 @@ export class ModelDefinitionUtils extends Service {
     const recursion = (currModelName, prevModelName = undefined) => {
       if (currModelName === prevModelName)
         throw new InvalidArgumentError(
-          'The model %s has a circular inheritance.',
+          'The model %v has a circular inheritance.',
           currModelName,
         );
       if (Object.keys(pkPropDefs).length === 0) {
@@ -301,7 +301,7 @@ export class ModelDefinitionUtils extends Service {
     const recursion = (currModelName, prevModelName = undefined) => {
       if (currModelName === prevModelName)
         throw new InvalidArgumentError(
-          'The model %s has a circular inheritance.',
+          'The model %v has a circular inheritance.',
           currModelName,
         );
       const modelDef = this.get(DefinitionRegistry).getModel(currModelName);
@@ -332,7 +332,7 @@ export class ModelDefinitionUtils extends Service {
     }
     if (!foundDef)
       throw new InvalidArgumentError(
-        'The model %s does not have relation name %s.',
+        'The model %v does not have relation name %v.',
         modelName,
         relationName,
       );
@@ -350,7 +350,7 @@ export class ModelDefinitionUtils extends Service {
     if (!modelData || typeof modelData !== 'object' || Array.isArray(modelData))
       throw new InvalidArgumentError(
         'The second argument of ModelDefinitionUtils.excludeObjectKeysByRelationNames ' +
-          'must be an Object, but %s given.',
+          'must be an Object, but %v given.',
         modelData,
       );
     const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName);

+ 12 - 12
src/definition/model/model-definition-utils.spec.js

@@ -1,6 +1,6 @@
 import chai from 'chai';
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {Schema} from '../../schema.js';
 import {DataType} from './properties/index.js';
 import {InvalidArgumentError} from '../../errors/index.js';
@@ -41,7 +41,7 @@ describe('ModelDefinitionUtils', function () {
       const throwable = () => S.getPrimaryKeyAsPropertyName('model');
       expect(throwable).to.throw(
         format(
-          'The property name "%s" of the model "model" is defined as a regular property. ' +
+          'The property name %v of the model "model" is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -176,7 +176,7 @@ describe('ModelDefinitionUtils', function () {
       const throwable = () => S.getPrimaryKeyAsColumnName('model');
       expect(throwable).to.throw(
         format(
-          'The property name "%s" of the model "model" is defined as a regular property. ' +
+          'The property name %v of the model "model" is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -1456,17 +1456,17 @@ describe('ModelDefinitionUtils', function () {
       const error = v =>
         format(
           'The second argument of ModelDefinitionUtils.excludeObjectKeysByRelationNames ' +
-            'must be an Object, but %s given.',
+            'must be an Object, but %v given.',
           v,
         );
-      expect(throwable('')).to.throw(error('""'));
-      expect(throwable('str')).to.throw(error('"str"'));
-      expect(throwable(10)).to.throw(error('10'));
-      expect(throwable(true)).to.throw(error('true'));
-      expect(throwable(false)).to.throw(error('false'));
-      expect(throwable([])).to.throw(error('Array'));
-      expect(throwable(undefined)).to.throw(error('undefined'));
-      expect(throwable(null)).to.throw(error('null'));
+      expect(throwable('')).to.throw(error(''));
+      expect(throwable('str')).to.throw(error('str'));
+      expect(throwable(10)).to.throw(error(10));
+      expect(throwable(true)).to.throw(error(true));
+      expect(throwable(false)).to.throw(error(false));
+      expect(throwable([])).to.throw(error([]));
+      expect(throwable(undefined)).to.throw(error(undefined));
+      expect(throwable(null)).to.throw(error(null));
       throwable({})();
       throwable({foo: 'bar'})();
     });

+ 12 - 12
src/definition/model/model-definition-validator.js

@@ -15,33 +15,33 @@ export class ModelDefinitionValidator extends Service {
   validate(modelDef) {
     if (!modelDef || typeof modelDef !== 'object' || Array.isArray(modelDef))
       throw new InvalidArgumentError(
-        'The model definition should be an Object, but %s given.',
+        'The model definition should be an Object, but %v given.',
         modelDef,
       );
     if (!modelDef.name || typeof modelDef.name !== 'string')
       throw new InvalidArgumentError(
         'The model definition requires the option "name" ' +
-          'as a non-empty String, but %s given.',
+          'as a non-empty String, but %v given.',
         modelDef.name,
       );
     if (modelDef.datasource && typeof modelDef.datasource !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "datasource" of the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "datasource" of the model %v ' +
+          'should be a String, but %v given.',
         modelDef.name,
         modelDef.datasource,
       );
     if (modelDef.base && typeof modelDef.base !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "base" of the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "base" of the model %v ' +
+          'should be a String, but %v given.',
         modelDef.name,
         modelDef.base,
       );
     if (modelDef.tableName && typeof modelDef.tableName !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "tableName" of the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "tableName" of the model %v ' +
+          'should be a String, but %v given.',
         modelDef.name,
         modelDef.tableName,
       );
@@ -51,8 +51,8 @@ export class ModelDefinitionValidator extends Service {
         Array.isArray(modelDef.properties)
       ) {
         throw new InvalidArgumentError(
-          'The provided option "properties" of the model %s ' +
-            'should be an Object, but %s given.',
+          'The provided option "properties" of the model %v ' +
+            'should be an Object, but %v given.',
           modelDef.name,
           modelDef.properties,
         );
@@ -68,8 +68,8 @@ export class ModelDefinitionValidator extends Service {
         Array.isArray(modelDef.relations)
       ) {
         throw new InvalidArgumentError(
-          'The provided option "relations" of the model %s ' +
-            'should be an Object, but %s given.',
+          'The provided option "relations" of the model %v ' +
+            'should be an Object, but %v given.',
           modelDef.name,
           modelDef.relations,
         );

+ 43 - 43
src/definition/model/model-definition-validator.spec.js

@@ -1,6 +1,6 @@
 import chai from 'chai';
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {RelationsDefinitionValidator} from './relations/index.js';
 import {PropertiesDefinitionValidator} from './properties/index.js';
 import {ModelDefinitionValidator} from './model-definition-validator.js';
@@ -18,16 +18,16 @@ describe('ModelDefinitionValidator', function () {
       const validate = value => () => S.validate(value);
       const error = value =>
         format(
-          'The model definition should be an Object, but %s given.',
+          'The model definition should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({name: 'model'})();
     });
 
@@ -36,17 +36,17 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The model definition requires the option "name" ' +
-            'as a non-empty String, but %s given.',
+            'as a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('model')();
     });
 
@@ -56,13 +56,13 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "datasource" of the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('datasource')();
     });
 
@@ -71,13 +71,13 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "base" of the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('base')();
     });
 
@@ -87,13 +87,13 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "tableName" of the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('tableName')();
     });
 
@@ -103,13 +103,13 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "properties" of the model "model" ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate({})();
     });
 
@@ -119,13 +119,13 @@ describe('ModelDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "relations" of the model "model" ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate({})();
     });
 

+ 3 - 3
src/definition/model/properties/default-values-definition-validator.js

@@ -16,13 +16,13 @@ export class DefaultValuesDefinitionValidator extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'A first argument of DefaultValuesDefinitionValidator.validate ' +
-          'should be a non-empty String, but %s given.',
+          'should be a non-empty String, but %v given.',
         modelName,
       );
     if (!propDefs || typeof propDefs !== 'object' || Array.isArray(propDefs))
       throw new InvalidArgumentError(
-        'The provided option "properties" of the model %s ' +
-          'should be an Object, but %s given.',
+        'The provided option "properties" of the model %v ' +
+          'should be an Object, but %v given.',
         modelName,
         propDefs,
       );

+ 18 - 18
src/definition/model/properties/default-values-definition-validator.spec.js

@@ -1,5 +1,5 @@
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {DataType} from './data-type.js';
 import {DefaultValuesDefinitionValidator} from './default-values-definition-validator.js';
 
@@ -12,17 +12,17 @@ describe('DefaultValuesDefinitionValidator', function () {
       const error = value =>
         format(
           'A first argument of DefaultValuesDefinitionValidator.validate ' +
-            'should be a non-empty String, but %s given.',
+            'should be a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('model')();
     });
 
@@ -31,16 +31,16 @@ describe('DefaultValuesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "properties" of the model "model" ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({})();
     });
 

+ 4 - 4
src/definition/model/properties/primary-keys-definition-validator.js

@@ -22,7 +22,7 @@ export class PrimaryKeysDefinitionValidator extends Service {
         Object.keys(propDefs).includes(DEF_PK);
       if (isDefaultPrimaryKeyAlreadyInUse)
         throw new InvalidArgumentError(
-          'The property name %s of the model %s is defined as a regular property. ' +
+          'The property name %v of the model %v is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -32,8 +32,8 @@ export class PrimaryKeysDefinitionValidator extends Service {
     }
     if (propNames.length > 1)
       throw new InvalidArgumentError(
-        'The model definition %s should not have ' +
-          'multiple primary keys, but %s keys given.',
+        'The model definition %v should not have ' +
+          'multiple primary keys, but %v keys given.',
         modelName,
         propNames.length,
       );
@@ -46,7 +46,7 @@ export class PrimaryKeysDefinitionValidator extends Service {
     ) {
       throw new InvalidArgumentError(
         'Do not specify a default value for the ' +
-          'primary key %s of the model %s.',
+          'primary key %v of the model %v.',
         pkPropName,
         modelName,
       );

+ 5 - 5
src/definition/model/properties/primary-keys-definition-validator.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {DataType} from './data-type.js';
 import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
 import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '../model-definition-utils.js';
@@ -53,7 +53,7 @@ describe('PrimaryKeysDefinitionValidator', function () {
         });
       expect(throwable).to.throw(
         format(
-          'The property name "%s" of the model "model" is defined as a regular property. ' +
+          'The property name %v of the model "model" is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -70,7 +70,7 @@ describe('PrimaryKeysDefinitionValidator', function () {
         });
       expect(throwable).to.throw(
         format(
-          'The property name "%s" of the model "model" is defined as a regular property. ' +
+          'The property name %v of the model "model" is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -88,7 +88,7 @@ describe('PrimaryKeysDefinitionValidator', function () {
         });
       expect(throwable).to.throw(
         format(
-          'The property name "%s" of the model "model" is defined as a regular property. ' +
+          'The property name %v of the model "model" is defined as a regular property. ' +
             'In this case, a primary key should be defined explicitly. ' +
             'Do use the option "primaryKey" to specify the primary key.',
           DEF_PK,
@@ -108,7 +108,7 @@ describe('PrimaryKeysDefinitionValidator', function () {
       expect(throwable).to.throw(
         format(
           'Do not specify a default value for the ' +
-            'primary key "%s" of the model "model".',
+            'primary key %v of the model "model".',
           DEF_PK,
         ),
       );

+ 34 - 35
src/definition/model/properties/properties-definition-validator.js

@@ -1,6 +1,5 @@
 import {DataType as Type} from './data-type.js';
 import {Service} from '../../../service/index.js';
-import {arrayToString} from '../../../utils/index.js';
 import {InvalidArgumentError} from '../../../errors/index.js';
 import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
 import {DefaultValuesDefinitionValidator} from './default-values-definition-validator.js';
@@ -19,13 +18,13 @@ export class PropertiesDefinitionValidator extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'A first argument of PropertiesDefinitionValidator.validate ' +
-          'should be a non-empty String, but %s given.',
+          'should be a non-empty String, but %v given.',
         modelName,
       );
     if (!propDefs || typeof propDefs !== 'object' || Array.isArray(propDefs)) {
       throw new InvalidArgumentError(
-        'The provided option "properties" of the model %s ' +
-          'should be an Object, but %s given.',
+        'The provided option "properties" of the model %v ' +
+          'should be an Object, but %v given.',
         modelName,
         propDefs,
       );
@@ -50,20 +49,20 @@ export class PropertiesDefinitionValidator extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'A first argument of PropertiesDefinitionValidator._validateProperty ' +
-          'should be a non-empty String, but %s given.',
+          'should be a non-empty String, but %v given.',
         modelName,
       );
     if (!propName || typeof propName !== 'string')
       throw new InvalidArgumentError(
-        'The property name of the model %s should be ' +
-          'a non-empty String, but %s given.',
+        'The property name of the model %v should be ' +
+          'a non-empty String, but %v given.',
         modelName,
         propName,
       );
     if (!propDef)
       throw new InvalidArgumentError(
-        'The property %s of the model %s should have ' +
-          'a property definition, but %s given.',
+        'The property %v of the model %v should have ' +
+          'a property definition, but %v given.',
         propName,
         modelName,
         propDef,
@@ -71,19 +70,19 @@ export class PropertiesDefinitionValidator extends Service {
     if (typeof propDef === 'string') {
       if (!Object.values(Type).includes(propDef))
         throw new InvalidArgumentError(
-          'In case of a short property definition, the property %s ' +
-            'of the model %s should have one of data types: %s, but %s given.',
+          'In case of a short property definition, the property %v ' +
+            'of the model %v should have one of data types: %l, but %v given.',
           propName,
           modelName,
-          new String(arrayToString(Object.values(Type))),
+          Object.values(Type),
           propDef,
         );
       return;
     }
     if (!propDef || typeof propDef !== 'object' || Array.isArray(propDef)) {
       throw new InvalidArgumentError(
-        'In case of a full property definition, the property %s ' +
-          'of the model %s should be an Object, but %s given.',
+        'In case of a full property definition, the property %v ' +
+          'of the model %v should be an Object, but %v given.',
         propName,
         modelName,
         propDef,
@@ -91,87 +90,87 @@ export class PropertiesDefinitionValidator extends Service {
     }
     if (!propDef.type || !Object.values(Type).includes(propDef.type))
       throw new InvalidArgumentError(
-        'The property %s of the model %s requires the option "type" ' +
-          'to have one of data types: %s, but %s given.',
+        'The property %v of the model %v requires the option "type" ' +
+          'to have one of data types: %l, but %v given.',
         propName,
         modelName,
-        new String(arrayToString(Object.values(Type))),
+        Object.values(Type),
         propDef.type,
       );
     if (propDef.itemType && !Object.values(Type).includes(propDef.itemType)) {
       throw new InvalidArgumentError(
-        'The provided option "itemType" of the property %s in the model %s ' +
-          'should have one of data types: %s, but %s given.',
+        'The provided option "itemType" of the property %v in the model %v ' +
+          'should have one of data types: %l, but %v given.',
         propName,
         modelName,
-        new String(arrayToString(Object.values(Type))),
+        Object.values(Type),
         propDef.itemType,
       );
     }
     if (propDef.model && typeof propDef.model !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "model" of the property %s in the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "model" of the property %v in the model %v ' +
+          'should be a String, but %v given.',
         propName,
         modelName,
         propDef.model,
       );
     if (propDef.primaryKey && typeof propDef.primaryKey !== 'boolean')
       throw new InvalidArgumentError(
-        'The provided option "primaryKey" of the property %s in the model %s ' +
-          'should be a Boolean, but %s given.',
+        'The provided option "primaryKey" of the property %v in the model %v ' +
+          'should be a Boolean, but %v given.',
         propName,
         modelName,
         propDef.primaryKey,
       );
     if (propDef.columnName && typeof propDef.columnName !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "columnName" of the property %s in the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "columnName" of the property %v in the model %v ' +
+          'should be a String, but %v given.',
         propName,
         modelName,
         propDef.columnName,
       );
     if (propDef.columnType && typeof propDef.columnType !== 'string')
       throw new InvalidArgumentError(
-        'The provided option "columnType" of the property %s in the model %s ' +
-          'should be a String, but %s given.',
+        'The provided option "columnType" of the property %v in the model %v ' +
+          'should be a String, but %v given.',
         propName,
         modelName,
         propDef.columnType,
       );
     if (propDef.required && typeof propDef.required !== 'boolean')
       throw new InvalidArgumentError(
-        'The provided option "required" of the property %s in the model %s ' +
-          'should be a Boolean, but %s given.',
+        'The provided option "required" of the property %v in the model %v ' +
+          'should be a Boolean, but %v given.',
         propName,
         modelName,
         propDef.required,
       );
     if (propDef.required && propDef.default !== undefined)
       throw new InvalidArgumentError(
-        'The property %s of the model %s is a required property, ' +
+        'The property %v of the model %v is a required property, ' +
           'so it should not have the option "default" to be provided.',
         propName,
         modelName,
       );
     if (propDef.primaryKey && propDef.required)
       throw new InvalidArgumentError(
-        'The property %s of the model %s is a primary key, ' +
+        'The property %v of the model %v is a primary key, ' +
           'so it should not have the option "required" to be provided.',
         propName,
         modelName,
       );
     if (propDef.primaryKey && propDef.default !== undefined)
       throw new InvalidArgumentError(
-        'The property %s of the model %s is a primary key, ' +
+        'The property %v of the model %v is a primary key, ' +
           'so it should not have the option "default" to be provided.',
         propName,
         modelName,
       );
     if (propDef.itemType && propDef.type !== Type.ARRAY)
       throw new InvalidArgumentError(
-        'The property %s of the model %s has the non-array type, ' +
+        'The property %v of the model %v has the non-array type, ' +
           'so it should not have the option "itemType" to be provided.',
         propName,
         modelName,
@@ -179,7 +178,7 @@ export class PropertiesDefinitionValidator extends Service {
       );
     if (propDef.model && propDef.type !== Type.OBJECT)
       throw new InvalidArgumentError(
-        'The property %s of the model %s has the non-object type, ' +
+        'The property %v of the model %v has the non-object type, ' +
           'so it should not have the option "model" to be provided.',
         propName,
         modelName,

+ 70 - 71
src/definition/model/properties/properties-definition-validator.spec.js

@@ -1,8 +1,7 @@
 import chai from 'chai';
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {DataType} from './data-type.js';
-import {arrayToString} from '../../../utils/index.js';
 import {PropertiesDefinitionValidator} from './properties-definition-validator.js';
 import {PrimaryKeysDefinitionValidator} from './primary-keys-definition-validator.js';
 import {DefaultValuesDefinitionValidator} from './default-values-definition-validator.js';
@@ -21,17 +20,17 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'A first argument of PropertiesDefinitionValidator.validate ' +
-            'should be a non-empty String, but %s given.',
+            'should be a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('model')();
     });
 
@@ -40,16 +39,16 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "properties" of the model "model" ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({})();
     });
 
@@ -58,10 +57,10 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The property name of the model "model" should be ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           value,
         );
-      expect(validate({['']: {}})).to.throw(error('""'));
+      expect(validate({['']: {}})).to.throw(error(''));
       validate({foo: DataType.STRING})();
     });
 
@@ -70,11 +69,11 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The property "foo" of the model "model" should have ' +
-            'a property definition, but %s given.',
+            'a property definition, but %v given.',
           value,
         );
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate(DataType.STRING)();
       validate({type: DataType.STRING})();
     });
@@ -84,11 +83,11 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'In case of a short property definition, the property "foo" ' +
-            'of the model "model" should have one of data types: %s, but %s given.',
-          arrayToString(Object.values(DataType)),
+            'of the model "model" should have one of data types: %l, but %v given.',
+          Object.values(DataType),
           value,
         );
-      expect(validate('invalid')).to.throw(error('"invalid"'));
+      expect(validate('invalid')).to.throw(error('invalid'));
       validate(DataType.STRING)();
     });
 
@@ -97,12 +96,12 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'In case of a full property definition, the property "foo" ' +
-            'of the model "model" should be an Object, but %s given.',
+            'of the model "model" should be an Object, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate({type: DataType.STRING})();
     });
 
@@ -111,18 +110,18 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The property "foo" of the model "model" requires the option "type" ' +
-            'to have one of data types: %s, but %s given.',
-          arrayToString(Object.values(DataType)),
+            'to have one of data types: %l, but %v given.',
+          Object.values(DataType),
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate(DataType.STRING)();
     });
 
@@ -134,15 +133,15 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "itemType" of the property "foo" in the model "model" ' +
-            'should have one of data types: %s, but %s given.',
-          arrayToString(Object.values(DataType)),
+            'should have one of data types: %l, but %v given.',
+          Object.values(DataType),
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate(DataType.STRING)();
     });
 
@@ -157,13 +156,13 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "model" of the property "foo" in the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('model')();
     });
 
@@ -178,12 +177,12 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "primaryKey" of the property "foo" in the model "model" ' +
-            'should be a Boolean, but %s given.',
+            'should be a Boolean, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate(true)();
       validate(false)();
     });
@@ -199,13 +198,13 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "columnName" of the property "foo" in the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('columnName')();
     });
 
@@ -220,13 +219,13 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "columnType" of the property "foo" in the model "model" ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate('columnType')();
     });
 
@@ -241,12 +240,12 @@ describe('PropertiesDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "required" of the property "foo" in the model "model" ' +
-            'should be a Boolean, but %s given.',
+            'should be a Boolean, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
       validate(true)();
       validate(false)();
     });

+ 52 - 53
src/definition/model/relations/relations-definition-validator.js

@@ -1,6 +1,5 @@
 import {RelationType} from './relation-type.js';
 import {Service} from '../../../service/index.js';
-import {arrayToString} from '../../../utils/index.js';
 import {RelationType as Type} from './relation-type.js';
 import {InvalidArgumentError} from '../../../errors/index.js';
 
@@ -18,13 +17,13 @@ export class RelationsDefinitionValidator extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'A first argument of RelationsDefinitionValidator.validate ' +
-          'should be a non-empty String, but %s given.',
+          'should be a non-empty String, but %v given.',
         modelName,
       );
     if (!relDefs || typeof relDefs !== 'object' || Array.isArray(relDefs))
       throw new InvalidArgumentError(
-        'The provided option "relations" of the model %s ' +
-          'should be an Object, but %s given.',
+        'The provided option "relations" of the model %v ' +
+          'should be an Object, but %v given.',
         modelName,
         relDefs,
       );
@@ -46,30 +45,30 @@ export class RelationsDefinitionValidator extends Service {
     if (!modelName || typeof modelName !== 'string')
       throw new InvalidArgumentError(
         'A first argument of RelationsDefinitionValidator._validateRelation ' +
-          'should be a non-empty String, but %s given.',
+          'should be a non-empty String, but %v given.',
         modelName,
       );
     if (!relName || typeof relName !== 'string')
       throw new InvalidArgumentError(
-        'The relation name of the model %s should be ' +
-          'a non-empty String, but %s given.',
+        'The relation name of the model %v should be ' +
+          'a non-empty String, but %v given.',
         modelName,
         relName,
       );
     if (!relDef || typeof relDef !== 'object' || Array.isArray(relDef))
       throw new InvalidArgumentError(
-        'The relation %s of the model %s should be an Object, but %s given.',
+        'The relation %v of the model %v should be an Object, but %v given.',
         relName,
         modelName,
         relDef,
       );
     if (!relDef.type || !Object.values(Type).includes(relDef.type))
       throw new InvalidArgumentError(
-        'The relation %s of the model %s requires the option "type" ' +
-          'to have one of relation types: %s, but %s given.',
+        'The relation %v of the model %v requires the option "type" ' +
+          'to have one of relation types: %l, but %v given.',
         relName,
         modelName,
-        new String(arrayToString(Object.values(Type))),
+        Object.values(Type),
         relDef.type,
       );
     this._validateBelongsTo(modelName, relName, relDef);
@@ -111,27 +110,27 @@ export class RelationsDefinitionValidator extends Service {
       // A polymorphic "belongsTo" relation.
       if (typeof relDef.polymorphic !== 'boolean')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "belongsTo", ' +
+          'The relation %v of the model %v has the type "belongsTo", ' +
             'so it expects the option "polymorphic" to be a Boolean, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.polymorphic,
         );
       if (relDef.foreignKey && typeof relDef.foreignKey !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s is a polymorphic "belongsTo" relation, ' +
+          'The relation %v of the model %v is a polymorphic "belongsTo" relation, ' +
             'so it expects the provided option "foreignKey" to be a String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.foreignKey,
         );
       if (relDef.discriminator && typeof relDef.discriminator !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s is a polymorphic "belongsTo" relation, ' +
+          'The relation %v of the model %v is a polymorphic "belongsTo" relation, ' +
             'so it expects the provided option "discriminator" to be a String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.discriminator,
@@ -140,25 +139,25 @@ export class RelationsDefinitionValidator extends Service {
       // A regular "belongsTo" relation.
       if (!relDef.model || typeof relDef.model !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "belongsTo", ' +
+          'The relation %v of the model %v has the type "belongsTo", ' +
             'so it requires the option "model" to be a non-empty String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.model,
         );
       if (relDef.foreignKey && typeof relDef.foreignKey !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "belongsTo", ' +
+          'The relation %v of the model %v has the type "belongsTo", ' +
             'so it expects the provided option "foreignKey" to be a String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.foreignKey,
         );
       if (relDef.discriminator)
         throw new InvalidArgumentError(
-          'The relation %s of the model %s is a non-polymorphic "belongsTo" relation, ' +
+          'The relation %v of the model %v is a non-polymorphic "belongsTo" relation, ' +
             'so it should not have the option "discriminator" to be provided.',
           relName,
           modelName,
@@ -207,9 +206,9 @@ export class RelationsDefinitionValidator extends Service {
     if (relDef.type !== RelationType.HAS_ONE) return;
     if (!relDef.model || typeof relDef.model !== 'string')
       throw new InvalidArgumentError(
-        'The relation %s of the model %s has the type "hasOne", ' +
+        'The relation %v of the model %v has the type "hasOne", ' +
           'so it requires the option "model" to be a non-empty String, ' +
-          'but %s given.',
+          'but %v given.',
         relName,
         modelName,
         relDef.model,
@@ -219,7 +218,7 @@ export class RelationsDefinitionValidator extends Service {
         // A polymorphic "hasOne" relation with a target relation name.
         if (relDef.foreignKey)
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" with ' +
+            'The relation %v of the model %v has the option "polymorphic" with ' +
               'a String value, so it should not have the option "foreignKey" ' +
               'to be provided.',
             relName,
@@ -227,7 +226,7 @@ export class RelationsDefinitionValidator extends Service {
           );
         if (relDef.discriminator)
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" with ' +
+            'The relation %v of the model %v has the option "polymorphic" with ' +
               'a String value, so it should not have the option "discriminator" ' +
               'to be provided.',
             relName,
@@ -237,27 +236,27 @@ export class RelationsDefinitionValidator extends Service {
         // A polymorphic "hasOne" relation with target relation keys.
         if (!relDef.foreignKey || typeof relDef.foreignKey !== 'string')
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" ' +
+            'The relation %v of the model %v has the option "polymorphic" ' +
               'with "true" value, so it requires the option "foreignKey" ' +
-              'to be a non-empty String, but %s given.',
+              'to be a non-empty String, but %v given.',
             relName,
             modelName,
             relDef.foreignKey,
           );
         if (!relDef.discriminator || typeof relDef.discriminator !== 'string')
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" ' +
+            'The relation %v of the model %v has the option "polymorphic" ' +
               'with "true" value, so it requires the option "discriminator" ' +
-              'to be a non-empty String, but %s given.',
+              'to be a non-empty String, but %v given.',
             relName,
             modelName,
             relDef.discriminator,
           );
       } else {
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "hasOne", ' +
+          'The relation %v of the model %v has the type "hasOne", ' +
             'so it expects the provided option "polymorphic" to be ' +
-            'a String or a Boolean, but %s given.',
+            'a String or a Boolean, but %v given.',
           relName,
           modelName,
           relDef.polymorphic,
@@ -267,16 +266,16 @@ export class RelationsDefinitionValidator extends Service {
       // A regular "hasOne" relation.
       if (!relDef.foreignKey || typeof relDef.foreignKey !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "hasOne", ' +
+          'The relation %v of the model %v has the type "hasOne", ' +
             'so it requires the option "foreignKey" to be a non-empty String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.foreignKey,
         );
       if (relDef.discriminator)
         throw new InvalidArgumentError(
-          'The relation %s of the model %s is a non-polymorphic "hasOne" relation, ' +
+          'The relation %v of the model %v is a non-polymorphic "hasOne" relation, ' +
             'so it should not have the option "discriminator" to be provided.',
           relName,
           modelName,
@@ -325,9 +324,9 @@ export class RelationsDefinitionValidator extends Service {
     if (relDef.type !== RelationType.HAS_MANY) return;
     if (!relDef.model || typeof relDef.model !== 'string')
       throw new InvalidArgumentError(
-        'The relation %s of the model %s has the type "hasMany", ' +
+        'The relation %v of the model %v has the type "hasMany", ' +
           'so it requires the option "model" to be a non-empty String, ' +
-          'but %s given.',
+          'but %v given.',
         relName,
         modelName,
         relDef.model,
@@ -337,7 +336,7 @@ export class RelationsDefinitionValidator extends Service {
         // A polymorphic "hasMany" relation with a target relation name.
         if (relDef.foreignKey)
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" with ' +
+            'The relation %v of the model %v has the option "polymorphic" with ' +
               'a String value, so it should not have the option "foreignKey" ' +
               'to be provided.',
             relName,
@@ -345,7 +344,7 @@ export class RelationsDefinitionValidator extends Service {
           );
         if (relDef.discriminator)
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" with ' +
+            'The relation %v of the model %v has the option "polymorphic" with ' +
               'a String value, so it should not have the option "discriminator" ' +
               'to be provided.',
             relName,
@@ -355,27 +354,27 @@ export class RelationsDefinitionValidator extends Service {
         // A polymorphic "hasMany" relation with target relation keys.
         if (!relDef.foreignKey || typeof relDef.foreignKey !== 'string')
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" ' +
+            'The relation %v of the model %v has the option "polymorphic" ' +
               'with "true" value, so it requires the option "foreignKey" ' +
-              'to be a non-empty String, but %s given.',
+              'to be a non-empty String, but %v given.',
             relName,
             modelName,
             relDef.foreignKey,
           );
         if (!relDef.discriminator || typeof relDef.discriminator !== 'string')
           throw new InvalidArgumentError(
-            'The relation %s of the model %s has the option "polymorphic" ' +
+            'The relation %v of the model %v has the option "polymorphic" ' +
               'with "true" value, so it requires the option "discriminator" ' +
-              'to be a non-empty String, but %s given.',
+              'to be a non-empty String, but %v given.',
             relName,
             modelName,
             relDef.discriminator,
           );
       } else {
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "hasMany", ' +
+          'The relation %v of the model %v has the type "hasMany", ' +
             'so it expects the provided option "polymorphic" to be ' +
-            'a String or a Boolean, but %s given.',
+            'a String or a Boolean, but %v given.',
           relName,
           modelName,
           relDef.polymorphic,
@@ -385,16 +384,16 @@ export class RelationsDefinitionValidator extends Service {
       // A regular "hasMany" relation.
       if (!relDef.foreignKey || typeof relDef.foreignKey !== 'string')
         throw new InvalidArgumentError(
-          'The relation %s of the model %s has the type "hasMany", ' +
+          'The relation %v of the model %v has the type "hasMany", ' +
             'so it requires the option "foreignKey" to be a non-empty String, ' +
-            'but %s given.',
+            'but %v given.',
           relName,
           modelName,
           relDef.foreignKey,
         );
       if (relDef.discriminator)
         throw new InvalidArgumentError(
-          'The relation %s of the model %s is a non-polymorphic "hasMany" relation, ' +
+          'The relation %v of the model %v is a non-polymorphic "hasMany" relation, ' +
             'so it should not have the option "discriminator" to be provided.',
           relName,
           modelName,
@@ -423,25 +422,25 @@ export class RelationsDefinitionValidator extends Service {
     if (relDef.type !== Type.REFERENCES_MANY) return;
     if (!relDef.model || typeof relDef.model !== 'string')
       throw new InvalidArgumentError(
-        'The relation %s of the model %s has the type "referencesMany", ' +
+        'The relation %v of the model %v has the type "referencesMany", ' +
           'so it requires the option "model" to be a non-empty String, ' +
-          'but %s given.',
+          'but %v given.',
         relName,
         modelName,
         relDef.model,
       );
     if (relDef.foreignKey && typeof relDef.foreignKey !== 'string')
       throw new InvalidArgumentError(
-        'The relation %s of the model %s has the type "referencesMany", ' +
+        'The relation %v of the model %v has the type "referencesMany", ' +
           'so it expects the provided option "foreignKey" to be a String, ' +
-          'but %s given.',
+          'but %v given.',
         relName,
         modelName,
         relDef.foreignKey,
       );
     if (relDef.discriminator)
       throw new InvalidArgumentError(
-        'The relation %s of the model %s has the type "referencesMany", ' +
+        'The relation %v of the model %v has the type "referencesMany", ' +
           'so it should not have the option "discriminator" to be provided.',
         relName,
         modelName,

+ 207 - 208
src/definition/model/relations/relations-definition-validator.spec.js

@@ -1,7 +1,6 @@
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {RelationType} from './relation-type.js';
-import {arrayToString} from '../../../utils/index.js';
 import {RelationsDefinitionValidator} from './relations-definition-validator.js';
 
 const S = new RelationsDefinitionValidator();
@@ -13,17 +12,17 @@ describe('RelationsDefinitionValidator', function () {
       const error = value =>
         format(
           'A first argument of RelationsDefinitionValidator.validate ' +
-            'should be a non-empty String, but %s given.',
+            'should be a non-empty String, but %v given.',
           value,
         );
-      expect(validate('')).to.throw(error('""'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('')).to.throw(error(''));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate('model')();
     });
 
@@ -32,16 +31,16 @@ describe('RelationsDefinitionValidator', function () {
       const error = value =>
         format(
           'The provided option "relations" of the model "model" ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({})();
     });
 
@@ -50,10 +49,10 @@ describe('RelationsDefinitionValidator', function () {
       const error = value =>
         format(
           'The relation name of the model "model" should be ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           value,
         );
-      expect(validate({['']: {}})).to.throw(error('""'));
+      expect(validate({['']: {}})).to.throw(error(''));
       validate({foo: {type: RelationType.BELONGS_TO, model: 'model'}})();
     });
 
@@ -62,16 +61,16 @@ describe('RelationsDefinitionValidator', function () {
       const error = value =>
         format(
           'The relation "foo" of the model "model" should ' +
-            'be an Object, but %s given.',
+            'be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate({type: RelationType.BELONGS_TO, model: 'model'})();
     });
 
@@ -83,18 +82,18 @@ describe('RelationsDefinitionValidator', function () {
       const error = value =>
         format(
           'The relation "foo" of the model "model" requires the option "type" ' +
-            'to have one of relation types: %s, but %s given.',
-          arrayToString(Object.values(RelationType)),
+            'to have one of relation types: %l, but %v given.',
+          Object.values(RelationType),
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate(false)).to.throw(error('false'));
-      expect(validate([])).to.throw(error('Array'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate(undefined)).to.throw(error('undefined'));
-      expect(validate(null)).to.throw(error('null'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate(false)).to.throw(error(false));
+      expect(validate([])).to.throw(error([]));
+      expect(validate({})).to.throw(error({}));
+      expect(validate(undefined)).to.throw(error(undefined));
+      expect(validate(null)).to.throw(error(null));
       validate(RelationType.BELONGS_TO)();
     });
 
@@ -108,21 +107,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "belongsTo", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -135,17 +134,17 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "belongsTo", ' +
                 'so it expects the provided option "foreignKey" to be a String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
           validate('foreignKey')();
           validate('')();
           validate(false)();
@@ -182,13 +181,13 @@ describe('RelationsDefinitionValidator', function () {
             format(
               'The relation "foo" of the model "model" has the type "belongsTo", ' +
                 'so it expects the option "polymorphic" to be a Boolean, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('str')).to.throw(error('"str"'));
-          expect(validate(10)).to.throw(error('10'));
-          expect(validate([])).to.throw(error('Array'));
-          expect(validate({})).to.throw(error('Object'));
+          expect(validate('str')).to.throw(error('str'));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate([])).to.throw(error([]));
+          expect(validate({})).to.throw(error({}));
           validate(true)();
         });
 
@@ -201,17 +200,17 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" is a polymorphic "belongsTo" relation, ' +
                 'so it expects the provided option "foreignKey" to be a String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
           validate('foreignKey')();
           validate('')();
           validate(false)();
@@ -228,17 +227,17 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" is a polymorphic "belongsTo" relation, ' +
                 'so it expects the provided option "discriminator" to be a String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
           validate('discriminator')();
           validate('')();
           validate(false)();
@@ -259,21 +258,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasOne", ' +
                 'so it requires the option "foreignKey" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('modelId')();
         });
 
@@ -286,21 +285,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasOne", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -331,21 +330,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasOne", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -396,21 +395,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasOne", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -425,21 +424,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the option "polymorphic" ' +
                 'with "true" value, so it requires the option "foreignKey" ' +
-                'to be a non-empty String, but %s given.',
+                'to be a non-empty String, but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('referenceId')();
         });
 
@@ -454,21 +453,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the option "polymorphic" ' +
                 'with "true" value, so it requires the option "discriminator" ' +
-                'to be a non-empty String, but %s given.',
+                'to be a non-empty String, but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('referenceType')();
         });
       });
@@ -485,21 +484,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasMany", ' +
                 'so it requires the option "foreignKey" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('modelId')();
         });
 
@@ -512,21 +511,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasMany", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -557,21 +556,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasMany", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -622,21 +621,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the type "hasMany", ' +
                 'so it requires the option "model" to be a non-empty String, ' +
-                'but %s given.',
+                'but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('model')();
         });
 
@@ -651,21 +650,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the option "polymorphic" ' +
                 'with "true" value, so it requires the option "foreignKey" ' +
-                'to be a non-empty String, but %s given.',
+                'to be a non-empty String, but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('referenceId')();
         });
 
@@ -680,21 +679,21 @@ describe('RelationsDefinitionValidator', function () {
             };
             return () => S.validate('model', {foo});
           };
-          const createError = value =>
+          const error = value =>
             format(
               'The relation "foo" of the model "model" has the option "polymorphic" ' +
                 'with "true" value, so it requires the option "discriminator" ' +
-                'to be a non-empty String, but %s given.',
+                'to be a non-empty String, but %v given.',
               value,
             );
-          expect(validate('')).to.throw(createError('""'));
-          expect(validate(10)).to.throw(createError('10'));
-          expect(validate(true)).to.throw(createError('true'));
-          expect(validate(false)).to.throw(createError('false'));
-          expect(validate({})).to.throw(createError('Object'));
-          expect(validate([])).to.throw(createError('Array'));
-          expect(validate(undefined)).to.throw(createError('undefined'));
-          expect(validate(null)).to.throw(createError('null'));
+          expect(validate('')).to.throw(error(''));
+          expect(validate(10)).to.throw(error(10));
+          expect(validate(true)).to.throw(error(true));
+          expect(validate(false)).to.throw(error(false));
+          expect(validate({})).to.throw(error({}));
+          expect(validate([])).to.throw(error([]));
+          expect(validate(undefined)).to.throw(error(undefined));
+          expect(validate(null)).to.throw(error(null));
           validate('referenceType')();
         });
       });
@@ -709,21 +708,21 @@ describe('RelationsDefinitionValidator', function () {
           };
           return () => S.validate('model', {foo});
         };
-        const createError = value =>
+        const error = value =>
           format(
             'The relation "foo" of the model "model" has the type "referencesMany", ' +
               'so it requires the option "model" to be a non-empty String, ' +
-              'but %s given.',
+              'but %v given.',
             value,
           );
-        expect(validate('')).to.throw(createError('""'));
-        expect(validate(10)).to.throw(createError('10'));
-        expect(validate(true)).to.throw(createError('true'));
-        expect(validate(false)).to.throw(createError('false'));
-        expect(validate({})).to.throw(createError('Object'));
-        expect(validate([])).to.throw(createError('Array'));
-        expect(validate(undefined)).to.throw(createError('undefined'));
-        expect(validate(null)).to.throw(createError('null'));
+        expect(validate('')).to.throw(error(''));
+        expect(validate(10)).to.throw(error(10));
+        expect(validate(true)).to.throw(error(true));
+        expect(validate(false)).to.throw(error(false));
+        expect(validate({})).to.throw(error({}));
+        expect(validate([])).to.throw(error([]));
+        expect(validate(undefined)).to.throw(error(undefined));
+        expect(validate(null)).to.throw(error(null));
         validate('model')();
       });
 
@@ -736,17 +735,17 @@ describe('RelationsDefinitionValidator', function () {
           };
           return () => S.validate('model', {foo});
         };
-        const createError = value =>
+        const error = value =>
           format(
             'The relation "foo" of the model "model" has the type "referencesMany", ' +
               'so it expects the provided option "foreignKey" to be a String, ' +
-              'but %s given.',
+              'but %v given.',
             value,
           );
-        expect(validate(10)).to.throw(createError('10'));
-        expect(validate(true)).to.throw(createError('true'));
-        expect(validate({})).to.throw(createError('Object'));
-        expect(validate([])).to.throw(createError('Array'));
+        expect(validate(10)).to.throw(error(10));
+        expect(validate(true)).to.throw(error(true));
+        expect(validate({})).to.throw(error({}));
+        expect(validate([])).to.throw(error([]));
         validate('foreignKey')();
         validate('')();
         validate(false)();

+ 2 - 16
src/errors/invalid-argument-error.js

@@ -1,20 +1,6 @@
-import {format} from 'util';
-import {valueToString} from '../utils/index.js';
+import {Errorf} from '@e22m4u/format';
 
 /**
  * Invalid argument error.
  */
-export class InvalidArgumentError extends Error {
-  /**
-   * Constructor.
-   *
-   * @param pattern
-   * @param args
-   */
-  constructor(pattern, ...args) {
-    const vars = args.map(valueToString);
-    const message =
-      typeof pattern === 'string' ? format(pattern, ...vars) : undefined;
-    super(message);
-  }
-}
+export class InvalidArgumentError extends Errorf {}

+ 16 - 16
src/errors/invalid-argument-error.spec.js

@@ -1,4 +1,5 @@
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {InvalidArgumentError} from './invalid-argument-error.js';
 
 describe('InvalidArgumentError', function () {
@@ -13,21 +14,20 @@ describe('InvalidArgumentError', function () {
   });
 
   it('interpolates a given pattern with variables', function () {
-    const error = new InvalidArgumentError(
-      '%s, %s, %s, %s, %s, %s, %s, %s, %s and %s',
-      'str',
-      10,
-      true,
-      false,
-      {},
-      [],
-      undefined,
-      null,
-      () => undefined,
-      function () {},
-    );
-    expect(error.message).to.be.eq(
-      '"str", 10, true, false, Object, Array, undefined, null, Function and Function',
-    );
+    const throwable = v => () => {
+      throw new InvalidArgumentError('%v', v);
+    };
+    const error = v => format('%v', v);
+    expect(throwable('str')).to.throw(error('str'));
+    expect(throwable('')).to.throw(error(''));
+    expect(throwable(10)).to.throw(error(10));
+    expect(throwable(0)).to.throw(error(0));
+    expect(throwable(true)).to.throw(error(true));
+    expect(throwable(false)).to.throw(error(false));
+    expect(throwable({})).to.throw(error({}));
+    expect(throwable([])).to.throw(error([]));
+    expect(throwable(undefined)).to.throw(error(undefined));
+    expect(throwable(null)).to.throw(error(null));
+    expect(throwable(() => undefined)).to.throw(error(() => undefined));
   });
 });

+ 3 - 4
src/errors/invalid-operator-value-error.js

@@ -1,5 +1,4 @@
-import {format} from 'util';
-import {valueToString} from '../utils/index.js';
+import {format} from '@e22m4u/format';
 
 /**
  * Invalid operator value error.
@@ -15,10 +14,10 @@ export class InvalidOperatorValueError extends Error {
   constructor(operator, expected, value) {
     super(
       format(
-        'Condition of {%s: ...} should have %s, %s given.',
+        'Condition of {%s: ...} should have %s, %v given.',
         operator,
         expected,
-        valueToString(value),
+        value,
       ),
     );
   }

+ 2 - 16
src/errors/not-implemented-error.js

@@ -1,20 +1,6 @@
-import {format} from 'util';
-import {valueToString} from '../utils/index.js';
+import {Errorf} from '@e22m4u/format';
 
 /**
  * Not implemented error.
  */
-export class NotImplementedError extends Error {
-  /**
-   * Constructor.
-   *
-   * @param pattern
-   * @param args
-   */
-  constructor(pattern, ...args) {
-    const vars = args.map(valueToString);
-    const message =
-      typeof pattern === 'string' ? format(pattern, ...vars) : undefined;
-    super(message);
-  }
-}
+export class NotImplementedError extends Errorf {}

+ 16 - 16
src/errors/not-implemented-error.spec.js

@@ -1,4 +1,5 @@
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {NotImplementedError} from './not-implemented-error.js';
 
 describe('NotImplementedError', function () {
@@ -13,21 +14,20 @@ describe('NotImplementedError', function () {
   });
 
   it('interpolates a given pattern with variables', function () {
-    const error = new NotImplementedError(
-      '%s, %s, %s, %s, %s, %s, %s, %s, %s and %s',
-      'str',
-      10,
-      true,
-      false,
-      {},
-      [],
-      undefined,
-      null,
-      () => undefined,
-      function () {},
-    );
-    expect(error.message).to.be.eq(
-      '"str", 10, true, false, Object, Array, undefined, null, Function and Function',
-    );
+    const throwable = v => () => {
+      throw new NotImplementedError('%v', v);
+    };
+    const error = v => format('%v', v);
+    expect(throwable('str')).to.throw(error('str'));
+    expect(throwable('')).to.throw(error(''));
+    expect(throwable(10)).to.throw(error(10));
+    expect(throwable(0)).to.throw(error(0));
+    expect(throwable(true)).to.throw(error(true));
+    expect(throwable(false)).to.throw(error(false));
+    expect(throwable({})).to.throw(error({}));
+    expect(throwable([])).to.throw(error([]));
+    expect(throwable(undefined)).to.throw(error(undefined));
+    expect(throwable(null)).to.throw(error(null));
+    expect(throwable(() => undefined)).to.throw(error(() => undefined));
   });
 });

+ 4 - 4
src/filter/fields-clause-tool.js

@@ -22,7 +22,7 @@ export class FieldsClauseTool extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'A first argument of FieldClauseTool.filter should be an Object or ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
     });
@@ -32,7 +32,7 @@ export class FieldsClauseTool extends Service {
       if (!field || typeof field !== 'string')
         throw new InvalidArgumentError(
           'The provided option "fields" should be a String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           field,
         );
     });
@@ -57,7 +57,7 @@ export class FieldsClauseTool extends Service {
       if (!key || typeof key !== 'string')
         throw new InvalidArgumentError(
           'The provided option "fields" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           key,
         );
     });
@@ -75,7 +75,7 @@ export class FieldsClauseTool extends Service {
       if (!key || typeof key !== 'string')
         throw new InvalidArgumentError(
           'The provided option "fields" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           key,
         );
     });

+ 21 - 21
src/filter/fields-clause-tool.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {format} from 'util';
 import {Schema} from '../schema.js';
+import {format} from '@e22m4u/format';
 import {FieldsClauseTool} from './fields-clause-tool.js';
 import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '../definition/index.js';
 
@@ -78,18 +78,18 @@ describe('FieldsClauseTool', function () {
       const error = value =>
         format(
           'The provided option "fields" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate([''])).to.throw(error('""'));
-      expect(validate([10])).to.throw(error('10'));
-      expect(validate([true])).to.throw(error('true'));
-      expect(validate([false])).to.throw(error('false'));
-      expect(validate([undefined])).to.throw(error('undefined'));
-      expect(validate([null])).to.throw(error('null'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate({})).to.throw(error({}));
+      expect(validate([''])).to.throw(error(''));
+      expect(validate([10])).to.throw(error(10));
+      expect(validate([true])).to.throw(error(true));
+      expect(validate([false])).to.throw(error(false));
+      expect(validate([undefined])).to.throw(error(undefined));
+      expect(validate([null])).to.throw(error(null));
       validate('');
       validate(false);
       validate(undefined);
@@ -111,18 +111,18 @@ describe('FieldsClauseTool', function () {
       const error = value =>
         format(
           'The provided option "fields" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           value,
         );
-      expect(fn(10)).to.throw(error('10'));
-      expect(fn(true)).to.throw(error('true'));
-      expect(fn({})).to.throw(error('Object'));
-      expect(fn([''])).to.throw(error('""'));
-      expect(fn([10])).to.throw(error('10'));
-      expect(fn([true])).to.throw(error('true'));
-      expect(fn([false])).to.throw(error('false'));
-      expect(fn([undefined])).to.throw(error('undefined'));
-      expect(fn([null])).to.throw(error('null'));
+      expect(fn(10)).to.throw(error(10));
+      expect(fn(true)).to.throw(error(true));
+      expect(fn({})).to.throw(error({}));
+      expect(fn([''])).to.throw(error(''));
+      expect(fn([10])).to.throw(error(10));
+      expect(fn([true])).to.throw(error(true));
+      expect(fn([false])).to.throw(error(false));
+      expect(fn([undefined])).to.throw(error(undefined));
+      expect(fn([null])).to.throw(error(null));
       expect(fn('')()).to.be.undefined;
       expect(fn(false)()).to.be.undefined;
       expect(fn(undefined)()).to.be.undefined;

+ 9 - 9
src/filter/include-clause-tool.js

@@ -148,7 +148,7 @@ export class IncludeClauseTool extends Service {
           break;
         default:
           throw new InvalidArgumentError(
-            'The relation type %s does not have an inclusion resolver.',
+            'The relation type %v does not have an inclusion resolver.',
             relDef.type,
           );
       }
@@ -186,7 +186,7 @@ export class IncludeClauseTool extends Service {
       );
       if (duplicateNames.length)
         throw new InvalidArgumentError(
-          'The provided option "include" has duplicates of %s.',
+          'The provided option "include" has duplicates of %v.',
           duplicateNames[0],
         );
     } else if (typeof clause === 'object') {
@@ -196,7 +196,7 @@ export class IncludeClauseTool extends Service {
         if (!clause.relation || typeof clause.relation !== 'string')
           throw new InvalidArgumentError(
             'The provided option "relation" should be ' +
-              'a non-empty String, but %s given.',
+              'a non-empty String, but %v given.',
             clause.relation,
           );
         if ('scope' in clause && clause) this.validateScopeClause(clause.scope);
@@ -211,7 +211,7 @@ export class IncludeClauseTool extends Service {
       // unknown.
       throw new InvalidArgumentError(
         'The provided option "include" should have a value of ' +
-          'following types: String, Object or Array, but %s given.',
+          'following types: String, Object or Array, but %v given.',
         clause,
       );
     }
@@ -226,7 +226,7 @@ export class IncludeClauseTool extends Service {
     if (!clause) return;
     if (typeof clause !== 'object' || Array.isArray(clause))
       throw new InvalidArgumentError(
-        'The provided option "scope" should be an Object, but %s given.',
+        'The provided option "scope" should be an Object, but %v given.',
         clause,
       );
     if ('where' in clause && clause.where)
@@ -276,7 +276,7 @@ export class IncludeClauseTool extends Service {
       );
       if (duplicateNames.length)
         throw new InvalidArgumentError(
-          'The provided option "include" has duplicates of %s.',
+          'The provided option "include" has duplicates of %v.',
           duplicateNames[0],
         );
     } else if (typeof clause === 'object') {
@@ -286,7 +286,7 @@ export class IncludeClauseTool extends Service {
         if (!clause.relation || typeof clause.relation !== 'string')
           throw new InvalidArgumentError(
             'The provided option "relation" should be ' +
-              'a non-empty String, but %s given.',
+              'a non-empty String, but %v given.',
             clause.relation,
           );
         const normalized = {relation: clause.relation};
@@ -307,7 +307,7 @@ export class IncludeClauseTool extends Service {
       // unknown
       throw new InvalidArgumentError(
         'The provided option "include" should have a value of ' +
-          'following types: String, Object or Array, but %s given.',
+          'following types: String, Object or Array, but %v given.',
         clause,
       );
     }
@@ -324,7 +324,7 @@ export class IncludeClauseTool extends Service {
     if (!clause) return;
     if (typeof clause !== 'object' || Array.isArray(clause))
       throw new InvalidArgumentError(
-        'The provided option "scope" should be an Object, but %s given.',
+        'The provided option "scope" should be an Object, but %v given.',
         clause,
       );
     const result = {};

+ 13 - 13
src/filter/include-clause-tool.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {IncludeClauseTool} from './include-clause-tool.js';
 
 describe('IncludeClauseTool', function () {
@@ -43,11 +43,11 @@ describe('IncludeClauseTool', function () {
       const createError = v =>
         format(
           'The provided option "include" should have a value of ' +
-            'following types: String, Object or Array, but %s given.',
+            'following types: String, Object or Array, but %v given.',
           v,
         );
-      const testFor = (v, s) => {
-        const error = createError(s);
+      const testFor = v => {
+        const error = createError(v);
         const clauses = [
           v,
           // arrays
@@ -72,9 +72,9 @@ describe('IncludeClauseTool', function () {
         ];
         clauses.forEach(c => expect(validate(c)).to.throw(error));
       };
-      testFor(10, '10');
-      testFor(true, 'true');
-      testFor(() => undefined, 'Function');
+      testFor(10);
+      testFor(true);
+      testFor(() => undefined);
     });
 
     it('throws an error for duplicates', function () {
@@ -596,11 +596,11 @@ describe('IncludeClauseTool', function () {
       const createError = v =>
         format(
           'The provided option "include" should have a value of ' +
-            'following types: String, Object or Array, but %s given.',
+            'following types: String, Object or Array, but %v given.',
           v,
         );
-      const testFor = (v, s) => {
-        const error = createError(s);
+      const testFor = v => {
+        const error = createError(v);
         const clauses = [
           v,
           // arrays
@@ -625,9 +625,9 @@ describe('IncludeClauseTool', function () {
         ];
         clauses.forEach(c => expect(validate(c)).to.throw(error));
       };
-      testFor(10, '10');
-      testFor(true, 'true');
-      testFor(() => undefined, 'Function');
+      testFor(10);
+      testFor(true);
+      testFor(() => undefined);
     });
 
     it('throws an error for duplicates', function () {

+ 13 - 13
src/filter/operator-clause-tool.js

@@ -58,7 +58,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testAll ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
 
@@ -135,7 +135,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testEqNeq ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('eq' in clause) return this.compare(clause.eq, value) === 0;
@@ -180,7 +180,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testGtLt ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('gt' in clause) return this.compare(value, clause.gt) > 0;
@@ -206,7 +206,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testInq ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('inq' in clause && clause.inq !== undefined) {
@@ -241,7 +241,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testNin ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('nin' in clause && clause.nin !== undefined) {
@@ -276,7 +276,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testBetween ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('between' in clause && clause.between !== undefined) {
@@ -311,7 +311,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testExists ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('exists' in clause && clause.exists !== undefined) {
@@ -343,7 +343,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testLike ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('like' in clause && clause.like !== undefined) {
@@ -370,7 +370,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testNlike ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('nlike' in clause && clause.nlike !== undefined) {
@@ -401,7 +401,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testIlike ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('ilike' in clause && clause.ilike !== undefined) {
@@ -432,7 +432,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testNilike ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('nilike' in clause && clause.nilike !== undefined) {
@@ -475,7 +475,7 @@ export class OperatorClauseTool extends Service {
     if (!clause || typeof clause !== 'object')
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testRegexp ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         clause,
       );
     if ('regexp' in clause && clause.regexp !== undefined) {
@@ -492,7 +492,7 @@ export class OperatorClauseTool extends Service {
       const flags = clause.flags || undefined;
       if (flags && typeof flags !== 'string')
         throw new InvalidArgumentError(
-          'RegExp flags must be a String, but %s given.',
+          'RegExp flags must be a String, but %v given.',
           clause.flags,
         );
       if (!value || typeof value !== 'string') return false;

+ 6 - 6
src/filter/operator-clause-tool.spec.js

@@ -1,5 +1,5 @@
-import {format} from 'util';
 import {expect} from 'chai';
+import {format} from '@e22m4u/format';
 import {OperatorClauseTool} from './operator-clause-tool.js';
 import {InvalidOperatorValueError} from '../errors/index.js';
 
@@ -1049,11 +1049,11 @@ describe('OperatorClauseTool', function () {
       const throwable = v => () =>
         S.testRegexp({regexp: 'Val.+', flags: v}, 'val');
       const error = v =>
-        format('RegExp flags must be a String, but %s given.', v);
-      expect(throwable(10)).to.throw(error('10'));
-      expect(throwable(true)).to.throw(error('true'));
-      expect(throwable([])).to.throw(error('Array'));
-      expect(throwable({})).to.throw(error('Object'));
+        format('RegExp flags must be a String, but %v given.', v);
+      expect(throwable(10)).to.throw(error(10));
+      expect(throwable(true)).to.throw(error(true));
+      expect(throwable([])).to.throw(error([]));
+      expect(throwable({})).to.throw(error({}));
       throwable('')();
       throwable(0)();
       throwable(false)();

+ 3 - 3
src/filter/order-clause-tool.js

@@ -19,7 +19,7 @@ export class OrderClauseTool extends Service {
       if (typeof key !== 'string')
         throw new InvalidArgumentError(
           'The provided option "order" should be a String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           key,
         );
       let reverse = 1;
@@ -44,7 +44,7 @@ export class OrderClauseTool extends Service {
       if (!key || typeof key !== 'string')
         throw new InvalidArgumentError(
           'The provided option "order" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           key,
         );
     });
@@ -63,7 +63,7 @@ export class OrderClauseTool extends Service {
       if (!key || typeof key !== 'string')
         throw new InvalidArgumentError(
           'The provided option "order" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           key,
         );
     });

+ 21 - 21
src/filter/order-clause-tool.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {OrderClauseTool} from './order-clause-tool.js';
 
 const S = new OrderClauseTool();
@@ -383,18 +383,18 @@ describe('OrderClauseTool', function () {
       const error = value =>
         format(
           'The provided option "order" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           value,
         );
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate({})).to.throw(error('Object'));
-      expect(validate([''])).to.throw(error('""'));
-      expect(validate([10])).to.throw(error('10'));
-      expect(validate([true])).to.throw(error('true'));
-      expect(validate([false])).to.throw(error('false'));
-      expect(validate([undefined])).to.throw(error('undefined'));
-      expect(validate([null])).to.throw(error('null'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate({})).to.throw(error({}));
+      expect(validate([''])).to.throw(error(''));
+      expect(validate([10])).to.throw(error(10));
+      expect(validate([true])).to.throw(error(true));
+      expect(validate([false])).to.throw(error(false));
+      expect(validate([undefined])).to.throw(error(undefined));
+      expect(validate([null])).to.throw(error(null));
       validate('');
       validate(false);
       validate(undefined);
@@ -416,18 +416,18 @@ describe('OrderClauseTool', function () {
       const error = value =>
         format(
           'The provided option "order" should be a non-empty String ' +
-            'or an Array of String, but %s given.',
+            'or an Array of String, but %v given.',
           value,
         );
-      expect(fn(10)).to.throw(error('10'));
-      expect(fn(true)).to.throw(error('true'));
-      expect(fn({})).to.throw(error('Object'));
-      expect(fn([''])).to.throw(error('""'));
-      expect(fn([10])).to.throw(error('10'));
-      expect(fn([true])).to.throw(error('true'));
-      expect(fn([false])).to.throw(error('false'));
-      expect(fn([undefined])).to.throw(error('undefined'));
-      expect(fn([null])).to.throw(error('null'));
+      expect(fn(10)).to.throw(error(10));
+      expect(fn(true)).to.throw(error(true));
+      expect(fn({})).to.throw(error({}));
+      expect(fn([''])).to.throw(error(''));
+      expect(fn([10])).to.throw(error(10));
+      expect(fn([true])).to.throw(error(true));
+      expect(fn([false])).to.throw(error(false));
+      expect(fn([undefined])).to.throw(error(undefined));
+      expect(fn([null])).to.throw(error(null));
       expect(fn('')()).to.be.undefined;
       expect(fn(false)()).to.be.undefined;
       expect(fn(undefined)()).to.be.undefined;

+ 5 - 5
src/filter/slice-clause-tool.js

@@ -16,17 +16,17 @@ export class SliceClauseTool extends Service {
     if (!Array.isArray(entities))
       throw new InvalidArgumentError(
         'A first argument of SliceClauseTool.slice ' +
-          'should be an Array, but %s given.',
+          'should be an Array, but %v given.',
         entities,
       );
     if (skip && typeof skip !== 'number')
       throw new InvalidArgumentError(
-        'The provided option "skip" should be a Number, but %s given.',
+        'The provided option "skip" should be a Number, but %v given.',
         skip,
       );
     if (limit && typeof limit !== 'number')
       throw new InvalidArgumentError(
-        'The provided option "limit" should be a Number, but %s given.',
+        'The provided option "limit" should be a Number, but %v given.',
         limit,
       );
     skip = skip || 0;
@@ -43,7 +43,7 @@ export class SliceClauseTool extends Service {
     if (!skip) return;
     if (typeof skip !== 'number')
       throw new InvalidArgumentError(
-        'The provided option "skip" should be a Number, but %s given.',
+        'The provided option "skip" should be a Number, but %v given.',
         skip,
       );
   }
@@ -57,7 +57,7 @@ export class SliceClauseTool extends Service {
     if (!limit) return;
     if (typeof limit !== 'number')
       throw new InvalidArgumentError(
-        'The provided option "limit" should be a Number, but %s given.',
+        'The provided option "limit" should be a Number, but %v given.',
         limit,
       );
   }

+ 9 - 9
src/filter/slice-clause-tool.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {SliceClauseTool} from './slice-clause-tool.js';
 
 const S = new SliceClauseTool();
@@ -81,12 +81,12 @@ describe('SliceClauseTool', function () {
         SliceClauseTool.validateSkipClause(clause);
       const error = value =>
         format(
-          'The provided option "skip" should be a Number, but %s given.',
+          'The provided option "skip" should be a Number, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate('');
       validate(false);
       validate(undefined);
@@ -102,12 +102,12 @@ describe('SliceClauseTool', function () {
         SliceClauseTool.validateLimitClause(clause);
       const error = value =>
         format(
-          'The provided option "limit" should be a Number, but %s given.',
+          'The provided option "limit" should be a Number, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate('');
       validate(false);
       validate(undefined);

+ 4 - 4
src/filter/where-clause-tool.js

@@ -39,7 +39,7 @@ export class WhereClauseTool extends Service {
     if (!Array.isArray(entities))
       throw new InvalidArgumentError(
         'A first argument of WhereUtils.filter ' +
-          'should be an Array of Objects, but %s given.',
+          'should be an Array of Objects, but %v given.',
         entities,
       );
     return entities.filter(this._createFilter(where));
@@ -54,7 +54,7 @@ export class WhereClauseTool extends Service {
     if (typeof whereClause === 'function') return whereClause;
     if (typeof whereClause !== 'object')
       throw new InvalidArgumentError(
-        'The provided option "where" should be an Object, but %s given.',
+        'The provided option "where" should be an Object, but %v given.',
         whereClause,
       );
     const keys = Object.keys(whereClause);
@@ -62,7 +62,7 @@ export class WhereClauseTool extends Service {
       if (typeof data !== 'object')
         throw new InvalidArgumentError(
           'A first argument of WhereUtils.filter ' +
-            'should be an Array of Objects, but %s given.',
+            'should be an Array of Objects, but %v given.',
           data,
         );
       return keys.every(key => {
@@ -152,7 +152,7 @@ export class WhereClauseTool extends Service {
     if (!clause) return;
     if (typeof clause !== 'object' || Array.isArray(clause))
       throw new InvalidArgumentError(
-        'The provided option "where" should be an Object, but %s given.',
+        'The provided option "where" should be an Object, but %v given.',
         clause,
       );
   }

+ 6 - 6
src/filter/where-clause-tool.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {WhereClauseTool} from './where-clause-tool.js';
 
 const S = new WhereClauseTool();
@@ -264,13 +264,13 @@ describe('WhereClauseTool', function () {
         WhereClauseTool.validateWhereClause(clause);
       const error = value =>
         format(
-          'The provided option "where" should be an Object, but %s given.',
+          'The provided option "where" should be an Object, but %v given.',
           value,
         );
-      expect(validate('str')).to.throw(error('"str"'));
-      expect(validate(10)).to.throw(error('10'));
-      expect(validate(true)).to.throw(error('true'));
-      expect(validate([])).to.throw(error('Array'));
+      expect(validate('str')).to.throw(error('str'));
+      expect(validate(10)).to.throw(error(10));
+      expect(validate(true)).to.throw(error(true));
+      expect(validate([])).to.throw(error([]));
       validate('');
       validate(false);
       validate(undefined);

+ 14 - 14
src/relations/belongs-to-resolver.js

@@ -31,37 +31,37 @@ export class BelongsToResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of BelongsToResolver.includeTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of BelongsToResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of BelongsToResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of BelongsToResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (foreignKey && typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The provided parameter "foreignKey" of BelongsToResolver.includeTo ' +
-          'should be a String, but %s given.',
+          'should be a String, but %v given.',
         foreignKey,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of BelongsToResolver.includeTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
     if (foreignKey == null) foreignKey = `${relationName}Id`;
@@ -69,7 +69,7 @@ export class BelongsToResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of BelongsToResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const targetId = entity[foreignKey];
@@ -118,37 +118,37 @@ export class BelongsToResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of BelongsToResolver.includePolymorphicTo ' +
-          'requires an Array of Object, but %s given.',
+          'requires an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of BelongsToResolver.includePolymorphicTo ' +
-          'requires a non-empty String, but %s given.',
+          'requires a non-empty String, but %v given.',
         sourceName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of BelongsToResolver.includePolymorphicTo ' +
-          'requires a non-empty String, but %s given.',
+          'requires a non-empty String, but %v given.',
         relationName,
       );
     if (foreignKey && typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The provided parameter "foreignKey" of BelongsToResolver.includePolymorphicTo ' +
-          'should be a String, but %s given.',
+          'should be a String, but %v given.',
         foreignKey,
       );
     if (discriminator && typeof discriminator !== 'string')
       throw new InvalidArgumentError(
         'The provided parameter "discriminator" of BelongsToResolver.includePolymorphicTo ' +
-          'should be a String, but %s given.',
+          'should be a String, but %v given.',
         discriminator,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of BelongsToResolver.includePolymorphicTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
     if (foreignKey == null) {
@@ -164,7 +164,7 @@ export class BelongsToResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const targetId = entity[foreignKey];

+ 107 - 107
src/relations/belongs-to-resolver.spec.js

@@ -1,6 +1,6 @@
 import {expect} from 'chai';
-import {format} from 'util';
 import {Schema} from '../schema.js';
+import {format} from '@e22m4u/format';
 import {DataType} from '../definition/index.js';
 import {RelationType} from '../definition/index.js';
 import {BelongsToResolver} from './belongs-to-resolver.js';
@@ -14,19 +14,19 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of BelongsToResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo(v, 'sourceName', 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -35,19 +35,19 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of BelongsToResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([v], 'sourceName', 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -56,18 +56,18 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of BelongsToResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], v, 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -76,18 +76,18 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of BelongsToResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], 'sourceName', v, 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -96,18 +96,18 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of BelongsToResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], 'sourceName', 'targetName', v);
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "foreignKey" to be a string', async function () {
@@ -116,15 +116,15 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The provided parameter "foreignKey" of BelongsToResolver.includeTo ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', 'relationName', v);
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -133,7 +133,7 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of BelongsToResolver.includeTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -145,10 +145,10 @@ describe('BelongsToResolver', function () {
           undefined,
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {
@@ -528,19 +528,19 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includePolymorphicTo(v, 'sourceName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -549,19 +549,19 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includePolymorphicTo([v], 'sourceName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -570,19 +570,19 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of BelongsToResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includePolymorphicTo([], v, 'sourceName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -591,18 +591,18 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of BelongsToResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includePolymorphicTo([], 'sourceName', v);
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "foreignKey" to be a string', async function () {
@@ -611,15 +611,15 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The provided parameter "foreignKey" of BelongsToResolver.includePolymorphicTo ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includePolymorphicTo([], 'sourceName', 'relationName', v);
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
     });
 
     it('requires the provided parameter "discriminator" to be a string', async function () {
@@ -628,15 +628,15 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The provided parameter "discriminator" of BelongsToResolver.includePolymorphicTo ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includePolymorphicTo([], 'sourceName', 'relationName', undefined, v);
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -645,7 +645,7 @@ describe('BelongsToResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of BelongsToResolver.includePolymorphicTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -657,10 +657,10 @@ describe('BelongsToResolver', function () {
           undefined,
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('does not throw an error if a target model is not found', async function () {

+ 26 - 26
src/relations/has-many-resolver.js

@@ -31,37 +31,37 @@ export class HasManyResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasManyResolver.includeTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!foreignKey || typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The parameter "foreignKey" of HasManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         foreignKey,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasManyResolver.includeTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -72,7 +72,7 @@ export class HasManyResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of HasManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const sourceId = entity[sourcePkPropName];
@@ -132,43 +132,43 @@ export class HasManyResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasManyResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasManyResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasManyResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!foreignKey || typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The parameter "foreignKey" of HasManyResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         foreignKey,
       );
     if (!discriminator || typeof discriminator !== 'string')
       throw new InvalidArgumentError(
         'The parameter "discriminator" of HasManyResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         discriminator,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasManyResolver.includePolymorphicTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -179,7 +179,7 @@ export class HasManyResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const sourceId = entity[sourcePkPropName];
@@ -240,37 +240,37 @@ export class HasManyResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasManyResolver.includePolymorphicByRelationName requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!targetRelationName || typeof targetRelationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetRelationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetRelationName,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasManyResolver.includePolymorphicByRelationName ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -279,9 +279,9 @@ export class HasManyResolver extends Service {
     ).getRelationDefinitionByName(targetName, targetRelationName);
     if (targetRelationDef.type !== RelationType.BELONGS_TO)
       throw new InvalidArgumentError(
-        'The relation %s of the model %s is a polymorphic "hasMany" relation, ' +
-          'so it requires the target relation %s to be a polymorphic "belongsTo", ' +
-          'but %s type given.',
+        'The relation %v of the model %v is a polymorphic "hasMany" relation, ' +
+          'so it requires the target relation %v to be a polymorphic "belongsTo", ' +
+          'but %v type given.',
         relationName,
         sourceName,
         targetRelationName,
@@ -289,8 +289,8 @@ export class HasManyResolver extends Service {
       );
     if (!targetRelationDef.polymorphic)
       throw new InvalidArgumentError(
-        'The relation %s of the model %s is a polymorphic "hasMany" relation, ' +
-          'so it requires the target relation %s to be a polymorphic too.',
+        'The relation %v of the model %v is a polymorphic "hasMany" relation, ' +
+          'so it requires the target relation %v to be a polymorphic too.',
         relationName,
         sourceName,
         targetRelationName,

+ 187 - 187
src/relations/has-many-resolver.spec.js

@@ -1,6 +1,6 @@
-import {format} from 'util';
 import {expect} from 'chai';
 import {Schema} from '../schema.js';
+import {format} from '@e22m4u/format';
 import {DataType} from '../definition/index.js';
 import {RelationType} from '../definition/index.js';
 import {HasManyResolver} from './has-many-resolver.js';
@@ -14,7 +14,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -25,14 +25,14 @@ describe('HasManyResolver', function () {
           'relationName',
           'foreignKey',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -42,19 +42,19 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([v], 'source', 'target', 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -63,19 +63,19 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], v, 'targetName', 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -84,19 +84,19 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', v, 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -105,19 +105,19 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', v, 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "foreignKey" parameter to be a non-empty string', async function () {
@@ -126,19 +126,19 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "foreignKey" of HasManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', 'relationName', v);
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -147,7 +147,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasManyResolver.includeTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -159,10 +159,10 @@ describe('HasManyResolver', function () {
           'foreignKey',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if a target model is not found', async function () {
@@ -726,7 +726,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -738,14 +738,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -755,7 +755,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -767,14 +767,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -783,7 +783,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasManyResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -795,14 +795,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -811,7 +811,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasManyResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -823,14 +823,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -839,7 +839,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasManyResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -851,14 +851,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "foreignKey" parameter to be a non-empty string', async function () {
@@ -867,7 +867,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "foreignKey" of HasManyResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -879,14 +879,14 @@ describe('HasManyResolver', function () {
           v,
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "discriminator" parameter to be a non-empty string', async function () {
@@ -895,7 +895,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "discriminator" of HasManyResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -907,14 +907,14 @@ describe('HasManyResolver', function () {
           'foreignKey',
           v,
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -923,7 +923,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasManyResolver.includePolymorphicTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -936,10 +936,10 @@ describe('HasManyResolver', function () {
           'discriminator',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {
@@ -1685,7 +1685,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includePolymorphicByRelationName requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1696,14 +1696,14 @@ describe('HasManyResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -1722,7 +1722,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasManyResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1733,14 +1733,14 @@ describe('HasManyResolver', function () {
           'children',
           'parent',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -1749,7 +1749,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1760,14 +1760,14 @@ describe('HasManyResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -1776,7 +1776,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1787,14 +1787,14 @@ describe('HasManyResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -1803,7 +1803,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1814,14 +1814,14 @@ describe('HasManyResolver', function () {
           v,
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetRelationName" parameter to be a non-empty string', async function () {
@@ -1830,7 +1830,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The parameter "targetRelationName" of HasManyResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1841,14 +1841,14 @@ describe('HasManyResolver', function () {
           'relationName',
           v,
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -1857,7 +1857,7 @@ describe('HasManyResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasManyResolver.includePolymorphicByRelationName ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1869,10 +1869,10 @@ describe('HasManyResolver', function () {
           'targetRelationName',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {

+ 26 - 26
src/relations/has-one-resolver.js

@@ -31,37 +31,37 @@ export class HasOneResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasOneResolver.includeTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasOneResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasOneResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasOneResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!foreignKey || typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The parameter "foreignKey" of HasOneResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         foreignKey,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasOneResolver.includeTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -72,7 +72,7 @@ export class HasOneResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of HasOneResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const sourceId = entity[sourcePkPropName];
@@ -129,43 +129,43 @@ export class HasOneResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasOneResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasOneResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasOneResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!foreignKey || typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The parameter "foreignKey" of HasOneResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         foreignKey,
       );
     if (!discriminator || typeof discriminator !== 'string')
       throw new InvalidArgumentError(
         'The parameter "discriminator" of HasOneResolver.includePolymorphicTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         discriminator,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasOneResolver.includePolymorphicTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -176,7 +176,7 @@ export class HasOneResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const sourceId = entity[sourcePkPropName];
@@ -234,37 +234,37 @@ export class HasOneResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of HasOneResolver.includePolymorphicByRelationName requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (!targetRelationName || typeof targetRelationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetRelationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetRelationName,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of HasOneResolver.includePolymorphicByRelationName ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
 
@@ -273,9 +273,9 @@ export class HasOneResolver extends Service {
     ).getRelationDefinitionByName(targetName, targetRelationName);
     if (targetRelationDef.type !== RelationType.BELONGS_TO)
       throw new InvalidArgumentError(
-        'The relation %s of the model %s is a polymorphic "hasOne" relation, ' +
-          'so it requires the target relation %s to be a polymorphic "belongsTo", ' +
-          'but %s type given.',
+        'The relation %v of the model %v is a polymorphic "hasOne" relation, ' +
+          'so it requires the target relation %v to be a polymorphic "belongsTo", ' +
+          'but %v type given.',
         relationName,
         sourceName,
         targetRelationName,
@@ -283,8 +283,8 @@ export class HasOneResolver extends Service {
       );
     if (!targetRelationDef.polymorphic)
       throw new InvalidArgumentError(
-        'The relation %s of the model %s is a polymorphic "hasOne" relation, ' +
-          'so it requires the target relation %s to be a polymorphic too.',
+        'The relation %v of the model %v is a polymorphic "hasOne" relation, ' +
+          'so it requires the target relation %v to be a polymorphic too.',
         relationName,
         sourceName,
         targetRelationName,

+ 187 - 187
src/relations/has-one-resolver.spec.js

@@ -1,6 +1,6 @@
-import {format} from 'util';
 import {expect} from 'chai';
 import {Schema} from '../schema.js';
+import {format} from '@e22m4u/format';
 import {DataType} from '../definition/index.js';
 import {RelationType} from '../definition/index.js';
 import {HasOneResolver} from './has-one-resolver.js';
@@ -14,7 +14,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -25,14 +25,14 @@ describe('HasOneResolver', function () {
           'relationName',
           'foreignKey',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -42,19 +42,19 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([v], 'source', 'target', 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -63,19 +63,19 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasOneResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], v, 'targetName', 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -84,19 +84,19 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasOneResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', v, 'relationName', 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -105,19 +105,19 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasOneResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', v, 'foreignKey');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "foreignKey" parameter to be a non-empty string', async function () {
@@ -126,19 +126,19 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "foreignKey" of HasOneResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', 'relationName', v);
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -147,7 +147,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasOneResolver.includeTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -159,10 +159,10 @@ describe('HasOneResolver', function () {
           'foreignKey',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if a target model is not found', async function () {
@@ -557,7 +557,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -569,14 +569,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -586,7 +586,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -598,14 +598,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -614,7 +614,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasOneResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -626,14 +626,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -642,7 +642,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasOneResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -654,14 +654,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -670,7 +670,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasOneResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -682,14 +682,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "foreignKey" parameter to be a non-empty string', async function () {
@@ -698,7 +698,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "foreignKey" of HasOneResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -710,14 +710,14 @@ describe('HasOneResolver', function () {
           v,
           'discriminator',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "discriminator" parameter to be a non-empty string', async function () {
@@ -726,7 +726,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "discriminator" of HasOneResolver.includePolymorphicTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -738,14 +738,14 @@ describe('HasOneResolver', function () {
           'foreignKey',
           v,
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -754,7 +754,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasOneResolver.includePolymorphicTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -767,10 +767,10 @@ describe('HasOneResolver', function () {
           'discriminator',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {
@@ -1307,7 +1307,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includePolymorphicByRelationName requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1318,14 +1318,14 @@ describe('HasOneResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -1344,7 +1344,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of HasOneResolver.includePolymorphicTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1355,14 +1355,14 @@ describe('HasOneResolver', function () {
           'child',
           'parent',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -1371,7 +1371,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1382,14 +1382,14 @@ describe('HasOneResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -1398,7 +1398,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1409,14 +1409,14 @@ describe('HasOneResolver', function () {
           'relationName',
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -1425,7 +1425,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1436,14 +1436,14 @@ describe('HasOneResolver', function () {
           v,
           'targetRelationName',
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetRelationName" parameter to be a non-empty string', async function () {
@@ -1452,7 +1452,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The parameter "targetRelationName" of HasOneResolver.includePolymorphicByRelationName requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1463,14 +1463,14 @@ describe('HasOneResolver', function () {
           'relationName',
           v,
         );
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -1479,7 +1479,7 @@ describe('HasOneResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of HasOneResolver.includePolymorphicByRelationName ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -1491,10 +1491,10 @@ describe('HasOneResolver', function () {
           'targetRelationName',
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {

+ 7 - 7
src/relations/references-many-resolver.js

@@ -31,37 +31,37 @@ export class ReferencesManyResolver extends Service {
     if (!entities || !Array.isArray(entities))
       throw new InvalidArgumentError(
         'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
-          'an Array of Object, but %s given.',
+          'an Array of Object, but %v given.',
         entities,
       );
     if (!sourceName || typeof sourceName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "sourceName" of ReferencesManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         sourceName,
       );
     if (!targetName || typeof targetName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "targetName" of ReferencesManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         targetName,
       );
     if (!relationName || typeof relationName !== 'string')
       throw new InvalidArgumentError(
         'The parameter "relationName" of ReferencesManyResolver.includeTo requires ' +
-          'a non-empty String, but %s given.',
+          'a non-empty String, but %v given.',
         relationName,
       );
     if (foreignKey && typeof foreignKey !== 'string')
       throw new InvalidArgumentError(
         'The provided parameter "foreignKey" of ReferencesManyResolver.includeTo ' +
-          'should be a String, but %s given.',
+          'should be a String, but %v given.',
         foreignKey,
       );
     if (scope && (typeof scope !== 'object' || Array.isArray(scope)))
       throw new InvalidArgumentError(
         'The provided parameter "scope" of ReferencesManyResolver.includeTo ' +
-          'should be an Object, but %s given.',
+          'should be an Object, but %v given.',
         scope,
       );
     if (foreignKey == null) {
@@ -72,7 +72,7 @@ export class ReferencesManyResolver extends Service {
       if (!entity || typeof entity !== 'object' || Array.isArray(entity))
         throw new InvalidArgumentError(
           'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           entity,
         );
       const ids = entity[foreignKey];

+ 56 - 56
src/relations/references-many-resolver.spec.js

@@ -1,6 +1,6 @@
-import {format} from 'util';
 import {expect} from 'chai';
 import {Schema} from '../schema.js';
+import {format} from '@e22m4u/format';
 import {DataType} from '../definition/index.js';
 import {RelationType} from '../definition/index.js';
 import {ReferencesManyResolver} from './references-many-resolver.js';
@@ -14,19 +14,19 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo(v, 'sourceName', 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires elements of the "entities" parameter to be an Object', async function () {
@@ -35,19 +35,19 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The parameter "entities" of ReferencesManyResolver.includeTo requires ' +
-            'an Array of Object, but %s given.',
+            'an Array of Object, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([v], 'sourceName', 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "sourceName" parameter to be a non-empty string', async function () {
@@ -56,18 +56,18 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The parameter "sourceName" of ReferencesManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], v, 'targetName', 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "targetName" parameter to be a non-empty string', async function () {
@@ -76,18 +76,18 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The parameter "targetName" of ReferencesManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], 'sourceName', v, 'relationName');
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the "relationName" parameter to be a non-empty string', async function () {
@@ -96,18 +96,18 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The parameter "relationName" of ReferencesManyResolver.includeTo requires ' +
-            'a non-empty String, but %s given.',
+            'a non-empty String, but %v given.',
           v,
         );
       const throwable = v => R.includeTo([], 'sourceName', 'targetName', v);
-      await expect(throwable('')).to.be.rejectedWith(error('""'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable(false)).to.be.rejectedWith(error('false'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
-      await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
-      await expect(throwable(null)).to.be.rejectedWith(error('null'));
+      await expect(throwable('')).to.be.rejectedWith(error(''));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable(false)).to.be.rejectedWith(error(false));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
+      await expect(throwable(undefined)).to.be.rejectedWith(error(undefined));
+      await expect(throwable(null)).to.be.rejectedWith(error(null));
     });
 
     it('requires the provided parameter "foreignKey" to be a string', async function () {
@@ -116,15 +116,15 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The provided parameter "foreignKey" of ReferencesManyResolver.includeTo ' +
-            'should be a String, but %s given.',
+            'should be a String, but %v given.',
           v,
         );
       const throwable = v =>
         R.includeTo([], 'sourceName', 'targetName', 'relationName', v);
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
-      await expect(throwable({})).to.be.rejectedWith(error('Object'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
+      await expect(throwable({})).to.be.rejectedWith(error({}));
     });
 
     it('requires the provided parameter "scope" to be an object', async function () {
@@ -133,7 +133,7 @@ describe('ReferencesManyResolver', function () {
       const error = v =>
         format(
           'The provided parameter "scope" of ReferencesManyResolver.includeTo ' +
-            'should be an Object, but %s given.',
+            'should be an Object, but %v given.',
           v,
         );
       const throwable = v =>
@@ -145,10 +145,10 @@ describe('ReferencesManyResolver', function () {
           undefined,
           v,
         );
-      await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
-      await expect(throwable(10)).to.be.rejectedWith(error('10'));
-      await expect(throwable(true)).to.be.rejectedWith(error('true'));
-      await expect(throwable([])).to.be.rejectedWith(error('Array'));
+      await expect(throwable('str')).to.be.rejectedWith(error('str'));
+      await expect(throwable(10)).to.be.rejectedWith(error(10));
+      await expect(throwable(true)).to.be.rejectedWith(error(true));
+      await expect(throwable([])).to.be.rejectedWith(error([]));
     });
 
     it('throws an error if the given target model is not found', async function () {

+ 1 - 1
src/repository/repository-registry.js

@@ -32,7 +32,7 @@ export class RepositoryRegistry extends Service {
     ) {
       throw new InvalidArgumentError(
         'The first argument of RepositoryRegistry.setRepositoryCtor ' +
-          'must inherit from Repository class, but %s given.',
+          'must inherit from Repository class, but %v given.',
         ctor,
       );
     }

+ 1 - 1
src/repository/repository.js

@@ -49,7 +49,7 @@ export class Repository extends Service {
     const datasourceName = modelDef.datasource;
     if (!datasourceName)
       throw new InvalidArgumentError(
-        'The model %s does not have a specified datasource.',
+        'The model %v does not have a specified datasource.',
         modelName,
       );
     this._datasourceName = datasourceName;

+ 0 - 15
src/utils/array-to-string.js

@@ -1,15 +0,0 @@
-import {valueToString} from './value-to-string.js';
-
-/**
- * Array to string.
- *
- * @param array
- * @param joiner
- * @param orEmpty
- * @return {string|*|string}
- */
-export function arrayToString(array, joiner = ', ', orEmpty = 'Array') {
-  if (Array.isArray(array))
-    return array.length ? array.map(valueToString).join(joiner) : orEmpty;
-  return valueToString(array);
-}

+ 0 - 33
src/utils/array-to-string.spec.js

@@ -1,33 +0,0 @@
-import {expect} from 'chai';
-import {arrayToString} from './array-to-string.js';
-
-describe('arrayToString', function () {
-  it('returns a string representation of a given array', function () {
-    const arr = ['str', 10, true, () => undefined];
-    const str = '"str", 10, true, Function';
-    expect(arrayToString(arr)).to.be.eq(str);
-    expect(arrayToString([])).to.be.eq('Array');
-  });
-
-  it('returns a string representation of a non-array items', function () {
-    expect(arrayToString('str')).to.be.eq('"str"');
-    expect(arrayToString(10)).to.be.eq('10');
-    expect(arrayToString(true)).to.be.eq('true');
-    expect(arrayToString(false)).to.be.eq('false');
-    expect(arrayToString({})).to.be.eq('Object');
-    expect(arrayToString(null)).to.be.eq('null');
-    expect(arrayToString(undefined)).to.be.eq('undefined');
-    expect(arrayToString(() => undefined)).to.be.eq('Function');
-    expect(arrayToString(function () {})).to.be.eq('Function');
-  });
-
-  it('allows to change the "joiner" argument', function () {
-    expect(arrayToString([1, 2, 3])).to.be.eq('1, 2, 3');
-    expect(arrayToString([1, 2, 3], '-')).to.be.eq('1-2-3');
-  });
-
-  it('allows to change the "orEmpty" argument', function () {
-    expect(arrayToString([])).to.be.eq('Array');
-    expect(arrayToString([], undefined, '-')).to.be.eq('-');
-  });
-});

+ 1 - 1
src/utils/exclude-object-keys.js

@@ -9,7 +9,7 @@ import {InvalidArgumentError} from '../errors/index.js';
 export function excludeObjectKeys(obj, keys) {
   if (typeof obj !== 'object' || !obj || Array.isArray(obj))
     throw new InvalidArgumentError(
-      'Cannot exclude keys from a non-Object value, %s given.',
+      'Cannot exclude keys from a non-Object value, %v given.',
       obj,
     );
   const result = {...obj};

+ 11 - 10
src/utils/exclude-object-keys.spec.js

@@ -1,5 +1,5 @@
 import {expect} from 'chai';
-import {format} from 'util';
+import {format} from '@e22m4u/format';
 import {excludeObjectKeys} from './exclude-object-keys.js';
 
 describe('excludeObjectKeys', function () {
@@ -35,14 +35,15 @@ describe('excludeObjectKeys', function () {
   });
 
   it('throws an error for a non-object values', function () {
-    const message = 'Cannot exclude keys from a non-Object value, %s given.';
-    const from = v => () => excludeObjectKeys(v, 'key');
-    expect(from('string')).to.throw(format(message, '"string"'));
-    expect(from(10)).to.throw(format(message, '10'));
-    expect(from(true)).to.throw(format(message, 'true'));
-    expect(from(false)).to.throw(format(message, 'false'));
-    expect(from([])).to.throw(format(message, 'Array'));
-    expect(from(null)).to.throw(format(message, 'null'));
-    expect(from(undefined)).to.throw(format(message, 'undefined'));
+    const throwable = v => () => excludeObjectKeys(v, 'key');
+    const error = v =>
+      format('Cannot exclude keys from a non-Object value, %v given.', v);
+    expect(throwable('string')).to.throw(error('string'));
+    expect(throwable(10)).to.throw(error(10));
+    expect(throwable(true)).to.throw(error(true));
+    expect(throwable(false)).to.throw(error(false));
+    expect(throwable([])).to.throw(error([]));
+    expect(throwable(null)).to.throw(error(null));
+    expect(throwable(undefined)).to.throw(error(undefined));
   });
 });

+ 0 - 2
src/utils/index.js

@@ -4,8 +4,6 @@ export * from './clone-deep.js';
 export * from './singularize.js';
 export * from './get-ctor-name.js';
 export * from './is-pure-object.js';
-export * from './value-to-string.js';
-export * from './array-to-string.js';
 export * from './string-to-regexp.js';
 export * from './get-value-by-path.js';
 export * from './select-object-keys.js';

+ 3 - 3
src/utils/select-object-keys.js

@@ -11,20 +11,20 @@ export function selectObjectKeys(obj, keys) {
   if (!obj || typeof obj !== 'object')
     throw new InvalidArgumentError(
       'A first argument of selectObjectKeys ' +
-        'should be an Object, but %s given.',
+        'should be an Object, but %v given.',
       obj,
     );
   if (!Array.isArray(keys))
     throw new InvalidArgumentError(
       'A second argument of selectObjectKeys ' +
-        'should be an Array of String, but %s given.',
+        'should be an Array of String, but %v given.',
       keys,
     );
   keys.forEach(key => {
     if (typeof key !== 'string')
       throw new InvalidArgumentError(
         'A second argument of selectObjectKeys ' +
-          'should be an Array of String, but %s given.',
+          'should be an Array of String, but %v given.',
         key,
       );
   });

+ 0 - 20
src/utils/value-to-string.js

@@ -1,20 +0,0 @@
-/**
- * Value to string.
- *
- * @param value
- * @return {string}
- */
-export function valueToString(value) {
-  if (typeof value === 'string') return `"${value}"`;
-  if (value instanceof String) return String(value);
-  if (
-    value &&
-    typeof value === 'object' &&
-    value.constructor &&
-    value.constructor.name
-  ) {
-    return value.constructor.name;
-  }
-  if (value instanceof Function) return 'Function';
-  return String(value);
-}

+ 0 - 23
src/utils/value-to-string.spec.js

@@ -1,23 +0,0 @@
-import {expect} from 'chai';
-import {valueToString} from './value-to-string.js';
-
-describe('valueToString', function () {
-  it('wraps a string to double quotes', function () {
-    expect(valueToString('str')).to.be.eql('"str"');
-  });
-
-  it('returns a string representation of a given value', function () {
-    expect(valueToString(10)).to.be.eql('10');
-    expect(valueToString(true)).to.be.eql('true');
-    expect(valueToString(false)).to.be.eql('false');
-    expect(valueToString(undefined)).to.be.eql('undefined');
-    expect(valueToString(null)).to.be.eql('null');
-    expect(valueToString(NaN)).to.be.eql('NaN');
-    expect(valueToString({})).to.be.eql('Object');
-    expect(valueToString([])).to.be.eql('Array');
-    expect(valueToString(new Date())).to.be.eql('Date');
-    expect(valueToString(new String('str'))).to.be.eql('str');
-    expect(valueToString(() => undefined)).to.be.eql('Function');
-    expect(valueToString(function () {})).to.be.eql('Function');
-  });
-});