Browse Source

chore: adds transformers and validators refactoring

e22m4u 1 year ago
parent
commit
d08ad7daca
100 changed files with 180 additions and 4 deletions
  1. 1 1
      docs/assets/navigation.js
  2. 0 0
      docs/assets/search.js
  3. 0 0
      docs/classes/Adapter.html
  4. 0 0
      docs/classes/AdapterLoader.html
  5. 0 0
      docs/classes/AdapterRegistry.html
  6. 0 0
      docs/classes/BelongsToResolver.html
  7. 0 0
      docs/classes/DatasourceDefinitionValidator.html
  8. 0 0
      docs/classes/DefinitionRegistry.html
  9. 0 0
      docs/classes/FieldsClauseTool.html
  10. 0 0
      docs/classes/HasManyResolver.html
  11. 0 0
      docs/classes/HasOneResolver.html
  12. 0 0
      docs/classes/IncludeClauseTool.html
  13. 0 0
      docs/classes/InvalidArgumentError.html
  14. 0 0
      docs/classes/InvalidOperatorValueError.html
  15. 0 0
      docs/classes/ModelDataSanitizer.html
  16. 0 0
      docs/classes/ModelDataTransformer.html
  17. 0 0
      docs/classes/ModelDataValidator.html
  18. 0 0
      docs/classes/ModelDefinitionUtils.html
  19. 0 0
      docs/classes/ModelDefinitionValidator.html
  20. 0 0
      docs/classes/NotImplementedError.html
  21. 0 0
      docs/classes/OperatorClauseTool.html
  22. 0 0
      docs/classes/OrderClauseTool.html
  23. 0 0
      docs/classes/PrimaryKeysDefinitionValidator.html
  24. 0 0
      docs/classes/PropertiesDefinitionValidator.html
  25. 0 0
      docs/classes/PropertyTransformerRegistry.html
  26. 0 0
      docs/classes/PropertyValidatorRegistry.html
  27. 0 0
      docs/classes/ReferencesManyResolver.html
  28. 0 0
      docs/classes/RelationsDefinitionValidator.html
  29. 0 0
      docs/classes/Repository.html
  30. 0 0
      docs/classes/RepositoryRegistry.html
  31. 0 0
      docs/classes/Schema.html
  32. 0 0
      docs/classes/SliceClauseTool.html
  33. 0 0
      docs/classes/WhereClauseTool.html
  34. 0 0
      docs/enums/DataType.html
  35. 0 0
      docs/enums/DecoratorTargetType.html
  36. 0 0
      docs/enums/RelationType.html
  37. 0 0
      docs/functions/capitalize.html
  38. 0 0
      docs/functions/cloneDeep.html
  39. 0 0
      docs/functions/excludeObjectKeys.html
  40. 0 0
      docs/functions/getCtorName.html
  41. 0 0
      docs/functions/getDecoratorTargetType.html
  42. 0 0
      docs/functions/getValueByPath.html
  43. 0 0
      docs/functions/isCtor.html
  44. 0 0
      docs/functions/isPureObject.html
  45. 0 0
      docs/functions/selectObjectKeys.html
  46. 0 0
      docs/functions/singularize.html
  47. 0 0
      docs/functions/stringToRegexp.html
  48. 0 0
      docs/index.html
  49. 0 0
      docs/interfaces/AndClause.html
  50. 0 0
      docs/interfaces/Constructor.html
  51. 0 0
      docs/interfaces/OrClause.html
  52. 5 0
      docs/modules.html
  53. 0 0
      docs/types/AnyObject.html
  54. 0 0
      docs/types/BelongsToDefinition.html
  55. 0 0
      docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html
  56. 0 0
      docs/types/DatasourceDefinition.html
  57. 0 0
      docs/types/FieldsClause.html
  58. 0 0
      docs/types/FilterClause.html
  59. 0 0
      docs/types/Flatten.html
  60. 0 0
      docs/types/FullPropertyDefinition.html
  61. 0 0
      docs/types/HasManyDefinition.html
  62. 0 0
      docs/types/HasOneDefinition.html
  63. 0 0
      docs/types/Identity.html
  64. 0 0
      docs/types/IncludeClause.html
  65. 0 0
      docs/types/ItemFilterClause.html
  66. 0 0
      docs/types/ModelData.html
  67. 0 0
      docs/types/ModelDefinition.html
  68. 0 0
      docs/types/ModelId.html
  69. 0 0
      docs/types/NestedIncludeClause.html
  70. 0 0
      docs/types/NormalizedFieldsClause.html
  71. 0 0
      docs/types/NormalizedIncludeClause.html
  72. 0 0
      docs/types/OperatorClause.html
  73. 0 0
      docs/types/OptionalUnlessRequiredId.html
  74. 0 0
      docs/types/OrderClause.html
  75. 0 0
      docs/types/PartialBy.html
  76. 0 0
      docs/types/PartialWithoutId.html
  77. 0 0
      docs/types/PolyBelongsToDefinition.html
  78. 0 0
      docs/types/PolyHasManyDefinitionWithTargetKeys.html
  79. 0 0
      docs/types/PolyHasManyDefinitionWithTargetRelationName.html
  80. 0 0
      docs/types/PolyHasOneDefinitionWithTargetKeys.html
  81. 0 0
      docs/types/PolyHasOneDefinitionWithTargetRelationName.html
  82. 0 0
      docs/types/PropertiesClause.html
  83. 0 0
      docs/types/PropertyDefinition.html
  84. 0 0
      docs/types/PropertyDefinitionMap.html
  85. 0 0
      docs/types/PropertyTransformOptions.html
  86. 0 0
      docs/types/PropertyTransformer.html
  87. 0 0
      docs/types/PropertyTransformerContext.html
  88. 0 0
      docs/types/PropertyValidateOptions.html
  89. 0 0
      docs/types/PropertyValidator.html
  90. 0 0
      docs/types/PropertyValidatorContext.html
  91. 0 0
      docs/types/ReferencesManyDefinition.html
  92. 0 0
      docs/types/RelationDefinition.html
  93. 0 0
      docs/types/RelationDefinitionMap.html
  94. 0 0
      docs/types/WhereClause.html
  95. 0 0
      docs/types/WithoutId.html
  96. 2 0
      src/adapter/adapter.js
  97. 9 3
      src/adapter/adapter.spec.js
  98. 14 0
      src/adapter/decorator/data-transformation-decorator.d.ts
  99. 54 0
      src/adapter/decorator/data-transformation-decorator.js
  100. 95 0
      src/adapter/decorator/data-transformation-decorator.spec.js

