adminizer 4.7.0-build.224 → 5.0.0-build.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/Readme.md +2 -1
  2. package/assets/add-De0wyF0A.js +1 -0
  3. package/assets/add-group-CMWybgIR.js +1 -0
  4. package/assets/add-user-BxP23daH.js +1 -0
  5. package/assets/app-CtWuWD5N.css +1 -0
  6. package/assets/app-layout-GYMU2HO1.js +1 -0
  7. package/assets/app.js +45 -50
  8. package/assets/catalog-tImW1BnS.js +6 -0
  9. package/assets/controls/chunks/_commonjsHelpers-C6fGbg64.js +6 -0
  10. package/assets/controls/chunks/index-CjiZ2FIa.js +93 -0
  11. package/assets/controls/chunks/jsx-runtime-jIxVPx5o.js +31 -0
  12. package/assets/controls/chunks/use-appearance-CFLOwiSX.js +38 -0
  13. package/assets/controls/chunks/use-window-size-BXgBKW65.js +19 -0
  14. package/assets/controls/chunks/vanilla-picker-Dg97NL4h.js +529 -0
  15. package/assets/controls/ckeditor.es.js +83683 -0
  16. package/assets/controls/handsontable.css +1 -0
  17. package/assets/controls/handsontable.es.js +70585 -0
  18. package/assets/controls/jsoneditor.css +1 -0
  19. package/assets/controls/jsoneditor.es.js +42082 -0
  20. package/assets/controls/leaflet.css +1 -0
  21. package/assets/controls/leaflet.es.js +10299 -0
  22. package/assets/controls/monaco.es.js +618 -0
  23. package/assets/controls/toast-ui.css +1 -0
  24. package/assets/controls/toast-ui.es.js +41797 -0
  25. package/assets/dashboard-CQ4atH3N.js +3 -0
  26. package/assets/debounce-BMmXVQ06.js +1 -0
  27. package/assets/history-BileQPEi.js +1 -0
  28. package/assets/init-user-8aUohVDq.js +1 -0
  29. package/assets/list-Pz_5mfSq.js +4 -0
  30. package/assets/login-CO4laf6m.js +1 -0
  31. package/assets/manifest.json +66 -602
  32. package/assets/media-manager-BDbpSSjH.js +6 -0
  33. package/assets/media-manager-BZPjl98I.css +1 -0
  34. package/assets/module-CQiOdgZN.js +1 -0
  35. package/assets/notification-BIyv1smE.js +20 -0
  36. package/assets/register-DBYIMXGQ.js +1 -0
  37. package/assets/ru-rYKdQbWF.js +1 -0
  38. package/assets/use-appearance-_EbbjHTh.js +1 -0
  39. package/assets/user-filters-list-Aq8CvCeh.js +1 -0
  40. package/assets/welcome-DxhWYzUL.js +1 -0
  41. package/controllers/add.d.ts +1 -1
  42. package/controllers/addGroup.js +3 -3
  43. package/controllers/addUser.js +3 -3
  44. package/controllers/catalog/Catalog.d.ts +1 -1
  45. package/controllers/catalog/Catalog.js +2 -1
  46. package/controllers/catalog/FrontendCatalogAdapter.d.ts +2 -12
  47. package/controllers/catalog/FrontendCatalogAdapter.js +3 -16
  48. package/controllers/catalog/FrontentCatalogAdapter.d.ts +2 -12
  49. package/controllers/catalog/FrontentCatalogAdapter.js +0 -16
  50. package/controllers/edit.js +6 -11
  51. package/controllers/editGroup.d.ts +1 -1
  52. package/controllers/editGroup.js +3 -3
  53. package/controllers/editUser.d.ts +1 -1
  54. package/controllers/editUser.js +3 -3
  55. package/controllers/feed.js +1 -1
  56. package/controllers/filter-fields/columns.js +1 -1
  57. package/controllers/filter-fields/getAllUserFilters.js +2 -2
  58. package/controllers/filter-fields/groups.js +2 -2
  59. package/controllers/filter-fields/savedFilters.js +1 -1
  60. package/controllers/history-actions/HistoryController.js +1 -1
  61. package/controllers/initUser.js +2 -2
  62. package/controllers/list.d.ts +1 -1
  63. package/controllers/login.d.ts +1 -1
  64. package/controllers/login.js +3 -3
  65. package/controllers/media-manager/ThumbController.js +2 -2
  66. package/controllers/media-manager/mediaManagerApi.js +13 -15
  67. package/controllers/register.d.ts +1 -1
  68. package/controllers/register.js +5 -5
  69. package/controllers/remove.d.ts +1 -1
  70. package/controllers/userApiKey.js +2 -2
  71. package/controllers/view.d.ts +1 -1
  72. package/controllers/view.js +5 -5
  73. package/controllers/widgets/Action.js +5 -2
  74. package/controllers/widgets/filterInfo.js +1 -1
  75. package/files/favicon.png +0 -0
  76. package/helpers/accessRightsHelper.d.ts +6 -4
  77. package/helpers/accessRightsHelper.js +13 -0
  78. package/helpers/diffHelpers.js +1 -1
  79. package/helpers/fieldsHelper.d.ts +1 -1
  80. package/helpers/fieldsHelper.js +8 -4
  81. package/helpers/filterDatetimeHelper.d.ts +1 -1
  82. package/helpers/inertiaAddHelper.d.ts +6 -5
  83. package/helpers/inertiaAddHelper.js +45 -37
  84. package/helpers/inertiaAutHelper.js +5 -5
  85. package/helpers/inertiaGroupHelper.d.ts +4 -4
  86. package/helpers/inertiaMenuHelper.js +1 -1
  87. package/helpers/inertiaUserHelper.d.ts +3 -3
  88. package/helpers/inertiaUserHelper.js +1 -1
  89. package/helpers/menuHelper.d.ts +2 -2
  90. package/index.d.ts +19 -6
  91. package/index.js +19 -6
  92. package/interfaces/adminpanelConfig.d.ts +10 -33
  93. package/interfaces/global.d.ts +10 -15
  94. package/interfaces/listQueryBuilder.d.ts +1 -1
  95. package/lib/Adminizer.d.ts +25 -2
  96. package/lib/Adminizer.js +124 -50
  97. package/lib/DataAccessor.d.ts +9 -5
  98. package/lib/DataAccessor.js +89 -42
  99. package/lib/access-rights/AccessRightsHandler.d.ts +17 -0
  100. package/lib/access-rights/AccessRightsHandler.js +63 -0
  101. package/lib/ai-assistant/AbstractAiModelService.d.ts +5 -8
  102. package/lib/ai-assistant/AbstractAiModelService.js +3 -14
  103. package/lib/ai-assistant/AiAssistantHandler.d.ts +2 -2
  104. package/lib/app-manager/AdminizerApp.d.ts +228 -0
  105. package/lib/app-manager/AdminizerApp.js +17 -0
  106. package/lib/app-manager/AppManager.d.ts +18 -0
  107. package/lib/app-manager/AppManager.js +537 -0
  108. package/lib/app-manager/AssetHandler.d.ts +17 -0
  109. package/lib/app-manager/AssetHandler.js +67 -0
  110. package/lib/app-manager/ConfigLayerHandler.d.ts +18 -0
  111. package/lib/app-manager/ConfigLayerHandler.js +119 -0
  112. package/lib/app-manager/ControllerHandler.d.ts +25 -0
  113. package/lib/app-manager/ControllerHandler.js +140 -0
  114. package/lib/catalog/AbstractCatalog.d.ts +28 -19
  115. package/lib/catalog/AbstractCatalog.js +41 -10
  116. package/lib/catalog/CatalogHandler.d.ts +13 -0
  117. package/lib/catalog/CatalogHandler.js +48 -2
  118. package/lib/catalog/CatalogTemplateComponentHandler.d.ts +23 -0
  119. package/lib/catalog/CatalogTemplateComponentHandler.js +59 -0
  120. package/lib/controls/Control.d.ts +17 -0
  121. package/lib/controls/Control.js +1 -0
  122. package/lib/controls/ControlsHandler.d.ts +5 -6
  123. package/lib/controls/ControlsHandler.js +0 -13
  124. package/lib/controls/codeEditor/MonacoEditor.d.ts +3 -4
  125. package/lib/controls/codeEditor/MonacoEditor.js +13 -8
  126. package/lib/controls/geojsoneditor/GeoEditor.d.ts +3 -4
  127. package/lib/controls/geojsoneditor/GeoEditor.js +14 -9
  128. package/lib/controls/jsoneditor/JsonEditor.d.ts +5 -6
  129. package/lib/controls/jsoneditor/JsonEditor.js +14 -13
  130. package/lib/controls/markdown/ToastUiEditor.d.ts +5 -6
  131. package/lib/controls/markdown/ToastUiEditor.js +14 -13
  132. package/lib/controls/table/Handsontable.d.ts +5 -6
  133. package/lib/controls/table/Handsontable.js +14 -13
  134. package/lib/controls/wysiwyg/CKeditor.d.ts +5 -6
  135. package/lib/controls/wysiwyg/CKeditor.js +14 -13
  136. package/lib/filters/ConditionValidator.d.ts +1 -1
  137. package/lib/filters/FilterService.d.ts +18 -18
  138. package/lib/filters/FilterService.js +11 -11
  139. package/lib/history-actions/AbstractHistoryAdapter.d.ts +14 -14
  140. package/lib/history-actions/AbstractHistoryAdapter.js +5 -6
  141. package/lib/history-actions/DefaultHistoryAdapter.d.ts +7 -7
  142. package/lib/history-actions/DefaultHistoryAdapter.js +2 -2
  143. package/lib/list-query-builder/ListQueryBuilder.d.ts +1 -1
  144. package/lib/media-manager/AbstractMediaManager.d.ts +14 -3
  145. package/lib/media-manager/AbstractMediaManager.js +16 -5
  146. package/lib/media-manager/MediaManagerHandler.d.ts +3 -0
  147. package/lib/media-manager/MediaManagerHandler.js +30 -5
  148. package/lib/media-manager/Thumb.js +7 -13
  149. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +6 -4
  150. package/lib/media-manager/helpers/MediaManagerHelper.js +18 -18
  151. package/lib/model/AbstractModel.d.ts +9 -5
  152. package/lib/model/AbstractModel.js +9 -13
  153. package/lib/model/InternalModelAccessFactory.js +9 -10
  154. package/lib/model/ModelHandler.d.ts +45 -7
  155. package/lib/model/ModelHandler.js +168 -11
  156. package/lib/model/adapter/sequelize.d.ts +2 -4
  157. package/lib/model/adapter/sequelize.js +16 -193
  158. package/lib/model/adapter/typeorm.d.ts +2 -4
  159. package/lib/model/adapter/typeorm.js +2 -35
  160. package/lib/notifications/AbstractNotificationService.d.ts +9 -9
  161. package/lib/notifications/AbstractNotificationService.js +8 -8
  162. package/lib/notifications/GeneralNotificationService.js +1 -1
  163. package/lib/notifications/SystemNotificationService.js +1 -1
  164. package/lib/ui-i18n/uiTranslationKeys.d.ts +1 -1
  165. package/lib/ui-i18n/uiTranslationKeys.js +1 -0
  166. package/lib/widgets/abstractCustom.d.ts +5 -2
  167. package/lib/widgets/abstractCustom.js +4 -0
  168. package/lib/widgets/widgetHandler.d.ts +5 -2
  169. package/lib/widgets/widgetHandler.js +60 -14
  170. package/models/{FilterAP.d.ts → Filter.d.ts} +4 -70
  171. package/models/Filter.js +1 -0
  172. package/models/FilterColumn.d.ts +10 -0
  173. package/models/FilterColumn.js +1 -0
  174. package/models/Group.d.ts +8 -0
  175. package/models/Group.js +1 -0
  176. package/models/HistoryActions.d.ts +14 -0
  177. package/models/HistoryActions.js +1 -0
  178. package/models/MediaManagerAP.d.ts +2 -54
  179. package/models/MediaManagerAP.js +1 -51
  180. package/models/MediaManagerAssociationsAP.d.ts +1 -35
  181. package/models/MediaManagerAssociationsAP.js +1 -33
  182. package/models/MediaManagerMetaAP.d.ts +2 -30
  183. package/models/MediaManagerMetaAP.js +1 -27
  184. package/models/Notification.d.ts +13 -0
  185. package/models/Notification.js +1 -0
  186. package/models/User.d.ts +23 -0
  187. package/models/User.js +1 -0
  188. package/models/UserNotification.d.ts +7 -0
  189. package/models/UserNotification.js +1 -0
  190. package/package.json +25 -30
  191. package/services/FeedService.d.ts +5 -5
  192. package/services/FeedService.js +1 -1
  193. package/system/Router.js +2 -10
  194. package/system/bindAccessRights.js +1 -1
  195. package/system/bindAuthorization.js +2 -2
  196. package/system/bindControls.js +7 -6
  197. package/system/bindDashboardWidgets.js +3 -2
  198. package/system/bindDev.js +1 -1
  199. package/system/bindHistory.d.ts +1 -1
  200. package/system/bindHistory.js +1 -1
  201. package/system/bindInertia.js +0 -6
  202. package/system/bindMediaManager.js +4 -17
  203. package/system/bindNotifications.d.ts +1 -1
  204. package/system/bindNotifications.js +1 -1
  205. package/system/bindReqFunctions.d.ts +1 -0
  206. package/system/bindReqFunctions.js +20 -3
  207. package/system/buildInternalModelAccess.js +2 -15
  208. package/system/defaults.js +5 -10
  209. package/system/systemModelContracts.d.ts +22 -0
  210. package/system/systemModelContracts.js +155 -0
  211. package/system/validateSystemModels.d.ts +2 -0
  212. package/system/validateSystemModels.js +101 -0
  213. package/translations/ar.json +2 -1
  214. package/translations/cn.json +2 -1
  215. package/translations/de.json +2 -1
  216. package/translations/en.json +1 -0
  217. package/translations/es.json +2 -1
  218. package/translations/fr.json +2 -1
  219. package/translations/hi.json +2 -1
  220. package/translations/jp.json +2 -1
  221. package/translations/ko.json +2 -1
  222. package/translations/pt.json +2 -1
  223. package/translations/ru.json +2 -1
  224. package/translations/ua.json +2 -1
  225. package/translations/uz.json +2 -1
  226. package/translations/vi.json +2 -1
  227. package/assets/RelationDialogStack-DhThUMep.js +0 -20
  228. package/assets/add-group-L8lMigab.js +0 -1
  229. package/assets/add-group-form-o7F6t6qW.js +0 -1
  230. package/assets/add-user-BE4-TNJw.js +0 -1
  231. package/assets/add-user-form-BP_8TjxN.js +0 -1
  232. package/assets/add-w398ZkhF.js +0 -1
  233. package/assets/app-C7J5ccrI.css +0 -1
  234. package/assets/app-layout-Bg455MIY.js +0 -1
  235. package/assets/app-shell-BT2kF0We.js +0 -1
  236. package/assets/app-sidebar-CZfPUXck.js +0 -1
  237. package/assets/app-sidebar-header-UVcKhNm6.js +0 -1
  238. package/assets/breadcrumbs-CrqIBT84.js +0 -1
  239. package/assets/catalog-btkCCwiv.js +0 -6
  240. package/assets/dashboard-Bvasc1cr.js +0 -3
  241. package/assets/date-picker-kxQWOxHk.js +0 -1
  242. package/assets/del-modal-C39LR5aQ.js +0 -1
  243. package/assets/dynamic-controls-DyPP5sTC.js +0 -1
  244. package/assets/geo-json-CGNQFl6J.js +0 -1
  245. package/assets/handsontable-Dv59QFH5.js +0 -336
  246. package/assets/history-DwKR8MPu.js +0 -1
  247. package/assets/home-BrtAkCRj.js +0 -2
  248. package/assets/icon-DpUVVHmK.js +0 -1
  249. package/assets/init-user-8PiKR1zX.js +0 -1
  250. package/assets/input-error-Cbt-Y3Fj.js +0 -1
  251. package/assets/jsoneditor-CiPXPMho.js +0 -3869
  252. package/assets/list-DGsL_qii.js +0 -4
  253. package/assets/login-Br_FcBU_.js +0 -1
  254. package/assets/material-icon-DOkM71fv.js +0 -1
  255. package/assets/module-EgfgIEhF.js +0 -1
  256. package/assets/monaco-ompgKQ3_.js +0 -11
  257. package/assets/nav-footer-DzLwfBAE.js +0 -1
  258. package/assets/nav-main-CSEbjYgs.js +0 -1
  259. package/assets/nav-user-DJ0hfhfH.js +0 -1
  260. package/assets/notification-B19ZLro7.js +0 -20
  261. package/assets/pagination-render-8GvJxq55.js +0 -1
  262. package/assets/register-CZzIeT2G.js +0 -1
  263. package/assets/ru-1NdRIQNV.js +0 -1
  264. package/assets/theme-switcher-CBbEj1u-.js +0 -1
  265. package/assets/toast-editor-DwVqd1rz.js +0 -668
  266. package/assets/user-filters-list-7Im79QyS.js +0 -1
  267. package/assets/user-info-YiU17Mmy.js +0 -1
  268. package/assets/user-menu-content-gdpNF5-8.js +0 -1
  269. package/assets/vanilla-picker-B3LgXoKV.js +0 -2
  270. package/assets/vendor-l0sNRNKZ.js +0 -1
  271. package/assets/welcome-nT0eFWHb.js +0 -1
  272. package/controllers/navigation/edit.d.ts +0 -1
  273. package/controllers/navigation/edit.js +0 -8
  274. package/lib/ai-assistant/DummyAiModelService.d.ts +0 -8
  275. package/lib/ai-assistant/DummyAiModelService.js +0 -14
  276. package/lib/ai-assistant/OpenAiModelService.d.ts +0 -24
  277. package/lib/ai-assistant/OpenAiModelService.js +0 -184
  278. package/lib/catalog/Navigation.d.ts +0 -49
  279. package/lib/catalog/Navigation.js +0 -492
  280. package/lib/controls/AbstractControls.d.ts +0 -30
  281. package/lib/controls/AbstractControls.js +0 -14
  282. package/lib/media-manager/DefaultMediaManager.d.ts +0 -20
  283. package/lib/media-manager/DefaultMediaManager.js +0 -127
  284. package/lib/media-manager/Items.d.ts +0 -50
  285. package/lib/media-manager/Items.js +0 -296
  286. package/models/FilterAP.js +0 -68
  287. package/models/FilterColumnAP.d.ts +0 -32
  288. package/models/FilterColumnAP.js +0 -21
  289. package/models/GroupAP.d.ts +0 -31
  290. package/models/GroupAP.js +0 -22
  291. package/models/HistoryActionsAP.d.ts +0 -56
  292. package/models/HistoryActionsAP.js +0 -42
  293. package/models/NavigationAP.d.ts +0 -22
  294. package/models/NavigationAP.js +0 -16
  295. package/models/NotificationAP.d.ts +0 -44
  296. package/models/NotificationAP.js +0 -30
  297. package/models/UserAP.d.ts +0 -81
  298. package/models/UserAP.js +0 -57
  299. package/models/UserNotificationAP.d.ts +0 -26
  300. package/models/UserNotificationAP.js +0 -18
  301. package/system/bindAiAssistant.d.ts +0 -2
  302. package/system/bindAiAssistant.js +0 -30
  303. package/system/bindModels.d.ts +0 -2
  304. package/system/bindModels.js +0 -48
  305. package/system/bindNavigation.d.ts +0 -2
  306. package/system/bindNavigation.js +0 -38
  307. /package/assets/{RelationDialogStack-B00Ot5qS.css → controls/ckeditor.css} +0 -0
