@nocobase/database 0.5.0-alpha.37 → 0.7.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. package/LICENSE +201 -21
  2. package/esm/collection-importer.d.ts +7 -0
  3. package/esm/collection-importer.js +49 -0
  4. package/esm/collection-importer.js.map +1 -0
  5. package/esm/collection.d.ts +73 -0
  6. package/esm/collection.js +224 -0
  7. package/esm/collection.js.map +1 -0
  8. package/esm/database.d.ts +101 -0
  9. package/esm/database.js +275 -0
  10. package/esm/database.js.map +1 -0
  11. package/esm/fields/array-field.d.ts +11 -0
  12. package/esm/fields/array-field.js +26 -0
  13. package/esm/fields/array-field.js.map +1 -0
  14. package/esm/fields/belongs-to-field.d.ts +12 -0
  15. package/esm/fields/belongs-to-field.js +57 -0
  16. package/esm/fields/belongs-to-field.js.map +1 -0
  17. package/esm/fields/belongs-to-many-field.d.ts +11 -0
  18. package/esm/fields/belongs-to-many-field.js +55 -0
  19. package/esm/fields/belongs-to-many-field.js.map +1 -0
  20. package/esm/fields/boolean-field.d.ts +8 -0
  21. package/esm/fields/boolean-field.js +8 -0
  22. package/esm/fields/boolean-field.js.map +1 -0
  23. package/esm/fields/context-field.d.ts +13 -0
  24. package/esm/fields/context-field.js +43 -0
  25. package/esm/fields/context-field.js.map +1 -0
  26. package/esm/fields/date-field.d.ts +8 -0
  27. package/esm/fields/date-field.js +8 -0
  28. package/esm/fields/date-field.js.map +1 -0
  29. package/esm/fields/field.d.ts +37 -0
  30. package/esm/fields/field.js +74 -0
  31. package/esm/fields/field.js.map +1 -0
  32. package/esm/fields/has-inverse-field.d.ts +4 -0
  33. package/esm/fields/has-inverse-field.js +2 -0
  34. package/esm/fields/has-inverse-field.js.map +1 -0
  35. package/esm/fields/has-many-field.d.ts +64 -0
  36. package/esm/fields/has-many-field.js +58 -0
  37. package/esm/fields/has-many-field.js.map +1 -0
  38. package/esm/fields/has-one-field.d.ts +64 -0
  39. package/esm/fields/has-one-field.js +57 -0
  40. package/esm/fields/has-one-field.js.map +1 -0
  41. package/esm/fields/index.d.ts +40 -0
  42. package/esm/fields/index.js +21 -0
  43. package/esm/fields/index.js.map +1 -0
  44. package/esm/fields/json-field.d.ts +14 -0
  45. package/esm/fields/json-field.js +17 -0
  46. package/esm/fields/json-field.js.map +1 -0
  47. package/esm/fields/number-field.d.ts +32 -0
  48. package/esm/fields/number-field.js +28 -0
  49. package/esm/fields/number-field.js.map +1 -0
  50. package/esm/fields/password-field.d.ts +21 -0
  51. package/esm/fields/password-field.js +71 -0
  52. package/esm/fields/password-field.js.map +1 -0
  53. package/esm/fields/radio-field.d.ts +14 -0
  54. package/esm/fields/radio-field.js +49 -0
  55. package/esm/fields/radio-field.js.map +1 -0
  56. package/esm/fields/relation-field.d.ts +20 -0
  57. package/esm/fields/relation-field.js +27 -0
  58. package/esm/fields/relation-field.js.map +1 -0
  59. package/esm/fields/sort-field.d.ts +16 -0
  60. package/esm/fields/sort-field.js +90 -0
  61. package/esm/fields/sort-field.js.map +1 -0
  62. package/esm/fields/string-field.d.ts +8 -0
  63. package/esm/fields/string-field.js +8 -0
  64. package/esm/fields/string-field.js.map +1 -0
  65. package/esm/fields/text-field.d.ts +8 -0
  66. package/esm/fields/text-field.js +8 -0
  67. package/esm/fields/text-field.js.map +1 -0
  68. package/esm/fields/time-field.d.ts +8 -0
  69. package/esm/fields/time-field.js +8 -0
  70. package/esm/fields/time-field.js.map +1 -0
  71. package/esm/fields/uid-field.d.ts +10 -0
  72. package/esm/fields/uid-field.js +27 -0
  73. package/esm/fields/uid-field.js.map +1 -0
  74. package/esm/fields/virtual-field.d.ts +8 -0
  75. package/esm/fields/virtual-field.js +8 -0
  76. package/esm/fields/virtual-field.js.map +1 -0
  77. package/esm/filter-parser.d.ts +27 -0
  78. package/esm/filter-parser.js +185 -0
  79. package/esm/filter-parser.js.map +1 -0
  80. package/esm/index.d.ts +15 -0
  81. package/esm/index.js +16 -0
  82. package/esm/index.js.map +1 -0
  83. package/esm/magic-attribute-model.d.ts +7 -0
  84. package/esm/magic-attribute-model.js +70 -0
  85. package/esm/magic-attribute-model.js.map +1 -0
  86. package/esm/mock-database.d.ts +22 -0
  87. package/esm/mock-database.js +34 -0
  88. package/esm/mock-database.js.map +1 -0
  89. package/esm/model-hook.d.ts +12 -0
  90. package/esm/model-hook.js +61 -0
  91. package/esm/model-hook.js.map +1 -0
  92. package/esm/model.d.ts +15 -0
  93. package/esm/model.js +80 -0
  94. package/esm/model.js.map +1 -0
  95. package/esm/operators/array.d.ts +26 -0
  96. package/esm/operators/array.js +105 -0
  97. package/esm/operators/array.js.map +1 -0
  98. package/esm/operators/association.d.ts +10 -0
  99. package/esm/operators/association.js +14 -0
  100. package/esm/operators/association.js.map +1 -0
  101. package/esm/operators/date.d.ts +34 -0
  102. package/esm/operators/date.js +35 -0
  103. package/esm/operators/date.js.map +1 -0
  104. package/esm/operators/empty.d.ts +28 -0
  105. package/esm/operators/empty.js +58 -0
  106. package/esm/operators/empty.js.map +1 -0
  107. package/esm/operators/index.d.ts +2 -0
  108. package/esm/operators/index.js +2 -0
  109. package/esm/operators/index.js.map +1 -0
  110. package/esm/operators/ne.d.ts +10 -0
  111. package/esm/operators/ne.js +12 -0
  112. package/esm/operators/ne.js.map +1 -0
  113. package/esm/operators/string.d.ts +21 -0
  114. package/esm/operators/string.js +35 -0
  115. package/esm/operators/string.js.map +1 -0
  116. package/esm/operators/utils.d.ts +4 -0
  117. package/esm/operators/utils.js +11 -0
  118. package/esm/operators/utils.js.map +1 -0
  119. package/esm/options-parser.d.ts +31 -0
  120. package/esm/options-parser.js +225 -0
  121. package/esm/options-parser.js.map +1 -0
  122. package/esm/playground.d.ts +1 -0
  123. package/esm/playground.js +53 -0
  124. package/esm/playground.js.map +1 -0
  125. package/esm/relation-repository/belongs-to-many-repository.d.ts +36 -0
  126. package/esm/relation-repository/belongs-to-many-repository.js +199 -0
  127. package/esm/relation-repository/belongs-to-many-repository.js.map +1 -0
  128. package/esm/relation-repository/belongs-to-repository.d.ts +17 -0
  129. package/esm/relation-repository/belongs-to-repository.js +4 -0
  130. package/esm/relation-repository/belongs-to-repository.js.map +1 -0
  131. package/esm/relation-repository/hasmany-repository.d.ts +23 -0
  132. package/esm/relation-repository/hasmany-repository.js +125 -0
  133. package/esm/relation-repository/hasmany-repository.js.map +1 -0
  134. package/esm/relation-repository/hasone-repository.d.ts +17 -0
  135. package/esm/relation-repository/hasone-repository.js +4 -0
  136. package/esm/relation-repository/hasone-repository.js.map +1 -0
  137. package/esm/relation-repository/multiple-relation-repository.d.ts +23 -0
  138. package/esm/relation-repository/multiple-relation-repository.js +149 -0
  139. package/esm/relation-repository/multiple-relation-repository.js.map +1 -0
  140. package/esm/relation-repository/relation-repository.d.ts +32 -0
  141. package/esm/relation-repository/relation-repository.js +93 -0
  142. package/esm/relation-repository/relation-repository.js.map +1 -0
  143. package/esm/relation-repository/single-relation-repository.d.ts +23 -0
  144. package/esm/relation-repository/single-relation-repository.js +96 -0
  145. package/esm/relation-repository/single-relation-repository.js.map +1 -0
  146. package/esm/relation-repository/types.d.ts +7 -0
  147. package/esm/relation-repository/types.js +2 -0
  148. package/esm/relation-repository/types.js.map +1 -0
  149. package/esm/repository.d.ts +165 -0
  150. package/esm/repository.js +276 -0
  151. package/esm/repository.js.map +1 -0
  152. package/esm/transaction-decorator.d.ts +1 -0
  153. package/esm/transaction-decorator.js +63 -0
  154. package/esm/transaction-decorator.js.map +1 -0
  155. package/esm/update-associations.d.ts +60 -0
  156. package/esm/update-associations.js +362 -0
  157. package/esm/update-associations.js.map +1 -0
  158. package/esm/update-guard.d.ts +26 -0
  159. package/esm/update-guard.js +122 -0
  160. package/esm/update-guard.js.map +1 -0
  161. package/lib/collection-importer.d.ts +7 -0
  162. package/lib/collection-importer.js +75 -0
  163. package/lib/collection-importer.js.map +1 -0
  164. package/lib/collection.d.ts +73 -0
  165. package/lib/collection.js +231 -0
  166. package/lib/collection.js.map +1 -0
  167. package/lib/database.d.ts +93 -43
  168. package/lib/database.js +277 -471
  169. package/lib/database.js.map +1 -1
  170. package/lib/fields/array-field.d.ts +11 -0
  171. package/lib/fields/array-field.js +30 -0
  172. package/lib/fields/array-field.js.map +1 -0
  173. package/lib/fields/belongs-to-field.d.ts +12 -0
  174. package/lib/fields/belongs-to-field.js +61 -0
  175. package/lib/fields/belongs-to-field.js.map +1 -0
  176. package/lib/fields/belongs-to-many-field.d.ts +11 -0
  177. package/lib/fields/belongs-to-many-field.js +59 -0
  178. package/lib/fields/belongs-to-many-field.js.map +1 -0
  179. package/lib/fields/boolean-field.d.ts +8 -0
  180. package/lib/fields/boolean-field.js +12 -0
  181. package/lib/fields/boolean-field.js.map +1 -0
  182. package/lib/fields/context-field.d.ts +13 -0
  183. package/lib/fields/context-field.js +47 -0
  184. package/lib/fields/context-field.js.map +1 -0
  185. package/lib/fields/date-field.d.ts +8 -0
  186. package/lib/fields/date-field.js +12 -0
  187. package/lib/fields/date-field.js.map +1 -0
  188. package/lib/fields/field.d.ts +37 -0
  189. package/lib/fields/field.js +81 -0
  190. package/lib/fields/field.js.map +1 -0
  191. package/lib/fields/has-inverse-field.d.ts +4 -0
  192. package/lib/fields/has-inverse-field.js +3 -0
  193. package/lib/fields/has-inverse-field.js.map +1 -0
  194. package/lib/fields/has-many-field.d.ts +64 -0
  195. package/lib/fields/has-many-field.js +62 -0
  196. package/lib/fields/has-many-field.js.map +1 -0
  197. package/lib/fields/has-one-field.d.ts +64 -0
  198. package/lib/fields/has-one-field.js +61 -0
  199. package/lib/fields/has-one-field.js.map +1 -0
  200. package/lib/fields/index.d.ts +40 -10
  201. package/lib/fields/index.js +31 -138
  202. package/lib/fields/index.js.map +1 -1
  203. package/lib/fields/json-field.d.ts +14 -0
  204. package/lib/fields/json-field.js +22 -0
  205. package/lib/fields/json-field.js.map +1 -0
  206. package/lib/fields/number-field.d.ts +32 -0
  207. package/lib/fields/number-field.js +36 -0
  208. package/lib/fields/number-field.js.map +1 -0
  209. package/lib/fields/password-field.d.ts +21 -0
  210. package/lib/fields/password-field.js +78 -0
  211. package/lib/fields/password-field.js.map +1 -0
  212. package/lib/fields/radio-field.d.ts +14 -0
  213. package/lib/fields/radio-field.js +53 -0
  214. package/lib/fields/radio-field.js.map +1 -0
  215. package/lib/fields/relation-field.d.ts +20 -0
  216. package/lib/fields/relation-field.js +31 -0
  217. package/lib/fields/relation-field.js.map +1 -0
  218. package/lib/fields/sort-field.d.ts +16 -0
  219. package/lib/fields/sort-field.js +94 -0
  220. package/lib/fields/sort-field.js.map +1 -0
  221. package/lib/fields/string-field.d.ts +8 -0
  222. package/lib/fields/string-field.js +12 -0
  223. package/lib/fields/string-field.js.map +1 -0
  224. package/lib/fields/text-field.d.ts +8 -0
  225. package/lib/fields/text-field.js +12 -0
  226. package/lib/fields/text-field.js.map +1 -0
  227. package/lib/fields/time-field.d.ts +8 -0
  228. package/lib/fields/time-field.js +12 -0
  229. package/lib/fields/time-field.js.map +1 -0
  230. package/lib/fields/uid-field.d.ts +10 -0
  231. package/lib/fields/uid-field.js +31 -0
  232. package/lib/fields/uid-field.js.map +1 -0
  233. package/lib/fields/virtual-field.d.ts +8 -0
  234. package/lib/fields/virtual-field.js +12 -0
  235. package/lib/fields/virtual-field.js.map +1 -0
  236. package/lib/filter-parser.d.ts +27 -0
  237. package/lib/filter-parser.js +191 -0
  238. package/lib/filter-parser.js.map +1 -0
  239. package/lib/index.d.ts +13 -6
  240. package/lib/index.js +27 -60
  241. package/lib/index.js.map +1 -1
  242. package/lib/magic-attribute-model.d.ts +7 -0
  243. package/lib/magic-attribute-model.js +77 -0
  244. package/lib/magic-attribute-model.js.map +1 -0
  245. package/lib/mock-database.d.ts +22 -0
  246. package/lib/mock-database.js +40 -0
  247. package/lib/mock-database.js.map +1 -0
  248. package/lib/model-hook.d.ts +12 -0
  249. package/lib/model-hook.js +68 -0
  250. package/lib/model-hook.js.map +1 -0
  251. package/lib/model.d.ts +11 -45
  252. package/lib/model.js +76 -452
  253. package/lib/model.js.map +1 -1
  254. package/lib/operators/array.d.ts +26 -0
  255. package/lib/operators/array.js +107 -0
  256. package/lib/operators/array.js.map +1 -0
  257. package/lib/operators/association.d.ts +10 -0
  258. package/lib/operators/association.js +16 -0
  259. package/lib/operators/association.js.map +1 -0
  260. package/lib/operators/date.d.ts +34 -0
  261. package/lib/operators/date.js +40 -0
  262. package/lib/operators/date.js.map +1 -0
  263. package/lib/operators/empty.d.ts +28 -0
  264. package/lib/operators/empty.js +82 -0
  265. package/lib/operators/empty.js.map +1 -0
  266. package/lib/operators/index.d.ts +2 -0
  267. package/lib/operators/index.js +4 -0
  268. package/lib/operators/index.js.map +1 -0
  269. package/lib/operators/ne.d.ts +10 -0
  270. package/lib/operators/ne.js +14 -0
  271. package/lib/operators/ne.js.map +1 -0
  272. package/lib/operators/string.d.ts +21 -0
  273. package/lib/operators/string.js +37 -0
  274. package/lib/operators/string.js.map +1 -0
  275. package/lib/operators/utils.d.ts +4 -0
  276. package/lib/operators/utils.js +16 -0
  277. package/lib/operators/utils.js.map +1 -0
  278. package/lib/options-parser.d.ts +31 -0
  279. package/lib/options-parser.js +232 -0
  280. package/lib/options-parser.js.map +1 -0
  281. package/lib/playground.d.ts +1 -0
  282. package/lib/playground.js +55 -0
  283. package/lib/playground.js.map +1 -0
  284. package/lib/relation-repository/belongs-to-many-repository.d.ts +36 -0
  285. package/lib/relation-repository/belongs-to-many-repository.js +206 -0
  286. package/lib/relation-repository/belongs-to-many-repository.js.map +1 -0
  287. package/lib/relation-repository/belongs-to-repository.d.ts +17 -0
  288. package/lib/relation-repository/belongs-to-repository.js +8 -0
  289. package/lib/relation-repository/belongs-to-repository.js.map +1 -0
  290. package/lib/relation-repository/hasmany-repository.d.ts +23 -0
  291. package/lib/relation-repository/hasmany-repository.js +129 -0
  292. package/lib/relation-repository/hasmany-repository.js.map +1 -0
  293. package/lib/relation-repository/hasone-repository.d.ts +17 -0
  294. package/lib/relation-repository/hasone-repository.js +8 -0
  295. package/lib/relation-repository/hasone-repository.js.map +1 -0
  296. package/lib/relation-repository/multiple-relation-repository.d.ts +23 -0
  297. package/lib/relation-repository/multiple-relation-repository.js +153 -0
  298. package/lib/relation-repository/multiple-relation-repository.js.map +1 -0
  299. package/lib/relation-repository/relation-repository.d.ts +32 -0
  300. package/lib/relation-repository/relation-repository.js +100 -0
  301. package/lib/relation-repository/relation-repository.js.map +1 -0
  302. package/lib/relation-repository/single-relation-repository.d.ts +23 -0
  303. package/lib/relation-repository/single-relation-repository.js +103 -0
  304. package/lib/relation-repository/single-relation-repository.js.map +1 -0
  305. package/lib/relation-repository/types.d.ts +7 -0
  306. package/lib/relation-repository/types.js +3 -0
  307. package/lib/relation-repository/types.js.map +1 -0
  308. package/lib/repository.d.ts +165 -0
  309. package/lib/repository.js +302 -0
  310. package/lib/repository.js.map +1 -0
  311. package/lib/transaction-decorator.d.ts +1 -0
  312. package/lib/transaction-decorator.js +70 -0
  313. package/lib/transaction-decorator.js.map +1 -0
  314. package/lib/update-associations.d.ts +60 -0
  315. package/lib/update-associations.js +374 -0
  316. package/lib/update-associations.js.map +1 -0
  317. package/lib/update-guard.d.ts +26 -0
  318. package/lib/update-guard.js +129 -0
  319. package/lib/update-guard.js.map +1 -0
  320. package/package.json +17 -5
  321. package/src/__tests__/collection-importer.test.ts +21 -0
  322. package/src/__tests__/collection.sortable.test.ts +65 -0
  323. package/src/__tests__/collection.test.ts +218 -0
  324. package/src/__tests__/database.import.test.ts +33 -0
  325. package/src/__tests__/database.test.ts +229 -0
  326. package/src/__tests__/field-options/hidden.test.ts +302 -0
  327. package/src/__tests__/field-options/sort-by.test.ts +220 -0
  328. package/src/__tests__/fields/belongs-to-field.test.ts +162 -0
  329. package/src/__tests__/fields/belongs-to-many-field.test.ts +61 -0
  330. package/src/__tests__/fields/context-field.test.ts +140 -0
  331. package/src/__tests__/fields/has-many-field.test.ts +152 -0
  332. package/src/__tests__/fields/has-one-field.test.ts +67 -0
  333. package/src/__tests__/fields/password-field.test.ts +30 -0
  334. package/src/__tests__/fields/sort-field.test.ts +133 -0
  335. package/src/__tests__/fields/string-field.test.ts +77 -0
  336. package/src/__tests__/filter-parser.test.ts +104 -0
  337. package/src/__tests__/fixtures/c0/a.ts +6 -0
  338. package/src/__tests__/fixtures/c1/b.ts +6 -0
  339. package/src/__tests__/fixtures/c2/a.ts +6 -0
  340. package/src/__tests__/fixtures/collections/delay-extend.ts +6 -0
  341. package/src/__tests__/fixtures/collections/delay-extend2.ts +6 -0
  342. package/src/__tests__/fixtures/collections/extend.ts +6 -0
  343. package/src/__tests__/fixtures/collections/extend2.ts +6 -0
  344. package/src/__tests__/fixtures/collections/posts.ts +4 -0
  345. package/src/__tests__/fixtures/collections/tags.js +4 -0
  346. package/src/__tests__/fixtures/collections/test.jpg +0 -0
  347. package/src/__tests__/fixtures/collections/user.json +9 -0
  348. package/src/__tests__/index.ts +1 -0
  349. package/src/__tests__/magic-attribute-model.test.ts +103 -0
  350. package/src/__tests__/model.test.ts +60 -0
  351. package/src/__tests__/operator/array-operator.test.ts +268 -0
  352. package/src/__tests__/operator/association-operator.test.ts +263 -0
  353. package/src/__tests__/operator/date-operator.test.ts +165 -0
  354. package/src/__tests__/operator/empty-operator.test.ts +77 -0
  355. package/src/__tests__/operator/ne.test.ts +33 -0
  356. package/src/__tests__/operator/string-operator.test.ts +62 -0
  357. package/src/__tests__/option-parser.test.ts +185 -0
  358. package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +697 -0
  359. package/src/__tests__/relation-repository/has-many-repository.test.ts +414 -0
  360. package/src/__tests__/relation-repository/hasone-repository.test.ts +77 -0
  361. package/src/__tests__/repository/count.test.ts +180 -0
  362. package/src/__tests__/repository/create.test.ts +163 -0
  363. package/src/__tests__/repository/destroy.test.ts +196 -0
  364. package/src/__tests__/repository/find.test.ts +247 -0
  365. package/src/__tests__/repository/update.test.ts +60 -0
  366. package/src/__tests__/repository.test.ts +438 -0
  367. package/src/__tests__/update-associations.test.ts +412 -0
  368. package/src/__tests__/update-guard.test.ts +376 -0
  369. package/src/collection-importer.ts +49 -0
  370. package/src/collection.ts +282 -0
  371. package/src/database.ts +340 -0
  372. package/src/fields/array-field.ts +35 -0
  373. package/src/fields/belongs-to-field.ts +76 -0
  374. package/src/fields/belongs-to-many-field.ts +77 -0
  375. package/src/fields/boolean-field.ts +12 -0
  376. package/src/fields/context-field.ts +45 -0
  377. package/src/fields/date-field.ts +12 -0
  378. package/src/fields/field.ts +105 -0
  379. package/src/fields/has-inverse-field.ts +5 -0
  380. package/src/fields/has-many-field.ts +143 -0
  381. package/src/fields/has-one-field.ts +136 -0
  382. package/src/fields/index.ts +72 -0
  383. package/src/fields/json-field.ts +25 -0
  384. package/src/fields/number-field.ts +52 -0
  385. package/src/fields/password-field.ts +72 -0
  386. package/src/fields/radio-field.ts +50 -0
  387. package/src/fields/relation-field.ts +37 -0
  388. package/src/fields/sort-field.ts +96 -0
  389. package/src/fields/string-field.ts +12 -0
  390. package/src/fields/text-field.ts +12 -0
  391. package/src/fields/time-field.ts +12 -0
  392. package/src/fields/uid-field.ts +24 -0
  393. package/src/fields/virtual-field.ts +12 -0
  394. package/src/filter-parser.ts +243 -0
  395. package/src/index.ts +16 -0
  396. package/src/magic-attribute-model.ts +62 -0
  397. package/src/mock-database.ts +42 -0
  398. package/src/model-hook.ts +69 -0
  399. package/src/model.ts +114 -0
  400. package/src/operators/array.ts +145 -0
  401. package/src/operators/association.ts +14 -0
  402. package/src/operators/date.ts +41 -0
  403. package/src/operators/empty.ts +75 -0
  404. package/src/operators/index.ts +8 -0
  405. package/src/operators/ne.ts +12 -0
  406. package/src/operators/string.ts +40 -0
  407. package/src/operators/utils.ts +13 -0
  408. package/src/options-parser.ts +285 -0
  409. package/src/playground.ts +52 -0
  410. package/src/relation-repository/belongs-to-many-repository.ts +240 -0
  411. package/src/relation-repository/belongs-to-repository.ts +23 -0
  412. package/src/relation-repository/hasmany-repository.ts +145 -0
  413. package/src/relation-repository/hasone-repository.ts +23 -0
  414. package/src/relation-repository/multiple-relation-repository.ts +198 -0
  415. package/src/relation-repository/relation-repository.ts +114 -0
  416. package/src/relation-repository/single-relation-repository.ts +99 -0
  417. package/src/relation-repository/types.ts +15 -0
  418. package/src/repository.ts +478 -0
  419. package/src/transaction-decorator.ts +58 -0
  420. package/src/update-associations.ts +478 -0
  421. package/src/update-guard.ts +167 -0
  422. package/tsconfig.build.json +9 -0
  423. package/tsconfig.json +5 -0
  424. package/examples/index.ts +0 -125
  425. package/examples/plugins/db-driven/index.ts +0 -25
  426. package/examples/plugins/db-driven/tables/fields.ts +0 -78
  427. package/examples/plugins/db-driven/tables/tables.ts +0 -53
  428. package/examples/tables/bar.js +0 -26
  429. package/examples/tables/comments.ts +0 -19
  430. package/examples/tables/foo.json +0 -3
  431. package/examples/tables/posts.ts +0 -28
  432. package/examples/tables/profiles.ts +0 -23
  433. package/examples/tables/tags.ts +0 -15
  434. package/examples/tables/users.ts +0 -34
  435. package/lib/database.d.ts.map +0 -1
  436. package/lib/fields/field-types.d.ts +0 -419
  437. package/lib/fields/field-types.d.ts.map +0 -1
  438. package/lib/fields/field-types.js +0 -1222
  439. package/lib/fields/field-types.js.map +0 -1
  440. package/lib/fields/index.d.ts.map +0 -1
  441. package/lib/fields/option-types.d.ts +0 -105
  442. package/lib/fields/option-types.d.ts.map +0 -1
  443. package/lib/fields/option-types.js +0 -18
  444. package/lib/fields/option-types.js.map +0 -1
  445. package/lib/index.d.ts.map +0 -1
  446. package/lib/model.d.ts.map +0 -1
  447. package/lib/op.d.ts +0 -45
  448. package/lib/op.d.ts.map +0 -1
  449. package/lib/op.js +0 -225
  450. package/lib/op.js.map +0 -1
  451. package/lib/table.d.ts +0 -56
  452. package/lib/table.d.ts.map +0 -1
  453. package/lib/table.js +0 -456
  454. package/lib/table.js.map +0 -1
  455. package/lib/utils.d.ts +0 -26
  456. package/lib/utils.d.ts.map +0 -1
  457. package/lib/utils.js +0 -438
  458. package/lib/utils.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ import { Field } from './field';