+ 1 - 1
docs/assets/navigation.js

@@ -1 +1 @@
-window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA6WZ227bOBCG30XXwWYbtN3d3DmOixqtY0N1WgRFEbDSxGZLkVqSKqIu9t0LWZZF8TCk0Vv9/3w8DA9D+/N/mYZnnV1nt0STbVtDdpHVRO+z6wx4U6nL4fsfe12x7CL7TnmZXf/9/8UYCYWQRAu5JXIH2gtxLWFeDoxoKrgPZGphwqwktQY5BheMKAXq8ihMI19ceWLfC1IihF5O4OSwo0rLNkgaDBjrBpjgO7UVOSjBfvj65VgwXpdTJRpZwC08UU67Gf1IGC27FLls1I62c7KHp8H1YMQ3FFip5ow0CrZCMJdnOzDaW6JWhLfhWbUMEdaaA4oydIy05AVrSsAG6Vhw3o8uWTO5ayrgeiGlL8k+VwJ1XcNhY38krAEc7Vox/kqUwLqV94F0y+Onb05dTxIRWequJ048LeB7TZkKMaeuM6jR3p63J++EXlY1gy7JUAYy5jFhzCGz2JJ1PShRloDjpgaMtZG0IrJ9B61KmlXcj7ckapCaQmpDiD2hnfZkDh+vQSvGz+EJJPACIsej34eT+/s7bYIwN95KLRTVwjcho5ZGCE+t68GIH4o9VMSl9N/RSEYL9DawDBjr0x4kyrIMaIXDy944UijXIJ9I0ZU3gzpFXL16bSDmgistm2KSfQNi6BhmLZGODCIGmPF2/fUbFHok6LY+jOIoWNF//vPXi1dXvhJtXKo2y2OJUW8Xb2b377ePm3y5muUPj+8WD4+bfL1Z5NuHx7vZamG3EQ2Ituip9ZxGPJ4Y1yzLbJ6pxTlMg5PugTNqUQ4jWoMztOPnaHTD2HCyhufJ74qxjzVnGOsYEohrjuTT1mO8ZQlcU93anOF7NN6sXh2IKUZJGipsRdh6jHcq/2zQSUgjBKfakpNoy9JLWZax6DtQGkp0tj2WKFXIijD6E0psT/td6Wy8135bjD4tQW3oVI2zuvwRds8ZKJXDvw2VULqpCvmi/LG+dZCjFKNsiNSUsBtnq56ERMInqvei0e74bD3KE6xNuCsDthS6czx2fet/d+pKel9LkZDfbHWoYu9I5eTyjNDEXkxO8qShIxG/12bCwBMio304vaL828XWE3nIBXz+ne5GrEgdx65InUo+vougP2/cVPttZ9LNKt3Ldcr0OHEu+EGKgY++GH/6JA3nMOSL8/uViZFtx/lMz+rwmmJk4zVn8wwpSgkd/smnfkFqqg839oh4anhxWISXozrlvH5pIpjozgqovYRBRADwfCgV+ufc9DgcQY4JAe5Az7WQ09NtRBkyDkH/P5nwon+j2OjDT6037aZj+ZGGA0FRNZ9s/hHRK2joppFgv65NwKgjGAUMCo0nz/ZgOMp3DSMysCINGYNoSfmu+8tlB8/edTl1OKgvvwBP4V6kfxsAAA=="
+window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA6WZXW/bNhSG/4uug2UN2m7LneO4mNE6NlSnRTAMAScd22wpUiOpIuqw/17IsiyKH4c0eqv3Pc+h+Hko/fVfpuFFZ7fZPdFk29aQXWU10YfsNgPeVOp6eP7LQVcsu8q+Ul5mt7//fzVGQiEk0UJuidyD9kJcS5iXAyOaCu4DmVqYMCtJrUGOwQUjSoG6PgnTyFc3ntgPgpQIoZcTODnsqdKyDZIGA8a6Ayb4Xm1FDkqwb752ORaM142pEo0s4B52lNOuRz8RRstuiFw2akfznO3hbnA9GPEdBVaqOSONgq0QzOXZDoz2J1Erwttwr1qGCGvNAUUZOkZa8oI1JWAv6Vhw3rdusGZy31TA9UJK3yD7XAnUdQ3Hhf2JsAZwtGvF+CtRAutm3kfSTY/vvj51PUnErSRc7YSsUKbhSqIiC8j1xInnZfGoKVMh5tR1ATXa2stW+oPQy6pm0E0dKAPzwGPCmMN8wRaC60GJsgQcNzVgrI2kFZHte2hVUq/ifjyTqEFqCqmJEHtCntaY+OFtGzGn5Dg3KJ7BsWL8HHYggRcQ2dj9PpzcVx5pg4C58Sy1UFQLX4eMWhoh3LWuByN+LA5QEZfSP0cjGS3Qc8wyYKzPB5AoyzKgtRkve+NIoVyD3JGiK8wGdYq4efPWQMwFV1o2xWT0DYihY5i1RBoyiBhgxtv1P1+g0CNBt/XxLU6CFf3rH7+9enPjKy7HqWqzPJYY9X7xbvb4Yfu8yZerWf70/H7x9LzJ15tFvn16fpitFnaOaEA0o6dKdZJ4PDGuWVDaPFOLc5gGZ7gHzqhFOYxoDc6rnR5HoxvGhp013E9+V4x9qpbDWMeQQFxzZDxtPcZblsA11a3NGZ5H482624GYYpSkocJmhK3HeOcS0wadhTRCsKstOYm2LL2UZRmLfgCloUR722OJUoWsCKPfocTWtN+VzsZb7bfF6NMy14ZO1TirGz/CHjkDpXL4t6ESSneoQr4of6yhHeQoxSgbIjUl7M5ZqmchkfCZ6oNotPt+th7lCdYmnJUBWwrd2R67tvVfzLprgy9TJOQnsw5V7AOpnLG8IDSxFZOdPOnVkYify5nw4gmR0Tacb2r+5WLriTzkAL78THcjVqSOY1ekTiWfb5D9huOOdcB3Md+8BwbQ9hUwiToX/CjG4Sdnao7TjREiHWPZLqSLYK8ELqwJxEiP2L4Yf3pZD8/ukC/O79csRrYdlzM968ZripGNe67NM6QoJXQsJp+HBampPtYyI2LX8OI4Ca9Hdcp5+9pEMNHtolB7CYOIAODlWET1F93pQTGCHBMC3IOeayGn+/6IMmQcgv4Tm/Civ8Zs9PHz+V276Vh+pOFAUFTNJ4t/RPQKGrppJNjfHUzAqCMYBQwKjQ+e7cFwlO8bRmRgRhoyBtGS8n33G20PL955OXU4qL9/AFRJeBBTHQAA"

