@nocobase/database 0.5.0-alpha.38 → 0.7.0-alpha.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 (458) hide show
  1. package/LICENSE +201 -21
  2. package/esm/collection-importer.d.ts +7 -0
  3. package/esm/collection-importer.js +49 -0
  4. package/esm/collection-importer.js.map +1 -0
  5. package/esm/collection.d.ts +73 -0
  6. package/esm/collection.js +224 -0
  7. package/esm/collection.js.map +1 -0
  8. package/esm/database.d.ts +101 -0
  9. package/esm/database.js +275 -0
  10. package/esm/database.js.map +1 -0
  11. package/esm/fields/array-field.d.ts +11 -0
  12. package/esm/fields/array-field.js +26 -0
  13. package/esm/fields/array-field.js.map +1 -0
  14. package/esm/fields/belongs-to-field.d.ts +12 -0
  15. package/esm/fields/belongs-to-field.js +57 -0
  16. package/esm/fields/belongs-to-field.js.map +1 -0
  17. package/esm/fields/belongs-to-many-field.d.ts +11 -0
  18. package/esm/fields/belongs-to-many-field.js +55 -0
  19. package/esm/fields/belongs-to-many-field.js.map +1 -0
  20. package/esm/fields/boolean-field.d.ts +8 -0
  21. package/esm/fields/boolean-field.js +8 -0
  22. package/esm/fields/boolean-field.js.map +1 -0
  23. package/esm/fields/context-field.d.ts +13 -0
  24. package/esm/fields/context-field.js +43 -0
  25. package/esm/fields/context-field.js.map +1 -0
  26. package/esm/fields/date-field.d.ts +8 -0
  27. package/esm/fields/date-field.js +8 -0
  28. package/esm/fields/date-field.js.map +1 -0
  29. package/esm/fields/field.d.ts +37 -0
  30. package/esm/fields/field.js +74 -0
  31. package/esm/fields/field.js.map +1 -0
  32. package/esm/fields/has-inverse-field.d.ts +4 -0
  33. package/esm/fields/has-inverse-field.js +2 -0
  34. package/esm/fields/has-inverse-field.js.map +1 -0
  35. package/esm/fields/has-many-field.d.ts +64 -0
  36. package/esm/fields/has-many-field.js +58 -0
  37. package/esm/fields/has-many-field.js.map +1 -0
  38. package/esm/fields/has-one-field.d.ts +64 -0
  39. package/esm/fields/has-one-field.js +57 -0
  40. package/esm/fields/has-one-field.js.map +1 -0
  41. package/esm/fields/index.d.ts +40 -0
  42. package/esm/fields/index.js +21 -0
  43. package/esm/fields/index.js.map +1 -0
  44. package/esm/fields/json-field.d.ts +14 -0
  45. package/esm/fields/json-field.js +17 -0
  46. package/esm/fields/json-field.js.map +1 -0
  47. package/esm/fields/number-field.d.ts +32 -0
  48. package/esm/fields/number-field.js +28 -0
  49. package/esm/fields/number-field.js.map +1 -0
  50. package/esm/fields/password-field.d.ts +21 -0
  51. package/esm/fields/password-field.js +71 -0
  52. package/esm/fields/password-field.js.map +1 -0
  53. package/esm/fields/radio-field.d.ts +14 -0
  54. package/esm/fields/radio-field.js +49 -0
  55. package/esm/fields/radio-field.js.map +1 -0
  56. package/esm/fields/relation-field.d.ts +20 -0
  57. package/esm/fields/relation-field.js +27 -0
  58. package/esm/fields/relation-field.js.map +1 -0
  59. package/esm/fields/sort-field.d.ts +16 -0
  60. package/esm/fields/sort-field.js +90 -0
  61. package/esm/fields/sort-field.js.map +1 -0
  62. package/esm/fields/string-field.d.ts +8 -0
  63. package/esm/fields/string-field.js +8 -0
  64. package/esm/fields/string-field.js.map +1 -0
  65. package/esm/fields/text-field.d.ts +8 -0
  66. package/esm/fields/text-field.js +8 -0
  67. package/esm/fields/text-field.js.map +1 -0
  68. package/esm/fields/time-field.d.ts +8 -0
  69. package/esm/fields/time-field.js +8 -0
  70. package/esm/fields/time-field.js.map +1 -0
  71. package/esm/fields/uid-field.d.ts +10 -0
  72. package/esm/fields/uid-field.js +27 -0
  73. package/esm/fields/uid-field.js.map +1 -0
  74. package/esm/fields/virtual-field.d.ts +8 -0
  75. package/esm/fields/virtual-field.js +8 -0
  76. package/esm/fields/virtual-field.js.map +1 -0
  77. package/esm/filter-parser.d.ts +27 -0
  78. package/esm/filter-parser.js +185 -0
  79. package/esm/filter-parser.js.map +1 -0
  80. package/esm/index.d.ts +15 -0
  81. package/esm/index.js +16 -0
  82. package/esm/index.js.map +1 -0
  83. package/esm/magic-attribute-model.d.ts +7 -0
  84. package/esm/magic-attribute-model.js +70 -0
  85. package/esm/magic-attribute-model.js.map +1 -0
  86. package/esm/mock-database.d.ts +22 -0
  87. package/esm/mock-database.js +34 -0
  88. package/esm/mock-database.js.map +1 -0
  89. package/esm/model-hook.d.ts +12 -0
  90. package/esm/model-hook.js +61 -0
  91. package/esm/model-hook.js.map +1 -0
  92. package/esm/model.d.ts +15 -0
  93. package/esm/model.js +80 -0
  94. package/esm/model.js.map +1 -0
  95. package/esm/operators/array.d.ts +26 -0
  96. package/esm/operators/array.js +105 -0
  97. package/esm/operators/array.js.map +1 -0
  98. package/esm/operators/association.d.ts +10 -0
  99. package/esm/operators/association.js +14 -0
  100. package/esm/operators/association.js.map +1 -0
  101. package/esm/operators/date.d.ts +34 -0
  102. package/esm/operators/date.js +35 -0
  103. package/esm/operators/date.js.map +1 -0
  104. package/esm/operators/empty.d.ts +28 -0
  105. package/esm/operators/empty.js +58 -0
  106. package/esm/operators/empty.js.map +1 -0
  107. package/esm/operators/index.d.ts +2 -0
  108. package/esm/operators/index.js +2 -0
  109. package/esm/operators/index.js.map +1 -0
  110. package/esm/operators/ne.d.ts +10 -0
  111. package/esm/operators/ne.js +12 -0
  112. package/esm/operators/ne.js.map +1 -0
  113. package/esm/operators/string.d.ts +21 -0
  114. package/esm/operators/string.js +35 -0
  115. package/esm/operators/string.js.map +1 -0
  116. package/esm/operators/utils.d.ts +4 -0
  117. package/esm/operators/utils.js +11 -0
  118. package/esm/operators/utils.js.map +1 -0
  119. package/esm/options-parser.d.ts +31 -0
  120. package/esm/options-parser.js +225 -0
  121. package/esm/options-parser.js.map +1 -0
  122. package/esm/playground.d.ts +1 -0
  123. package/esm/playground.js +53 -0
  124. package/esm/playground.js.map +1 -0
  125. package/esm/relation-repository/belongs-to-many-repository.d.ts +36 -0
  126. package/esm/relation-repository/belongs-to-many-repository.js +199 -0
  127. package/esm/relation-repository/belongs-to-many-repository.js.map +1 -0
  128. package/esm/relation-repository/belongs-to-repository.d.ts +17 -0
  129. package/esm/relation-repository/belongs-to-repository.js +4 -0
  130. package/esm/relation-repository/belongs-to-repository.js.map +1 -0
  131. package/esm/relation-repository/hasmany-repository.d.ts +23 -0
  132. package/esm/relation-repository/hasmany-repository.js +125 -0
  133. package/esm/relation-repository/hasmany-repository.js.map +1 -0
  134. package/esm/relation-repository/hasone-repository.d.ts +17 -0
  135. package/esm/relation-repository/hasone-repository.js +4 -0
  136. package/esm/relation-repository/hasone-repository.js.map +1 -0
  137. package/esm/relation-repository/multiple-relation-repository.d.ts +23 -0
  138. package/esm/relation-repository/multiple-relation-repository.js +149 -0
  139. package/esm/relation-repository/multiple-relation-repository.js.map +1 -0
  140. package/esm/relation-repository/relation-repository.d.ts +32 -0
  141. package/esm/relation-repository/relation-repository.js +93 -0
  142. package/esm/relation-repository/relation-repository.js.map +1 -0
  143. package/esm/relation-repository/single-relation-repository.d.ts +23 -0
  144. package/esm/relation-repository/single-relation-repository.js +96 -0
  145. package/esm/relation-repository/single-relation-repository.js.map +1 -0
  146. package/esm/relation-repository/types.d.ts +7 -0
  147. package/esm/relation-repository/types.js +2 -0
  148. package/esm/relation-repository/types.js.map +1 -0
  149. package/esm/repository.d.ts +165 -0
  150. package/esm/repository.js +276 -0
  151. package/esm/repository.js.map +1 -0
  152. package/esm/transaction-decorator.d.ts +1 -0
  153. package/esm/transaction-decorator.js +63 -0
  154. package/esm/transaction-decorator.js.map +1 -0
  155. package/esm/update-associations.d.ts +60 -0
  156. package/esm/update-associations.js +362 -0
  157. package/esm/update-associations.js.map +1 -0
  158. package/esm/update-guard.d.ts +26 -0
  159. package/esm/update-guard.js +122 -0
  160. package/esm/update-guard.js.map +1 -0
  161. package/lib/collection-importer.d.ts +7 -0
  162. package/lib/collection-importer.js +75 -0
  163. package/lib/collection-importer.js.map +1 -0
  164. package/lib/collection.d.ts +73 -0
  165. package/lib/collection.js +231 -0
  166. package/lib/collection.js.map +1 -0
  167. package/lib/database.d.ts +93 -43
  168. package/lib/database.js +277 -471
  169. package/lib/database.js.map +1 -1
  170. package/lib/fields/array-field.d.ts +11 -0
  171. package/lib/fields/array-field.js +30 -0
  172. package/lib/fields/array-field.js.map +1 -0
  173. package/lib/fields/belongs-to-field.d.ts +12 -0
  174. package/lib/fields/belongs-to-field.js +61 -0
  175. package/lib/fields/belongs-to-field.js.map +1 -0
  176. package/lib/fields/belongs-to-many-field.d.ts +11 -0
  177. package/lib/fields/belongs-to-many-field.js +59 -0
  178. package/lib/fields/belongs-to-many-field.js.map +1 -0
  179. package/lib/fields/boolean-field.d.ts +8 -0
  180. package/lib/fields/boolean-field.js +12 -0
  181. package/lib/fields/boolean-field.js.map +1 -0
  182. package/lib/fields/context-field.d.ts +13 -0
  183. package/lib/fields/context-field.js +47 -0
  184. package/lib/fields/context-field.js.map +1 -0
  185. package/lib/fields/date-field.d.ts +8 -0
  186. package/lib/fields/date-field.js +12 -0
  187. package/lib/fields/date-field.js.map +1 -0
  188. package/lib/fields/field.d.ts +37 -0
  189. package/lib/fields/field.js +81 -0
  190. package/lib/fields/field.js.map +1 -0
  191. package/lib/fields/has-inverse-field.d.ts +4 -0
  192. package/lib/fields/has-inverse-field.js +3 -0
  193. package/lib/fields/has-inverse-field.js.map +1 -0
  194. package/lib/fields/has-many-field.d.ts +64 -0
  195. package/lib/fields/has-many-field.js +62 -0
  196. package/lib/fields/has-many-field.js.map +1 -0
  197. package/lib/fields/has-one-field.d.ts +64 -0
  198. package/lib/fields/has-one-field.js +61 -0
  199. package/lib/fields/has-one-field.js.map +1 -0
  200. package/lib/fields/index.d.ts +40 -10
  201. package/lib/fields/index.js +31 -138
  202. package/lib/fields/index.js.map +1 -1
  203. package/lib/fields/json-field.d.ts +14 -0
  204. package/lib/fields/json-field.js +22 -0
  205. package/lib/fields/json-field.js.map +1 -0
  206. package/lib/fields/number-field.d.ts +32 -0
  207. package/lib/fields/number-field.js +36 -0
  208. package/lib/fields/number-field.js.map +1 -0
  209. package/lib/fields/password-field.d.ts +21 -0
  210. package/lib/fields/password-field.js +78 -0
  211. package/lib/fields/password-field.js.map +1 -0
  212. package/lib/fields/radio-field.d.ts +14 -0
  213. package/lib/fields/radio-field.js +53 -0
  214. package/lib/fields/radio-field.js.map +1 -0
  215. package/lib/fields/relation-field.d.ts +20 -0
  216. package/lib/fields/relation-field.js +31 -0
  217. package/lib/fields/relation-field.js.map +1 -0
  218. package/lib/fields/sort-field.d.ts +16 -0
  219. package/lib/fields/sort-field.js +94 -0
  220. package/lib/fields/sort-field.js.map +1 -0
  221. package/lib/fields/string-field.d.ts +8 -0
  222. package/lib/fields/string-field.js +12 -0
  223. package/lib/fields/string-field.js.map +1 -0
  224. package/lib/fields/text-field.d.ts +8 -0
  225. package/lib/fields/text-field.js +12 -0
  226. package/lib/fields/text-field.js.map +1 -0
  227. package/lib/fields/time-field.d.ts +8 -0
  228. package/lib/fields/time-field.js +12 -0
  229. package/lib/fields/time-field.js.map +1 -0
  230. package/lib/fields/uid-field.d.ts +10 -0
  231. package/lib/fields/uid-field.js +31 -0
  232. package/lib/fields/uid-field.js.map +1 -0
  233. package/lib/fields/virtual-field.d.ts +8 -0
  234. package/lib/fields/virtual-field.js +12 -0
  235. package/lib/fields/virtual-field.js.map +1 -0
  236. package/lib/filter-parser.d.ts +27 -0
  237. package/lib/filter-parser.js +191 -0
  238. package/lib/filter-parser.js.map +1 -0
  239. package/lib/index.d.ts +13 -6
  240. package/lib/index.js +27 -60
  241. package/lib/index.js.map +1 -1
  242. package/lib/magic-attribute-model.d.ts +7 -0
  243. package/lib/magic-attribute-model.js +77 -0
  244. package/lib/magic-attribute-model.js.map +1 -0
  245. package/lib/mock-database.d.ts +22 -0
  246. package/lib/mock-database.js +40 -0
  247. package/lib/mock-database.js.map +1 -0
  248. package/lib/model-hook.d.ts +12 -0
  249. package/lib/model-hook.js +68 -0
  250. package/lib/model-hook.js.map +1 -0
  251. package/lib/model.d.ts +11 -45
  252. package/lib/model.js +76 -452
  253. package/lib/model.js.map +1 -1
  254. package/lib/operators/array.d.ts +26 -0
  255. package/lib/operators/array.js +107 -0
  256. package/lib/operators/array.js.map +1 -0
  257. package/lib/operators/association.d.ts +10 -0
  258. package/lib/operators/association.js +16 -0
  259. package/lib/operators/association.js.map +1 -0
  260. package/lib/operators/date.d.ts +34 -0
  261. package/lib/operators/date.js +40 -0
  262. package/lib/operators/date.js.map +1 -0
  263. package/lib/operators/empty.d.ts +28 -0
  264. package/lib/operators/empty.js +82 -0
  265. package/lib/operators/empty.js.map +1 -0
  266. package/lib/operators/index.d.ts +2 -0
  267. package/lib/operators/index.js +4 -0
  268. package/lib/operators/index.js.map +1 -0
  269. package/lib/operators/ne.d.ts +10 -0
  270. package/lib/operators/ne.js +14 -0
  271. package/lib/operators/ne.js.map +1 -0
  272. package/lib/operators/string.d.ts +21 -0
  273. package/lib/operators/string.js +37 -0
  274. package/lib/operators/string.js.map +1 -0
  275. package/lib/operators/utils.d.ts +4 -0
  276. package/lib/operators/utils.js +16 -0
  277. package/lib/operators/utils.js.map +1 -0
  278. package/lib/options-parser.d.ts +31 -0
  279. package/lib/options-parser.js +232 -0
  280. package/lib/options-parser.js.map +1 -0
  281. package/lib/playground.d.ts +1 -0
  282. package/lib/playground.js +55 -0
  283. package/lib/playground.js.map +1 -0
  284. package/lib/relation-repository/belongs-to-many-repository.d.ts +36 -0
  285. package/lib/relation-repository/belongs-to-many-repository.js +206 -0
  286. package/lib/relation-repository/belongs-to-many-repository.js.map +1 -0
  287. package/lib/relation-repository/belongs-to-repository.d.ts +17 -0
  288. package/lib/relation-repository/belongs-to-repository.js +8 -0
  289. package/lib/relation-repository/belongs-to-repository.js.map +1 -0
  290. package/lib/relation-repository/hasmany-repository.d.ts +23 -0
  291. package/lib/relation-repository/hasmany-repository.js +129 -0
  292. package/lib/relation-repository/hasmany-repository.js.map +1 -0
  293. package/lib/relation-repository/hasone-repository.d.ts +17 -0
  294. package/lib/relation-repository/hasone-repository.js +8 -0
  295. package/lib/relation-repository/hasone-repository.js.map +1 -0
  296. package/lib/relation-repository/multiple-relation-repository.d.ts +23 -0
  297. package/lib/relation-repository/multiple-relation-repository.js +153 -0
  298. package/lib/relation-repository/multiple-relation-repository.js.map +1 -0
  299. package/lib/relation-repository/relation-repository.d.ts +32 -0
  300. package/lib/relation-repository/relation-repository.js +100 -0
  301. package/lib/relation-repository/relation-repository.js.map +1 -0
  302. package/lib/relation-repository/single-relation-repository.d.ts +23 -0
  303. package/lib/relation-repository/single-relation-repository.js +103 -0
  304. package/lib/relation-repository/single-relation-repository.js.map +1 -0
  305. package/lib/relation-repository/types.d.ts +7 -0
  306. package/lib/relation-repository/types.js +3 -0
  307. package/lib/relation-repository/types.js.map +1 -0
  308. package/lib/repository.d.ts +165 -0
  309. package/lib/repository.js +302 -0
  310. package/lib/repository.js.map +1 -0
  311. package/lib/transaction-decorator.d.ts +1 -0
  312. package/lib/transaction-decorator.js +70 -0
  313. package/lib/transaction-decorator.js.map +1 -0
  314. package/lib/update-associations.d.ts +60 -0
  315. package/lib/update-associations.js +374 -0
  316. package/lib/update-associations.js.map +1 -0
  317. package/lib/update-guard.d.ts +26 -0
  318. package/lib/update-guard.js +129 -0
  319. package/lib/update-guard.js.map +1 -0
  320. package/package.json +17 -5
  321. package/src/__tests__/collection-importer.test.ts +21 -0
  322. package/src/__tests__/collection.sortable.test.ts +65 -0
  323. package/src/__tests__/collection.test.ts +218 -0
  324. package/src/__tests__/database.import.test.ts +33 -0
  325. package/src/__tests__/database.test.ts +229 -0
  326. package/src/__tests__/field-options/hidden.test.ts +302 -0
  327. package/src/__tests__/field-options/sort-by.test.ts +220 -0
  328. package/src/__tests__/fields/belongs-to-field.test.ts +162 -0
  329. package/src/__tests__/fields/belongs-to-many-field.test.ts +61 -0
  330. package/src/__tests__/fields/context-field.test.ts +140 -0
  331. package/src/__tests__/fields/has-many-field.test.ts +152 -0
  332. package/src/__tests__/fields/has-one-field.test.ts +67 -0
  333. package/src/__tests__/fields/password-field.test.ts +30 -0
  334. package/src/__tests__/fields/sort-field.test.ts +133 -0
  335. package/src/__tests__/fields/string-field.test.ts +77 -0
  336. package/src/__tests__/filter-parser.test.ts +104 -0
  337. package/src/__tests__/fixtures/c0/a.ts +6 -0
  338. package/src/__tests__/fixtures/c1/b.ts +6 -0
  339. package/src/__tests__/fixtures/c2/a.ts +6 -0
  340. package/src/__tests__/fixtures/collections/delay-extend.ts +6 -0
  341. package/src/__tests__/fixtures/collections/delay-extend2.ts +6 -0
  342. package/src/__tests__/fixtures/collections/extend.ts +6 -0
  343. package/src/__tests__/fixtures/collections/extend2.ts +6 -0
  344. package/src/__tests__/fixtures/collections/posts.ts +4 -0
  345. package/src/__tests__/fixtures/collections/tags.js +4 -0
  346. package/src/__tests__/fixtures/collections/test.jpg +0 -0
  347. package/src/__tests__/fixtures/collections/user.json +9 -0
  348. package/src/__tests__/index.ts +1 -0
  349. package/src/__tests__/magic-attribute-model.test.ts +103 -0
  350. package/src/__tests__/model.test.ts +60 -0
  351. package/src/__tests__/operator/array-operator.test.ts +268 -0
  352. package/src/__tests__/operator/association-operator.test.ts +263 -0
  353. package/src/__tests__/operator/date-operator.test.ts +165 -0
  354. package/src/__tests__/operator/empty-operator.test.ts +77 -0
  355. package/src/__tests__/operator/ne.test.ts +33 -0
  356. package/src/__tests__/operator/string-operator.test.ts +62 -0
  357. package/src/__tests__/option-parser.test.ts +185 -0
  358. package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +697 -0
  359. package/src/__tests__/relation-repository/has-many-repository.test.ts +414 -0
  360. package/src/__tests__/relation-repository/hasone-repository.test.ts +77 -0
  361. package/src/__tests__/repository/count.test.ts +180 -0
  362. package/src/__tests__/repository/create.test.ts +163 -0
  363. package/src/__tests__/repository/destroy.test.ts +196 -0
  364. package/src/__tests__/repository/find.test.ts +247 -0
  365. package/src/__tests__/repository/update.test.ts +60 -0
  366. package/src/__tests__/repository.test.ts +438 -0
  367. package/src/__tests__/update-associations.test.ts +412 -0
  368. package/src/__tests__/update-guard.test.ts +376 -0
  369. package/src/collection-importer.ts +49 -0
  370. package/src/collection.ts +282 -0
  371. package/src/database.ts +340 -0
  372. package/src/fields/array-field.ts +35 -0
  373. package/src/fields/belongs-to-field.ts +76 -0
  374. package/src/fields/belongs-to-many-field.ts +77 -0
  375. package/src/fields/boolean-field.ts +12 -0
  376. package/src/fields/context-field.ts +45 -0
  377. package/src/fields/date-field.ts +12 -0
  378. package/src/fields/field.ts +105 -0
  379. package/src/fields/has-inverse-field.ts +5 -0
  380. package/src/fields/has-many-field.ts +143 -0
  381. package/src/fields/has-one-field.ts +136 -0
  382. package/src/fields/index.ts +72 -0
  383. package/src/fields/json-field.ts +25 -0
  384. package/src/fields/number-field.ts +52 -0
  385. package/src/fields/password-field.ts +72 -0
  386. package/src/fields/radio-field.ts +50 -0
  387. package/src/fields/relation-field.ts +37 -0
  388. package/src/fields/sort-field.ts +96 -0
  389. package/src/fields/string-field.ts +12 -0
  390. package/src/fields/text-field.ts +12 -0
  391. package/src/fields/time-field.ts +12 -0
  392. package/src/fields/uid-field.ts +24 -0
  393. package/src/fields/virtual-field.ts +12 -0
  394. package/src/filter-parser.ts +243 -0
  395. package/src/index.ts +16 -0
  396. package/src/magic-attribute-model.ts +62 -0
  397. package/src/mock-database.ts +42 -0
  398. package/src/model-hook.ts +69 -0
  399. package/src/model.ts +114 -0
  400. package/src/operators/array.ts +145 -0
  401. package/src/operators/association.ts +14 -0
  402. package/src/operators/date.ts +41 -0
  403. package/src/operators/empty.ts +75 -0
  404. package/src/operators/index.ts +8 -0
  405. package/src/operators/ne.ts +12 -0
  406. package/src/operators/string.ts +40 -0
  407. package/src/operators/utils.ts +13 -0
  408. package/src/options-parser.ts +285 -0
  409. package/src/playground.ts +52 -0
  410. package/src/relation-repository/belongs-to-many-repository.ts +240 -0
  411. package/src/relation-repository/belongs-to-repository.ts +23 -0
  412. package/src/relation-repository/hasmany-repository.ts +145 -0
  413. package/src/relation-repository/hasone-repository.ts +23 -0
  414. package/src/relation-repository/multiple-relation-repository.ts +198 -0
  415. package/src/relation-repository/relation-repository.ts +114 -0
  416. package/src/relation-repository/single-relation-repository.ts +99 -0
  417. package/src/relation-repository/types.ts +15 -0
  418. package/src/repository.ts +478 -0
  419. package/src/transaction-decorator.ts +58 -0
  420. package/src/update-associations.ts +478 -0
  421. package/src/update-guard.ts +167 -0
  422. package/tsconfig.build.json +9 -0
  423. package/tsconfig.json +5 -0
  424. package/examples/index.ts +0 -125
  425. package/examples/plugins/db-driven/index.ts +0 -25
  426. package/examples/plugins/db-driven/tables/fields.ts +0 -78
  427. package/examples/plugins/db-driven/tables/tables.ts +0 -53
  428. package/examples/tables/bar.js +0 -26
  429. package/examples/tables/comments.ts +0 -19
  430. package/examples/tables/foo.json +0 -3
  431. package/examples/tables/posts.ts +0 -28
  432. package/examples/tables/profiles.ts +0 -23
  433. package/examples/tables/tags.ts +0 -15
  434. package/examples/tables/users.ts +0 -34
  435. package/lib/database.d.ts.map +0 -1
  436. package/lib/fields/field-types.d.ts +0 -419
  437. package/lib/fields/field-types.d.ts.map +0 -1
  438. package/lib/fields/field-types.js +0 -1222
  439. package/lib/fields/field-types.js.map +0 -1
  440. package/lib/fields/index.d.ts.map +0 -1
  441. package/lib/fields/option-types.d.ts +0 -105
  442. package/lib/fields/option-types.d.ts.map +0 -1
  443. package/lib/fields/option-types.js +0 -18
  444. package/lib/fields/option-types.js.map +0 -1
  445. package/lib/index.d.ts.map +0 -1
  446. package/lib/model.d.ts.map +0 -1
  447. package/lib/op.d.ts +0 -45
  448. package/lib/op.d.ts.map +0 -1
  449. package/lib/op.js +0 -225
  450. package/lib/op.js.map +0 -1
  451. package/lib/table.d.ts +0 -56
  452. package/lib/table.d.ts.map +0 -1
  453. package/lib/table.js +0 -456
  454. package/lib/table.js.map +0 -1
  455. package/lib/utils.d.ts +0 -26
  456. package/lib/utils.d.ts.map +0 -1
  457. package/lib/utils.js +0 -438
  458. package/lib/utils.js.map +0 -1
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.transactionWrapperBuilder = void 0;
16
+ const lodash_1 = __importDefault(require("lodash"));
17
+ function transactionWrapperBuilder(transactionGenerator) {
18
+ return function transaction(transactionInjector) {
19
+ return (target, name, descriptor) => {
20
+ const oldValue = descriptor.value;
21
+ descriptor.value = function () {
22
+ return __awaiter(this, arguments, void 0, function* () {
23
+ let transaction;
24
+ let newTransaction = false;
25
+ if (arguments.length > 0 && typeof arguments[0] === 'object') {
26
+ transaction = arguments[0]['transaction'];
27
+ }
28
+ if (!transaction) {
29
+ transaction = yield transactionGenerator.apply(this);
30
+ newTransaction = true;
31
+ }
32
+ // 需要将 newTransaction 注入到被装饰函数参数内
33
+ if (newTransaction) {
34
+ try {
35
+ let callArguments;
36
+ if (lodash_1.default.isPlainObject(arguments[0])) {
37
+ callArguments = Object.assign(Object.assign({}, arguments[0]), { transaction });
38
+ }
39
+ else if (transactionInjector) {
40
+ callArguments = transactionInjector(arguments, transaction);
41
+ }
42
+ else if (lodash_1.default.isNull(arguments[0]) || lodash_1.default.isUndefined(arguments[0])) {
43
+ callArguments = {
44
+ transaction,
45
+ };
46
+ }
47
+ else {
48
+ throw new Error(`please provide transactionInjector for ${name} call`);
49
+ }
50
+ const results = yield oldValue.apply(this, [callArguments]);
51
+ yield transaction.commit();
52
+ return results;
53
+ }
54
+ catch (err) {
55
+ console.error({ err });
56
+ yield transaction.rollback();
57
+ throw err;
58
+ }
59
+ }
60
+ else {
61
+ return oldValue.apply(this, arguments);
62
+ }
63
+ });
64
+ };
65
+ return descriptor;
66
+ };
67
+ };
68
+ }
69
+ exports.transactionWrapperBuilder = transactionWrapperBuilder;
70
+ //# sourceMappingURL=transaction-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-decorator.js","sourceRoot":"","sources":["../src/transaction-decorator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,oDAA4B;AAE5B,SAAgB,yBAAyB,CAAC,oBAAoB;IAC5D,OAAO,SAAS,WAAW,CAAC,mBAAoB;QAC9C,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;YAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;YAElC,UAAU,CAAC,KAAK,GAAG;;oBACjB,IAAI,WAAW,CAAC;oBAChB,IAAI,cAAc,GAAG,KAAK,CAAC;oBAE3B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;wBAC5D,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;qBAC3C;oBAED,IAAI,CAAC,WAAW,EAAE;wBAChB,WAAW,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACrD,cAAc,GAAG,IAAI,CAAC;qBACvB;oBAED,iCAAiC;oBACjC,IAAI,cAAc,EAAE;wBAClB,IAAI;4BACF,IAAI,aAAa,CAAC;4BAClB,IAAI,gBAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;gCACtC,aAAa,mCACR,SAAS,CAAC,CAAC,CAAC,KACf,WAAW,GACZ,CAAC;6BACH;iCAAM,IAAI,mBAAmB,EAAE;gCAC9B,aAAa,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;6BAC7D;iCAAM,IAAI,gBAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,gBAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;gCAC1E,aAAa,GAAG;oCACd,WAAW;iCACZ,CAAC;6BACH;iCAAM;gCACL,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,OAAO,CAAC,CAAC;6BACxE;4BAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;4BAE5D,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC;4BAE3B,OAAO,OAAO,CAAC;yBAChB;wBAAC,OAAO,GAAG,EAAE;4BACZ,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;4BACvB,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;4BAC7B,MAAM,GAAG,CAAC;yBACX;qBACF;yBAAM;wBACL,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;qBACxC;gBACH,CAAC;aAAA,CAAC;YAEF,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAvDD,8DAuDC","sourcesContent":["import lodash from 'lodash';\n\nexport function transactionWrapperBuilder(transactionGenerator) {\n return function transaction(transactionInjector?) {\n return (target, name, descriptor) => {\n const oldValue = descriptor.value;\n\n descriptor.value = async function () {\n let transaction;\n let newTransaction = false;\n\n if (arguments.length > 0 && typeof arguments[0] === 'object') {\n transaction = arguments[0]['transaction'];\n }\n\n if (!transaction) {\n transaction = await transactionGenerator.apply(this);\n newTransaction = true;\n }\n\n // 需要将 newTransaction 注入到被装饰函数参数内\n if (newTransaction) {\n try {\n let callArguments;\n if (lodash.isPlainObject(arguments[0])) {\n callArguments = {\n ...arguments[0],\n transaction,\n };\n } else if (transactionInjector) {\n callArguments = transactionInjector(arguments, transaction);\n } else if (lodash.isNull(arguments[0]) || lodash.isUndefined(arguments[0])) {\n callArguments = {\n transaction,\n };\n } else {\n throw new Error(`please provide transactionInjector for ${name} call`);\n }\n\n const results = await oldValue.apply(this, [callArguments]);\n\n await transaction.commit();\n\n return results;\n } catch (err) {\n console.error({ err });\n await transaction.rollback();\n throw err;\n }\n } else {\n return oldValue.apply(this, arguments);\n }\n };\n\n return descriptor;\n };\n };\n}\n"]}
@@ -0,0 +1,60 @@
1
+ import { Association, BelongsToMany, Hookable, Transactionable } from 'sequelize';
2
+ import { Model } from './model';
3
+ import { TransactionAble } from './repository';
4
+ export declare function modelAssociations(instance: Model): {
5
+ [key: string]: Association<import("sequelize").Model<any, any>, import("sequelize").Model<any, any>>;
6
+ };
7
+ export declare function belongsToManyAssociations(instance: Model): Array<BelongsToMany>;
8
+ export declare function modelAssociationByKey(instance: Model, key: string): Association;
9
+ declare type UpdateValue = {
10
+ [key: string]: any;
11
+ };
12
+ interface UpdateOptions extends TransactionAble {
13
+ filter?: any;
14
+ filterByTk?: number | string;
15
+ whitelist?: string[];
16
+ blacklist?: string[];
17
+ updateAssociationValues?: string[];
18
+ sanitized?: boolean;
19
+ sourceModel?: Model;
20
+ }
21
+ interface UpdateAssociationOptions extends Transactionable, Hookable {
22
+ updateAssociationValues?: string[];
23
+ sourceModel?: Model;
24
+ context?: any;
25
+ associationContext?: any;
26
+ }
27
+ export declare function updateModelByValues(instance: Model, values: UpdateValue, options?: UpdateOptions): Promise<void>;
28
+ export declare function updateThroughTableValue(instance: Model, throughName: string, throughValues: any, source: Model, transaction?: any): Promise<any>;
29
+ /**
30
+ * update association of instance by values
31
+ * @param instance
32
+ * @param values
33
+ * @param options
34
+ */
35
+ export declare function updateAssociations(instance: Model, values: any, options?: UpdateAssociationOptions): Promise<void>;
36
+ /**
37
+ * update model association by key
38
+ * @param instance
39
+ * @param key
40
+ * @param value
41
+ * @param options
42
+ */
43
+ export declare function updateAssociation(instance: Model, key: string, value: any, options?: UpdateAssociationOptions): Promise<boolean>;
44
+ /**
45
+ * update belongsTo and HasOne
46
+ * @param model
47
+ * @param key
48
+ * @param value
49
+ * @param options
50
+ */
51
+ export declare function updateSingleAssociation(model: Model, key: string, value: any, options?: UpdateAssociationOptions): Promise<boolean>;
52
+ /**
53
+ * update multiple association of model by value
54
+ * @param model
55
+ * @param key
56
+ * @param value
57
+ * @param options
58
+ */
59
+ export declare function updateMultipleAssociation(model: Model, key: string, value: any, options?: UpdateAssociationOptions): Promise<boolean>;
60
+ export {};
@@ -0,0 +1,374 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.updateMultipleAssociation = exports.updateSingleAssociation = exports.updateAssociation = exports.updateAssociations = exports.updateThroughTableValue = exports.updateModelByValues = exports.modelAssociationByKey = exports.belongsToManyAssociations = exports.modelAssociations = void 0;
13
+ const model_1 = require("./model");
14
+ const update_guard_1 = require("./update-guard");
15
+ function isUndefinedOrNull(value) {
16
+ return typeof value === 'undefined' || value === null;
17
+ }
18
+ function isStringOrNumber(value) {
19
+ return typeof value === 'string' || typeof value === 'number';
20
+ }
21
+ function getKeysByPrefix(keys, prefix) {
22
+ return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));
23
+ }
24
+ function modelAssociations(instance) {
25
+ return instance.constructor.associations;
26
+ }
27
+ exports.modelAssociations = modelAssociations;
28
+ function belongsToManyAssociations(instance) {
29
+ const associations = modelAssociations(instance);
30
+ return Object.entries(associations)
31
+ .filter((entry) => {
32
+ const [key, association] = entry;
33
+ return association.associationType == 'BelongsToMany';
34
+ })
35
+ .map((association) => {
36
+ return association[1];
37
+ });
38
+ }
39
+ exports.belongsToManyAssociations = belongsToManyAssociations;
40
+ function modelAssociationByKey(instance, key) {
41
+ return modelAssociations(instance)[key];
42
+ }
43
+ exports.modelAssociationByKey = modelAssociationByKey;
44
+ function updateModelByValues(instance, values, options) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ if (!(options === null || options === void 0 ? void 0 : options.sanitized)) {
47
+ const guard = new update_guard_1.UpdateGuard();
48
+ //@ts-ignore
49
+ guard.setModel(instance.constructor);
50
+ guard.setBlackList(options.blacklist);
51
+ guard.setWhiteList(options.whitelist);
52
+ guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
53
+ values = guard.sanitize(values);
54
+ }
55
+ yield instance.update(values, options);
56
+ yield updateAssociations(instance, values, options);
57
+ });
58
+ }
59
+ exports.updateModelByValues = updateModelByValues;
60
+ function updateThroughTableValue(instance, throughName, throughValues, source, transaction = null) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ // update through table values
63
+ for (const belongsToMany of belongsToManyAssociations(instance)) {
64
+ // @ts-ignore
65
+ const throughModel = belongsToMany.through.model;
66
+ const throughModelName = throughModel.name;
67
+ if (throughModelName === throughModelName) {
68
+ const where = {
69
+ [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
70
+ [belongsToMany.otherKey]: source.get(belongsToMany.targetKey),
71
+ };
72
+ return yield throughModel.update(throughValues, {
73
+ where,
74
+ transaction,
75
+ });
76
+ }
77
+ }
78
+ });
79
+ }
80
+ exports.updateThroughTableValue = updateThroughTableValue;
81
+ /**
82
+ * update association of instance by values
83
+ * @param instance
84
+ * @param values
85
+ * @param options
86
+ */
87
+ function updateAssociations(instance, values, options = {}) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ // if no values set, return
90
+ if (!values) {
91
+ return;
92
+ }
93
+ let newTransaction = false;
94
+ let transaction = options.transaction;
95
+ if (!transaction) {
96
+ newTransaction = true;
97
+ transaction = yield instance.sequelize.transaction();
98
+ }
99
+ const keys = Object.keys(values);
100
+ for (const key of Object.keys(modelAssociations(instance))) {
101
+ if (keys.includes(key)) {
102
+ yield updateAssociation(instance, key, values[key], Object.assign(Object.assign({}, options), { transaction }));
103
+ }
104
+ }
105
+ // update through table values
106
+ for (const belongsToMany of belongsToManyAssociations(instance)) {
107
+ // @ts-ignore
108
+ const throughModel = belongsToMany.through.model;
109
+ const throughModelName = throughModel.name;
110
+ if (values[throughModelName] && options.sourceModel) {
111
+ const where = {
112
+ [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
113
+ [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey),
114
+ };
115
+ yield throughModel.update(values[throughModel.name], {
116
+ where,
117
+ context: options.context,
118
+ transaction,
119
+ });
120
+ }
121
+ }
122
+ if (newTransaction) {
123
+ yield transaction.commit();
124
+ }
125
+ });
126
+ }
127
+ exports.updateAssociations = updateAssociations;
128
+ function isReverseAssociationPair(a, b) {
129
+ const typeSet = new Set();
130
+ typeSet.add(a.associationType);
131
+ typeSet.add(b.associationType);
132
+ if (typeSet.size == 1 && typeSet.has('BelongsToMany')) {
133
+ return (a.through.tableName === b.through.tableName &&
134
+ a.target.name === b.source.name &&
135
+ b.target.name === a.source.name &&
136
+ a.foreignKey === b.otherKey &&
137
+ a.sourceKey === b.targetKey &&
138
+ a.otherKey === b.foreignKey &&
139
+ a.targetKey === b.sourceKey);
140
+ }
141
+ if ((typeSet.has('HasOne') && typeSet.has('BelongsTo')) || (typeSet.has('HasMany') && typeSet.has('BelongsTo'))) {
142
+ const sourceAssoc = a.associationType == 'BelongsTo' ? b : a;
143
+ const targetAssoc = sourceAssoc == a ? b : a;
144
+ return (sourceAssoc.source.name === targetAssoc.target.name &&
145
+ sourceAssoc.foreignKey === targetAssoc.foreignKey &&
146
+ sourceAssoc.sourceKey === targetAssoc.targetKey);
147
+ }
148
+ return false;
149
+ }
150
+ /**
151
+ * update model association by key
152
+ * @param instance
153
+ * @param key
154
+ * @param value
155
+ * @param options
156
+ */
157
+ function updateAssociation(instance, key, value, options = {}) {
158
+ return __awaiter(this, void 0, void 0, function* () {
159
+ const association = modelAssociationByKey(instance, key);
160
+ if (!association) {
161
+ return false;
162
+ }
163
+ if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {
164
+ return false;
165
+ }
166
+ switch (association.associationType) {
167
+ case 'HasOne':
168
+ case 'BelongsTo':
169
+ return updateSingleAssociation(instance, key, value, options);
170
+ case 'HasMany':
171
+ case 'BelongsToMany':
172
+ return updateMultipleAssociation(instance, key, value, options);
173
+ }
174
+ });
175
+ }
176
+ exports.updateAssociation = updateAssociation;
177
+ /**
178
+ * update belongsTo and HasOne
179
+ * @param model
180
+ * @param key
181
+ * @param value
182
+ * @param options
183
+ */
184
+ function updateSingleAssociation(model, key, value, options = {}) {
185
+ return __awaiter(this, void 0, void 0, function* () {
186
+ const association = modelAssociationByKey(model, key);
187
+ if (!association) {
188
+ return false;
189
+ }
190
+ if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {
191
+ return false;
192
+ }
193
+ const { context, updateAssociationValues = [], transaction = yield model.sequelize.transaction() } = options;
194
+ const keys = getKeysByPrefix(updateAssociationValues, key);
195
+ try {
196
+ // set method of association
197
+ const setAccessor = association.accessors.set;
198
+ const removeAssociation = () => __awaiter(this, void 0, void 0, function* () {
199
+ yield model[setAccessor](null, { transaction });
200
+ model.setDataValue(key, null);
201
+ if (!options.transaction) {
202
+ yield transaction.commit();
203
+ }
204
+ return true;
205
+ });
206
+ if (isUndefinedOrNull(value)) {
207
+ return yield removeAssociation();
208
+ }
209
+ if (isStringOrNumber(value)) {
210
+ yield model[setAccessor](value, { context, transaction });
211
+ if (!options.transaction) {
212
+ yield transaction.commit();
213
+ }
214
+ return true;
215
+ }
216
+ if (value instanceof model_1.Model) {
217
+ yield model[setAccessor](value, { context, transaction });
218
+ model.setDataValue(key, value);
219
+ if (!options.transaction) {
220
+ yield transaction.commit();
221
+ }
222
+ return true;
223
+ }
224
+ const createAccessor = association.accessors.create;
225
+ let dataKey;
226
+ let M;
227
+ if (association.associationType === 'BelongsTo') {
228
+ M = association.target;
229
+ // @ts-ignore
230
+ dataKey = association.targetKey;
231
+ }
232
+ else {
233
+ M = association.source;
234
+ dataKey = M.primaryKeyAttribute;
235
+ }
236
+ if (isStringOrNumber(value[dataKey])) {
237
+ let instance = yield M.findOne({
238
+ where: {
239
+ [dataKey]: value[dataKey],
240
+ },
241
+ transaction,
242
+ });
243
+ if (instance) {
244
+ yield model[setAccessor](instance, { context, transaction });
245
+ if (updateAssociationValues.includes(key)) {
246
+ yield instance.update(value, Object.assign(Object.assign({}, options), { transaction }));
247
+ }
248
+ yield updateAssociations(instance, value, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
249
+ model.setDataValue(key, instance);
250
+ if (!options.transaction) {
251
+ yield transaction.commit();
252
+ }
253
+ return true;
254
+ }
255
+ }
256
+ const instance = yield model[createAccessor](value, { context, transaction });
257
+ yield updateAssociations(instance, value, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
258
+ model.setDataValue(key, instance);
259
+ // @ts-ignore
260
+ if (association.targetKey) {
261
+ model.setDataValue(association.foreignKey, instance[dataKey]);
262
+ }
263
+ if (!options.transaction) {
264
+ yield transaction.commit();
265
+ }
266
+ }
267
+ catch (error) {
268
+ if (!options.transaction) {
269
+ yield transaction.rollback();
270
+ }
271
+ throw error;
272
+ }
273
+ });
274
+ }
275
+ exports.updateSingleAssociation = updateSingleAssociation;
276
+ /**
277
+ * update multiple association of model by value
278
+ * @param model
279
+ * @param key
280
+ * @param value
281
+ * @param options
282
+ */
283
+ function updateMultipleAssociation(model, key, value, options = {}) {
284
+ return __awaiter(this, void 0, void 0, function* () {
285
+ const association = modelAssociationByKey(model, key);
286
+ if (!association) {
287
+ return false;
288
+ }
289
+ if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {
290
+ return false;
291
+ }
292
+ const { context, updateAssociationValues = [], transaction = yield model.sequelize.transaction() } = options;
293
+ const keys = getKeysByPrefix(updateAssociationValues, key);
294
+ try {
295
+ const setAccessor = association.accessors.set;
296
+ const createAccessor = association.accessors.create;
297
+ if (isUndefinedOrNull(value)) {
298
+ yield model[setAccessor](null, { transaction, context });
299
+ model.setDataValue(key, null);
300
+ return;
301
+ }
302
+ if (isStringOrNumber(value)) {
303
+ yield model[setAccessor](value, { transaction, context });
304
+ return;
305
+ }
306
+ if (!Array.isArray(value)) {
307
+ value = [value];
308
+ }
309
+ const list1 = []; // to be setted
310
+ const list2 = []; // to be added
311
+ for (const item of value) {
312
+ if (isUndefinedOrNull(item)) {
313
+ continue;
314
+ }
315
+ if (isStringOrNumber(item)) {
316
+ list1.push(item);
317
+ }
318
+ else if (item instanceof model_1.Model) {
319
+ list1.push(item);
320
+ }
321
+ else if (item.sequelize) {
322
+ list1.push(item);
323
+ }
324
+ else if (typeof item === 'object') {
325
+ list2.push(item);
326
+ }
327
+ }
328
+ // associate targets in lists1
329
+ yield model[setAccessor](list1, { transaction, context });
330
+ const list3 = [];
331
+ for (const item of list2) {
332
+ const pk = association.target.primaryKeyAttribute;
333
+ const through = association.through ? association.through.model.name : null;
334
+ const accessorOptions = {
335
+ context,
336
+ transaction,
337
+ };
338
+ const throughValue = item[through];
339
+ if (throughValue) {
340
+ accessorOptions['through'] = throughValue;
341
+ }
342
+ if (isUndefinedOrNull(item[pk])) {
343
+ // create new record
344
+ const instance = yield model[createAccessor](item, accessorOptions);
345
+ yield updateAssociations(instance, item, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
346
+ list3.push(instance);
347
+ }
348
+ else {
349
+ // set & update record
350
+ const instance = yield association.target.findByPk(item[pk], {
351
+ transaction,
352
+ });
353
+ const addAccessor = association.accessors.add;
354
+ yield model[addAccessor](item[pk], accessorOptions);
355
+ if (updateAssociationValues.includes(key)) {
356
+ yield instance.update(item, Object.assign(Object.assign({}, options), { transaction }));
357
+ }
358
+ yield updateAssociations(instance, item, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
359
+ list3.push(instance);
360
+ }
361
+ }
362
+ model.setDataValue(key, list1.concat(list3));
363
+ if (!options.transaction) {
364
+ yield transaction.commit();
365
+ }
366
+ }
367
+ catch (error) {
368
+ yield transaction.rollback();
369
+ throw error;
370
+ }
371
+ });
372
+ }
373
+ exports.updateMultipleAssociation = updateMultipleAssociation;
374
+ //# sourceMappingURL=update-associations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-associations.js","sourceRoot":"","sources":["../src/update-associations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Association,\n BelongsTo,\n BelongsToMany,\n HasMany,\n HasOne,\n Hookable,\n ModelCtor,\n Transactionable,\n} from 'sequelize';\nimport { Model } from './model';\nimport { TransactionAble } from './repository';\nimport { UpdateGuard } from './update-guard';\n\nfunction isUndefinedOrNull(value: any) {\n return typeof value === 'undefined' || value === null;\n}\n\nfunction isStringOrNumber(value: any) {\n return typeof value === 'string' || typeof value === 'number';\n}\n\nfunction getKeysByPrefix(keys: string[], prefix: string) {\n return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));\n}\n\nexport function modelAssociations(instance: Model) {\n return (<typeof Model>instance.constructor).associations;\n}\n\nexport function belongsToManyAssociations(instance: Model): Array<BelongsToMany> {\n const associations = modelAssociations(instance);\n return Object.entries(associations)\n .filter((entry) => {\n const [key, association] = entry;\n return association.associationType == 'BelongsToMany';\n })\n .map((association) => {\n return <BelongsToMany>association[1];\n });\n}\n\nexport function modelAssociationByKey(instance: Model, key: string): Association {\n return modelAssociations(instance)[key] as Association;\n}\n\ntype UpdateValue = { [key: string]: any };\n\ninterface UpdateOptions extends TransactionAble {\n filter?: any;\n filterByTk?: number | string;\n // 字段白名单\n whitelist?: string[];\n // 字段黑名单\n blacklist?: string[];\n // 关系数据默认会新建并建立关联处理,如果是已存在的数据只关联,但不更新关系数据\n // 如果需要更新关联数据,可以通过 updateAssociationValues 指定\n updateAssociationValues?: string[];\n sanitized?: boolean;\n sourceModel?: Model;\n}\n\ninterface UpdateAssociationOptions extends Transactionable, Hookable {\n updateAssociationValues?: string[];\n sourceModel?: Model;\n context?: any;\n associationContext?: any;\n}\n\nexport async function updateModelByValues(instance: Model, values: UpdateValue, options?: UpdateOptions) {\n if (!options?.sanitized) {\n const guard = new UpdateGuard();\n //@ts-ignore\n guard.setModel(instance.constructor);\n guard.setBlackList(options.blacklist);\n guard.setWhiteList(options.whitelist);\n guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);\n values = guard.sanitize(values);\n }\n\n await instance.update(values, options);\n await updateAssociations(instance, values, options);\n}\n\nexport async function updateThroughTableValue(\n instance: Model,\n throughName: string,\n throughValues: any,\n source: Model,\n transaction = null,\n) {\n // update through table values\n for (const belongsToMany of belongsToManyAssociations(instance)) {\n // @ts-ignore\n const throughModel = belongsToMany.through.model;\n const throughModelName = throughModel.name;\n\n if (throughModelName === throughModelName) {\n const where = {\n [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),\n [belongsToMany.otherKey]: source.get(belongsToMany.targetKey),\n };\n\n return await throughModel.update(throughValues, {\n where,\n transaction,\n });\n }\n }\n}\n\n/**\n * update association of instance by values\n * @param instance\n * @param values\n * @param options\n */\nexport async function updateAssociations(instance: Model, values: any, options: UpdateAssociationOptions = {}) {\n // if no values set, return\n if (!values) {\n return;\n }\n\n let newTransaction = false;\n let transaction = options.transaction;\n\n if (!transaction) {\n newTransaction = true;\n transaction = await instance.sequelize.transaction();\n }\n\n const keys = Object.keys(values);\n\n for (const key of Object.keys(modelAssociations(instance))) {\n if (keys.includes(key)) {\n await updateAssociation(instance, key, values[key], {\n ...options,\n transaction,\n });\n }\n }\n\n // update through table values\n for (const belongsToMany of belongsToManyAssociations(instance)) {\n // @ts-ignore\n const throughModel = belongsToMany.through.model;\n const throughModelName = throughModel.name;\n\n if (values[throughModelName] && options.sourceModel) {\n const where = {\n [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),\n [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey),\n };\n\n await throughModel.update(values[throughModel.name], {\n where,\n context: options.context,\n transaction,\n });\n }\n }\n\n if (newTransaction) {\n await transaction.commit();\n }\n}\n\nfunction isReverseAssociationPair(a: any, b: any) {\n const typeSet = new Set();\n typeSet.add(a.associationType);\n typeSet.add(b.associationType);\n\n if (typeSet.size == 1 && typeSet.has('BelongsToMany')) {\n return (\n a.through.tableName === b.through.tableName &&\n a.target.name === b.source.name &&\n b.target.name === a.source.name &&\n a.foreignKey === b.otherKey &&\n a.sourceKey === b.targetKey &&\n a.otherKey === b.foreignKey &&\n a.targetKey === b.sourceKey\n );\n }\n\n if ((typeSet.has('HasOne') && typeSet.has('BelongsTo')) || (typeSet.has('HasMany') && typeSet.has('BelongsTo'))) {\n const sourceAssoc = a.associationType == 'BelongsTo' ? b : a;\n const targetAssoc = sourceAssoc == a ? b : a;\n\n return (\n sourceAssoc.source.name === targetAssoc.target.name &&\n sourceAssoc.foreignKey === targetAssoc.foreignKey &&\n sourceAssoc.sourceKey === targetAssoc.targetKey\n );\n }\n\n return false;\n}\n\n/**\n * update model association by key\n * @param instance\n * @param key\n * @param value\n * @param options\n */\nexport async function updateAssociation(\n instance: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = modelAssociationByKey(instance, key);\n\n if (!association) {\n return false;\n }\n\n if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {\n return false;\n }\n\n switch (association.associationType) {\n case 'HasOne':\n case 'BelongsTo':\n return updateSingleAssociation(instance, key, value, options);\n case 'HasMany':\n case 'BelongsToMany':\n return updateMultipleAssociation(instance, key, value, options);\n }\n}\n\n/**\n * update belongsTo and HasOne\n * @param model\n * @param key\n * @param value\n * @param options\n */\nexport async function updateSingleAssociation(\n model: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = <HasOne | BelongsTo>modelAssociationByKey(model, key);\n\n if (!association) {\n return false;\n }\n\n if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {\n return false;\n }\n\n const { context, updateAssociationValues = [], transaction = await model.sequelize.transaction() } = options;\n const keys = getKeysByPrefix(updateAssociationValues, key);\n\n try {\n // set method of association\n const setAccessor = association.accessors.set;\n\n const removeAssociation = async () => {\n await model[setAccessor](null, { transaction });\n model.setDataValue(key, null);\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n };\n\n if (isUndefinedOrNull(value)) {\n return await removeAssociation();\n }\n\n if (isStringOrNumber(value)) {\n await model[setAccessor](value, { context, transaction });\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n\n if (value instanceof Model) {\n await model[setAccessor](value, { context, transaction });\n model.setDataValue(key, value);\n\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n\n const createAccessor = association.accessors.create;\n let dataKey: string;\n let M: ModelCtor<Model>;\n if (association.associationType === 'BelongsTo') {\n M = association.target as ModelCtor<Model>;\n // @ts-ignore\n dataKey = association.targetKey;\n } else {\n M = association.source as ModelCtor<Model>;\n dataKey = M.primaryKeyAttribute;\n }\n\n if (isStringOrNumber(value[dataKey])) {\n let instance: any = await M.findOne({\n where: {\n [dataKey]: value[dataKey],\n },\n transaction,\n });\n\n if (instance) {\n await model[setAccessor](instance, { context, transaction });\n\n if (updateAssociationValues.includes(key)) {\n await instance.update(value, { ...options, transaction });\n }\n\n await updateAssociations(instance, value, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n model.setDataValue(key, instance);\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n }\n\n const instance = await model[createAccessor](value, { context, transaction });\n await updateAssociations(instance, value, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n model.setDataValue(key, instance);\n // @ts-ignore\n if (association.targetKey) {\n model.setDataValue(association.foreignKey, instance[dataKey]);\n }\n if (!options.transaction) {\n await transaction.commit();\n }\n } catch (error) {\n if (!options.transaction) {\n await transaction.rollback();\n }\n throw error;\n }\n}\n\n/**\n * update multiple association of model by value\n * @param model\n * @param key\n * @param value\n * @param options\n */\nexport async function updateMultipleAssociation(\n model: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = <BelongsToMany | HasMany>modelAssociationByKey(model, key);\n\n if (!association) {\n return false;\n }\n\n if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {\n return false;\n }\n\n const { context, updateAssociationValues = [], transaction = await model.sequelize.transaction() } = options;\n const keys = getKeysByPrefix(updateAssociationValues, key);\n\n try {\n const setAccessor = association.accessors.set;\n\n const createAccessor = association.accessors.create;\n if (isUndefinedOrNull(value)) {\n await model[setAccessor](null, { transaction, context });\n model.setDataValue(key, null);\n return;\n }\n\n if (isStringOrNumber(value)) {\n await model[setAccessor](value, { transaction, context });\n return;\n }\n\n if (!Array.isArray(value)) {\n value = [value];\n }\n\n const list1 = []; // to be setted\n const list2 = []; // to be added\n for (const item of value) {\n if (isUndefinedOrNull(item)) {\n continue;\n }\n if (isStringOrNumber(item)) {\n list1.push(item);\n } else if (item instanceof Model) {\n list1.push(item);\n } else if (item.sequelize) {\n list1.push(item);\n } else if (typeof item === 'object') {\n list2.push(item);\n }\n }\n\n // associate targets in lists1\n await model[setAccessor](list1, { transaction, context });\n\n const list3 = [];\n for (const item of list2) {\n const pk = association.target.primaryKeyAttribute;\n\n const through = (<any>association).through ? (<any>association).through.model.name : null;\n\n const accessorOptions = {\n context,\n transaction,\n };\n\n const throughValue = item[through];\n\n if (throughValue) {\n accessorOptions['through'] = throughValue;\n }\n\n if (isUndefinedOrNull(item[pk])) {\n // create new record\n const instance = await model[createAccessor](item, accessorOptions);\n await updateAssociations(instance, item, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n list3.push(instance);\n } else {\n // set & update record\n const instance = await association.target.findByPk<any>(item[pk], {\n transaction,\n });\n const addAccessor = association.accessors.add;\n\n await model[addAccessor](item[pk], accessorOptions);\n if (updateAssociationValues.includes(key)) {\n await instance.update(item, { ...options, transaction });\n }\n await updateAssociations(instance, item, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n list3.push(instance);\n }\n }\n\n model.setDataValue(key, list1.concat(list3));\n if (!options.transaction) {\n await transaction.commit();\n }\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import { ModelCtor } from 'sequelize';
2
+ import { AssociationKeysToBeUpdate, BlackList, WhiteList } from './repository';
3
+ declare type UpdateValueItem = string | number | UpdateValues;
4
+ declare type UpdateValues = {
5
+ [key: string]: UpdateValueItem | Array<UpdateValueItem>;
6
+ };
7
+ declare type UpdateAction = 'create' | 'update';
8
+ export declare class UpdateGuard {
9
+ model: ModelCtor<any>;
10
+ action: UpdateAction;
11
+ private associationKeysToBeUpdate;
12
+ private blackList;
13
+ private whiteList;
14
+ setAction(action: UpdateAction): void;
15
+ setModel(model: ModelCtor<any>): void;
16
+ setAssociationKeysToBeUpdate(associationKeysToBeUpdate: AssociationKeysToBeUpdate): void;
17
+ setWhiteList(whiteList: WhiteList): void;
18
+ setBlackList(blackList: BlackList): void;
19
+ /**
20
+ * Sanitize values by whitelist blacklist
21
+ * @param values
22
+ */
23
+ sanitize(values: UpdateValues): {};
24
+ static fromOptions(model: any, options: any): UpdateGuard;
25
+ }
26
+ export {};