@@ -1,14 +1,15 @@
1
1
  import { MaterialIcon } from "./MaaterialIcons";
2
2
  import { EditorOptions } from "@toast-ui/editor/types/editor";
3
3
  import { GridSettings as HandsontableSettings } from "handsontable/settings";
4
- import { GroupAP } from "../models/GroupAP";
5
- import { UserAP } from "../models/UserAP";
4
+ import { Group } from "../models/Group";
5
+ import { User } from "../models/User";
6
6
  import { InternalModelAccessMap } from "./internalModelAccess";
7
7
  /**
8
8
  * Controller function type - async function that handles requests and returns a response
9
9
  */
10
10
  export type ControllerFunction = (req: ReqType, res: ResType) => Promise<any>;
11
11
  export type AdminpanelIcon = MaterialIcon;
12
+ export type NonEmptyArray<T> = [T, ...T[]];
12
13
  export type FieldsTypes = "string" | "password" | "date" | "datetime" | "time" | "integer" | "number" | "float" | "color" | "email" | "month" | "week" | "range" | "boolean" | "binary" | "text" | "longtext" | "mediumtext" | "ckeditor" | "wysiwyg" | "texteditor" | "word" | 'tui' | 'tuieditor' | 'toast-ui' | "jsoneditor" | "json" | "array" | "object" | "ace" | "code" | "html" | "xml" | "aceeditor" | "menu" | "schedule" | "worktime" | "association" | "association-many" | "select" | "select-many" | "table" | "geojson" | "mediamanager" | "single-file" |
