@nocobase/database 0.7.0-alpha.6 → 0.7.0-alpha.60

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 (298) hide show
  1. package/lib/collection-importer.js +101 -67
  2. package/lib/collection.js +339 -210
  3. package/lib/database.d.ts +4 -1
  4. package/lib/database.js +489 -275
  5. package/lib/fields/array-field.js +45 -25
  6. package/lib/fields/belongs-to-field.js +101 -54
  7. package/lib/fields/belongs-to-many-field.js +98 -53
  8. package/lib/fields/boolean-field.js +24 -9
  9. package/lib/fields/context-field.js +77 -42
  10. package/lib/fields/date-field.js +24 -9
  11. package/lib/fields/field.js +114 -75
  12. package/lib/fields/has-inverse-field.js +4 -2
  13. package/lib/fields/has-many-field.js +105 -56
  14. package/lib/fields/has-one-field.js +105 -54
  15. package/lib/fields/index.d.ts +3 -1
  16. package/lib/fields/index.js +277 -32
  17. package/lib/fields/json-field.js +36 -16
  18. package/lib/fields/number-field.js +53 -26
  19. package/lib/fields/password-field.js +118 -73
  20. package/lib/fields/radio-field.js +75 -47
  21. package/lib/fields/relation-field.js +41 -28
  22. package/lib/fields/sort-field.js +165 -89
  23. package/lib/fields/string-field.js +24 -9
  24. package/lib/fields/text-field.js +24 -9
  25. package/lib/fields/time-field.js +24 -9
  26. package/lib/fields/uid-field.js +57 -28
  27. package/lib/fields/uuid-field.d.ts +9 -0
  28. package/lib/fields/uuid-field.js +39 -0
  29. package/lib/fields/virtual-field.js +24 -9
  30. package/lib/filter-parser.js +288 -179
  31. package/lib/index.js +210 -29
  32. package/lib/magic-attribute-model.js +123 -71
  33. package/lib/mock-database.js +68 -34
  34. package/lib/model-hook.js +101 -60
  35. package/lib/model.js +116 -81
  36. package/lib/operators/array.js +136 -96
  37. package/lib/operators/association.js +30 -14
  38. package/lib/operators/boolean.d.ts +13 -0
  39. package/lib/operators/boolean.js +35 -0
  40. package/lib/operators/date.js +78 -34
  41. package/lib/operators/empty.js +113 -75
  42. package/lib/operators/index.js +15 -3
  43. package/lib/operators/ne.js +27 -12
  44. package/{esm/operators/ne.d.ts → lib/operators/notIn.d.ts} +2 -2
  45. package/lib/operators/notIn.js +29 -0
  46. package/lib/operators/string.js +56 -35
  47. package/lib/operators/utils.js +18 -10
  48. package/lib/options-parser.js +323 -215
  49. package/lib/playground.js +66 -53
  50. package/lib/relation-repository/belongs-to-many-repository.js +281 -198
  51. package/lib/relation-repository/belongs-to-repository.js +10 -6
  52. package/lib/relation-repository/hasmany-repository.js +168 -121
  53. package/lib/relation-repository/hasone-repository.js +10 -6
  54. package/lib/relation-repository/multiple-relation-repository.d.ts +3 -3
  55. package/lib/relation-repository/multiple-relation-repository.js +263 -148
  56. package/lib/relation-repository/relation-repository.d.ts +1 -1
  57. package/lib/relation-repository/relation-repository.js +155 -95
  58. package/lib/relation-repository/single-relation-repository.d.ts +6 -6
  59. package/lib/relation-repository/single-relation-repository.js +138 -99
  60. package/lib/relation-repository/types.js +4 -2
  61. package/lib/repository.d.ts +4 -7
  62. package/lib/repository.js +465 -291
  63. package/lib/transaction-decorator.js +80 -67
  64. package/lib/update-associations.d.ts +1 -2
  65. package/lib/update-associations.js +525 -321
  66. package/lib/update-guard.js +160 -117
  67. package/package.json +3 -8
  68. package/src/__tests__/fields/uuid-field.test.ts +30 -0
  69. package/src/__tests__/operator/notIn.test.ts +33 -0
  70. package/src/__tests__/option-parser.test.ts +20 -0
  71. package/src/database.ts +51 -4
  72. package/src/fields/context-field.ts +1 -1
  73. package/src/fields/index.ts +3 -0
  74. package/src/fields/uuid-field.ts +21 -0
  75. package/src/mock-database.ts +1 -1
  76. package/src/model-hook.ts +1 -1
  77. package/src/operators/boolean.ts +18 -0
  78. package/src/operators/index.ts +2 -0
  79. package/src/operators/notIn.ts +12 -0
  80. package/src/options-parser.ts +1 -1
  81. package/src/relation-repository/multiple-relation-repository.ts +8 -6
  82. package/src/relation-repository/relation-repository.ts +11 -6
  83. package/src/relation-repository/single-relation-repository.ts +6 -6
  84. package/src/repository.ts +4 -6
  85. package/src/update-associations.ts +1 -2
  86. package/esm/collection-importer.d.ts +0 -7
  87. package/esm/collection-importer.js +0 -49
  88. package/esm/collection-importer.js.map +0 -1
  89. package/esm/collection.d.ts +0 -73
  90. package/esm/collection.js +0 -224
  91. package/esm/collection.js.map +0 -1
  92. package/esm/database.d.ts +0 -101
  93. package/esm/database.js +0 -275
  94. package/esm/database.js.map +0 -1
  95. package/esm/fields/array-field.d.ts +0 -11
  96. package/esm/fields/array-field.js +0 -26
  97. package/esm/fields/array-field.js.map +0 -1
  98. package/esm/fields/belongs-to-field.d.ts +0 -12
  99. package/esm/fields/belongs-to-field.js +0 -57
  100. package/esm/fields/belongs-to-field.js.map +0 -1
  101. package/esm/fields/belongs-to-many-field.d.ts +0 -11
  102. package/esm/fields/belongs-to-many-field.js +0 -55
  103. package/esm/fields/belongs-to-many-field.js.map +0 -1
  104. package/esm/fields/boolean-field.d.ts +0 -8
  105. package/esm/fields/boolean-field.js +0 -8
  106. package/esm/fields/boolean-field.js.map +0 -1
  107. package/esm/fields/context-field.d.ts +0 -13
  108. package/esm/fields/context-field.js +0 -43
  109. package/esm/fields/context-field.js.map +0 -1
  110. package/esm/fields/date-field.d.ts +0 -8
  111. package/esm/fields/date-field.js +0 -8
  112. package/esm/fields/date-field.js.map +0 -1
  113. package/esm/fields/field.d.ts +0 -37
  114. package/esm/fields/field.js +0 -74
  115. package/esm/fields/field.js.map +0 -1
  116. package/esm/fields/has-inverse-field.d.ts +0 -4
  117. package/esm/fields/has-inverse-field.js +0 -2
  118. package/esm/fields/has-inverse-field.js.map +0 -1
  119. package/esm/fields/has-many-field.d.ts +0 -64
  120. package/esm/fields/has-many-field.js +0 -58
  121. package/esm/fields/has-many-field.js.map +0 -1
  122. package/esm/fields/has-one-field.d.ts +0 -64
  123. package/esm/fields/has-one-field.js +0 -57
  124. package/esm/fields/has-one-field.js.map +0 -1
  125. package/esm/fields/index.d.ts +0 -40
  126. package/esm/fields/index.js +0 -21
  127. package/esm/fields/index.js.map +0 -1
  128. package/esm/fields/json-field.d.ts +0 -14
  129. package/esm/fields/json-field.js +0 -17
  130. package/esm/fields/json-field.js.map +0 -1
  131. package/esm/fields/number-field.d.ts +0 -32
  132. package/esm/fields/number-field.js +0 -28
  133. package/esm/fields/number-field.js.map +0 -1
  134. package/esm/fields/password-field.d.ts +0 -21
  135. package/esm/fields/password-field.js +0 -71
  136. package/esm/fields/password-field.js.map +0 -1
  137. package/esm/fields/radio-field.d.ts +0 -14
  138. package/esm/fields/radio-field.js +0 -49
  139. package/esm/fields/radio-field.js.map +0 -1
  140. package/esm/fields/relation-field.d.ts +0 -20
  141. package/esm/fields/relation-field.js +0 -27
  142. package/esm/fields/relation-field.js.map +0 -1
  143. package/esm/fields/sort-field.d.ts +0 -16
  144. package/esm/fields/sort-field.js +0 -90
  145. package/esm/fields/sort-field.js.map +0 -1
  146. package/esm/fields/string-field.d.ts +0 -8
  147. package/esm/fields/string-field.js +0 -8
  148. package/esm/fields/string-field.js.map +0 -1
  149. package/esm/fields/text-field.d.ts +0 -8
  150. package/esm/fields/text-field.js +0 -8
  151. package/esm/fields/text-field.js.map +0 -1
  152. package/esm/fields/time-field.d.ts +0 -8
  153. package/esm/fields/time-field.js +0 -8
  154. package/esm/fields/time-field.js.map +0 -1
  155. package/esm/fields/uid-field.d.ts +0 -10
  156. package/esm/fields/uid-field.js +0 -27
  157. package/esm/fields/uid-field.js.map +0 -1
  158. package/esm/fields/virtual-field.d.ts +0 -8
  159. package/esm/fields/virtual-field.js +0 -8
  160. package/esm/fields/virtual-field.js.map +0 -1
  161. package/esm/filter-parser.d.ts +0 -27
  162. package/esm/filter-parser.js +0 -185
  163. package/esm/filter-parser.js.map +0 -1
  164. package/esm/index.d.ts +0 -15
  165. package/esm/index.js +0 -16
  166. package/esm/index.js.map +0 -1
  167. package/esm/magic-attribute-model.d.ts +0 -7
  168. package/esm/magic-attribute-model.js +0 -70
  169. package/esm/magic-attribute-model.js.map +0 -1
  170. package/esm/mock-database.d.ts +0 -22
  171. package/esm/mock-database.js +0 -34
  172. package/esm/mock-database.js.map +0 -1
  173. package/esm/model-hook.d.ts +0 -12
  174. package/esm/model-hook.js +0 -61
  175. package/esm/model-hook.js.map +0 -1
  176. package/esm/model.d.ts +0 -15
  177. package/esm/model.js +0 -80
  178. package/esm/model.js.map +0 -1
  179. package/esm/operators/array.d.ts +0 -26
  180. package/esm/operators/array.js +0 -105
  181. package/esm/operators/array.js.map +0 -1
  182. package/esm/operators/association.d.ts +0 -10
  183. package/esm/operators/association.js +0 -14
  184. package/esm/operators/association.js.map +0 -1
  185. package/esm/operators/date.d.ts +0 -34
  186. package/esm/operators/date.js +0 -35
  187. package/esm/operators/date.js.map +0 -1
  188. package/esm/operators/empty.d.ts +0 -28
  189. package/esm/operators/empty.js +0 -58
  190. package/esm/operators/empty.js.map +0 -1
  191. package/esm/operators/index.d.ts +0 -2
  192. package/esm/operators/index.js +0 -2
  193. package/esm/operators/index.js.map +0 -1
  194. package/esm/operators/ne.js +0 -12
  195. package/esm/operators/ne.js.map +0 -1
  196. package/esm/operators/string.d.ts +0 -21
  197. package/esm/operators/string.js +0 -35
  198. package/esm/operators/string.js.map +0 -1
  199. package/esm/operators/utils.d.ts +0 -4
  200. package/esm/operators/utils.js +0 -11
  201. package/esm/operators/utils.js.map +0 -1
  202. package/esm/options-parser.d.ts +0 -31
  203. package/esm/options-parser.js +0 -225
  204. package/esm/options-parser.js.map +0 -1
  205. package/esm/playground.d.ts +0 -1
  206. package/esm/playground.js +0 -53
  207. package/esm/playground.js.map +0 -1
  208. package/esm/relation-repository/belongs-to-many-repository.d.ts +0 -36
  209. package/esm/relation-repository/belongs-to-many-repository.js +0 -199
  210. package/esm/relation-repository/belongs-to-many-repository.js.map +0 -1
  211. package/esm/relation-repository/belongs-to-repository.d.ts +0 -17
  212. package/esm/relation-repository/belongs-to-repository.js +0 -4
  213. package/esm/relation-repository/belongs-to-repository.js.map +0 -1
  214. package/esm/relation-repository/hasmany-repository.d.ts +0 -23
  215. package/esm/relation-repository/hasmany-repository.js +0 -125
  216. package/esm/relation-repository/hasmany-repository.js.map +0 -1
  217. package/esm/relation-repository/hasone-repository.d.ts +0 -17
  218. package/esm/relation-repository/hasone-repository.js +0 -4
  219. package/esm/relation-repository/hasone-repository.js.map +0 -1
  220. package/esm/relation-repository/multiple-relation-repository.d.ts +0 -23
  221. package/esm/relation-repository/multiple-relation-repository.js +0 -149
  222. package/esm/relation-repository/multiple-relation-repository.js.map +0 -1
  223. package/esm/relation-repository/relation-repository.d.ts +0 -32
  224. package/esm/relation-repository/relation-repository.js +0 -93
  225. package/esm/relation-repository/relation-repository.js.map +0 -1
  226. package/esm/relation-repository/single-relation-repository.d.ts +0 -23
  227. package/esm/relation-repository/single-relation-repository.js +0 -96
  228. package/esm/relation-repository/single-relation-repository.js.map +0 -1
  229. package/esm/relation-repository/types.d.ts +0 -7
  230. package/esm/relation-repository/types.js +0 -2
  231. package/esm/relation-repository/types.js.map +0 -1
  232. package/esm/repository.d.ts +0 -165
  233. package/esm/repository.js +0 -276
  234. package/esm/repository.js.map +0 -1
  235. package/esm/transaction-decorator.d.ts +0 -1
  236. package/esm/transaction-decorator.js +0 -63
  237. package/esm/transaction-decorator.js.map +0 -1
  238. package/esm/update-associations.d.ts +0 -60
  239. package/esm/update-associations.js +0 -362
  240. package/esm/update-associations.js.map +0 -1
  241. package/esm/update-guard.d.ts +0 -26
  242. package/esm/update-guard.js +0 -122
  243. package/esm/update-guard.js.map +0 -1
  244. package/lib/collection-importer.js.map +0 -1
  245. package/lib/collection.js.map +0 -1
  246. package/lib/database.js.map +0 -1
  247. package/lib/fields/array-field.js.map +0 -1
  248. package/lib/fields/belongs-to-field.js.map +0 -1
  249. package/lib/fields/belongs-to-many-field.js.map +0 -1
  250. package/lib/fields/boolean-field.js.map +0 -1
  251. package/lib/fields/context-field.js.map +0 -1
  252. package/lib/fields/date-field.js.map +0 -1
  253. package/lib/fields/field.js.map +0 -1
  254. package/lib/fields/has-inverse-field.js.map +0 -1
  255. package/lib/fields/has-many-field.js.map +0 -1
  256. package/lib/fields/has-one-field.js.map +0 -1
  257. package/lib/fields/index.js.map +0 -1
  258. package/lib/fields/json-field.js.map +0 -1
  259. package/lib/fields/number-field.js.map +0 -1
  260. package/lib/fields/password-field.js.map +0 -1
  261. package/lib/fields/radio-field.js.map +0 -1
  262. package/lib/fields/relation-field.js.map +0 -1
  263. package/lib/fields/sort-field.js.map +0 -1
  264. package/lib/fields/string-field.js.map +0 -1
  265. package/lib/fields/text-field.js.map +0 -1
  266. package/lib/fields/time-field.js.map +0 -1
  267. package/lib/fields/uid-field.js.map +0 -1
  268. package/lib/fields/virtual-field.js.map +0 -1
  269. package/lib/filter-parser.js.map +0 -1
  270. package/lib/index.js.map +0 -1
  271. package/lib/magic-attribute-model.js.map +0 -1
  272. package/lib/mock-database.js.map +0 -1
  273. package/lib/model-hook.js.map +0 -1
  274. package/lib/model.js.map +0 -1
  275. package/lib/operators/array.js.map +0 -1
  276. package/lib/operators/association.js.map +0 -1
  277. package/lib/operators/date.js.map +0 -1
  278. package/lib/operators/empty.js.map +0 -1
  279. package/lib/operators/index.js.map +0 -1
  280. package/lib/operators/ne.js.map +0 -1
  281. package/lib/operators/string.js.map +0 -1
  282. package/lib/operators/utils.js.map +0 -1
  283. package/lib/options-parser.js.map +0 -1
  284. package/lib/playground.js.map +0 -1
  285. package/lib/relation-repository/belongs-to-many-repository.js.map +0 -1
  286. package/lib/relation-repository/belongs-to-repository.js.map +0 -1
  287. package/lib/relation-repository/hasmany-repository.js.map +0 -1
  288. package/lib/relation-repository/hasone-repository.js.map +0 -1
  289. package/lib/relation-repository/multiple-relation-repository.js.map +0 -1
  290. package/lib/relation-repository/relation-repository.js.map +0 -1
  291. package/lib/relation-repository/single-relation-repository.js.map +0 -1
  292. package/lib/relation-repository/types.js.map +0 -1
  293. package/lib/repository.js.map +0 -1
  294. package/lib/transaction-decorator.js.map +0 -1
  295. package/lib/update-associations.js.map +0 -1
  296. package/lib/update-guard.js.map +0 -1
  297. package/tsconfig.build.json +0 -9
  298. package/tsconfig.json +0 -5
