adminizer 4.6.0 → 4.7.0-build.221

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 (335) hide show
  1. package/Readme.md +12 -0
  2. package/assets/RelationDialogStack-CnHFOYyR.css +1 -0
  3. package/assets/RelationDialogStack-DI2bZxQX.js +20 -0
  4. package/assets/add-4213XScp.js +1 -0
  5. package/assets/add-group--F1XxfJ1.js +1 -0
  6. package/assets/add-group-form-DKRXC2n-.js +1 -0
  7. package/assets/add-user-b9HfMq7z.js +1 -0
  8. package/assets/add-user-form-UXAToWQd.js +1 -0
  9. package/assets/app-Clx8f5hd.css +1 -0
  10. package/assets/app-layout-C02ja4OI.js +1 -0
  11. package/assets/app-shell-D8wtkECO.js +1 -0
  12. package/assets/app-sidebar-BR5_zwxj.js +1 -0
  13. package/assets/app-sidebar-header-BZbIBQjq.js +1 -0
  14. package/assets/app.js +59 -7990
  15. package/assets/breadcrumbs-CODaqVkB.js +1 -0
  16. package/assets/catalog-6ZZjWdFs.js +6 -0
  17. package/assets/dashboard-CftAdKiH.js +3 -0
  18. package/assets/date-picker-DSOkNiNo.js +1 -0
  19. package/assets/del-modal-Cd4M7af8.js +1 -0
  20. package/assets/dynamic-controls-BsrJhPDY.js +1 -0
  21. package/assets/geo-json-CzR5JBXL.js +1 -0
  22. package/assets/handsontable-BI98OF5R.js +336 -0
  23. package/assets/history-DLHSU7Ak.js +1 -0
  24. package/assets/home-NcQ7nnU0.js +2 -0
  25. package/assets/icon-C2JNaLxH.js +1 -0
  26. package/assets/init-user-D2HSyXup.js +1 -0
  27. package/assets/input-error-CH2caTtO.js +1 -0
  28. package/assets/jsoneditor-DVNQmA6G.js +3869 -0
  29. package/assets/list-CFU0-TgN.js +4 -0
  30. package/assets/login-DFSLEO17.js +1 -0
  31. package/assets/manifest.json +246 -273
  32. package/assets/material-icon-Bx9pGQiQ.js +1 -0
  33. package/assets/media-manager-WcKe1EvD.js +6 -0
  34. package/assets/module-CT7PC6pc.js +1 -0
  35. package/assets/monaco-Bl4zdWCn.js +11 -0
  36. package/assets/nav-footer-BiSQkPt4.js +1 -0
  37. package/assets/nav-main-rTH0PfDw.js +1 -0
  38. package/assets/nav-user-Bj6cWs0a.js +1 -0
  39. package/assets/notification-Bi-PX87D.js +20 -0
  40. package/assets/pagination-render-AKJvTIRA.js +1 -0
  41. package/assets/register-BTP4uxsK.js +1 -0
  42. package/assets/ru-eW0WKkga.js +1 -0
  43. package/assets/theme-switcher-Dm8EOGzx.js +1 -0
  44. package/assets/toast-editor-DOg_gvSp.js +668 -0
  45. package/assets/user-filters-list-YUfR4XMI.js +1 -0
  46. package/assets/user-info-BgSbT02v.js +1 -0
  47. package/assets/user-menu-content-TQTXHIv6.js +1 -0
  48. package/assets/{vanilla-picker-l5rcX3cq.js → vanilla-picker-B3LgXoKV.js} +1 -7
  49. package/assets/welcome-vLwTu1R6.js +1 -0
  50. package/controllers/add.d.ts +1 -1
  51. package/controllers/add.js +20 -26
  52. package/controllers/addGroup.d.ts +1 -1
  53. package/controllers/addGroup.js +7 -15
  54. package/controllers/addUser.d.ts +1 -1
  55. package/controllers/addUser.js +10 -16
  56. package/controllers/catalog/Catalog.d.ts +1 -1
  57. package/controllers/catalog/Catalog.js +1 -10
  58. package/controllers/catalog/FrontendCatalogAdapter.d.ts +3 -3
  59. package/controllers/catalog/FrontendCatalogAdapter.js +0 -6
  60. package/controllers/catalog/FrontentCatalogAdapter.d.ts +3 -3
  61. package/controllers/catalog/FrontentCatalogAdapter.js +0 -4
  62. package/controllers/ckeditorUpload.js +2 -18
  63. package/controllers/dashboard.d.ts +1 -1
  64. package/controllers/dashboard.js +2 -5
  65. package/controllers/edit.js +24 -37
  66. package/controllers/editGroup.d.ts +1 -1
  67. package/controllers/editGroup.js +10 -21
  68. package/controllers/editUser.d.ts +1 -1
  69. package/controllers/editUser.js +11 -23
  70. package/controllers/exportData.d.ts +6 -0
  71. package/controllers/exportData.js +315 -0
  72. package/controllers/feed.d.ts +6 -0
  73. package/controllers/feed.js +73 -0
  74. package/controllers/feedback/feedbackController.d.ts +1 -1
  75. package/controllers/feedback/feedbackController.js +5 -7
  76. package/controllers/filter-fields/columns.d.ts +11 -0
  77. package/controllers/filter-fields/columns.js +106 -0
  78. package/controllers/filter-fields/filterFields.d.ts +10 -0
  79. package/controllers/filter-fields/filterFields.js +141 -0
  80. package/controllers/filter-fields/getAllUserFilters.d.ts +6 -0
  81. package/controllers/filter-fields/getAllUserFilters.js +115 -0
  82. package/controllers/filter-fields/groups.d.ts +5 -0
  83. package/controllers/filter-fields/groups.js +26 -0
  84. package/controllers/filter-fields/savedFilters.d.ts +25 -0
  85. package/controllers/filter-fields/savedFilters.js +317 -0
  86. package/controllers/getAllWidgets.d.ts +1 -1
  87. package/controllers/getAllWidgets.js +1 -9
  88. package/controllers/history-actions/HistoryController.js +6 -31
  89. package/controllers/initUser.js +6 -5
  90. package/controllers/inlineUpdate.d.ts +7 -0
  91. package/controllers/inlineUpdate.js +148 -0
  92. package/controllers/list.d.ts +1 -1
  93. package/controllers/list.js +383 -70
  94. package/controllers/listUserFilters.d.ts +5 -0
  95. package/controllers/listUserFilters.js +26 -0
  96. package/controllers/login.js +2 -2
  97. package/controllers/media-manager/mediaManagerApi.js +0 -9
  98. package/controllers/navigation/edit.js +3 -9
  99. package/controllers/notifications/NotificationController.d.ts +1 -1
  100. package/controllers/notifications/NotificationController.js +12 -36
  101. package/controllers/register.js +10 -9
  102. package/controllers/remove.js +10 -19
  103. package/controllers/timezones.d.ts +1 -1
  104. package/controllers/timezones.js +0 -6
  105. package/controllers/userApiKey.d.ts +7 -0
  106. package/controllers/userApiKey.js +36 -0
  107. package/controllers/view.js +14 -26
  108. package/controllers/welcome.d.ts +1 -1
  109. package/controllers/welcome.js +0 -4
  110. package/controllers/widgets/Action.d.ts +1 -1
  111. package/controllers/widgets/Action.js +1 -9
  112. package/controllers/widgets/Custom.d.ts +1 -1
  113. package/controllers/widgets/Custom.js +1 -9
  114. package/controllers/widgets/Info.d.ts +1 -1
  115. package/controllers/widgets/Info.js +1 -9
  116. package/controllers/widgets/filterInfo.d.ts +1 -0
  117. package/controllers/widgets/filterInfo.js +44 -0
  118. package/controllers/widgets/switch.d.ts +1 -1
  119. package/controllers/widgets/switch.js +1 -9
  120. package/controllers/widgetsDB.d.ts +1 -1
  121. package/controllers/widgetsDB.js +2 -8
  122. package/helpers/accessRightsHelper.d.ts +1 -1
  123. package/helpers/accessRightsHelper.js +5 -4
  124. package/helpers/apiKeyHelper.d.ts +5 -0
  125. package/helpers/apiKeyHelper.js +8 -0
  126. package/helpers/configHelper.js +12 -15
  127. package/helpers/controllerHelper.d.ts +14 -21
  128. package/helpers/controllerHelper.js +50 -83
  129. package/helpers/fieldsHelper.js +3 -3
  130. package/helpers/filterDatetimeHelper.d.ts +5 -0
  131. package/helpers/filterDatetimeHelper.js +84 -0
  132. package/helpers/inertiaActionsHelper.d.ts +2 -2
  133. package/helpers/inertiaActionsHelper.js +5 -4
  134. package/helpers/inertiaAddHelper.d.ts +3 -414
  135. package/helpers/inertiaAddHelper.js +39 -15
  136. package/helpers/inertiaGroupHelper.d.ts +2 -2
  137. package/helpers/inertiaGroupHelper.js +3 -3
  138. package/helpers/inertiaListHelper.d.ts +7 -3
  139. package/helpers/inertiaListHelper.js +26 -12
  140. package/helpers/inertiaMenuHelper.d.ts +1 -0
  141. package/helpers/inertiaMenuHelper.js +15 -3
  142. package/helpers/inertiaUserHelper.d.ts +3 -2
  143. package/helpers/inertiaUserHelper.js +7 -3
  144. package/helpers/menuHelper.d.ts +5 -2
  145. package/helpers/menuHelper.js +64 -12
  146. package/helpers/viteHelper.js +1 -2
  147. package/index.d.ts +6 -2
  148. package/index.js +6 -2
  149. package/interfaces/adminpanelConfig.d.ts +126 -39
  150. package/interfaces/internalModelAccess.d.ts +37 -0
  151. package/interfaces/internalModelAccess.js +1 -0
  152. package/interfaces/listQueryBuilder.d.ts +22 -0
  153. package/interfaces/listQueryBuilder.js +1 -0
  154. package/interfaces/queryCriteria.d.ts +54 -0
  155. package/interfaces/queryCriteria.js +1 -0
  156. package/interfaces/types.d.ts +1 -13
  157. package/lib/Adminizer.d.ts +4 -2
  158. package/lib/Adminizer.js +29 -10
  159. package/lib/DataAccessor.d.ts +8 -5
  160. package/lib/DataAccessor.js +89 -42
  161. package/lib/I18n.d.ts +5 -1
  162. package/lib/I18n.js +45 -19
  163. package/lib/MiddlewareManager.d.ts +8 -0
  164. package/lib/MiddlewareManager.js +53 -0
  165. package/lib/ai-assistant/OpenAiModelService.d.ts +3 -3
  166. package/lib/ai-assistant/OpenAiModelService.js +23 -24
  167. package/lib/catalog/Navigation.d.ts +1 -0
  168. package/lib/catalog/Navigation.js +12 -11
  169. package/lib/controls/jsoneditor/JsonEditor.d.ts +1 -2
  170. package/lib/controls/markdown/ToastUiEditor.d.ts +1 -2
  171. package/lib/feedback/FeedbackHandler.js +2 -2
  172. package/lib/filters/ConditionValidator.d.ts +107 -0
  173. package/lib/filters/ConditionValidator.js +483 -0
  174. package/lib/filters/CustomFilterHandler.d.ts +122 -0
  175. package/lib/filters/CustomFilterHandler.js +131 -0
  176. package/lib/filters/FilterCustomFieldHandler.d.ts +2 -0
  177. package/lib/filters/FilterCustomFieldHandler.js +2 -0
  178. package/lib/filters/FilterService.d.ts +82 -0
  179. package/lib/filters/FilterService.js +323 -0
  180. package/lib/filters/index.d.ts +6 -0
  181. package/lib/filters/index.js +4 -0
  182. package/lib/history-actions/AbstractHistoryAdapter.d.ts +5 -4
  183. package/lib/history-actions/AbstractHistoryAdapter.js +45 -30
  184. package/lib/history-actions/DefaultHistoryAdapter.d.ts +2 -0
  185. package/lib/history-actions/DefaultHistoryAdapter.js +12 -6
  186. package/lib/history-actions/HistoryHandler.js +1 -1
  187. package/lib/list-query-builder/ListQueryBuilder.d.ts +117 -0
  188. package/lib/list-query-builder/ListQueryBuilder.js +707 -0
  189. package/lib/media-manager/AbstractMediaManager.d.ts +9 -8
  190. package/lib/media-manager/DefaultMediaManager.d.ts +2 -0
  191. package/lib/media-manager/DefaultMediaManager.js +27 -15
  192. package/lib/media-manager/Items.d.ts +4 -1
  193. package/lib/media-manager/Items.js +62 -59
  194. package/lib/media-manager/MediaManagerHandler.js +1 -1
  195. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +5 -1
  196. package/lib/media-manager/helpers/MediaManagerHelper.js +38 -4
  197. package/lib/model/AbstractModel.d.ts +33 -25
  198. package/lib/model/AbstractModel.js +54 -2
  199. package/lib/model/InternalModelAccessFactory.d.ts +18 -0
  200. package/lib/model/InternalModelAccessFactory.js +82 -0
  201. package/lib/model/ModelHandler.d.ts +6 -0
  202. package/lib/model/ModelHandler.js +14 -0
  203. package/lib/model/adapter/sequelize.d.ts +32 -10
  204. package/lib/model/adapter/sequelize.js +409 -62
  205. package/lib/model/adapter/typeorm.d.ts +62 -0
  206. package/lib/model/adapter/typeorm.js +777 -0
  207. package/lib/model/internalModelAccessToken.d.ts +1 -0
  208. package/lib/model/internalModelAccessToken.js +1 -0
  209. package/lib/model/internalModelRepository.d.ts +3 -0
  210. package/lib/model/internalModelRepository.js +4 -0
  211. package/lib/notifications/AbstractNotificationService.d.ts +3 -0
  212. package/lib/notifications/AbstractNotificationService.js +42 -36
  213. package/lib/notifications/GeneralNotificationService.js +37 -40
  214. package/lib/notifications/SystemNotificationService.js +33 -36
  215. package/lib/requestProcessor.js +0 -3
  216. package/lib/ui-i18n/getUiTranslations.d.ts +1 -0
  217. package/lib/ui-i18n/getUiTranslations.js +3 -0
  218. package/lib/ui-i18n/uiTranslationKeys.d.ts +6 -0
  219. package/lib/ui-i18n/uiTranslationKeys.js +268 -0
  220. package/lib/widgets/widgetHandler.d.ts +7 -2
  221. package/lib/widgets/widgetHandler.js +98 -18
  222. package/models/FilterAP.d.ts +116 -0
  223. package/models/FilterAP.js +68 -0
  224. package/models/FilterColumnAP.d.ts +32 -0
  225. package/models/FilterColumnAP.js +21 -0
  226. package/models/GroupAP.d.ts +1 -1
  227. package/models/HistoryActionsAP.d.ts +3 -3
  228. package/models/MediaManagerMetaAP.d.ts +1 -1
  229. package/models/NavigationAP.d.ts +1 -1
  230. package/models/UserAP.d.ts +6 -1
  231. package/models/UserAP.js +4 -0
  232. package/package.json +39 -32
  233. package/policies/authPolicies.d.ts +12 -0
  234. package/policies/authPolicies.js +104 -0
  235. package/policies/permissionResolvers.d.ts +12 -0
  236. package/policies/permissionResolvers.js +52 -0
  237. package/services/FeedService.d.ts +70 -0
  238. package/services/FeedService.js +334 -0
  239. package/system/Router.d.ts +1 -0
  240. package/system/Router.js +136 -59
  241. package/system/bindAccessRights.js +11 -30
  242. package/system/bindAuthorization.js +18 -18
  243. package/system/bindCors.js +16 -1
  244. package/system/bindCustomFilterHandlers.d.ts +2 -0
  245. package/system/bindCustomFilterHandlers.js +4 -0
  246. package/system/bindInertia.js +18 -61
  247. package/system/bindReqFunctions.js +10 -2
  248. package/system/bindTranslations.js +7 -3
  249. package/system/buildInternalModelAccess.d.ts +4 -0
  250. package/system/buildInternalModelAccess.js +59 -0
  251. package/system/defaults.js +18 -14
  252. package/system/routePolicies.d.ts +2 -0
  253. package/system/routePolicies.js +29 -0
  254. package/translations/en.json +151 -39
  255. package/translations/ru.json +211 -64
  256. package/ui/components/handsontable.js +13 -27
  257. package/ui/components/ui/dialog-stack.js +1 -3
  258. package/ui/components/ui/popover.js +1 -1
  259. package/ui/components/ui/sidebar.js +1 -1
  260. package/assets/RelationDialogStack-D9UVEF9s.js +0 -407
  261. package/assets/RelationDialogStack-DV8OITPR.css +0 -4
  262. package/assets/add-BlvzWQKF.js +0 -1
  263. package/assets/add-group-1Uoq9NWe.js +0 -1
  264. package/assets/add-group-form-B01gwDGu.js +0 -1
  265. package/assets/add-user-BQCAsaRy.js +0 -1
  266. package/assets/add-user-form-Cgwc9JkI.js +0 -1
  267. package/assets/app-DaOMy1nl.css +0 -72
  268. package/assets/app-layout-CAm60qoE.js +0 -1
  269. package/assets/app-shell-QWCtn9ye.js +0 -1
  270. package/assets/app-sidebar-CfaYbnSy.js +0 -1
  271. package/assets/app-sidebar-header-BsPFDhZ8.js +0 -1
  272. package/assets/breadcrumbs-CZZirDj8.js +0 -1
  273. package/assets/catalog-k5myk7fk.js +0 -6
  274. package/assets/dashboard-BkL9ybBw.js +0 -3
  275. package/assets/date-picker-B5AZ_7Q9.js +0 -1
  276. package/assets/del-modal-BoyXZloG.js +0 -1
  277. package/assets/dynamic-controls-k61T9W2P.js +0 -1
  278. package/assets/form-1WGY0YgG.js +0 -1
  279. package/assets/form-DJapG3qF.js +0 -1
  280. package/assets/geo-json-DsMUHo0l.js +0 -4
  281. package/assets/handsontable-PxYdjN8c.js +0 -298
  282. package/assets/history-CluyR-yJ.js +0 -1
  283. package/assets/home-Dug9zBzM.js +0 -2
  284. package/assets/icon-DfDLMG5f.js +0 -1
  285. package/assets/init-user-CF80MEnT.js +0 -1
  286. package/assets/input-error-DuuqFgZa.js +0 -1
  287. package/assets/jsoneditor-De1FvcYu.js +0 -3882
  288. package/assets/list-CuexshNt.js +0 -1
  289. package/assets/list-table-BsEWjTKY.js +0 -22
  290. package/assets/login-eDemYzN-.js +0 -1
  291. package/assets/material-icon-DMT8KdmE.js +0 -1
  292. package/assets/media-manager-DfYa_mT_.js +0 -14
  293. package/assets/module-Cd4Tm6uq.js +0 -1
  294. package/assets/monaco-BhBYtg3d.js +0 -11
  295. package/assets/nav-footer-D3olYxtz.js +0 -1
  296. package/assets/nav-main-BctqyzeV.js +0 -1
  297. package/assets/nav-user-Bn1Lt-BZ.js +0 -1
  298. package/assets/notification-D64qvni-.js +0 -27
  299. package/assets/pagination-render-DxD78ahJ.js +0 -1
  300. package/assets/register-349PwYbe.js +0 -1
  301. package/assets/theme-switcher-DfExsHW2.js +0 -1
  302. package/assets/toast-editor-ESK5iWPx.js +0 -845
  303. package/assets/user-info-DtBK5Kh8.js +0 -1
  304. package/assets/user-menu-content-0XYOCMaA.js +0 -1
  305. package/assets/welcome-PDp-gUei.js +0 -1
  306. package/controllers/form.d.ts +0 -1
  307. package/controllers/form.js +0 -86
  308. package/helpers/formHelper.d.ts +0 -6
  309. package/helpers/formHelper.js +0 -38
  310. package/helpers/inertiaFromHelper.d.ts +0 -11
  311. package/helpers/inertiaFromHelper.js +0 -98
  312. package/helpers/runtimeMode.d.ts +0 -1
  313. package/helpers/runtimeMode.js +0 -3
  314. package/lib/PolicyManager.d.ts +0 -8
  315. package/lib/PolicyManager.js +0 -53
  316. package/lib/datatable/NodeTable.d.ts +0 -49
  317. package/lib/datatable/NodeTable.js +0 -207
  318. package/lib/model/adapter/waterline.d.ts +0 -32
  319. package/lib/model/adapter/waterline.js +0 -180
  320. package/migrations/index.d.ts +0 -3
  321. package/migrations/index.js +0 -4
  322. package/migrations/knex/20250106000001_adminizer_init.d.ts +0 -8
  323. package/migrations/knex/20250106000001_adminizer_init.js +0 -164
  324. package/migrations/umzug/0001.d.ts +0 -7
  325. package/migrations/umzug/0001.js +0 -121
  326. package/migrations/umzugExports.d.ts +0 -2
  327. package/migrations/umzugExports.js +0 -9
  328. package/system/bindForms.d.ts +0 -2
  329. package/system/bindForms.js +0 -20
  330. /package/{policies → middlewares}/addMessages.d.ts +0 -0
  331. /package/{policies → middlewares}/addMessages.js +0 -0
  332. /package/{policies → middlewares}/checkAuth.d.ts +0 -0
  333. /package/{policies → middlewares}/checkAuth.js +0 -0
  334. /package/{policies → middlewares}/setLocale.d.ts +0 -0
  335. /package/{policies → middlewares}/setLocale.js +0 -0