13
14
  /**
14
15
  * it will be needed only for polygon data
@@ -58,7 +59,7 @@ export interface AdminpanelConfig {
58
59
  /**
59
60
  * Optional additional link at the bottom of the login page
60
61
  * Example:
61
- * addishinalLoginPage: { link: '/model/userap/register', textKey: 'Additional login page' }
62
+ * addishinalLoginPage: { link: '/model/User/register', textKey: 'Additional login page' }
62
63
  * link can be relative to routePrefix (e.g. 'model/help' or '/model/help') or absolute (https://...)
63
64
  */
64
65
  addishinalLoginPage?: {
@@ -98,13 +99,13 @@ export interface AdminpanelConfig {
98
99
  * Optional callback to filter or transform all navbar links after models have been processed.
99
100
  * Receives all links (static + model-generated) and the current user; returns the final array.
100
101
  */
101
- handleAdditionalLinks?: (user: UserAP, allLinks: HrefConfig[]) => HrefConfig[];
102
+ handleAdditionalLinks?: (user: User, allLinks: HrefConfig[]) => HrefConfig[];
102
103
  /**
103
104
  * Per-section handlers, applied after all links (static + model-generated) are collected.
104
105
  * Each key is a section name; the handler receives links belonging to that section.
105
106
  */
106
107
  sectionHandlers?: {
107
- [section: string]: (user: UserAP, links: HrefConfig[]) => HrefConfig[];
108
+ [section: string]: (user: User, links: HrefConfig[]) => HrefConfig[];
108
109
  };
109
110
  };
110
111
  /**
@@ -198,10 +199,6 @@ export interface AdminpanelConfig {
198
199
  * System field for store absolute root path adminpanel hookfolder
199
200
  */
200
201
  rootPath?: string;
201
- /**
202
- * Navigation
203
- */
204
- navigation?: NavigationConfig;
205
202
  mediamanager?: MediaManagerConfig;
206
203
  /** System settings */
207
204
  system?: {
@@ -395,15 +392,15 @@ export interface ModelConfig {
395
392
  * */
396
393
  identifierField?: string;
397
394
  /** In this field we can set model field, for which we want to check user access right.
398
- * May be association or association-many to UserAP or GroupAP */
395
+ * May be association or association-many to User or Group */
399
396
  userAccessRelation?: {
400
397
  field: string;
401
398
  via?: string;
402
399
  } | string;
403
400
  userAccessRelationCallback?: (userWithGroups: UserWithGroups, record: any) => boolean;
404
401
  }
405
- type UserWithGroups = UserAP & {
406
- groups: GroupAP[];
402
+ type UserWithGroups = User & {
403
+ groups: Group[];
407
404
  };
408
405
  export type ModelFieldConfig = (BaseFieldConfig | TuiEditorFieldConfig) & {
409
406
  groupsAccessRights?: string[];
@@ -491,7 +488,7 @@ export interface TuiEditorFieldConfig extends BaseFieldConfig {
491
488
  export interface MediaManagerOptionsField {
492
489
  id: 'default' | string;
493
490
  group: string;
494
- accept: string[];
491
+ accept: NonEmptyArray<string>;
495
492
  initTab?: 'tile-image' | 'table-video' | 'table-text' | 'table-application' | 'table-all' | 'tile-all';
496
493
  config?: Record<string, any>;
497
494
  onlyView?: boolean;
@@ -586,26 +583,6 @@ export interface HrefConfig {
586
583
  */
587
584
  section?: string;
588
585
  }
589
- export interface NavigationItemTypeConfig {
590
- model: string;
591
- title: string;
592
- /**
593
- * /page/${data.record.slug}
594
- */
595
- urlPath: string | ((v: any) => string);
596
- }
597
- export interface NavigationConfig {
598
- model?: string;
599
- sections: string[];
600
- groupField: {
601
- name: string;
602
- required: boolean;
603
- label: string;
604
- }[];
605
- allowContentInGroup?: boolean;
606
- items: NavigationItemTypeConfig[];
607
- movingGroupsRootOnly?: boolean;
608
- }
609
586
  export interface MediaManagerConfig {
610
587
  fileStoragePath: string;
611
588
  allowMIME?: string[];
@@ -4,7 +4,8 @@ import multer from "multer";
4
4
  import { I18n } from "../lib/I18n";
5
5
  import { Inertia } from "../lib/inertia/inertiaAdapter";
6
6
  import { Flash } from "../lib/inertia/flash";
7
- import { UserAP } from "../models/UserAP";
7
+ import { User } from "../models/User";
8
+ import { AppRuntime } from "../lib/app-manager/AdminizerApp";
8
9
  declare global {
9
10
  /** @deprecated use import from TS model decalration */
10
11
  type ModelsAP = {
@@ -38,25 +39,20 @@ declare global {
38
39
  isPublic?: boolean;
39
40
  parent?: ModelsAP["MediaManagerAP"];
40
41
  };
41
- NavigationAP: {
42
- id?: string;
43
- label: string;
44
- tree: any;
45
- };
46
42
  };
47
43
  type reqSession = {
48
44
  flashMessages: Record<string, string[]>;
49
45
  xInertiaCurrentComponent: string | undefined;
50
- UserAP: UserAP;
46
+ User: User;
51
47
  messages: {
52
48
  adminError: string[];
53
49
  adminSuccess: string[];
54
50
  };
55
- userPretended?: UserAP;
51
+ userPretended?: User;
56
52
  };
57
53
  type FlashMessages = 'info' | 'error' | 'success' | string;
58
54
  type ReqType = Request & {
59
- user: UserAP;
55
+ user: User;
60
56
  Inertia: Inertia;
61
57
  flash: Flash<FlashMessages>;
62
58
  session: reqSession;
@@ -67,7 +63,11 @@ declare global {
67
63
  route: {
68
64
  [key: string]: string;
69
65
  };
66
+ /**
67
+ * @deprecated Will be removed in Adminizer v6. Use `runtime` in app controllers.
68
+ */
70
69
  adminizer: Adminizer;
70
+ runtime: AppRuntime;
71
71
  upload: (options?: {
72
72
  destination?: string;
73
73
  filename?: (file: Express.Multer.File) => string;
@@ -77,12 +77,7 @@ declare global {
77
77
  uploadedFileType: string;
78
78
  params: Record<string, string>;
79
79
  };
80
- type ResType = Response & {
81
- /**
82
- * @deprecated // TODO delete after finish catalog
83
- */
84
- viewAdmin(specifiedPath: string, locals?: any, cb_view?: Function): void;
85
- };
80
+ type ResType = Response;
86
81
  type MiddlewareType = (req: ReqType, res: ResType, next: NextFunction) => void;
87
82
  type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
88
83
  }
@@ -1,4 +1,4 @@
1
- import { FilterCondition } from "../models/FilterAP";
1
+ import { FilterCondition } from "../models/Filter";
2
2
  /**
3
3
  * Input format for list/feed/export query builder.
4
4
  * This is not the internal model query language.
@@ -14,15 +14,29 @@ import type { ViteDevServer } from 'vite';
14
14
  import { MenuHelper } from "../helpers/menuHelper";
15
15
  import { ControlsHandler } from "./controls/ControlsHandler";
16
16
  import { CatalogHandler } from "./catalog/CatalogHandler";
17
+ import { CatalogTemplateComponentHandler } from "./catalog/CatalogTemplateComponentHandler";
17
18
  import { AiAssistantHandler } from './ai-assistant/AiAssistantHandler';
18
19
  import { NotificationHandler } from './notifications/NotificationHandler';
19
20
  import { INotification } from "../interfaces/types";
20
21
  import { MediaManagerHandler } from "./media-manager/MediaManagerHandler";
21
- import { StorageServices } from "./catalog/Navigation";
22
22
  import { HistoryHandler } from "./history-actions/HistoryHandler";
23
23
  import { CustomFilterHandler } from "./filters/CustomFilterHandler";
24
24
  import { FeedbackHandler } from "./feedback/FeedbackHandler";
25
+ import { AppManager } from "./app-manager/AppManager";
26
+ import { ControllerHandler } from "./app-manager/ControllerHandler";
27
+ import { AssetHandler } from "./app-manager/AssetHandler";
28
+ import { ConfigLayerHandler } from "./app-manager/ConfigLayerHandler";
29
+ import { AccessRightsHandler } from "./access-rights/AccessRightsHandler";
30
+ export declare function createAdminizerLogger(): winston.Logger;
31
+ export interface EmitAsyncOptions {
32
+ /**
33
+ * Maximum time to wait for each listener. Set to 0 to disable the timeout.
34
+ * @default 10000
35
+ */
36
+ timeoutMs?: number;
37
+ }
25
38
  export declare class Adminizer {
39
+ private static readonly defaultListenerTimeoutMs;
26
40
  /**
27
41
  * If you convey this default Middleware, it will add it to the very top of the router,
28
42
  * and will contact each request
@@ -46,9 +60,14 @@ export declare class Adminizer {
46
60
  vite: ViteDevServer;
47
61
  controlsHandler: ControlsHandler;
48
62
  catalogHandler: CatalogHandler;
63
+ catalogTemplateComponentHandler: CatalogTemplateComponentHandler;
49
64
  mediaManagerHandler: MediaManagerHandler;
50
- storageServices: StorageServices;
51
65
  feedbackHandler: FeedbackHandler;
66
+ appManager: AppManager;
67
+ controllerHandler: ControllerHandler;
68
+ assetHandler: AssetHandler;
69
+ configLayerHandler: ConfigLayerHandler;
70
+ accessRightsHandler: AccessRightsHandler;
52
71
  jwtSecret: string;
53
72
  static logger: winston.Logger;
54
73
  constructor(ormAdapters: AbstractAdapter[]);
@@ -61,6 +80,10 @@ export declare class Adminizer {
61
80
  init(config: AdminpanelConfig): Promise<void>;
62
81
  sendNotification(notification: Omit<INotification, 'id' | 'createdAt' | 'icon'>): Promise<boolean>;
63
82
  get emitter(): EventEmitter;
83
+ /**
84
+ * Runs event listeners and waits for async module side effects before continuing.
85
+ */
86
+ emitAsync<TPayload = unknown>(event: string | symbol, payload: TPayload, options?: EmitAsyncOptions): Promise<void>;
64
87
  getOrmAdapter(ormType: string): AbstractAdapter;
65
88
  static get log(): {
66
89
  info: (...args: any[]) => winston.Logger;
package/lib/Adminizer.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import express from "express";
2
2
  import cookieParser from 'cookie-parser';
3
+ import * as fs from "fs";
3
4
  import * as path from "path";
4
5
  import winston from "winston";
5
6
  import chalk from "chalk";
@@ -9,11 +10,10 @@ import Router from "./../system/Router.js";
9
10
  import bindAssets from "../system/bindAssets.js";
10
11
  import bindDev from "../system/bindDev.js";
11
12
  import bindDashboardWidgets from "../system/bindDashboardWidgets.js";
12
- import { bindNavigation } from "../system/bindNavigation.js";
13
13
  import bindMediaManager from "../system/bindMediaManager.js";
14
14
  import bindAccessRights from "../system/bindAccessRights.js";
15
15
  import bindAuthorization from "../system/bindAuthorization.js";
16
- import bindModels from "../system/bindModels.js";
16
+ import { validateSystemModels } from "../system/validateSystemModels.js";
17
17
  import bindTranslations from "../system/bindTranslations.js";
18
18
  import { ModelHandler } from "./model/ModelHandler.js";
19
19
  import { WidgetHandler } from "./widgets/widgetHandler.js";
@@ -28,16 +28,67 @@ import { MenuHelper } from "../helpers/menuHelper.js";
28
28
  import { bindControls } from "../system/bindControls.js";
29
29
  import { ControlsHandler } from "./controls/ControlsHandler.js";
30
30
  import { CatalogHandler } from "./catalog/CatalogHandler.js";
31
+ import { CatalogTemplateComponentHandler } from "./catalog/CatalogTemplateComponentHandler.js";
31
32
  import { v4 as uuid } from "uuid";
32
33
  import { bindNotifications } from "../system/bindNotifications.js";
33
- import { bindAiAssistant } from "../system/bindAiAssistant.js";
34
34
  import { MediaManagerHandler } from "./media-manager/MediaManagerHandler.js";
35
35
  import { bindCors } from "../system/bindCors.js";
36
36
  import bindHistory from "../system/bindHistory.js";
37
37
  import bindCustomFilterHandlers from "../system/bindCustomFilterHandlers.js";
38
38
  import { FeedbackHandler } from "./feedback/FeedbackHandler.js";
39
39
  import { buildInternalModelAccess } from "../system/buildInternalModelAccess.js";
40
+ import { AppManager } from "./app-manager/AppManager.js";
41
+ import { ControllerHandler } from "./app-manager/ControllerHandler.js";
42
+ import { AssetHandler } from "./app-manager/AssetHandler.js";
43
+ import { ConfigLayerHandler } from "./app-manager/ConfigLayerHandler.js";
44
+ import { AccessRightsHandler } from "./access-rights/AccessRightsHandler.js";
45
+ const logFilePath = "logs/app.log";
46
+ function ensureLogDirectory(filePath) {
47
+ const logDirectory = path.dirname(filePath);
48
+ if (logDirectory !== ".") {
49
+ fs.mkdirSync(logDirectory, { recursive: true });
50
+ }
51
+ }
52
+ function isFileLoggingEnabled() {
53
+ return ["1", "true", "yes"].includes((process.env.ADMINIZER_LOG_TO_FILE ?? "").toLowerCase());
54
+ }
55
+ export function createAdminizerLogger() {
56
+ const transports = [
57
+ new winston.transports.Console({
58
+ format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, ...meta }) => {
59
+ const metaString = Object.keys(meta).length ? JSON.stringify(meta) : "";
60
+ const colors = {
61
+ error: chalk.red,
62
+ warn: chalk.yellow,
63
+ info: chalk.green,
64
+ http: chalk.magenta,
65
+ verbose: chalk.cyan,
66
+ debug: chalk.blue,
67
+ silly: chalk.gray,
68
+ };
69
+ const colorize = colors[level] ?? chalk.white;
70
+ const line = `[${timestamp}] ${level.toUpperCase()}: ${message} ${metaString}`;
71
+ return colorize(line);
72
+ }))
73
+ }),
74
+ ];
75
+ if (isFileLoggingEnabled()) {
76
+ ensureLogDirectory(logFilePath);
77
+ transports.push(new winston.transports.File({
78
+ filename: logFilePath,
79
+ }));
80
+ }
81
+ return winston.createLogger({
82
+ level: process.env.LOG_LEVEL ?? "debug",
83
+ format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, ...meta }) => {
84
+ const metaString = Object.keys(meta).length ? JSON.stringify(meta) : "";
85
+ return `[${timestamp}] ${level.toUpperCase()}: ${message} ${metaString}`;
86
+ })),
87
+ transports,
88
+ });
89
+ }
40
90
  export class Adminizer {
91
+ static defaultListenerTimeoutMs = 10_000;
41
92
  // Preconfigures
42
93
  /**
43
94
  * If you convey this default Middleware, it will add it to the very top of the router,
@@ -63,42 +114,36 @@ export class Adminizer {
63
114
  vite;
64
115
  controlsHandler;
65
116
  catalogHandler;
117
+ catalogTemplateComponentHandler;
66
118
  mediaManagerHandler;
67
- storageServices;
68
119
  feedbackHandler;
120
+ appManager;
121
+ controllerHandler;
122
+ assetHandler;
123
+ configLayerHandler;
124
+ accessRightsHandler;
69
125
  // Constants
70
126
  jwtSecret = process.env.JWT_SECRET ?? uuid();
71
- static logger = winston.createLogger({
72
- level: process.env.LOG_LEVEL ?? "debug",
73
- format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, ...meta }) => {
74
- const metaString = Object.keys(meta).length ? JSON.stringify(meta) : "";
75
- return `[${timestamp}] ${level.toUpperCase()}: ${message} ${metaString}`;
76
- })),
77
- transports: [
78
- new winston.transports.Console({
79
- format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message, ...meta }) => {
80
- const metaString = Object.keys(meta).length ? JSON.stringify(meta) : "";
81
- const colors = {
82
- error: chalk.red,
83
- warn: chalk.yellow,
84
- info: chalk.green,
85
- http: chalk.magenta,
86
- verbose: chalk.cyan,
87
- debug: chalk.blue,
88
- silly: chalk.gray,
89
- };
90
- const colorize = colors[level] ?? chalk.white;
91
- const line = `[${timestamp}] ${level.toUpperCase()}: ${message} ${metaString}`;
92
- return colorize(line);
93
- }))
94
- }),
95
- new winston.transports.File({ filename: "logs/app.log" }),
96
- ],
97
- });
127
+ static logger = createAdminizerLogger();
98
128
  constructor(ormAdapters) {
99
129
  this.app = express();
100
130
  this._emitter = new EventEmitter();
101
131
  this.ormAdapters = ormAdapters;
132
+ this.modelHandler = new ModelHandler();
133
+ this.middlewareManager = new MiddlewareManager(this);
134
+ this.accessRightsHelper = new AccessRightsHelper(this);
135
+ this.accessRightsHandler = new AccessRightsHandler(this);
136
+ this.configHelper = new ConfigHelper(this);
137
+ this.widgetHandler = new WidgetHandler(this);
138
+ this.controlsHandler = new ControlsHandler();
139
+ this.catalogHandler = new CatalogHandler();
140
+ this.catalogTemplateComponentHandler = new CatalogTemplateComponentHandler();
141
+ this.mediaManagerHandler = new MediaManagerHandler();
142
+ this.feedbackHandler = new FeedbackHandler(this);
143
+ this.controllerHandler = new ControllerHandler(this);
144
+ this.assetHandler = new AssetHandler(this);
145
+ this.configLayerHandler = new ConfigLayerHandler(this);
146
+ this.appManager = new AppManager(this);
102
147
  }
103
148
  getMiddleware() {
104
149
  return (req, res, next) => {
@@ -192,22 +237,14 @@ export class Adminizer {
192
237
  if (isViteDev)
193
238
  await this.viteMiddleware();
194
239
  this.emitter.emit('adminizer:init');
195
- this.modelHandler = new ModelHandler();
196
- // TODO: 'hot reload' unbind models
197
- await bindModels(this);
240
+ // validate models
241
+ validateSystemModels(this);
198
242
  this.modelHandler.configureInternalAccess(buildInternalModelAccess(this.config, this.modelHandler));
199
243
  bindCustomFilterHandlers(this);
200
244
  this.config.rootPath = path.resolve(import.meta.dirname + "/..");
201
- this.middlewareManager = new MiddlewareManager(this);
202
245
  await this.middlewareManager.loadMiddlewares();
203
246
  // TODO: 'hot reload' problem with deleting access right tokens
204
- this.accessRightsHelper = new AccessRightsHelper(this);
205
- // Helpers go to construtor
206
- this.configHelper = new ConfigHelper(this);
207
247
  this.menuHelper = new MenuHelper(this.config);
208
- this.widgetHandler = new WidgetHandler(this);
209
- this.catalogHandler = new CatalogHandler();
210
- this.mediaManagerHandler = new MediaManagerHandler();
211
248
  bindExpressUtils(this.app);
212
249
  bindReqFunctions(this);
213
250
  // Bind assets
@@ -217,8 +254,7 @@ export class Adminizer {
217
254
  bindDev(this);
218
255
  }
219
256
  }
220
- await bindDashboardWidgets(this);
221
- await bindNavigation(this);
257
+ bindDashboardWidgets(this);
222
258
  bindMediaManager(this);
223
259
  await bindAccessRights(this);
224
260
  if (I18n.appendLocale) {
@@ -228,20 +264,15 @@ export class Adminizer {
228
264
  this.config.translation = false;
229
265
  }
230
266
  //bind controls
231
- this.controlsHandler = new ControlsHandler();
232
267
  bindControls(this);
233
268
  // bind Inertia
234
269
  bindInertia(this);
235
270
  await bindAuthorization(this);
236
271
  // Bind notifications
237
272
  if (this.config.notifications.enabled)
238
- await bindNotifications(this);
239
- if (this.config.aiAssistant?.enabled)
240
- await bindAiAssistant(this);
273
+ bindNotifications(this);
241
274
  if (this.config.history?.enabled)
242
- await bindHistory(this);
243
- // FeedbackHandler registers its own route lazily when handler.register() is called
244
- this.feedbackHandler = new FeedbackHandler(this);
275
+ bindHistory(this);
245
276
  this.router = new Router(this);
246
277
  await this.router.bind(); // must be after binding policies and req/res functions
247
278
  /**
@@ -263,6 +294,49 @@ export class Adminizer {
263
294
  get emitter() {
264
295
  return this._emitter;
265
296
  }
297
+ /**
298
+ * Runs event listeners and waits for async module side effects before continuing.
299
+ */
300
+ async emitAsync(event, payload, options = {}) {
301
+ const timeoutMs = options.timeoutMs ?? Adminizer.defaultListenerTimeoutMs;
302
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
303
+ throw new RangeError("emitAsync timeoutMs must be a finite non-negative number");
304
+ }
305
+ await Promise.all(this._emitter.listeners(event).map(async (listener, listenerIndex) => {
306
+ const listenerName = listener.name || "<anonymous>";
307
+ let timeout;
308
+ try {
309
+ const listenerPromise = Promise.resolve().then(() => listener.call(this._emitter, payload));
310
+ if (timeoutMs === 0) {
311
+ await listenerPromise;
312
+ return;
313
+ }
314
+ const timeoutPromise = new Promise((_, reject) => {
315
+ timeout = setTimeout(() => {
316
+ reject(new Error(`Listener "${listenerName}" for event "${String(event)}" timed out after ${timeoutMs} ms`));
317
+ }, timeoutMs);
318
+ });
319
+ await Promise.race([listenerPromise, timeoutPromise]);
320
+ }
321
+ catch (error) {
322
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
323
+ Adminizer.logger.error("Async event listener failed", {
324
+ event: String(event),
325
+ listener: listenerName,
326
+ listenerIndex,
327
+ timeoutMs,
328
+ error: normalizedError.message,
329
+ stack: normalizedError.stack,
330
+ });
331
+ throw error;
332
+ }
333
+ finally {
334
+ if (timeout) {
335
+ clearTimeout(timeout);
336
+ }
337
+ }
338
+ }));
339
+ }
266
340
  getOrmAdapter(ormType) {
267
341
  return this.ormAdapters.find(item => item.ormType === ormType);
268
342
  }
@@ -5,18 +5,19 @@ import { ModelResource } from "../interfaces/types";
5
5
  import { ActionType } from "../interfaces/adminpanelConfig";
6
6
  import { Fields } from "../helpers/fieldsHelper";
7
7
  import { Adminizer } from "./Adminizer";
8
- import { UserAP } from "../models/UserAP";
8
+ import { User } from "../models/User";
9
9
  import { QueryCriteria } from "../interfaces/queryCriteria";
10
10
  export declare class DataAccessor {
11
11
  readonly adminizer: Adminizer;
12
- user: UserAP;
12
+ user: User;
13
13
  modelResource: ModelResource;
14
14
  action: ActionType;
15
15
  private fields;
16
16
  private actionVerb;
17
- constructor(adminizer: Adminizer, user: UserAP, modelResource: ModelResource, action: ActionType);
17
+ constructor(adminizer: Adminizer, user: User, modelResource: ModelResource, action: ActionType);
18
18
  private getModelConfig;
19
19
  private accessRelationModel;
20
+ private resolveRelationTarget;
20
21
  /**
21
22
  * Retrieves the fields for the given ModelResource based on action type,
22
23
  * taking into account access rights and configuration settings.
@@ -26,14 +27,17 @@ export declare class DataAccessor {
26
27
  private orderFieldsByConfig;
27
28
  private getAssociatedFieldsConfig;
28
29
  private checkFieldAccess;
30
+ private getSelectedFields;
31
+ private getPopulateCriteria;
32
+ private canUseSelectedFieldFallback;
29
33
  /**
30
34
  * Returns filtered record applying config from this.fields on this record
31
35
  * @data - record from a specific model */
32
- process<T>(record: T): Partial<T>;
36
+ process<T>(record: T, criteria?: QueryCriteria): Partial<T>;
33
37
  /** Filters associated records (simplified process() function) */
34
38
  private filterAssociatedRecord;
35
39
  /** Process for an array of records */
36
- processMany<T>(records: T[]): Partial<T>[];
40
+ processMany<T>(records: T[], criteria?: QueryCriteria): Partial<T>[];
37
41
  sanitizeUserRelationAccess(criteria?: QueryCriteria): Promise<QueryCriteria>;
38
42
  setUserRelationAccess<T>(record: T): Promise<Partial<T>>;
39
43
  }