@tachybase/database 0.23.8

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 (226) hide show
  1. package/.turbo/turbo-build.log +10 -0
  2. package/LICENSE +201 -0
  3. package/lib/collection-factory.d.ts +17 -0
  4. package/lib/collection-factory.js +52 -0
  5. package/lib/collection-group-manager.d.ts +26 -0
  6. package/lib/collection-group-manager.js +57 -0
  7. package/lib/collection-importer.d.ts +7 -0
  8. package/lib/collection-importer.js +74 -0
  9. package/lib/collection.d.ts +138 -0
  10. package/lib/collection.js +686 -0
  11. package/lib/database-utils/index.d.ts +9 -0
  12. package/lib/database-utils/index.js +71 -0
  13. package/lib/database-utils/traverseJSON.d.ts +10 -0
  14. package/lib/database-utils/traverseJSON.js +126 -0
  15. package/lib/database.d.ts +201 -0
  16. package/lib/database.js +765 -0
  17. package/lib/decorators/must-have-filter-decorator.d.ts +2 -0
  18. package/lib/decorators/must-have-filter-decorator.js +38 -0
  19. package/lib/decorators/target-collection-decorator.d.ts +2 -0
  20. package/lib/decorators/target-collection-decorator.js +47 -0
  21. package/lib/decorators/transaction-decorator.d.ts +1 -0
  22. package/lib/decorators/transaction-decorator.js +88 -0
  23. package/lib/eager-loading/eager-loading-tree.d.ts +31 -0
  24. package/lib/eager-loading/eager-loading-tree.js +439 -0
  25. package/lib/errors/identifier-error.d.ts +3 -0
  26. package/lib/errors/identifier-error.js +35 -0
  27. package/lib/errors/zero-column-table-error.d.ts +2 -0
  28. package/lib/errors/zero-column-table-error.js +31 -0
  29. package/lib/features/references-map.d.ts +18 -0
  30. package/lib/features/references-map.js +109 -0
  31. package/lib/features/referential-integrity-check.d.ts +8 -0
  32. package/lib/features/referential-integrity-check.js +83 -0
  33. package/lib/field-repository/array-field-repository.d.ts +28 -0
  34. package/lib/field-repository/array-field-repository.js +197 -0
  35. package/lib/fields/array-field.d.ts +11 -0
  36. package/lib/fields/array-field.js +57 -0
  37. package/lib/fields/belongs-to-field.d.ts +17 -0
  38. package/lib/fields/belongs-to-field.js +154 -0
  39. package/lib/fields/belongs-to-many-field.d.ts +20 -0
  40. package/lib/fields/belongs-to-many-field.js +187 -0
  41. package/lib/fields/boolean-field.d.ts +8 -0
  42. package/lib/fields/boolean-field.js +36 -0
  43. package/lib/fields/context-field.d.ts +14 -0
  44. package/lib/fields/context-field.js +70 -0
  45. package/lib/fields/date-field.d.ts +13 -0
  46. package/lib/fields/date-field.js +64 -0
  47. package/lib/fields/field.d.ts +43 -0
  48. package/lib/fields/field.js +156 -0
  49. package/lib/fields/has-inverse-field.d.ts +4 -0
  50. package/lib/fields/has-inverse-field.js +15 -0
  51. package/lib/fields/has-many-field.d.ts +68 -0
  52. package/lib/fields/has-many-field.js +156 -0
  53. package/lib/fields/has-one-field.d.ts +68 -0
  54. package/lib/fields/has-one-field.js +150 -0
  55. package/lib/fields/index.d.ts +46 -0
  56. package/lib/fields/index.js +65 -0
  57. package/lib/fields/json-field.d.ts +14 -0
  58. package/lib/fields/json-field.js +54 -0
  59. package/lib/fields/nanoid-field.d.ts +13 -0
  60. package/lib/fields/nanoid-field.js +58 -0
  61. package/lib/fields/number-field.d.ts +41 -0
  62. package/lib/fields/number-field.js +85 -0
  63. package/lib/fields/password-field.d.ts +21 -0
  64. package/lib/fields/password-field.js +95 -0
  65. package/lib/fields/radio-field.d.ts +16 -0
  66. package/lib/fields/radio-field.js +66 -0
  67. package/lib/fields/relation-field.d.ts +21 -0
  68. package/lib/fields/relation-field.js +79 -0
  69. package/lib/fields/set-field.d.ts +10 -0
  70. package/lib/fields/set-field.js +46 -0
  71. package/lib/fields/sort-field.d.ts +16 -0
  72. package/lib/fields/sort-field.js +187 -0
  73. package/lib/fields/string-field.d.ts +8 -0
  74. package/lib/fields/string-field.js +36 -0
  75. package/lib/fields/text-field.d.ts +8 -0
  76. package/lib/fields/text-field.js +36 -0
  77. package/lib/fields/time-field.d.ts +8 -0
  78. package/lib/fields/time-field.js +36 -0
  79. package/lib/fields/uid-field.d.ts +13 -0
  80. package/lib/fields/uid-field.js +63 -0
  81. package/lib/fields/uuid-field.d.ts +9 -0
  82. package/lib/fields/uuid-field.js +45 -0
  83. package/lib/fields/virtual-field.d.ts +8 -0
  84. package/lib/fields/virtual-field.js +36 -0
  85. package/lib/filter-match.d.ts +1 -0
  86. package/lib/filter-match.js +66 -0
  87. package/lib/filter-parser.d.ts +21 -0
  88. package/lib/filter-parser.js +230 -0
  89. package/lib/helpers.d.ts +3 -0
  90. package/lib/helpers.js +167 -0
  91. package/lib/index.d.ts +30 -0
  92. package/lib/index.js +114 -0
  93. package/lib/inherited-collection.d.ts +14 -0
  94. package/lib/inherited-collection.js +138 -0
  95. package/lib/inherited-map.d.ts +21 -0
  96. package/lib/inherited-map.js +113 -0
  97. package/lib/inherited-sync-runner.d.ts +4 -0
  98. package/lib/inherited-sync-runner.js +175 -0
  99. package/lib/listeners/adjacency-list.d.ts +2 -0
  100. package/lib/listeners/adjacency-list.js +42 -0
  101. package/lib/listeners/append-child-collection-name-after-repository-find.d.ts +6 -0
  102. package/lib/listeners/append-child-collection-name-after-repository-find.js +66 -0
  103. package/lib/listeners/index.d.ts +2 -0
  104. package/lib/listeners/index.js +33 -0
  105. package/lib/magic-attribute-model.d.ts +8 -0
  106. package/lib/magic-attribute-model.js +203 -0
  107. package/lib/migration.d.ts +35 -0
  108. package/lib/migration.js +103 -0
  109. package/lib/mock-database.d.ts +25 -0
  110. package/lib/mock-database.js +126 -0
  111. package/lib/model-hook.d.ts +12 -0
  112. package/lib/model-hook.js +92 -0
  113. package/lib/model.d.ts +23 -0
  114. package/lib/model.js +152 -0
  115. package/lib/operators/array.d.ts +2 -0
  116. package/lib/operators/array.js +158 -0
  117. package/lib/operators/association.d.ts +2 -0
  118. package/lib/operators/association.js +35 -0
  119. package/lib/operators/boolean.d.ts +2 -0
  120. package/lib/operators/boolean.js +38 -0
  121. package/lib/operators/child-collection.d.ts +2 -0
  122. package/lib/operators/child-collection.js +67 -0
  123. package/lib/operators/date.d.ts +2 -0
  124. package/lib/operators/date.js +140 -0
  125. package/lib/operators/empty.d.ts +5 -0
  126. package/lib/operators/empty.js +89 -0
  127. package/lib/operators/eq.d.ts +2 -0
  128. package/lib/operators/eq.js +35 -0
  129. package/lib/operators/index.d.ts +5 -0
  130. package/lib/operators/index.js +56 -0
  131. package/lib/operators/jsonb.d.ts +2 -0
  132. package/lib/operators/jsonb.js +50 -0
  133. package/lib/operators/ne.d.ts +2 -0
  134. package/lib/operators/ne.js +40 -0
  135. package/lib/operators/notIn.d.ts +2 -0
  136. package/lib/operators/notIn.js +33 -0
  137. package/lib/operators/string.d.ts +2 -0
  138. package/lib/operators/string.js +109 -0
  139. package/lib/operators/utils.d.ts +4 -0
  140. package/lib/operators/utils.js +40 -0
  141. package/lib/options-parser.d.ts +37 -0
  142. package/lib/options-parser.js +332 -0
  143. package/lib/playground.d.ts +1 -0
  144. package/lib/playground.js +43 -0
  145. package/lib/query-interface/mysql-query-interface.d.ts +35 -0
  146. package/lib/query-interface/mysql-query-interface.js +122 -0
  147. package/lib/query-interface/postgres-query-interface.d.ts +32 -0
  148. package/lib/query-interface/postgres-query-interface.js +189 -0
  149. package/lib/query-interface/query-interface-builder.d.ts +2 -0
  150. package/lib/query-interface/query-interface-builder.js +46 -0
  151. package/lib/query-interface/query-interface.d.ts +42 -0
  152. package/lib/query-interface/query-interface.js +46 -0
  153. package/lib/query-interface/sqlite-query-interface.d.ts +35 -0
  154. package/lib/query-interface/sqlite-query-interface.js +131 -0
  155. package/lib/relation-repository/belongs-to-many-repository.d.ts +21 -0
  156. package/lib/relation-repository/belongs-to-many-repository.js +280 -0
  157. package/lib/relation-repository/belongs-to-repository.d.ts +6 -0
  158. package/lib/relation-repository/belongs-to-repository.js +39 -0
  159. package/lib/relation-repository/hasmany-repository.d.ts +10 -0
  160. package/lib/relation-repository/hasmany-repository.js +182 -0
  161. package/lib/relation-repository/hasone-repository.d.ts +6 -0
  162. package/lib/relation-repository/hasone-repository.js +39 -0
  163. package/lib/relation-repository/multiple-relation-repository.d.ts +20 -0
  164. package/lib/relation-repository/multiple-relation-repository.js +229 -0
  165. package/lib/relation-repository/relation-repository.d.ts +29 -0
  166. package/lib/relation-repository/relation-repository.js +202 -0
  167. package/lib/relation-repository/single-relation-repository.d.ts +25 -0
  168. package/lib/relation-repository/single-relation-repository.js +162 -0
  169. package/lib/relation-repository/types.d.ts +7 -0
  170. package/lib/relation-repository/types.js +15 -0
  171. package/lib/repositories/tree-repository/adjacency-list-repository.d.ts +18 -0
  172. package/lib/repositories/tree-repository/adjacency-list-repository.js +183 -0
  173. package/lib/repositories/view-repository.d.ts +3 -0
  174. package/lib/repositories/view-repository.js +32 -0
  175. package/lib/repository.d.ts +206 -0
  176. package/lib/repository.js +597 -0
  177. package/lib/sql-collection/index.d.ts +2 -0
  178. package/lib/sql-collection/index.js +23 -0
  179. package/lib/sql-collection/query-generator.d.ts +10 -0
  180. package/lib/sql-collection/query-generator.js +70 -0
  181. package/lib/sql-collection/sql-collection.d.ts +7 -0
  182. package/lib/sql-collection/sql-collection.js +69 -0
  183. package/lib/sql-collection/sql-model.d.ts +16 -0
  184. package/lib/sql-collection/sql-model.js +168 -0
  185. package/lib/sql-parser/index.d.ts +10 -0
  186. package/lib/sql-parser/index.js +10699 -0
  187. package/lib/sql-parser/postgres.d.ts +10 -0
  188. package/lib/sql-parser/postgres.js +31506 -0
  189. package/lib/sql-parser/sql.pegjs +1297 -0
  190. package/lib/sync-runner.d.ts +30 -0
  191. package/lib/sync-runner.js +277 -0
  192. package/lib/types.d.ts +49 -0
  193. package/lib/types.js +15 -0
  194. package/lib/update-associations.d.ts +60 -0
  195. package/lib/update-associations.js +405 -0
  196. package/lib/update-guard.d.ts +28 -0
  197. package/lib/update-guard.js +202 -0
  198. package/lib/utils.d.ts +7 -0
  199. package/lib/utils.js +127 -0
  200. package/lib/value-parsers/array-value-parser.d.ts +8 -0
  201. package/lib/value-parsers/array-value-parser.js +58 -0
  202. package/lib/value-parsers/base-value-parser.d.ts +12 -0
  203. package/lib/value-parsers/base-value-parser.js +63 -0
  204. package/lib/value-parsers/boolean-value-parser.d.ts +4 -0
  205. package/lib/value-parsers/boolean-value-parser.js +52 -0
  206. package/lib/value-parsers/date-value-parser.d.ts +5 -0
  207. package/lib/value-parsers/date-value-parser.js +88 -0
  208. package/lib/value-parsers/index.d.ts +12 -0
  209. package/lib/value-parsers/index.js +78 -0
  210. package/lib/value-parsers/json-value-parser.d.ts +4 -0
  211. package/lib/value-parsers/json-value-parser.js +47 -0
  212. package/lib/value-parsers/number-value-parser.d.ts +4 -0
  213. package/lib/value-parsers/number-value-parser.js +58 -0
  214. package/lib/value-parsers/string-value-parser.d.ts +8 -0
  215. package/lib/value-parsers/string-value-parser.js +64 -0
  216. package/lib/value-parsers/to-many-value-parser.d.ts +13 -0
  217. package/lib/value-parsers/to-many-value-parser.js +108 -0
  218. package/lib/value-parsers/to-one-value-parser.d.ts +4 -0
  219. package/lib/value-parsers/to-one-value-parser.js +48 -0
  220. package/lib/view/field-type-map.d.ts +97 -0
  221. package/lib/view/field-type-map.js +90 -0
  222. package/lib/view/view-inference.d.ts +32 -0
  223. package/lib/view/view-inference.js +146 -0
  224. package/lib/view-collection.d.ts +6 -0
  225. package/lib/view-collection.js +45 -0
  226. package/package.json +38 -0