File diff suppressed because it is too large
+ 0 - 0
docs/assets/search.js


File diff suppressed because it is too large
+ 0 - 0
docs/classes/Adapter.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/AdapterLoader.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/AdapterRegistry.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/BelongsToResolver.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/DatasourceDefinitionValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/DefinitionRegistry.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/FieldsClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/HasManyResolver.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/HasOneResolver.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/IncludeClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/InvalidArgumentError.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/InvalidOperatorValueError.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ModelDataSanitizer.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ModelDataTransformer.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ModelDataValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ModelDefinitionUtils.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ModelDefinitionValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/NotImplementedError.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/OperatorClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/OrderClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/PrimaryKeysDefinitionValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/PropertiesDefinitionValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/PropertyTransformerRegistry.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/PropertyValidatorRegistry.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/ReferencesManyResolver.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/RelationsDefinitionValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/Repository.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/RepositoryRegistry.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/Schema.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/SliceClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/classes/WhereClauseTool.html


File diff suppressed because it is too large
+ 0 - 0
docs/enums/DataType.html


File diff suppressed because it is too large
+ 0 - 0
docs/enums/DecoratorTargetType.html


File diff suppressed because it is too large
+ 0 - 0
docs/enums/RelationType.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/capitalize.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/cloneDeep.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/excludeObjectKeys.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/getCtorName.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/getDecoratorTargetType.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/getValueByPath.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/isCtor.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/isPureObject.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/selectObjectKeys.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/singularize.html


