@nocobase/database 0.5.0-alpha.38 → 0.7.0-alpha.10

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 +50 -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,232 @@
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 });
6
+ exports.OptionsParser = void 0;
7
+ const sequelize_1 = require("sequelize");
8
+ const filter_parser_1 = __importDefault(require("./filter-parser"));
9
+ const debug = require('debug')('noco-database');
10
+ class OptionsParser {
11
+ constructor(options, context) {
12
+ const { collection } = context;
13
+ this.collection = collection;
14
+ this.model = collection.model;
15
+ this.options = options;
16
+ this.database = collection.context.database;
17
+ this.filterParser = new filter_parser_1.default(options === null || options === void 0 ? void 0 : options.filter, {
18
+ collection,
19
+ app: {
20
+ ctx: options === null || options === void 0 ? void 0 : options.context,
21
+ },
22
+ });
23
+ this.context = context;
24
+ }
25
+ isAssociation(key) {
26
+ return this.model.associations[key] !== undefined;
27
+ }
28
+ isAssociationPath(path) {
29
+ return this.isAssociation(path.split('.')[0]);
30
+ }
31
+ toSequelizeParams() {
32
+ var _a;
33
+ const queryParams = this.filterParser.toSequelizeParams();
34
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.filterByTk) {
35
+ queryParams.where = {
36
+ [sequelize_1.Op.and]: [
37
+ queryParams.where,
38
+ {
39
+ [this.context.targetKey || this.collection.filterTargetKey]: this.options.filterByTk,
40
+ },
41
+ ],
42
+ };
43
+ }
44
+ return this.parseSort(this.parseFields(queryParams));
45
+ }
46
+ /**
47
+ * parser sort options
48
+ * @param filterParams
49
+ * @protected
50
+ */
51
+ parseSort(filterParams) {
52
+ var _a;
53
+ let sort = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.sort) || [];
54
+ if (typeof sort === 'string') {
55
+ sort = sort.split(',');
56
+ }
57
+ const orderParams = sort.map((sortKey) => {
58
+ const direction = sortKey.startsWith('-') ? 'DESC' : 'ASC';
59
+ const sortField = sortKey.replace('-', '').split('.');
60
+ // handle sort by association
61
+ if (sortField.length > 1) {
62
+ let associationModel = this.model;
63
+ for (let i = 0; i < sortField.length - 1; i++) {
64
+ const associationKey = sortField[i];
65
+ sortField[i] = associationModel.associations[associationKey].target;
66
+ associationModel = sortField[i];
67
+ }
68
+ }
69
+ sortField.push(direction);
70
+ return sortField;
71
+ });
72
+ if (orderParams.length > 0) {
73
+ return Object.assign({ order: orderParams }, filterParams);
74
+ }
75
+ return filterParams;
76
+ }
77
+ parseFields(filterParams) {
78
+ var _a, _b, _c;
79
+ const appends = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.appends) || [];
80
+ const except = [];
81
+ let attributes = {
82
+ include: [],
83
+ exclude: [],
84
+ }; // out put all fields by default
85
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.fields) {
86
+ // 将fields拆分为 attributes 和 appends
87
+ for (const field of this.options.fields) {
88
+ if (this.isAssociationPath(field)) {
89
+ // field is association field
90
+ appends.push(field);
91
+ }
92
+ else {
93
+ // field is model attribute, change attributes to array type
94
+ if (!Array.isArray(attributes))
95
+ attributes = [];
96
+ attributes.push(field);
97
+ }
98
+ }
99
+ }
100
+ if ((_c = this.options) === null || _c === void 0 ? void 0 : _c.except) {
101
+ for (const exceptKey of this.options.except) {
102
+ if (this.isAssociationPath(exceptKey)) {
103
+ // except association field
104
+ except.push(exceptKey);
105
+ }
106
+ else {
107
+ // if attributes is array form, ignore except
108
+ if (Array.isArray(attributes))
109
+ continue;
110
+ attributes.exclude.push(exceptKey);
111
+ }
112
+ }
113
+ }
114
+ return Object.assign({ attributes }, this.parseExcept(except, this.parseAppends(appends, filterParams)));
115
+ }
116
+ parseExcept(except, filterParams) {
117
+ if (!except)
118
+ return filterParams;
119
+ const setExcept = (queryParams, except) => {
120
+ // split exceptKey to path form
121
+ // posts.comments.content => ['posts', 'comments', 'content']
122
+ // then set except on include attributes
123
+ const exceptPath = except.split('.');
124
+ const association = exceptPath[0];
125
+ const lastLevel = exceptPath.length <= 2;
126
+ let existIncludeIndex = queryParams['include'].findIndex((include) => include['association'] == association);
127
+ if (existIncludeIndex == -1) {
128
+ // if include not exists, ignore this except
129
+ return;
130
+ }
131
+ if (lastLevel) {
132
+ // if it not have exclude form
133
+ if (Array.isArray(queryParams['include'][existIncludeIndex]['attributes'])) {
134
+ return;
135
+ }
136
+ else {
137
+ if (!queryParams['include'][existIncludeIndex]['attributes']['exclude']) {
138
+ queryParams['include'][existIncludeIndex]['attributes']['exclude'] = [];
139
+ }
140
+ queryParams['include'][existIncludeIndex]['attributes']['exclude'].push(exceptPath[1]);
141
+ }
142
+ }
143
+ else {
144
+ setExcept(queryParams['include'][existIncludeIndex], exceptPath.filter((_, index) => index !== 0).join('.'));
145
+ }
146
+ };
147
+ for (const exceptKey of except) {
148
+ setExcept(filterParams, exceptKey);
149
+ }
150
+ return filterParams;
151
+ }
152
+ parseAppends(appends, filterParams) {
153
+ if (!appends)
154
+ return filterParams;
155
+ /**
156
+ * set include params
157
+ * @param includeRoot
158
+ * @param appends
159
+ */
160
+ const setInclude = (model, queryParams, append) => {
161
+ const appendFields = append.split('.');
162
+ const appendAssociation = appendFields[0];
163
+ const associations = model.associations;
164
+ // if append length less or equal 2
165
+ // example:
166
+ // appends: ['posts']
167
+ // appends: ['posts.title']
168
+ // All of these can be seen as last level
169
+ let lastLevel = false;
170
+ if (appendFields.length == 1) {
171
+ lastLevel = true;
172
+ }
173
+ if (appendFields.length == 2) {
174
+ const associationModel = associations[appendFields[0]].target;
175
+ if (associationModel.rawAttributes[appendFields[1]]) {
176
+ lastLevel = true;
177
+ }
178
+ }
179
+ // find association index
180
+ if (queryParams['include'] == undefined) {
181
+ queryParams['include'] = [];
182
+ }
183
+ let existIncludeIndex = queryParams['include'].findIndex((include) => include['association'] == appendAssociation);
184
+ // if association not exist, create it
185
+ if (existIncludeIndex == -1) {
186
+ // association not exists
187
+ queryParams['include'].push({
188
+ association: appendAssociation,
189
+ });
190
+ existIncludeIndex = 0;
191
+ }
192
+ // end appends
193
+ // without nests association
194
+ if (lastLevel) {
195
+ // get exist association attributes
196
+ let attributes = queryParams['include'][existIncludeIndex]['attributes'] || {
197
+ include: [], // all fields are output by default
198
+ };
199
+ // if need set attribute
200
+ if (appendFields.length == 2) {
201
+ if (!Array.isArray(attributes)) {
202
+ attributes = [];
203
+ }
204
+ const attributeName = appendFields[1];
205
+ // push field to it
206
+ attributes.push(attributeName);
207
+ }
208
+ else {
209
+ // if attributes is empty array, change it to object
210
+ if (Array.isArray(attributes) && attributes.length == 0) {
211
+ attributes = {
212
+ include: [],
213
+ };
214
+ }
215
+ }
216
+ // set new attributes
217
+ queryParams['include'][existIncludeIndex] = Object.assign(Object.assign({}, queryParams['include'][existIncludeIndex]), { attributes });
218
+ }
219
+ else {
220
+ setInclude(model.associations[queryParams['include'][existIncludeIndex].association].target, queryParams['include'][existIncludeIndex], appendFields.filter((_, index) => index !== 0).join('.'));
221
+ }
222
+ };
223
+ // handle every appends
224
+ for (const append of appends) {
225
+ setInclude(this.model, filterParams, append);
226
+ }
227
+ debug('filter params: %o', filterParams);
228
+ return filterParams;
229
+ }
230
+ }
231
+ exports.OptionsParser = OptionsParser;
232
+ //# sourceMappingURL=options-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options-parser.js","sourceRoot":"","sources":["../src/options-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { FindAttributeOptions, ModelCtor, Op } from 'sequelize';\nimport { Collection } from './collection';\nimport { Database } from './database';\nimport FilterParser from './filter-parser';\nimport { Appends, Except, FindOptions } from './repository';\n\nconst debug = require('debug')('noco-database');\n\ninterface OptionsParserContext {\n collection: Collection;\n targetKey?: string;\n}\n\nexport class OptionsParser {\n options: FindOptions;\n database: Database;\n collection: Collection;\n model: ModelCtor<any>;\n filterParser: FilterParser;\n context: OptionsParserContext;\n\n constructor(options: FindOptions, context: OptionsParserContext) {\n const { collection } = context;\n\n this.collection = collection;\n this.model = collection.model;\n this.options = options;\n this.database = collection.context.database;\n this.filterParser = new FilterParser(options?.filter, {\n collection,\n app: {\n ctx: options?.context,\n },\n });\n this.context = context;\n }\n\n isAssociation(key: string) {\n return this.model.associations[key] !== undefined;\n }\n\n isAssociationPath(path: string) {\n return this.isAssociation(path.split('.')[0]);\n }\n\n toSequelizeParams() {\n const queryParams = this.filterParser.toSequelizeParams();\n\n if (this.options?.filterByTk) {\n queryParams.where = {\n [Op.and]: [\n queryParams.where,\n {\n [this.context.targetKey || this.collection.filterTargetKey]: this.options.filterByTk,\n },\n ],\n };\n }\n\n return this.parseSort(this.parseFields(queryParams));\n }\n\n /**\n * parser sort options\n * @param filterParams\n * @protected\n */\n protected parseSort(filterParams) {\n let sort = this.options?.sort || [];\n if (typeof sort === 'string') {\n sort = sort.split(',');\n }\n const orderParams = sort.map((sortKey: string) => {\n const direction = sortKey.startsWith('-') ? 'DESC' : 'ASC';\n const sortField: Array<any> = sortKey.replace('-', '').split('.');\n\n // handle sort by association\n if (sortField.length > 1) {\n let associationModel = this.model;\n\n for (let i = 0; i < sortField.length - 1; i++) {\n const associationKey = sortField[i];\n sortField[i] = associationModel.associations[associationKey].target;\n associationModel = sortField[i];\n }\n }\n\n sortField.push(direction);\n return sortField;\n });\n\n if (orderParams.length > 0) {\n return {\n order: orderParams,\n ...filterParams,\n };\n }\n\n return filterParams;\n }\n\n protected parseFields(filterParams: any) {\n const appends = this.options?.appends || [];\n const except = [];\n\n let attributes: FindAttributeOptions = {\n include: [],\n exclude: [],\n }; // out put all fields by default\n\n if (this.options?.fields) {\n // 将fields拆分为 attributes 和 appends\n for (const field of this.options.fields) {\n if (this.isAssociationPath(field)) {\n // field is association field\n appends.push(field);\n } else {\n // field is model attribute, change attributes to array type\n if (!Array.isArray(attributes)) attributes = [];\n\n attributes.push(field);\n }\n }\n }\n\n if (this.options?.except) {\n for (const exceptKey of this.options.except) {\n if (this.isAssociationPath(exceptKey)) {\n // except association field\n except.push(exceptKey);\n } else {\n // if attributes is array form, ignore except\n if (Array.isArray(attributes)) continue;\n attributes.exclude.push(exceptKey);\n }\n }\n }\n\n return {\n attributes,\n ...this.parseExcept(except, this.parseAppends(appends, filterParams)),\n };\n }\n\n protected parseExcept(except: Except, filterParams: any) {\n if (!except) return filterParams;\n const setExcept = (queryParams: any, except: string) => {\n // split exceptKey to path form\n // posts.comments.content => ['posts', 'comments', 'content']\n // then set except on include attributes\n const exceptPath = except.split('.');\n const association = exceptPath[0];\n const lastLevel = exceptPath.length <= 2;\n\n let existIncludeIndex = queryParams['include'].findIndex((include) => include['association'] == association);\n\n if (existIncludeIndex == -1) {\n // if include not exists, ignore this except\n return;\n }\n\n if (lastLevel) {\n // if it not have exclude form\n if (Array.isArray(queryParams['include'][existIncludeIndex]['attributes'])) {\n return;\n } else {\n if (!queryParams['include'][existIncludeIndex]['attributes']['exclude']) {\n queryParams['include'][existIncludeIndex]['attributes']['exclude'] = [];\n }\n\n queryParams['include'][existIncludeIndex]['attributes']['exclude'].push(exceptPath[1]);\n }\n } else {\n setExcept(queryParams['include'][existIncludeIndex], exceptPath.filter((_, index) => index !== 0).join('.'));\n }\n };\n\n for (const exceptKey of except) {\n setExcept(filterParams, exceptKey);\n }\n\n return filterParams;\n }\n\n protected parseAppends(appends: Appends, filterParams: any) {\n if (!appends) return filterParams;\n\n /**\n * set include params\n * @param includeRoot\n * @param appends\n */\n const setInclude = (model: ModelCtor<any>, queryParams: any, append: string) => {\n const appendFields = append.split('.');\n const appendAssociation = appendFields[0];\n\n const associations = model.associations;\n\n // if append length less or equal 2\n // example:\n // appends: ['posts']\n // appends: ['posts.title']\n // All of these can be seen as last level\n let lastLevel: boolean = false;\n\n if (appendFields.length == 1) {\n lastLevel = true;\n }\n\n if (appendFields.length == 2) {\n const associationModel = associations[appendFields[0]].target;\n if (associationModel.rawAttributes[appendFields[1]]) {\n lastLevel = true;\n }\n }\n\n // find association index\n if (queryParams['include'] == undefined) {\n queryParams['include'] = [];\n }\n\n let existIncludeIndex = queryParams['include'].findIndex(\n (include) => include['association'] == appendAssociation,\n );\n\n // if association not exist, create it\n if (existIncludeIndex == -1) {\n // association not exists\n queryParams['include'].push({\n association: appendAssociation,\n });\n\n existIncludeIndex = 0;\n }\n\n // end appends\n // without nests association\n if (lastLevel) {\n // get exist association attributes\n let attributes = queryParams['include'][existIncludeIndex]['attributes'] || {\n include: [], // all fields are output by default\n };\n\n // if need set attribute\n if (appendFields.length == 2) {\n if (!Array.isArray(attributes)) {\n attributes = [];\n }\n\n const attributeName = appendFields[1];\n\n // push field to it\n attributes.push(attributeName);\n } else {\n // if attributes is empty array, change it to object\n if (Array.isArray(attributes) && attributes.length == 0) {\n attributes = {\n include: [],\n };\n }\n }\n\n // set new attributes\n queryParams['include'][existIncludeIndex] = {\n ...queryParams['include'][existIncludeIndex],\n attributes,\n };\n } else {\n setInclude(\n model.associations[queryParams['include'][existIncludeIndex].association].target,\n queryParams['include'][existIncludeIndex],\n appendFields.filter((_, index) => index !== 0).join('.'),\n );\n }\n };\n\n // handle every appends\n for (const append of appends) {\n setInclude(this.model, filterParams, append);\n }\n\n debug('filter params: %o', filterParams);\n return filterParams;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
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
+ const database_1 = require("./database");
13
+ const db = new database_1.Database({
14
+ dialect: 'sqlite',
15
+ dialectModule: require('sqlite3'),
16
+ storage: ':memory:',
17
+ });
18
+ (() => __awaiter(void 0, void 0, void 0, function* () {
19
+ const User = db.collection({
20
+ name: 'users',
21
+ fields: [{ type: 'string', name: 'name' }],
22
+ });
23
+ const Post = db.collection({
24
+ name: 'posts',
25
+ fields: [
26
+ { type: 'string', name: 'title' },
27
+ {
28
+ type: 'belongsTo',
29
+ name: 'user',
30
+ },
31
+ ],
32
+ });
33
+ yield db.sync();
34
+ const repository = User.repository;
35
+ yield repository.createMany({
36
+ records: [
37
+ { name: 'u1', posts: [{ title: 'u1t1' }] },
38
+ { name: 'u2', posts: [{ title: 'u2t1' }] },
39
+ { name: 'u3', posts: [{ title: 'u3t1' }] },
40
+ ],
41
+ });
42
+ const Model = User.model;
43
+ const user = yield Model.findOne({
44
+ subQuery: false,
45
+ where: {
46
+ '$posts.title$': 'u1t1',
47
+ },
48
+ include: { association: 'posts', attributes: [] },
49
+ attributes: {
50
+ include: [],
51
+ },
52
+ });
53
+ console.log(user.toJSON());
54
+ }))();
55
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","sourceRoot":"","sources":["../src/playground.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,yCAAsC;AAGtC,MAAM,EAAE,GAAG,IAAI,mBAAQ,CAAC;IACtB,OAAO,EAAE,QAAQ;IACjB,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC;IACjC,OAAO,EAAE,UAAU;CACpB,CAAC,CAAC;AAEH,CAAC,GAAS,EAAE;IACV,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC;QACzB,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;KAC3C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAC;QACzB,IAAI,EAAE,OAAO;QACb,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;YACjC;gBACE,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,MAAM;aACb;SACF;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAEhB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IAEnC,MAAM,UAAU,CAAC,UAAU,CAAC;QAC1B,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE;YAC1C,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE;YAC1C,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE;SAC3C;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;QAC/B,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE;YACL,eAAe,EAAE,MAAM;SACxB;QACD,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE;QACjD,UAAU,EAAE;YACV,OAAO,EAAE,EAAE;SACZ;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAA,CAAC,EAAE,CAAC","sourcesContent":["import { Database } from './database';\nimport FilterParser from './filter-parser';\n\nconst db = new Database({\n dialect: 'sqlite',\n dialectModule: require('sqlite3'),\n storage: ':memory:',\n});\n\n(async () => {\n const User = db.collection({\n name: 'users',\n fields: [{ type: 'string', name: 'name' }],\n });\n\n const Post = db.collection({\n name: 'posts',\n fields: [\n { type: 'string', name: 'title' },\n {\n type: 'belongsTo',\n name: 'user',\n },\n ],\n });\n\n await db.sync();\n\n const repository = User.repository;\n\n await repository.createMany({\n records: [\n { name: 'u1', posts: [{ title: 'u1t1' }] },\n { name: 'u2', posts: [{ title: 'u2t1' }] },\n { name: 'u3', posts: [{ title: 'u3t1' }] },\n ],\n });\n\n const Model = User.model;\n const user = await Model.findOne({\n subQuery: false,\n where: {\n '$posts.title$': 'u1t1',\n },\n include: { association: 'posts', attributes: [] },\n attributes: {\n include: [],\n },\n });\n\n console.log(user.toJSON());\n})();\n"]}
@@ -0,0 +1,36 @@
1
+ import { Transaction } from 'sequelize';
2
+ import { Model } from '../model';
3
+ import { CreateOptions, DestroyOptions, FindOptions, TargetKey, UpdateOptions } from '../repository';
4
+ import { FindAndCountOptions, FindOneOptions, MultipleRelationRepository } from './multiple-relation-repository';
5
+ import { AssociatedOptions, PrimaryKeyWithThroughValues } from './types';
6
+ declare type CreateBelongsToManyOptions = CreateOptions;
7
+ interface IBelongsToManyRepository<M extends Model> {
8
+ find(options?: FindOptions): Promise<M[]>;
9
+ findAndCount(options?: FindAndCountOptions): Promise<[M[], number]>;
10
+ findOne(options?: FindOneOptions): Promise<M>;
11
+ create(options?: CreateBelongsToManyOptions): Promise<M>;
12
+ update(options?: UpdateOptions): Promise<M>;
13
+ destroy(options?: number | string | number[] | string[] | DestroyOptions): Promise<Boolean>;
14
+ set(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
15
+ add(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
16
+ remove(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
17
+ toggle(options: TargetKey | {
18
+ pk?: TargetKey;
19
+ transaction?: Transaction;
20
+ }): Promise<void>;
21
+ }
22
+ export declare class BelongsToManyRepository extends MultipleRelationRepository implements IBelongsToManyRepository<any> {
23
+ create(options?: CreateBelongsToManyOptions): Promise<any>;
24
+ destroy(options?: TargetKey | TargetKey[] | DestroyOptions): Promise<Boolean>;
25
+ protected setTargets(call: 'add' | 'set', options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
26
+ add(options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
27
+ set(options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
28
+ toggle(options: TargetKey | {
29
+ tk?: TargetKey;
30
+ transaction?: Transaction;
31
+ }): Promise<void>;
32
+ extendFindOptions(findOptions: any): any;
33
+ throughName(): any;
34
+ throughModel(): any;
35
+ }
36
+ export {};
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.BelongsToManyRepository = void 0;
22
+ const lodash_1 = __importDefault(require("lodash"));
23
+ const sequelize_1 = require("sequelize");
24
+ const update_associations_1 = require("../update-associations");
25
+ const multiple_relation_repository_1 = require("./multiple-relation-repository");
26
+ const relation_repository_1 = require("./relation-repository");
27
+ class BelongsToManyRepository extends multiple_relation_repository_1.MultipleRelationRepository {
28
+ create(options) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ const transaction = yield this.getTransaction(options);
31
+ const createAccessor = this.accessors().create;
32
+ const values = options.values || {};
33
+ const sourceModel = yield this.getSourceModel(transaction);
34
+ const createOptions = Object.assign(Object.assign({}, options), { through: values[this.throughName()], transaction });
35
+ return sourceModel[createAccessor](values, createOptions);
36
+ });
37
+ }
38
+ destroy(options) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const transaction = yield this.getTransaction(options);
41
+ const association = this.association;
42
+ const instancesToIds = (instances) => {
43
+ return instances.map((instance) => instance.get(this.targetKey()));
44
+ };
45
+ // Through Table
46
+ const throughTableWhere = [
47
+ {
48
+ [association.foreignKey]: this.sourceKeyValue,
49
+ },
50
+ ];
51
+ let ids;
52
+ if (options && options['filter']) {
53
+ const instances = yield this.find({
54
+ filter: options['filter'],
55
+ transaction,
56
+ });
57
+ ids = instancesToIds(instances);
58
+ }
59
+ if (options && options['filterByTk']) {
60
+ const instances = this.association.toInstanceArray(options['filterByTk']);
61
+ ids = ids ? lodash_1.default.intersection(ids, instancesToIds(instances)) : instancesToIds(instances);
62
+ }
63
+ if (options && !options['filterByTk'] && !options['filter']) {
64
+ const sourceModel = yield this.getSourceModel(transaction);
65
+ const instances = yield sourceModel[this.accessors().get]({
66
+ transaction,
67
+ });
68
+ ids = instancesToIds(instances);
69
+ }
70
+ throughTableWhere.push({
71
+ [association.otherKey]: {
72
+ [sequelize_1.Op.in]: ids,
73
+ },
74
+ });
75
+ // delete through table data
76
+ yield this.throughModel().destroy({
77
+ where: throughTableWhere,
78
+ transaction,
79
+ });
80
+ yield this.targetModel.destroy({
81
+ where: {
82
+ [this.targetKey()]: {
83
+ [sequelize_1.Op.in]: ids,
84
+ },
85
+ },
86
+ transaction,
87
+ });
88
+ return true;
89
+ });
90
+ }
91
+ setTargets(call, options) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ let handleKeys;
94
+ const transaction = yield this.getTransaction(options, false);
95
+ if (lodash_1.default.isPlainObject(options)) {
96
+ options = options.tk || [];
97
+ }
98
+ if (lodash_1.default.isString(options) || lodash_1.default.isNumber(options)) {
99
+ handleKeys = [options];
100
+ } // if it is type primaryKeyWithThroughValues
101
+ else if (lodash_1.default.isArray(options) && options.length == 2 && lodash_1.default.isPlainObject(options[0][1])) {
102
+ handleKeys = [options];
103
+ }
104
+ else {
105
+ handleKeys = options;
106
+ }
107
+ const sourceModel = yield this.getSourceModel(transaction);
108
+ const setObj = handleKeys.reduce((carry, item) => {
109
+ if (Array.isArray(item)) {
110
+ carry[item[0]] = item[1];
111
+ }
112
+ else {
113
+ carry[item] = true;
114
+ }
115
+ return carry;
116
+ }, {});
117
+ yield sourceModel[this.accessors()[call]](Object.keys(setObj), {
118
+ transaction,
119
+ });
120
+ for (const [id, throughValues] of Object.entries(setObj)) {
121
+ if (typeof throughValues === 'object') {
122
+ const instance = yield this.targetModel.findByPk(id, {
123
+ transaction,
124
+ });
125
+ yield (0, update_associations_1.updateThroughTableValue)(instance, this.throughName(), throughValues, sourceModel, transaction);
126
+ }
127
+ }
128
+ });
129
+ }
130
+ add(options) {
131
+ return __awaiter(this, void 0, void 0, function* () {
132
+ yield this.setTargets('add', options);
133
+ });
134
+ }
135
+ set(options) {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ yield this.setTargets('set', options);
138
+ });
139
+ }
140
+ toggle(options) {
141
+ return __awaiter(this, void 0, void 0, function* () {
142
+ const transaction = yield this.getTransaction(options);
143
+ const sourceModel = yield this.getSourceModel(transaction);
144
+ const has = yield sourceModel[this.accessors().hasSingle](options['tk'], {
145
+ transaction,
146
+ });
147
+ if (has) {
148
+ yield this.remove(Object.assign(Object.assign({}, options), { transaction }));
149
+ }
150
+ else {
151
+ yield this.add(Object.assign(Object.assign({}, options), { transaction }));
152
+ }
153
+ return;
154
+ });
155
+ }
156
+ extendFindOptions(findOptions) {
157
+ let joinTableAttributes;
158
+ if (lodash_1.default.get(findOptions, 'fields')) {
159
+ joinTableAttributes = [];
160
+ }
161
+ return Object.assign(Object.assign({}, findOptions), { joinTableAttributes });
162
+ }
163
+ throughName() {
164
+ return this.throughModel().name;
165
+ }
166
+ throughModel() {
167
+ return this.association.through.model;
168
+ }
169
+ }
170
+ __decorate([
171
+ (0, relation_repository_1.transaction)()
172
+ ], BelongsToManyRepository.prototype, "create", null);
173
+ __decorate([
174
+ (0, relation_repository_1.transaction)((args, transaction) => {
175
+ return {
176
+ filterByTk: args[0],
177
+ transaction,
178
+ };
179
+ })
180
+ ], BelongsToManyRepository.prototype, "destroy", null);
181
+ __decorate([
182
+ (0, relation_repository_1.transaction)((args, transaction) => {
183
+ return {
184
+ tk: args[0],
185
+ transaction,
186
+ };
187
+ })
188
+ ], BelongsToManyRepository.prototype, "add", null);
189
+ __decorate([
190
+ (0, relation_repository_1.transaction)((args, transaction) => {
191
+ return {
192
+ tk: args[0],
193
+ transaction,
194
+ };
195
+ })
196
+ ], BelongsToManyRepository.prototype, "set", null);
197
+ __decorate([
198
+ (0, relation_repository_1.transaction)((args, transaction) => {
199
+ return {
200
+ tk: args[0],
201
+ transaction,
202
+ };
203
+ })
204
+ ], BelongsToManyRepository.prototype, "toggle", null);
205
+ exports.BelongsToManyRepository = BelongsToManyRepository;
206
+ //# sourceMappingURL=belongs-to-many-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-many-repository.js","sourceRoot":"","sources":["../../src/relation-repository/belongs-to-many-repository.ts"],"names":[],"mappings":"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","sourcesContent":["import lodash from 'lodash';\nimport { BelongsToMany, Op, Transaction } from 'sequelize';\nimport { Model } from '../model';\nimport { CreateOptions, DestroyOptions, FindOptions, TargetKey, UpdateOptions } from '../repository';\nimport { updateThroughTableValue } from '../update-associations';\nimport { FindAndCountOptions, FindOneOptions, MultipleRelationRepository } from './multiple-relation-repository';\nimport { transaction } from './relation-repository';\nimport { AssociatedOptions, PrimaryKeyWithThroughValues } from './types';\n\ntype CreateBelongsToManyOptions = CreateOptions;\n\ninterface IBelongsToManyRepository<M extends Model> {\n find(options?: FindOptions): Promise<M[]>;\n findAndCount(options?: FindAndCountOptions): Promise<[M[], number]>;\n findOne(options?: FindOneOptions): Promise<M>;\n // 新增并关联,存在中间表数据\n create(options?: CreateBelongsToManyOptions): Promise<M>;\n // 更新,存在中间表数据\n update(options?: UpdateOptions): Promise<M>;\n // 删除\n destroy(options?: number | string | number[] | string[] | DestroyOptions): Promise<Boolean>;\n // 建立关联\n set(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;\n // 附加关联,存在中间表数据\n add(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;\n // 移除关联\n remove(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;\n toggle(options: TargetKey | { pk?: TargetKey; transaction?: Transaction }): Promise<void>;\n}\n\nexport class BelongsToManyRepository extends MultipleRelationRepository implements IBelongsToManyRepository<any> {\n @transaction()\n async create(options?: CreateBelongsToManyOptions): Promise<any> {\n const transaction = await this.getTransaction(options);\n\n const createAccessor = this.accessors().create;\n\n const values = options.values || {};\n\n const sourceModel = await this.getSourceModel(transaction);\n\n const createOptions = {\n ...options,\n through: values[this.throughName()],\n transaction,\n };\n\n return sourceModel[createAccessor](values, createOptions);\n }\n\n @transaction((args, transaction) => {\n return {\n filterByTk: args[0],\n transaction,\n };\n })\n async destroy(options?: TargetKey | TargetKey[] | DestroyOptions): Promise<Boolean> {\n const transaction = await this.getTransaction(options);\n const association = <BelongsToMany>this.association;\n\n const instancesToIds = (instances) => {\n return instances.map((instance) => instance.get(this.targetKey()));\n };\n\n // Through Table\n const throughTableWhere: Array<any> = [\n {\n [association.foreignKey]: this.sourceKeyValue,\n },\n ];\n\n let ids;\n\n if (options && options['filter']) {\n const instances = await this.find({\n filter: options['filter'],\n transaction,\n });\n\n ids = instancesToIds(instances);\n }\n\n if (options && options['filterByTk']) {\n const instances = (<any>this.association).toInstanceArray(options['filterByTk']);\n ids = ids ? lodash.intersection(ids, instancesToIds(instances)) : instancesToIds(instances);\n }\n\n if (options && !options['filterByTk'] && !options['filter']) {\n const sourceModel = await this.getSourceModel(transaction);\n\n const instances = await sourceModel[this.accessors().get]({\n transaction,\n });\n\n ids = instancesToIds(instances);\n }\n\n throughTableWhere.push({\n [association.otherKey]: {\n [Op.in]: ids,\n },\n });\n\n // delete through table data\n await this.throughModel().destroy({\n where: throughTableWhere,\n transaction,\n });\n\n await this.targetModel.destroy({\n where: {\n [this.targetKey()]: {\n [Op.in]: ids,\n },\n },\n transaction,\n });\n\n return true;\n }\n\n protected async setTargets(\n call: 'add' | 'set',\n options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions,\n ) {\n let handleKeys: TargetKey[] | PrimaryKeyWithThroughValues[];\n\n const transaction = await this.getTransaction(options, false);\n\n if (lodash.isPlainObject(options)) {\n options = (<AssociatedOptions>options).tk || [];\n }\n\n if (lodash.isString(options) || lodash.isNumber(options)) {\n handleKeys = [<TargetKey>options];\n } // if it is type primaryKeyWithThroughValues\n else if (lodash.isArray(options) && options.length == 2 && lodash.isPlainObject(options[0][1])) {\n handleKeys = [<PrimaryKeyWithThroughValues>options];\n } else {\n handleKeys = <TargetKey[] | PrimaryKeyWithThroughValues[]>options;\n }\n\n const sourceModel = await this.getSourceModel(transaction);\n\n const setObj = (<any>handleKeys).reduce((carry, item) => {\n if (Array.isArray(item)) {\n carry[item[0]] = item[1];\n } else {\n carry[item] = true;\n }\n return carry;\n }, {});\n\n await sourceModel[this.accessors()[call]](Object.keys(setObj), {\n transaction,\n });\n\n for (const [id, throughValues] of Object.entries(setObj)) {\n if (typeof throughValues === 'object') {\n const instance = await this.targetModel.findByPk(id, {\n transaction,\n });\n await updateThroughTableValue(instance, this.throughName(), throughValues, sourceModel, transaction);\n }\n }\n }\n\n @transaction((args, transaction) => {\n return {\n tk: args[0],\n transaction,\n };\n })\n async add(\n options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions,\n ): Promise<void> {\n await this.setTargets('add', options);\n }\n\n @transaction((args, transaction) => {\n return {\n tk: args[0],\n transaction,\n };\n })\n async set(\n options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions,\n ): Promise<void> {\n await this.setTargets('set', options);\n }\n\n @transaction((args, transaction) => {\n return {\n tk: args[0],\n transaction,\n };\n })\n async toggle(options: TargetKey | { tk?: TargetKey; transaction?: Transaction }): Promise<void> {\n const transaction = await this.getTransaction(options);\n const sourceModel = await this.getSourceModel(transaction);\n\n const has = await sourceModel[this.accessors().hasSingle](options['tk'], {\n transaction,\n });\n\n if (has) {\n await this.remove({\n ...(<any>options),\n transaction,\n });\n } else {\n await this.add({\n ...(<any>options),\n transaction,\n });\n }\n\n return;\n }\n\n extendFindOptions(findOptions) {\n let joinTableAttributes;\n if (lodash.get(findOptions, 'fields')) {\n joinTableAttributes = [];\n }\n\n return {\n ...findOptions,\n joinTableAttributes,\n };\n }\n\n throughName() {\n return this.throughModel().name;\n }\n\n throughModel() {\n return (<any>this.association).through.model;\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { Model } from '../model';
2
+ import { CreateOptions, UpdateOptions } from '../repository';
3
+ import { SingleRelationFindOption, SingleRelationRepository } from './single-relation-repository';
4
+ interface BelongsToFindOptions extends SingleRelationFindOption {
5
+ }
6
+ interface IBelongsToRepository<M extends Model> {
7
+ find(options?: BelongsToFindOptions): Promise<M>;
8
+ findOne(options?: BelongsToFindOptions): Promise<M>;
9
+ create(options?: CreateOptions): Promise<M>;
10
+ update(options?: UpdateOptions): Promise<M>;
11
+ destroy(): Promise<Boolean>;
12
+ set(primaryKey: any): Promise<void>;
13
+ remove(): Promise<void>;
14
+ }
15
+ export declare class BelongsToRepository extends SingleRelationRepository implements IBelongsToRepository<any> {
16
+ }
17
+ export {};
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BelongsToRepository = void 0;
4
+ const single_relation_repository_1 = require("./single-relation-repository");
5
+ class BelongsToRepository extends single_relation_repository_1.SingleRelationRepository {
6
+ }
7
+ exports.BelongsToRepository = BelongsToRepository;
8
+ //# sourceMappingURL=belongs-to-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-repository.js","sourceRoot":"","sources":["../../src/relation-repository/belongs-to-repository.ts"],"names":[],"mappings":";;;AAEA,6EAAkG;AAoBlG,MAAa,mBAAoB,SAAQ,qDAAwB;CAAwC;AAAzG,kDAAyG","sourcesContent":["import { Model } from '../model';\nimport { CreateOptions, UpdateOptions } from '../repository';\nimport { SingleRelationFindOption, SingleRelationRepository } from './single-relation-repository';\n\ninterface BelongsToFindOptions extends SingleRelationFindOption {}\n\ninterface IBelongsToRepository<M extends Model> {\n // 不需要 findOne,find 就是 findOne\n find(options?: BelongsToFindOptions): Promise<M>;\n findOne(options?: BelongsToFindOptions): Promise<M>;\n // 新增并关联,如果存在关联,解除之后,与新数据建立关联\n create(options?: CreateOptions): Promise<M>;\n // 更新\n update(options?: UpdateOptions): Promise<M>;\n // 删除\n destroy(): Promise<Boolean>;\n // 建立关联\n set(primaryKey: any): Promise<void>;\n // 移除关联\n remove(): Promise<void>;\n}\n\nexport class BelongsToRepository extends SingleRelationRepository implements IBelongsToRepository<any> {}\n"]}