@@ -0,0 +1,405 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var update_associations_exports = {};
30
+ __export(update_associations_exports, {
31
+ belongsToManyAssociations: () => belongsToManyAssociations,
32
+ modelAssociationByKey: () => modelAssociationByKey,
33
+ modelAssociations: () => modelAssociations,
34
+ updateAssociation: () => updateAssociation,
35
+ updateAssociations: () => updateAssociations,
36
+ updateModelByValues: () => updateModelByValues,
37
+ updateMultipleAssociation: () => updateMultipleAssociation,
38
+ updateSingleAssociation: () => updateSingleAssociation,
39
+ updateThroughTableValue: () => updateThroughTableValue
40
+ });
41
+ module.exports = __toCommonJS(update_associations_exports);
42
+ var import_lodash = __toESM(require("lodash"));
43
+ var import_model = require("./model");
44
+ var import_update_guard = require("./update-guard");
45
+ function isUndefinedOrNull(value) {
46
+ return typeof value === "undefined" || value === null;
47
+ }
48
+ __name(isUndefinedOrNull, "isUndefinedOrNull");
49
+ function isStringOrNumber(value) {
50
+ return typeof value === "string" || typeof value === "number";
51
+ }
52
+ __name(isStringOrNumber, "isStringOrNumber");
53
+ function getKeysByPrefix(keys, prefix) {
54
+ return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));
55
+ }
56
+ __name(getKeysByPrefix, "getKeysByPrefix");
57
+ function modelAssociations(instance) {
58
+ return instance.constructor.associations;
59
+ }
60
+ __name(modelAssociations, "modelAssociations");
61
+ function belongsToManyAssociations(instance) {
62
+ const associations = modelAssociations(instance);
63
+ return Object.entries(associations).filter((entry) => {
64
+ const [key, association] = entry;
65
+ return association.associationType == "BelongsToMany";
66
+ }).map((association) => {
67
+ return association[1];
68
+ });
69
+ }
70
+ __name(belongsToManyAssociations, "belongsToManyAssociations");
71
+ function modelAssociationByKey(instance, key) {
72
+ return modelAssociations(instance)[key];
73
+ }
74
+ __name(modelAssociationByKey, "modelAssociationByKey");
75
+ async function updateModelByValues(instance, values, options) {
76
+ if (!(options == null ? void 0 : options.sanitized)) {
77
+ const guard = new import_update_guard.UpdateGuard();
78
+ guard.setModel(instance.constructor);
79
+ guard.setBlackList(options.blacklist);
80
+ guard.setWhiteList(options.whitelist);
81
+ guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
82
+ values = guard.sanitize(values);
83
+ }
84
+ await instance.update(values, options);
85
+ await updateAssociations(instance, values, options);
86
+ }
87
+ __name(updateModelByValues, "updateModelByValues");
88
+ async function updateThroughTableValue(instance, throughName, throughValues, source, transaction = null) {
89
+ for (const belongsToMany of belongsToManyAssociations(instance)) {
90
+ const throughModel = belongsToMany.through.model;
91
+ const throughModelName = throughModel.name;
92
+ if (throughModelName === throughModelName) {
93
+ const where = {
94
+ [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
95
+ [belongsToMany.otherKey]: source.get(belongsToMany.targetKey)
96
+ };
97
+ return await throughModel.update(throughValues, {
98
+ where,
99
+ transaction
100
+ });
101
+ }
102
+ }
103
+ }
104
+ __name(updateThroughTableValue, "updateThroughTableValue");
105
+ async function updateAssociations(instance, values, options = {}) {
106
+ if (!values) {
107
+ return;
108
+ }
109
+ if (options == null ? void 0 : options.updateAssociationValues) {
110
+ options.recursive = true;
111
+ }
112
+ let newTransaction = false;
113
+ let transaction = options.transaction;
114
+ if (!transaction) {
115
+ newTransaction = true;
116
+ transaction = await instance.sequelize.transaction();
117
+ }
118
+ const keys = Object.keys(values);
119
+ try {
120
+ for (const key of Object.keys(modelAssociations(instance))) {
121
+ if (keys.includes(key)) {
122
+ await updateAssociation(instance, key, values[key], {
123
+ ...options,
124
+ transaction
125
+ });
126
+ }
127
+ }
128
+ for (const belongsToMany of belongsToManyAssociations(instance)) {
129
+ const throughModel = belongsToMany.through.model;
130
+ const throughModelName = throughModel.name;
131
+ if (values[throughModelName] && options.sourceModel) {
132
+ const where = {
133
+ [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
134
+ [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey)
135
+ };
136
+ await throughModel.update(values[throughModel.name], {
137
+ where,
138
+ context: options.context,
139
+ transaction
140
+ });
141
+ }
142
+ }
143
+ if (newTransaction) {
144
+ await transaction.commit();
145
+ }
146
+ } catch (error) {
147
+ if (newTransaction) {
148
+ await transaction.rollback();
149
+ }
150
+ throw error;
151
+ }
152
+ }
153
+ __name(updateAssociations, "updateAssociations");
154
+ function isReverseAssociationPair(a, b) {
155
+ const typeSet = /* @__PURE__ */ new Set();
156
+ typeSet.add(a.associationType);
157
+ typeSet.add(b.associationType);
158
+ if (typeSet.size == 1 && typeSet.has("BelongsToMany")) {
159
+ return a.through.tableName === b.through.tableName && a.target.name === b.source.name && b.target.name === a.source.name && a.foreignKey === b.otherKey && a.sourceKey === b.targetKey && a.otherKey === b.foreignKey && a.targetKey === b.sourceKey;
160
+ }
161
+ if (typeSet.has("HasOne") && typeSet.has("BelongsTo") || typeSet.has("HasMany") && typeSet.has("BelongsTo")) {
162
+ const sourceAssoc = a.associationType == "BelongsTo" ? b : a;
163
+ const targetAssoc = sourceAssoc == a ? b : a;
164
+ return sourceAssoc.source.name === targetAssoc.target.name && sourceAssoc.target.name === targetAssoc.source.name && sourceAssoc.foreignKey === targetAssoc.foreignKey && sourceAssoc.sourceKey === targetAssoc.targetKey;
165
+ }
166
+ return false;
167
+ }
168
+ __name(isReverseAssociationPair, "isReverseAssociationPair");
169
+ async function updateAssociation(instance, key, value, options = {}) {
170
+ const association = modelAssociationByKey(instance, key);
171
+ if (!association) {
172
+ return false;
173
+ }
174
+ if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {
175
+ return false;
176
+ }
177
+ switch (association.associationType) {
178
+ case "HasOne":
179
+ case "BelongsTo":
180
+ return updateSingleAssociation(instance, key, value, options);
181
+ case "HasMany":
182
+ case "BelongsToMany":
183
+ return updateMultipleAssociation(instance, key, value, options);
184
+ }
185
+ }
186
+ __name(updateAssociation, "updateAssociation");
187
+ async function updateSingleAssociation(model, key, value, options = {}) {
188
+ const association = modelAssociationByKey(model, key);
189
+ if (!association) {
190
+ return false;
191
+ }
192
+ if (!["undefined", "string", "number", "object"].includes(typeof value)) {
193
+ return false;
194
+ }
195
+ if (Array.isArray(value)) {
196
+ throw new Error(`The value of '${key}' cannot be in array format`);
197
+ }
198
+ const { recursive, context, updateAssociationValues = [], transaction } = options;
199
+ const keys = getKeysByPrefix(updateAssociationValues, key);
200
+ const setAccessor = association.accessors.set;
201
+ const removeAssociation = /* @__PURE__ */ __name(async () => {
202
+ await model[setAccessor](null, { transaction });
203
+ model.setDataValue(key, null);
204
+ return true;
205
+ }, "removeAssociation");
206
+ if (isUndefinedOrNull(value)) {
207
+ return await removeAssociation();
208
+ }
209
+ if (association.associationType === "HasOne" && !model.get(association.sourceKeyAttribute)) {
210
+ throw new Error(`The source key ${association.sourceKeyAttribute} is not set in ${model.constructor.name}`);
211
+ }
212
+ const checkBelongsToForeignKeyValue = /* @__PURE__ */ __name(() => {
213
+ if (association.associationType === "BelongsTo" && !model.get(association.foreignKey)) {
214
+ throw new Error(
215
+ // @ts-ignore
216
+ `The target key ${association.targetKey} is not set in ${association.target.name}`
217
+ );
218
+ }
219
+ }, "checkBelongsToForeignKeyValue");
220
+ if (isStringOrNumber(value)) {
221
+ await model[setAccessor](value, { context, transaction });
222
+ return true;
223
+ }
224
+ if (value instanceof import_model.Model) {
225
+ await model[setAccessor](value, { context, transaction });
226
+ model.setDataValue(key, value);
227
+ return true;
228
+ }
229
+ const createAccessor = association.accessors.create;
230
+ let dataKey;
231
+ let M;
232
+ if (association.associationType === "BelongsTo") {
233
+ M = association.target;
234
+ dataKey = association.targetKey;
235
+ } else {
236
+ M = association.target;
237
+ dataKey = M.primaryKeyAttribute;
238
+ }
239
+ if (isStringOrNumber(value[dataKey])) {
240
+ const instance2 = await M.findOne({
241
+ where: {
242
+ [dataKey]: value[dataKey]
243
+ },
244
+ transaction
245
+ });
246
+ if (instance2) {
247
+ await model[setAccessor](instance2, { context, transaction });
248
+ if (!recursive) {
249
+ return;
250
+ }
251
+ if (updateAssociationValues.includes(key)) {
252
+ await instance2.update(value, { ...options, transaction });
253
+ }
254
+ await updateAssociations(instance2, value, {
255
+ ...options,
256
+ transaction,
257
+ associationContext: association,
258
+ updateAssociationValues: keys
259
+ });
260
+ model.setDataValue(key, instance2);
261
+ return true;
262
+ }
263
+ }
264
+ const instance = await model[createAccessor](value, { context, transaction });
265
+ await updateAssociations(instance, value, {
266
+ ...options,
267
+ transaction,
268
+ associationContext: association,
269
+ updateAssociationValues: keys
270
+ });
271
+ model.setDataValue(key, instance);
272
+ if (association.targetKey) {
273
+ model.setDataValue(association.foreignKey, instance[dataKey]);
274
+ }
275
+ checkBelongsToForeignKeyValue();
276
+ }
277
+ __name(updateSingleAssociation, "updateSingleAssociation");
278
+ async function updateMultipleAssociation(model, key, value, options = {}) {
279
+ var _a, _b;
280
+ const association = modelAssociationByKey(model, key);
281
+ if (!association) {
282
+ return false;
283
+ }
284
+ if (!["undefined", "string", "number", "object"].includes(typeof value)) {
285
+ return false;
286
+ }
287
+ const { recursive, context, updateAssociationValues = [], transaction } = options;
288
+ const keys = getKeysByPrefix(updateAssociationValues, key);
289
+ const setAccessor = association.accessors.set;
290
+ const createAccessor = association.accessors.create;
291
+ if (isUndefinedOrNull(value)) {
292
+ await model[setAccessor](null, { transaction, context, individualHooks: true });
293
+ model.setDataValue(key, null);
294
+ return;
295
+ }
296
+ if (association.associationType === "HasMany" && !model.get(association.sourceKeyAttribute)) {
297
+ throw new Error(`The source key ${association.sourceKeyAttribute} is not set in ${model.constructor.name}`);
298
+ }
299
+ if (isStringOrNumber(value)) {
300
+ await model[setAccessor](value, { transaction, context, individualHooks: true });
301
+ return;
302
+ }
303
+ value = import_lodash.default.castArray(value);
304
+ const setItems = [];
305
+ const objectItems = [];
306
+ for (const item of value) {
307
+ if (isUndefinedOrNull(item)) {
308
+ continue;
309
+ }
310
+ if (isStringOrNumber(item)) {
311
+ setItems.push(item);
312
+ } else if (item instanceof import_model.Model) {
313
+ setItems.push(item);
314
+ } else if (item.sequelize) {
315
+ setItems.push(item);
316
+ } else if (typeof item === "object") {
317
+ const targetKey2 = association.targetKey || "id";
318
+ if (item[targetKey2]) {
319
+ setItems.push(item[targetKey2]);
320
+ }
321
+ objectItems.push(item);
322
+ }
323
+ }
324
+ await model[setAccessor](setItems, { transaction, context, individualHooks: true });
325
+ const newItems = [];
326
+ const pk = association.target.primaryKeyAttribute;
327
+ const tmpKey = (_a = association["options"]) == null ? void 0 : _a["targetKey"];
328
+ let targetKey = pk;
329
+ const db = model.constructor["database"];
330
+ if (tmpKey !== pk) {
331
+ const targetKeyFieldOptions = (_b = db.getFieldByPath(`${association.target.name}.${tmpKey}`)) == null ? void 0 : _b.options;
332
+ if (targetKeyFieldOptions == null ? void 0 : targetKeyFieldOptions.unique) {
333
+ targetKey = tmpKey;
334
+ }
335
+ }
336
+ for (const item of objectItems) {
337
+ const through = association.through ? association.through.model.name : null;
338
+ const accessorOptions = {
339
+ context,
340
+ transaction
341
+ };
342
+ const throughValue = item[through];
343
+ if (throughValue) {
344
+ accessorOptions["through"] = throughValue;
345
+ }
346
+ if (isUndefinedOrNull(item[targetKey])) {
347
+ const instance = await model[createAccessor](item, accessorOptions);
348
+ await updateAssociations(instance, item, {
349
+ ...options,
350
+ transaction,
351
+ associationContext: association,
352
+ updateAssociationValues: keys
353
+ });
354
+ newItems.push(instance);
355
+ } else {
356
+ const where = {
357
+ [targetKey]: item[targetKey]
358
+ };
359
+ let instance = await association.target.findOne({
360
+ where,
361
+ transaction
362
+ });
363
+ if (!instance) {
364
+ instance = await model[createAccessor](item, accessorOptions);
365
+ await updateAssociations(instance, item, {
366
+ ...options,
367
+ transaction,
368
+ associationContext: association,
369
+ updateAssociationValues: keys
370
+ });
371
+ newItems.push(instance);
372
+ continue;
373
+ }
374
+ const addAccessor = association.accessors.add;
375
+ await model[addAccessor](instance[association.target.primaryKeyAttribute], accessorOptions);
376
+ if (!recursive) {
377
+ continue;
378
+ }
379
+ if (updateAssociationValues.includes(key)) {
380
+ await instance.update(item, { ...options, transaction });
381
+ }
382
+ await updateAssociations(instance, item, {
383
+ ...options,
384
+ transaction,
385
+ associationContext: association,
386
+ updateAssociationValues: keys
387
+ });
388
+ newItems.push(instance);
389
+ }
390
+ }
391
+ model.setDataValue(key, setItems.concat(newItems));
392
+ }
393
+ __name(updateMultipleAssociation, "updateMultipleAssociation");
394
+ // Annotate the CommonJS export names for ESM import in node:
395
+ 0 && (module.exports = {
396
+ belongsToManyAssociations,
397
+ modelAssociationByKey,
398
+ modelAssociations,
399
+ updateAssociation,
400
+ updateAssociations,
401
+ updateModelByValues,
402
+ updateMultipleAssociation,
403
+ updateSingleAssociation,
404
+ updateThroughTableValue
405
+ });
@@ -0,0 +1,28 @@
1
+ import { ModelStatic } from 'sequelize';
2
+ import { AssociationKeysToBeUpdate, BlackList, WhiteList } from './repository';
3
+ type UpdateValueItem = string | number | UpdateValues;
4
+ type UpdateValues = {
5
+ [key: string]: UpdateValueItem | Array<UpdateValueItem>;
6
+ };
7
+ type UpdateAction = 'create' | 'update';
8
+ export declare class UpdateGuard {
9
+ model: ModelStatic<any>;
10
+ action: UpdateAction;
11
+ underscored: boolean;
12
+ private associationKeysToBeUpdate;
13
+ private blackList;
14
+ private whiteList;
15
+ static fromOptions(model: any, options: any): UpdateGuard;
16
+ setAction(action: UpdateAction): void;
17
+ setModel(model: ModelStatic<any>): void;
18
+ setAssociationKeysToBeUpdate(associationKeysToBeUpdate: AssociationKeysToBeUpdate): void;
19
+ setWhiteList(whiteList: WhiteList): void;
20
+ setBlackList(blackList: BlackList): void;
21
+ checkValues(values: any): void;
22
+ /**
23
+ * Sanitize values by whitelist blacklist
24
+ * @param values
25
+ */
26
+ sanitize(values: UpdateValues): {};
27
+ }
28
+ export {};
@@ -0,0 +1,202 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var update_guard_exports = {};
30
+ __export(update_guard_exports, {
31
+ UpdateGuard: () => UpdateGuard
32
+ });
33
+ module.exports = __toCommonJS(update_guard_exports);
34
+ var import_lodash = __toESM(require("lodash"));
35
+ var import_model = require("./model");
36
+ const _UpdateGuard = class _UpdateGuard {
37
+ model;
38
+ action;
39
+ underscored;
40
+ associationKeysToBeUpdate;
41
+ blackList;
42
+ whiteList;
43
+ static fromOptions(model, options) {
44
+ const guard = new _UpdateGuard();
45
+ guard.setModel(model);
46
+ guard.setWhiteList(options.whitelist);
47
+ guard.setBlackList(options.blacklist);
48
+ guard.setAction(import_lodash.default.get(options, "action", "update"));
49
+ guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
50
+ if (options.underscored) {
51
+ guard.underscored = options.underscored;
52
+ }
53
+ return guard;
54
+ }
55
+ setAction(action) {
56
+ this.action = action;
57
+ }
58
+ setModel(model) {
59
+ this.model = model;
60
+ }
61
+ setAssociationKeysToBeUpdate(associationKeysToBeUpdate) {
62
+ if (this.action == "create") {
63
+ this.associationKeysToBeUpdate = Object.keys(this.model.associations);
64
+ } else {
65
+ this.associationKeysToBeUpdate = associationKeysToBeUpdate;
66
+ }
67
+ }
68
+ setWhiteList(whiteList) {
69
+ this.whiteList = whiteList;
70
+ }
71
+ setBlackList(blackList) {
72
+ this.blackList = blackList;
73
+ }
74
+ checkValues(values) {
75
+ const dfs = /* @__PURE__ */ __name((values2, model) => {
76
+ const associations = model.associations;
77
+ const belongsToManyThroughNames = [];
78
+ const associationValueKeys = Object.keys(associations).filter((key) => {
79
+ return Object.keys(values2).includes(key);
80
+ });
81
+ const belongsToManyValueKeys = associationValueKeys.filter((key) => {
82
+ return associations[key].associationType === "BelongsToMany";
83
+ });
84
+ const hasManyValueKeys = associationValueKeys.filter((key) => {
85
+ return associations[key].associationType === "HasMany";
86
+ });
87
+ for (const belongsToManyKey of belongsToManyValueKeys) {
88
+ const association = associations[belongsToManyKey];
89
+ const through = association.through.model;
90
+ belongsToManyThroughNames.push(through.name);
91
+ }
92
+ for (const hasManyKey of hasManyValueKeys) {
93
+ const association = associations[hasManyKey];
94
+ if (belongsToManyThroughNames.includes(association.target.name)) {
95
+ throw new Error(
96
+ `HasMany association ${hasManyKey} cannot be used with BelongsToMany association ${association.target.name} with same through model`
97
+ );
98
+ }
99
+ }
100
+ }, "dfs");
101
+ dfs(values, this.model);
102
+ }
103
+ /**
104
+ * Sanitize values by whitelist blacklist
105
+ * @param values
106
+ */
107
+ sanitize(values) {
108
+ if (values === null || values === void 0) {
109
+ return values;
110
+ }
111
+ values = import_lodash.default.clone(values);
112
+ if (!this.model) {
113
+ throw new Error("please set model first");
114
+ }
115
+ this.checkValues(values);
116
+ const associations = this.model.associations;
117
+ const associationsValues = import_lodash.default.pick(values, Object.keys(associations));
118
+ const listOfAssociation = /* @__PURE__ */ __name((list, association) => {
119
+ if (list) {
120
+ list = list.filter((whiteListKey) => whiteListKey.startsWith(`${association}.`)).map((whiteListKey) => whiteListKey.replace(`${association}.`, ""));
121
+ if (list.length == 0) {
122
+ return void 0;
123
+ }
124
+ return list;
125
+ }
126
+ return void 0;
127
+ }, "listOfAssociation");
128
+ Object.keys(associationsValues).forEach((association) => {
129
+ let associationValues = associationsValues[association];
130
+ const associationObj = associations[association];
131
+ const filterAssociationToBeUpdate = /* @__PURE__ */ __name((value) => {
132
+ if (value === null) {
133
+ return value;
134
+ }
135
+ const associationKeysToBeUpdate = this.associationKeysToBeUpdate || [];
136
+ if (associationKeysToBeUpdate.includes(association)) {
137
+ return value;
138
+ }
139
+ const associationKeyName = associationObj.associationType == "BelongsTo" || associationObj.associationType == "HasOne" ? associationObj.targetKey : associationObj.target.primaryKeyAttribute;
140
+ if (value[associationKeyName]) {
141
+ return import_lodash.default.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
142
+ }
143
+ return value;
144
+ }, "filterAssociationToBeUpdate");
145
+ const sanitizeValue = /* @__PURE__ */ __name((value) => {
146
+ const associationUpdateGuard = new _UpdateGuard();
147
+ associationUpdateGuard.setModel(associations[association].target);
148
+ ["whiteList", "blackList", "associationKeysToBeUpdate"].forEach((optionKey) => {
149
+ associationUpdateGuard[`set${import_lodash.default.upperFirst(optionKey)}`](listOfAssociation(this[optionKey], association));
150
+ });
151
+ return associationUpdateGuard.sanitize(filterAssociationToBeUpdate(value));
152
+ }, "sanitizeValue");
153
+ if (Array.isArray(associationValues)) {
154
+ associationValues = associationValues.map((value) => {
155
+ if (value === void 0 || value === null || typeof value == "string" || typeof value == "number") {
156
+ return value;
157
+ } else {
158
+ return sanitizeValue(value);
159
+ }
160
+ });
161
+ } else if (typeof associationValues === "object" && associationValues !== null) {
162
+ associationValues = sanitizeValue(associationValues);
163
+ }
164
+ values[association] = associationValues;
165
+ if (associationObj.associationType === "BelongsTo") {
166
+ if (typeof associationValues === "object" && associationValues !== null) {
167
+ if (associationValues[associationObj.targetKey] != null) {
168
+ values[associationObj.foreignKey] = associationValues[associationObj.targetKey];
169
+ }
170
+ } else {
171
+ values[associationObj.foreignKey] = associationValues;
172
+ }
173
+ }
174
+ });
175
+ if (values instanceof import_model.Model) {
176
+ return values;
177
+ }
178
+ let valuesKeys = Object.keys(values || {});
179
+ if (this.whiteList) {
180
+ valuesKeys = valuesKeys.filter((valueKey) => {
181
+ return this.whiteList.findIndex((whiteKey) => {
182
+ const keyPaths = whiteKey.split(".");
183
+ return keyPaths[0] === valueKey;
184
+ }) !== -1;
185
+ });
186
+ }
187
+ if (this.blackList) {
188
+ valuesKeys = valuesKeys.filter((valueKey) => !this.blackList.includes(valueKey));
189
+ }
190
+ const result = valuesKeys.reduce((obj, key) => {
191
+ import_lodash.default.set(obj, key, values[key]);
192
+ return obj;
193
+ }, {});
194
+ return result;
195
+ }
196
+ };
197
+ __name(_UpdateGuard, "UpdateGuard");
198
+ let UpdateGuard = _UpdateGuard;
199
+ // Annotate the CommonJS export names for ESM import in node:
200
+ 0 && (module.exports = {
201
+ UpdateGuard
202
+ });
package/lib/utils.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import Database from './database';
2
+ export declare function md5(value: string): string;
3
+ export declare function checkIdentifier(value: string): void;
4
+ export declare function getTableName(collectionName: string, options: any): any;
5
+ export declare function snakeCase(name: string): any;
6
+ export declare function patchSequelizeQueryInterface(db: Database): void;
7
+ export declare function percent2float(value: string): number;