File diff suppressed because it is too large
+ 0 - 0
docs/functions/stringToRegexp.html


File diff suppressed because it is too large
+ 0 - 0
docs/index.html


File diff suppressed because it is too large
+ 0 - 0
docs/interfaces/AndClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/interfaces/Constructor.html


File diff suppressed because it is too large
+ 0 - 0
docs/interfaces/OrClause.html


File diff suppressed because it is too large
+ 5 - 0
docs/modules.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/AnyObject.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/BelongsToDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/DatasourceDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/FieldsClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/FilterClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/Flatten.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/FullPropertyDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/HasManyDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/HasOneDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/Identity.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/IncludeClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/ItemFilterClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/ModelData.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/ModelDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/ModelId.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/NestedIncludeClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/NormalizedFieldsClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/NormalizedIncludeClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/OperatorClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/OptionalUnlessRequiredId.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/OrderClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PartialBy.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PartialWithoutId.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PolyBelongsToDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PolyHasManyDefinitionWithTargetKeys.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PolyHasManyDefinitionWithTargetRelationName.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PolyHasOneDefinitionWithTargetKeys.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PolyHasOneDefinitionWithTargetRelationName.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertiesClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyDefinitionMap.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyTransformOptions.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyTransformer.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyTransformerContext.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyValidateOptions.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyValidator.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/PropertyValidatorContext.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/ReferencesManyDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/RelationDefinition.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/RelationDefinitionMap.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/WhereClause.html


File diff suppressed because it is too large
+ 0 - 0
docs/types/WithoutId.html


+ 2 - 0
src/adapter/adapter.js

@@ -7,6 +7,7 @@ import {DefaultValuesDecorator} from './decorator/index.js';
 import {DataValidationDecorator} from './decorator/index.js';
 import {DataSanitizingDecorator} from './decorator/index.js';
 import {FieldsFilteringDecorator} from './decorator/index.js';