@@ -0,0 +1,777 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { pathToFileURL, fileURLToPath } from "url";
4
+ import { Brackets, EntitySchema, NotBrackets, } from "typeorm";
5
+ import { v4 as uuid } from "uuid";
6
+ import { AbstractAdapter, AbstractModel } from "../AbstractModel.js";
7
+ const ROOT_ALIAS = "record";
8
+ function normalizeModelName(modelName) {
9
+ return modelName.toLowerCase();
10
+ }
11
+ function getSchemaFieldName(attr, fallback) {
12
+ return attr.field || attr.columnName || fallback;
13
+ }
14
+ function resolveAdminizerTypeFromColumn(column) {
15
+ const type = typeof column.type === "function"
16
+ ? column.type.name.toLowerCase()
17
+ : String(column.type ?? "").toLowerCase();
18
+ if (type.includes("bool"))
19
+ return "boolean";
20
+ if (type.includes("int") ||
21
+ type.includes("float") ||
22
+ type.includes("double") ||
23
+ type.includes("decimal") ||
24
+ type.includes("number")) {
25
+ return "number";
26
+ }
27
+ if (type.includes("json"))
28
+ return "json";
29
+ if (type.includes("date") || type.includes("time"))
30
+ return "string";
31
+ if (type.includes("char") || type.includes("text") || type.includes("uuid") || type.includes("string")) {
32
+ return "string";
33
+ }
34
+ return "ref";
35
+ }
36
+ function resolveTypeOrmColumnType(attr) {
37
+ if (attr.autoCreatedAt || attr.autoUpdatedAt || attr.type === "datetime" || attr.type === "date") {
38
+ return "datetime";
39
+ }
40
+ switch (attr.type) {
41
+ case "number":
42
+ return "integer";
43
+ case "boolean":
44
+ return "boolean";
45
+ case "json":
46
+ case "ref":
47
+ return "simple-json";
48
+ case "datetime":
49
+ case "date":
50
+ return "datetime";
51
+ case "string":
52
+ default:
53
+ return "varchar";
54
+ }
55
+ }
56
+ function getPrimaryColumnType(metadata) {
57
+ const primary = metadata.primaryColumns[0];
58
+ return primary ? resolveAdminizerTypeFromColumn(primary) : "ref";
59
+ }
60
+ function getPrimaryKeyValue(record, primaryKey) {
61
+ return record?.[primaryKey];
62
+ }
63
+ function normalizeRelationValue(value, primaryKey) {
64
+ if (value && typeof value === "object") {
65
+ return value[primaryKey] ?? value;
66
+ }
67
+ return value;
68
+ }
69
+ function mapRelationType(relationType) {
70
+ return relationType === "one-to-many" || relationType === "many-to-many"
71
+ ? "association-many"
72
+ : "association";
73
+ }
74
+ export function mapTypeOrmToAdminizerAttributes(metadata) {
75
+ const result = {};
76
+ for (const column of metadata.columns) {
77
+ result[column.propertyName] = {
78
+ type: resolveAdminizerTypeFromColumn(column),
79
+ required: !column.isNullable,
80
+ allowNull: column.isNullable,
81
+ unique: Boolean(column.isUnique),
82
+ defaultsTo: column.default,
83
+ columnName: column.databaseName,
84
+ };
85
+ }
86
+ for (const relation of metadata.relations) {
87
+ const targetName = relation.inverseEntityMetadata.name;
88
+ const relationType = mapRelationType(relation.relationType);
89
+ if (relationType === "association") {
90
+ const joinColumn = relation.joinColumns[0];
91
+ const via = joinColumn?.propertyName || joinColumn?.databaseName || `${relation.propertyName}Id`;
92
+ if (!result[via]) {
93
+ result[via] = {
94
+ type: getPrimaryColumnType(relation.inverseEntityMetadata),
95
+ primaryKeyForAssociation: true,
96
+ columnName: joinColumn?.databaseName || via,
97
+ };
98
+ }
99
+ else {
100
+ result[via].primaryKeyForAssociation = true;
101
+ }
102
+ result[relation.propertyName] = {
103
+ type: "association",
104
+ model: targetName,
105
+ via,
106
+ };
107
+ }
108
+ else {
109
+ result[relation.propertyName] = {
110
+ type: "association-many",
111
+ collection: targetName,
112
+ via: relation.inverseRelation?.propertyName || relation.inverseSidePropertyPath,
113
+ };
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+ export function createTypeOrmEntitySchemaFromAdminizerSchema(modelName, schema, allSchemas) {
119
+ const columns = {};
120
+ const relations = {};
121
+ const schemaWithTimestamps = {
122
+ ...schema,
123
+ ...(schema.createdAt ? {} : {
124
+ createdAt: {
125
+ type: "datetime",
126
+ autoCreatedAt: true,
127
+ },
128
+ }),
129
+ ...(schema.updatedAt ? {} : {
130
+ updatedAt: {
131
+ type: "datetime",
132
+ autoUpdatedAt: true,
133
+ },
134
+ }),
135
+ };
136
+ for (const [field, rawAttr] of Object.entries(schemaWithTimestamps)) {
137
+ const attr = typeof rawAttr === "string" ? { type: rawAttr } : { ...rawAttr };
138
+ if (attr.model || attr.collection) {
139
+ continue;
140
+ }
141
+ const column = {
142
+ type: resolveTypeOrmColumnType(attr),
143
+ name: getSchemaFieldName(attr, field),
144
+ nullable: !attr.primaryKey && !attr.required,
145
+ };
146
+ if (attr.primaryKey) {
147
+ column.primary = true;
148
+ column.nullable = false;
149
+ }
150
+ if (attr.autoIncrement) {
151
+ column.generated = "increment";
152
+ }
153
+ if (attr.uuid) {
154
+ column.generated = "uuid";
155
+ }
156
+ if (attr.unique) {
157
+ column.unique = true;
158
+ }
159
+ if (attr.defaultsTo !== undefined) {
160
+ column.default = attr.defaultsTo;
161
+ }
162
+ if (attr.autoCreatedAt) {
163
+ column.createDate = true;
164
+ }
165
+ if (attr.autoUpdatedAt) {
166
+ column.updateDate = true;
167
+ }
168
+ columns[field] = column;
169
+ }
170
+ for (const [field, rawAttr] of Object.entries(schemaWithTimestamps)) {
171
+ const attr = typeof rawAttr === "string" ? { type: rawAttr } : rawAttr;
172
+ if (attr.model) {
173
+ relations[field] = {
174
+ type: "many-to-one",
175
+ target: attr.model,
176
+ joinColumn: {
177
+ name: `${field}Id`,
178
+ },
179
+ nullable: !attr.required,
180
+ onDelete: attr.onDelete,
181
+ };
182
+ continue;
183
+ }
184
+ if (attr.collection && attr.via) {
185
+ const targetSchema = allSchemas[attr.collection];
186
+ const inverse = targetSchema?.[attr.via];
187
+ const isManyToMany = inverse?.collection === modelName;
188
+ if (isManyToMany) {
189
+ const isOwner = normalizeModelName(modelName) > normalizeModelName(attr.collection);
190
+ relations[field] = {
191
+ type: "many-to-many",
192
+ target: attr.collection,
193
+ inverseSide: attr.via,
194
+ joinTable: isOwner
195
+ ? {
196
+ name: [modelName, attr.collection].sort().join("").toLowerCase(),
197
+ joinColumn: { name: `${modelName}Id` },
198
+ inverseJoinColumn: { name: `${attr.collection}Id` },
199
+ }
200
+ : false,
201
+ };
202
+ }
203
+ else {
204
+ relations[field] = {
205
+ type: "one-to-many",
206
+ target: attr.collection,
207
+ inverseSide: attr.via,
208
+ };
209
+ }
210
+ }
211
+ }
212
+ return new EntitySchema({
213
+ name: modelName,
214
+ tableName: modelName.toLowerCase(),
215
+ columns,
216
+ relations,
217
+ });
218
+ }
219
+ export async function loadSystemTypeOrmEntities() {
220
+ const currentDir = import.meta.url ? path.dirname(fileURLToPath(import.meta.url)) : process.cwd();
221
+ const possiblePaths = [
222
+ path.resolve(currentDir, "../../../../models"),
223
+ path.resolve(currentDir, "../../../../src/models"),
224
+ path.resolve(currentDir, "../../../models"),
225
+ path.resolve(currentDir, "../../../src/models"),
226
+ path.resolve(process.cwd(), "node_modules/adminizer/src/models"),
227
+ path.resolve(process.cwd(), "node_modules/adminizer/models"),
228
+ ];
229
+ const modelsDir = possiblePaths.find((possiblePath) => fs.existsSync(possiblePath));
230
+ if (!modelsDir) {
231
+ return [];
232
+ }
233
+ let files = fs.readdirSync(modelsDir).filter((file) => file.endsWith(".js"));
234
+ if (!files.length) {
235
+ files = fs.readdirSync(modelsDir).filter((file) => file.endsWith(".ts") && !file.endsWith(".d.ts"));
236
+ }
237
+ const schemas = {};
238
+ for (const file of files) {
239
+ const modelName = path.basename(file, path.extname(file));
240
+ const filePath = path.resolve(modelsDir, file);
241
+ const mod = await import(pathToFileURL(filePath).href);
242
+ schemas[modelName] = mod.default;
243
+ }
244
+ return Object.entries(schemas).map(([modelName, schema]) => createTypeOrmEntitySchemaFromAdminizerSchema(modelName, schema, schemas));
245
+ }
246
+ export class TypeOrmModel extends AbstractModel {
247
+ metadata;
248
+ repository;
249
+ paramIndex = 0;
250
+ constructor(modelName, metadata) {
251
+ super(modelName, mapTypeOrmToAdminizerAttributes(metadata), metadata.primaryColumns[0]?.propertyName || "id", metadata.name);
252
+ this.metadata = metadata;
253
+ this.repository = metadata.connection.getRepository(metadata.target);
254
+ }
255
+ nextParamName() {
256
+ this.paramIndex += 1;
257
+ return `p${this.paramIndex}`;
258
+ }
259
+ createQueryBuilder(alias = ROOT_ALIAS) {
260
+ this.paramIndex = 0;
261
+ return this.repository.createQueryBuilder(alias);
262
+ }
263
+ get relationNames() {
264
+ return this.metadata.relations.map((relation) => relation.propertyName);
265
+ }
266
+ getRelation(name) {
267
+ return this.metadata.relations.find((relation) => relation.propertyName === name);
268
+ }
269
+ getFieldColumn(alias, field) {
270
+ const attr = this.attributes[field];
271
+ if (attr?.type === "association" && attr.via) {
272
+ return `${alias}.${attr.via}`;
273
+ }
274
+ return `${alias}.${field}`;
275
+ }
276
+ getMetadataForAlias(alias) {
277
+ if (alias === ROOT_ALIAS) {
278
+ return this.metadata;
279
+ }
280
+ const relationPrefix = `${ROOT_ALIAS}_`;
281
+ if (!alias.startsWith(relationPrefix)) {
282
+ return undefined;
283
+ }
284
+ const relationName = alias.slice(relationPrefix.length);
285
+ return this.getRelation(relationName)?.inverseEntityMetadata;
286
+ }
287
+ getOrderColumn(alias, field) {
288
+ const metadata = this.getMetadataForAlias(alias);
289
+ if (!metadata) {
290
+ return undefined;
291
+ }
292
+ const attr = alias === ROOT_ALIAS ? this.attributes[field] : undefined;
293
+ const normalizedField = attr?.type === "association" && attr.via ? attr.via : field;
294
+ const column = metadata.columns.find((item) => item.propertyName === normalizedField ||
295
+ item.databaseName === normalizedField);
296
+ return column ? `${alias}.${column.propertyName}` : undefined;
297
+ }
298
+ getOrder(criteria) {
299
+ if (!criteria.sort) {
300
+ return [];
301
+ }
302
+ if (typeof criteria.sort === "string") {
303
+ const [field, dir] = criteria.sort.trim().split(/\s+/);
304
+ return [[field, dir?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
305
+ }
306
+ return Object.entries(criteria.sort).map(([field, dir]) => [
307
+ field,
308
+ String(dir).toUpperCase() === "DESC" ? "DESC" : "ASC",
309
+ ]);
310
+ }
311
+ buildAttributes(select) {
312
+ if (!select) {
313
+ return undefined;
314
+ }
315
+ const validColumns = new Set(this.metadata.columns.map((column) => column.propertyName));
316
+ if (Array.isArray(select)) {
317
+ const fields = select.filter((field) => validColumns.has(field));
318
+ return fields.length ? fields : undefined;
319
+ }
320
+ const fields = Object.entries(select)
321
+ .filter(([field, enabled]) => enabled && validColumns.has(field))
322
+ .map(([field]) => field);
323
+ return fields.length ? fields : undefined;
324
+ }
325
+ normalizeCriteria(criteria = {}) {
326
+ const criteriaSortValue = "sort" in criteria ? criteria.sort : undefined;
327
+ const isOrderingSort = typeof criteriaSortValue === "string";
328
+ const { where: nestedWhere, skip, limit, sort, select, populate, ...rest } = criteria;
329
+ if (!isOrderingSort && criteriaSortValue !== undefined) {
330
+ rest.sort = criteriaSortValue;
331
+ }
332
+ const hasNestedWhereKeys = nestedWhere && Object.keys(nestedWhere).length > 0;
333
+ return {
334
+ where: hasNestedWhereKeys ? nestedWhere : rest,
335
+ limit,
336
+ skip,
337
+ order: this.getOrder(criteria),
338
+ select: this.buildAttributes(select),
339
+ };
340
+ }
341
+ addRequestedRelations(qb, populate) {
342
+ const aliases = new Map();
343
+ const relations = populate ? Object.keys(populate) : this.relationNames;
344
+ for (const relationName of relations) {
345
+ if (!this.getRelation(relationName)) {
346
+ continue;
347
+ }
348
+ const alias = `${ROOT_ALIAS}_${relationName}`;
349
+ qb.leftJoinAndSelect(`${ROOT_ALIAS}.${relationName}`, alias);
350
+ aliases.set(relationName, alias);
351
+ }
352
+ if (populate) {
353
+ for (const [relationName, nestedCriteria] of Object.entries(populate)) {
354
+ if (nestedCriteria === true) {
355
+ continue;
356
+ }
357
+ const alias = aliases.get(relationName);
358
+ if (!alias) {
359
+ continue;
360
+ }
361
+ const options = this.normalizeCriteria(nestedCriteria);
362
+ if (Object.keys(options.where).length > 0) {
363
+ this.applyWhere(qb, options.where, alias, aliases);
364
+ }
365
+ for (const [field, direction] of options.order) {
366
+ const orderColumn = this.getOrderColumn(alias, field);
367
+ if (orderColumn) {
368
+ qb.addOrderBy(orderColumn, direction);
369
+ }
370
+ }
371
+ }
372
+ }
373
+ return aliases;
374
+ }
375
+ addAllRelationJoins(qb) {
376
+ const aliases = new Map();
377
+ for (const relationName of this.relationNames) {
378
+ const alias = `${ROOT_ALIAS}_${relationName}`;
379
+ if (!aliases.has(relationName)) {
380
+ qb.leftJoinAndSelect(`${ROOT_ALIAS}.${relationName}`, alias);
381
+ aliases.set(relationName, alias);
382
+ }
383
+ }
384
+ return aliases;
385
+ }
386
+ isNativeWhere(where) {
387
+ return where instanceof Brackets || where instanceof NotBrackets;
388
+ }
389
+ applyFindOptions(qb, criteria) {
390
+ const options = this.normalizeCriteria(criteria);
391
+ const aliases = this.addRequestedRelations(qb, criteria.populate);
392
+ if (this.isNativeWhere(options.where) || Object.keys(options.where).length > 0) {
393
+ this.applyWhere(qb, options.where, ROOT_ALIAS, aliases);
394
+ }
395
+ if (options.select) {
396
+ qb.select(options.select.map((field) => `${ROOT_ALIAS}.${field}`));
397
+ }
398
+ for (const [field, direction] of options.order) {
399
+ const orderColumn = this.getOrderColumn(ROOT_ALIAS, field);
400
+ if (orderColumn) {
401
+ qb.addOrderBy(orderColumn, direction);
402
+ }
403
+ }
404
+ if (typeof options.skip === "number") {
405
+ qb.skip(options.skip);
406
+ }
407
+ if (typeof options.limit === "number") {
408
+ qb.take(options.limit);
409
+ }
410
+ }
411
+ applyWhere(qb, where, alias, relationAliases) {
412
+ if (this.isNativeWhere(where)) {
413
+ qb.andWhere(where);
414
+ return;
415
+ }
416
+ const brackets = this.buildWhereBrackets(where, alias, relationAliases);
417
+ if (brackets) {
418
+ qb.andWhere(brackets);
419
+ }
420
+ }
421
+ buildWhereBrackets(where, alias, relationAliases) {
422
+ const entries = Object.entries(where).filter(([, value]) => value !== undefined);
423
+ if (!entries.length) {
424
+ return undefined;
425
+ }
426
+ return new Brackets((builder) => {
427
+ entries.forEach(([key, value], index) => {
428
+ const expression = this.buildWhereExpression(key, value, alias, relationAliases);
429
+ if (!expression) {
430
+ return;
431
+ }
432
+ if (index === 0) {
433
+ builder.where(expression.sql, expression.params);
434
+ }
435
+ else {
436
+ builder.andWhere(expression.sql, expression.params);
437
+ }
438
+ });
439
+ });
440
+ }
441
+ buildWhereExpression(key, value, alias, relationAliases) {
442
+ if (key === "and") {
443
+ const items = Array.isArray(value) ? value : [];
444
+ return {
445
+ sql: new Brackets((builder) => {
446
+ items.forEach((item, index) => {
447
+ const bracket = this.buildWhereBrackets(item, alias, relationAliases);
448
+ if (!bracket)
449
+ return;
450
+ index === 0 ? builder.where(bracket) : builder.andWhere(bracket);
451
+ });
452
+ }),
453
+ };
454
+ }
455
+ if (key === "or") {
456
+ const items = Array.isArray(value) ? value : [];
457
+ return {
458
+ sql: new Brackets((builder) => {
459
+ items.forEach((item, index) => {
460
+ const bracket = this.buildWhereBrackets(item, alias, relationAliases);
461
+ if (!bracket)
462
+ return;
463
+ index === 0 ? builder.where(bracket) : builder.orWhere(bracket);
464
+ });
465
+ }),
466
+ };
467
+ }
468
+ if (key === "not") {
469
+ const bracket = this.buildWhereBrackets(value, alias, relationAliases);
470
+ if (!bracket)
471
+ return undefined;
472
+ return {
473
+ sql: new NotBrackets((builder) => builder.where(bracket)),
474
+ };
475
+ }
476
+ const relationPathMatch = key.match(/^\$([A-Za-z0-9_]+)\.([A-Za-z0-9_]+)\$$/);
477
+ if (relationPathMatch) {
478
+ const relationAlias = relationAliases.get(relationPathMatch[1]);
479
+ if (!relationAlias) {
480
+ return undefined;
481
+ }
482
+ return this.buildFieldCondition(`${relationAlias}.${relationPathMatch[2]}`, value);
483
+ }
484
+ const attr = this.attributes[key];
485
+ if (attr?.type === "association-many") {
486
+ const relationAlias = relationAliases.get(key);
487
+ const relation = this.getRelation(key);
488
+ const targetPrimaryKey = relation?.inverseEntityMetadata.primaryColumns[0]?.propertyName || "id";
489
+ if (relationAlias) {
490
+ return this.buildFieldCondition(`${relationAlias}.${targetPrimaryKey}`, value);
491
+ }
492
+ }
493
+ return this.buildFieldCondition(this.getFieldColumn(alias, key), value);
494
+ }
495
+ buildFieldCondition(column, value) {
496
+ if (value === null) {
497
+ return { sql: `${column} IS NULL` };
498
+ }
499
+ if (Array.isArray(value)) {
500
+ const param = this.nextParamName();
501
+ return { sql: `${column} IN (:...${param})`, params: { [param]: value } };
502
+ }
503
+ if (value && typeof value === "object" && !(value instanceof Date)) {
504
+ const expressions = [];
505
+ const params = {};
506
+ for (const [operator, raw] of Object.entries(value)) {
507
+ if (raw === undefined)
508
+ continue;
509
+ const built = this.buildOperatorCondition(column, operator, raw);
510
+ if (!built)
511
+ continue;
512
+ expressions.push(built.sql);
513
+ Object.assign(params, built.params);
514
+ }
515
+ if (!expressions.length) {
516
+ return undefined;
517
+ }
518
+ return {
519
+ sql: expressions.length === 1 ? expressions[0] : expressions.map((item) => `(${item})`).join(" AND "),
520
+ params,
521
+ };
522
+ }
523
+ const param = this.nextParamName();
524
+ return { sql: `${column} = :${param}`, params: { [param]: value } };
525
+ }
526
+ buildOperatorCondition(column, operator, value) {
527
+ const param = this.nextParamName();
528
+ const params = { [param]: value };
529
+ switch (operator) {
530
+ case "eq":
531
+ case "$eq":
532
+ return { sql: `${column} = :${param}`, params };
533
+ case "ne":
534
+ case "!=":
535
+ case "$ne":
536
+ return { sql: `${column} != :${param}`, params };
537
+ case "gt":
538
+ case ">":
539
+ case "$gt":
540
+ return { sql: `${column} > :${param}`, params };
541
+ case "gte":
542
+ case ">=":
543
+ case "$gte":
544
+ return { sql: `${column} >= :${param}`, params };
545
+ case "lt":
546
+ case "<":
547
+ case "$lt":
548
+ return { sql: `${column} < :${param}`, params };
549
+ case "lte":
550
+ case "<=":
551
+ case "$lte":
552
+ return { sql: `${column} <= :${param}`, params };
553
+ case "contains":
554
+ return { sql: `CAST(${column} AS TEXT) LIKE :${param}`, params: { [param]: `%${value}%` } };
555
+ case "startsWith":
556
+ return { sql: `CAST(${column} AS TEXT) LIKE :${param}`, params: { [param]: `${value}%` } };
557
+ case "endsWith":
558
+ return { sql: `CAST(${column} AS TEXT) LIKE :${param}`, params: { [param]: `%${value}` } };
559
+ case "in":
560
+ case "$in":
561
+ return { sql: `${column} IN (:...${param})`, params };
562
+ case "notIn":
563
+ case "nin":
564
+ case "$notIn":
565
+ return { sql: `${column} NOT IN (:...${param})`, params };
566
+ case "between":
567
+ case "$between": {
568
+ const [from, to] = Array.isArray(value) ? value : [undefined, undefined];
569
+ const fromParam = `${param}From`;
570
+ const toParam = `${param}To`;
571
+ return {
572
+ sql: `${column} BETWEEN :${fromParam} AND :${toParam}`,
573
+ params: { [fromParam]: from, [toParam]: to },
574
+ };
575
+ }
576
+ case "isNull":
577
+ return value ? { sql: `${column} IS NULL` } : undefined;
578
+ case "isNotNull":
579
+ return value ? { sql: `${column} IS NOT NULL` } : undefined;
580
+ case "jsonContains": {
581
+ const serialized = JSON.stringify(value).replace(/[%_]/g, "\\$&");
582
+ return { sql: `CAST(${column} AS TEXT) LIKE :${param}`, params: { [param]: `%${serialized}%` } };
583
+ }
584
+ default:
585
+ return undefined;
586
+ }
587
+ }
588
+ splitData(data) {
589
+ const plainData = {};
590
+ const manyRelationData = {};
591
+ for (const [key, value] of Object.entries(data)) {
592
+ const relation = this.getRelation(key);
593
+ if (!relation) {
594
+ plainData[key] = value;
595
+ continue;
596
+ }
597
+ if (relation.isManyToMany || relation.isOneToMany) {
598
+ manyRelationData[key] = value;
599
+ continue;
600
+ }
601
+ const primaryKey = relation.inverseEntityMetadata.primaryColumns[0]?.propertyName || "id";
602
+ plainData[key] = value === null || value === undefined
603
+ ? value
604
+ : { [primaryKey]: normalizeRelationValue(value, primaryKey) };
605
+ }
606
+ return { plainData, manyRelationData };
607
+ }
608
+ async assignManyRelations(entity, relationData) {
609
+ let shouldSaveEntity = false;
610
+ for (const [key, value] of Object.entries(relationData)) {
611
+ const relation = this.getRelation(key);
612
+ if (!relation) {
613
+ continue;
614
+ }
615
+ if (relation.isOneToMany) {
616
+ await this.assignOneToManyRelation(entity, key, value);
617
+ continue;
618
+ }
619
+ if (!relation.isManyToMany) {
620
+ continue;
621
+ }
622
+ const primaryKey = relation.inverseEntityMetadata.primaryColumns[0]?.propertyName || "id";
623
+ entity[key] = Array.isArray(value)
624
+ ? value.map((item) => ({ [primaryKey]: normalizeRelationValue(item, primaryKey) }))
625
+ : [];
626
+ shouldSaveEntity = true;
627
+ }
628
+ return shouldSaveEntity ? this.repository.save(entity) : entity;
629
+ }
630
+ async assignOneToManyRelation(entity, relationName, value) {
631
+ const relation = this.getRelation(relationName);
632
+ const inverseRelation = relation?.inverseRelation;
633
+ if (!relation || !inverseRelation) {
634
+ return;
635
+ }
636
+ const parentId = getPrimaryKeyValue(entity, this.primaryKey);
637
+ const targetPrimaryKey = relation.inverseEntityMetadata.primaryColumns[0]?.propertyName || "id";
638
+ const inverseProperty = inverseRelation.propertyName;
639
+ const targetRepository = this.metadata.connection.getRepository(relation.inverseEntityMetadata.target);
640
+ const selectedIds = Array.isArray(value)
641
+ ? value
642
+ .map((item) => normalizeRelationValue(item, targetPrimaryKey))
643
+ .filter((item) => item !== undefined && item !== null && item !== "")
644
+ : [];
645
+ const selectedIdSet = new Set(selectedIds.map((item) => String(item)));
646
+ const currentChildren = await targetRepository
647
+ .createQueryBuilder("target")
648
+ .leftJoin(`target.${inverseProperty}`, "parent")
649
+ .where(`parent.${this.primaryKey} = :parentId`, { parentId })
650
+ .getMany();
651
+ const childrenToClear = currentChildren.filter((child) => !selectedIdSet.has(String(child[targetPrimaryKey])));
652
+ for (const child of childrenToClear) {
653
+ child[inverseProperty] = null;
654
+ await targetRepository.save(child);
655
+ }
656
+ if (!selectedIds.length) {
657
+ return;
658
+ }
659
+ const selectedChildren = await targetRepository
660
+ .createQueryBuilder("target")
661
+ .where(`target.${targetPrimaryKey} IN (:...ids)`, { ids: selectedIds })
662
+ .getMany();
663
+ for (const child of selectedChildren) {
664
+ child[inverseProperty] = { [this.primaryKey]: parentId };
665
+ await targetRepository.save(child);
666
+ }
667
+ }
668
+ async reloadByPrimaryKey(entity) {
669
+ const primaryValue = getPrimaryKeyValue(entity, this.primaryKey);
670
+ const qb = this.createQueryBuilder();
671
+ this.addAllRelationJoins(qb);
672
+ qb.where(`${ROOT_ALIAS}.${this.primaryKey} = :id`, { id: primaryValue });
673
+ return await qb.getOne();
674
+ }
675
+ async _create(data) {
676
+ const { plainData, manyRelationData } = this.splitData(data);
677
+ if (!plainData[this.primaryKey]) {
678
+ const primary = this.metadata.primaryColumns[0];
679
+ if (primary && resolveAdminizerTypeFromColumn(primary) === "string" && !primary.isGenerated) {
680
+ plainData[this.primaryKey] = uuid();
681
+ }
682
+ }
683
+ let entity = this.repository.create(plainData);
684
+ entity = await this.repository.save(entity);
685
+ if (Object.keys(manyRelationData).length > 0) {
686
+ entity = await this.assignManyRelations(entity, manyRelationData);
687
+ }
688
+ return await this.reloadByPrimaryKey(entity);
689
+ }
690
+ async _findOne(criteria = {}) {
691
+ const qb = this.createQueryBuilder();
692
+ this.applyFindOptions(qb, criteria);
693
+ return await qb.getOne();
694
+ }
695
+ async _find(criteria = {}) {
696
+ const qb = this.createQueryBuilder();
697
+ this.applyFindOptions(qb, criteria);
698
+ return await qb.getMany();
699
+ }
700
+ async _updateOne(criteria, data) {
701
+ const record = await this._findOne(criteria);
702
+ if (!record) {
703
+ return null;
704
+ }
705
+ const { plainData, manyRelationData } = this.splitData(data);
706
+ this.repository.merge(record, plainData);
707
+ let saved = await this.repository.save(record);
708
+ if (Object.keys(manyRelationData).length > 0) {
709
+ saved = await this.assignManyRelations(saved, manyRelationData);
710
+ }
711
+ return await this.reloadByPrimaryKey(saved);
712
+ }
713
+ async _update(criteria, data) {
714
+ const records = await this._find(criteria);
715
+ const updated = [];
716
+ for (const record of records) {
717
+ const updatedRecord = await this._updateOne({ where: { [this.primaryKey]: record[this.primaryKey] } }, data);
718
+ if (updatedRecord) {
719
+ updated.push(updatedRecord);
720
+ }
721
+ }
722
+ return updated;
723
+ }
724
+ async _destroyOne(criteria) {
725
+ const record = await this._findOne(criteria);
726
+ if (!record) {
727
+ return null;
728
+ }
729
+ await this.repository.remove(record);
730
+ return record;
731
+ }
732
+ async _destroy(criteria) {
733
+ const records = await this._find(criteria);
734
+ if (!records.length) {
735
+ return [];
736
+ }
737
+ await this.repository.remove(records);
738
+ return records;
739
+ }
740
+ async _count(criteria = {}) {
741
+ const qb = this.createQueryBuilder();
742
+ const options = this.normalizeCriteria(criteria);
743
+ const aliases = this.addRequestedRelations(qb, criteria.populate);
744
+ if (this.isNativeWhere(options.where) || Object.keys(options.where).length > 0) {
745
+ this.applyWhere(qb, options.where, ROOT_ALIAS, aliases);
746
+ }
747
+ return await qb.getCount();
748
+ }
749
+ }
750
+ export class TypeOrmAdapter extends AbstractAdapter {
751
+ dataSource;
752
+ Model = TypeOrmModel;
753
+ constructor(dataSource) {
754
+ super("typeorm", dataSource);
755
+ this.dataSource = dataSource;
756
+ }
757
+ get models() {
758
+ return this.dataSource.entityMetadatas.reduce((acc, metadata) => {
759
+ acc[metadata.name] = metadata;
760
+ return acc;
761
+ }, {});
762
+ }
763
+ getModel(modelName) {
764
+ return this.dataSource.entityMetadatas.find((metadata) => metadata.name.toLowerCase() === modelName.toLowerCase() ||
765
+ metadata.tableName.toLowerCase() === modelName.toLowerCase());
766
+ }
767
+ getAttributes(modelName) {
768
+ const model = this.getModel(modelName);
769
+ return model ? mapTypeOrmToAdminizerAttributes(model) : undefined;
770
+ }
771
+ static createEntitySchema(modelName, schema, allSchemas = { [modelName]: schema }) {
772
+ return createTypeOrmEntitySchemaFromAdminizerSchema(modelName, schema, allSchemas);
773
+ }
774
+ static async loadSystemEntities() {
775
+ return await loadSystemTypeOrmEntities();
776
+ }
777
+ }