e22m4u 2 лет назад
Родитель
Сommit
85139bcc41
100 измененных файлов с 1943 добавлено и 302 удалено
  1. 8 1
      .eslintrc.cjs
  2. 4 3
      package.json
  3. 16 0
      src/adapter/adapter-loader.d.ts
  4. 4 4
      src/adapter/adapter-loader.js
  5. 14 0
      src/adapter/adapter-registry.d.ts
  6. 4 3
      src/adapter/adapter-registry.js
  7. 6 24
      src/adapter/adapter.d.ts
  8. 14 11
      src/adapter/adapter.js
  9. 122 0
      src/adapter/builtin/memory-adapter.d.ts
  10. 13 13
      src/adapter/builtin/memory-adapter.js
  11. 13 0
      src/adapter/decorator/data-sanitizing-decorator.d.ts
  12. 1 1
      src/adapter/decorator/data-sanitizing-decorator.js
  13. 13 0
      src/adapter/decorator/data-validation-decorator.d.ts
  14. 13 0
      src/adapter/decorator/default-values-decorator.d.ts
  15. 13 0
      src/adapter/decorator/fields-filtering-decorator.d.ts
  16. 1 1
      src/adapter/decorator/fields-filtering-decorator.js
  17. 13 0
      src/adapter/decorator/inclusion-decorator.d.ts
  18. 5 0
      src/adapter/decorator/index.d.ts
  19. 2 0
      src/adapter/index.d.ts
  20. 14 0
      src/definition/datasource/datasource-definition-validator.d.ts
  21. 0 1
      src/definition/datasource/datasource-definition-validator.js
  22. 1 1
      src/definition/datasource/datasource-definition.d.ts
  23. 1 0
      src/definition/datasource/index.d.ts
  24. 50 0
      src/definition/definition-registry.d.ts
  25. 12 12
      src/definition/definition-registry.js
  26. 1 0
      src/definition/index.d.ts
  27. 4 0
      src/definition/model/index.d.ts
  28. 15 0
      src/definition/model/model-data-sanitizer.d.ts
  29. 1 1
      src/definition/model/model-data-sanitizer.js
  30. 32 0
      src/definition/model/model-data-validator.d.ts
  31. 3 4
      src/definition/model/model-data-validator.js
  32. 161 0
      src/definition/model/model-definition-utils.d.ts
  33. 32 23
      src/definition/model/model-definition-utils.js
  34. 14 0
      src/definition/model/model-definition-validator.d.ts
  35. 1 1
      src/definition/model/model-definition-validator.js
  36. 7 7
      src/definition/model/model-definition.d.ts
  37. 15 0
      src/definition/model/properties/default-values-definition-validator.d.ts
  38. 3 3
      src/definition/model/properties/default-values-definition-validator.js
  39. 3 0
      src/definition/model/properties/index.d.ts
  40. 15 0
      src/definition/model/properties/primary-keys-definition-validator.d.ts
  41. 2 2
      src/definition/model/properties/primary-keys-definition-validator.js
  42. 15 0
      src/definition/model/properties/properties-definition-validator.d.ts
  43. 5 5
      src/definition/model/properties/properties-definition-validator.js
  44. 9 11
      src/definition/model/properties/property-definition.d.ts
  45. 1 0
      src/definition/model/relations/index.d.ts
  46. 6 6
      src/definition/model/relations/relation-definition.d.ts
  47. 15 0
      src/definition/model/relations/relations-definition-validator.d.ts
  48. 7 7
      src/definition/model/relations/relations-definition-validator.js
  49. 3 0
      src/errors/index.d.ts
  50. 6 0
      src/errors/invalid-argument-error.d.ts
  51. 13 0
      src/errors/invalid-operator-value-error.d.ts
  52. 3 3
      src/errors/invalid-operator-value-error.js
  53. 6 0
      src/errors/not-implemented-error.d.ts
  54. 38 0
      src/filter/fields-clause-tool.d.ts
  55. 6 4
      src/filter/fields-clause-tool.js
  56. 6 6
      src/filter/fields-clause-tool.spec.js
  57. 317 7
      src/filter/filter.d.ts
  58. 53 0
      src/filter/include-clause-tool.d.ts
  59. 10 7
      src/filter/include-clause-tool.js
  60. 6 0
      src/filter/index.d.ts
  61. 223 0
      src/filter/operator-clause-tool.d.ts
  62. 39 27
      src/filter/operator-clause-tool.js
  63. 32 0
      src/filter/order-clause-tool.d.ts
  64. 11 8
      src/filter/order-clause-tool.js
  65. 6 6
      src/filter/order-clause-tool.spec.js
  66. 30 0
      src/filter/slice-clause-tool.d.ts
  67. 7 6
      src/filter/slice-clause-tool.js
  68. 12 12
      src/filter/slice-clause-tool.spec.js
  69. 23 0
      src/filter/where-clause-tool.d.ts
  70. 13 7
      src/filter/where-clause-tool.js
  71. 7 7
      src/filter/where-clause-tool.spec.js
  72. 3 0
      src/index.d.ts
  73. 46 0
      src/relations/belongs-to-resolver.d.ts
  74. 2 2
      src/relations/belongs-to-resolver.js
  75. 67 0
      src/relations/has-many-resolver.d.ts
  76. 3 3
      src/relations/has-many-resolver.js
  77. 67 0
      src/relations/has-one-resolver.d.ts
  78. 3 3
      src/relations/has-one-resolver.js
  79. 4 0
      src/relations/index.d.ts
  80. 27 0
      src/relations/references-many-resolver.d.ts
  81. 1 1
      src/relations/references-many-resolver.js
  82. 1 0
      src/repository/index.d.ts
  83. 22 0
      src/repository/repository-registry.d.ts
  84. 5 2
      src/repository/repository-registry.js
  85. 5 19
      src/repository/repository.d.ts
  86. 15 14
      src/repository/repository.js
  87. 5 1
      src/schema.js
  88. 4 4
      src/types.d.ts
  89. 6 0
      src/utils/capitalize.d.ts
  90. 1 1
      src/utils/capitalize.js
  91. 6 0
      src/utils/clone-deep.d.ts
  92. 2 1
      src/utils/clone-deep.js
  93. 10 0
      src/utils/exclude-object-keys.d.ts
  94. 3 2
      src/utils/exclude-object-keys.js
  95. 6 0
      src/utils/get-ctor-name.d.ts
  96. 2 1
      src/utils/get-ctor-name.js
  97. 12 0
      src/utils/get-value-by-path.d.ts
  98. 4 3
      src/utils/get-value-by-path.js
  99. 10 0
      src/utils/index.d.ts
  100. 7 0
      src/utils/is-ctor.d.ts

+ 8 - 1
.eslintrc.cjs

@@ -9,12 +9,19 @@ module.exports = {
   },
   plugins: [
     'mocha',
+    'jsdoc',
     'chai-expect',
   ],
   extends: [
-    'eslint:recommended',
     'prettier',
+    'plugin:jsdoc/recommended',
     'plugin:mocha/recommended',
     'plugin:chai-expect/recommended',
+    'plugin:jsdoc/recommended-error',
   ],
+  rules: {
+    'jsdoc/require-param-description': 0,
+    'jsdoc/require-returns-description': 0,
+    'jsdoc/tag-lines': ['error', 'any', {startLines: 1}],
+  },
 }

+ 4 - 3
package.json

