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
@@ -1,4 +1,4 @@
1
- import { DataTypes, Op } from "sequelize";
1
+ import { Sequelize, DataTypes, Op, HasMany } from "sequelize";
2
2
  import { AbstractAdapter, AbstractModel } from "../AbstractModel.js";
3
3
  import path from "path";
4
4
  import fs from "fs";
@@ -64,10 +64,15 @@ function generateAssociationsFromSchema(models, schemas) {
64
64
  if (model.rawAttributes[alias] || model.associations[alias]) {
65
65
  asName = `${alias}Ref`;
66
66
  }
67
- model.belongsTo(targetModel, {
67
+ const belongsToOptions = {
68
68
  as: asName,
69
69
  foreignKey,
70
- });
70
+ };
71
+ // Add onDelete constraint if specified
72
+ if (field.onDelete) {
73
+ belongsToOptions.onDelete = field.onDelete;
74
+ }
75
+ model.belongsTo(targetModel, belongsToOptions);
71
76
  }
72
77
  }
73
78
  }
@@ -76,19 +81,24 @@ function resolveType(type) {
76
81
  const sqlType = typeof type.toString === "function"
77
82
  ? type.toString().toLowerCase()
78
83
  : "";
79
- if (sqlType.includes("string") || sqlType.includes("uuid"))
84
+ if (sqlType.includes("string") ||
85
+ sqlType.includes("uuid") ||
86
+ sqlType.includes("char") ||
87
+ sqlType.includes("text")) {
80
88
  return "string";
89
+ }
90
+ // tinyint(1) is used by MySQL/MariaDB for BOOLEAN
91
+ if (sqlType.includes("bool") || sqlType === "tinyint(1)")
92
+ return "boolean";
81
93
  if (sqlType.includes("int") || sqlType.includes("float") || sqlType.includes("decimal"))
82
94
  return "number";
83
- if (sqlType.includes("bool"))
84
- return "boolean";
85
95
  if (sqlType.includes("json"))
86
96
  return "json";
87
97
  if (sqlType.includes("date"))
88
98
  return "string";
89
99
  return "ref";
90
100
  }
