@e22m4u/js-repository 0.0.42 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.eslintignore +1 -0
  2. package/.husky/pre-commit +1 -0
  3. package/README.md +515 -577
  4. package/docs/.nojekyll +1 -0
  5. package/docs/assets/highlight.css +99 -0
  6. package/docs/assets/main.js +59 -0
  7. package/docs/assets/navigation.js +1 -0
  8. package/docs/assets/search.js +1 -0
  9. package/docs/assets/style.css +1394 -0
  10. package/docs/classes/Adapter.html +38 -0
  11. package/docs/classes/AdapterLoader.html +16 -0
  12. package/docs/classes/AdapterRegistry.html +16 -0
  13. package/docs/classes/BelongsToResolver.html +18 -0
  14. package/docs/classes/DatasourceDefinitionValidator.html +16 -0
  15. package/docs/classes/DefinitionRegistry.html +26 -0
  16. package/docs/classes/FieldsClauseTool.html +20 -0
  17. package/docs/classes/HasManyResolver.html +20 -0
  18. package/docs/classes/HasOneResolver.html +20 -0
  19. package/docs/classes/IncludeClauseTool.html +24 -0
  20. package/docs/classes/InvalidArgumentError.html +14 -0
  21. package/docs/classes/InvalidOperatorValueError.html +14 -0
  22. package/docs/classes/ModelDataSanitizer.html +16 -0
  23. package/docs/classes/ModelDataValidator.html +18 -0
  24. package/docs/classes/ModelDefinitionUtils.html +46 -0
  25. package/docs/classes/ModelDefinitionValidator.html +16 -0
  26. package/docs/classes/NotImplementedError.html +14 -0
  27. package/docs/classes/OperatorClauseTool.html +72 -0
  28. package/docs/classes/OrderClauseTool.html +20 -0
  29. package/docs/classes/PrimaryKeysDefinitionValidator.html +16 -0
  30. package/docs/classes/PropertiesDefinitionValidator.html +16 -0
  31. package/docs/classes/ReferencesManyResolver.html +16 -0
  32. package/docs/classes/RelationsDefinitionValidator.html +16 -0
  33. package/docs/classes/Repository.html +44 -0
  34. package/docs/classes/RepositoryRegistry.html +18 -0
  35. package/docs/classes/Schema.html +20 -0
  36. package/docs/classes/SliceClauseTool.html +20 -0
  37. package/docs/classes/WhereClauseTool.html +18 -0
  38. package/docs/enums/DataType.html +8 -0
  39. package/docs/enums/RelationType.html +6 -0
  40. package/docs/functions/capitalize.html +2 -0
  41. package/docs/functions/cloneDeep.html +2 -0
  42. package/docs/functions/excludeObjectKeys.html +2 -0
  43. package/docs/functions/getCtorName.html +2 -0
  44. package/docs/functions/getValueByPath.html +2 -0
  45. package/docs/functions/isCtor.html +2 -0
  46. package/docs/functions/isPureObject.html +2 -0
  47. package/docs/functions/selectObjectKeys.html +2 -0
  48. package/docs/functions/singularize.html +2 -0
  49. package/docs/functions/stringToRegexp.html +2 -0
  50. package/docs/index.html +284 -0
  51. package/docs/interfaces/AndClause.html +5 -0
  52. package/docs/interfaces/OrClause.html +5 -0
  53. package/docs/modules.html +80 -0
  54. package/docs/types/AnyObject.html +2 -0
  55. package/docs/types/BelongsToDefinition.html +6 -0
  56. package/docs/types/DEFAULT_PRIMARY_KEY_PROPERTY_NAME.html +2 -0
  57. package/docs/types/DatasourceDefinition.html +2 -0
  58. package/docs/types/FieldsClause.html +4 -0
  59. package/docs/types/FilterClause.html +2 -0
  60. package/docs/types/Flatten.html +1 -0
  61. package/docs/types/FullPropertyDefinition.html +2 -0
  62. package/docs/types/HasManyDefinition.html +4 -0
  63. package/docs/types/HasOneDefinition.html +4 -0
  64. package/docs/types/Identity.html +2 -0
  65. package/docs/types/IncludeClause.html +14 -0
  66. package/docs/types/ItemFilterClause.html +2 -0
  67. package/docs/types/ModelData.html +2 -0
  68. package/docs/types/ModelDefinition.html +2 -0
  69. package/docs/types/ModelId.html +2 -0
  70. package/docs/types/NestedIncludeClause.html +10 -0
  71. package/docs/types/NormalizedFieldsClause.html +4 -0
  72. package/docs/types/NormalizedIncludeClause.html +6 -0
  73. package/docs/types/OperatorClause.html +4 -0
  74. package/docs/types/OptionalUnlessRequiredId.html +2 -0
  75. package/docs/types/OrderClause.html +4 -0
  76. package/docs/types/PartialBy.html +2 -0
  77. package/docs/types/PartialWithoutId.html +2 -0
  78. package/docs/types/PolyBelongsToDefinition.html +6 -0
  79. package/docs/types/PolyHasManyDefinitionWithTargetKeys.html +4 -0
  80. package/docs/types/PolyHasManyDefinitionWithTargetRelationName.html +4 -0
  81. package/docs/types/PolyHasOneDefinitionWithTargetKeys.html +4 -0
  82. package/docs/types/PolyHasOneDefinitionWithTargetRelationName.html +4 -0
  83. package/docs/types/PropertiesClause.html +4 -0
  84. package/docs/types/PropertyDefinition.html +2 -0
  85. package/docs/types/PropertyDefinitionMap.html +2 -0
  86. package/docs/types/ReferencesManyDefinition.html +6 -0
  87. package/docs/types/RelationDefinition.html +4 -0
  88. package/docs/types/RelationDefinitionMap.html +2 -0
  89. package/docs/types/WhereClause.html +4 -0
  90. package/docs/types/WithoutId.html +2 -0
  91. package/package.json +14 -12
  92. package/src/adapter/adapter.d.ts +13 -0
  93. package/src/adapter/adapter.js +15 -0
  94. package/src/adapter/adapter.spec.js +8 -0
  95. package/src/adapter/builtin/memory-adapter.d.ts +13 -0
  96. package/src/adapter/builtin/memory-adapter.js +30 -0
  97. package/src/adapter/builtin/memory-adapter.spec.js +652 -0
  98. package/src/adapter/decorator/data-sanitizing-decorator.js +6 -0
  99. package/src/adapter/decorator/data-sanitizing-decorator.spec.js +13 -0
  100. package/src/adapter/decorator/data-validation-decorator.js +6 -0
  101. package/src/adapter/decorator/data-validation-decorator.spec.js +13 -0
  102. package/src/adapter/decorator/default-values-decorator.js +6 -0
  103. package/src/adapter/decorator/default-values-decorator.spec.js +16 -0
  104. package/src/adapter/decorator/fields-filtering-decorator.js +13 -0
  105. package/src/adapter/decorator/fields-filtering-decorator.spec.js +17 -0
  106. package/src/adapter/decorator/inclusion-decorator.js +13 -0
  107. package/src/adapter/decorator/inclusion-decorator.spec.js +17 -0
  108. package/src/definition/model/relations/relation-definition.d.ts +3 -3
  109. package/src/definition/model/relations/relations-definition-validator.js +4 -4
  110. package/src/repository/repository.js +2 -6
  111. package/typedoc.json +4 -0