@@ -10,7 +10,7 @@
   "scripts": {
     "lint": "eslint .",
     "lint:fix": "eslint . --fix",
-    "format": "prettier --write \"./src/**/*.js\"",
+    "format": "prettier --write \"./src/**/*.{js,ts}\"",
     "test": "eslint . && c8 --reporter=text-summary mocha",
     "test:coverage": "eslint . && c8 --reporter=text mocha",
     "prepare": "npx husky install"
@@ -33,8 +33,8 @@
   "license": "MIT",
   "homepage": "https://github.com/e22m4u/node-repository",
   "dependencies": {
-    "@e22m4u/util-format": "0.0.6",
-    "@e22m4u/service": "0.0.5"
+    "@e22m4u/service": "0.0.6",
+    "@e22m4u/util-format": "0.0.6"
   },
   "devDependencies": {
     "@commitlint/cli": "^17.7.1",
@@ -47,6 +47,7 @@
     "eslint": "^8.47.0",
     "eslint-config-prettier": "^9.0.0",
     "eslint-plugin-chai-expect": "^3.0.0",
+    "eslint-plugin-jsdoc": "^46.8.2",
     "eslint-plugin-mocha": "^10.1.0",
     "husky": "^8.0.3",
     "mocha": "^10.2.0",

+ 16 - 0
src/adapter/adapter-loader.d.ts

@@ -0,0 +1,16 @@
+import {Adapter} from './adapter';
+import {AnyObject} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Adapter loader.
+ */
+export declare class AdapterLoader extends Service {
+  /**
+   * Load by name.
+   *
+   * @param adapterName
+   * @param settings
+   */
+  loadByName(adapterName: string, settings?: AnyObject): Promise<Adapter>;
+}

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

@@ -10,8 +10,8 @@ export class AdapterLoader extends Service {
    * Load by name.
    *
    * @param {string} adapterName
-   * @param {object} settings
-   * @return {Promise<any>}
+   * @param {object|undefined} settings
+   * @returns {Promise<Adapter>}
    */
   async loadByName(adapterName, settings = undefined) {
     if (!adapterName || typeof adapterName !== 'string')
@@ -47,8 +47,8 @@ export class AdapterLoader extends Service {
 /**
  * Find adapter ctor in module.
  *
- * @param module
- * @return {*}
+ * @param {object} module
+ * @returns {*}
  */
 function findAdapterCtorInModule(module) {
   let adapterCtor;

+ 14 - 0
src/adapter/adapter-registry.d.ts

@@ -0,0 +1,14 @@
+import {Adapter} from './adapter';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Adapter registry.
+ */
+export declare class AdapterRegistry extends Service {
+  /**
+   * Get adapter.
+   *
+   * @param datasourceName
+   */
+  getAdapter(datasourceName: string): Promise<Adapter>;
+}

+ 4 - 3
src/adapter/adapter-registry.js

@@ -1,3 +1,4 @@
+import {Adapter} from './adapter.js';
 import {Service} from '@e22m4u/service';
 import {AdapterLoader} from './adapter-loader.js';
 import {DefinitionRegistry} from '../definition/index.js';
@@ -9,15 +10,15 @@ export class AdapterRegistry extends Service {
   /**
    * Adapters.
    *
-   * @type {{[name: string]: object}}
+   * @type {object}
    */
   _adapters = {};
 
   /**
    * Get adapter.
    *
-   * @param datasourceName
-   * @return {Promise<object>}
+   * @param {string} datasourceName
+   * @returns {Promise<Adapter>}
    */
   async getAdapter(datasourceName) {
     let adapter = this._adapters[datasourceName];

+ 6 - 24
src/adapter/adapter.d.ts

@@ -22,10 +22,7 @@ export declare class Adapter extends Service {
    * @param container
    * @param settings
    */
-  constructor(
-    container?: ServiceContainer,
-    settings?: AnyObject,
-  );
+  constructor(container?: ServiceContainer, settings?: AnyObject);
 
   /**
    * Create.
@@ -76,10 +73,7 @@ export declare class Adapter extends Service {
    * @param modelName
    * @param filter
    */
-  find(
-    modelName: string,
-    filter?: Filter,
-  ): Promise<ModelData[]>;
+  find(modelName: string, filter?: Filter): Promise<ModelData[]>;
 
   /**
    * Find by id.
@@ -100,10 +94,7 @@ export declare class Adapter extends Service {
    * @param modelName
    * @param where
    */
-  delete(
-    modelName: string,
-    where?: WhereClause,
-  ): Promise<number>;
+  delete(modelName: string, where?: WhereClause): Promise<number>;
 
   /**
    * Delete by id.
@@ -111,10 +102,7 @@ export declare class Adapter extends Service {
    * @param modelName
    * @param id
    */
-  deleteById(
-    modelName: string,
-    id: Identifier,
-  ): Promise<boolean>;
+  deleteById(modelName: string, id: Identifier): Promise<boolean>;
 
   /**
    * Exists.
@@ -122,10 +110,7 @@ export declare class Adapter extends Service {
    * @param modelName
    * @param id
    */
-  exists(
-    modelName: string,
-    id: Identifier,
-  ): Promise<boolean>;
+  exists(modelName: string, id: Identifier): Promise<boolean>;
 
   /**
    * Count.
@@ -133,8 +118,5 @@ export declare class Adapter extends Service {
    * @param modelName
    * @param where
    */
-  count(
-    modelName: string,
-    where?: WhereClause,
-  ): Promise<number>;
+  count(modelName: string, where?: WhereClause): Promise<number>;
 }

+ 14 - 11
src/adapter/adapter.js

@@ -1,4 +1,5 @@
 /* eslint no-unused-vars: 0 */
+/* eslint jsdoc/require-returns-check: 0 */
 import {Service} from '@e22m4u/service';
 import {NotImplementedError} from '../errors/index.js';
 import {InclusionDecorator} from './decorator/index.js';
@@ -13,13 +14,15 @@ import {FieldsFilteringDecorator} from './decorator/index.js';
 export class Adapter extends Service {
   /**
    * Settings.
+   *
+   * @type {object|undefined}
    */
   _settings;
 
   /**
    * Settings.
    *
-   * @return {object|undefined}
+   * @returns {object|undefined}
    */
   get settings() {
     return this._settings;
@@ -50,7 +53,7 @@ export class Adapter extends Service {
    * @param {string} modelName
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   create(modelName, modelData, filter = undefined) {
     throw new NotImplementedError(
@@ -66,7 +69,7 @@ export class Adapter extends Service {
    * @param {number|string} id
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   replaceById(modelName, id, modelData, filter = undefined) {
     throw new NotImplementedError(
@@ -82,7 +85,7 @@ export class Adapter extends Service {
    * @param {number|string} id
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   patchById(modelName, id, modelData, filter = undefined) {
     throw new NotImplementedError(
@@ -96,7 +99,7 @@ export class Adapter extends Service {
    *
    * @param {string} modelName
    * @param {object|undefined} filter
-   * @return {Promise<object[]>}
+   * @returns {Promise<object[]>}
    */
   find(modelName, filter = undefined) {
     throw new NotImplementedError(
@@ -111,7 +114,7 @@ export class Adapter extends Service {
    * @param {string} modelName
    * @param {number|string} id
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   findById(modelName, id, filter = undefined) {
     throw new NotImplementedError(
@@ -125,7 +128,7 @@ export class Adapter extends Service {
    *
    * @param {string} modelName
    * @param {object|undefined} where
-   * @return {Promise<number>}
+   * @returns {Promise<number>}
    */
   delete(modelName, where = undefined) {
     throw new NotImplementedError(
@@ -139,7 +142,7 @@ export class Adapter extends Service {
    *
    * @param {string} modelName
    * @param {number|string} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   deleteById(modelName, id) {
     throw new NotImplementedError(
@@ -153,7 +156,7 @@ export class Adapter extends Service {
    *
    * @param {string} modelName
    * @param {number|string} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   exists(modelName, id) {
     throw new NotImplementedError(
@@ -166,8 +169,8 @@ export class Adapter extends Service {
    * Count.
    *
    * @param {string} modelName
-   * @param {WhereClause|undefined} where
-   * @return {Promise<number>}
+   * @param {object|undefined} where
+   * @returns {Promise<number>}
    */
   count(modelName, where = undefined) {
     throw new NotImplementedError(

+ 122 - 0
src/adapter/builtin/memory-adapter.d.ts

@@ -0,0 +1,122 @@
+import {Adapter} from '../adapter';
+import {Filter} from '../../filter';
+import {AnyObject} from '../../types';
+import {ModelData} from '../../types';
+import {Identifier} from '../../types';
+import {ItemFilter} from '../../filter';
+import {WhereClause} from '../../filter';
+import {ServiceContainer} from '@e22m4u/service';
+
+/**
+ * Memory adapter.
+ */
+export declare class MemoryAdapter extends Adapter {
+  /**
+   * Settings.
+   */
+  get settings(): AnyObject | undefined;
+
+  /**
+   * Constructor.
+   *
+   * @param container
+   * @param settings
+   */
+  constructor(container?: ServiceContainer, settings?: AnyObject);
+
+  /**
+   * Create.
+   *
+   * @param modelName
+   * @param modelData
+   * @param filter
+   */
+  create(
+    modelName: string,
+    modelData: ModelData,
+    filter?: ItemFilter,
+  ): Promise<ModelData>;
+
+  /**
+   * Replace by id.
+   *
+   * @param modelName
+   * @param id
+   * @param modelData
+   * @param filter
+   */
+  replaceById(
+    modelName: string,
+    id: Identifier,
+    modelData: ModelData,
+    filter?: ItemFilter,
+  ): Promise<ModelData>;
+
+  /**
+   * Patch by id.
+   *
+   * @param modelName
+   * @param id
+   * @param modelData
+   * @param filter
+   */
+  patchById(
+    modelName: string,
+    id: Identifier,
+    modelData: ModelData,
+    filter?: ItemFilter,
+  ): Promise<ModelData>;
+
+  /**
+   * Find.
+   *
+   * @param modelName
+   * @param filter
+   */
+  find(modelName: string, filter?: Filter): Promise<ModelData[]>;
+
+  /**
+   * Find by id.
+   *
+   * @param modelName
+   * @param id
+   * @param filter
+   */
+  findById(
+    modelName: string,
+    id: Identifier,
+    filter?: Filter,
+  ): Promise<ModelData>;
+
+  /**
+   * Delete.
+   *
+   * @param modelName
+   * @param where
+   */
+  delete(modelName: string, where?: WhereClause): Promise<number>;
+
+  /**
+   * Delete by id.
+   *
+   * @param modelName
+   * @param id
+   */
+  deleteById(modelName: string, id: Identifier): Promise<boolean>;
+
+  /**
+   * Exists.
+   *
+   * @param modelName
+   * @param id
+   */
+  exists(modelName: string, id: Identifier): Promise<boolean>;
+
+  /**
+   * Count.
+   *
+   * @param modelName
+   * @param where
+   */
+  count(modelName: string, where?: WhereClause): Promise<number>;
+}

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

@@ -30,7 +30,7 @@ export class MemoryAdapter extends Adapter {
    * Get table or create.
    *
    * @param {string} modelName
-   * @return {Map<number, object>}
+   * @returns {Map<number, object>}
    */
   _getTableOrCreate(modelName) {
     const tableName =
@@ -47,7 +47,7 @@ export class MemoryAdapter extends Adapter {
    *
    * @param {string} modelName
    * @param {string} propName
-   * @return {number}
+   * @returns {number}
    */
   _genNextIdValue(modelName, propName) {
     const propType = this.getService(
@@ -83,7 +83,7 @@ export class MemoryAdapter extends Adapter {
    * @param {string} modelName
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   // eslint-disable-next-line no-unused-vars
   async create(modelName, modelData, filter = undefined) {
@@ -123,7 +123,7 @@ export class MemoryAdapter extends Adapter {
    * @param {string|number} id
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   // eslint-disable-next-line no-unused-vars
   async replaceById(modelName, id, modelData, filter = undefined) {
@@ -161,7 +161,7 @@ export class MemoryAdapter extends Adapter {
    * @param {string|number} id
    * @param {object} modelData
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   // eslint-disable-next-line no-unused-vars
   async patchById(modelName, id, modelData, filter = undefined) {
@@ -200,8 +200,8 @@ export class MemoryAdapter extends Adapter {
    * Find.
    *
    * @param {string} modelName
-   * @param {Record<string, unknown>|undefined} filter
-   * @return {Promise<object[]>}
+   * @param {object|undefined} filter
+   * @returns {Promise<object[]>}
    */
   async find(modelName, filter = undefined) {
     const table = this._getTableOrCreate(modelName);
@@ -237,7 +237,7 @@ export class MemoryAdapter extends Adapter {
    * @param {string} modelName
    * @param {string|number} id
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   // eslint-disable-next-line no-unused-vars
   async findById(modelName, id, filter = undefined) {
@@ -263,8 +263,8 @@ export class MemoryAdapter extends Adapter {
    * Delete.
    *
    * @param {string} modelName
-   * @param {Record<string, unknown>|undefined} where
-   * @return {Promise<number>}
+   * @param {object|undefined} where
+   * @returns {Promise<number>}
    */
   async delete(modelName, where = undefined) {
     const table = this._getTableOrCreate(modelName);
@@ -297,7 +297,7 @@ export class MemoryAdapter extends Adapter {
    *
    * @param {string} modelName
    * @param {string|number} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   async deleteById(modelName, id) {
     const table = this._getTableOrCreate(modelName);
@@ -311,7 +311,7 @@ export class MemoryAdapter extends Adapter {
    *
    * @param {string} modelName
    * @param {string|number} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   async exists(modelName, id) {
     const table = this._getTableOrCreate(modelName);
@@ -323,7 +323,7 @@ export class MemoryAdapter extends Adapter {
    *
    * @param {string} modelName
    * @param {object|undefined} where
-   * @return {Promise<number>}
+   * @returns {Promise<number>}
    */
   async count(modelName, where = undefined) {
     const table = this._getTableOrCreate(modelName);

+ 13 - 0
src/adapter/decorator/data-sanitizing-decorator.d.ts

@@ -0,0 +1,13 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Data sanitizing decorator.
+ */
+export declare class DataSanitizingDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param adapter
+   */
+  decorate(adapter): void;
+}

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

@@ -10,7 +10,7 @@ export class DataSanitizingDecorator extends Service {
   /**
    * Decorate.
    *
-   * @param adapter
+   * @param {Adapter} adapter
    */
   decorate(adapter) {
     if (!adapter || !(adapter instanceof Adapter))

+ 13 - 0
src/adapter/decorator/data-validation-decorator.d.ts

@@ -0,0 +1,13 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Data validation decorator.
+ */
+export declare class DataValidationDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param adapter
+   */
+  decorate(adapter): void;
+}

+ 13 - 0
src/adapter/decorator/default-values-decorator.d.ts

@@ -0,0 +1,13 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Default values decorator.
+ */
+export declare class DefaultValuesDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param adapter
+   */
+  decorate(adapter): void;
+}

+ 13 - 0
src/adapter/decorator/fields-filtering-decorator.d.ts

@@ -0,0 +1,13 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Fields filtering decorator.
+ */
+export declare class FieldsFilteringDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param adapter
+   */
+  decorate(adapter): void;
+}

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

@@ -10,7 +10,7 @@ export class FieldsFilteringDecorator extends Service {
   /**
    * Decorate.
    *
-   * @param adapter
+   * @param {Adapter} adapter
    */
   decorate(adapter) {
     if (!adapter || !(adapter instanceof Adapter))

+ 13 - 0
src/adapter/decorator/inclusion-decorator.d.ts

@@ -0,0 +1,13 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Inclusion decorator.
+ */
+export declare class InclusionDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param adapter
+   */
+  decorate(adapter): void;
+}

+ 5 - 0
src/adapter/decorator/index.d.ts

@@ -0,0 +1,5 @@
+export * from './inclusion-decorator';
+export * from './default-values-decorator';
+export * from './data-sanitizing-decorator';
+export * from './data-validation-decorator';
+export * from './fields-filtering-decorator';

+ 2 - 0
src/adapter/index.d.ts

@@ -1 +1,3 @@
 export * from './adapter';
+export * from './adapter-loader';
+export * from './adapter-registry';

+ 14 - 0
src/definition/datasource/datasource-definition-validator.d.ts

@@ -0,0 +1,14 @@
+import {Service} from '@e22m4u/service';
+import {DatasourceDefinition} from './datasource-definition';
+
+/**
+ * Datasource definition validator.
+ */
+export declare class DatasourceDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param datasourceDef
+   */
+  validate(datasourceDef: DatasourceDefinition): void;
+}

+ 0 - 1
src/definition/datasource/datasource-definition-validator.js

@@ -9,7 +9,6 @@ export class DatasourceDefinitionValidator extends Service {
    * Validate.
    *
    * @param {object} datasourceDef
-   * @return {void}
    */
   validate(datasourceDef) {
     if (!datasourceDef || typeof datasourceDef !== 'object')

+ 1 - 1
src/definition/datasource/datasource-definition.d.ts

@@ -4,4 +4,4 @@
 export declare type DatasourceDefinition = {
   name: string;
   adapter: string;
-}
+};

+ 1 - 0
src/definition/datasource/index.d.ts

@@ -1 +1,2 @@
 export * from './datasource-definition';
+export * from './datasource-definition-validator';

+ 50 - 0
src/definition/definition-registry.d.ts

@@ -0,0 +1,50 @@
+import {Service} from '@e22m4u/service';
+import {ModelDefinition} from './model';
+import {DatasourceDefinition} from './datasource';
+
+/**
+ * Definition registry.
+ */
+export declare class DefinitionRegistry extends Service {
+  /**
+   * Add datasource.
+   *
+   * @param datasourceDef
+   */
+  addDatasource(datasourceDef: DatasourceDefinition): void;
+
+  /**
+   * Has datasource.
+   *
+   * @param name
+   */
+  hasDatasource(name: string): boolean;
+
+  /**
+   * Get datasource.
+   *
+   * @param name
+   */
+  getDatasource(name: string): DatasourceDefinition;
+
+  /**
+   * Add model.
+   *
+   * @param modelDef
+   */
+  addModel(modelDef: ModelDefinition): void;
+
+  /**
+   * Has model.
+   *
+   * @param name
+   */
+  hasModel(name: string): boolean;
+
+  /**
+   * Get model.
+   *
+   * @param name
+   */
+  getModel(name: string): ModelDefinition;
+}

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

@@ -10,21 +10,21 @@ export class DefinitionRegistry extends Service {
   /**
    * Datasources.
    *
-   * @type {{[name: string]: object}}
+   * @type {object}
    */
   _datasources = {};
 
   /**
    * Models.
    *
-   * @type {{[name: string]: object}}
+   * @type {object}
    */
   _models = {};
 
   /**
    * Add datasource.
    *
-   * @param datasourceDef
+   * @param {object} datasourceDef
    */
   addDatasource(datasourceDef) {
     this.getService(DatasourceDefinitionValidator).validate(datasourceDef);
@@ -40,8 +40,8 @@ export class DefinitionRegistry extends Service {
   /**
    * Has datasource.
    *
-   * @param name
-   * @return {boolean}
+   * @param {string} name
+   * @returns {boolean}
    */
   hasDatasource(name) {
     return Boolean(this._datasources[name]);
@@ -50,8 +50,8 @@ export class DefinitionRegistry extends Service {
   /**
    * Get datasource.
    *
-   * @param name
-   * @return {Object}
+   * @param {string} name
+   * @returns {object}
    */
   getDatasource(name) {
     const datasourceDef = this._datasources[name];
@@ -63,7 +63,7 @@ export class DefinitionRegistry extends Service {
   /**
    * Add model.
    *
-   * @param modelDef
+   * @param {object} modelDef
    */
   addModel(modelDef) {
     this.getService(ModelDefinitionValidator).validate(modelDef);
@@ -76,8 +76,8 @@ export class DefinitionRegistry extends Service {
   /**
    * Has model.
    *
-   * @param name
-   * @return {boolean}
+   * @param {string} name
+   * @returns {boolean}
    */
   hasModel(name) {
     return Boolean(this._models[name]);
@@ -86,8 +86,8 @@ export class DefinitionRegistry extends Service {
   /**
    * Get model.
    *
-   * @param name
-   * @return {object}
+   * @param {string} name
+   * @returns {object}
    */
   getModel(name) {
     const modelDef = this._models[name];

+ 1 - 0
src/definition/index.d.ts

@@ -1,2 +1,3 @@
 export * from './model';
 export * from './datasource';
+export * from './definition-registry';

+ 4 - 0
src/definition/model/index.d.ts

@@ -1,3 +1,7 @@
 export * from './relations';
 export * from './properties';
 export * from './model-definition';
+export * from './model-data-validator';
+export * from './model-data-sanitizer';
+export * from './model-definition-utils';
+export * from './model-definition-validator';

+ 15 - 0
src/definition/model/model-data-sanitizer.d.ts

@@ -0,0 +1,15 @@
+import {ModelData} from '../../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Model data sanitizer.
+ */
+export declare class ModelDataSanitizer extends Service {
+  /**
+   * Sanitize.
+   *
+   * @param modelName
+   * @param modelData
+   */
+  sanitize(modelName: string, modelData: ModelData): ModelData;
+}

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

@@ -11,7 +11,7 @@ export class ModelDataSanitizer extends Service {
    *
    * @param {string} modelName
    * @param {object} modelData
-   * @return {object}
+   * @returns {object}
    */
   sanitize(modelName, modelData) {
     if (!modelName || typeof modelName !== 'string')

+ 32 - 0
src/definition/model/model-data-validator.d.ts

@@ -0,0 +1,32 @@
+import {Service} from '@e22m4u/service';
+import {ModelData} from '../../types';
+import {PropertyDefinition} from './properties';
+
+/**
+ * Model data validator.
+ */
+export declare class ModelDataValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelName
+   * @param modelData
+   * @param isPartial
+   */
+  validate(modelName: string, modelData: ModelData, isPartial?: boolean): void;
+
+  /**
+   * Validate property value.
+   *
+   * @param modelName
+   * @param propName
+   * @param propDef
+   * @param propValue
+   */
+  validatePropertyValue(
+    modelName: string,
+    propName: string,
+    propDef: PropertyDefinition,
+    propValue: unknown,
+  ): void;
+}

+ 3 - 4
src/definition/model/model-data-validator.js

@@ -46,8 +46,7 @@ export class ModelDataValidator extends Service {
    * @param {string} modelName
    * @param {string} propName
    * @param {string|object} propDef
-   * @param {any} propValue
-   * @return {void}
+   * @param {*} propValue
    */
   validatePropertyValue(modelName, propName, propDef, propValue) {
     // undefined and null
@@ -72,9 +71,9 @@ export class ModelDataValidator extends Service {
    * @param {string} modelName
    * @param {string} propName
    * @param {string|object} propDef
-   * @param {any} propValue
+   * @param {*} propValue
    * @param {boolean} isArrayValue
-   * @return {void}
+   * @returns {void}
    */
   _validatePropertyValueType(
     modelName,

+ 161 - 0
src/definition/model/model-definition-utils.d.ts

@@ -0,0 +1,161 @@
+import {DataType} from './properties';
+import {ModelData} from '../../types';
+import {Service} from '@e22m4u/service';
+import {RelationDefinition} from './relations';
+import {PropertyDefinitionMap} from './model-definition';
+import {RelationDefinitionMap} from './model-definition';
+
+/**
+ * Default primary key property name.
+ */
+export type DEFAULT_PRIMARY_KEY_PROPERTY_NAME = 'id';
+
+/**
+ * Model definition utils.
+ */
+export declare class ModelDefinitionUtils extends Service {
+  /**
+   * Get primary key as property name.
+   *
+   * @param modelName
+   */
+  getPrimaryKeyAsPropertyName(modelName: string): string;
+
+  /**
+   * Get primary key as column name.
+   *
+   * @param modelName
+   */
+  getPrimaryKeyAsColumnName(modelName: string): string;
+
+  /**
+   * Get table name by model name.
+   *
+   * @param modelName
+   */
+  getTableNameByModelName(modelName: string): string;
+
+  /**
+   * Get column name by property name.
+   *
+   * @param modelName
+   * @param propertyName
+   */
+  getColumnNameByPropertyName(modelName: string, propertyName: string): string;
+
+  /**
+   * Get default property value.
+   *
+   * @param modelName
+   * @param propertyName
+   */
+  getDefaultPropertyValue(modelName: string, propertyName: string): unknown;
+
+  /**
+   * Set default values to empty properties.
+   *
+   * @param modelName
+   * @param modelData
+   * @param onlyProvidedProperties
+   */
+  setDefaultValuesToEmptyProperties<T extends ModelData>(
+    modelName: string,
+    modelData: T,
+    onlyProvidedProperties?: boolean,
+  ): T;
+
+  /**
+   * Convert property names to column names.
+   *
+   * @param modelName
+   * @param modelData
+   */
+  convertPropertyNamesToColumnNames(
+    modelName: string,
+    modelData: ModelData,
+  ): ModelData;
+
+  /**
+   * Convert column names to property names.
+   *
+   * @param modelName
+   * @param tableData
+   */
+  convertColumnNamesToPropertyNames(
+    modelName: string,
+    tableData: ModelData,
+  ): ModelData;
+
+  /**
+   * Get data type by property name.
+   *
+   * @param modelName
+   * @param propertyName
+   */
+  getDataTypeByPropertyName(modelName: string, propertyName: string): DataType;
+
+  /**
+   * Get own properties definition of primary keys.
+   *
+   * @param modelName
+   */
+  getOwnPropertiesDefinitionOfPrimaryKeys(
+    modelName: string,
+  ): PropertyDefinitionMap;
+
+  /**
+   * Get own properties definition without primary keys.
+   *
+   * @param modelName
+   */
+  getOwnPropertiesDefinitionWithoutPrimaryKeys(
+    modelName: string,
+  ): PropertyDefinitionMap;
+
+  /**
+   * Get properties definition in base model hierarchy.
+   *
+   * @param modelName
+   */
+  getPropertiesDefinitionInBaseModelHierarchy(
+    modelName: string,
+  ): PropertyDefinitionMap;
+
+  /**
+   * Get own relations definition.
+   *
+   * @param modelName
+   */
+  getOwnRelationsDefinition(modelName: string): RelationDefinitionMap;
+
+  /**
+   * Get relations definition in base model hierarchy.
+   *
+   * @param modelName
+   */
+  getRelationsDefinitionInBaseModelHierarchy(
+    modelName: string,
+  ): RelationDefinitionMap;
+
+  /**
+   * Get relation definition by name.
+   *
+   * @param modelName
+   * @param relationName
+   */
+  getRelationDefinitionByName(
+    modelName: string,
+    relationName: string,
+  ): RelationDefinition;
+
+  /**
+   * Exclude object keys by relation names.
+   *
+   * @param modelName
+   * @param modelData
+   */
+  excludeObjectKeysByRelationNames<T extends ModelData>(
+    modelName: string,
+    modelData: T,
+  ): Partial<T>;
+}

+ 32 - 23
src/definition/model/model-definition-utils.js

@@ -19,7 +19,8 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get primary key as property name.
    *
-   * @param modelName
+   * @param {string} modelName
+   * @returns {string}
    */
   getPrimaryKeyAsPropertyName(modelName) {
     const propDefs =
@@ -48,7 +49,8 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get primary key as column name.
    *
-   * @param modelName
+   * @param {string} modelName
+   * @returns {string}
    */
   getPrimaryKeyAsColumnName(modelName) {
     const pkPropName = this.getPrimaryKeyAsPropertyName(modelName);
@@ -65,7 +67,8 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get table name by model name.
    *
-   * @param modelName
+   * @param {string} modelName
+   * @returns {string}
    */
   getTableNameByModelName(modelName) {
     const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
@@ -75,8 +78,9 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get column name by property name.
    *
-   * @param modelName
-   * @param propertyName
+   * @param {string} modelName
+   * @param {string} propertyName
+   * @returns {string}
    */
   getColumnNameByPropertyName(modelName, propertyName) {
     const propDefs =
@@ -96,8 +100,9 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get default property value.
    *
-   * @param modelName
-   * @param propertyName
+   * @param {string} modelName
+   * @param {string} propertyName
+   * @returns {*}
    */
   getDefaultPropertyValue(modelName, propertyName) {
     const propDefs =
@@ -118,9 +123,10 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Set default values for empty properties.
    *
-   * @param modelName
-   * @param modelData
-   * @param onlyProvidedProperties
+   * @param {string} modelName
+   * @param {object} modelData
+   * @param {boolean|undefined} onlyProvidedProperties
+   * @returns {object}
    */
   setDefaultValuesToEmptyProperties(
     modelName,
@@ -154,8 +160,9 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Convert property names to column names.
    *
-   * @param modelName
-   * @param modelData
+   * @param {string} modelName
+   * @param {object} modelData
+   * @returns {object}
    */
   convertPropertyNamesToColumnNames(modelName, modelData) {
     const propDefs =
@@ -176,8 +183,9 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Convert column names to property names.
    *
-   * @param modelName
-   * @param tableData
+   * @param {string} modelName
+   * @param {object} tableData
+   * @returns {object}
    */
   convertColumnNamesToPropertyNames(modelName, tableData) {
     const propDefs =
@@ -197,8 +205,9 @@ export class ModelDefinitionUtils extends Service {
   /**
    * Get data type by property name.
    *
-   * @param modelName
-   * @param propertyName
+   * @param {string} modelName
+   * @param {string} propertyName
+   * @returns {string}
    */
   getDataTypeByPropertyName(modelName, propertyName) {
     const propDefs =
@@ -221,7 +230,7 @@ export class ModelDefinitionUtils extends Service {
    * Get own properties definition of primary keys.
    *
    * @param {string} modelName
-   * @return {object}
+   * @returns {object}
    */
   getOwnPropertiesDefinitionOfPrimaryKeys(modelName) {
     const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
@@ -237,7 +246,7 @@ export class ModelDefinitionUtils extends Service {
    * Get own properties definition without primary keys.
    *
    * @param {string} modelName
-   * @return {object}
+   * @returns {object}
    */
   getOwnPropertiesDefinitionWithoutPrimaryKeys(modelName) {
     const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
@@ -253,7 +262,7 @@ export class ModelDefinitionUtils extends Service {
    * Get properties definition in base model hierarchy.
    *
    * @param {string} modelName
-   * @return {object}
+   * @returns {object}
    */
   getPropertiesDefinitionInBaseModelHierarchy(modelName) {
     let result = {};
@@ -284,7 +293,7 @@ export class ModelDefinitionUtils extends Service {
    * Get own relations definition.
    *
    * @param {string} modelName
-   * @return {object}
+   * @returns {object}
    */
   getOwnRelationsDefinition(modelName) {
     const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
@@ -295,7 +304,7 @@ export class ModelDefinitionUtils extends Service {
    * Get relations definition in base model hierarchy.
    *
    * @param {string} modelName
-   * @return {object}
+   * @returns {object}
    */
   getRelationsDefinitionInBaseModelHierarchy(modelName) {
     let result = {};
@@ -320,7 +329,7 @@ export class ModelDefinitionUtils extends Service {
    *
    * @param {string} modelName
    * @param {string} relationName
-   * @return {object}
+   * @returns {object}
    */
   getRelationDefinitionByName(modelName, relationName) {
     const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName);
@@ -346,7 +355,7 @@ export class ModelDefinitionUtils extends Service {
    *
    * @param {string} modelName
    * @param {object} modelData
-   * @return {object}
+   * @returns {object}
    */
   excludeObjectKeysByRelationNames(modelName, modelData) {
     if (!modelData || typeof modelData !== 'object' || Array.isArray(modelData))

+ 14 - 0
src/definition/model/model-definition-validator.d.ts

@@ -0,0 +1,14 @@
+import {Service} from '@e22m4u/service';
+import {ModelDefinition} from './model-definition';
+
+/**
+ * Model definition validator.
+ */
+export declare class ModelDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelDef
+   */
+  validate(modelDef: ModelDefinition): void;
+}

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

@@ -10,7 +10,7 @@ export class ModelDefinitionValidator extends Service {
   /**
    * Validate.
    *
-   * @param modelDef
+   * @param {object} modelDef
    */
   validate(modelDef) {
     if (!modelDef || typeof modelDef !== 'object' || Array.isArray(modelDef))

+ 7 - 7
src/definition/model/model-definition.d.ts

@@ -5,15 +5,15 @@ import {PropertyDefinition} from './properties';
  * Property definition map.
  */
 export declare type PropertyDefinitionMap = {
-  [name: string]: PropertyDefinition,
-}
+  [name: string]: PropertyDefinition;
+};
 
 /**
  * Relation definition map.
  */
 export declare type RelationDefinitionMap = {
-  [name: string]: RelationDefinition,
-}
+  [name: string]: RelationDefinition;
+};
 
 /**
  * Model definition.
@@ -23,6 +23,6 @@ export declare type ModelDefinition = {
   datasource?: string;
   base?: string;
   tableName?: string;
-  properties?: PropertyDefinitionMap,
-  relations?: RelationDefinitionMap,
-}
+  properties?: PropertyDefinitionMap;
+  relations?: RelationDefinitionMap;
+};

+ 15 - 0
src/definition/model/properties/default-values-definition-validator.d.ts

@@ -0,0 +1,15 @@
+import {Service} from '@e22m4u/service';
+import {PropertyDefinitionMap} from '../model-definition';
+
+/**
+ * Default values definition validator.
+ */
+export declare class DefaultValuesDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelName
+   * @param propDefs
+   */
+  validate(modelName: string, propDefs: PropertyDefinitionMap): void;
+}

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

@@ -1,6 +1,6 @@
 import {Service} from '@e22m4u/service';
-import {InvalidArgumentError} from '../../../errors/index.js';
 import {ModelDataValidator} from '../model-data-validator.js';
+import {InvalidArgumentError} from '../../../errors/index.js';
 
 /**
  * Default values definition validator.
@@ -9,8 +9,8 @@ export class DefaultValuesDefinitionValidator extends Service {
   /**
    * Validate.
    *
-   * @param modelName
-   * @param propDefs
+   * @param {string} modelName
+   * @param {object} propDefs
    */
   validate(modelName, propDefs) {
     if (!modelName || typeof modelName !== 'string')

+ 3 - 0
src/definition/model/properties/index.d.ts

@@ -1,2 +1,5 @@
 export * from './data-type';
 export * from './property-definition';
+export * from './properties-definition-validator';
+export * from './primary-keys-definition-validator';
+export * from './default-values-definition-validator';

+ 15 - 0
src/definition/model/properties/primary-keys-definition-validator.d.ts

@@ -0,0 +1,15 @@
+import {Service} from '@e22m4u/service';
+import {PropertyDefinitionMap} from '../model-definition';
+
+/**
+ * Primary keys definition validator.
+ */
+export declare class PrimaryKeysDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelName
+   * @param propDefs
+   */
+  validate(modelName: string, propDefs: PropertyDefinitionMap): void;
+}

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

@@ -9,8 +9,8 @@ export class PrimaryKeysDefinitionValidator extends Service {
   /**
    * Validate.
    *
-   * @param modelName
-   * @param propDefs
+   * @param {string} modelName
+   * @param {object} propDefs
    */
   validate(modelName, propDefs) {
     const propNames = Object.keys(propDefs).filter(propName => {

+ 15 - 0
src/definition/model/properties/properties-definition-validator.d.ts

@@ -0,0 +1,15 @@
+import {Service} from '@e22m4u/service';
+import {PropertyDefinitionMap} from '../model-definition';
+
+/**
+ * Properties definition validator.
+ */
+export declare class PropertiesDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelName
+   * @param propDefs
+   */
+  validate(modelName: string, propDefs: PropertyDefinitionMap): void;
+}

+ 5 - 5
src/definition/model/properties/properties-definition-validator.js

@@ -11,8 +11,8 @@ export class PropertiesDefinitionValidator extends Service {
   /**
    * Validate.
    *
-   * @param modelName
-   * @param propDefs
+   * @param {string} modelName
+   * @param {object} propDefs
    */
   validate(modelName, propDefs) {
     if (!modelName || typeof modelName !== 'string')
@@ -47,9 +47,9 @@ export class PropertiesDefinitionValidator extends Service {
   /**
    * Validate property.
    *
-   * @param modelName
-   * @param propName
-   * @param propDef
+   * @param {string} modelName
+   * @param {string} propName
+   * @param {object} propDef
    */
   _validateProperty(modelName, propName, propDef) {
     if (!modelName || typeof modelName !== 'string')

+ 9 - 11
src/definition/model/properties/property-definition.d.ts

@@ -4,18 +4,16 @@ import {DataType} from './data-type';
  * Full property definition.
  */
 export declare type FullPropertyDefinition = {
-  type: DataType,
-  itemType?: DataType,
-  model?: string,
-  primaryKey?: boolean,
-  columnName?: string,
-  columnType?: string,
-  required?: boolean,
-}
+  type: DataType;
+  itemType?: DataType;
+  model?: string;
+  primaryKey?: boolean;
+  columnName?: string;
+  columnType?: string;
+  required?: boolean;
+};
 
 /**
  * Property definition.
  */
-declare type PropertyDefinition =
-  | DataType
-  | FullPropertyDefinition;
+declare type PropertyDefinition = DataType | FullPropertyDefinition;

+ 1 - 0
src/definition/model/relations/index.d.ts

@@ -1,2 +1,3 @@
 export * from './relation-type';
 export * from './relation-definition';
+export * from './relation-definition-validator';

+ 6 - 6
src/definition/model/relations/relation-definition.d.ts

@@ -4,9 +4,9 @@ import {RelationType} from './relation-type';
  * Relation definition.
  */
 declare type RelationDefinition = {
-  type: RelationType,
-  model?: string,
-  foreignKey?: string,
-  polymorphic?: boolean|string,
-  discriminator?: string,
-}
+  type: RelationType;
+  model?: string;
+  foreignKey?: string;
+  polymorphic?: boolean | string;
+  discriminator?: string;
+};

+ 15 - 0
src/definition/model/relations/relations-definition-validator.d.ts

@@ -0,0 +1,15 @@
+import {Service} from '@e22m4u/service';
+import {RelationDefinitionMap} from '../model-definition';
+
+/**
+ * Relations definition validator.
+ */
+export declare class RelationsDefinitionValidator extends Service {
+  /**
+   * Validate.
+   *
+   * @param modelName
+   * @param relDefs
+   */
+  validate(modelName: string, relDefs: RelationDefinitionMap): void;
+}

+ 7 - 7
src/definition/model/relations/relations-definition-validator.js

@@ -10,8 +10,8 @@ export class RelationsDefinitionValidator extends Service {
   /**
    * Validate.
    *
-   * @param modelName
-   * @param relDefs
+   * @param {string} modelName
+   * @param {object} relDefs
    */
   validate(modelName, relDefs) {
     if (!modelName || typeof modelName !== 'string')
@@ -37,9 +37,9 @@ export class RelationsDefinitionValidator extends Service {
   /**
    * Validate relation.
    *
-   * @param modelName
-   * @param relName
-   * @param relDef
+   * @param {string} modelName
+   * @param {string} relName
+   * @param {object} relDef
    */
   _validateRelation(modelName, relName, relDef) {
     if (!modelName || typeof modelName !== 'string')
@@ -199,7 +199,7 @@ export class RelationsDefinitionValidator extends Service {
    *
    * @param {string} modelName
    * @param {string} relName
-   * @param {Record<string, unknown>} relDef
+   * @param {object} relDef
    * @private
    */
   _validateHasOne(modelName, relName, relDef) {
@@ -415,7 +415,7 @@ export class RelationsDefinitionValidator extends Service {
    *
    * @param {string} modelName
    * @param {string} relName
-   * @param {Record<string, unknown>} relDef
+   * @param {object} relDef
    * @private
    */
   _validateReferencesMany(modelName, relName, relDef) {

+ 3 - 0
src/errors/index.d.ts

@@ -0,0 +1,3 @@
+export * from './not-implemented-error';
+export * from './invalid-argument-error';
+export * from './invalid-operator-value-error';

+ 6 - 0
src/errors/invalid-argument-error.d.ts

@@ -0,0 +1,6 @@
+import {Errorf} from '@e22m4u/util-format';
+
+/**
+ * Invalid argument error.
+ */
+export declare class InvalidArgumentError extends Errorf {}

+ 13 - 0
src/errors/invalid-operator-value-error.d.ts

@@ -0,0 +1,13 @@
+/**
+ * Invalid operator value error.
+ */
+export declare class InvalidOperatorValueError extends Error {
+  /**
+   * Constructor.
+   *
+   * @param operator
+   * @param expects
+   * @param value
+   */
+  constructor(operator: string, expects: string, value: unknown);
+}

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

@@ -7,9 +7,9 @@ export class InvalidOperatorValueError extends Error {
   /**
    * Constructor.
    *
-   * @param operator
-   * @param expected
-   * @param value
+   * @param {string} operator
+   * @param {string} expected
+   * @param {*} value
    */
   constructor(operator, expected, value) {
     super(

+ 6 - 0
src/errors/not-implemented-error.d.ts

@@ -0,0 +1,6 @@
+import {Errorf} from '@e22m4u/util-format';
+
+/**
+ * Not implemented error.
+ */
+export declare class NotImplementedError extends Errorf {}

+ 38 - 0
src/filter/fields-clause-tool.d.ts

@@ -0,0 +1,38 @@
+import {ModelData} from '../types';
+import {FieldsClause} from './filter';
+import {Service} from '@e22m4u/service';
+import {NormalizedFieldsClause} from './filter';
+
+/**
+ * Field clause tool.
+ */
+export declare class FieldsClauseTool extends Service {
+  /**
+   * Filter.
+   *
+   * @param entities
+   * @param modelName
+   * @param clause
+   */
+  filter<T extends ModelData | ModelData[]>(
+    entities: T,
+    modelName: string,
+    clause: FieldsClause | undefined,
+  ): T;
+
+  /**
+   * Validate fields clause.
+   *
+   * @param clause
+   */
+  static validateFieldsClause(clause: FieldsClause | undefined): void;
+
+  /**
+   * Normalize fields clause.
+   *
+   * @param clause
+   */
+  static normalizeFieldsClause(
+    clause: FieldsClause | undefined,
+  ): NormalizedFieldsClause | undefined;
+}

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

@@ -12,8 +12,8 @@ export class FieldsClauseTool extends Service {
    *
    * @param {object|object[]} entities
    * @param {string} modelName
-   * @param {string|string[]} clause
-   * @return {object|object[]}
+   * @param {string|string[]|undefined} clause
+   * @returns {object|object[]}
    */
   filter(entities, modelName, clause) {
     const isArray = Array.isArray(entities);
@@ -27,6 +27,7 @@ export class FieldsClauseTool extends Service {
         );
     });
 
+    if (!clause) return entities;
     const fields = Array.isArray(clause) ? clause.slice() : [clause];
     fields.forEach(field => {
       if (!field || typeof field !== 'string')
@@ -50,7 +51,7 @@ export class FieldsClauseTool extends Service {
   /**
    * Validate fields clause.
    *
-   * @param clause
+   * @param {string|string[]|undefined} clause
    */
   static validateFieldsClause(clause) {
     if (!clause) return;
@@ -68,7 +69,8 @@ export class FieldsClauseTool extends Service {
   /**
    * Normalize fields clause.
    *
-   * @param clause
+   * @param {string|string[]|undefined} clause
+   * @returns {string[]|undefined}
    */
   static normalizeFieldsClause(clause) {
     if (!clause) return;

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

@@ -89,12 +89,12 @@ describe('FieldsClauseTool', function () {
       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);
-      validate(null);
-      validate('foo');
-      validate(['foo']);
+      validate('')();
+      validate(false)();
+      validate(undefined)();
+      validate(null)();
+      validate('foo')();
+      validate(['foo'])();
     });
   });
 

+ 317 - 7
src/filter/filter.d.ts

@@ -1,24 +1,334 @@
+import {ModelData} from '../types';
+
 /**
  * Filter.
  */
 export declare type Filter = {
   where?: WhereClause;
-  order?: string | string[];
+  order?: OrderClause;
   limit?: number;
   skip?: number;
-  fields?: string | string[];
-  include?: Record<string, unknown>;
+  fields?: FieldsClause;
+  include?: IncludeClause;
 };
 
 /**
  * Item filter.
  */
-export declare type ItemFilter =
-  | Pick<Filter, 'fields' | 'include'>;
+export declare type ItemFilter = Pick<Filter, 'fields' | 'include'>;
 
 /**
  * Where clause.
+ *
+ * @example
+ * ```ts
+ * value => value.featured === true
+ * {foo: 'bar'}
+ * {foo: {eq: 'bar'}}
+ * {foo: {neq: 'bar'}}
+ * {foo: {gt: 5}}
+ * {foo: {lt: 10}}
+ * {foo: {gte: 5}}
+ * {foo: {lte: 10}}
+ * {foo: {inq: ['bar', 'baz']}}
+ * {foo: {nin: ['bar', 'baz']}}
+ * {foo: {between: [5, 10]}}
+ * {foo: {exists: true}}
+ * {foo: {like: 'bar'}}
+ * {foo: {ilike: 'BaR'}}
+ * {foo: {nlike: 'bar'}}
+ * {foo: {nilike: 'BaR'}}
+ * {foo: {regexp: 'ba.+'}}
+ * {foo: {regexp: 'ba.+', flags: 'i'}}
+ * {and: [...]}
+ * {or: [...]}
+ * ```
+ */
+export declare type WhereClause =
+  | FunctionClause
+  | PropertiesClause
+  | AndClause
+  | OrClause;
+
+/**
+ * Function clause.
+ *
+ * @example
+ * ```ts
+ * (value) => value.featured === true;
+ * ```
+ */
+export type FunctionClause = (value: ModelData) => boolean;
+
+/**
+ * Properties clause.
+ *
+ * @example
+ * ```ts
+ * {
+ *   name: {inq: ['John', 'Mary']},
+ *   status: 'ACTIVE',
+ *   age: {gte: 40}
+ * }
+ * ```
+ */
+export type PropertiesClause = {
+  [property: string]:
+    | OperatorClause
+    | string
+    | number
+    | boolean
+    | RegExp
+    | null
+    | undefined;
+};
+
+/**
+ * Operator clause.
+ *
+ * @example
+ * ```ts
+ * {eq: 'bar'}
+ * {neq: 'bar'}
+ * {gt: 5}
+ * {lt: 10}
+ * {gte: 5}
+ * {lte: 10}
+ * {inq: ['bar', 'baz']}
+ * {nin: ['bar', 'baz']}
+ * {between: [5, 10]}
+ * {exists: true}
+ * {like: 'bar'}
+ * {ilike: 'BaR'}
+ * {nlike: 'bar'}
+ * {nilike: 'BaR'}
+ * {regexp: 'ba.+'}
+ * {regexp: 'ba.+', flags: 'i'}
+ * ```
+ */
+export declare type OperatorClause = {
+  eq?: unknown;
+  neq?: unknown;
+  gt?: string | number;
+  gte?: string | number;
+  lt?: string | number;
+  lte?: string | number;
+  inq?: unknown[];
+  nin?: unknown[];
+  between?: readonly [string | number, string | number];
+  exists?: boolean;
+  like?: string | RegExp;
+  nlike?: string | RegExp;
+  ilike?: string | RegExp;
+  nilike?: string | RegExp;
+  regexp?: string | RegExp;
+};
+
+/**
+ * And clause.
+ *
+ * @example
+ * ```ts
+ * {
+ *   and: [...],
+ * }
+ * ```
  */
-export declare type WhereClause = {
-  [property: string]: unknown,
+export interface AndClause {
+  and: WhereClause[];
 }
+
+/**
+ * Or clause.
+ *
+ * @example
+ * ```ts
+ * {
+ *   or: [...],
+ * }
+ * ```
+ */
+export interface OrClause {
+  or: WhereClause[];
+}
+
+/**
+ * Order clause.
+ *
+ * @example
+ * ```ts
+ * 'prop'
+ * 'prop ASC'
+ * 'prop DESC';
+ * ['prop1', 'prop2'];
+ * ['prop1 ASC', 'prop2 DESC'];
+ * ```
+ */
+export type OrderClause = string | string[];
+
+/**
+ * Fields.
+ *
+ * @example
+ * ```ts
+ * 'prop'
+ * ['prop1', 'prop2']
+ * ```
+ */
+export type FieldsClause = string | NormalizedFieldsClause;
+
+/**
+ * Normalized fields clause.
+ *
+ * @example
+ * ```ts
+ * [
+ *   'prop1',
+ *   'prop2',
+ * ]
+ * ```
+ */
+export type NormalizedFieldsClause = string[];
+
+/**
+ * Include clause.
+ *
+ * @example
+ * ```ts
+ * 'customers'
+ * ```
+ *
+ * @example
+ * ```ts
+ * [
+ *   'customers',
+ *   'orders',
+ * ]
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: 'orders'
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: {
+ *     address: 'city',
+ *   },
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: [
+ *     'orders',
+ *     {address: 'city'},
+ *   ],
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   relation: 'customer',
+ *   scope: {
+ *     where: {removed: false},
+ *     order: 'createdAt DESC',
+ *     skip: 0,
+ *     limit: 16,
+ *     fields: ['id', 'name', 'removed'],
+ *     include: 'address',
+ *   }
+ * }
+ * ```
+ */
+export declare type IncludeClause =
+  | string
+  | string[]
+  | NestedIncludeClause
+  | NestedIncludeClause[]
+  | NormalizedIncludeClause
+  | NormalizedIncludeClause[];
+
+/**
+ * Nested include clause.
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: 'orders'
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: {
+ *     address: 'city',
+ *   },
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   customer: [
+ *     'orders',
+ *     {address: 'city'},
+ *   ],
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   relation: 'customer',
+ *   scope: {
+ *     where: {removed: false},
+ *     order: 'createdAt DESC',
+ *     skip: 0,
+ *     limit: 16,
+ *     fields: ['id', 'name', 'removed'],
+ *     include: 'address',
+ *   }
+ * }
+ * ```
+ */
+export declare type NestedIncludeClause = {
+  [property: string]: IncludeClause;
+};
+
+/**
+ * Inclusion.
+ *
+ * @example
+ * ```ts
+ * {
+ *   relation: 'customer',
+ * }
+ * ```
+ *
+ * @example
+ * ```ts
+ * {
+ *   relation: 'customer',
+ *   scope: {
+ *     where: {removed: false},
+ *     order: 'createdAt DESC',
+ *     skip: 0,
+ *     limit: 16,
+ *     fields: ['id', 'name', 'removed'],
+ *     include: 'address',
+ *   }
+ * }
+ * ```
+ */
+export declare type NormalizedIncludeClause = {
+  relation: string;
+  scope?: Filter;
+};

+ 53 - 0
src/filter/include-clause-tool.d.ts

@@ -0,0 +1,53 @@
+import {Filter} from './filter';
+import {ModelData} from '../types';
+import {IncludeClause} from './filter';
+import {Service} from '@e22m4u/service';
+import {NormalizedIncludeClause} from './filter';
+
+/**
+ * Include clause tool.
+ */
+export declare class IncludeClauseTool extends Service {
+  /**
+   * Include to.
+   *
+   * @param entities
+   * @param modelName
+   * @param clause
+   */
+  includeTo(
+    entities: ModelData[],
+    modelName: string,
+    clause: IncludeClause | undefined,
+  ): Promise<void>;
+
+  /**
+   * Validate include clause.
+   *
+   * @param clause
+   */
+  static validateIncludeClause(clause: IncludeClause | undefined): void;
+
+  /**
+   * Validate scope clause.
+   *
+   * @param clause
+   */
+  static validateScopeClause(clause: Filter | undefined): void;
+
+  /**
+   * Normalize include clause.
+   *
+   * @param clause
+   */
+  static normalizeIncludeClause(
+    clause: IncludeClause | undefined,
+  ): NormalizedIncludeClause[];
+
+  /**
+   * Normalize scope clause.
+   *
+   * @param clause
+   */
+  static normalizeScopeClause(clause: Filter | undefined): Filter | undefined;
+}

+ 10 - 7
src/filter/include-clause-tool.js

@@ -13,6 +13,8 @@ import {ReferencesManyResolver} from '../relations/index.js';
 
 /**
  * Include clause tool.
+ *
+ * @typedef {string|string[]|object|object[]} IncludeClause
  */
 export class IncludeClauseTool extends Service {
   /**
@@ -20,8 +22,8 @@ export class IncludeClauseTool extends Service {
    *
    * @param {object[]} entities
    * @param {string} modelName
-   * @param {object[]} clause
-   * @return {Promise<void>}
+   * @param {IncludeClause|undefined} clause
+   * @returns {Promise<void>}
    */
   async includeTo(entities, modelName, clause) {
     clause = IncludeClauseTool.normalizeIncludeClause(clause);
@@ -158,7 +160,7 @@ export class IncludeClauseTool extends Service {
   /**
    * Validate include clause.
    *
-   * @param clause
+   * @param {IncludeClause|undefined} clause
    */
   static validateIncludeClause(clause) {
     if (!clause) {
@@ -219,7 +221,7 @@ export class IncludeClauseTool extends Service {
   /**
    * Validate scope clause.
    *
-   * @param clause
+   * @param {object|undefined} clause
    */
   static validateScopeClause(clause) {
     if (!clause) return;
@@ -245,7 +247,8 @@ export class IncludeClauseTool extends Service {
   /**
    * Normalize include clause.
    *
-   * @param clause
+   * @param {IncludeClause|undefined} clause
+   * @returns {object[]}
    */
   static normalizeIncludeClause(clause) {
     let result = [];
@@ -316,8 +319,8 @@ export class IncludeClauseTool extends Service {
   /**
    * Normalize scope clause.
    *
-   * @param clause
-   * @return {undefined|{}}
+   * @param {object|undefined} clause
+   * @returns {object|undefined}
    */
   static normalizeScopeClause(clause) {
     if (!clause) return;

+ 6 - 0
src/filter/index.d.ts

@@ -1 +1,7 @@
 export * from './filter';
+export * from './slice-clause-tool';
+export * from './order-clause-tool';
+export * from './where-clause-tool';
+export * from './fields-clause-tool';
+export * from './include-clause-tool';
+export * from './operator-clause-tool';

+ 223 - 0
src/filter/operator-clause-tool.d.ts

@@ -0,0 +1,223 @@
+import {Service} from '@e22m4u/service';
+
+/**
+ * Operator clause tool.
+ */
+export declare class OperatorClauseTool extends Service {
+  /**
+   * Compare.
+   *
+   * @param val1
+   * @param val2
+   */
+  compare(val1: unknown, val2: unknown): number;
+
+  /**
+   * Test all operators.
+   *
+   * @param clause
+   * @param value
+   */
+  testAll(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test eq/neq operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   eq: 'foo',
+   * }
+   * ```
+   *
+   * @example
+   * ```ts
+   * {
+   *   neq: 'foo',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testEqNeq(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test lt/gt/lte/gte operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   lt: 10,
+   * }
+   * ```
+   *
+   * @example
+   * ```ts
+   * {
+   *   lte: 10,
+   * }
+   * ```
+   *
+   * @example
+   * ```ts
+   * {
+   *   gt: 10,
+   * }
+   * ```
+   *
+   * @example
+   * ```ts
+   * {
+   *   gte: 10,
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testGtLt(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test inc operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   inc: ['foo', 'bar'],
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testInq(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test nin operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   nin: ['foo', 'bar'],
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testNin(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test between operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   between: [10, 20],
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testBetween(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test exists operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   exists: true,
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testExists(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test like operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   like: 'foo',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testLike(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test nlike operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   nlike: 'foo',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testNlike(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test ilike operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   ilike: 'foo',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testIlike(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test nilike operator.
+   *
+   * @example
+   * ```ts
+   * {
+   *   nilike: 'foo',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testNilike(clause: object, value: unknown): boolean | undefined;
+
+  /**
+   * Test regexp.
+   *
+   * @example
+   * ```ts
+   * {
+   *   regexp: 'foo.*',
+   * }
+   * ```
+   *
+   * @example
+   * ```ts
+   * {
+   *   regexp: 'foo.*',
+   *   flags: 'i',
+   * }
+   * ```
+   *
+   * @param clause
+   * @param value
+   */
+  testRegexp(clause: object, value: unknown): boolean | undefined;
+}

+ 39 - 27
src/filter/operator-clause-tool.js

@@ -10,8 +10,8 @@ export class OperatorClauseTool extends Service {
   /**
    * Compare.
    *
-   * @param {any} val1 The 1st value
-   * @param {any} val2 The 2nd value
+   * @param {*} val1 The 1st value
+   * @param {*} val2 The 2nd value
    * @returns {number} 0: =, positive: >, negative <
    */
   compare(val1, val2) {
@@ -51,11 +51,12 @@ export class OperatorClauseTool extends Service {
   /**
    * Test all operators.
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testAll(clause, value) {
-    if (!clause || typeof clause !== 'object')
+    if (!clause || typeof clause !== 'object' || Array.isArray(clause))
       throw new InvalidArgumentError(
         'A first argument of OperatorUtils.testAll ' +
           'should be an Object, but %v given.',
@@ -128,8 +129,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testEqNeq(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -173,8 +175,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testGtLt(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -199,8 +202,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testInq(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -234,8 +238,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testNin(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -269,8 +274,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testBetween(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -304,8 +310,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testExists(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -336,8 +343,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testLike(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -363,8 +371,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testNlike(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -394,8 +403,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testIlike(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -425,8 +435,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testNilike(clause, value) {
     if (!clause || typeof clause !== 'object')
@@ -468,8 +479,9 @@ export class OperatorClauseTool extends Service {
    * }
    * ```
    *
-   * @param clause
-   * @param value
+   * @param {object} clause
+   * @param {*} value
+   * @returns {boolean|undefined}
    */
   testRegexp(clause, value) {
     if (!clause || typeof clause !== 'object')

+ 32 - 0
src/filter/order-clause-tool.d.ts

@@ -0,0 +1,32 @@
+import {ModelData} from '../types';
+import {OrderClause} from './filter';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Order clause tool.
+ */
+export declare class OrderClauseTool extends Service {
+  /**
+   * Sort.
+   *
+   * @param entities
+   * @param clause
+   */
+  sort(entities: ModelData[], clause: OrderClause | undefined): void;
+
+  /**
+   * Validate order clause.
+   *
+   * @param clause
+   */
+  static validateOrderClause(clause: OrderClause | undefined): void;
+
+  /**
+   * Normalize order clause.
+   *
+   * @param clause
+   */
+  static normalizeOrderClause(
+    clause: OrderClause | undefined,
+  ): string[] | undefined;
+}

+ 11 - 8
src/filter/order-clause-tool.js

@@ -7,12 +7,13 @@ import {InvalidArgumentError} from '../errors/index.js';
  */
 export class OrderClauseTool extends Service {
   /**
-   Sort.
+   * Sort.
    *
-   * @param entities
-   * @param clause
+   * @param {object[]} entities
+   * @param {string|string[]|undefined} clause
    */
   sort(entities, clause) {
+    if (!clause) return;
     if (!Array.isArray(clause)) clause = [clause];
     const mapping = [];
     clause.forEach((key, index) => {
@@ -36,9 +37,10 @@ export class OrderClauseTool extends Service {
   /**
    * Validate order clause.
    *
-   * @param clause
+   * @param {string|string[]|undefined} clause
    */
   static validateOrderClause(clause) {
+    if (!clause) return;
     const tempClause = Array.isArray(clause) ? clause : [clause];
     tempClause.forEach(key => {
       if (!key || typeof key !== 'string')
@@ -53,8 +55,8 @@ export class OrderClauseTool extends Service {
   /**
    * Normalize order clause.
    *
-   * @param {string|string[]} clause
-   * @return {string[]|undefined}
+   * @param {string|string[]|undefined} clause
+   * @returns {string[]|undefined}
    */
   static normalizeOrderClause(clause) {
     if (!clause) return;
@@ -74,8 +76,9 @@ export class OrderClauseTool extends Service {
 /**
  * Compare fn.
  *
- * @param a
- * @param b
+ * @param {*} a
+ * @param {*} b
+ * @returns {number}
  */
 function compareFn(a, b) {
   let undefinedA, undefinedB;

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

@@ -394,12 +394,12 @@ describe('OrderClauseTool', function () {
       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);
-      validate(null);
-      validate('foo');
-      validate(['foo']);
+      validate('')();
+      validate(false)();
+      validate(undefined)();
+      validate(null)();
+      validate('foo')();
+      validate(['foo'])();
     });
   });
 

+ 30 - 0
src/filter/slice-clause-tool.d.ts

@@ -0,0 +1,30 @@
+import {ModelData} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Slice clause tool.
+ */
+export declare class SliceClauseTool extends Service {
+  /**
+   * Slice.
+   *
+   * @param entities
+   * @param skip
+   * @param limit
+   */
+  slice(entities: ModelData[], skip?: number, limit?: number): ModelData[];
+
+  /**
+   * Validate skip clause.
+   *
+   * @param skip
+   */
+  static validateSkipClause(skip: number | undefined): void;
+
+  /**
+   * Validate limit clause.
+   *
+   * @param limit
+   */
+  static validateLimitClause(limit: number | undefined): void;
+}

+ 7 - 6
src/filter/slice-clause-tool.js

@@ -8,11 +8,12 @@ export class SliceClauseTool extends Service {
   /**
    * Filter.
    *
-   * @param entities
-   * @param skip
-   * @param limit
+   * @param {object[]} entities
+   * @param {number|undefined} skip
+   * @param {number|undefined} limit
+   * @returns {object[]}
    */
-  slice(entities, skip, limit) {
+  slice(entities, skip = undefined, limit = undefined) {
     if (!Array.isArray(entities))
       throw new InvalidArgumentError(
         'A first argument of SliceClauseTool.slice ' +
@@ -37,7 +38,7 @@ export class SliceClauseTool extends Service {
   /**
    * Validate skip clause.
    *
-   * @param skip
+   * @param {number|undefined} skip
    */
   static validateSkipClause(skip) {
     if (!skip) return;
@@ -51,7 +52,7 @@ export class SliceClauseTool extends Service {
   /**
    * Validate limit clause.
    *
-   * @param limit
+   * @param {number|undefined} limit
    */
   static validateLimitClause(limit) {
     if (!limit) return;

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

@@ -86,12 +86,12 @@ describe('SliceClauseTool', function () {
       expect(validate('str')).to.throw(error('"str"'));
       expect(validate(true)).to.throw(error('true'));
       expect(validate([])).to.throw(error('Array'));
-      validate('');
-      validate(false);
-      validate(undefined);
-      validate(null);
-      validate(10);
-      validate(0);
+      validate('')();
+      validate(false)();
+      validate(undefined)();
+      validate(null)();
+      validate(10)();
+      validate(0)();
     });
   });
 
@@ -106,12 +106,12 @@ describe('SliceClauseTool', function () {
       expect(validate('str')).to.throw(error('"str"'));
       expect(validate(true)).to.throw(error('true'));
       expect(validate([])).to.throw(error('Array'));
-      validate('');
-      validate(false);
-      validate(undefined);
-      validate(null);
-      validate(10);
-      validate(0);
+      validate('')();
+      validate(false)();
+      validate(undefined)();
+      validate(null)();
+      validate(10)();
+      validate(0)();
     });
   });
 });

+ 23 - 0
src/filter/where-clause-tool.d.ts

@@ -0,0 +1,23 @@
+import {ModelData} from '../types';
+import {WhereClause} from './filter';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Where clause tool.
+ */
+export declare class WhereClauseTool extends Service {
+  /**
+   * Filter.
+   *
+   * @param entities
+   * @param where
+   */
+  filter(entities: ModelData[], where: WhereClause | undefined): ModelData[];
+
+  /**
+   * Validate where clause.
+   *
+   * @param clause
+   */
+  static validateWhereClause(clause: WhereClause | undefined): void;
+}

+ 13 - 7
src/filter/where-clause-tool.js

@@ -5,6 +5,8 @@ import {OperatorClauseTool} from './operator-clause-tool.js';
 
 /**
  * Where clause tool.
+ *
+ * @typedef {object|Function} WhereClause
  */
 export class WhereClauseTool extends Service {
   /**
@@ -32,23 +34,26 @@ export class WhereClauseTool extends Service {
    *
    * ```
    *
-   * @param entities
-   * @param where
+   * @param {object[]} entities
+   * @param {WhereClause|undefined} where
+   * @returns {object[]}
    */
-  filter(entities, where = {}) {
+  filter(entities, where = undefined) {
     if (!Array.isArray(entities))
       throw new InvalidArgumentError(
         'A first argument of WhereUtils.filter ' +
           'should be an Array of Objects, but %v given.',
         entities,
       );
+    if (!where) return entities;
     return entities.filter(this._createFilter(where));
   }
 
   /**
    * Create where filter.
    *
-   * @param whereClause
+   * @param {WhereClause} whereClause
+   * @returns {Function}
    */
   _createFilter(whereClause) {
     if (typeof whereClause === 'function') return whereClause;
@@ -117,8 +122,9 @@ export class WhereClauseTool extends Service {
   /**
    * Value testing.
    *
-   * @param example
-   * @param value
+   * @param {*} example
+   * @param {*} value
+   * @returns {boolean}
    */
   _test(example, value) {
     // Test null.
@@ -146,7 +152,7 @@ export class WhereClauseTool extends Service {
   /**
    * Validate where clause.
    *
-   * @param clause
+   * @param {WhereClause|undefined} clause
    */
   static validateWhereClause(clause) {
     if (!clause) return;

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

@@ -235,7 +235,7 @@ describe('WhereClauseTool', function () {
     });
 
     it('throws an error if a first argument is not an Array', function () {
-      const throwable = () => S.filter(10);
+      const throwable = () => S.filter(10, {});
       expect(throwable).to.throw(
         'A first argument of WhereUtils.filter ' +
           'should be an Array of Objects, but 10 given.',
@@ -243,7 +243,7 @@ describe('WhereClauseTool', function () {
     });
 
     it('throws an error if elements of a first argument is not an Object', function () {
-      const throwable = () => S.filter([10]);
+      const throwable = () => S.filter([10], {});
       expect(throwable).to.throw(
         'A first argument of WhereUtils.filter ' +
           'should be an Array of Objects, but 10 given.',
@@ -270,11 +270,11 @@ describe('WhereClauseTool', function () {
       expect(validate(10)).to.throw(error('10'));
       expect(validate(true)).to.throw(error('true'));
       expect(validate([])).to.throw(error('Array'));
-      validate('');
-      validate(false);
-      validate(undefined);
-      validate(null);
-      validate({});
+      validate('')();
+      validate(false)();
+      validate(undefined)();
+      validate(null)();
+      validate({})();
     });
   });
 });

+ 3 - 0
src/index.d.ts

@@ -1,6 +1,9 @@
 export * from './types';
+export * from './utils';
 export * from './schema';
 export * from './filter';
+export * from './errors';
 export * from './adapter';
+export * from './relations';
 export * from './definition';
 export * from './repository';

+ 46 - 0
src/relations/belongs-to-resolver.d.ts

@@ -0,0 +1,46 @@
+import {Filter} from '../filter';
+import {ModelData} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Belongs to resolver.
+ */
+export declare class BelongsToResolver extends Service {
+  /**
+   * Include to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param scope
+   */
+  includeTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey?: string,
+    scope?: Filter,
+  ): Promise<void>;
+
+  /**
+   * Include polymorphic to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param relationName
+   * @param foreignKey
+   * @param discriminator
+   * @param scope
+   */
+  includePolymorphicTo(
+    entities: ModelData[],
+    sourceName: string,
+    relationName: string,
+    foreignKey?: string,
+    discriminator?: string,
+    scope?: Filter,
+  ): Promise<void>;
+}

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

@@ -18,7 +18,7 @@ export class BelongsToResolver extends Service {
    * @param {string} relationName
    * @param {string|undefined} foreignKey
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includeTo(
     entities,
@@ -107,7 +107,7 @@ export class BelongsToResolver extends Service {
    * @param {string|undefined} foreignKey
    * @param {string|undefined} discriminator
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includePolymorphicTo(
     entities,

+ 67 - 0
src/relations/has-many-resolver.d.ts

@@ -0,0 +1,67 @@
+import {Filter} from '../filter';
+import {ModelData} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Has many resolver.
+ */
+export declare class HasManyResolver extends Service {
+  /**
+   * Include to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param scope
+   */
+  includeTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey: string,
+    scope?: Filter,
+  ): Promise<void>;
+
+  /**
+   * Include polymorphic to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param discriminator
+   * @param scope
+   */
+  includePolymorphicTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey: string,
+    discriminator: string,
+    scope?: Filter,
+  ): Promise<void>;
+
+  /**
+   * Include polymorphic by relation name.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param targetRelationName
+   * @param scope
+   */
+  includePolymorphicByRelationName(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    targetRelationName: string,
+    scope?: Filter,
+  ): Promise<void>;
+}

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

@@ -18,7 +18,7 @@ export class HasManyResolver extends Service {
    * @param {string} relationName
    * @param {string} foreignKey
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includeTo(
     entities,
@@ -120,7 +120,7 @@ export class HasManyResolver extends Service {
    * @param {string} foreignKey
    * @param {string} discriminator
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includePolymorphicTo(
     entities,
@@ -231,7 +231,7 @@ export class HasManyResolver extends Service {
    * @param {string} relationName
    * @param {string} targetRelationName
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includePolymorphicByRelationName(
     entities,

+ 67 - 0
src/relations/has-one-resolver.d.ts

@@ -0,0 +1,67 @@
+import {Filter} from '../filter';
+import {ModelData} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * Has one resolver.
+ */
+export declare class HasOneResolver extends Service {
+  /**
+   * Include to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param scope
+   */
+  includeTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey: string,
+    scope?: Filter,
+  ): Promise<void>;
+
+  /**
+   * Include polymorphic to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param discriminator
+   * @param scope
+   */
+  includePolymorphicTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey: string,
+    discriminator: string,
+    scope?: Filter,
+  ): Promise<void>;
+
+  /**
+   * Include polymorphic by relation name.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param targetRelationName
+   * @param scope
+   */
+  includePolymorphicByRelationName(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    targetRelationName: string,
+    scope?: Filter,
+  ): Promise<void>;
+}

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

@@ -18,7 +18,7 @@ export class HasOneResolver extends Service {
    * @param {string} relationName
    * @param {string} foreignKey
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includeTo(
     entities,
@@ -117,7 +117,7 @@ export class HasOneResolver extends Service {
    * @param {string} foreignKey
    * @param {string} discriminator
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includePolymorphicTo(
     entities,
@@ -225,7 +225,7 @@ export class HasOneResolver extends Service {
    * @param {string} relationName
    * @param {string} targetRelationName
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includePolymorphicByRelationName(
     entities,

+ 4 - 0
src/relations/index.d.ts

@@ -0,0 +1,4 @@
+export * from './has-one-resolver';
+export * from './has-many-resolver';
+export * from './belongs-to-resolver';
+export * from './references-many-resolver';

+ 27 - 0
src/relations/references-many-resolver.d.ts

@@ -0,0 +1,27 @@
+import {Filter} from '../filter';
+import {ModelData} from '../types';
+import {Service} from '@e22m4u/service';
+
+/**
+ * References many resolver.
+ */
+export declare class ReferencesManyResolver extends Service {
+  /**
+   * Include to.
+   *
+   * @param entities
+   * @param sourceName
+   * @param targetName
+   * @param relationName
+   * @param foreignKey
+   * @param scope
+   */
+  includeTo(
+    entities: ModelData[],
+    sourceName: string,
+    targetName: string,
+    relationName: string,
+    foreignKey?: string,
+    scope?: Filter,
+  ): Promise<void>;
+}

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

@@ -18,7 +18,7 @@ export class ReferencesManyResolver extends Service {
    * @param {string} relationName
    * @param {string|undefined} foreignKey
    * @param {object|undefined} scope
-   * @return {Promise<void>}
+   * @returns {Promise<void>}
    */
   async includeTo(
     entities,

+ 1 - 0
src/repository/index.d.ts

@@ -1 +1,2 @@
 export * from './repository';
+export * from './repository-registry';

+ 22 - 0
src/repository/repository-registry.d.ts

@@ -0,0 +1,22 @@
+import {Service} from '@e22m4u/service';
+import {Repository} from './repository';
+import {Constructor} from '@e22m4u/service';
+
+/**
+ * Repository registry.
+ */
+export declare class RepositoryRegistry extends Service {
+  /**
+   * Set repository registry.
+   *
+   * @param ctor
+   */
+  setRepositoryCtor(ctor: Constructor<Repository>): void;
+
+  /**
+   * Get repository.
+   *
+   * @param modelName
+   */
+  getRepository(modelName: string): Repository;
+}

+ 5 - 2
src/repository/repository-registry.js

@@ -8,6 +8,8 @@ import {InvalidArgumentError} from '../errors/index.js';
 export class RepositoryRegistry extends Service {
   /**
    * Repositories.
+   *
+   * @type {object}
    */
   _repositories = {};
 
@@ -22,7 +24,7 @@ export class RepositoryRegistry extends Service {
   /**
    * Set repository ctor.
    *
-   * @param ctor
+   * @param {typeof Repository} ctor
    */
   setRepositoryCtor(ctor) {
     if (
@@ -42,7 +44,8 @@ export class RepositoryRegistry extends Service {
   /**
    * Get repository.
    *
-   * @param modelName
+   * @param {string} modelName
+   * @returns {Repository}
    */
   getRepository(modelName) {
     let repository = this._repositories[modelName];

+ 5 - 19
src/repository/repository.d.ts

@@ -26,10 +26,7 @@ export declare class Repository {
    * @param container
    * @param modelName
    */
-  constructor(
-    container: ServiceContainer,
-    modelName: string,
-  );
+  constructor(container: ServiceContainer, modelName: string);
 
   /**
    * Get adapter.
@@ -42,10 +39,7 @@ export declare class Repository {
    * @param data
    * @param filter
    */
-  create(
-    data: ModelData,
-    filter?: ItemFilter,
-  ): Promise<ModelData>;
+  create(data: ModelData, filter?: ItemFilter): Promise<ModelData>;
 
   /**
    * Replace by id.
@@ -66,10 +60,7 @@ export declare class Repository {
    * @param data
    * @param filter
    */
-  replaceOrCreate(
-    data: ModelData,
-    filter?: ItemFilter,
-  ): Promise<ModelData>;
+  replaceOrCreate(data: ModelData, filter?: ItemFilter): Promise<ModelData>;
 
   /**
    * Patch by id.
@@ -96,9 +87,7 @@ export declare class Repository {
    *
    * @param filter
    */
-  findOne(
-    filter?: ItemFilter,
-  ): Promise<ModelData | undefined>;
+  findOne(filter?: ItemFilter): Promise<ModelData | undefined>;
 
   /**
    * Find by id.
@@ -106,10 +95,7 @@ export declare class Repository {
    * @param id
    * @param filter
    */
-  findById(
-    id: Identifier,
-    filter?: ItemFilter,
-  ): Promise<ModelData>;
+  findById(id: Identifier, filter?: ItemFilter): Promise<ModelData>;
 
   /**
    * Delete.

+ 15 - 14
src/repository/repository.js

@@ -1,4 +1,5 @@
 import {Service} from '@e22m4u/service';
+import {Adapter} from '../adapter/index.js';
 import {AdapterRegistry} from '../adapter/index.js';
 import {InvalidArgumentError} from '../errors/index.js';
 import {DefinitionRegistry} from '../definition/index.js';
@@ -18,7 +19,7 @@ export class Repository extends Service {
   /**
    * Model name.
    *
-   * @return {string}
+   * @returns {string}
    */
   get modelName() {
     return this._modelName;
@@ -34,7 +35,7 @@ export class Repository extends Service {
   /**
    * Datasource name.
    *
-   * @return {string}
+   * @returns {string}
    */
   get datasourceName() {
     return this._datasourceName;
@@ -63,7 +64,7 @@ export class Repository extends Service {
   /**
    * Get adapter.
    *
-   * @return {Adapter}
+   * @returns {Adapter}
    */
   async getAdapter() {
     return this.getService(AdapterRegistry).getAdapter(this.datasourceName);
@@ -74,7 +75,7 @@ export class Repository extends Service {
    *
    * @param {object} data
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   async create(data, filter = undefined) {
     const adapter = await this.getAdapter();
@@ -87,7 +88,7 @@ export class Repository extends Service {
    * @param {number|string} id
    * @param {object} data
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   async replaceById(id, data, filter = undefined) {
     const adapter = await this.getAdapter();
@@ -99,7 +100,7 @@ export class Repository extends Service {
    *
    * @param {object} data
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   async replaceOrCreate(data, filter = undefined) {
     const pkPropName = this.getService(
@@ -116,7 +117,7 @@ export class Repository extends Service {
    * @param {number|string} id
    * @param {object} data
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   async patchById(id, data, filter = undefined) {
     const adapter = await this.getAdapter();
@@ -127,7 +128,7 @@ export class Repository extends Service {
    * Find.
    *
    * @param {object|undefined} filter
-   * @return {Promise<object[]>}
+   * @returns {Promise<object[]>}
    */
   async find(filter = undefined) {
     const adapter = await this.getAdapter();
@@ -138,7 +139,7 @@ export class Repository extends Service {
    * Find one.
    *
    * @param {object|undefined} filter
-   * @return {Promise<object|undefined>}
+   * @returns {Promise<object|undefined>}
    */
   async findOne(filter = undefined) {
     const adapter = await this.getAdapter();
@@ -153,7 +154,7 @@ export class Repository extends Service {
    *
    * @param {number|string} id
    * @param {object|undefined} filter
-   * @return {Promise<object>}
+   * @returns {Promise<object>}
    */
   async findById(id, filter = undefined) {
     const adapter = await this.getAdapter();
@@ -164,7 +165,7 @@ export class Repository extends Service {
    * Delete.
    *
    * @param {object|undefined} where
-   * @return {Promise<number>}
+   * @returns {Promise<number>}
    */
   async delete(where = undefined) {
     const adapter = await this.getAdapter();
@@ -175,7 +176,7 @@ export class Repository extends Service {
    * Delete by id.
    *
    * @param {number|string} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   async deleteById(id) {
     const adapter = await this.getAdapter();
@@ -186,7 +187,7 @@ export class Repository extends Service {
    * Exists.
    *
    * @param {number|string} id
-   * @return {Promise<boolean>}
+   * @returns {Promise<boolean>}
    */
   async exists(id) {
     const adapter = await this.getAdapter();
@@ -197,7 +198,7 @@ export class Repository extends Service {
    * Count.
    *
    * @param {object|undefined} where
-   * @return {Promise<number>}
+   * @returns {Promise<number>}
    */
   async count(where = undefined) {
     const adapter = await this.getAdapter();

+ 5 - 1
src/schema.js

@@ -1,4 +1,5 @@
 import {Service} from '@e22m4u/service';
+import {Repository} from './repository/index.js';
 import {DefinitionRegistry} from './definition/index.js';
 import {RepositoryRegistry} from './repository/index.js';
 
@@ -10,6 +11,7 @@ export class Schema extends Service {
    * Define datasource.
    *
    * @param {object} datasourceDef
+   * @returns {this}
    */
   defineDatasource(datasourceDef) {
     this.getService(DefinitionRegistry).addDatasource(datasourceDef);
@@ -20,6 +22,7 @@ export class Schema extends Service {
    * Define model.
    *
    * @param {object} modelDef
+   * @returns {this}
    */
   defineModel(modelDef) {
     this.getService(DefinitionRegistry).addModel(modelDef);
@@ -29,7 +32,8 @@ export class Schema extends Service {
   /**
    * Get repository.
    *
-   * @param {Repository} modelName
+   * @param {string} modelName
+   * @returns {Repository}
    */
   getRepository(modelName) {
     return this.getService(RepositoryRegistry).getRepository(modelName);

+ 4 - 4
src/types.d.ts

@@ -2,15 +2,15 @@
  * Any object.
  */
 export declare type AnyObject = {
-  [property: string]: unknown,
-}
+  [property: string]: unknown;
+};
 
 /**
  * Model data.
  */
 export declare type ModelData = {
-  [property: string]: unknown
-}
+  [property: string]: unknown;
+};
 
 /**
  * Identifier.

+ 6 - 0
src/utils/capitalize.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Capitalize.
+ *
+ * @param string
+ */
+export declare function capitalize(string: string): string;

+ 1 - 1
src/utils/capitalize.js

@@ -2,7 +2,7 @@
  * Capitalize.
  *
  * @param {string} string
- * @return {string}
+ * @returns {string}
  */
 export function capitalize(string) {
   if (!string || typeof string !== 'string') return string;

+ 6 - 0
src/utils/clone-deep.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Clone deep.
+ *
+ * @param value
+ */
+export declare function cloneDeep<T>(value: T): T;

+ 2 - 1
src/utils/clone-deep.js

@@ -2,7 +2,8 @@
  * Clone deep.
  *
  * @author https://stackoverflow.com/a/4460624
- * @param value
+ * @param {*} value
+ * @returns {*}
  */
 export function cloneDeep(value) {
   if (!value) return value; // null, undefined values check

+ 10 - 0
src/utils/exclude-object-keys.d.ts

@@ -0,0 +1,10 @@
+/**
+ * Exclude object keys.
+ *
+ * @param obj
+ * @param keys
+ */
+export declare function excludeObjectKeys<T extends object>(
+  obj: T,
+  keys: string | string[],
+): Partial<T>;

+ 3 - 2
src/utils/exclude-object-keys.js

@@ -3,8 +3,9 @@ import {InvalidArgumentError} from '../errors/index.js';
 /**
  * Exclude object keys.
  *
- * @param obj
- * @param keys
+ * @param {object} obj
+ * @param {string|string[]} keys
+ * @returns {object}
  */
 export function excludeObjectKeys(obj, keys) {
   if (typeof obj !== 'object' || !obj || Array.isArray(obj))

+ 6 - 0
src/utils/get-ctor-name.d.ts

@@ -0,0 +1,6 @@
+/**
+ * Get ctor name.
+ *
+ * @param value
+ */
+export declare function getCtorName(value: unknown): string | undefined;

+ 2 - 1
src/utils/get-ctor-name.js

@@ -1,7 +1,8 @@
 /**
  * Get ctor name.
  *
- * @param value
+ * @param {*} value
+ * @returns {string|undefined}
  */
 export function getCtorName(value) {
   if (value === null) return 'Null';

+ 12 - 0
src/utils/get-value-by-path.d.ts

@@ -0,0 +1,12 @@
+/**
+ * Get value by path.
+ *
+ * @param obj
+ * @param path
+ * @param orElse
+ */
+export declare function getValueByPath(
+  obj: object,
+  path: string,
+  orElse?: unknown,
+): unknown;

+ 4 - 3
src/utils/get-value-by-path.js

@@ -1,9 +1,10 @@
 /**
  * Get value by path.
  *
- * @param obj
- * @param path
- * @param orElse
+ * @param {object} obj
+ * @param {string} path
+ * @param {*} orElse
+ * @returns {*}
  */
 export function getValueByPath(obj, path, orElse = undefined) {
   if (!obj || typeof obj !== 'object') return orElse;

+ 10 - 0
src/utils/index.d.ts

@@ -0,0 +1,10 @@
+export * from './is-ctor';
+export * from './capitalize';
+export * from './clone-deep';
+export * from './singularize';
+export * from './get-ctor-name';
+export * from './is-pure-object';
+export * from './string-to-regexp';
+export * from './get-value-by-path';
+export * from './select-object-keys';
+export * from './exclude-object-keys';

+ 7 - 0
src/utils/is-ctor.d.ts

@@ -0,0 +1,7 @@
+/**
+ * Is ctor.
+ *
+ * @param {*} value
+ * @returns {boolean}
+ */
+export declare function isCtor(value: unknown): boolean;

Некоторые файлы не были показаны из-за большого количества измененных файлов