@baasix/baasix 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (666) hide show
  1. package/LICENSE.MD +85 -0
  2. package/README.md +526 -0
  3. package/assets/banner.jpg +0 -0
  4. package/assets/banner_small.jpg +0 -0
  5. package/assets/logo_icon.svg +20 -0
  6. package/assets/logo_icon_rounded.svg +20 -0
  7. package/dist/LICENSE.MD +85 -0
  8. package/dist/README.md +526 -0
  9. package/dist/app/404/index.html +1 -0
  10. package/dist/app/404.html +1 -0
  11. package/dist/app/_next/static/chunks/041e1f03-56ae8a902a7f2fe6.js +24 -0
  12. package/dist/app/_next/static/chunks/1117-05479929a8da73e3.js +1 -0
  13. package/dist/app/_next/static/chunks/1299.77cc7b7b76b75cba.js +1 -0
  14. package/dist/app/_next/static/chunks/1303-35a96e9c9cdeab9d.js +1 -0
  15. package/dist/app/_next/static/chunks/1509-56ac00cdaaecdf53.js +1 -0
  16. package/dist/app/_next/static/chunks/1668-e3eabd0f6753c780.js +1 -0
  17. package/dist/app/_next/static/chunks/1783-d9fb550fd324300c.js +1 -0
  18. package/dist/app/_next/static/chunks/2117-29b5fa47421595ad.js +2 -0
  19. package/dist/app/_next/static/chunks/2344.35b46d2179a765b5.js +1 -0
  20. package/dist/app/_next/static/chunks/257.990da16794a31292.js +1 -0
  21. package/dist/app/_next/static/chunks/2676-73b0ee7c80073a84.js +1 -0
  22. package/dist/app/_next/static/chunks/3563-b8842744384391fe.js +1 -0
  23. package/dist/app/_next/static/chunks/363642f4-933b579ed3c85f60.js +1 -0
  24. package/dist/app/_next/static/chunks/3817-e20c8f0a0810fc95.js +1 -0
  25. package/dist/app/_next/static/chunks/3834.84944e390d902509.js +2 -0
  26. package/dist/app/_next/static/chunks/4043-3a30c8a75896f241.js +1 -0
  27. package/dist/app/_next/static/chunks/4225-14090c7c0cd9dec6.js +1 -0
  28. package/dist/app/_next/static/chunks/4438-c9a12ca15b6e9160.js +1 -0
  29. package/dist/app/_next/static/chunks/4458-679fd0c6884f456a.js +1 -0
  30. package/dist/app/_next/static/chunks/4475-8bdfbd536fba8c48.js +1 -0
  31. package/dist/app/_next/static/chunks/4883-8a924721bb21b3b0.js +1 -0
  32. package/dist/app/_next/static/chunks/489-683ab07188f9df2b.js +1 -0
  33. package/dist/app/_next/static/chunks/4952-1b97320cf61f3f21.js +1 -0
  34. package/dist/app/_next/static/chunks/5094-8d53e403235d4ca6.js +1 -0
  35. package/dist/app/_next/static/chunks/5101-3a146e0625747ad1.js +1 -0
  36. package/dist/app/_next/static/chunks/54a60aa6-d9747982e0a81f58.js +79 -0
  37. package/dist/app/_next/static/chunks/5650-f096291df402bfc2.js +1 -0
  38. package/dist/app/_next/static/chunks/600-539045311240f579.js +1 -0
  39. package/dist/app/_next/static/chunks/6170-803b82e19d3ade6d.js +89 -0
  40. package/dist/app/_next/static/chunks/6241-30d7169d1010e5a4.js +1 -0
  41. package/dist/app/_next/static/chunks/6530-a91e10cffa4200c4.js +1 -0
  42. package/dist/app/_next/static/chunks/6547-4bbbdb5c399aef1e.js +1 -0
  43. package/dist/app/_next/static/chunks/6712-781937c53a2c49da.js +1 -0
  44. package/dist/app/_next/static/chunks/6fcbdc68-90be1a5480b8d353.js +1 -0
  45. package/dist/app/_next/static/chunks/70e0d97a-aeaf0cdc26ba1a58.js +1 -0
  46. package/dist/app/_next/static/chunks/7214-5154a89d08d24dde.js +1 -0
  47. package/dist/app/_next/static/chunks/7324-b53229c59a640880.js +10 -0
  48. package/dist/app/_next/static/chunks/7636-66424f0b51d350e9.js +1 -0
  49. package/dist/app/_next/static/chunks/7874-39a3f2541165a675.js +1 -0
  50. package/dist/app/_next/static/chunks/7982-9da12b83f11e3f5f.js +1 -0
  51. package/dist/app/_next/static/chunks/8213a2eb-da25a3b3c5521b2b.js +1 -0
  52. package/dist/app/_next/static/chunks/8473-6598318371eca31b.js +1 -0
  53. package/dist/app/_next/static/chunks/8640fa6b-72e43370f68e5587.js +1 -0
  54. package/dist/app/_next/static/chunks/9090-3ef676f29c95f1c7.js +1 -0
  55. package/dist/app/_next/static/chunks/9124-a02f9e209e6e3cce.js +1 -0
  56. package/dist/app/_next/static/chunks/926-156f32067d111d6b.js +1 -0
  57. package/dist/app/_next/static/chunks/9487-b17481605e513b83.js +1 -0
  58. package/dist/app/_next/static/chunks/9599-a7e572bb88c3392b.js +1 -0
  59. package/dist/app/_next/static/chunks/9881-419697138376e755.js +1 -0
  60. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/all-activity/page-8917930b4d663405.js +1 -0
  61. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/email-log/page-b27a6ee32782d7df.js +1 -0
  62. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/notifications/page-b7eda523ede2702c.js +1 -0
  63. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/page-1cfa62d1caedaed0.js +1 -0
  64. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/sessions/page-3e21e20db90aeff7.js +1 -0
  65. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-executions/page-27bcc26b747fb29b.js +1 -0
  66. package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-logs/page-9f9e9e952aef436e.js +1 -0
  67. package/dist/app/_next/static/chunks/app/(authenticated)/change-password/page-8d61aa499eabb127.js +1 -0
  68. package/dist/app/_next/static/chunks/app/(authenticated)/dashboard/page-1ceeac9e72997a8a.js +1 -0
  69. package/dist/app/_next/static/chunks/app/(authenticated)/data-browser/page-8cda2b57759dd670.js +1 -0
  70. package/dist/app/_next/static/chunks/app/(authenticated)/file-manager/page-8c6f1b1da66ad7e4.js +1 -0
  71. package/dist/app/_next/static/chunks/app/(authenticated)/layout-f70d225b2759c998.js +1 -0
  72. package/dist/app/_next/static/chunks/app/(authenticated)/settings/migrations/page-aacec8f7cfb40ab2.js +1 -0
  73. package/dist/app/_next/static/chunks/app/(authenticated)/settings/permissions/page-828110cfcde429c6.js +1 -0
  74. package/dist/app/_next/static/chunks/app/(authenticated)/settings/project/page-420e794bb76bd204.js +1 -0
  75. package/dist/app/_next/static/chunks/app/(authenticated)/settings/roles/page-9001d02b28f70708.js +1 -0
  76. package/dist/app/_next/static/chunks/app/(authenticated)/settings/schema/page-899574f35091dd58.js +1 -0
  77. package/dist/app/_next/static/chunks/app/(authenticated)/settings/tasks/page-ad7ab3e27c83f44f.js +1 -0
  78. package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/edit/page-bd83414cb8c4cb04.js +1 -0
  79. package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/page-3181447f8772b1d3.js +1 -0
  80. package/dist/app/_next/static/chunks/app/(authenticated)/settings/tenants/page-ef9bfbacef5a1d73.js +1 -0
  81. package/dist/app/_next/static/chunks/app/(authenticated)/users/invites/page-480306b7b2bbac7e.js +1 -0
  82. package/dist/app/_next/static/chunks/app/(authenticated)/users/list/page-74da51254c2606b3.js +1 -0
  83. package/dist/app/_next/static/chunks/app/(authenticated)/users/page-e99c6f0b915001b2.js +1 -0
  84. package/dist/app/_next/static/chunks/app/(authenticated)/users/preferences/page-1a935630ce8f2b12.js +1 -0
  85. package/dist/app/_next/static/chunks/app/(authenticated)/users/user-roles/page-901dfb8ea1f39ca8.js +1 -0
  86. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/detail/page-9a6b839aea688ca4.js +1 -0
  87. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/edit/page-11774efbc2fecae2.js +1 -0
  88. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/execution/page-8ec1aea90412c03d.js +1 -0
  89. package/dist/app/_next/static/chunks/app/(authenticated)/workflows/page-88bc5b36ccb0a1f7.js +1 -0
  90. package/dist/app/_next/static/chunks/app/(public)/forgot-password/page-ed263fd46ef81c20.js +1 -0
  91. package/dist/app/_next/static/chunks/app/(public)/layout-f538977545844af8.js +1 -0
  92. package/dist/app/_next/static/chunks/app/(public)/login/page-c0a10b137f346096.js +1 -0
  93. package/dist/app/_next/static/chunks/app/(public)/register/page-4cb7644893efd9b3.js +1 -0
  94. package/dist/app/_next/static/chunks/app/_not-found/page-653f8815b78256cc.js +1 -0
  95. package/dist/app/_next/static/chunks/app/layout-591ca7a3e16528a1.js +1 -0
  96. package/dist/app/_next/static/chunks/app/page-dd19d124b5fa2577.js +1 -0
  97. package/dist/app/_next/static/chunks/c37d3baf.c2ff165f5b02c692.js +1 -0
  98. package/dist/app/_next/static/chunks/d0deef33.0379166a4ec23470.js +1 -0
  99. package/dist/app/_next/static/chunks/fd9d1056-54169f07cd680d6c.js +1 -0
  100. package/dist/app/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
  101. package/dist/app/_next/static/chunks/main-324e91f5a430cddf.js +1 -0
  102. package/dist/app/_next/static/chunks/main-app-55bcae20c77aaf0e.js +1 -0
  103. package/dist/app/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
  104. package/dist/app/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
  105. package/dist/app/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  106. package/dist/app/_next/static/chunks/webpack-2c306566f7ee1b63.js +1 -0
  107. package/dist/app/_next/static/css/6c4002bae4e236b2.css +3 -0
  108. package/dist/app/_next/static/css/a275cc2b185e04f8.css +1 -0
  109. package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_buildManifest.js +1 -0
  110. package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_ssgManifest.js +1 -0
  111. package/dist/app/activity-log/all-activity/index.html +1 -0
  112. package/dist/app/activity-log/all-activity/index.txt +14 -0
  113. package/dist/app/activity-log/email-log/index.html +1 -0
  114. package/dist/app/activity-log/email-log/index.txt +14 -0
  115. package/dist/app/activity-log/index.html +1 -0
  116. package/dist/app/activity-log/index.txt +14 -0
  117. package/dist/app/activity-log/notifications/index.html +1 -0
  118. package/dist/app/activity-log/notifications/index.txt +14 -0
  119. package/dist/app/activity-log/sessions/index.html +1 -0
  120. package/dist/app/activity-log/sessions/index.txt +14 -0
  121. package/dist/app/activity-log/workflow-executions/index.html +1 -0
  122. package/dist/app/activity-log/workflow-executions/index.txt +14 -0
  123. package/dist/app/activity-log/workflow-logs/index.html +1 -0
  124. package/dist/app/activity-log/workflow-logs/index.txt +14 -0
  125. package/dist/app/change-password/index.html +1 -0
  126. package/dist/app/change-password/index.txt +14 -0
  127. package/dist/app/dashboard/index.html +1 -0
  128. package/dist/app/dashboard/index.txt +14 -0
  129. package/dist/app/data-browser/index.html +1 -0
  130. package/dist/app/data-browser/index.txt +14 -0
  131. package/dist/app/file-manager/index.html +1 -0
  132. package/dist/app/file-manager/index.txt +14 -0
  133. package/dist/app/forgot-password/index.html +1 -0
  134. package/dist/app/forgot-password/index.txt +13 -0
  135. package/dist/app/index.html +1 -0
  136. package/dist/app/index.txt +9 -0
  137. package/dist/app/login/index.html +1 -0
  138. package/dist/app/login/index.txt +13 -0
  139. package/dist/app/logo-dark.png +0 -0
  140. package/dist/app/logo-icon.svg +81 -0
  141. package/dist/app/logo-light.png +0 -0
  142. package/dist/app/register/index.html +1 -0
  143. package/dist/app/register/index.txt +13 -0
  144. package/dist/app/settings/migrations/index.html +1 -0
  145. package/dist/app/settings/migrations/index.txt +14 -0
  146. package/dist/app/settings/permissions/index.html +1 -0
  147. package/dist/app/settings/permissions/index.txt +14 -0
  148. package/dist/app/settings/project/index.html +1 -0
  149. package/dist/app/settings/project/index.txt +14 -0
  150. package/dist/app/settings/roles/index.html +1 -0
  151. package/dist/app/settings/roles/index.txt +14 -0
  152. package/dist/app/settings/schema/index.html +1 -0
  153. package/dist/app/settings/schema/index.txt +14 -0
  154. package/dist/app/settings/tasks/index.html +1 -0
  155. package/dist/app/settings/tasks/index.txt +14 -0
  156. package/dist/app/settings/templates/edit/index.html +1 -0
  157. package/dist/app/settings/templates/edit/index.txt +14 -0
  158. package/dist/app/settings/templates/index.html +1 -0
  159. package/dist/app/settings/templates/index.txt +14 -0
  160. package/dist/app/settings/tenants/index.html +1 -0
  161. package/dist/app/settings/tenants/index.txt +14 -0
  162. package/dist/app/users/index.html +1 -0
  163. package/dist/app/users/index.txt +14 -0
  164. package/dist/app/users/invites/index.html +1 -0
  165. package/dist/app/users/invites/index.txt +14 -0
  166. package/dist/app/users/list/index.html +1 -0
  167. package/dist/app/users/list/index.txt +14 -0
  168. package/dist/app/users/preferences/index.html +1 -0
  169. package/dist/app/users/preferences/index.txt +14 -0
  170. package/dist/app/users/user-roles/index.html +1 -0
  171. package/dist/app/users/user-roles/index.txt +14 -0
  172. package/dist/app/workflows/detail/index.html +1 -0
  173. package/dist/app/workflows/detail/index.txt +14 -0
  174. package/dist/app/workflows/edit/index.html +1 -0
  175. package/dist/app/workflows/edit/index.txt +14 -0
  176. package/dist/app/workflows/execution/index.html +1 -0
  177. package/dist/app/workflows/execution/index.txt +14 -0
  178. package/dist/app/workflows/index.html +1 -0
  179. package/dist/app/workflows/index.txt +14 -0
  180. package/dist/app.d.ts +36 -0
  181. package/dist/app.d.ts.map +1 -0
  182. package/dist/app.js +546 -0
  183. package/dist/app.js.map +1 -0
  184. package/dist/auth/adapters/baasix-adapter.d.ts +12 -0
  185. package/dist/auth/adapters/baasix-adapter.d.ts.map +1 -0
  186. package/dist/auth/adapters/baasix-adapter.js +318 -0
  187. package/dist/auth/adapters/baasix-adapter.js.map +1 -0
  188. package/dist/auth/adapters/index.d.ts +6 -0
  189. package/dist/auth/adapters/index.d.ts.map +1 -0
  190. package/dist/auth/adapters/index.js +5 -0
  191. package/dist/auth/adapters/index.js.map +1 -0
  192. package/dist/auth/core.d.ts +73 -0
  193. package/dist/auth/core.d.ts.map +1 -0
  194. package/dist/auth/core.js +528 -0
  195. package/dist/auth/core.js.map +1 -0
  196. package/dist/auth/index.d.ts +56 -0
  197. package/dist/auth/index.d.ts.map +1 -0
  198. package/dist/auth/index.js +58 -0
  199. package/dist/auth/index.js.map +1 -0
  200. package/dist/auth/oauth2/index.d.ts +5 -0
  201. package/dist/auth/oauth2/index.d.ts.map +1 -0
  202. package/dist/auth/oauth2/index.js +5 -0
  203. package/dist/auth/oauth2/index.js.map +1 -0
  204. package/dist/auth/oauth2/utils.d.ts +90 -0
  205. package/dist/auth/oauth2/utils.d.ts.map +1 -0
  206. package/dist/auth/oauth2/utils.js +167 -0
  207. package/dist/auth/oauth2/utils.js.map +1 -0
  208. package/dist/auth/providers/apple.d.ts +28 -0
  209. package/dist/auth/providers/apple.d.ts.map +1 -0
  210. package/dist/auth/providers/apple.js +192 -0
  211. package/dist/auth/providers/apple.js.map +1 -0
  212. package/dist/auth/providers/credential.d.ts +87 -0
  213. package/dist/auth/providers/credential.d.ts.map +1 -0
  214. package/dist/auth/providers/credential.js +162 -0
  215. package/dist/auth/providers/credential.js.map +1 -0
  216. package/dist/auth/providers/facebook.d.ts +26 -0
  217. package/dist/auth/providers/facebook.d.ts.map +1 -0
  218. package/dist/auth/providers/facebook.js +112 -0
  219. package/dist/auth/providers/facebook.js.map +1 -0
  220. package/dist/auth/providers/github.d.ts +29 -0
  221. package/dist/auth/providers/github.d.ts.map +1 -0
  222. package/dist/auth/providers/github.js +144 -0
  223. package/dist/auth/providers/github.js.map +1 -0
  224. package/dist/auth/providers/google.d.ts +32 -0
  225. package/dist/auth/providers/google.d.ts.map +1 -0
  226. package/dist/auth/providers/google.js +145 -0
  227. package/dist/auth/providers/google.js.map +1 -0
  228. package/dist/auth/providers/index.d.ts +22 -0
  229. package/dist/auth/providers/index.d.ts.map +1 -0
  230. package/dist/auth/providers/index.js +17 -0
  231. package/dist/auth/providers/index.js.map +1 -0
  232. package/dist/auth/routes.d.ts +63 -0
  233. package/dist/auth/routes.d.ts.map +1 -0
  234. package/dist/auth/routes.js +827 -0
  235. package/dist/auth/routes.js.map +1 -0
  236. package/dist/auth/services/index.d.ts +10 -0
  237. package/dist/auth/services/index.d.ts.map +1 -0
  238. package/dist/auth/services/index.js +7 -0
  239. package/dist/auth/services/index.js.map +1 -0
  240. package/dist/auth/services/session.d.ts +81 -0
  241. package/dist/auth/services/session.d.ts.map +1 -0
  242. package/dist/auth/services/session.js +186 -0
  243. package/dist/auth/services/session.js.map +1 -0
  244. package/dist/auth/services/token.d.ts +41 -0
  245. package/dist/auth/services/token.d.ts.map +1 -0
  246. package/dist/auth/services/token.js +44 -0
  247. package/dist/auth/services/token.js.map +1 -0
  248. package/dist/auth/services/verification.d.ts +77 -0
  249. package/dist/auth/services/verification.d.ts.map +1 -0
  250. package/dist/auth/services/verification.js +143 -0
  251. package/dist/auth/services/verification.js.map +1 -0
  252. package/dist/auth/types.d.ts +318 -0
  253. package/dist/auth/types.d.ts.map +1 -0
  254. package/dist/auth/types.js +6 -0
  255. package/dist/auth/types.js.map +1 -0
  256. package/dist/customTypes/arrays.d.ts +200 -0
  257. package/dist/customTypes/arrays.d.ts.map +1 -0
  258. package/dist/customTypes/arrays.js +309 -0
  259. package/dist/customTypes/arrays.js.map +1 -0
  260. package/dist/customTypes/index.d.ts +8 -0
  261. package/dist/customTypes/index.d.ts.map +1 -0
  262. package/dist/customTypes/index.js +11 -0
  263. package/dist/customTypes/index.js.map +1 -0
  264. package/dist/customTypes/postgis.d.ts +146 -0
  265. package/dist/customTypes/postgis.d.ts.map +1 -0
  266. package/dist/customTypes/postgis.js +315 -0
  267. package/dist/customTypes/postgis.js.map +1 -0
  268. package/dist/customTypes/ranges.d.ts +128 -0
  269. package/dist/customTypes/ranges.d.ts.map +1 -0
  270. package/dist/customTypes/ranges.js +257 -0
  271. package/dist/customTypes/ranges.js.map +1 -0
  272. package/dist/index.d.ts +37 -0
  273. package/dist/index.d.ts.map +1 -0
  274. package/dist/index.js +42 -0
  275. package/dist/index.js.map +1 -0
  276. package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts +29 -0
  277. package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts.map +1 -0
  278. package/dist/migrations/0.1.0-alpha.0_initial_setup.js +72 -0
  279. package/dist/migrations/0.1.0-alpha.0_initial_setup.js.map +1 -0
  280. package/dist/migrations/_example_migration.d.ts +31 -0
  281. package/dist/migrations/_example_migration.d.ts.map +1 -0
  282. package/dist/migrations/_example_migration.js +75 -0
  283. package/dist/migrations/_example_migration.js.map +1 -0
  284. package/dist/plugins/definePlugin.d.ts +49 -0
  285. package/dist/plugins/definePlugin.d.ts.map +1 -0
  286. package/dist/plugins/definePlugin.js +131 -0
  287. package/dist/plugins/definePlugin.js.map +1 -0
  288. package/dist/plugins/softDelete.d.ts +179 -0
  289. package/dist/plugins/softDelete.d.ts.map +1 -0
  290. package/dist/plugins/softDelete.js +235 -0
  291. package/dist/plugins/softDelete.js.map +1 -0
  292. package/dist/routes/auth.route.d.ts +14 -0
  293. package/dist/routes/auth.route.d.ts.map +1 -0
  294. package/dist/routes/auth.route.js +421 -0
  295. package/dist/routes/auth.route.js.map +1 -0
  296. package/dist/routes/file.route.d.ts +7 -0
  297. package/dist/routes/file.route.d.ts.map +1 -0
  298. package/dist/routes/file.route.js +274 -0
  299. package/dist/routes/file.route.js.map +1 -0
  300. package/dist/routes/items.route.d.ts +7 -0
  301. package/dist/routes/items.route.d.ts.map +1 -0
  302. package/dist/routes/items.route.js +369 -0
  303. package/dist/routes/items.route.js.map +1 -0
  304. package/dist/routes/migration.route.d.ts +7 -0
  305. package/dist/routes/migration.route.d.ts.map +1 -0
  306. package/dist/routes/migration.route.js +225 -0
  307. package/dist/routes/migration.route.js.map +1 -0
  308. package/dist/routes/notification.route.d.ts +7 -0
  309. package/dist/routes/notification.route.d.ts.map +1 -0
  310. package/dist/routes/notification.route.js +124 -0
  311. package/dist/routes/notification.route.js.map +1 -0
  312. package/dist/routes/openapi.route.d.ts +7 -0
  313. package/dist/routes/openapi.route.d.ts.map +1 -0
  314. package/dist/routes/openapi.route.js +2169 -0
  315. package/dist/routes/openapi.route.js.map +1 -0
  316. package/dist/routes/permission.route.d.ts +7 -0
  317. package/dist/routes/permission.route.d.ts.map +1 -0
  318. package/dist/routes/permission.route.js +158 -0
  319. package/dist/routes/permission.route.js.map +1 -0
  320. package/dist/routes/realtime.route.d.ts +21 -0
  321. package/dist/routes/realtime.route.d.ts.map +1 -0
  322. package/dist/routes/realtime.route.js +243 -0
  323. package/dist/routes/realtime.route.js.map +1 -0
  324. package/dist/routes/reports.route.d.ts +7 -0
  325. package/dist/routes/reports.route.d.ts.map +1 -0
  326. package/dist/routes/reports.route.js +95 -0
  327. package/dist/routes/reports.route.js.map +1 -0
  328. package/dist/routes/schema.route.d.ts +7 -0
  329. package/dist/routes/schema.route.d.ts.map +1 -0
  330. package/dist/routes/schema.route.js +1780 -0
  331. package/dist/routes/schema.route.js.map +1 -0
  332. package/dist/routes/settings.route.d.ts +7 -0
  333. package/dist/routes/settings.route.d.ts.map +1 -0
  334. package/dist/routes/settings.route.js +154 -0
  335. package/dist/routes/settings.route.js.map +1 -0
  336. package/dist/routes/templates.route.d.ts +7 -0
  337. package/dist/routes/templates.route.d.ts.map +1 -0
  338. package/dist/routes/templates.route.js +91 -0
  339. package/dist/routes/templates.route.js.map +1 -0
  340. package/dist/routes/utils.route.d.ts +7 -0
  341. package/dist/routes/utils.route.d.ts.map +1 -0
  342. package/dist/routes/utils.route.js +33 -0
  343. package/dist/routes/utils.route.js.map +1 -0
  344. package/dist/routes/workflow.route.d.ts +7 -0
  345. package/dist/routes/workflow.route.d.ts.map +1 -0
  346. package/dist/routes/workflow.route.js +787 -0
  347. package/dist/routes/workflow.route.js.map +1 -0
  348. package/dist/services/AssetsService.d.ts +39 -0
  349. package/dist/services/AssetsService.d.ts.map +1 -0
  350. package/dist/services/AssetsService.js +255 -0
  351. package/dist/services/AssetsService.js.map +1 -0
  352. package/dist/services/CacheService.d.ts +169 -0
  353. package/dist/services/CacheService.d.ts.map +1 -0
  354. package/dist/services/CacheService.js +722 -0
  355. package/dist/services/CacheService.js.map +1 -0
  356. package/dist/services/FilesService.d.ts +30 -0
  357. package/dist/services/FilesService.d.ts.map +1 -0
  358. package/dist/services/FilesService.js +268 -0
  359. package/dist/services/FilesService.js.map +1 -0
  360. package/dist/services/HooksManager.d.ts +38 -0
  361. package/dist/services/HooksManager.d.ts.map +1 -0
  362. package/dist/services/HooksManager.js +165 -0
  363. package/dist/services/HooksManager.js.map +1 -0
  364. package/dist/services/ItemsService.d.ts +273 -0
  365. package/dist/services/ItemsService.d.ts.map +1 -0
  366. package/dist/services/ItemsService.js +2458 -0
  367. package/dist/services/ItemsService.js.map +1 -0
  368. package/dist/services/MailService.d.ts +76 -0
  369. package/dist/services/MailService.d.ts.map +1 -0
  370. package/dist/services/MailService.js +585 -0
  371. package/dist/services/MailService.js.map +1 -0
  372. package/dist/services/MigrationService.d.ts +243 -0
  373. package/dist/services/MigrationService.d.ts.map +1 -0
  374. package/dist/services/MigrationService.js +914 -0
  375. package/dist/services/MigrationService.js.map +1 -0
  376. package/dist/services/NotificationService.d.ts +35 -0
  377. package/dist/services/NotificationService.d.ts.map +1 -0
  378. package/dist/services/NotificationService.js +159 -0
  379. package/dist/services/NotificationService.js.map +1 -0
  380. package/dist/services/PermissionService.d.ts +128 -0
  381. package/dist/services/PermissionService.d.ts.map +1 -0
  382. package/dist/services/PermissionService.js +373 -0
  383. package/dist/services/PermissionService.js.map +1 -0
  384. package/dist/services/PluginManager.d.ts +138 -0
  385. package/dist/services/PluginManager.d.ts.map +1 -0
  386. package/dist/services/PluginManager.js +463 -0
  387. package/dist/services/PluginManager.js.map +1 -0
  388. package/dist/services/RealtimeService.d.ts +209 -0
  389. package/dist/services/RealtimeService.d.ts.map +1 -0
  390. package/dist/services/RealtimeService.js +978 -0
  391. package/dist/services/RealtimeService.js.map +1 -0
  392. package/dist/services/ReportService.d.ts +13 -0
  393. package/dist/services/ReportService.d.ts.map +1 -0
  394. package/dist/services/ReportService.js +91 -0
  395. package/dist/services/ReportService.js.map +1 -0
  396. package/dist/services/SettingsService.d.ts +60 -0
  397. package/dist/services/SettingsService.d.ts.map +1 -0
  398. package/dist/services/SettingsService.js +474 -0
  399. package/dist/services/SettingsService.js.map +1 -0
  400. package/dist/services/SocketService.d.ts +129 -0
  401. package/dist/services/SocketService.d.ts.map +1 -0
  402. package/dist/services/SocketService.js +600 -0
  403. package/dist/services/SocketService.js.map +1 -0
  404. package/dist/services/StatsService.d.ts +10 -0
  405. package/dist/services/StatsService.d.ts.map +1 -0
  406. package/dist/services/StatsService.js +40 -0
  407. package/dist/services/StatsService.js.map +1 -0
  408. package/dist/services/StorageService.d.ts +20 -0
  409. package/dist/services/StorageService.d.ts.map +1 -0
  410. package/dist/services/StorageService.js +164 -0
  411. package/dist/services/StorageService.js.map +1 -0
  412. package/dist/services/TasksService.d.ts +74 -0
  413. package/dist/services/TasksService.d.ts.map +1 -0
  414. package/dist/services/TasksService.js +404 -0
  415. package/dist/services/TasksService.js.map +1 -0
  416. package/dist/services/WorkflowService.d.ts +305 -0
  417. package/dist/services/WorkflowService.d.ts.map +1 -0
  418. package/dist/services/WorkflowService.js +1811 -0
  419. package/dist/services/WorkflowService.js.map +1 -0
  420. package/dist/templates/logo/logo.png +0 -0
  421. package/dist/templates/mails/default.liquid +23 -0
  422. package/dist/types/aggregation.d.ts +40 -0
  423. package/dist/types/aggregation.d.ts.map +1 -0
  424. package/dist/types/aggregation.js +6 -0
  425. package/dist/types/aggregation.js.map +1 -0
  426. package/dist/types/assets.d.ts +32 -0
  427. package/dist/types/assets.d.ts.map +1 -0
  428. package/dist/types/assets.js +6 -0
  429. package/dist/types/assets.js.map +1 -0
  430. package/dist/types/auth.d.ts +50 -0
  431. package/dist/types/auth.d.ts.map +1 -0
  432. package/dist/types/auth.js +6 -0
  433. package/dist/types/auth.js.map +1 -0
  434. package/dist/types/cache.d.ts +47 -0
  435. package/dist/types/cache.d.ts.map +1 -0
  436. package/dist/types/cache.js +6 -0
  437. package/dist/types/cache.js.map +1 -0
  438. package/dist/types/database.d.ts +16 -0
  439. package/dist/types/database.d.ts.map +1 -0
  440. package/dist/types/database.js +6 -0
  441. package/dist/types/database.js.map +1 -0
  442. package/dist/types/fields.d.ts +71 -0
  443. package/dist/types/fields.d.ts.map +1 -0
  444. package/dist/types/fields.js +6 -0
  445. package/dist/types/fields.js.map +1 -0
  446. package/dist/types/files.d.ts +33 -0
  447. package/dist/types/files.d.ts.map +1 -0
  448. package/dist/types/files.js +6 -0
  449. package/dist/types/files.js.map +1 -0
  450. package/dist/types/hooks.d.ts +29 -0
  451. package/dist/types/hooks.d.ts.map +1 -0
  452. package/dist/types/hooks.js +6 -0
  453. package/dist/types/hooks.js.map +1 -0
  454. package/dist/types/import-export.d.ts +62 -0
  455. package/dist/types/import-export.d.ts.map +1 -0
  456. package/dist/types/import-export.js +6 -0
  457. package/dist/types/import-export.js.map +1 -0
  458. package/dist/types/index.d.ts +31 -0
  459. package/dist/types/index.d.ts.map +1 -0
  460. package/dist/types/index.js +58 -0
  461. package/dist/types/index.js.map +1 -0
  462. package/dist/types/mail.d.ts +34 -0
  463. package/dist/types/mail.d.ts.map +1 -0
  464. package/dist/types/mail.js +6 -0
  465. package/dist/types/mail.js.map +1 -0
  466. package/dist/types/notifications.d.ts +16 -0
  467. package/dist/types/notifications.d.ts.map +1 -0
  468. package/dist/types/notifications.js +6 -0
  469. package/dist/types/notifications.js.map +1 -0
  470. package/dist/types/plugin.d.ts +351 -0
  471. package/dist/types/plugin.d.ts.map +1 -0
  472. package/dist/types/plugin.js +8 -0
  473. package/dist/types/plugin.js.map +1 -0
  474. package/dist/types/query.d.ts +71 -0
  475. package/dist/types/query.d.ts.map +1 -0
  476. package/dist/types/query.js +6 -0
  477. package/dist/types/query.js.map +1 -0
  478. package/dist/types/relations.d.ts +111 -0
  479. package/dist/types/relations.d.ts.map +1 -0
  480. package/dist/types/relations.js +6 -0
  481. package/dist/types/relations.js.map +1 -0
  482. package/dist/types/reports.d.ts +17 -0
  483. package/dist/types/reports.d.ts.map +1 -0
  484. package/dist/types/reports.js +6 -0
  485. package/dist/types/reports.js.map +1 -0
  486. package/dist/types/schema.d.ts +26 -0
  487. package/dist/types/schema.d.ts.map +1 -0
  488. package/dist/types/schema.js +6 -0
  489. package/dist/types/schema.js.map +1 -0
  490. package/dist/types/seed.d.ts +27 -0
  491. package/dist/types/seed.d.ts.map +1 -0
  492. package/dist/types/seed.js +6 -0
  493. package/dist/types/seed.js.map +1 -0
  494. package/dist/types/services.d.ts +68 -0
  495. package/dist/types/services.d.ts.map +1 -0
  496. package/dist/types/services.js +6 -0
  497. package/dist/types/services.js.map +1 -0
  498. package/dist/types/settings.d.ts +36 -0
  499. package/dist/types/settings.d.ts.map +1 -0
  500. package/dist/types/settings.js +6 -0
  501. package/dist/types/settings.js.map +1 -0
  502. package/dist/types/sockets.d.ts +26 -0
  503. package/dist/types/sockets.d.ts.map +1 -0
  504. package/dist/types/sockets.js +6 -0
  505. package/dist/types/sockets.js.map +1 -0
  506. package/dist/types/sort.d.ts +25 -0
  507. package/dist/types/sort.d.ts.map +1 -0
  508. package/dist/types/sort.js +6 -0
  509. package/dist/types/sort.js.map +1 -0
  510. package/dist/types/spatial.d.ts +19 -0
  511. package/dist/types/spatial.d.ts.map +1 -0
  512. package/dist/types/spatial.js +6 -0
  513. package/dist/types/spatial.js.map +1 -0
  514. package/dist/types/stats.d.ts +21 -0
  515. package/dist/types/stats.d.ts.map +1 -0
  516. package/dist/types/stats.js +6 -0
  517. package/dist/types/stats.js.map +1 -0
  518. package/dist/types/storage.d.ts +19 -0
  519. package/dist/types/storage.d.ts.map +1 -0
  520. package/dist/types/storage.js +6 -0
  521. package/dist/types/storage.js.map +1 -0
  522. package/dist/types/tasks.d.ts +14 -0
  523. package/dist/types/tasks.d.ts.map +1 -0
  524. package/dist/types/tasks.js +6 -0
  525. package/dist/types/tasks.js.map +1 -0
  526. package/dist/types/utils.d.ts +54 -0
  527. package/dist/types/utils.d.ts.map +1 -0
  528. package/dist/types/utils.js +6 -0
  529. package/dist/types/utils.js.map +1 -0
  530. package/dist/types/workflow.d.ts +17 -0
  531. package/dist/types/workflow.d.ts.map +1 -0
  532. package/dist/types/workflow.js +6 -0
  533. package/dist/types/workflow.js.map +1 -0
  534. package/dist/utils/aggregationUtils.d.ts +192 -0
  535. package/dist/utils/aggregationUtils.d.ts.map +1 -0
  536. package/dist/utils/aggregationUtils.js +450 -0
  537. package/dist/utils/aggregationUtils.js.map +1 -0
  538. package/dist/utils/auth.d.ts +93 -0
  539. package/dist/utils/auth.d.ts.map +1 -0
  540. package/dist/utils/auth.js +557 -0
  541. package/dist/utils/auth.js.map +1 -0
  542. package/dist/utils/cache.d.ts +64 -0
  543. package/dist/utils/cache.d.ts.map +1 -0
  544. package/dist/utils/cache.js +464 -0
  545. package/dist/utils/cache.js.map +1 -0
  546. package/dist/utils/common.d.ts +53 -0
  547. package/dist/utils/common.d.ts.map +1 -0
  548. package/dist/utils/common.js +162 -0
  549. package/dist/utils/common.js.map +1 -0
  550. package/dist/utils/db.d.ts +101 -0
  551. package/dist/utils/db.d.ts.map +1 -0
  552. package/dist/utils/db.js +413 -0
  553. package/dist/utils/db.js.map +1 -0
  554. package/dist/utils/dirname.d.ts +30 -0
  555. package/dist/utils/dirname.d.ts.map +1 -0
  556. package/dist/utils/dirname.js +95 -0
  557. package/dist/utils/dirname.js.map +1 -0
  558. package/dist/utils/dynamicVariableResolver.d.ts +17 -0
  559. package/dist/utils/dynamicVariableResolver.d.ts.map +1 -0
  560. package/dist/utils/dynamicVariableResolver.js +262 -0
  561. package/dist/utils/dynamicVariableResolver.js.map +1 -0
  562. package/dist/utils/env.d.ts +38 -0
  563. package/dist/utils/env.d.ts.map +1 -0
  564. package/dist/utils/env.js +80 -0
  565. package/dist/utils/env.js.map +1 -0
  566. package/dist/utils/errorHandler.d.ts +14 -0
  567. package/dist/utils/errorHandler.d.ts.map +1 -0
  568. package/dist/utils/errorHandler.js +79 -0
  569. package/dist/utils/errorHandler.js.map +1 -0
  570. package/dist/utils/fieldExpansion.d.ts +30 -0
  571. package/dist/utils/fieldExpansion.d.ts.map +1 -0
  572. package/dist/utils/fieldExpansion.js +145 -0
  573. package/dist/utils/fieldExpansion.js.map +1 -0
  574. package/dist/utils/fieldUtils.d.ts +179 -0
  575. package/dist/utils/fieldUtils.d.ts.map +1 -0
  576. package/dist/utils/fieldUtils.js +424 -0
  577. package/dist/utils/fieldUtils.js.map +1 -0
  578. package/dist/utils/filterOperators.d.ts +472 -0
  579. package/dist/utils/filterOperators.d.ts.map +1 -0
  580. package/dist/utils/filterOperators.js +1229 -0
  581. package/dist/utils/filterOperators.js.map +1 -0
  582. package/dist/utils/importUtils.d.ts +127 -0
  583. package/dist/utils/importUtils.d.ts.map +1 -0
  584. package/dist/utils/importUtils.js +437 -0
  585. package/dist/utils/importUtils.js.map +1 -0
  586. package/dist/utils/index.d.ts +75 -0
  587. package/dist/utils/index.d.ts.map +1 -0
  588. package/dist/utils/index.js +101 -0
  589. package/dist/utils/index.js.map +1 -0
  590. package/dist/utils/logger.d.ts +41 -0
  591. package/dist/utils/logger.d.ts.map +1 -0
  592. package/dist/utils/logger.js +217 -0
  593. package/dist/utils/logger.js.map +1 -0
  594. package/dist/utils/orderUtils.d.ts +117 -0
  595. package/dist/utils/orderUtils.d.ts.map +1 -0
  596. package/dist/utils/orderUtils.js +249 -0
  597. package/dist/utils/orderUtils.js.map +1 -0
  598. package/dist/utils/queryBuilder.d.ts +118 -0
  599. package/dist/utils/queryBuilder.d.ts.map +1 -0
  600. package/dist/utils/queryBuilder.js +489 -0
  601. package/dist/utils/queryBuilder.js.map +1 -0
  602. package/dist/utils/relationLoader.d.ts +65 -0
  603. package/dist/utils/relationLoader.d.ts.map +1 -0
  604. package/dist/utils/relationLoader.js +1081 -0
  605. package/dist/utils/relationLoader.js.map +1 -0
  606. package/dist/utils/relationPathResolver.d.ts +30 -0
  607. package/dist/utils/relationPathResolver.d.ts.map +1 -0
  608. package/dist/utils/relationPathResolver.js +173 -0
  609. package/dist/utils/relationPathResolver.js.map +1 -0
  610. package/dist/utils/relationUtils.d.ts +139 -0
  611. package/dist/utils/relationUtils.d.ts.map +1 -0
  612. package/dist/utils/relationUtils.js +711 -0
  613. package/dist/utils/relationUtils.js.map +1 -0
  614. package/dist/utils/router.d.ts +6 -0
  615. package/dist/utils/router.d.ts.map +1 -0
  616. package/dist/utils/router.js +95 -0
  617. package/dist/utils/router.js.map +1 -0
  618. package/dist/utils/schema.d.ts +88 -0
  619. package/dist/utils/schema.d.ts.map +1 -0
  620. package/dist/utils/schema.js +24 -0
  621. package/dist/utils/schema.js.map +1 -0
  622. package/dist/utils/schemaManager.d.ts +238 -0
  623. package/dist/utils/schemaManager.d.ts.map +1 -0
  624. package/dist/utils/schemaManager.js +1992 -0
  625. package/dist/utils/schemaManager.js.map +1 -0
  626. package/dist/utils/schemaValidator.d.ts +83 -0
  627. package/dist/utils/schemaValidator.d.ts.map +1 -0
  628. package/dist/utils/schemaValidator.js +491 -0
  629. package/dist/utils/schemaValidator.js.map +1 -0
  630. package/dist/utils/seed.d.ts +45 -0
  631. package/dist/utils/seed.d.ts.map +1 -0
  632. package/dist/utils/seed.js +248 -0
  633. package/dist/utils/seed.js.map +1 -0
  634. package/dist/utils/sessionCleanup.d.ts +10 -0
  635. package/dist/utils/sessionCleanup.d.ts.map +1 -0
  636. package/dist/utils/sessionCleanup.js +49 -0
  637. package/dist/utils/sessionCleanup.js.map +1 -0
  638. package/dist/utils/sortUtils.d.ts +117 -0
  639. package/dist/utils/sortUtils.d.ts.map +1 -0
  640. package/dist/utils/sortUtils.js +232 -0
  641. package/dist/utils/sortUtils.js.map +1 -0
  642. package/dist/utils/spatialUtils.d.ts +244 -0
  643. package/dist/utils/spatialUtils.d.ts.map +1 -0
  644. package/dist/utils/spatialUtils.js +359 -0
  645. package/dist/utils/spatialUtils.js.map +1 -0
  646. package/dist/utils/systemschema.d.ts +11040 -0
  647. package/dist/utils/systemschema.d.ts.map +1 -0
  648. package/dist/utils/systemschema.js +1777 -0
  649. package/dist/utils/systemschema.js.map +1 -0
  650. package/dist/utils/tenantUtils.d.ts +34 -0
  651. package/dist/utils/tenantUtils.d.ts.map +1 -0
  652. package/dist/utils/tenantUtils.js +124 -0
  653. package/dist/utils/tenantUtils.js.map +1 -0
  654. package/dist/utils/typeMapper.d.ts +25 -0
  655. package/dist/utils/typeMapper.d.ts.map +1 -0
  656. package/dist/utils/typeMapper.js +282 -0
  657. package/dist/utils/typeMapper.js.map +1 -0
  658. package/dist/utils/valueValidator.d.ts +60 -0
  659. package/dist/utils/valueValidator.d.ts.map +1 -0
  660. package/dist/utils/valueValidator.js +303 -0
  661. package/dist/utils/valueValidator.js.map +1 -0
  662. package/dist/utils/workflow.d.ts +87 -0
  663. package/dist/utils/workflow.d.ts.map +1 -0
  664. package/dist/utils/workflow.js +205 -0
  665. package/dist/utils/workflow.js.map +1 -0
  666. package/package.json +115 -0