@@ -18,6 +18,11 @@ class TestAdapter extends Adapter {
18
18
  return Promise.resolve({});
19
19
  }
20
20
 
21
+ // eslint-disable-next-line no-unused-vars
22
+ replaceOrCreate(modelName, modelData, filter = undefined) {
23
+ return Promise.resolve({});
24
+ }
25
+
21
26
  // eslint-disable-next-line no-unused-vars
22
27
  patch(modelName, modelData, where = undefined) {
23
28
  return Promise.resolve(1);
@@ -54,6 +59,14 @@ describe('DataSanitizingDecorator', function () {
54
59
  expect(V.sanitize).to.be.called.with.exactly('model', data);
55
60
  });
56
61
 
62
+ it('overrides the "replaceOrCreate" method and sanitizes a given data', async function () {
63
+ sandbox.on(V, 'sanitize');
64
+ const data = {};
65
+ await A.replaceOrCreate('model', data);
66
+ expect(V.sanitize).to.be.called.once;
67
+ expect(V.sanitize).to.be.called.with.exactly('model', data);
68
+ });
69
+
57
70
  it('overrides the "patch" method and sanitizes a given data', async function () {
58
71
  sandbox.on(V, 'sanitize');
59
72
  const data = {};
@@ -32,6 +32,12 @@ export class DataValidationDecorator extends Service {
32
32
  return replaceById.call(this, modelName, id, modelData, filter);
33
33
  };
34
34
 
35
+ const replaceOrCreate = adapter.replaceOrCreate;
36
+ adapter.replaceOrCreate = function (modelName, modelData, filter) {
37
+ this.getService(ModelDataValidator).validate(modelName, modelData);
38
+ return replaceOrCreate.call(this, modelName, modelData, filter);
39
+ };
40
+
35
41
  const patch = adapter.patch;
36
42
  adapter.patch = function (modelName, modelData, where) {
37
43
  this.getService(ModelDataValidator).validate(modelName, modelData, true);
@@ -18,6 +18,11 @@ class TestAdapter extends Adapter {
18
18
  return Promise.resolve({});
19
19
  }
20
20
 
21
+ // eslint-disable-next-line no-unused-vars
22
+ replaceOrCreate(modelName, modelData, filter = undefined) {
23
+ return Promise.resolve({});
24
+ }
25
+
21
26
  // eslint-disable-next-line no-unused-vars
22
27
  patch(modelName, modelData, where = undefined) {
23
28
  return Promise.resolve(1);
@@ -54,6 +59,14 @@ describe('DataValidationDecorator', function () {
54
59
  expect(V.validate).to.be.called.with.exactly('model', data);
55
60
  });
56
61
 
62
+ it('overrides the "replaceOrCreate" method and validates a given data', async function () {
63
+ sandbox.on(V, 'validate');
64
+ const data = {};
65
+ await A.replaceOrCreate('model', data);
66
+ expect(V.validate).to.be.called.once;
67
+ expect(V.validate).to.be.called.with.exactly('model', data);
68
+ });
69
+
57
70
  it('overrides the "patchById" method and validates a given data', async function () {
58
71
  sandbox.on(V, 'validate');
59
72
  const data = {};
@@ -36,6 +36,12 @@ export class DefaultValuesDecorator extends Service {
36
36
  return replaceById.call(this, modelName, id, modelData, filter);
37
37
  };
38
38
 
39
+ const replaceOrCreate = adapter.replaceOrCreate;
40
+ adapter.replaceOrCreate = function (modelName, modelData, filter) {
41
+ modelData = setDefaults(modelName, modelData);
42
+ return replaceOrCreate.call(this, modelName, modelData, filter);
43
+ };
44
+
39
45
  const patch = adapter.patch;
40
46
  adapter.patch = function (modelName, modelData, where) {
41
47
  modelData = setDefaults(modelName, modelData, true);
@@ -29,6 +29,11 @@ class TestAdapter extends Adapter {
29
29
  return modelData;
30
30
  }
31
31
 
32
+ // eslint-disable-next-line no-unused-vars
33
+ async replaceOrCreate(modelName, modelData, filter = undefined) {
34
+ return modelData;
35
+ }
36
+
32
37
  // eslint-disable-next-line no-unused-vars
33
38
  patch(modelName, modelData, where = undefined) {
34
39
  return Promise.resolve(modelData);
@@ -81,6 +86,17 @@ describe('DefaultValuesDecorator', function () {
81
86
  );
82
87
  });
83
88
 
89
+ it('overrides the "replaceOrCreate" method and sets default values to input data', async function () {
90
+ sandbox.on(U, 'setDefaultValuesToEmptyProperties');
91
+ const retval = await A.replaceOrCreate('model', INPUT_DATA);
92
+ expect(retval).to.be.eql({prop: 'value'});
93
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.once;
94
+ expect(U.setDefaultValuesToEmptyProperties).to.be.called.with.exactly(
95
+ 'model',
96
+ INPUT_DATA,
97
+ );
98
+ });
99
+
84
100
  describe('overrides the "patch" method and sets default values to input data', function () {
85
101
  it('does not set default values to not existing properties of input data', async function () {
86
102
  sandbox.on(U, 'setDefaultValuesToEmptyProperties');
@@ -45,6 +45,19 @@ export class FieldsFilteringDecorator extends Service {
45
45
  return result;
46
46
  };
47
47
 
48
+ const replaceOrCreate = adapter.replaceOrCreate;
49
+ adapter.replaceOrCreate = async function (modelName, modelData, filter) {
50
+ let result = await replaceOrCreate.call(
51
+ this,
52
+ modelName,
53
+ modelData,
54
+ filter,
55
+ );
56
+ if (filter && typeof filter === 'object' && filter.fields)
57
+ result = selectFields(result, modelName, filter.fields);
58
+ return result;
59
+ };
60
+
48
61
  const patchById = adapter.patchById;
49
62
  adapter.patchById = async function (modelName, id, modelData, filter) {
50
63
  let result = await patchById.call(this, modelName, id, modelData, filter);
@@ -32,6 +32,11 @@ class TestAdapter extends Adapter {
32
32
  return MODEL_DATA;
33
33
  }
34
34
 
35
+ // eslint-disable-next-line no-unused-vars
36
+ async replaceOrCreate(modelName, modelData, filter = undefined) {
37
+ return MODEL_DATA;
38
+ }
39
+
35
40
  // eslint-disable-next-line no-unused-vars
36
41
  async patchById(modelName, id, modelData, filter = undefined) {
37
42
  return MODEL_DATA;
@@ -81,6 +86,18 @@ describe('FieldsFilteringDecorator', function () {
81
86
  );
82
87
  });
83
88
 
89
+ it('overrides the "replaceOrCreate" method and filtering output fields', async function () {
90
+ sandbox.on(T, 'filter');
91
+ const retval = await A.replaceOrCreate(MODEL_NAME, {}, FILTER);
92
+ expect(retval).to.be.eql(RETVAL_DATA);
93
+ expect(T.filter).to.be.called.once;
94
+ expect(T.filter).to.be.called.with.exactly(
95
+ MODEL_DATA,
96
+ MODEL_NAME,
97
+ FILTER.fields,
98
+ );
99
+ });
100
+
84
101
  it('overrides the "patchById" method and filtering output fields', async function () {
85
102
  sandbox.on(T, 'filter');
86
103
  const retval = await A.patchById(MODEL_NAME, 1, {}, FILTER);
@@ -45,6 +45,19 @@ export class InclusionDecorator extends Service {
45
45
  return retvalData;
46
46
  };
47
47
 
48
+ const replaceOrCreate = adapter.replaceOrCreate;
49
+ adapter.replaceOrCreate = async function (modelName, modelData, filter) {
50
+ const retvalData = await replaceOrCreate.call(
51
+ this,
52
+ modelName,
53
+ modelData,
54
+ filter,
55
+ );
56
+ if (filter && typeof filter === 'object' && filter.include)
57
+ await includeTo([retvalData], modelName, filter.include);
58
+ return retvalData;
59
+ };
60
+
48
61
  const patchById = adapter.patchById;
49
62
  adapter.patchById = async function (modelName, id, modelData, filter) {
50
63
  const retvalData = await patchById.call(
@@ -30,6 +30,11 @@ class TestAdapter extends Adapter {
30
30
  return Object.assign({}, MODEL_DATA);
31
31
  }
32
32
 
33
+ // eslint-disable-next-line no-unused-vars
34
+ async replaceOrCreate(modelName, modelData, filter = undefined) {
35
+ return Object.assign({}, MODEL_DATA);
36
+ }
37
+
33
38
  // eslint-disable-next-line no-unused-vars
34
39
  async patchById(modelName, id, modelData, filter = undefined) {
35
40
  return Object.assign({}, MODEL_DATA);
@@ -79,6 +84,18 @@ describe('InclusionDecorator', function () {
79
84
  expect(T.includeTo).to.be.called.once;
80
85
  });
81
86
 
87
+ it('overrides the "replaceOrCreate" method and applies clause inclusion', async function () {
88
+ sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
89
+ expect(entities).to.be.eql([MODEL_DATA]);
90
+ expect(modelName).to.be.eql('model');
91
+ expect(clause).to.be.eql(FILTER.include);
92
+ Object.assign(entities[0], RETVAL_DATA);
93
+ });
94
+ const retval = await A.replaceOrCreate('model', {}, FILTER);
95
+ expect(retval).to.be.eql(RETVAL_DATA);
96
+ expect(T.includeTo).to.be.called.once;
97
+ });
98
+
82
99
  it('overrides the "patchById" method and applies clause inclusion', async function () {
83
100
  sandbox.on(T, 'includeTo', function (entities, modelName, clause) {
84
101
  expect(entities).to.be.eql([MODEL_DATA]);
@@ -73,7 +73,7 @@ export declare type BelongsToDefinition = {
73
73
  * type: RelationType.BELONGS_TO,
74
74
  * polymorphic: true,
75
75
  * foreignKey: 'referenceId',
76
- * discriminator: 'referenceType,
76
+ * discriminator: 'referenceType',
77
77
  * }
78
78
  * ```
79
79
  */
@@ -134,7 +134,7 @@ export declare type PolyHasOneDefinitionWithTargetRelationName = {
134
134
  * model: 'model',
135
135
  * polymorphic: true,
136
136
  * foreignKey: 'referenceId',
137
- * discriminator: 'referenceType,
137
+ * discriminator: 'referenceType',
138
138
  * }
139
139
  * ```
140
140
  */
@@ -196,7 +196,7 @@ export declare type PolyHasManyDefinitionWithTargetRelationName = {
196
196
  * model: 'model',
197
197
  * polymorphic: true,
198
198
  * foreignKey: 'referenceId',
199
- * discriminator: 'referenceType,
199
+ * discriminator: 'referenceType',
200
200
  * }
201
201
  * ```
202
202
  */
@@ -94,8 +94,8 @@ export class RelationsDefinitionValidator extends Service {
94
94
  * {
95
95
  * type: RelationType.BELONGS_TO,
96
96
  * polymorphic: true,
97
- * foreignKey: 'referenceId', // optional
98
- * discriminator: 'referenceType, // optional
97
+ * foreignKey: 'referenceId', // optional
98
+ * discriminator: 'referenceType', // optional
99
99
  * }
100
100
  * ```
101
101
  *
@@ -193,7 +193,7 @@ export class RelationsDefinitionValidator extends Service {
193
193
  * model: 'model',
194
194
  * polymorphic: true,
195
195
  * foreignKey: 'referenceId',
196
- * discriminator: 'referenceType,
196
+ * discriminator: 'referenceType',
197
197
  * }
198
198
  * ```
199
199
  *
@@ -311,7 +311,7 @@ export class RelationsDefinitionValidator extends Service {
311
311
  * model: 'model',
312
312
  * polymorphic: true,
313
313
  * foreignKey: 'referenceId',
314
- * discriminator: 'referenceType,
314
+ * discriminator: 'referenceType',
315
315
  * }
316
316
  * ```
317
317
  *
@@ -103,12 +103,8 @@ export class Repository extends Service {
103
103
  * @returns {Promise<object>}
104
104
  */
105
105
  async replaceOrCreate(data, filter = undefined) {
106
- const pkPropName = this.getService(
107
- ModelDefinitionUtils,
108
- ).getPrimaryKeyAsPropertyName(this.modelName);
109
- const pkValue = data[pkPropName];
110
- if (pkValue == null) return this.create(data, filter);
111
- return this.replaceById(pkValue, data, filter);
106
+ const adapter = await this.getAdapter();
107
+ return adapter.replaceOrCreate(this.modelName, data, filter);
112
108
  }
113
109
 
114
110
  /**
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "entryPoints": ["src/index.d.ts"],
3
+ "out": "docs"
4
+ }