+import {DataTransformationDecorator} from './decorator/index.js';
 
 /**
  * Adapter.
@@ -41,6 +42,7 @@ export class Adapter extends Service {
     if (this.constructor !== Adapter) {
       this.getService(DataSanitizingDecorator).decorate(this);
       this.getService(DefaultValuesDecorator).decorate(this);
+      this.getService(DataTransformationDecorator).decorate(this);
       this.getService(DataValidationDecorator).decorate(this);
       this.getService(FieldsFilteringDecorator).decorate(this);
       this.getService(InclusionDecorator).decorate(this);

+ 9 - 3
src/adapter/adapter.spec.js

@@ -9,6 +9,7 @@ import {DefaultValuesDecorator} from './decorator/index.js';
 import {DataValidationDecorator} from './decorator/index.js';
 import {DataSanitizingDecorator} from './decorator/index.js';
 import {FieldsFilteringDecorator} from './decorator/index.js';
+import {DataTransformationDecorator} from './decorator/index.js';
 
 const sandbox = chai.spy.sandbox();
 
@@ -35,9 +36,10 @@ describe('Adapter', function () {
       const schema = new Schema();
       const dec1 = schema.getService(DataSanitizingDecorator);
       const dec2 = schema.getService(DefaultValuesDecorator);
-      const dec3 = schema.getService(DataValidationDecorator);
-      const dec4 = schema.getService(FieldsFilteringDecorator);
-      const dec5 = schema.getService(InclusionDecorator);
+      const dec3 = schema.getService(DataTransformationDecorator);
+      const dec4 = schema.getService(DataValidationDecorator);
+      const dec5 = schema.getService(FieldsFilteringDecorator);
+      const dec6 = schema.getService(InclusionDecorator);
       const order = [];
       const decorate = function (ctx) {
         expect(ctx).to.be.instanceof(Adapter);
@@ -48,6 +50,7 @@ describe('Adapter', function () {
       sandbox.on(dec3, 'decorate', decorate);
       sandbox.on(dec4, 'decorate', decorate);
       sandbox.on(dec5, 'decorate', decorate);
+      sandbox.on(dec6, 'decorate', decorate);
       new Adapter(schema.container);
       expect(order).to.be.empty;
       expect(dec1.decorate).to.be.not.called;
@@ -55,6 +58,7 @@ describe('Adapter', function () {
       expect(dec3.decorate).to.be.not.called;
       expect(dec4.decorate).to.be.not.called;
       expect(dec5.decorate).to.be.not.called;
+      expect(dec6.decorate).to.be.not.called;
       class ExtendedAdapter extends Adapter {}
       new ExtendedAdapter(schema.container);
       expect(order[0]).to.be.eql(dec1);
@@ -62,11 +66,13 @@ describe('Adapter', function () {
       expect(order[2]).to.be.eql(dec3);
       expect(order[3]).to.be.eql(dec4);
       expect(order[4]).to.be.eql(dec5);
+      expect(order[5]).to.be.eql(dec6);
       expect(dec1.decorate).to.be.called.once;
       expect(dec2.decorate).to.be.called.once;
       expect(dec3.decorate).to.be.called.once;
       expect(dec4.decorate).to.be.called.once;
       expect(dec5.decorate).to.be.called.once;
+      expect(dec6.decorate).to.be.called.once;
     });
   });
 

+ 14 - 0
src/adapter/decorator/data-transformation-decorator.d.ts

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

+ 54 - 0
src/adapter/decorator/data-transformation-decorator.js

@@ -0,0 +1,54 @@
+import {Adapter} from '../adapter.js';
+import {Service} from '@e22m4u/js-service';
+import {InvalidArgumentError} from '../../errors/index.js';
+import {ModelDataTransformer} from '../../definition/index.js';
+
+/**
+ * Data transformation decorator.
+ */
+export class DataTransformationDecorator extends Service {
+  /**
+   * Decorate.
+   *
+   * @param {Adapter} adapter
+   */
+  decorate(adapter) {
+    if (!adapter || !(adapter instanceof Adapter))
+      throw new InvalidArgumentError(
+        'The first argument of DataTransformerDecorator.decorate should be ' +
+          'an Adapter instance, but %v given.',
+        adapter,
+      );
+    const transformer = this.getService(ModelDataTransformer);
+
+    const create = adapter.create;
+    adapter.create = function (modelName, modelData, filter) {
+      modelData = transformer.transform(modelName, modelData);
+      return create.call(this, modelName, modelData, filter);
+    };
+
+    const replaceById = adapter.replaceById;
+    adapter.replaceById = function (modelName, id, modelData, filter) {
+      modelData = transformer.transform(modelName, modelData);
+      return replaceById.call(this, modelName, id, modelData, filter);
+    };
+
+    const replaceOrCreate = adapter.replaceOrCreate;
+    adapter.replaceOrCreate = function (modelName, modelData, filter) {
+      modelData = transformer.transform(modelName, modelData);
+      return replaceOrCreate.call(this, modelName, modelData, filter);
+    };
+
+    const patch = adapter.patch;
+    adapter.patch = function (modelName, modelData, where) {
+      modelData = transformer.transform(modelName, modelData, true);
+      return patch.call(this, modelName, modelData, where);
+    };
+
+    const patchById = adapter.patchById;
+    adapter.patchById = function (modelName, id, modelData, filter) {
+      modelData = transformer.transform(modelName, modelData, true);
+      return patchById.call(this, modelName, id, modelData, filter);
+    };
+  }
+}