2
+
3
+ export interface HasInverseField {
4
+ inverseField: () => Field;
5
+ }
@@ -0,0 +1,143 @@
1
+ import { omit } from 'lodash';
2
+ import {
3
+ AssociationScope,
4
+ DataType,
5
+ ForeignKeyOptions,
6
+ HasManyOptions,
7
+ HasManyOptions as SequelizeHasManyOptions,
8
+ Utils,
9
+ } from 'sequelize';
10
+
11
+ import { BaseRelationFieldOptions, MultipleRelationFieldOptions, RelationField } from './relation-field';
12
+
13
+ export interface HasManyFieldOptions extends HasManyOptions {
14
+ /**
15
+ * The name of the field to use as the key for the association in the source table. Defaults to the primary
16
+ * key of the source table
17
+ */
18
+ sourceKey?: string;
19
+
20
+ /**
21
+ * A string or a data type to represent the identifier in the table
22
+ */
23
+ keyType?: DataType;
24
+
25
+ scope?: AssociationScope;
26
+
27
+ /**
28
+ * The alias of this model, in singular form. See also the `name` option passed to `sequelize.define`. If
29
+ * you create multiple associations between the same tables, you should provide an alias to be able to
30
+ * distinguish between them. If you provide an alias when creating the assocition, you should provide the
31
+ * same alias when eager loading and when getting associated models. Defaults to the singularized name of
32
+ * target
33
+ */
34
+ as?: string | { singular: string; plural: string };
35
+
36
+ /**
37
+ * The name of the foreign key in the target table or an object representing the type definition for the
38
+ * foreign column (see `Sequelize.define` for syntax). When using an object, you can add a `name` property
39
+ * to set the name of the column. Defaults to the name of source + primary key of source
40
+ */
41
+ foreignKey?: string | ForeignKeyOptions;
42
+
43
+ /**
44
+ * What happens when delete occurs.
45
+ *
46
+ * Cascade if this is a n:m, and set null if it is a 1:m
47
+ *
48
+ * @default 'SET NULL' or 'CASCADE'
49
+ */
50
+ onDelete?: string;
51
+
52
+ /**
53
+ * What happens when update occurs
54
+ *
55
+ * @default 'CASCADE'
56
+ */
57
+ onUpdate?: string;
58
+
59
+ /**
60
+ * Should on update and on delete constraints be enabled on the foreign key.
61
+ */
62
+ constraints?: boolean;
63
+ foreignKeyConstraint?: boolean;
64
+
65
+ // scope?: AssociationScope;
66
+
67
+ /**
68
+ * If `false` the applicable hooks will not be called.
69
+ * The default value depends on the context.
70
+ */
71
+ hooks?: boolean;
72
+ }
73
+
74
+ export class HasManyField extends RelationField {
75
+ get foreignKey() {
76
+ if (this.options.foreignKey) {
77
+ return this.options.foreignKey;
78
+ }
79
+ const { model } = this.context.collection;
80
+ return Utils.camelize([model.options.name.singular, this.sourceKey || model.primaryKeyAttribute].join('_'));
81
+ }
82
+
83
+ bind() {
84
+ const { database, collection } = this.context;
85
+ const Target = this.TargetModel;
86
+ if (!Target) {
87
+ database.addPendingField(this);
88
+ return false;
89
+ }
90
+
91
+ if (collection.model.associations[this.name]) {
92
+ delete collection.model.associations[this.name];
93
+ }
94
+
95
+ const association = collection.model.hasMany(Target, {
96
+ as: this.name,
97
+ foreignKey: this.foreignKey,
98
+ ...omit(this.options, ['name', 'type', 'target']),
99
+ });
100
+
101
+ // inverse relation
102
+ // this.TargetModel.belongsTo(collection.model);
103
+
104
+ // 建立关系之后从 pending 列表中删除
105
+ database.removePendingField(this);
106
+
107
+ if (!this.options.foreignKey) {
108
+ this.options.foreignKey = association.foreignKey;
109
+ }
110
+ if (!this.options.sourceKey) {
111
+ // @ts-ignore
112
+ this.options.sourceKey = association.sourceKey;
113
+ }
114
+ return true;
115
+ }
116
+
117
+ unbind() {
118
+ const { database, collection } = this.context;
119
+ // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
120
+ database.removePendingField(this);
121
+ // 如果关系表内没有显式的创建外键字段,删除关系时,外键也删除掉
122
+ const tcoll = database.collections.get(this.target);
123
+ const foreignKey = this.options.foreignKey;
124
+ const field = tcoll.findField((field) => {
125
+ if (field.name === foreignKey) {
126
+ return true;
127
+ }
128
+ return field.type === 'belongsTo' && field.foreignKey === foreignKey;
129
+ });
130
+ if (!field) {
131
+ tcoll.model.removeAttribute(foreignKey);
132
+ }
133
+ // 删掉 model 的关联字段
134
+ delete collection.model.associations[this.name];
135
+ // @ts-ignore
136
+ collection.model.refreshAttributes();
137
+ }
138
+ }
139
+
140
+ export interface HasManyFieldOptions extends MultipleRelationFieldOptions, SequelizeHasManyOptions {
141
+ type: 'hasMany';
142
+ target?: string;
143
+ }
@@ -0,0 +1,136 @@
1
+ import { omit } from 'lodash';
2
+ import {
3
+ AssociationScope,
4
+ DataType,
5
+ ForeignKeyOptions,
6
+ HasOneOptions,
7
+ HasOneOptions as SequelizeHasOneOptions,
8
+ Utils
9
+ } from 'sequelize';
10
+ import { BaseRelationFieldOptions, RelationField } from './relation-field';
11
+
12
+ export interface HasOneFieldOptions extends HasOneOptions {
13
+ /**
14
+ * The name of the field to use as the key for the association in the source table. Defaults to the primary
15
+ * key of the source table
16
+ */
17
+ sourceKey?: string;
18
+
19
+ /**
20
+ * A string or a data type to represent the identifier in the table
21
+ */
22
+ keyType?: DataType;
23
+
24
+ scope?: AssociationScope;
25
+
26
+ /**
27
+ * The alias of this model, in singular form. See also the `name` option passed to `sequelize.define`. If
28
+ * you create multiple associations between the same tables, you should provide an alias to be able to
29
+ * distinguish between them. If you provide an alias when creating the assocition, you should provide the
30
+ * same alias when eager loading and when getting associated models. Defaults to the singularized name of
31
+ * target
32
+ */
33
+ as?: string | { singular: string; plural: string };
34
+
35
+ /**
36
+ * The name of the foreign key in the target table or an object representing the type definition for the
37
+ * foreign column (see `Sequelize.define` for syntax). When using an object, you can add a `name` property
38
+ * to set the name of the column. Defaults to the name of source + primary key of source
39
+ */
40
+ foreignKey?: string | ForeignKeyOptions;
41
+
42
+ /**
43
+ * What happens when delete occurs.
44
+ *
45
+ * Cascade if this is a n:m, and set null if it is a 1:m
46
+ *
47
+ * @default 'SET NULL' or 'CASCADE'
48
+ */
49
+ onDelete?: string;
50
+
51
+ /**
52
+ * What happens when update occurs
53
+ *
54
+ * @default 'CASCADE'
55
+ */
56
+ onUpdate?: string;
57
+
58
+ /**
59
+ * Should on update and on delete constraints be enabled on the foreign key.
60
+ */
61
+ constraints?: boolean;
62
+ foreignKeyConstraint?: boolean;
63
+
64
+ // scope?: AssociationScope;
65
+
66
+ /**
67
+ * If `false` the applicable hooks will not be called.
68
+ * The default value depends on the context.
69
+ */
70
+ hooks?: boolean;
71
+ }
72
+
73
+ export class HasOneField extends RelationField {
74
+ get target() {
75
+ const { target, name } = this.options;
76
+ return target || Utils.pluralize(name);
77
+ }
78
+
79
+ get foreignKey() {
80
+ if (this.options.foreignKey) {
81
+ return this.options.foreignKey;
82
+ }
83
+ const { model } = this.context.collection;
84
+ return Utils.camelize([model.options.name.singular, model.primaryKeyAttribute].join('_'));
85
+ }
86
+
87
+ bind() {
88
+ const { database, collection } = this.context;
89
+ const Target = this.TargetModel;
90
+ if (!Target) {
91
+ database.addPendingField(this);
92
+ return false;
93
+ }
94
+ const association = collection.model.hasOne(Target, {
95
+ as: this.name,
96
+ foreignKey: this.foreignKey,
97
+ ...omit(this.options, ['name', 'type', 'target']),
98
+ });
99
+ // 建立关系之后从 pending 列表中删除
100
+ database.removePendingField(this);
101
+ if (!this.options.foreignKey) {
102
+ this.options.foreignKey = association.foreignKey;
103
+ }
104
+ if (!this.options.sourceKey) {
105
+ // @ts-ignore
106
+ this.options.sourceKey = association.sourceKey;
107
+ }
108
+ return true;
109
+ }
110
+
111
+ unbind() {
112
+ const { database, collection } = this.context;
113
+ // 如果关系字段还没建立就删除了,也同步删除待建立关联的关系字段
114
+ database.removePendingField(this);
115
+ // 如果关系表内没有显式的创建外键字段,删除关系时,外键也删除掉
116
+ const tcoll = database.collections.get(this.target);
117
+ const foreignKey = this.options.foreignKey;
118
+ const field = tcoll.findField((field) => {
119
+ if (field.name === foreignKey) {
120
+ return true;
121
+ }
122
+ return field.type === 'belongsTo' && field.foreignKey === foreignKey;
123
+ });
124
+ if (!field) {
125
+ tcoll.model.removeAttribute(foreignKey);
126
+ }
127
+ // 删掉 model 的关联字段
128
+ delete collection.model.associations[this.name];
129
+ // @ts-ignore
130
+ collection.model.refreshAttributes();
131
+ }
132
+ }
133
+
134
+ export interface HasOneFieldOptions extends BaseRelationFieldOptions, SequelizeHasOneOptions {
135
+ type: 'hasOne';
136
+ }
@@ -0,0 +1,72 @@
1
+ import { ArrayFieldOptions } from './array-field';
2
+ import { BelongsToFieldOptions } from './belongs-to-field';
3
+ import { BelongsToManyFieldOptions } from './belongs-to-many-field';
4
+ import { BooleanFieldOptions } from './boolean-field';
5
+ import { ContextFieldOptions } from './context-field';
6
+ import { DateFieldOptions } from './date-field';
7
+ import { BaseFieldOptions } from './field';
8
+ import { HasManyFieldOptions } from './has-many-field';
9
+ import { HasOneFieldOptions } from './has-one-field';
10
+ import { JsonbFieldOptions, JsonFieldOptions } from './json-field';
11
+ import {
12
+ DecimalFieldOptions,
13
+ DoubleFieldOptions,
14
+ FloatFieldOptions,
15
+ IntegerFieldOptions,
16
+ RealFieldOptions
17
+ } from './number-field';
18
+ import { PasswordFieldOptions } from './password-field';
19
+ import { RadioFieldOptions } from './radio-field';
20
+ import { SortFieldOptions } from './sort-field';
21
+ import { StringFieldOptions } from './string-field';
22
+ import { TextFieldOptions } from './text-field';
23
+ import { TimeFieldOptions } from './time-field';
24
+ import { UidFieldOptions } from './uid-field';
25
+ import { VirtualFieldOptions } from './virtual-field';
26
+
27
+ export * from './array-field';
28
+ export * from './belongs-to-field';
29
+ export * from './belongs-to-many-field';
30
+ export * from './boolean-field';
31
+ export * from './context-field';
32
+ export * from './date-field';
33
+ export * from './field';
34
+ export * from './has-many-field';
35
+ export * from './has-one-field';
36
+ export * from './json-field';
37
+ export * from './number-field';
38
+ export * from './password-field';
39
+ export * from './radio-field';
40
+ export * from './relation-field';
41
+ export * from './sort-field';
42
+ export * from './string-field';
43
+ export * from './text-field';
44
+ export * from './time-field';
45
+ export * from './uid-field';
46
+ export * from './virtual-field';
47
+
48
+ export type FieldOptions =
49
+ | BaseFieldOptions
50
+ | StringFieldOptions
51
+ | IntegerFieldOptions
52
+ | FloatFieldOptions
53
+ | DecimalFieldOptions
54
+ | DoubleFieldOptions
55
+ | RealFieldOptions
56
+ | JsonFieldOptions
57
+ | JsonbFieldOptions
58
+ | BooleanFieldOptions
59
+ | RadioFieldOptions
60
+ | SortFieldOptions
61
+ | TextFieldOptions
62
+ | VirtualFieldOptions
63
+ | ArrayFieldOptions
64
+ | TimeFieldOptions
65
+ | DateFieldOptions
66
+ | UidFieldOptions
67
+ | PasswordFieldOptions
68
+ | ContextFieldOptions
69
+ | BelongsToFieldOptions
70
+ | HasOneFieldOptions
71
+ | HasManyFieldOptions
72
+ | BelongsToManyFieldOptions;
@@ -0,0 +1,25 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { BaseColumnFieldOptions, Field } from './field';
3
+
4
+ export class JsonField extends Field {
5
+ get dataType() {
6
+ return DataTypes.JSON;
7
+ }
8
+ }
9
+
10
+ export interface JsonFieldOptions extends BaseColumnFieldOptions {
11
+ type: 'json';
12
+ }
13
+
14
+ export class JsonbField extends Field {
15
+ get dataType() {
16
+ const dialect = this.context.database.sequelize.getDialect();
17
+ if (dialect === 'postgres') {
18
+ return DataTypes.JSONB;
19
+ }
20
+ return DataTypes.JSON;
21
+ }
22
+ }
23
+ export interface JsonbFieldOptions extends BaseColumnFieldOptions {
24
+ type: 'jsonb';
25
+ }
@@ -0,0 +1,52 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { BaseColumnFieldOptions, Field } from './field';
3
+
4
+ export class IntegerField extends Field {
5
+ get dataType() {
6
+ return DataTypes.INTEGER;
7
+ }
8
+ }
9
+
10
+ export interface IntegerFieldOptions extends BaseColumnFieldOptions {
11
+ type: 'integer';
12
+ }
13
+
14
+ export class FloatField extends Field {
15
+ get dataType() {
16
+ return DataTypes.FLOAT;
17
+ }
18
+ }
19
+
20
+ export interface FloatFieldOptions extends BaseColumnFieldOptions {
21
+ type: 'float';
22
+ }
23
+
24
+ export class DoubleField extends Field {
25
+ get dataType() {
26
+ return DataTypes.DOUBLE;
27
+ }
28
+ }
29
+
30
+ export interface DoubleFieldOptions extends BaseColumnFieldOptions {
31
+ type: 'double';
32
+ }
33
+
34
+ export class RealField extends Field {
35
+ get dataType() {
36
+ return DataTypes.REAL;
37
+ }
38
+ }
39
+
40
+ export interface RealFieldOptions extends BaseColumnFieldOptions {
41
+ type: 'real';
42
+ }
43
+
44
+ export class DecimalField extends Field {
45
+ get dataType() {
46
+ return DataTypes.DECIMAL;
47
+ }
48
+ }
49
+
50
+ export interface DecimalFieldOptions extends BaseColumnFieldOptions {
51
+ type: 'decimal';
52
+ }
@@ -0,0 +1,72 @@
1
+ import crypto from 'crypto';
2
+ import { DataTypes } from 'sequelize';
3
+ import { BaseColumnFieldOptions, Field } from './field';
4
+
5
+ export interface PasswordFieldOptions extends BaseColumnFieldOptions {
6
+ type: 'password';
7
+ /**
8
+ * @default 64
9
+ */
10
+ length?: number;
11
+ /**
12
+ * @default 8
13
+ */
14
+ randomBytesSize?: number;
15
+ }
16
+
17
+ export class PasswordField extends Field {
18
+ get dataType() {
19
+ return DataTypes.STRING;
20
+ }
21
+
22
+ async verify(password: string, hash: string) {
23
+ const { length = 64, randomBytesSize = 8 } = this.options;
24
+ return new Promise((resolve, reject) => {
25
+ const salt = hash.substring(0, randomBytesSize * 2);
26
+ const key = hash.substring(randomBytesSize * 2);
27
+ crypto.scrypt(password, salt, length / 2 - randomBytesSize, (err, derivedKey) => {
28
+ if (err) reject(err);
29
+ resolve(key == derivedKey.toString('hex'));
30
+ });
31
+ });
32
+ }
33
+
34
+ async hash(password: string) {
35
+ const { length = 64, randomBytesSize = 8 } = this.options;
36
+ return new Promise((resolve, reject) => {
37
+ const salt = crypto.randomBytes(randomBytesSize).toString('hex');
38
+ crypto.scrypt(password, salt, length / 2 - randomBytesSize, (err, derivedKey) => {
39
+ if (err) reject(err);
40
+ resolve(salt + derivedKey.toString('hex'));
41
+ });
42
+ });
43
+ }
44
+
45
+ init() {
46
+ const { name } = this.options;
47
+ this.listener = async (model) => {
48
+ if (!model.changed(name as any)) {
49
+ return;
50
+ }
51
+ const value = model.get(name) as string;
52
+ if (value) {
53
+ const hash = await this.hash(value);
54
+ model.set(name, hash);
55
+ } else {
56
+ model.set(name, null);
57
+ }
58
+ };
59
+ }
60
+
61
+ bind() {
62
+ super.bind();
63
+ this.on('beforeCreate', this.listener);
64
+ this.on('beforeUpdate', this.listener);
65
+ }
66
+
67
+ unbind() {
68
+ super.unbind();
69
+ this.off('beforeCreate', this.listener);
70
+ this.off('beforeUpdate', this.listener);
71
+ }
72
+ }
@@ -0,0 +1,50 @@
1
+ import { DataTypes } from 'sequelize';
2
+ import { BaseColumnFieldOptions, Field } from './field';
3
+
4
+ export interface RadioFieldOptions extends BaseColumnFieldOptions {
5
+ type: 'radio';
6
+ }
7
+
8
+ /**
9
+ * 暂时只支持全局,不支持批量
10
+ */
11
+ export class RadioField extends Field {
12
+ get dataType() {
13
+ return DataTypes.BOOLEAN;
14
+ }
15
+
16
+ init() {
17
+ const { name } = this.options;
18
+ this.listener = async (model, { transaction }) => {
19
+ if (!model.changed(name as any)) {
20
+ return;
21
+ }
22
+ const value = model.get(name) as boolean;
23
+ if (value) {
24
+ const M = this.collection.model;
25
+ await M.update(
26
+ { [name]: false },
27
+ {
28
+ where: {
29
+ [name]: true,
30
+ },
31
+ transaction,
32
+ hooks: false,
33
+ },
34
+ );
35
+ }
36
+ };
37
+ }
38
+
39
+ bind() {
40
+ super.bind();
41
+ this.on('beforeCreate', this.listener.bind(this));
42
+ this.on('beforeUpdate', this.listener.bind(this));
43
+ }
44
+
45
+ unbind() {
46
+ super.unbind();
47
+ this.off('beforeCreate', this.listener.bind(this));
48
+ this.off('beforeUpdate', this.listener.bind(this));
49
+ }
50
+ }
@@ -0,0 +1,37 @@
1
+ import { BaseFieldOptions, Field } from './field';
2
+
3
+ export interface BaseRelationFieldOptions extends BaseFieldOptions {}
4
+
5
+ export interface MultipleRelationFieldOptions extends BaseRelationFieldOptions {
6
+ sortBy?: string | string[];
7
+ }
8
+
9
+ export abstract class RelationField extends Field {
10
+ /**
11
+ * target relation name
12
+ */
13
+ get target() {
14
+ const { target, name } = this.options;
15
+ return target || name;
16
+ }
17
+
18
+ get foreignKey() {
19
+ return this.options.foreignKey;
20
+ }
21
+
22
+ get sourceKey() {
23
+ return this.options.sourceKey || this.collection.model.primaryKeyAttribute;
24
+ }
25
+
26
+ get targetKey() {
27
+ return this.options.targetKey || this.TargetModel.primaryKeyAttribute;
28
+ }
29
+
30
+ /**
31
+ * get target model from database by it's name
32
+ * @constructor
33
+ */
34
+ get TargetModel() {
35
+ return this.context.database.sequelize.models[this.target];
36
+ }
37
+ }
@@ -0,0 +1,96 @@
1
+ import { Mutex } from 'async-mutex';
2
+ import { isNumber } from 'lodash';
3
+ import { DataTypes } from 'sequelize';
4
+ import { BaseColumnFieldOptions, Field } from './field';
5
+
6
+ const sortFieldMutex = new Mutex();
7
+
8
+ export class SortField extends Field {
9
+ get dataType() {
10
+ return DataTypes.INTEGER;
11
+ }
12
+
13
+ async setSortValue(instance, options) {
14
+ const { name, scopeKey } = this.options;
15
+ const { model } = this.context.collection;
16
+
17
+ if (isNumber(instance.get(name)) && instance._previousDataValues[scopeKey] == instance[scopeKey]) {
18
+ return;
19
+ }
20
+
21
+ const where = {};
22
+
23
+ if (scopeKey) {
24
+ const value = instance.get(scopeKey);
25
+ if (value !== undefined && value !== null) {
26
+ where[scopeKey] = value;
27
+ }
28
+ }
29
+
30
+ await sortFieldMutex.runExclusive(async () => {
31
+ const max = await model.max<number, any>(name, { ...options, where });
32
+ const newValue = (max || 0) + 1;
33
+ instance.set(name, newValue);
34
+ });
35
+ }
36
+
37
+ async onScopeChange(instance, options) {
38
+ const { scopeKey } = this.options;
39
+ if (scopeKey && !instance.isNewRecord && instance._previousDataValues[scopeKey] != instance[scopeKey]) {
40
+ await this.setSortValue(instance, options);
41
+ }
42
+ }
43
+
44
+ async initRecordsSortValue({ transaction }) {
45
+ const totalCount = await this.collection.repository.count({
46
+ transaction,
47
+ });
48
+ const emptyCount = await this.collection.repository.count({
49
+ filter: {
50
+ [this.name]: null,
51
+ },
52
+ transaction,
53
+ });
54
+
55
+ if (emptyCount === totalCount && emptyCount > 0) {
56
+ const records = await this.collection.repository.find({
57
+ order: [this.collection.model.primaryKeyAttribute],
58
+ transaction,
59
+ });
60
+
61
+ let start = 1;
62
+ for (const record of records) {
63
+ await record.update(
64
+ {
65
+ sort: start,
66
+ },
67
+ {
68
+ transaction,
69
+ silent: true,
70
+ },
71
+ );
72
+
73
+ start += 1;
74
+ }
75
+ }
76
+ }
77
+
78
+ bind() {
79
+ super.bind();
80
+ this.on('afterSync', this.initRecordsSortValue.bind(this));
81
+ this.on('beforeUpdate', this.onScopeChange.bind(this));
82
+ this.on('beforeCreate', this.setSortValue.bind(this));
83
+ }
84
+
85
+ unbind() {
86
+ super.unbind();
87
+ this.off('beforeUpdate', this.onScopeChange.bind(this));
88
+ this.off('beforeCreate', this.setSortValue.bind(this));
89
+ this.off('afterSync', this.initRecordsSortValue.bind(this));
90
+ }
91
+ }
92
+
93
+ export interface SortFieldOptions extends BaseColumnFieldOptions {
94
+ type: 'sort';
95
+ scopeKey?: string;
96
+ }