@@ -1,129 +1,172 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
6
  exports.UpdateGuard = void 0;
7
- const lodash_1 = __importDefault(require("lodash"));
8
- const model_1 = require("./model");
7
+
8
+ function _lodash() {
9
+ const data = _interopRequireDefault(require("lodash"));
10
+
11
+ _lodash = function _lodash() {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ var _model = require("./model");
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
+
9
22
  class UpdateGuard {
10
- setAction(action) {
11
- this.action = action;
23
+ constructor() {
24
+ this.model = void 0;
25
+ this.action = void 0;
26
+ this.associationKeysToBeUpdate = void 0;
27
+ this.blackList = void 0;
28
+ this.whiteList = void 0;
29
+ }
30
+
31
+ setAction(action) {
32
+ this.action = action;
33
+ }
34
+
35
+ setModel(model) {
36
+ this.model = model;
37
+ }
38
+
39
+ setAssociationKeysToBeUpdate(associationKeysToBeUpdate) {
40
+ if (this.action == 'create') {
41
+ this.associationKeysToBeUpdate = Object.keys(this.model.associations);
42
+ } else {
43
+ this.associationKeysToBeUpdate = associationKeysToBeUpdate;
12
44
  }
13
- setModel(model) {
14
- this.model = model;
45
+ }
46
+
47
+ setWhiteList(whiteList) {
48
+ this.whiteList = whiteList;
49
+ }
50
+
51
+ setBlackList(blackList) {
52
+ this.blackList = blackList;
53
+ }
54
+ /**
55
+ * Sanitize values by whitelist blacklist
56
+ * @param values
57
+ */
58
+
59
+
60
+ sanitize(values) {
61
+ values = _lodash().default.clone(values);
62
+
63
+ if (!this.model) {
64
+ throw new Error('please set model first');
15
65
  }
16
- setAssociationKeysToBeUpdate(associationKeysToBeUpdate) {
17
- if (this.action == 'create') {
18
- this.associationKeysToBeUpdate = Object.keys(this.model.associations);
66
+
67
+ const associations = this.model.associations;
68
+
69
+ const associationsValues = _lodash().default.pick(values, Object.keys(associations)); // build params of association update guard
70
+
71
+
72
+ const listOfAssociation = (list, association) => {
73
+ if (list) {
74
+ list = list.filter(whiteListKey => whiteListKey.startsWith(`${association}.`)).map(whiteListKey => whiteListKey.replace(`${association}.`, ''));
75
+
76
+ if (list.length == 0) {
77
+ return undefined;
19
78
  }
20
- else {
21
- this.associationKeysToBeUpdate = associationKeysToBeUpdate;
79
+
80
+ return list;
81
+ }
82
+
83
+ return undefined;
84
+ }; // sanitize association values
85
+
86
+
87
+ Object.keys(associationsValues).forEach(association => {
88
+ let associationValues = associationsValues[association];
89
+
90
+ const filterAssociationToBeUpdate = value => {
91
+ const associationKeysToBeUpdate = this.associationKeysToBeUpdate || [];
92
+
93
+ if (associationKeysToBeUpdate.includes(association)) {
94
+ return value;
22
95
  }
23
- }
24
- setWhiteList(whiteList) {
25
- this.whiteList = whiteList;
26
- }
27
- setBlackList(blackList) {
28
- this.blackList = blackList;
29
- }
30
- /**
31
- * Sanitize values by whitelist blacklist
32
- * @param values
33
- */
34
- sanitize(values) {
35
- values = lodash_1.default.clone(values);
36
- if (!this.model) {
37
- throw new Error('please set model first');
96
+
97
+ const associationObj = associations[association];
98
+ const associationKeyName = associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne' ? associationObj.targetKey : associationObj.target.primaryKeyAttribute;
99
+
100
+ if (value[associationKeyName]) {
101
+ return _lodash().default.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
38
102
  }
39
- const associations = this.model.associations;
40
- const associationsValues = lodash_1.default.pick(values, Object.keys(associations));
41
- // build params of association update guard
42
- const listOfAssociation = (list, association) => {
43
- if (list) {
44
- list = list
45
- .filter((whiteListKey) => whiteListKey.startsWith(`${association}.`))
46
- .map((whiteListKey) => whiteListKey.replace(`${association}.`, ''));
47
- if (list.length == 0) {
48
- return undefined;
49
- }
50
- return list;
51
- }
52
- return undefined;
53
- };
54
- // sanitize association values
55
- Object.keys(associationsValues).forEach((association) => {
56
- let associationValues = associationsValues[association];
57
- const filterAssociationToBeUpdate = (value) => {
58
- const associationKeysToBeUpdate = this.associationKeysToBeUpdate || [];
59
- if (associationKeysToBeUpdate.includes(association)) {
60
- return value;
61
- }
62
- const associationObj = associations[association];
63
- const associationKeyName = associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne'
64
- ? associationObj.targetKey
65
- : associationObj.target.primaryKeyAttribute;
66
- if (value[associationKeyName]) {
67
- return lodash_1.default.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
68
- }
69
- return value;
70
- };
71
- const sanitizeValue = (value) => {
72
- const associationUpdateGuard = new UpdateGuard();
73
- associationUpdateGuard.setModel(associations[association].target);
74
- ['whiteList', 'blackList', 'associationKeysToBeUpdate'].forEach((optionKey) => {
75
- associationUpdateGuard[`set${lodash_1.default.upperFirst(optionKey)}`](listOfAssociation(this[optionKey], association));
76
- });
77
- return associationUpdateGuard.sanitize(filterAssociationToBeUpdate(value));
78
- };
79
- if (Array.isArray(associationValues)) {
80
- associationValues = associationValues.map((value) => {
81
- if (typeof value == 'string' || typeof value == 'number') {
82
- return value;
83
- }
84
- else {
85
- return sanitizeValue(value);
86
- }
87
- });
88
- }
89
- else if (typeof associationValues === 'object' && associationValues !== null) {
90
- associationValues = sanitizeValue(associationValues);
91
- }
92
- // set association values to sanitized value
93
- values[association] = associationValues;
103
+
104
+ return value;
105
+ };
106
+
107
+ const sanitizeValue = value => {
108
+ const associationUpdateGuard = new UpdateGuard();
109
+ associationUpdateGuard.setModel(associations[association].target);
110
+ ['whiteList', 'blackList', 'associationKeysToBeUpdate'].forEach(optionKey => {
111
+ associationUpdateGuard[`set${_lodash().default.upperFirst(optionKey)}`](listOfAssociation(this[optionKey], association));
94
112
  });
95
- if (values instanceof model_1.Model) {
96
- return values;
97
- }
98
- let valuesKeys = Object.keys(values || {});
99
- // handle whitelist
100
- if (this.whiteList) {
101
- valuesKeys = valuesKeys.filter((valueKey) => {
102
- return (this.whiteList.findIndex((whiteKey) => {
103
- const keyPaths = whiteKey.split('.');
104
- return keyPaths[0] === valueKey;
105
- }) !== -1);
106
- });
107
- }
108
- // handle blacklist
109
- if (this.blackList) {
110
- valuesKeys = valuesKeys.filter((valueKey) => !this.blackList.includes(valueKey));
111
- }
112
- const result = valuesKeys.reduce((obj, key) => {
113
- lodash_1.default.set(obj, key, values[key]);
114
- return obj;
115
- }, {});
116
- return result;
113
+ return associationUpdateGuard.sanitize(filterAssociationToBeUpdate(value));
114
+ };
115
+
116
+ if (Array.isArray(associationValues)) {
117
+ associationValues = associationValues.map(value => {
118
+ if (typeof value == 'string' || typeof value == 'number') {
119
+ return value;
120
+ } else {
121
+ return sanitizeValue(value);
122
+ }
123
+ });
124
+ } else if (typeof associationValues === 'object' && associationValues !== null) {
125
+ associationValues = sanitizeValue(associationValues);
126
+ } // set association values to sanitized value
127
+
128
+
129
+ values[association] = associationValues;
130
+ });
131
+
132
+ if (values instanceof _model.Model) {
133
+ return values;
117
134
  }
118
- static fromOptions(model, options) {
119
- const guard = new UpdateGuard();
120
- guard.setModel(model);
121
- guard.setWhiteList(options.whitelist);
122
- guard.setBlackList(options.blacklist);
123
- guard.setAction(lodash_1.default.get(options, 'action', 'update'));
124
- guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
125
- return guard;
135
+
136
+ let valuesKeys = Object.keys(values || {}); // handle whitelist
137
+
138
+ if (this.whiteList) {
139
+ valuesKeys = valuesKeys.filter(valueKey => {
140
+ return this.whiteList.findIndex(whiteKey => {
141
+ const keyPaths = whiteKey.split('.');
142
+ return keyPaths[0] === valueKey;
143
+ }) !== -1;
144
+ });
145
+ } // handle blacklist
146
+
147
+
148
+ if (this.blackList) {
149
+ valuesKeys = valuesKeys.filter(valueKey => !this.blackList.includes(valueKey));
126
150
  }
151
+
152
+ const result = valuesKeys.reduce((obj, key) => {
153
+ _lodash().default.set(obj, key, values[key]);
154
+
155
+ return obj;
156
+ }, {});
157
+ return result;
158
+ }
159
+
160
+ static fromOptions(model, options) {
161
+ const guard = new UpdateGuard();
162
+ guard.setModel(model);
163
+ guard.setWhiteList(options.whitelist);
164
+ guard.setBlackList(options.blacklist);
165
+ guard.setAction(_lodash().default.get(options, 'action', 'update'));
166
+ guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
167
+ return guard;
168
+ }
169
+
127
170
  }
128
- exports.UpdateGuard = UpdateGuard;
129
- //# sourceMappingURL=update-guard.js.map
171
+
172
+ exports.UpdateGuard = UpdateGuard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "0.7.0-alpha.6",
3
+ "version": "0.7.0-alpha.60",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -11,13 +11,8 @@
11
11
  "url": "http://www.apache.org/licenses/LICENSE-2.0"
12
12
  }
13
13
  ],
14
- "scripts": {
15
- "build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm",
16
- "build:cjs": "tsc --project tsconfig.build.json",
17
- "build:esm": "tsc --project tsconfig.build.json --module es2015 --outDir esm"
18
- },
19
14
  "dependencies": {
20
- "@nocobase/utils": "0.7.0-alpha.6",
15
+ "@nocobase/utils": "0.7.0-alpha.60",
21
16
  "async-mutex": "^0.3.2",
22
17
  "deepmerge": "^4.2.2",
23
18
  "flat": "^5.0.2",
@@ -29,5 +24,5 @@
29
24
  "url": "git+https://github.com/nocobase/nocobase.git",
30
25
  "directory": "packages/database"
31
26
  },
32
- "gitHead": "7d0087cbb3b7663ba05366ca3b80db2853669ee9"
27
+ "gitHead": "f0d0afbb19dbd90ac3cf4155748fa084c67f54ee"
33
28
  }
@@ -0,0 +1,30 @@
1
+ import { mockDatabase } from '../';
2
+ import { Database } from '../../database';
3
+
4
+ describe('string field', () => {
5
+ let db: Database;
6
+
7
+ beforeEach(async () => {
8
+ db = mockDatabase();
9
+ });
10
+
11
+ afterEach(async () => {
12
+ await db.close();
13
+ });
14
+
15
+ it('define', async () => {
16
+ const Test = db.collection({
17
+ name: 'tests',
18
+ autoGenId: false,
19
+ fields: [
20
+ {
21
+ type: 'uuid',
22
+ name: 'id',
23
+ primaryKey: true,
24
+ },
25
+ ],
26
+ });
27
+ await Test.sync();
28
+ await Test.model.create();
29
+ });
30
+ });
@@ -0,0 +1,33 @@
1
+ import { mockDatabase } from '../index';
2
+ import Database from '../../database';
3
+
4
+ describe('ne operator', () => {
5
+ let db: Database;
6
+ let Test;
7
+ beforeEach(async () => {
8
+ db = mockDatabase({});
9
+
10
+ Test = db.collection({
11
+ name: 'tests',
12
+ fields: [{ type: 'string', name: 'name' }],
13
+ });
14
+
15
+ await db.sync();
16
+ });
17
+
18
+ afterEach(async () => {
19
+ await db.close();
20
+ });
21
+
22
+ it('should notIn with null', async () => {
23
+ await db.getRepository('tests').create({});
24
+
25
+ const results = await db.getRepository('tests').count({
26
+ filter: {
27
+ 'name.$notIn': ['123'],
28
+ },
29
+ });
30
+
31
+ expect(results).toEqual(1);
32
+ });
33
+ });
@@ -81,6 +81,7 @@ describe('option parser', () => {
81
81
  ],
82
82
  });
83
83
  });
84
+
84
85
  test('with sort option', () => {
85
86
  let options: any = {
86
87
  sort: ['id'],
@@ -182,4 +183,23 @@ describe('option parser', () => {
182
183
 
183
184
  expect(params['include'][0]['attributes']['exclude']).toContain('id');
184
185
  });
186
+
187
+ test('option parser with multiple association', () => {
188
+ // fields with association field
189
+ const options = {
190
+ appends: ['user', 'comments.id', 'tags.id'],
191
+ };
192
+
193
+ const parser = new OptionsParser(options, {
194
+ collection: Post,
195
+ });
196
+
197
+ const params = parser.toSequelizeParams();
198
+ expect(params.include.length).toBe(3);
199
+ expect(params.include[0].association).toBe('user');
200
+ expect(params.include[1].association).toBe('comments');
201
+ expect(params.include[1].attributes).toEqual(['id']);
202
+ expect(params.include[2].association).toBe('tags');
203
+ expect(params.include[2].attributes).toEqual(['id']);
204
+ });
185
205
  });
package/src/database.ts CHANGED
@@ -2,7 +2,17 @@ import { applyMixins, AsyncEmitter } from '@nocobase/utils';
2
2
  import merge from 'deepmerge';
3
3
  import { EventEmitter } from 'events';
4
4
  import lodash from 'lodash';
5
- import { ModelCtor, Op, Options, QueryInterfaceDropAllTablesOptions, Sequelize, SyncOptions, Utils } from 'sequelize';
5
+ import { isAbsolute, resolve } from 'path';
6
+ import {
7
+ ModelCtor,
8
+ Op,
9
+ Options,
10
+ QueryInterfaceDropAllTablesOptions,
11
+ QueryOptions,
12
+ Sequelize,
13
+ SyncOptions,
14
+ Utils
15
+ } from 'sequelize';
6
16
  import { Collection, CollectionOptions, RepositoryType } from './collection';
7
17
  import { ImporterReader, ImportFileExtension } from './collection-importer';
8
18
  import * as FieldTypes from './fields';
@@ -64,8 +74,22 @@ export class Database extends EventEmitter implements AsyncEmitter {
64
74
  if (options instanceof Sequelize) {
65
75
  this.sequelize = options;
66
76
  } else {
67
- this.sequelize = new Sequelize(options);
68
- this.options = options;
77
+ const opts = {
78
+ sync: {
79
+ alter: {
80
+ drop: false,
81
+ },
82
+ force: false,
83
+ },
84
+ ...options,
85
+ };
86
+ if (options.storage && options.storage !== ':memory:') {
87
+ if (!isAbsolute(options.storage)) {
88
+ opts.storage = resolve(process.cwd(), options.storage);
89
+ }
90
+ }
91
+ this.sequelize = new Sequelize(opts);
92
+ this.options = opts;
69
93
  }
70
94
 
71
95
  this.collections = new Map();
@@ -248,6 +272,29 @@ export class Database extends EventEmitter implements AsyncEmitter {
248
272
  return this.sequelize.getDialect() === 'sqlite' && lodash.get(this.options, 'storage') == ':memory:';
249
273
  }
250
274
 
275
+ async auth(options: QueryOptions & { repeat?: number } = {}) {
276
+ const { repeat = 10, ...others } = options;
277
+ const delay = (ms) => new Promise((yea) => setTimeout(yea, ms));
278
+ let count = 1;
279
+ const authenticate = async () => {
280
+ try {
281
+ await this.sequelize.authenticate(others);
282
+ console.log('Connection has been established successfully.');
283
+ return true;
284
+ } catch (error) {
285
+ if (count >= repeat) {
286
+ throw error;
287
+ }
288
+ console.log('reconnecting...', count);
289
+ ++count;
290
+ await delay(500);
291
+ return await authenticate();
292
+ }
293
+ };
294
+
295
+ return await authenticate();
296
+ }
297
+
251
298
  async reconnect() {
252
299
  if (this.isSqliteMemory()) {
253
300
  return;
@@ -312,7 +359,7 @@ export class Database extends EventEmitter implements AsyncEmitter {
312
359
  return result;
313
360
  }
314
361
 
315
- emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;
362
+ declare emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;
316
363
  }
317
364
 
318
365
  export function extend(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions) {
@@ -1,4 +1,4 @@
1
- import { lodash } from '@umijs/utils';
1
+ import lodash from 'lodash';
2
2
  import { DataTypes } from 'sequelize';
3
3
  import { Model } from '../model';
4
4
  import { BaseColumnFieldOptions, Field } from './field';
@@ -22,6 +22,7 @@ import { StringFieldOptions } from './string-field';
22
22
  import { TextFieldOptions } from './text-field';
23
23
  import { TimeFieldOptions } from './time-field';
24
24
  import { UidFieldOptions } from './uid-field';
25
+ import { UUIDFieldOptions } from './uuid-field';
25
26
  import { VirtualFieldOptions } from './virtual-field';
26
27
 
27
28
  export * from './array-field';
@@ -43,6 +44,7 @@ export * from './string-field';
43
44
  export * from './text-field';
44
45
  export * from './time-field';
45
46
  export * from './uid-field';
47
+ export * from './uuid-field';
46
48
  export * from './virtual-field';
47
49
 
48
50
  export type FieldOptions =
@@ -64,6 +66,7 @@ export type FieldOptions =
64
66
  | TimeFieldOptions
65
67
  | DateFieldOptions
66
68
  | UidFieldOptions
69
+ | UUIDFieldOptions
67
70
  | PasswordFieldOptions
68
71
  | ContextFieldOptions
69
72
  | BelongsToFieldOptions
@@ -0,0 +1,21 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { BaseColumnFieldOptions, Field, FieldContext } from './field';
3
+
4
+ export class UuidField extends Field {
5
+ constructor(options?: any, context?: FieldContext) {
6
+ super(
7
+ {
8
+ defaultValue: DataTypes.UUIDV4,
9
+ ...options,
10
+ },
11
+ context,
12
+ );
13
+ }
14
+ get dataType() {
15
+ return DataTypes.UUID;
16
+ }
17
+ }
18
+
19
+ export interface UUIDFieldOptions extends BaseColumnFieldOptions {
20
+ type: 'uuid';
21
+ }
@@ -24,7 +24,7 @@ export function getConfigByEnv() {
24
24
  host: process.env.DB_HOST,
25
25
  port: process.env.DB_PORT,
26
26
  dialect: process.env.DB_DIALECT,
27
- logging: process.env.DB_LOG_SQL === 'on' ? console.log : false,
27
+ logging: process.env.DB_LOGGING === 'on' ? console.log : false,
28
28
  storage:
29
29
  process.env.DB_STORAGE && process.env.DB_STORAGE !== ':memory:'
30
30
  ? resolve(process.cwd(), process.env.DB_STORAGE)
package/src/model-hook.ts CHANGED
@@ -27,7 +27,7 @@ export class ModelHook {
27
27
 
28
28
  findModelName(hookArgs) {
29
29
  for (const arg of hookArgs) {
30
- if (arg instanceof Model) {
30
+ if (arg?._previousDataValues) {
31
31
  return (<Model>arg).constructor.name;
32
32
  }
33
33
 
@@ -0,0 +1,18 @@
1
+ import { Op } from 'sequelize';
2
+
3
+ export default {
4
+ $isFalsy() {
5
+ return {
6
+ [Op.or]: {
7
+ [Op.is]: null,
8
+ [Op.eq]: false,
9
+ },
10
+ };
11
+ },
12
+
13
+ $isTruly() {
14
+ return {
15
+ [Op.eq]: true,
16
+ };
17
+ },
18
+ };
@@ -5,4 +5,6 @@ export default {
5
5
  ...require('./empty').default,
6
6
  ...require('./string').default,
7
7
  ...require('./ne').default,
8
+ ...require('./notIn').default,
9
+ ...require('./boolean').default,
8
10
  };
@@ -0,0 +1,12 @@
1
+ import { Op } from 'sequelize';
2
+
3
+ export default {
4
+ $notIn(val, ctx) {
5
+ return {
6
+ [Op.or]: {
7
+ [Op.notIn]: val,
8
+ [Op.is]: null,
9
+ },
10
+ };
11
+ },
12
+ };
@@ -230,7 +230,7 @@ export class OptionsParser {
230
230
  association: appendAssociation,
231
231
  });
232
232
 
233
- existIncludeIndex = 0;
233
+ existIncludeIndex = queryParams['include'].length - 1;
234
234
  }
235
235
 
236
236
  // end appends
@@ -1,5 +1,5 @@
1
1
  import { omit } from 'lodash';
2
- import { MultiAssociationAccessors, Op, Sequelize, Transaction } from 'sequelize';
2
+ import { MultiAssociationAccessors, Op, Sequelize, Transaction, Transactionable } from 'sequelize';
3
3
  import {
4
4
  CommonFindOptions,
5
5
  CountOptions,
@@ -9,7 +9,6 @@ import {
9
9
  FindOptions,
10
10
  TargetKey,
11
11
  TK,
12
- TransactionAble,
13
12
  UpdateOptions
14
13
  } from '../repository';
15
14
  import { updateModelByValues } from '../update-associations';
@@ -20,7 +19,7 @@ export interface FindAndCountOptions extends CommonFindOptions {}
20
19
 
21
20
  export interface FindOneOptions extends CommonFindOptions, FilterByTk {}
22
21
 
23
- export interface AssociatedOptions extends TransactionAble {
22
+ export interface AssociatedOptions extends Transactionable {
24
23
  tk?: TK;
25
24
  }
26
25
 
@@ -150,7 +149,10 @@ export abstract class MultipleRelationRepository extends RelationRepository {
150
149
 
151
150
  const queryOptions = this.buildQueryOptions(options as any);
152
151
 
153
- const instances = await this.find(queryOptions);
152
+ const instances = await this.find({
153
+ ...queryOptions,
154
+ transaction,
155
+ });
154
156
 
155
157
  for (const instance of instances) {
156
158
  await updateModelByValues(instance, values, {
@@ -163,8 +165,8 @@ export abstract class MultipleRelationRepository extends RelationRepository {
163
165
 
164
166
  for (const instance of instances) {
165
167
  if (options.hooks !== false) {
166
- await this.db.emitAsync(`${this.targetCollection.name}.afterUpdateWithAssociations`, instance, options);
167
- await this.db.emitAsync(`${this.targetCollection.name}.afterSaveWithAssociations`, instance, options);
168
+ await this.db.emitAsync(`${this.targetCollection.name}.afterUpdateWithAssociations`, instance, {...options, transaction});
169
+ await this.db.emitAsync(`${this.targetCollection.name}.afterSaveWithAssociations`, instance, {...options, transaction});
168
170
  }
169
171
  }
170
172