91
- export function mapSequelizeToWaterline(model) {
101
+ export function mapSequelizeToAdminizerAttributes(model) {
92
102
  const result = {};
93
103
  const rawAttrs = model.getAttributes();
94
104
  for (const name in rawAttrs) {
@@ -155,61 +165,233 @@ function capitalize(str) {
155
165
  export class SequelizeModel extends AbstractModel {
156
166
  model;
157
167
  constructor(modelName, model) {
158
- super(modelName, mapSequelizeToWaterline(model), model.primaryKeyAttribute, model.name);
168
+ super(modelName, mapSequelizeToAdminizerAttributes(model), model.primaryKeyAttribute, model.name);
159
169
  this.model = model;
160
170
  }
171
+ _buildJsonContainsCondition(targetKey, item) {
172
+ const pattern = `%${JSON.stringify(item).replace(/[%_]/g, "\\$&")}%`;
173
+ const attribute = this.model.rawAttributes?.[targetKey];
174
+ const columnName = typeof attribute?.field === "string" ? attribute.field : targetKey;
175
+ return Sequelize.where(Sequelize.cast(Sequelize.col(`${this.model.name}.${columnName}`), "TEXT"), { [Op.like]: pattern });
176
+ }
161
177
  _convertCriteriaToSequelize(criteria) {
178
+ // Special handling for Sequelize.literal() at the top level
179
+ if (criteria && typeof criteria === 'object' && 'val' in criteria && typeof criteria.val === 'string') {
180
+ // This is a Sequelize.literal object, return it as-is
181
+ return criteria;
182
+ }
162
183
  const result = {};
163
- for (const key in criteria) {
184
+ // Handle both string keys and Symbol keys (Op.and, Op.or, etc.)
185
+ const allKeys = [
186
+ ...Object.keys(criteria),
187
+ ...Object.getOwnPropertySymbols(criteria)
188
+ ];
189
+ for (const key of allKeys) {
164
190
  const value = criteria[key];
165
- if (value === undefined ||
166
- (typeof value === "object" && value !== null && Object.keys(value).length === 0)) {
167
- continue;
168
- }
169
- // 🧠 Replace the key with `via` if this is an association
170
- const attr = this.attributes?.[key];
191
+ // 🧠 Replace the key with `via` if this is an association (MUST happen before null/other checks)
171
192
  let targetKey = key;
172
- if (attr?.type === "association" && attr.via) {
173
- targetKey = attr.via;
193
+ // Only process string keys for association replacement
194
+ if (typeof key === 'string') {
195
+ const attr = this.attributes?.[key];
196
+ // Check if this is an association attribute (either from attributes or model.associations)
197
+ if (attr?.type === "association" && attr.via) {
198
+ targetKey = attr.via;
199
+ }
200
+ else if (this.model.associations[key]) {
201
+ // Fallback: check associations directly
202
+ const assoc = this.model.associations[key];
203
+ if (assoc && 'foreignKey' in assoc) {
204
+ targetKey = assoc.foreignKey;
205
+ }
206
+ }
174
207
  }
208
+ // Special handling for null values (IS NULL condition)
175
209
  if (value === null) {
176
210
  result[targetKey] = { [Op.is]: null };
211
+ continue;
212
+ }
213
+ // 🔹 Handle Sequelize Op operators (already in Sequelize format)
214
+ if (key === Op.and || key === 'and') {
215
+ result[Op.and] = Array.isArray(value)
216
+ ? value.map((item) => this._convertCriteriaToSequelize(item))
217
+ : [];
218
+ continue;
219
+ }
220
+ if (key === Op.or || key === 'or') {
221
+ result[Op.or] = Array.isArray(value)
222
+ ? value.map((item) => this._convertCriteriaToSequelize(item))
223
+ : [];
224
+ continue;
225
+ }
226
+ if (key === Op.not || key === 'not' || key === '$not') {
227
+ result[Op.not] = this._convertCriteriaToSequelize(value);
228
+ continue;
177
229
  }
178
- else if (Array.isArray(value)) {
230
+ // Skip Symbol keys that are not handled above (should not happen, but safety check)
231
+ if (typeof key === 'symbol') {
232
+ continue;
233
+ }
234
+ if (Array.isArray(value)) {
179
235
  // ✅ Array processing - use the IN operator
180
236
  result[targetKey] = { [Op.in]: value };
181
237
  }
182
238
  else if (typeof value === "object" && !Array.isArray(value)) {
183
- const operatorEntries = Object.entries(value)
184
- .filter(([_, v]) => v !== undefined && v !== null)
185
- .map(([op, val]) => {
239
+ // Check if value already contains Sequelize Op operators
240
+ // Need to check both string keys and Symbol keys
241
+ const valueKeys = Object.keys(value);
242
+ const valueSymbols = Object.getOwnPropertySymbols(value);
243
+ // Helper function to check if a symbol/op is a Sequelize operator
244
+ const isSequelizeOp = (op) => {
245
+ // Check direct Symbol equality first
246
+ if (op === Op.gt || op === Op.gte || op === Op.lt || op === Op.lte ||
247
+ op === Op.eq || op === Op.ne || op === Op.in || op === Op.notIn ||
248
+ op === Op.like || op === Op.iLike || op === Op.between ||
249
+ op === Op.startsWith || op === Op.endsWith || op === Op.is || op === Op.not) {
250
+ return true;
251
+ }
252
+ // Fallback: check by Symbol description (handles different Symbol instances)
253
+ if (typeof op === 'symbol') {
254
+ const desc = op.description || op.toString();
255
+ return desc.includes('gt') || desc.includes('gte') || desc.includes('lt') || desc.includes('lte') ||
256
+ desc.includes('eq') || desc.includes('ne') || desc.includes('in') || desc.includes('notIn') ||
257
+ desc.includes('like') || desc.includes('iLike') || desc.includes('between') ||
258
+ desc.includes('startsWith') || desc.includes('endsWith') || desc.includes('is') || desc.includes('not');
259
+ }
260
+ // Check string operators used by Adminizer's adapter-neutral criteria format
261
+ return op === '$gt' || op === '$gte' || op === '$lt' || op === '$lte' ||
262
+ op === '$eq' || op === '$ne' || op === '$in' || op === '$notIn' ||
263
+ op === '$like' || op === '$iLike' || op === '$between' ||
264
+ op === '$startsWith' || op === '$endsWith' || op === '$is' || op === '$not' ||
265
+ op === 'not';
266
+ };
267
+ const hasSequelizeOp = [...valueKeys, ...valueSymbols].some(isSequelizeOp);
268
+ // If already Sequelize format, pass through
269
+ if (hasSequelizeOp) {
270
+ result[targetKey] = value;
271
+ continue;
272
+ }
273
+ // Handle operator objects like {contains: 'val'} from Adminizer's criteria format
274
+ for (const [op, val] of Object.entries(value)) {
275
+ if (val === undefined || val === null)
276
+ continue;
186
277
  switch (op) {
278
+ case "eq":
279
+ result[targetKey] = { [Op.eq]: val };
280
+ break;
281
+ case "ne":
282
+ result[targetKey] = { [Op.ne]: val };
283
+ break;
284
+ case "gt":
285
+ result[targetKey] = { [Op.gt]: val };
286
+ break;
287
+ case "gte":
288
+ result[targetKey] = { [Op.gte]: val };
289
+ break;
290
+ case "lt":
291
+ result[targetKey] = { [Op.lt]: val };
292
+ break;
293
+ case "lte":
294
+ result[targetKey] = { [Op.lte]: val };
295
+ break;
187
296
  case "contains":
188
- return [Op.like, `%${val}%`];
297
+ // Check if field is a date/datetime type
298
+ const attr = this.model.rawAttributes?.[targetKey];
299
+ const typeName = attr?.type;
300
+ // Check type name (works for DATE, DATEONLY, TIME, etc.)
301
+ const typeStr = typeof typeName === 'function'
302
+ ? typeName.name.toLowerCase()
303
+ : String(typeName).toLowerCase();
304
+ const isDateType = typeStr.includes('date') || typeStr.includes('time');
305
+ // TIME type should use LIKE (it's stored as 'HH:MM' string)
306
+ const isTimeType = typeStr === 'time';
307
+ if (isDateType && !isTimeType) {
308
+ // For date fields (not time), check if value is a valid date
309
+ const dateValue = new Date(String(val));
310
+ if (isNaN(dateValue.getTime())) {
311
+ // Invalid date string - skip this condition entirely
312
+ // This prevents moment.js warnings
313
+ // Don't add anything to result - field will be excluded from WHERE
314
+ }
315
+ else {
316
+ // Valid date - use exact match
317
+ result[targetKey] = { [Op.eq]: dateValue };
318
+ }
319
+ }
320
+ else {
321
+ // For time fields and non-date fields - use Op.like with wildcards
322
+ result[targetKey] = { [Op.like]: `%${val}%` };
323
+ }
324
+ break;
189
325
  case "startsWith":
190
- return [Op.startsWith, val];
326
+ result[targetKey] = { [Op.startsWith]: val };
327
+ break;
191
328
  case "endsWith":
192
- return [Op.endsWith, val];
329
+ result[targetKey] = { [Op.endsWith]: val };
330
+ break;
193
331
  case ">":
194
- return [Op.gt, val];
332
+ result[targetKey] = { [Op.gt]: val };
333
+ break;
195
334
  case ">=":
196
- return [Op.gte, val];
335
+ result[targetKey] = { [Op.gte]: val };
336
+ break;
197
337
  case "<":
198
- return [Op.lt, val];
338
+ result[targetKey] = { [Op.lt]: val };
339
+ break;
199
340
  case "<=":
200
- return [Op.lte, val];
341
+ result[targetKey] = { [Op.lte]: val };
342
+ break;
201
343
  case "!=":
202
- return [Op.ne, val];
344
+ result[targetKey] = { [Op.ne]: val };
345
+ break;
203
346
  case "in":
204
- return [Op.in, val];
347
+ result[targetKey] = { [Op.in]: val };
348
+ break;
349
+ case "notIn":
350
+ result[targetKey] = { [Op.notIn]: val };
351
+ break;
205
352
  case "nin":
206
- return [Op.notIn, val];
353
+ result[targetKey] = { [Op.notIn]: val };
354
+ break;
355
+ case "between":
356
+ result[targetKey] = { [Op.between]: val };
357
+ break;
358
+ case "isNull":
359
+ if (val) {
360
+ result[targetKey] = { [Op.is]: null };
361
+ }
362
+ break;
363
+ case "isNotNull":
364
+ if (val) {
365
+ result[targetKey] = { [Op.not]: null };
366
+ }
367
+ break;
368
+ case "regex":
369
+ result[targetKey] = { [Op.regexp]: val };
370
+ break;
371
+ case "jsonContains": {
372
+ const values = Array.isArray(val) ? val : [val];
373
+ const clauses = values.map((item) => this._buildJsonContainsCondition(targetKey, item));
374
+ result[Op.and] = [
375
+ ...(result[Op.and] ?? []),
376
+ ...clauses
377
+ ];
378
+ break;
379
+ }
380
+ case "$is":
381
+ result[targetKey] = { [Op.is]: val };
382
+ break;
383
+ case "$not":
384
+ result[targetKey] = { [Op.not]: val };
385
+ break;
386
+ case "$ne":
387
+ result[targetKey] = { [Op.ne]: val };
388
+ break;
389
+ case "not":
390
+ result[targetKey] = { [Op.not]: val };
391
+ break;
207
392
  default:
208
- return [Op.eq, val];
393
+ result[targetKey] = { [Op.eq]: val };
209
394
  }
210
- });
211
- if (operatorEntries.length > 0) {
212
- result[targetKey] = Object.fromEntries(operatorEntries);
213
395
  }
214
396
  }
215
397
  else {
@@ -218,13 +400,23 @@ export class SequelizeModel extends AbstractModel {
218
400
  }
219
401
  return result;
220
402
  }
221
- _convertWaterlineCriteriaToSequelizeOptions(criteria) {
222
- // console.debug("WATERLINE CRITERIA (raw):", criteria);
223
- const { where: nestedWhere, skip, limit, sort, ...rest } = criteria;
224
- const rawWhere = (nestedWhere && Object.keys(nestedWhere).length > 0)
225
- ? nestedWhere
226
- : rest;
227
- // console.debug("WATERLINE CRITERIA: using rawWhere =", rawWhere);
403
+ _convertAdminizerCriteriaToSequelizeOptions(criteria) {
404
+ // For Sequelize: extract adapter-neutral pagination and ordering params.
405
+ // Everything else is WHERE criteria.
406
+ // 'sort' as string = ordering ("field direction") goes to ORDER BY
407
+ // 'sort' as boolean/object = model field — goes to WHERE
408
+ const criteriaSortValue = 'sort' in criteria ? criteria.sort : undefined;
409
+ const isOrderingSort = typeof criteriaSortValue === 'string';
410
+ const { where: nestedWhere, skip, limit, sort: criteriaSort, select, populate, ...rest } = criteria;
411
+ // If 'sort' is a model field (not an ordering string), put it back
412
+ if (!isOrderingSort && criteriaSortValue !== undefined) {
413
+ rest.sort = criteriaSortValue;
414
+ }
415
+ // Check if nestedWhere has any keys (including Symbol keys like Op.and)
416
+ const hasNestedWhereKeys = nestedWhere && (Object.keys(nestedWhere).length > 0 ||
417
+ Object.getOwnPropertySymbols(nestedWhere).length > 0);
418
+ // If there's an explicit 'where' key, use it. Otherwise use rest (field conditions).
419
+ const rawWhere = hasNestedWhereKeys ? nestedWhere : rest;
228
420
  const where = this._convertCriteriaToSequelize(rawWhere);
229
421
  const result = { where };
230
422
  if (typeof skip === "number") {
@@ -235,11 +427,21 @@ export class SequelizeModel extends AbstractModel {
235
427
  result.limit = limit;
236
428
  // console.debug("→ limit =", limit);
237
429
  }
238
- if (typeof sort === "string") {
239
- const [field, dir] = sort.trim().split(/\s+/);
430
+ if (typeof criteriaSort === "string") {
431
+ const [field, dir] = criteriaSort.trim().split(/\s+/);
240
432
  result.order = [[field, dir?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
241
433
  // console.debug("→ order =", result.order);
242
434
  }
435
+ else if (criteriaSort && typeof criteriaSort === "object") {
436
+ result.order = Object.entries(criteriaSort).map(([field, dir]) => [
437
+ field,
438
+ String(dir).toUpperCase() === "DESC" ? "DESC" : "ASC"
439
+ ]);
440
+ }
441
+ const attributes = this._buildAttributes(select);
442
+ if (attributes) {
443
+ result.attributes = attributes;
444
+ }
243
445
  return result;
244
446
  }
245
447
  async _assignAssociations(instance, assocData) {
@@ -293,8 +495,6 @@ export class SequelizeModel extends AbstractModel {
293
495
  plainData[key] = val;
294
496
  }
295
497
  }
296
- console.debug(">> Normal fields for create():", JSON.stringify(plainData));
297
- console.debug(">> Association data:", JSON.stringify(assocData));
298
498
  let instance;
299
499
  try {
300
500
  instance = await this.model.create(plainData);
@@ -345,13 +545,15 @@ export class SequelizeModel extends AbstractModel {
345
545
  // --- FIND ONE ---
346
546
  async _findOne(criteria) {
347
547
  // console.debug(">> _findOne: input criteria:", criteria);
348
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
349
- const includes = this._buildIncludes();
548
+ const { where, attributes } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
549
+ const includes = criteria.populate
550
+ ? this._buildCriteriaIncludes(criteria.populate)
551
+ : this._buildIncludes();
350
552
  // console.debug(">> _findOne: converted where:", where);
351
553
  // console.debug(">> _findOne: includes:", includes);
352
554
  let instance = null;
353
555
  try {
354
- instance = await this.model.findOne({ where, include: includes });
556
+ instance = await this.model.findOne({ where, attributes, include: includes });
355
557
  // console.debug(">> _findOne: raw instance:", instance ? instance.toJSON() : null);
356
558
  }
357
559
  catch (err) {
@@ -367,13 +569,17 @@ export class SequelizeModel extends AbstractModel {
367
569
  return plain;
368
570
  }
369
571
  // --- FIND MANY ---
370
- async _find(criteria = {}, options = {}) {
572
+ async _find(criteria = {}) {
371
573
  const assocNames = Object.keys(this.model.associations);
372
574
  // console.debug(">> _find: input criteria:", criteria, "options:", options);
373
- const { where, limit, offset, order } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
374
- const includes = options.populate
375
- ? options.populate.map(([field, opts]) => ({ association: field, ...opts }))
376
- : assocNames.map(a => ({ association: a }));
575
+ const { where, limit, offset, order, attributes } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
576
+ const hasRelationPathCondition = this._hasRelationPathCondition(where);
577
+ const usedRelationAliases = hasRelationPathCondition
578
+ ? this._extractRelationAliasesFromWhere(where)
579
+ : new Set();
580
+ const includes = criteria.populate
581
+ ? this._buildCriteriaIncludes(criteria.populate)
582
+ : assocNames.map((alias) => this._buildListInclude(alias, usedRelationAliases, hasRelationPathCondition));
377
583
  // console.debug(">> _find: where, limit, offset, order, includes:", {
378
584
  // where,
379
585
  // limit,
@@ -384,10 +590,12 @@ export class SequelizeModel extends AbstractModel {
384
590
  let instances;
385
591
  instances = await this.model.findAll({
386
592
  where,
593
+ attributes,
387
594
  limit,
388
595
  offset,
389
596
  order,
390
- include: includes
597
+ include: includes,
598
+ subQuery: hasRelationPathCondition ? false : undefined
391
599
  });
392
600
  for (const inst of instances) {
393
601
  //For each association, we call getxxx () once again
@@ -412,9 +620,40 @@ export class SequelizeModel extends AbstractModel {
412
620
  // console.debug(">> _find: plain results:", plain);
413
621
  return plain;
414
622
  }
623
+ /**
624
+ * Public method for raw SQL where clauses (Sequelize.literal support)
625
+ * Bypasses Adminizer criteria conversion for direct Sequelize usage
626
+ */
627
+ async findWithRawWhere(where, options = {}) {
628
+ const assocNames = Object.keys(this.model.associations);
629
+ const includes = options.populate !== false
630
+ ? assocNames.map(a => ({ association: a }))
631
+ : [];
632
+ const instances = await this.model.findAll({
633
+ where,
634
+ limit: options.limit,
635
+ offset: options.offset,
636
+ order: options.order,
637
+ include: includes
638
+ });
639
+ return instances.map(i => i.get({ plain: true }));
640
+ }
641
+ /**
642
+ * Public method for count with raw SQL where clauses
643
+ */
644
+ async countWithRawWhere(where) {
645
+ const assocNames = Object.keys(this.model.associations);
646
+ const include = assocNames.map((association) => ({ association }));
647
+ return await this.model.count({
648
+ where,
649
+ include,
650
+ distinct: true,
651
+ col: this.primaryKey || this.model.primaryKeyAttribute || 'id'
652
+ });
653
+ }
415
654
  // --- UPDATE ONE ---
416
655
  async _updateOne(criteria, data) {
417
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
656
+ const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
418
657
  const record = await this.model.findOne({ where });
419
658
  if (!record)
420
659
  return null;
@@ -445,7 +684,7 @@ export class SequelizeModel extends AbstractModel {
445
684
  }
446
685
  // --- UPDATE MANY ---
447
686
  async _update(criteria, data) {
448
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
687
+ const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
449
688
  const assocNames = Object.keys(this.model.associations);
450
689
  const plainData = {};
451
690
  const assocData = {};
@@ -479,7 +718,7 @@ export class SequelizeModel extends AbstractModel {
479
718
  }
480
719
  // --- DESTROY ONE ---
481
720
  async _destroyOne(criteria) {
482
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
721
+ const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
483
722
  const record = await this.model.findOne({ where });
484
723
  if (!record)
485
724
  return null;
@@ -514,7 +753,7 @@ export class SequelizeModel extends AbstractModel {
514
753
  }
515
754
  // --- DESTROY MANY ---
516
755
  async _destroy(criteria) {
517
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
756
+ const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
518
757
  const records = await this.model.findAll({ where });
519
758
  const assocNames = Object.keys(this.model.associations);
520
759
  for (const record of records) {
@@ -551,14 +790,122 @@ export class SequelizeModel extends AbstractModel {
551
790
  }
552
791
  // --- COUNT ---
553
792
  async _count(criteria = {}) {
554
- const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
555
- const result = await this.model.count({ where });
793
+ const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
794
+ const assocNames = Object.keys(this.model.associations);
795
+ const include = assocNames.map((association) => ({ association }));
796
+ const result = await this.model.count({
797
+ where,
798
+ include,
799
+ distinct: true,
800
+ col: this.primaryKey || this.model.primaryKeyAttribute || 'id'
801
+ });
556
802
  return result;
557
803
  }
558
804
  // --- HELPER ---
805
+ _hasRelationPathCondition(input) {
806
+ if (!input || typeof input !== 'object') {
807
+ return false;
808
+ }
809
+ if (Array.isArray(input)) {
810
+ return input.some((item) => this._hasRelationPathCondition(item));
811
+ }
812
+ const keys = [
813
+ ...Object.keys(input),
814
+ ...Object.getOwnPropertySymbols(input)
815
+ ];
816
+ for (const key of keys) {
817
+ if (typeof key === 'string' && /^\$[A-Za-z0-9_]+\.[A-Za-z0-9_]+\$$/.test(key)) {
818
+ return true;
819
+ }
820
+ const value = input[key];
821
+ if (value && typeof value === 'object' && this._hasRelationPathCondition(value)) {
822
+ return true;
823
+ }
824
+ }
825
+ return false;
826
+ }
827
+ _extractRelationAliasesFromWhere(input, aliases = new Set()) {
828
+ if (!input || typeof input !== 'object') {
829
+ return aliases;
830
+ }
831
+ if (Array.isArray(input)) {
832
+ input.forEach((item) => this._extractRelationAliasesFromWhere(item, aliases));
833
+ return aliases;
834
+ }
835
+ const keys = [
836
+ ...Object.keys(input),
837
+ ...Object.getOwnPropertySymbols(input)
838
+ ];
839
+ for (const key of keys) {
840
+ if (typeof key === 'string') {
841
+ const match = key.match(/^\$([A-Za-z0-9_]+)\.[A-Za-z0-9_]+\$$/);
842
+ if (match?.[1]) {
843
+ aliases.add(match[1]);
844
+ }
845
+ }
846
+ const value = input[key];
847
+ if (value && typeof value === 'object') {
848
+ this._extractRelationAliasesFromWhere(value, aliases);
849
+ }
850
+ }
851
+ return aliases;
852
+ }
853
+ _buildListInclude(alias, usedRelationAliases, hasRelationPathCondition) {
854
+ const include = { association: alias };
855
+ if (!hasRelationPathCondition) {
856
+ return include;
857
+ }
858
+ const association = this.model.associations[alias];
859
+ const isUsedInWhere = usedRelationAliases.has(alias);
860
+ const isHasMany = association instanceof HasMany || association?.associationType === 'HasMany';
861
+ // When filtering by relation path ($alias.field$), extra joined hasMany associations
862
+ // can duplicate base rows and break page size. Load such associations separately.
863
+ if (isHasMany && !isUsedInWhere) {
864
+ include.separate = true;
865
+ }
866
+ return include;
867
+ }
559
868
  _buildIncludes() {
560
869
  return Object.keys(this.model.associations).map(key => ({ association: key }));
561
870
  }
871
+ _buildAttributes(select) {
872
+ if (!select) {
873
+ return undefined;
874
+ }
875
+ if (Array.isArray(select)) {
876
+ const attributes = select.filter((field) => this.model.rawAttributes?.[field]);
877
+ return attributes.length ? attributes : undefined;
878
+ }
879
+ const attributes = Object.entries(select)
880
+ .filter(([field, enabled]) => enabled && this.model.rawAttributes?.[field])
881
+ .map(([field]) => field);
882
+ return attributes.length ? attributes : undefined;
883
+ }
884
+ _buildCriteriaIncludes(populate) {
885
+ return Object.entries(populate).map(([association, nestedCriteria]) => {
886
+ if (nestedCriteria === true) {
887
+ return { association };
888
+ }
889
+ const { where, attributes, order, limit, } = this._convertAdminizerCriteriaToSequelizeOptions(nestedCriteria);
890
+ const include = { association };
891
+ if (where && (Object.keys(where).length > 0 || Object.getOwnPropertySymbols(where).length > 0)) {
892
+ include.where = where;
893
+ }
894
+ if (attributes) {
895
+ include.attributes = attributes;
896
+ }
897
+ if (order) {
898
+ include.order = order;
899
+ }
900
+ if (typeof limit === "number") {
901
+ include.limit = limit;
902
+ }
903
+ if (nestedCriteria.populate) {
904
+ include.include = this._buildCriteriaIncludes(nestedCriteria.populate);
905
+ }
906
+ return include;
907
+ });
908
+ }
562
909
  }
563
910
  export class SequelizeAdapter extends AbstractAdapter {
564
911
  sequelize;
@@ -629,7 +976,7 @@ export class SequelizeAdapter extends AbstractAdapter {
629
976
  }
630
977
  }
631
978
  }
632
- /**Generation of the SEQUELIZE model from the definition, analogue of Waterinecollection.extenD*/
979
+ /** Generation of the Sequelize model from Adminizer's model definition */
633
980
  function generateSequelizeModel(sequelize, modelName, rawAttributes) {
634
981
  const attributes = {};
635
982
  let primaryKey = null;