+ 95 - 0
src/adapter/decorator/data-transformation-decorator.spec.js

@@ -0,0 +1,95 @@
+import chai from 'chai';
+import {expect} from 'chai';
+import {Adapter} from '../adapter.js';
+import {Schema} from '../../schema.js';
+import {ModelDataTransformer} from '../../definition/index.js';
+
+const S = new Schema();
+S.defineModel({name: 'model'});
+
+class TestAdapter extends Adapter {
+  // eslint-disable-next-line no-unused-vars
+  create(modelName, modelData, filter = undefined) {
+    return Promise.resolve(modelData);
+  }
+
+  // eslint-disable-next-line no-unused-vars
+  replaceById(modelName, id, modelData, filter = undefined) {
+    return Promise.resolve(modelData);
+  }
+
+  // eslint-disable-next-line no-unused-vars
+  replaceOrCreate(modelName, modelData, filter = undefined) {
+    return Promise.resolve(modelData);
+  }
+
+  // eslint-disable-next-line no-unused-vars
+  patch(modelName, modelData, where = undefined) {
+    return Promise.resolve(modelData);
+  }
+
+  // eslint-disable-next-line no-unused-vars
+  patchById(modelName, id, modelData, filter = undefined) {
+    return Promise.resolve(modelData);
+  }
+}
+
+const A = S.getService(TestAdapter);
+const V = S.getService(ModelDataTransformer);
+const sandbox = chai.spy.sandbox();
+
+describe('DataTransformationDecorator', function () {
+  afterEach(function () {
+    sandbox.restore();
+  });
+
+  it('overrides the "create" method and transforms a given data', async function () {
+    const modelData = {kind: 'modelData'};
+    const transformedData = {kind: 'transformedData'};
+    sandbox.on(V, 'transform', () => transformedData);
+    const res = await A.create('model', modelData);
+    expect(res).to.be.eql(transformedData);
+    expect(V.transform).to.be.called.once;
+    expect(V.transform).to.be.called.with.exactly('model', modelData);
+  });
+
+  it('overrides the "replaceById" method and transforms a given data', async function () {
+    const modelData = {kind: 'modelData'};
+    const transformedData = {kind: 'transformedData'};
+    sandbox.on(V, 'transform', () => transformedData);
+    const res = await A.replaceById('model', 1, modelData);
+    expect(res).to.be.eql(transformedData);
+    expect(V.transform).to.be.called.once;
+    expect(V.transform).to.be.called.with.exactly('model', modelData);
+  });
+
+  it('overrides the "replaceOrCreate" method and transforms a given data', async function () {
+    const modelData = {kind: 'modelData'};
+    const transformedData = {kind: 'transformedData'};
+    sandbox.on(V, 'transform', () => transformedData);
+    const res = await A.replaceOrCreate('model', modelData);
+    expect(res).to.be.eql(transformedData);
+    expect(V.transform).to.be.called.once;
+    expect(V.transform).to.be.called.with.exactly('model', modelData);
+  });
+
+  it('overrides the "patch" method and transforms a given data', async function () {
+    const modelData = {kind: 'modelData'};
+    const transformedData = {kind: 'transformedData'};
+    sandbox.on(V, 'transform', () => transformedData);
+    const res = await A.patch('model', modelData);
+    expect(res).to.be.eql(transformedData);
+    expect(V.transform).to.be.called.once;
+    expect(V.transform).to.be.called.with.exactly('model', modelData, true);
+  });
+
+  it('overrides the "patchById" method and transforms a given data', async function () {
+    const modelData = {kind: 'modelData'};
+    const transformedData = {kind: 'transformedData'};
+    sandbox.on(V, 'transform', () => transformedData);
+    const res = await A.patchById('model', 1, modelData);
+    expect(res).to.be.eql(transformedData);
+    expect(V.transform).to.be.called.once;
+    expect(V.transform).to.be.called.with.exactly('model', modelData, true);
+  });
+});

Some files were not shown because too many files changed in this diff