@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,101 @@
1
+ /// <reference types="node" />
2
+ import { AsyncEmitter } from '@nocobase/utils';
3
+ import merge from 'deepmerge';
4
+ import { EventEmitter } from 'events';
5
+ import { ModelCtor, Options, QueryInterfaceDropAllTablesOptions, Sequelize, SyncOptions } from 'sequelize';
6
+ import { Collection, CollectionOptions, RepositoryType } from './collection';
7
+ import { ImportFileExtension } from './collection-importer';
8
+ import * as FieldTypes from './fields';
9
+ import { Field, FieldContext, RelationField } from './fields';
10
+ import { Model } from './model';
11
+ import { ModelHook } from './model-hook';
12
+ import { RelationRepository } from './relation-repository/relation-repository';
13
+ import { Repository } from './repository';
14
+ export interface MergeOptions extends merge.Options {
15
+ }
16
+ export interface PendingOptions {
17
+ field: RelationField;
18
+ model: ModelCtor<Model>;
19
+ }
20
+ interface MapOf<T> {
21
+ [key: string]: T;
22
+ }
23
+ export interface IDatabaseOptions extends Options {
24
+ tablePrefix?: string;
25
+ }
26
+ export declare type DatabaseOptions = IDatabaseOptions | Sequelize;
27
+ interface RegisterOperatorsContext {
28
+ db?: Database;
29
+ path?: string;
30
+ field?: Field;
31
+ app?: any;
32
+ }
33
+ export interface CleanOptions extends QueryInterfaceDropAllTablesOptions {
34
+ drop?: boolean;
35
+ }
36
+ declare type OperatorFunc = (value: any, ctx?: RegisterOperatorsContext) => any;
37
+ export declare class Database extends EventEmitter implements AsyncEmitter {
38
+ sequelize: Sequelize;
39
+ fieldTypes: Map<any, any>;
40
+ options: IDatabaseOptions;
41
+ models: Map<string, ModelCtor<Model<any, any>>>;
42
+ repositories: Map<string, typeof Repository>;
43
+ operators: Map<any, any>;
44
+ collections: Map<string, Collection<any, any>>;
45
+ pendingFields: Map<string, FieldTypes.RelationField[]>;
46
+ modelCollection: Map<ModelCtor<any>, Collection<any, any>>;
47
+ modelHook: ModelHook;
48
+ delayCollectionExtend: Map<string, {
49
+ collectionOptions: CollectionOptions;
50
+ mergeOptions?: any;
51
+ }[]>;
52
+ constructor(options: DatabaseOptions);
53
+ /**
54
+ * Add collection to database
55
+ * @param options
56
+ */
57
+ collection<Attributes = any, CreateAttributes = Attributes>(options: CollectionOptions): Collection<Attributes, CreateAttributes>;
58
+ getTablePrefix(): string;
59
+ /**
60
+ * get exists collection by its name
61
+ * @param name
62
+ */
63
+ getCollection(name: string): Collection;
64
+ hasCollection(name: string): boolean;
65
+ removeCollection(name: string): void;
66
+ getModel<M extends Model>(name: string): ModelCtor<M>;
67
+ getRepository<R extends Repository>(name: string): R;
68
+ getRepository<R extends RelationRepository>(name: string, relationId: string | number): R;
69
+ addPendingField(field: RelationField): void;
70
+ removePendingField(field: RelationField): void;
71
+ registerFieldTypes(fieldTypes: MapOf<typeof Field>): void;
72
+ registerModels(models: MapOf<ModelCtor<any>>): void;
73
+ registerRepositories(repositories: MapOf<RepositoryType>): void;
74
+ initOperators(): void;
75
+ registerOperators(operators: MapOf<OperatorFunc>): void;
76
+ buildField(options: any, context: FieldContext): any;
77
+ sync(options?: SyncOptions): Promise<Sequelize>;
78
+ clean(options: CleanOptions): Promise<void>;
79
+ isSqliteMemory(): boolean;
80
+ reconnect(): Promise<void>;
81
+ closed(): any;
82
+ close(): Promise<void>;
83
+ on(event: string | symbol, listener: (...args: any[]) => void): this;
84
+ import(options: {
85
+ directory: string;
86
+ extensions?: ImportFileExtension[];
87
+ }): Promise<Map<string, Collection>>;
88
+ emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;
89
+ }
90
+ export declare function extend(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions): {
91
+ collectionOptions: CollectionOptions;
92
+ mergeOptions: MergeOptions;
93
+ extend: boolean;
94
+ };
95
+ export declare const defineCollection: (collectionOptions: CollectionOptions) => CollectionOptions;
96
+ export declare const extendCollection: (collectionOptions: CollectionOptions, mergeOptions?: MergeOptions) => {
97
+ collectionOptions: CollectionOptions;
98
+ mergeOptions: MergeOptions;
99
+ extend: boolean;
100
+ };
101
+ export default Database;
@@ -0,0 +1,275 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __rest = (this && this.__rest) || function (s, e) {
11
+ var t = {};
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
+ t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
+ t[p[i]] = s[p[i]];
18
+ }
19
+ return t;
20
+ };
21
+ import { applyMixins, AsyncEmitter } from '@nocobase/utils';
22
+ import { EventEmitter } from 'events';
23
+ import lodash from 'lodash';
24
+ import { Op, Sequelize, Utils } from 'sequelize';
25
+ import { Collection } from './collection';
26
+ import { ImporterReader } from './collection-importer';
27
+ import * as FieldTypes from './fields';
28
+ import { ModelHook } from './model-hook';
29
+ import extendOperators from './operators';
30
+ export class Database extends EventEmitter {
31
+ constructor(options) {
32
+ super();
33
+ this.fieldTypes = new Map();
34
+ this.models = new Map();
35
+ this.repositories = new Map();
36
+ this.operators = new Map();
37
+ this.collections = new Map();
38
+ this.pendingFields = new Map();
39
+ this.modelCollection = new Map();
40
+ this.delayCollectionExtend = new Map();
41
+ if (options instanceof Sequelize) {
42
+ this.sequelize = options;
43
+ }
44
+ else {
45
+ this.sequelize = new Sequelize(options);
46
+ this.options = options;
47
+ }
48
+ this.collections = new Map();
49
+ this.modelHook = new ModelHook(this);
50
+ this.on('afterDefineCollection', (collection) => {
51
+ var _a, _b;
52
+ // after collection defined, call bind method on pending fields
53
+ (_a = this.pendingFields.get(collection.name)) === null || _a === void 0 ? void 0 : _a.forEach((field) => field.bind());
54
+ (_b = this.delayCollectionExtend.get(collection.name)) === null || _b === void 0 ? void 0 : _b.forEach((collectionExtend) => {
55
+ collection.updateOptions(collectionExtend.collectionOptions, collectionExtend.mergeOptions);
56
+ });
57
+ });
58
+ // register database field types
59
+ for (const [name, field] of Object.entries(FieldTypes)) {
60
+ if (['Field', 'RelationField'].includes(name)) {
61
+ continue;
62
+ }
63
+ let key = name.replace(/Field$/g, '');
64
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
65
+ this.registerFieldTypes({
66
+ [key]: field,
67
+ });
68
+ }
69
+ this.initOperators();
70
+ }
71
+ /**
72
+ * Add collection to database
73
+ * @param options
74
+ */
75
+ collection(options) {
76
+ this.emit('beforeDefineCollection', options);
77
+ const collection = new Collection(options, {
78
+ database: this,
79
+ });
80
+ this.collections.set(collection.name, collection);
81
+ this.modelCollection.set(collection.model, collection);
82
+ this.emit('afterDefineCollection', collection);
83
+ return collection;
84
+ }
85
+ getTablePrefix() {
86
+ return this.options.tablePrefix || '';
87
+ }
88
+ /**
89
+ * get exists collection by its name
90
+ * @param name
91
+ */
92
+ getCollection(name) {
93
+ return this.collections.get(name);
94
+ }
95
+ hasCollection(name) {
96
+ return this.collections.has(name);
97
+ }
98
+ removeCollection(name) {
99
+ const collection = this.collections.get(name);
100
+ this.emit('beforeRemoveCollection', collection);
101
+ const result = this.collections.delete(name);
102
+ if (result) {
103
+ this.emit('afterRemoveCollection', collection);
104
+ }
105
+ }
106
+ getModel(name) {
107
+ return this.getCollection(name).model;
108
+ }
109
+ getRepository(name, relationId) {
110
+ var _a, _b, _c;
111
+ if (relationId) {
112
+ const [collection, relation] = name.split('.');
113
+ return (_b = (_a = this.getRepository(collection)) === null || _a === void 0 ? void 0 : _a.relation(relation)) === null || _b === void 0 ? void 0 : _b.of(relationId);
114
+ }
115
+ return (_c = this.getCollection(name)) === null || _c === void 0 ? void 0 : _c.repository;
116
+ }
117
+ addPendingField(field) {
118
+ const associating = this.pendingFields;
119
+ const items = this.pendingFields.get(field.target) || [];
120
+ items.push(field);
121
+ associating.set(field.target, items);
122
+ }
123
+ removePendingField(field) {
124
+ const items = this.pendingFields.get(field.target) || [];
125
+ const index = items.indexOf(field);
126
+ if (index !== -1) {
127
+ delete items[index];
128
+ this.pendingFields.set(field.target, items);
129
+ }
130
+ }
131
+ registerFieldTypes(fieldTypes) {
132
+ for (const [type, fieldType] of Object.entries(fieldTypes)) {
133
+ this.fieldTypes.set(type, fieldType);
134
+ }
135
+ }
136
+ registerModels(models) {
137
+ for (const [type, schemaType] of Object.entries(models)) {
138
+ this.models.set(type, schemaType);
139
+ }
140
+ }
141
+ registerRepositories(repositories) {
142
+ for (const [type, schemaType] of Object.entries(repositories)) {
143
+ this.repositories.set(type, schemaType);
144
+ }
145
+ }
146
+ initOperators() {
147
+ const operators = new Map();
148
+ // Sequelize 内置
149
+ for (const key in Op) {
150
+ operators.set('$' + key, Op[key]);
151
+ const val = Utils.underscoredIf(key, true);
152
+ operators.set('$' + val, Op[key]);
153
+ operators.set('$' + val.replace(/_/g, ''), Op[key]);
154
+ }
155
+ this.operators = operators;
156
+ this.registerOperators(Object.assign({}, extendOperators));
157
+ }
158
+ registerOperators(operators) {
159
+ for (const [key, operator] of Object.entries(operators)) {
160
+ this.operators.set(key, operator);
161
+ }
162
+ }
163
+ buildField(options, context) {
164
+ const { type } = options;
165
+ const Field = this.fieldTypes.get(type);
166
+ if (!Field) {
167
+ throw Error(`unsupported field type ${type}`);
168
+ }
169
+ return new Field(options, context);
170
+ }
171
+ sync(options) {
172
+ return __awaiter(this, void 0, void 0, function* () {
173
+ const isMySQL = this.sequelize.getDialect() === 'mysql';
174
+ if (isMySQL) {
175
+ yield this.sequelize.query('SET FOREIGN_KEY_CHECKS = 0', null);
176
+ }
177
+ const result = yield this.sequelize.sync(options);
178
+ if (isMySQL) {
179
+ yield this.sequelize.query('SET FOREIGN_KEY_CHECKS = 1', null);
180
+ }
181
+ return result;
182
+ });
183
+ }
184
+ clean(options) {
185
+ return __awaiter(this, void 0, void 0, function* () {
186
+ const { drop } = options, others = __rest(options, ["drop"]);
187
+ if (drop) {
188
+ yield this.sequelize.getQueryInterface().dropAllTables(others);
189
+ }
190
+ });
191
+ }
192
+ isSqliteMemory() {
193
+ return this.sequelize.getDialect() === 'sqlite' && lodash.get(this.options, 'storage') == ':memory:';
194
+ }
195
+ reconnect() {
196
+ return __awaiter(this, void 0, void 0, function* () {
197
+ if (this.isSqliteMemory()) {
198
+ return;
199
+ }
200
+ // @ts-ignore
201
+ const ConnectionManager = this.sequelize.dialect.connectionManager.constructor;
202
+ // @ts-ignore
203
+ const connectionManager = new ConnectionManager(this.sequelize.dialect, this.sequelize);
204
+ // @ts-ignore
205
+ this.sequelize.dialect.connectionManager = connectionManager;
206
+ // @ts-ignore
207
+ this.sequelize.connectionManager = connectionManager;
208
+ });
209
+ }
210
+ closed() {
211
+ // @ts-ignore
212
+ return this.sequelize.connectionManager.pool._draining;
213
+ }
214
+ close() {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ if (this.isSqliteMemory()) {
217
+ return;
218
+ }
219
+ return this.sequelize.close();
220
+ });
221
+ }
222
+ on(event, listener) {
223
+ const modelEventName = this.modelHook.isModelHook(event);
224
+ if (modelEventName && !this.modelHook.hasBindEvent(modelEventName)) {
225
+ this.sequelize.addHook(modelEventName, this.modelHook.sequelizeHookBuilder(modelEventName));
226
+ this.modelHook.bindEvent(modelEventName);
227
+ }
228
+ return super.on(event, listener);
229
+ }
230
+ import(options) {
231
+ return __awaiter(this, void 0, void 0, function* () {
232
+ const reader = new ImporterReader(options.directory, options.extensions);
233
+ const modules = yield reader.read();
234
+ const result = new Map();
235
+ for (const module of modules) {
236
+ if (module.extend) {
237
+ const collectionName = module.collectionOptions.name;
238
+ const existCollection = this.getCollection(collectionName);
239
+ if (existCollection) {
240
+ existCollection.updateOptions(module.collectionOptions, module.mergeOptions);
241
+ }
242
+ else {
243
+ const existDelayExtends = this.delayCollectionExtend.get(collectionName) || [];
244
+ this.delayCollectionExtend.set(collectionName, [...existDelayExtends, module]);
245
+ }
246
+ }
247
+ else {
248
+ const collection = this.collection(module);
249
+ result.set(collection.name, collection);
250
+ }
251
+ }
252
+ return result;
253
+ });
254
+ }
255
+ }
256
+ export function extend(collectionOptions, mergeOptions) {
257
+ return {
258
+ collectionOptions,
259
+ mergeOptions,
260
+ extend: true,
261
+ };
262
+ }
263
+ export const defineCollection = (collectionOptions) => {
264
+ return collectionOptions;
265
+ };
266
+ export const extendCollection = (collectionOptions, mergeOptions) => {
267
+ return {
268
+ collectionOptions,
269
+ mergeOptions,
270
+ extend: true,
271
+ };
272
+ };
273
+ applyMixins(Database, [AsyncEmitter]);
274
+ export default Database;
275
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyMixins, AsyncEmitter } from '@nocobase/utils';\nimport merge from 'deepmerge';\nimport { EventEmitter } from 'events';\nimport lodash from 'lodash';\nimport { ModelCtor, Op, Options, QueryInterfaceDropAllTablesOptions, Sequelize, SyncOptions, Utils } from 'sequelize';\nimport { Collection, CollectionOptions, RepositoryType } from './collection';\nimport { ImporterReader, ImportFileExtension } from './collection-importer';\nimport * as FieldTypes from './fields';\nimport { Field, FieldContext, RelationField } from './fields';\nimport { Model } from './model';\nimport { ModelHook } from './model-hook';\nimport extendOperators from './operators';\nimport { RelationRepository } from './relation-repository/relation-repository';\nimport { Repository } from './repository';\n\nexport interface MergeOptions extends merge.Options {}\n\nexport interface PendingOptions {\n field: RelationField;\n model: ModelCtor<Model>;\n}\n\ninterface MapOf<T> {\n [key: string]: T;\n}\n\nexport interface IDatabaseOptions extends Options {\n tablePrefix?: string;\n}\n\nexport type DatabaseOptions = IDatabaseOptions | Sequelize;\n\ninterface RegisterOperatorsContext {\n db?: Database;\n path?: string;\n field?: Field;\n app?: any;\n}\n\nexport interface CleanOptions extends QueryInterfaceDropAllTablesOptions {\n drop?: boolean;\n}\n\ntype OperatorFunc = (value: any, ctx?: RegisterOperatorsContext) => any;\n\nexport class Database extends EventEmitter implements AsyncEmitter {\n sequelize: Sequelize;\n fieldTypes = new Map();\n options: IDatabaseOptions;\n models = new Map<string, ModelCtor<Model>>();\n repositories = new Map<string, RepositoryType>();\n operators = new Map();\n collections = new Map<string, Collection>();\n pendingFields = new Map<string, RelationField[]>();\n modelCollection = new Map<ModelCtor<any>, Collection>();\n\n modelHook: ModelHook;\n\n delayCollectionExtend = new Map<string, { collectionOptions: CollectionOptions; mergeOptions?: any }[]>();\n\n constructor(options: DatabaseOptions) {\n super();\n\n if (options instanceof Sequelize) {\n this.sequelize = options;\n } else {\n this.sequelize = new Sequelize(options);\n this.options = options;\n }\n\n this.collections = new Map();\n this.modelHook = new ModelHook(this);\n\n this.on('afterDefineCollection', (collection: Collection) => {\n // after collection defined, call bind method on pending fields\n this.pendingFields.get(collection.name)?.forEach((field) => field.bind());\n this.delayCollectionExtend.get(collection.name)?.forEach((collectionExtend) => {\n collection.updateOptions(collectionExtend.collectionOptions, collectionExtend.mergeOptions);\n });\n });\n\n // register database field types\n for (const [name, field] of Object.entries(FieldTypes)) {\n if (['Field', 'RelationField'].includes(name)) {\n continue;\n }\n let key = name.replace(/Field$/g, '');\n key = key.substring(0, 1).toLowerCase() + key.substring(1);\n this.registerFieldTypes({\n [key]: field,\n });\n }\n\n this.initOperators();\n }\n\n /**\n * Add collection to database\n * @param options\n */\n collection<Attributes = any, CreateAttributes = Attributes>(\n options: CollectionOptions,\n ): Collection<Attributes, CreateAttributes> {\n this.emit('beforeDefineCollection', options);\n\n const collection = new Collection(options, {\n database: this,\n });\n\n this.collections.set(collection.name, collection);\n this.modelCollection.set(collection.model, collection);\n\n this.emit('afterDefineCollection', collection);\n\n return collection;\n }\n\n getTablePrefix() {\n return this.options.tablePrefix || '';\n }\n\n /**\n * get exists collection by its name\n * @param name\n */\n getCollection(name: string): Collection {\n return this.collections.get(name);\n }\n\n hasCollection(name: string): boolean {\n return this.collections.has(name);\n }\n\n removeCollection(name: string) {\n const collection = this.collections.get(name);\n this.emit('beforeRemoveCollection', collection);\n\n const result = this.collections.delete(name);\n\n if (result) {\n this.emit('afterRemoveCollection', collection);\n }\n }\n\n getModel<M extends Model>(name: string) {\n return this.getCollection(name).model as ModelCtor<M>;\n }\n\n getRepository<R extends Repository>(name: string): R;\n getRepository<R extends RelationRepository>(name: string, relationId: string | number): R;\n\n getRepository<R extends RelationRepository>(name: string, relationId?: string | number): Repository | R {\n if (relationId) {\n const [collection, relation] = name.split('.');\n return this.getRepository(collection)?.relation(relation)?.of(relationId) as R;\n }\n\n return this.getCollection(name)?.repository;\n }\n\n addPendingField(field: RelationField) {\n const associating = this.pendingFields;\n const items = this.pendingFields.get(field.target) || [];\n items.push(field);\n associating.set(field.target, items);\n }\n\n removePendingField(field: RelationField) {\n const items = this.pendingFields.get(field.target) || [];\n const index = items.indexOf(field);\n if (index !== -1) {\n delete items[index];\n this.pendingFields.set(field.target, items);\n }\n }\n\n registerFieldTypes(fieldTypes: MapOf<typeof Field>) {\n for (const [type, fieldType] of Object.entries(fieldTypes)) {\n this.fieldTypes.set(type, fieldType);\n }\n }\n\n registerModels(models: MapOf<ModelCtor<any>>) {\n for (const [type, schemaType] of Object.entries(models)) {\n this.models.set(type, schemaType);\n }\n }\n\n registerRepositories(repositories: MapOf<RepositoryType>) {\n for (const [type, schemaType] of Object.entries(repositories)) {\n this.repositories.set(type, schemaType);\n }\n }\n\n initOperators() {\n const operators = new Map();\n\n // Sequelize 内置\n for (const key in Op) {\n operators.set('$' + key, Op[key]);\n const val = Utils.underscoredIf(key, true);\n operators.set('$' + val, Op[key]);\n operators.set('$' + val.replace(/_/g, ''), Op[key]);\n }\n\n this.operators = operators;\n\n this.registerOperators({\n ...extendOperators,\n });\n }\n\n registerOperators(operators: MapOf<OperatorFunc>) {\n for (const [key, operator] of Object.entries(operators)) {\n this.operators.set(key, operator);\n }\n }\n\n buildField(options, context: FieldContext) {\n const { type } = options;\n const Field = this.fieldTypes.get(type);\n if (!Field) {\n throw Error(`unsupported field type ${type}`);\n }\n return new Field(options, context);\n }\n\n async sync(options?: SyncOptions) {\n const isMySQL = this.sequelize.getDialect() === 'mysql';\n if (isMySQL) {\n await this.sequelize.query('SET FOREIGN_KEY_CHECKS = 0', null);\n }\n const result = await this.sequelize.sync(options);\n if (isMySQL) {\n await this.sequelize.query('SET FOREIGN_KEY_CHECKS = 1', null);\n }\n return result;\n }\n\n async clean(options: CleanOptions) {\n const { drop, ...others } = options;\n if (drop) {\n await this.sequelize.getQueryInterface().dropAllTables(others);\n }\n }\n\n public isSqliteMemory() {\n return this.sequelize.getDialect() === 'sqlite' && lodash.get(this.options, 'storage') == ':memory:';\n }\n\n async reconnect() {\n if (this.isSqliteMemory()) {\n return;\n }\n // @ts-ignore\n const ConnectionManager = this.sequelize.dialect.connectionManager.constructor;\n // @ts-ignore\n const connectionManager = new ConnectionManager(this.sequelize.dialect, this.sequelize);\n // @ts-ignore\n this.sequelize.dialect.connectionManager = connectionManager;\n // @ts-ignore\n this.sequelize.connectionManager = connectionManager;\n }\n\n closed() {\n // @ts-ignore\n return this.sequelize.connectionManager.pool._draining;\n }\n\n async close() {\n if (this.isSqliteMemory()) {\n return;\n }\n\n return this.sequelize.close();\n }\n\n on(event: string | symbol, listener: (...args: any[]) => void): this {\n const modelEventName = this.modelHook.isModelHook(event);\n\n if (modelEventName && !this.modelHook.hasBindEvent(modelEventName)) {\n this.sequelize.addHook(modelEventName, this.modelHook.sequelizeHookBuilder(modelEventName));\n\n this.modelHook.bindEvent(modelEventName);\n }\n\n return super.on(event, listener);\n }\n\n async import(options: { directory: string; extensions?: ImportFileExtension[] }): Promise<Map<string, Collection>> {\n const reader = new ImporterReader(options.directory, options.extensions);\n const modules = await reader.read();\n const result = new Map<string, Collection>();\n\n for (const module of modules) {\n if (module.extend) {\n const collectionName = module.collectionOptions.name;\n const existCollection = this.getCollection(collectionName);\n if (existCollection) {\n existCollection.updateOptions(module.collectionOptions, module.mergeOptions);\n } else {\n const existDelayExtends = this.delayCollectionExtend.get(collectionName) || [];\n\n this.delayCollectionExtend.set(collectionName, [...existDelayExtends, module]);\n }\n } else {\n const collection = this.collection(module);\n result.set(collection.name, collection);\n }\n }\n\n return result;\n }\n\n emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;\n}\n\nexport function extend(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions) {\n return {\n collectionOptions,\n mergeOptions,\n extend: true,\n };\n}\n\nexport const defineCollection = (collectionOptions: CollectionOptions) => {\n return collectionOptions;\n};\n\nexport const extendCollection = (collectionOptions: CollectionOptions, mergeOptions?: MergeOptions) => {\n return {\n collectionOptions,\n mergeOptions,\n extend: true,\n };\n};\n\napplyMixins(Database, [AsyncEmitter]);\n\nexport default Database;\n"]}
@@ -0,0 +1,11 @@
1
+ import { BaseColumnFieldOptions, Field } from './field';
2
+ import { DataTypes } from 'sequelize';
3
+ export declare class ArrayField extends Field {
4
+ get dataType(): DataTypes.AbstractDataTypeConstructor;
5
+ sortValue(model: any): void;
6
+ bind(): void;
7
+ unbind(): void;
8
+ }
9
+ export interface ArrayFieldOptions extends BaseColumnFieldOptions {
10
+ type: 'array';
11
+ }
@@ -0,0 +1,26 @@
1
+ import { Field } from './field';
2
+ import { DataTypes } from 'sequelize';
3
+ export class ArrayField extends Field {
4
+ get dataType() {
5
+ if (this.database.sequelize.getDialect() === 'postgres') {
6
+ return DataTypes.JSONB;
7
+ }
8
+ return DataTypes.JSON;
9
+ }
10
+ sortValue(model) {
11
+ const oldValue = model.get(this.options.name);
12
+ if (oldValue) {
13
+ const newValue = oldValue.sort();
14
+ model.set(this.options.name, newValue);
15
+ }
16
+ }
17
+ bind() {
18
+ super.bind();
19
+ this.on('beforeSave', this.sortValue.bind(this));
20
+ }
21
+ unbind() {
22
+ super.unbind();
23
+ this.off('beforeSave', this.sortValue.bind(this));
24
+ }
25
+ }
26
+ //# sourceMappingURL=array-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-field.js","sourceRoot":"","sources":["../../src/fields/array-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,IAAI,QAAQ;QACV,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,UAAU,EAAE;YACvD,OAAO,SAAS,CAAC,KAAK,CAAC;SACxB;QAED,OAAO,SAAS,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,SAAS,CAAC,KAAK;QACb,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,QAAQ,EAAE;YACZ,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;SACxC;IACH,CAAC;IAED,IAAI;QACF,KAAK,CAAC,IAAI,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM;QACJ,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;CACF","sourcesContent":["import { BaseColumnFieldOptions, Field } from './field';\nimport { DataTypes } from 'sequelize';\n\nexport class ArrayField extends Field {\n get dataType() {\n if (this.database.sequelize.getDialect() === 'postgres') {\n return DataTypes.JSONB;\n }\n\n return DataTypes.JSON;\n }\n\n sortValue(model) {\n const oldValue = model.get(this.options.name);\n\n if (oldValue) {\n const newValue = oldValue.sort();\n model.set(this.options.name, newValue);\n }\n }\n\n bind() {\n super.bind();\n this.on('beforeSave', this.sortValue.bind(this));\n }\n\n unbind() {\n super.unbind();\n this.off('beforeSave', this.sortValue.bind(this));\n }\n}\n\nexport interface ArrayFieldOptions extends BaseColumnFieldOptions {\n type: 'array';\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { BelongsToOptions as SequelizeBelongsToOptions } from 'sequelize';
2
+ import { BaseRelationFieldOptions, RelationField } from './relation-field';
3
+ export declare class BelongsToField extends RelationField {
4
+ static type: string;
5
+ get target(): any;
6
+ bind(): boolean;
7
+ unbind(): void;
8
+ }
9
+ export interface BelongsToFieldOptions extends BaseRelationFieldOptions, SequelizeBelongsToOptions {
10
+ type: 'belongsTo';
11
+ target?: string;
12
+ }
@@ -0,0 +1,57 @@
1
+ import { omit } from 'lodash';
2
+ import { Utils } from 'sequelize';
3
+ import { RelationField } from './relation-field';
4
+ export class BelongsToField extends RelationField {
5
+ get target() {
6
+ const { target, name } = this.options;
7
+ return target || Utils.pluralize(name);
8
+ }
9
+ bind() {
10
+ const { database, collection } = this.context;
11
+ const Target = this.TargetModel;
12
+ // if target model not exists, add it to pending field,
13
+ // it will bind later
14
+ if (!Target) {
15
+ database.addPendingField(this);
16
+ return false;
17
+ }
18
+ if (collection.model.associations[this.name]) {
19
+ delete collection.model.associations[this.name];
20
+ }
21
+ // define relation on sequelize model
22
+ const association = collection.model.belongsTo(Target, Object.assign({ as: this.name }, omit(this.options, ['name', 'type', 'target'])));
23
+ // inverse relation
24
+ // this.TargetModel.hasMany(collection.model);
25
+ // 建立关系之后从 pending 列表中删除
26
+ database.removePendingField(this);
27
+ if (!this.options.foreignKey) {
28
+ this.options.foreignKey = association.foreignKey;
29
+ }
30
+ if (!this.options.sourceKey) {
31
+ // @ts-ignore
32
+ this.options.sourceKey = association.sourceKey;
33
+ }
34
+ return true;
35
+ }
36
+ unbind() {
37
+ const { database, collection } = this.context;
38
+ // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
39
+ database.removePendingField(this);
40
+ // 如果外键没有显式的创建,关系表也无反向关联字段,删除关系时,外键也删除掉
41
+ const tcoll = database.collections.get(this.target);
42
+ const foreignKey = this.options.foreignKey;
43
+ const field1 = collection.getField(foreignKey);
44
+ const field2 = tcoll.findField((field) => {
45
+ return field.type === 'hasMany' && field.foreignKey === foreignKey;
46
+ });
47
+ if (!field1 && !field2) {
48
+ collection.model.removeAttribute(foreignKey);
49
+ }
50
+ // 删掉 model 的关联字段
51
+ delete collection.model.associations[this.name];
52
+ // @ts-ignore
53
+ collection.model.refreshAttributes();
54
+ }
55
+ }
56
+ BelongsToField.type = 'belongsTo';
57
+ //# sourceMappingURL=belongs-to-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-field.js","sourceRoot":"","sources":["../../src/fields/belongs-to-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAiD,KAAK,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,EAA4B,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,MAAM,OAAO,cAAe,SAAQ,aAAa;IAG/C,IAAI,MAAM;QACR,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACtC,OAAO,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,IAAI;QACF,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAEhC,uDAAuD;QACvD,qBAAqB;QACrB,IAAI,CAAC,MAAM,EAAE;YACX,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC;SACd;QAED,IAAI,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC5C,OAAO,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACjD;QAED,qCAAqC;QACrC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,kBACnD,EAAE,EAAE,IAAI,CAAC,IAAI,IACV,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EACjD,CAAC;QAEH,mBAAmB;QACnB,8CAA8C;QAE9C,wBAAwB;QACxB,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC;SAClD;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;YAC3B,aAAa;YACb,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;SAChD;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9C,iCAAiC;QACjC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClC,uCAAuC;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YACvC,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE;YACtB,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;SAC9C;QACD,iBAAiB;QACjB,OAAO,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,aAAa;QACb,UAAU,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;IACvC,CAAC;;AAhEM,mBAAI,GAAG,WAAW,CAAC","sourcesContent":["import { omit } from 'lodash';\nimport { BelongsToOptions as SequelizeBelongsToOptions, Utils } from 'sequelize';\nimport { BaseRelationFieldOptions, RelationField } from './relation-field';\n\nexport class BelongsToField extends RelationField {\n static type = 'belongsTo';\n\n get target() {\n const { target, name } = this.options;\n return target || Utils.pluralize(name);\n }\n\n bind() {\n const { database, collection } = this.context;\n const Target = this.TargetModel;\n\n // if target model not exists, add it to pending field,\n // it will bind later\n if (!Target) {\n database.addPendingField(this);\n return false;\n }\n\n if (collection.model.associations[this.name]) {\n delete collection.model.associations[this.name];\n }\n\n // define relation on sequelize model\n const association = collection.model.belongsTo(Target, {\n as: this.name,\n ...omit(this.options, ['name', 'type', 'target']),\n });\n\n // inverse relation\n // this.TargetModel.hasMany(collection.model);\n\n // 建立关系之后从 pending 列表中删除\n database.removePendingField(this);\n\n if (!this.options.foreignKey) {\n this.options.foreignKey = association.foreignKey;\n }\n\n if (!this.options.sourceKey) {\n // @ts-ignore\n this.options.sourceKey = association.sourceKey;\n }\n\n return true;\n }\n\n unbind() {\n const { database, collection } = this.context;\n // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段\n database.removePendingField(this);\n // 如果外键没有显式的创建,关系表也无反向关联字段,删除关系时,外键也删除掉\n const tcoll = database.collections.get(this.target);\n const foreignKey = this.options.foreignKey;\n const field1 = collection.getField(foreignKey);\n const field2 = tcoll.findField((field) => {\n return field.type === 'hasMany' && field.foreignKey === foreignKey;\n });\n if (!field1 && !field2) {\n collection.model.removeAttribute(foreignKey);\n }\n // 删掉 model 的关联字段\n delete collection.model.associations[this.name];\n // @ts-ignore\n collection.model.refreshAttributes();\n }\n}\n\nexport interface BelongsToFieldOptions extends BaseRelationFieldOptions, SequelizeBelongsToOptions {\n type: 'belongsTo';\n target?: string;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { BelongsToManyOptions as SequelizeBelongsToManyOptions } from 'sequelize';
2
+ import { MultipleRelationFieldOptions, RelationField } from './relation-field';
3
+ export declare class BelongsToManyField extends RelationField {
4
+ get through(): any;
5
+ bind(): boolean;
6
+ unbind(): void;
7
+ }
8
+ export interface BelongsToManyFieldOptions extends MultipleRelationFieldOptions, Omit<SequelizeBelongsToManyOptions, 'through'> {
9
+ type: 'belongsToMany';
10
+ through?: string;
11
+ }
@@ -0,0 +1,55 @@
1
+ import { omit } from 'lodash';
2
+ import { Utils } from 'sequelize';
3
+ import { RelationField } from './relation-field';
4
+ export class BelongsToManyField extends RelationField {
5
+ get through() {
6
+ return (this.options.through ||
7
+ Utils.camelize([this.context.collection.model.name, this.target]
8
+ .map((name) => name.toLowerCase())
9
+ .sort()
10
+ .join('_')));
11
+ }
12
+ bind() {
13
+ const { database, collection } = this.context;
14
+ const Target = this.TargetModel;
15
+ if (!Target) {
16
+ database.addPendingField(this);
17
+ return false;
18
+ }
19
+ const through = this.through;
20
+ let Through;
21
+ if (database.hasCollection(through)) {
22
+ Through = database.getCollection(through);
23
+ }
24
+ else {
25
+ Through = database.collection({
26
+ name: through,
27
+ });
28
+ Object.defineProperty(Through.model, 'isThrough', { value: true });
29
+ }
30
+ const association = collection.model.belongsToMany(Target, Object.assign(Object.assign({}, omit(this.options, ['name', 'type', 'target'])), { as: this.name, through: Through.model }));
31
+ // 建立关系之后从 pending 列表中删除
32
+ database.removePendingField(this);
33
+ if (!this.options.foreignKey) {
34
+ this.options.foreignKey = association.foreignKey;
35
+ }
36
+ if (!this.options.sourceKey) {
37
+ this.options.sourceKey = association.sourceKey;
38
+ }
39
+ if (!this.options.otherKey) {
40
+ this.options.otherKey = association.otherKey;
41
+ }
42
+ if (!this.options.through) {
43
+ this.options.through = this.through;
44
+ }
45
+ return true;
46
+ }
47
+ unbind() {
48
+ const { database, collection } = this.context;
49
+ // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
50
+ database.removePendingField(this);
51
+ // 删掉 model 的关联字段
52
+ delete collection.model.associations[this.name];
53
+ }
54
+ }
55
+ //# sourceMappingURL=belongs-to-many-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"belongs-to-many-field.js","sourceRoot":"","sources":["../../src/fields/belongs-to-many-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAyD,KAAK,EAAE,MAAM,WAAW,CAAC;AAEzF,OAAO,EAAgC,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/E,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,IAAI,OAAO;QACT,OAAO,CACL,IAAI,CAAC,OAAO,CAAC,OAAO;YACpB,KAAK,CAAC,QAAQ,CACZ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;iBAC9C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;iBACjC,IAAI,EAAE;iBACN,IAAI,CAAC,GAAG,CAAC,CACb,CACF,CAAC;IACJ,CAAC;IAED,IAAI;QACF,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE;YACX,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,KAAK,CAAC;SACd;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAE7B,IAAI,OAAmB,CAAC;QAExB,IAAI,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE;YACnC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;SAC3C;aAAM;YACL,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC;gBAC5B,IAAI,EAAE,OAAO;aACd,CAAC,CAAC;YACH,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACpE;QAED,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,kCACpD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,KACjD,EAAE,EAAE,IAAI,CAAC,IAAI,EACb,OAAO,EAAE,OAAO,CAAC,KAAK,IACtB,CAAC;QAEH,wBAAwB;QACxB,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC;SAClD;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;YAC3B,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;SAChD;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;YAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC;SAC9C;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACzB,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;SACrC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9C,iCAAiC;QACjC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClC,iBAAiB;QACjB,OAAO,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;CACF","sourcesContent":["import { omit } from 'lodash';\nimport { BelongsToManyOptions as SequelizeBelongsToManyOptions, Utils } from 'sequelize';\nimport { Collection } from '../collection';\nimport { MultipleRelationFieldOptions, RelationField } from './relation-field';\n\nexport class BelongsToManyField extends RelationField {\n get through() {\n return (\n this.options.through ||\n Utils.camelize(\n [this.context.collection.model.name, this.target]\n .map((name) => name.toLowerCase())\n .sort()\n .join('_'),\n )\n );\n }\n\n bind() {\n const { database, collection } = this.context;\n const Target = this.TargetModel;\n if (!Target) {\n database.addPendingField(this);\n return false;\n }\n const through = this.through;\n\n let Through: Collection;\n\n if (database.hasCollection(through)) {\n Through = database.getCollection(through);\n } else {\n Through = database.collection({\n name: through,\n });\n Object.defineProperty(Through.model, 'isThrough', { value: true });\n }\n\n const association = collection.model.belongsToMany(Target, {\n ...omit(this.options, ['name', 'type', 'target']),\n as: this.name,\n through: Through.model,\n });\n\n // 建立关系之后从 pending 列表中删除\n database.removePendingField(this);\n\n if (!this.options.foreignKey) {\n this.options.foreignKey = association.foreignKey;\n }\n if (!this.options.sourceKey) {\n this.options.sourceKey = association.sourceKey;\n }\n if (!this.options.otherKey) {\n this.options.otherKey = association.otherKey;\n }\n if (!this.options.through) {\n this.options.through = this.through;\n }\n return true;\n }\n\n unbind() {\n const { database, collection } = this.context;\n // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段\n database.removePendingField(this);\n // 删掉 model 的关联字段\n delete collection.model.associations[this.name];\n }\n}\n\nexport interface BelongsToManyFieldOptions\n extends MultipleRelationFieldOptions,\n Omit<SequelizeBelongsToManyOptions, 'through'> {\n type: 'belongsToMany';\n through?: string;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { BaseColumnFieldOptions, Field } from './field';
3
+ export declare class BooleanField extends Field {
4
+ get dataType(): DataTypes.AbstractDataTypeConstructor;
5
+ }
6
+ export interface BooleanFieldOptions extends BaseColumnFieldOptions {
7
+ type: 'boolean';
8
+ }
@@ -0,0 +1,8 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { Field } from './field';
3
+ export class BooleanField extends Field {
4
+ get dataType() {
5
+ return DataTypes.BOOLEAN;
6
+ }
7
+ }
8
+ //# sourceMappingURL=boolean-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean-field.js","sourceRoot":"","sources":["../../src/fields/boolean-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAA0B,KAAK,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,IAAI,QAAQ;QACV,OAAO,SAAS,CAAC,OAAO,CAAC;IAC3B,CAAC;CACF","sourcesContent":["import { DataTypes } from 'sequelize';\nimport { BaseColumnFieldOptions, Field } from './field';\n\nexport class BooleanField extends Field {\n get dataType() {\n return DataTypes.BOOLEAN;\n }\n}\n\nexport interface BooleanFieldOptions extends BaseColumnFieldOptions {\n type: 'boolean';\n}\n"]}