@@ -0,0 +1,711 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { getDatabase } from './db.js';
3
+ /**
4
+ * Relation builder for dynamic schemas
5
+ */
6
+ export class RelationBuilder {
7
+ relationsMap = new Map();
8
+ /**
9
+ * Store association definitions for a table
10
+ * Relations will be resolved at query time using Drizzle's query API
11
+ * Note: This merges with existing associations instead of replacing them
12
+ */
13
+ storeAssociations(tableName, associations) {
14
+ console.log(`[RelationBuilder] Storing associations for ${tableName}:`, Object.keys(associations));
15
+ // Get existing associations for this table
16
+ const existing = this.relationsMap.get(tableName) || {};
17
+ // Merge new associations with existing ones
18
+ const merged = { ...existing, ...associations };
19
+ console.log(`[RelationBuilder] After merge, ${tableName} has:`, Object.keys(merged));
20
+ this.relationsMap.set(tableName, merged);
21
+ }
22
+ /**
23
+ * Get associations for a table
24
+ */
25
+ getAssociations(tableName) {
26
+ const assocs = this.relationsMap.get(tableName);
27
+ console.log(`[RelationBuilder] Retrieved associations for ${tableName}:`, assocs ? Object.keys(assocs) : 'none');
28
+ return assocs;
29
+ }
30
+ /**
31
+ * Get all associations
32
+ */
33
+ getAllAssociations() {
34
+ return this.relationsMap;
35
+ }
36
+ /**
37
+ * Get foreign key column name for a relation
38
+ */
39
+ getForeignKey(assoc, defaultKey) {
40
+ return assoc.foreignKey || defaultKey || `${assoc.model.toLowerCase()}Id`;
41
+ }
42
+ /**
43
+ * Check if an association is a one-to-many type
44
+ */
45
+ isOneToMany(assoc) {
46
+ return assoc.type === 'HasMany';
47
+ }
48
+ /**
49
+ * Check if an association is a many-to-one type
50
+ */
51
+ isManyToOne(assoc) {
52
+ return assoc.type === 'BelongsTo';
53
+ }
54
+ /**
55
+ * Check if an association is a many-to-many type
56
+ */
57
+ isManyToMany(assoc) {
58
+ return assoc.type === 'BelongsToMany';
59
+ }
60
+ }
61
+ /**
62
+ * Singleton instance
63
+ */
64
+ export const relationBuilder = new RelationBuilder();
65
+ /**
66
+ * Helper to create foreign key constraint SQL
67
+ */
68
+ export function createForeignKeySQL(tableName, columnName, referencedTable, referencedColumn = 'id', onDelete = 'CASCADE', onUpdate = 'CASCADE') {
69
+ const constraintName = `fk_${tableName}_${columnName}`;
70
+ return `
71
+ ALTER TABLE "${tableName}"
72
+ ADD CONSTRAINT "${constraintName}"
73
+ FOREIGN KEY ("${columnName}")
74
+ REFERENCES "${referencedTable}"("${referencedColumn}")
75
+ ON DELETE ${onDelete}
76
+ ON UPDATE ${onUpdate}
77
+ `.trim();
78
+ }
79
+ /**
80
+ * Helper to check if a field is a polymorphic relation
81
+ */
82
+ export function isPolymorphicRelation(assoc) {
83
+ return assoc.type === 'M2A' || assoc.polymorphic === true;
84
+ }
85
+ /**
86
+ * Helper to get polymorphic field names
87
+ */
88
+ export function getPolymorphicFields(relationName) {
89
+ return {
90
+ typeField: `${relationName}Type`,
91
+ idField: `${relationName}Id`,
92
+ };
93
+ }
94
+ /**
95
+ * Build junction table for many-to-many relations
96
+ * Example: UserRoles for User <-> Role
97
+ */
98
+ export function buildJunctionTable(table1Name, table2Name, table1Key = 'id', table2Key = 'id') {
99
+ const junctionName = `${table1Name}${table2Name}`;
100
+ const fk1 = `${table1Name}${table1Key.charAt(0).toUpperCase()}${table1Key.slice(1)}`;
101
+ const fk2 = `${table2Name}${table2Key.charAt(0).toUpperCase()}${table2Key.slice(1)}`;
102
+ return `
103
+ CREATE TABLE IF NOT EXISTS "${junctionName}" (
104
+ "${fk1}" UUID NOT NULL,
105
+ "${fk2}" UUID NOT NULL,
106
+ "createdAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
107
+ "updatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
108
+ PRIMARY KEY ("${fk1}", "${fk2}"),
109
+ FOREIGN KEY ("${fk1}") REFERENCES "${table1Name}"("${table1Key}") ON DELETE CASCADE,
110
+ FOREIGN KEY ("${fk2}") REFERENCES "${table2Name}"("${table2Key}") ON DELETE CASCADE
111
+ )
112
+ `.trim();
113
+ }
114
+ /**
115
+ * Convert Sequelize association type to Drizzle relation type
116
+ */
117
+ export function sequelizeTosDrizzleRelationType(sequelizeType) {
118
+ switch (sequelizeType) {
119
+ case 'HasMany':
120
+ case 'BelongsToMany':
121
+ return 'many';
122
+ case 'HasOne':
123
+ case 'BelongsTo':
124
+ return 'one';
125
+ default:
126
+ return null;
127
+ }
128
+ }
129
+ // ============================================================================
130
+ // Relational Data Processing
131
+ // ============================================================================
132
+ /**
133
+ * Process relational data - extract nested objects/arrays
134
+ * @param collection - Collection name
135
+ * @param data - Data to process
136
+ * @param service - Service instance
137
+ * @param ItemsServiceClass - ItemsService class for creating related service instances
138
+ */
139
+ export async function processRelationalData(collection, data, service, ItemsServiceClass) {
140
+ console.log(`[RelationUtils] Processing relational data for ${collection}`);
141
+ const result = {};
142
+ const deferredHasMany = [];
143
+ const deferredM2M = [];
144
+ const deferredM2A = [];
145
+ // Get relation metadata for this collection
146
+ const associations = relationBuilder.getAssociations(collection);
147
+ console.log(`[RelationUtils] Associations for ${collection}:`, associations ? Object.keys(associations) : 'none');
148
+ if (!associations) {
149
+ // No relations defined, return data as-is
150
+ console.log(`[RelationUtils] No associations found for ${collection}, returning data as-is`);
151
+ return {
152
+ result: { ...data },
153
+ deferredHasMany,
154
+ deferredM2M,
155
+ deferredM2A
156
+ };
157
+ }
158
+ // Process BelongsTo relationships first - they need to be created/resolved before main record
159
+ for (const [key, value] of Object.entries(data)) {
160
+ const association = associations[key];
161
+ if (!association || value == null) {
162
+ // Not a relation or value is null - include in result
163
+ result[key] = value;
164
+ continue;
165
+ }
166
+ if (association.type === 'BelongsTo') {
167
+ console.log(`[RelationUtils] Processing BelongsTo relation: ${key}`);
168
+ // Use passed ItemsService class to create related service
169
+ const relatedService = new ItemsServiceClass(association.model, {
170
+ accountability: service.accountability,
171
+ tenant: service.tenant
172
+ });
173
+ const foreignKey = association.foreignKey || `${key}_Id`;
174
+ if (typeof value === 'object' && !value.id) {
175
+ // Create new related record
176
+ console.log(`[RelationUtils] Creating new ${association.model} for ${key}`);
177
+ const newRelatedId = await relatedService.createOne(value, { bypassPermissions: true });
178
+ console.log(`[RelationUtils] Created ${association.model} with ID:`, newRelatedId);
179
+ console.log(`[RelationUtils] Setting ${foreignKey} =`, newRelatedId);
180
+ result[foreignKey] = newRelatedId;
181
+ }
182
+ else if (typeof value === 'object' && value.id) {
183
+ // Reference existing record (optionally update it)
184
+ console.log(`[RelationUtils] Using existing ${association.model} ${value.id} for ${key}`);
185
+ // If there are other fields besides id, update the related record
186
+ const updateFields = { ...value };
187
+ delete updateFields.id;
188
+ if (Object.keys(updateFields).length > 0) {
189
+ await relatedService.updateOne(value.id, updateFields, { bypassPermissions: true });
190
+ }
191
+ result[foreignKey] = value.id;
192
+ }
193
+ else {
194
+ // Use existing record ID directly
195
+ result[foreignKey] = value;
196
+ }
197
+ // Don't include the relation name in result (we stored the foreignKey instead)
198
+ // delete result[key]; - already not added
199
+ }
200
+ else {
201
+ // Not a BelongsTo - include in result for now, process later
202
+ result[key] = value;
203
+ }
204
+ }
205
+ // Process HasMany, BelongsToMany, and M2A relationships - these are deferred
206
+ for (const [key, value] of Object.entries(data)) {
207
+ const association = associations[key];
208
+ if (!association || value == null)
209
+ continue;
210
+ // Check for M2A (polymorphic) relations first
211
+ // M2A is stored as HasMany with polymorphic: true
212
+ if (isPolymorphicRelation(association)) {
213
+ if (Array.isArray(value)) {
214
+ console.log(`[RelationUtils] Deferring M2A relation: ${key}`);
215
+ deferredM2A.push({ association: key, associationInfo: association, value });
216
+ }
217
+ // Remove from result
218
+ delete result[key];
219
+ }
220
+ else if (association.type === 'HasMany') {
221
+ if (Array.isArray(value)) {
222
+ console.log(`[RelationUtils] Deferring HasMany relation: ${key}`);
223
+ deferredHasMany.push({ association: key, associationInfo: association, value });
224
+ }
225
+ // Remove from result
226
+ delete result[key];
227
+ }
228
+ else if (association.type === 'BelongsToMany') {
229
+ if (Array.isArray(value)) {
230
+ console.log(`[RelationUtils] Deferring BelongsToMany relation: ${key}`);
231
+ deferredM2M.push({ association: key, associationInfo: association, value });
232
+ }
233
+ // Remove from result
234
+ delete result[key];
235
+ }
236
+ }
237
+ console.log(`[RelationUtils] Processed relational data:`, {
238
+ resultKeys: Object.keys(result),
239
+ deferredHasManyCount: deferredHasMany.length,
240
+ deferredM2MCount: deferredM2M.length,
241
+ deferredM2ACount: deferredM2A.length
242
+ });
243
+ return {
244
+ result,
245
+ deferredHasMany,
246
+ deferredM2M,
247
+ deferredM2A
248
+ };
249
+ }
250
+ /**
251
+ * Handle HasMany relationship after main record is created
252
+ *
253
+ * @param item - The created/updated main record with its ID
254
+ * @param association - Name of the association
255
+ * @param associationInfo - Metadata about the association
256
+ * @param value - Array of related items to create/update
257
+ * @param service - The service instance
258
+ * @param ItemsServiceClass - ItemsService class for creating related service instances
259
+ * @param transaction - Optional transaction
260
+ */
261
+ export async function handleHasManyRelationship(item, association, associationInfo, value, service, ItemsServiceClass, transaction) {
262
+ console.log(`[RelationUtils] Handling HasMany relationship: ${association}`);
263
+ if (!Array.isArray(value)) {
264
+ console.warn(`[RelationUtils] HasMany value is not an array for ${association}`);
265
+ return;
266
+ }
267
+ // Use passed ItemsService class to create related service
268
+ const relatedService = new ItemsServiceClass(associationInfo.model, {
269
+ accountability: service.accountability,
270
+ tenant: service.tenant
271
+ });
272
+ const foreignKey = associationInfo.foreignKey || `${service.collection.toLowerCase()}_Id`;
273
+ const parentId = item[service.primaryKey];
274
+ // Get existing related records
275
+ const existingRecordsResult = await relatedService.readByQuery({
276
+ filter: { [foreignKey]: { eq: parentId } }
277
+ }, true); // bypassPermissions
278
+ const existingRecords = existingRecordsResult.data || [];
279
+ // Create a set of existing IDs
280
+ const existingIds = new Set(existingRecords.map((record) => record.id));
281
+ // Create a set of IDs from the update value
282
+ const updateIds = new Set(value.filter(item => item.id).map(item => item.id));
283
+ // Find records to delete or unlink
284
+ const idsToDelete = [...existingIds].filter(id => !updateIds.has(id));
285
+ if (idsToDelete.length > 0) {
286
+ console.log(`[RelationUtils] Removing ${idsToDelete.length} orphaned HasMany records`);
287
+ // Check if foreign key is nullable by looking at schema
288
+ const { schemaManager } = await import('./schemaManager.js');
289
+ const targetSchema = await schemaManager.getSchemaDefinition(associationInfo.model);
290
+ const fkField = targetSchema?.fields?.[foreignKey];
291
+ const allowsNull = !fkField || fkField.allowNull !== false;
292
+ // For junction tables or non-nullable foreign keys, delete the records
293
+ // For nullable foreign keys, just set the FK to null (unlink)
294
+ // Check both the schema property and name suffix for backward compatibility
295
+ const isJunctionTable = targetSchema?.isJunction === true || associationInfo.model.endsWith('_junction');
296
+ if (isJunctionTable || !allowsNull) {
297
+ await Promise.all(idsToDelete.map(async (id) => {
298
+ await relatedService.deleteOne(id, { bypassPermissions: true, transaction });
299
+ }));
300
+ }
301
+ else {
302
+ // Set foreign key to null instead of deleting
303
+ await Promise.all(idsToDelete.map(async (id) => {
304
+ await relatedService.updateOne(id, { [foreignKey]: null }, { bypassPermissions: true, transaction });
305
+ }));
306
+ }
307
+ }
308
+ // Create or update the related records
309
+ await Promise.all(value.map(async (relItem) => {
310
+ const data = { ...relItem };
311
+ // Set the foreign key to link to parent
312
+ data[foreignKey] = parentId;
313
+ if (relItem.id) {
314
+ // Update existing record
315
+ console.log(`[RelationUtils] Updating HasMany record ${relItem.id} for ${association}`);
316
+ await relatedService.updateOne(relItem.id, data, { bypassPermissions: true, transaction });
317
+ }
318
+ else {
319
+ // Create new record
320
+ console.log(`[RelationUtils] Creating new HasMany record for ${association}`);
321
+ await relatedService.createOne(data, { bypassPermissions: true, transaction });
322
+ }
323
+ }));
324
+ console.log(`[RelationUtils] Completed HasMany relationship: ${association}`);
325
+ }
326
+ /**
327
+ * Handle M2M (BelongsToMany) relationship after main record is created
328
+ *
329
+ * @param item - The created/updated main record with its ID
330
+ * @param association - Name of the association
331
+ * @param associationInfo - Metadata about the association
332
+ * @param value - Array of related items (IDs or objects with IDs)
333
+ * @param service - The service instance
334
+ * @param ItemsServiceClass - ItemsService class for creating related service instances
335
+ * @param transaction - Optional transaction
336
+ */
337
+ export async function handleM2MRelationship(item, association, associationInfo, value, service, ItemsServiceClass, transaction) {
338
+ console.log(`[RelationUtils] Handling M2M relationship: ${association}`);
339
+ if (!Array.isArray(value)) {
340
+ console.warn(`[RelationUtils] M2M value is not an array for ${association}`);
341
+ return;
342
+ }
343
+ // Use statically imported getDatabase and sql
344
+ const db = getDatabase();
345
+ // Use transaction if provided, otherwise use db
346
+ const dbOrTx = transaction || db;
347
+ // Get junction table name from association metadata
348
+ const junctionTable = associationInfo.through || `${service.collection}_${associationInfo.model}_junction`;
349
+ console.log(`[RelationUtils] Using junction table: ${junctionTable}`);
350
+ // Define foreign key column names
351
+ const sourceKey = associationInfo.foreignKey || `${service.collection}_id`;
352
+ const targetKey = associationInfo.otherKey || `${associationInfo.model}_id`;
353
+ const parentId = item[service.primaryKey];
354
+ console.log(`[RelationUtils] M2M keys: sourceKey=${sourceKey}, targetKey=${targetKey}, parentId=${parentId}`);
355
+ // Process value array - create any new related records first
356
+ const processedIds = [];
357
+ for (const targetItem of value) {
358
+ if (typeof targetItem === 'object' && targetItem !== null) {
359
+ if (targetItem.id) {
360
+ // Existing record - just use the ID
361
+ processedIds.push(targetItem.id);
362
+ }
363
+ else {
364
+ // New record - create it first using passed ItemsService class
365
+ const relatedService = new ItemsServiceClass(associationInfo.model, {
366
+ accountability: service.accountability,
367
+ tenant: service.tenant
368
+ });
369
+ console.log(`[RelationUtils] Creating new ${associationInfo.model} for M2M relation`);
370
+ const newId = await relatedService.createOne(targetItem, { bypassPermissions: true, transaction });
371
+ processedIds.push(newId);
372
+ }
373
+ }
374
+ else {
375
+ // Direct ID
376
+ processedIds.push(targetItem);
377
+ }
378
+ }
379
+ // Clear existing relations for this record
380
+ console.log(`[RelationUtils] Clearing existing M2M relations in ${junctionTable}`);
381
+ await dbOrTx.execute(sql `
382
+ DELETE FROM "${sql.raw(junctionTable)}"
383
+ WHERE "${sql.raw(sourceKey)}" = ${parentId}
384
+ `);
385
+ // Create new junction records
386
+ if (processedIds.length > 0) {
387
+ console.log(`[RelationUtils] Creating ${processedIds.length} M2M junction records`);
388
+ for (const targetId of processedIds) {
389
+ await dbOrTx.execute(sql `
390
+ INSERT INTO "${sql.raw(junctionTable)}" ("${sql.raw(sourceKey)}", "${sql.raw(targetKey)}")
391
+ VALUES (${parentId}, ${targetId})
392
+ `);
393
+ }
394
+ }
395
+ console.log(`[RelationUtils] Completed M2M relationship: ${association}`);
396
+ }
397
+ /**
398
+ * Handle M2A (polymorphic) relationship after main record is created
399
+ *
400
+ * @param item - The created/updated main record with its ID
401
+ * @param association - Name of the association
402
+ * @param associationInfo - Metadata about the association
403
+ * @param value - Array of polymorphic relation items
404
+ * @param service - The service instance
405
+ * @param ItemsServiceClass - ItemsService class (not used in M2A but kept for consistency)
406
+ * @param transaction - Optional transaction
407
+ */
408
+ export async function handleM2ARelationship(item, association, associationInfo, value, service, ItemsServiceClass, transaction) {
409
+ console.log(`[RelationUtils] Handling M2A relationship: ${association}`);
410
+ if (!Array.isArray(value)) {
411
+ console.warn(`[RelationUtils] M2A value is not an array for ${association}`);
412
+ return;
413
+ }
414
+ // Use statically imported getDatabase and sql
415
+ const db = getDatabase();
416
+ // Use transaction if provided, otherwise use db
417
+ const dbOrTx = transaction || db;
418
+ // M2A uses a polymorphic junction table
419
+ // The junction table name is stored in 'through' property
420
+ const junctionTable = associationInfo.through;
421
+ if (!junctionTable) {
422
+ console.error(`[RelationUtils] M2A relation ${association} missing 'through' property`);
423
+ return;
424
+ }
425
+ console.log(`[RelationUtils] Using M2A junction table: ${junctionTable}`);
426
+ // Define column names for polymorphic relation
427
+ const sourceKey = `${service.collection}_id`;
428
+ const targetKey = 'item_id'; // Polymorphic ID field
429
+ const typeKey = 'collection'; // Polymorphic type field
430
+ const parentId = item[service.primaryKey];
431
+ console.log(`[RelationUtils] M2A keys: sourceKey=${sourceKey}, targetKey=${targetKey}, typeKey=${typeKey}`);
432
+ // Clear existing relations for this record
433
+ console.log(`[RelationUtils] Clearing existing M2A relations in ${junctionTable}`);
434
+ await dbOrTx.execute(sql `
435
+ DELETE FROM "${sql.raw(junctionTable)}"
436
+ WHERE "${sql.raw(sourceKey)}" = ${parentId}
437
+ `);
438
+ // Create new polymorphic junction records
439
+ if (value.length > 0) {
440
+ console.log(`[RelationUtils] Creating ${value.length} M2A junction records`);
441
+ for (const item of value) {
442
+ // Extract the target type and ID
443
+ const targetType = item.type || item.collection;
444
+ const targetId = item.item_id || item.item || item.id;
445
+ if (!targetType || !targetId) {
446
+ console.warn(`[RelationUtils] Skipping invalid M2A item:`, item);
447
+ continue;
448
+ }
449
+ console.log(`[RelationUtils] Creating M2A junction: ${sourceKey}=${parentId}, ${typeKey}=${targetType}, ${targetKey}=${targetId}`);
450
+ await dbOrTx.execute(sql `
451
+ INSERT INTO "${sql.raw(junctionTable)}" ("${sql.raw(sourceKey)}", "${sql.raw(typeKey)}", "${sql.raw(targetKey)}")
452
+ VALUES (${parentId}, ${targetType}, ${targetId})
453
+ `);
454
+ }
455
+ }
456
+ console.log(`[RelationUtils] Completed M2A relationship: ${association}`);
457
+ }
458
+ /**
459
+ * Handle related records before delete (CASCADE, SET NULL, etc.)
460
+ * Processes HasMany, HasOne, and BelongsToMany relationships based on onDelete settings
461
+ */
462
+ export async function handleRelatedRecordsBeforeDelete(item, service, transaction) {
463
+ console.log(`[RelationUtils] Handling related records before delete for ${service.collection}`);
464
+ const associations = relationBuilder.getAssociations(service.collection);
465
+ if (!associations) {
466
+ return;
467
+ }
468
+ const db = getDatabase();
469
+ const dbOrTx = transaction || db;
470
+ for (const [associationName, association] of Object.entries(associations)) {
471
+ const onDelete = association.onDelete || 'CASCADE';
472
+ if (association.type === 'HasMany') {
473
+ await handleHasManyDelete(item, association, associationName, service, dbOrTx, onDelete);
474
+ }
475
+ else if (association.type === 'HasOne') {
476
+ await handleHasOneDelete(item, association, associationName, service, dbOrTx, onDelete);
477
+ }
478
+ else if (association.type === 'BelongsToMany') {
479
+ await handleBelongsToManyDelete(item, association, associationName, service, dbOrTx);
480
+ }
481
+ else if (isPolymorphicRelation(association)) {
482
+ await handleM2ADelete(item, association, associationName, service, dbOrTx);
483
+ }
484
+ }
485
+ }
486
+ /**
487
+ * Handle HasMany delete - CASCADE or SET NULL related records
488
+ */
489
+ async function handleHasManyDelete(item, association, associationName, service, dbOrTx, onDelete) {
490
+ const { schemaManager } = await import('./schemaManager.js');
491
+ const targetTable = schemaManager.getTable(association.model);
492
+ if (!targetTable) {
493
+ console.warn(`[RelationUtils] Target table ${association.model} not found for HasMany delete`);
494
+ return;
495
+ }
496
+ const foreignKey = association.foreignKey || `${service.collection.toLowerCase()}_Id`;
497
+ const parentId = item[service.primaryKey];
498
+ if (parentId === undefined || parentId === null) {
499
+ console.warn(`[RelationUtils] Cannot delete HasMany records - parentId is ${parentId}`);
500
+ return;
501
+ }
502
+ console.log(`[RelationUtils] HandleHasManyDelete: ${associationName}, onDelete=${onDelete}`);
503
+ if (onDelete === 'CASCADE') {
504
+ // Delete all related records
505
+ const fkColumn = targetTable[foreignKey];
506
+ if (fkColumn) {
507
+ const { eq } = await import('drizzle-orm');
508
+ await dbOrTx.delete(targetTable).where(eq(fkColumn, parentId));
509
+ console.log(`[RelationUtils] Cascaded delete for ${associationName}`);
510
+ }
511
+ }
512
+ else if (onDelete === 'SET NULL') {
513
+ // Set foreign key to null on related records
514
+ const fkColumn = targetTable[foreignKey];
515
+ if (fkColumn) {
516
+ const { eq } = await import('drizzle-orm');
517
+ await dbOrTx.update(targetTable).set({ [foreignKey]: null }).where(eq(fkColumn, parentId));
518
+ console.log(`[RelationUtils] Set null for ${associationName}`);
519
+ }
520
+ }
521
+ // RESTRICT and NO ACTION are handled by database constraints
522
+ }
523
+ /**
524
+ * Handle HasOne delete - CASCADE or SET NULL the related record
525
+ */
526
+ async function handleHasOneDelete(item, association, associationName, service, dbOrTx, onDelete) {
527
+ // HasOne delete works the same as HasMany, just for a single record
528
+ await handleHasManyDelete(item, association, associationName, service, dbOrTx, onDelete);
529
+ }
530
+ /**
531
+ * Handle BelongsToMany delete - Remove junction table records
532
+ */
533
+ async function handleBelongsToManyDelete(item, association, associationName, service, dbOrTx) {
534
+ const junctionTable = association.through;
535
+ if (!junctionTable) {
536
+ console.warn(`[RelationUtils] No junction table defined for ${associationName}`);
537
+ return;
538
+ }
539
+ const sourceKey = association.foreignKey || `${service.collection}_id`;
540
+ const parentId = item[service.primaryKey];
541
+ if (parentId === undefined || parentId === null) {
542
+ console.warn(`[RelationUtils] Cannot delete M2M junction records - parentId is ${parentId}`);
543
+ return;
544
+ }
545
+ console.log(`[RelationUtils] Removing M2M junction records from ${junctionTable} for ${associationName}`);
546
+ await dbOrTx.execute(sql `
547
+ DELETE FROM "${sql.raw(junctionTable)}"
548
+ WHERE "${sql.raw(sourceKey)}" = ${parentId}
549
+ `);
550
+ }
551
+ /**
552
+ * Handle M2A (polymorphic) delete - Remove polymorphic junction table records
553
+ */
554
+ async function handleM2ADelete(item, association, associationName, service, dbOrTx) {
555
+ const junctionTable = association.through;
556
+ if (!junctionTable) {
557
+ console.warn(`[RelationUtils] No junction table defined for M2A ${associationName}`);
558
+ return;
559
+ }
560
+ const sourceKey = `${service.collection}_id`;
561
+ const parentId = item[service.primaryKey];
562
+ if (parentId === undefined || parentId === null) {
563
+ console.warn(`[RelationUtils] Cannot delete M2A junction records - parentId is ${parentId}`);
564
+ return;
565
+ }
566
+ console.log(`[RelationUtils] Removing M2A junction records from ${junctionTable} for ${associationName}`);
567
+ await dbOrTx.execute(sql `
568
+ DELETE FROM "${sql.raw(junctionTable)}"
569
+ WHERE "${sql.raw(sourceKey)}" = ${parentId}
570
+ `);
571
+ }
572
+ /**
573
+ * Validate relational data - ensures referenced records exist
574
+ */
575
+ export async function validateRelationalData(data, collection, service) {
576
+ console.log(`[RelationUtils] Validating relational data for ${collection}`);
577
+ const associations = relationBuilder.getAssociations(collection);
578
+ if (!associations) {
579
+ return;
580
+ }
581
+ const errors = [];
582
+ for (const [key, value] of Object.entries(data)) {
583
+ const association = associations[key];
584
+ if (!association || value == null)
585
+ continue;
586
+ try {
587
+ await validateRelation(association, key, value, service);
588
+ }
589
+ catch (error) {
590
+ errors.push({ field: key, message: error.message });
591
+ }
592
+ }
593
+ if (errors.length > 0) {
594
+ const { APIError } = await import('./errorHandler.js');
595
+ throw new APIError('Validation failed for relational data', 400, errors);
596
+ }
597
+ }
598
+ /**
599
+ * Validate a single relation - check if referenced records exist
600
+ */
601
+ async function validateRelation(association, fieldName, value, service) {
602
+ // Dynamically import ItemsService to avoid circular dependency
603
+ const { default: ItemsService } = await import('../services/ItemsService.js');
604
+ const relatedService = new ItemsService(association.model, {
605
+ accountability: service.accountability,
606
+ tenant: service.tenant
607
+ });
608
+ switch (association.type) {
609
+ case 'BelongsTo':
610
+ if (typeof value === 'object' && !value.id) {
611
+ // New record to be created - validate will happen during create
612
+ return;
613
+ }
614
+ else {
615
+ const id = typeof value === 'object' ? value.id : value;
616
+ try {
617
+ await relatedService.readOne(id, {}, true); // bypassPermissions
618
+ }
619
+ catch (error) {
620
+ throw new Error(`Related record not found: ${id}`);
621
+ }
622
+ }
623
+ break;
624
+ case 'HasMany':
625
+ case 'BelongsToMany':
626
+ if (!Array.isArray(value)) {
627
+ throw new Error(`Value must be an array for ${fieldName}`);
628
+ }
629
+ for (const item of value) {
630
+ if (typeof item === 'object' && !item.id) {
631
+ // New record to be created - validation will happen during create
632
+ continue;
633
+ }
634
+ const id = typeof item === 'object' ? item.id : item;
635
+ try {
636
+ await relatedService.readOne(id, {}, true); // bypassPermissions
637
+ }
638
+ catch (error) {
639
+ throw new Error(`Related record not found: ${id}`);
640
+ }
641
+ }
642
+ break;
643
+ }
644
+ }
645
+ /**
646
+ * Resolve circular dependencies in data
647
+ * Detects BelongsTo relations that reference the parent record being created
648
+ */
649
+ export async function resolveCircularDependencies(data, collection, service) {
650
+ console.log(`[RelationUtils] Resolving circular dependencies for ${collection}`);
651
+ const associations = relationBuilder.getAssociations(collection);
652
+ if (!associations) {
653
+ return { resolvedData: data, deferredFields: [] };
654
+ }
655
+ const resolvedData = { ...data };
656
+ const deferredFields = [];
657
+ for (const [key, value] of Object.entries(data)) {
658
+ const association = associations[key];
659
+ if (!association || value == null)
660
+ continue;
661
+ if (hasCircularDependency(association, value, service.primaryKey)) {
662
+ console.log(`[RelationUtils] Found circular dependency in ${key}`);
663
+ deferredFields.push({ field: key, value });
664
+ delete resolvedData[key];
665
+ }
666
+ }
667
+ console.log(`[RelationUtils] Resolved ${deferredFields.length} circular dependencies`);
668
+ return { resolvedData, deferredFields };
669
+ }
670
+ /**
671
+ * Check if a value has circular dependency
672
+ * A circular dependency occurs when a BelongsTo relation references the parent's primary key
673
+ */
674
+ function hasCircularDependency(association, value, primaryKey) {
675
+ if (association.type !== 'BelongsTo')
676
+ return false;
677
+ // Check if the value is an object that references the parent's primary key
678
+ // This happens when creating a record that has a BelongsTo pointing back to itself
679
+ return typeof value === 'object' && !value.id && value[primaryKey];
680
+ }
681
+ /**
682
+ * Process deferred fields after main record creation
683
+ * Updates related records to link back to the newly created parent
684
+ */
685
+ export async function processDeferredFields(item, deferredFields, service, transaction) {
686
+ if (deferredFields.length === 0)
687
+ return;
688
+ console.log(`[RelationUtils] Processing ${deferredFields.length} deferred fields`);
689
+ const associations = relationBuilder.getAssociations(service.collection);
690
+ if (!associations)
691
+ return;
692
+ // Dynamically import ItemsService to avoid circular dependency
693
+ const { default: ItemsService } = await import('../services/ItemsService.js');
694
+ for (const { field, value } of deferredFields) {
695
+ const association = associations[field];
696
+ if (!association)
697
+ continue;
698
+ // Create a service for the related model
699
+ const relatedService = new ItemsService(association.model, {
700
+ accountability: service.accountability,
701
+ tenant: service.tenant
702
+ });
703
+ // Update the related record to link to the new parent
704
+ const foreignKey = association.foreignKey || `${field}_Id`;
705
+ if (value[service.primaryKey]) {
706
+ console.log(`[RelationUtils] Updating deferred ${field}: setting ${foreignKey} = ${item[service.primaryKey]}`);
707
+ await relatedService.updateOne(value[service.primaryKey], { [foreignKey]: item[service.primaryKey] }, { transaction, bypassPermissions: true });
708
+ }
709
+ }
710
+ }
711
+ //# sourceMappingURL=relationUtils.js.map