adminizer 5.0.0-build.9 → 5.1.0-build.25

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 (232) hide show
  1. package/assets/abnfDiagram-VCTEODGH-BTgLIXrb.js +1 -0
  2. package/assets/add-C8V8qjvm.js +1 -0
  3. package/assets/add-group-Ezq_Ocot.js +1 -0
  4. package/assets/add-user-CluNf2QG.js +1 -0
  5. package/assets/ai-assistant/agent.es.js +28464 -0
  6. package/assets/app-C96pcs-J.js +138 -0
  7. package/assets/app-DPmI-MvN.css +1 -0
  8. package/assets/arc-G6n0TtRf.js +1 -0
  9. package/assets/architectureDiagram-5GKGNRK7-TQ4_iSAG.js +36 -0
  10. package/assets/asmcrypto-DZeQH0LC.js +1 -0
  11. package/assets/blockDiagram-I7D4REHJ-1q050zQd.js +129 -0
  12. package/assets/c4Diagram-7LVT6UL2-BXn0hW62.js +38 -0
  13. package/assets/{catalog-dk6a0I1u.js → catalog-Cpx4OH_r.js} +3 -3
  14. package/assets/channel-JZzXP_E5.js +1 -0
  15. package/assets/chunk-2Q5K7J3B-BSnocdBz.js +1 -0
  16. package/assets/chunk-5VM5RSS4-BvfoMSpq.js +15 -0
  17. package/assets/chunk-F27PBJKO-CMyFcBlX.js +1 -0
  18. package/assets/chunk-IMKFNOWR--8Y02hwt.js +231 -0
  19. package/assets/chunk-JWPE2WC7-C18m6v8d.js +1 -0
  20. package/assets/chunk-POPQ4Y6H-DzoTZe0a.js +1 -0
  21. package/assets/chunk-SVP7TREG-Ce98IXh7.js +88 -0
  22. package/assets/chunk-TICWLB2K-BeLoUlaL.js +206 -0
  23. package/assets/chunk-XXDRQBXY-DCZSZ1aW.js +1 -0
  24. package/assets/classDiagram-ZZMXUADV-jA4zeKxs.js +1 -0
  25. package/assets/classDiagram-v2-VYDZK3BY-jA4zeKxs.js +1 -0
  26. package/assets/controls/ckeditor.es.js +9382 -9320
  27. package/assets/controls/handsontable.es.js +11971 -11938
  28. package/assets/controls/jsoneditor.es.js +10442 -10233
  29. package/assets/controls/toast-ui.es.js +1308 -1279
  30. package/assets/cose-bilkent-JH36ORCC-Cy9np608.js +1 -0
  31. package/assets/cynefin-OW5HDTMX-Ba6uP79R.js +166 -0
  32. package/assets/cynefinDiagram-5FMLGOSQ-DhMBBq7T.js +62 -0
  33. package/assets/cytoscape.esm-DzSz-X2X.js +321 -0
  34. package/assets/dagre-GXQ25YYZ-BdAnQUCV.js +4 -0
  35. package/assets/dashboard-BFVFBIio.js +3 -0
  36. package/assets/debounce-B3mXI_sx.js +1 -0
  37. package/assets/defaultLocale-DX6XiGOO.js +1 -0
  38. package/assets/diagram-S7CK7UJ4-BDYUGbNl.js +30 -0
  39. package/assets/diagram-UQ7AKVKN-PURK0-X-.js +41 -0
  40. package/assets/diagram-VSXAHHWV-DxHdFxl9.js +3 -0
  41. package/assets/diagram-VX7I27RA-Vz8xmeYc.js +24 -0
  42. package/assets/diagram-Z3DM3KII-CFXUpBMy.js +24 -0
  43. package/assets/docs-DU3h-HtS.js +1 -0
  44. package/assets/ebnfDiagram-PWID7BFC-BXNvxMGP.js +1 -0
  45. package/assets/erDiagram-RLTQ6QDP-DN0GgZEI.js +99 -0
  46. package/assets/flowDiagram-HODETNUW-DXdnwgBv.js +168 -0
  47. package/assets/ganttDiagram-EL5Y4UJY-Cv8_dxX3.js +292 -0
  48. package/assets/gitGraphDiagram-WWUBYQGX-BO8T858E.js +106 -0
  49. package/assets/history-BmwWpckq.js +1 -0
  50. package/assets/infoDiagram-27XIBGKW-DMSJ1RNc.js +2 -0
  51. package/assets/init-Gi6I4Gst.js +1 -0
  52. package/assets/init-user-BIdB8U_4.js +1 -0
  53. package/assets/isObject-DL-BuaBl.js +1 -0
  54. package/assets/ishikawaDiagram-5VMMS53U-_tLJESbl.js +70 -0
  55. package/assets/journeyDiagram-3NMN7TZE-DMMhdo-_.js +139 -0
  56. package/assets/kanban-definition-UXKFOSKX-CxQrB4t6.js +89 -0
  57. package/assets/katex-HP8lGamR.js +257 -0
  58. package/assets/layout-_oS_xxCJ.js +1 -0
  59. package/assets/linear-VLYuNK3x.js +1 -0
  60. package/assets/{list-CcMtS4hD.js → list-YTyJQtiR.js} +2 -2
  61. package/assets/login-B9GlhjZh.js +1 -0
  62. package/assets/manifest.json +834 -58
  63. package/assets/media-manager-Bb1VWlzd.js +6 -0
  64. package/assets/mermaid.core-BknV2vft.js +310 -0
  65. package/assets/mindmap-definition-YA3MSWOX-DBjjjDq4.js +96 -0
  66. package/assets/module-DQ1NK8Xg.js +1 -0
  67. package/assets/notification-CgNOsXvn.js +20 -0
  68. package/assets/ordinal-Cboi1Yqb.js +1 -0
  69. package/assets/pegDiagram-XKGWAZYB-uRznTaO4.js +1 -0
  70. package/assets/pieDiagram-E7YTZNPT-D1TkCH8I.js +39 -0
  71. package/assets/quadrantDiagram-AXDQQJYC-BofJ36Jz.js +7 -0
  72. package/assets/railroadDiagram-O6MQD6OU-e1ZM2IT1.js +1 -0
  73. package/assets/register-DjTtMayF.js +1 -0
  74. package/assets/requirementDiagram-BXWQKSXE-DQWArRbb.js +84 -0
  75. package/assets/ru-CqAtka69.js +1 -0
  76. package/assets/sankeyDiagram-P5KCCOFB-fVOu2jzi.js +40 -0
  77. package/assets/sequenceDiagram-WJ2MYXX4-Dj24cqpu.js +162 -0
  78. package/assets/sizeCapture-INFHLROL-CsApVrVi.js +1 -0
  79. package/assets/stateDiagram-D77RDMKH-IU2Szlid.js +1 -0
  80. package/assets/stateDiagram-v2-MP3YSRHH-B-EW3cIC.js +1 -0
  81. package/assets/swimlanes-42K2YHIH-97rBqTR-.js +1 -0
  82. package/assets/swimlanesDiagram-VR7AAH4N-CqG2iydK.js +8 -0
  83. package/assets/timeline-definition-24CTP7MA-DSgRzx1V.js +120 -0
  84. package/assets/toNumber-DZb-r9sy.js +1 -0
  85. package/assets/use-appearance-CXz2xWgT.js +1 -0
  86. package/assets/user-filters-list-BAR4CBN_.js +1 -0
  87. package/assets/vennDiagram-4TSXK5OY-BqMksFxE.js +34 -0
  88. package/assets/wardleyDiagram-VM6X3IG4-BMmxRODC.js +78 -0
  89. package/assets/welcome-CPXT7_4b.js +1 -0
  90. package/assets/with-app-layout-C6dqetfx.js +31 -0
  91. package/assets/xychartDiagram-S5SC5T6Z-3xRuF0l4.js +7 -0
  92. package/controllers/access-rights/permissionOptions.d.ts +2 -0
  93. package/controllers/access-rights/permissionOptions.js +23 -0
  94. package/controllers/add.js +2 -2
  95. package/controllers/addGroup.js +15 -6
  96. package/controllers/ai/AiAgentController.d.ts +66 -0
  97. package/controllers/ai/AiAgentController.js +435 -0
  98. package/controllers/ai/AiAssistantController.d.ts +0 -4
  99. package/controllers/ai/AiAssistantController.js +4 -78
  100. package/controllers/catalog/FrontendCatalogAdapter.js +7 -8
  101. package/controllers/docs/index.d.ts +22 -0
  102. package/controllers/docs/index.js +126 -0
  103. package/controllers/edit.js +2 -2
  104. package/controllers/editGroup.js +15 -6
  105. package/controllers/filter-fields/savedFilters.js +1 -1
  106. package/controllers/history-actions/HistoryController.js +7 -7
  107. package/controllers/inlineUpdate.js +10 -3
  108. package/controllers/list.js +1 -1
  109. package/controllers/login.js +1 -1
  110. package/controllers/notifications/NotificationController.js +14 -8
  111. package/controllers/view.js +3 -3
  112. package/controllers/widgets/filterInfo.js +1 -1
  113. package/helpers/accessRightsHelper.d.ts +63 -2
  114. package/helpers/accessRightsHelper.js +202 -13
  115. package/helpers/assetVersionHelper.d.ts +14 -0
  116. package/helpers/assetVersionHelper.js +42 -0
  117. package/helpers/configHelper.js +19 -18
  118. package/helpers/controllerHelper.d.ts +1 -0
  119. package/helpers/controllerHelper.js +25 -15
  120. package/helpers/fieldsHelper.d.ts +2 -1
  121. package/helpers/fieldsHelper.js +11 -5
  122. package/helpers/inertiaActionsHelper.d.ts +1 -1
  123. package/helpers/inertiaActionsHelper.js +4 -5
  124. package/helpers/inertiaAddHelper.d.ts +1 -1
  125. package/helpers/inertiaAddHelper.js +7 -6
  126. package/helpers/inertiaGroupHelper.js +10 -2
  127. package/helpers/inertiaListHelper.d.ts +1 -1
  128. package/helpers/inertiaListHelper.js +7 -8
  129. package/helpers/inertiaMenuHelper.d.ts +7 -2
  130. package/helpers/inertiaMenuHelper.js +12 -27
  131. package/helpers/menuHelper.d.ts +11 -1
  132. package/helpers/menuHelper.js +12 -0
  133. package/helpers/modelResourceHelper.d.ts +9 -0
  134. package/helpers/modelResourceHelper.js +43 -0
  135. package/helpers/navigationAccessHelper.d.ts +13 -0
  136. package/helpers/navigationAccessHelper.js +45 -0
  137. package/index.d.ts +11 -0
  138. package/index.js +11 -0
  139. package/interfaces/adminpanelConfig.d.ts +160 -2
  140. package/interfaces/queryCriteria.d.ts +13 -0
  141. package/interfaces/types.d.ts +169 -0
  142. package/lib/Adminizer.d.ts +8 -0
  143. package/lib/Adminizer.js +30 -2
  144. package/lib/DataAccessor.d.ts +100 -3
  145. package/lib/DataAccessor.js +454 -245
  146. package/lib/access-graph/AccessGraphResolver.d.ts +136 -0
  147. package/lib/access-graph/AccessGraphResolver.js +605 -0
  148. package/lib/access-graph/RecordAccessCache.d.ts +23 -0
  149. package/lib/access-graph/RecordAccessCache.js +30 -0
  150. package/lib/access-graph/RecordAccessResolver.d.ts +83 -0
  151. package/lib/access-graph/RecordAccessResolver.js +295 -0
  152. package/lib/access-graph/shared.d.ts +60 -0
  153. package/lib/access-graph/shared.js +121 -0
  154. package/lib/admin-links/AdminLinkHandler.d.ts +72 -0
  155. package/lib/admin-links/AdminLinkHandler.js +183 -0
  156. package/lib/ai-assistant/AbstractAiConversationHistoryService.d.ts +39 -0
  157. package/lib/ai-assistant/AbstractAiConversationHistoryService.js +98 -0
  158. package/lib/ai-assistant/AbstractAiModelService.d.ts +139 -2
  159. package/lib/ai-assistant/AbstractAiModelService.js +154 -1
  160. package/lib/ai-assistant/AiAgentRunManager.d.ts +35 -0
  161. package/lib/ai-assistant/AiAgentRunManager.js +109 -0
  162. package/lib/ai-assistant/AiAssistantAgentSkillHandler.d.ts +61 -0
  163. package/lib/ai-assistant/AiAssistantAgentSkillHandler.js +90 -0
  164. package/lib/ai-assistant/AiAssistantHandler.d.ts +1 -0
  165. package/lib/ai-assistant/AiAssistantHandler.js +4 -0
  166. package/lib/ai-assistant/AiAssistantUiMethodHandler.d.ts +60 -0
  167. package/lib/ai-assistant/AiAssistantUiMethodHandler.js +144 -0
  168. package/lib/ai-assistant/builtinAgentSkills.d.ts +9 -0
  169. package/lib/ai-assistant/builtinAgentSkills.js +259 -0
  170. package/lib/ai-assistant/jsonSafe.d.ts +13 -0
  171. package/lib/ai-assistant/jsonSafe.js +81 -0
  172. package/lib/app-manager/AdminizerApp.d.ts +40 -1
  173. package/lib/app-manager/AppManager.js +48 -42
  174. package/lib/app-manager/ConfigLayerHandler.js +4 -0
  175. package/lib/docs/AbstractDocumentation.d.ts +100 -0
  176. package/lib/docs/AbstractDocumentation.js +108 -0
  177. package/lib/docs/DocumentationHandler.d.ts +100 -0
  178. package/lib/docs/DocumentationHandler.js +198 -0
  179. package/lib/docs/FileDocumentation.d.ts +47 -0
  180. package/lib/docs/FileDocumentation.js +189 -0
  181. package/lib/docs/docsAgentSkills.d.ts +10 -0
  182. package/lib/docs/docsAgentSkills.js +93 -0
  183. package/lib/filters/FilterService.js +4 -3
  184. package/lib/history-actions/AbstractHistoryAdapter.d.ts +26 -1
  185. package/lib/history-actions/AbstractHistoryAdapter.js +155 -25
  186. package/lib/media-manager/helpers/MediaManagerHelper.js +9 -7
  187. package/lib/model/AbstractModel.d.ts +48 -0
  188. package/lib/model/AbstractModel.js +14 -4
  189. package/lib/model/ModelHandler.d.ts +61 -2
  190. package/lib/model/ModelHandler.js +136 -8
  191. package/lib/model/adapter/sequelize.d.ts +40 -1
  192. package/lib/model/adapter/sequelize.js +243 -77
  193. package/lib/model/adapter/typeorm.d.ts +16 -0
  194. package/lib/model/adapter/typeorm.js +136 -9
  195. package/lib/notifications/GeneralNotificationService.js +6 -5
  196. package/lib/notifications/SystemNotificationService.js +1 -1
  197. package/lib/ui-i18n/uiTranslationKeys.d.ts +2 -1
  198. package/lib/ui-i18n/uiTranslationKeys.js +42 -1
  199. package/lib/widgets/widgetHandler.js +10 -6
  200. package/models/Group.d.ts +2 -1
  201. package/package.json +35 -23
  202. package/policies/authPolicies.js +6 -6
  203. package/policies/permissionResolvers.d.ts +1 -0
  204. package/policies/permissionResolvers.js +3 -0
  205. package/system/Router.js +21 -3
  206. package/system/bindAccessRights.js +13 -3
  207. package/system/bindDocs.d.ts +13 -0
  208. package/system/bindDocs.js +77 -0
  209. package/system/bindInertia.js +30 -7
  210. package/system/buildInternalModelAccess.d.ts +9 -0
  211. package/system/buildInternalModelAccess.js +37 -4
  212. package/system/defaults.js +7 -1
  213. package/system/validateSystemModels.js +29 -9
  214. package/assets/add-CBlLpLr0.js +0 -1
  215. package/assets/add-group-H0IKIsNm.js +0 -1
  216. package/assets/add-user-CoTLmxtF.js +0 -1
  217. package/assets/app-DNXiApCk.css +0 -1
  218. package/assets/app-layout-xxJpLAvb.js +0 -1
  219. package/assets/app.js +0 -138
  220. package/assets/dashboard-DVJS5EPP.js +0 -3
  221. package/assets/debounce-BMmXVQ06.js +0 -1
  222. package/assets/history-bWRuzbye.js +0 -1
  223. package/assets/init-user-8aUohVDq.js +0 -1
  224. package/assets/login-CO4laf6m.js +0 -1
  225. package/assets/media-manager-BDbpSSjH.js +0 -6
  226. package/assets/module-CqO_BKsH.js +0 -1
  227. package/assets/notification-B5l2wwmi.js +0 -20
  228. package/assets/register-DBYIMXGQ.js +0 -1
  229. package/assets/ru-rYKdQbWF.js +0 -1
  230. package/assets/use-appearance-_EbbjHTh.js +0 -1
  231. package/assets/user-filters-list-C7kMKN5f.js +0 -1
  232. package/assets/welcome-6z-7sXnQ.js +0 -1
@@ -1,5 +1,6 @@
1
1
  import { AbstractModel } from "../lib/model/AbstractModel.js";
2
2
  import { ModelConfig } from "./adminpanelConfig.js";
3
+ import type { User } from "../models/User.js";
3
4
  export interface ModelResource {
4
5
  name: string;
5
6
  config?: ModelConfig;
@@ -11,7 +12,24 @@ export interface AccessRightsToken {
11
12
  description: string;
12
13
  department: string;
13
14
  id: string;
15
+ getOptions?: (user: User) => Promise<PermissionOption[]>;
16
+ check?: (user: User, context?: PermissionContext) => Promise<boolean>;
14
17
  }
18
+ export interface PermissionOption {
19
+ id: string;
20
+ name: string;
21
+ description?: string;
22
+ }
23
+ export interface PermissionContext {
24
+ rights?: string[];
25
+ [key: string]: unknown;
26
+ }
27
+ /** Serialized as a JSON string in Group.tokens for a contextual token. */
28
+ export interface GroupPermissionGrant {
29
+ tokenId: string;
30
+ rights: string[];
31
+ }
32
+ export type PermissionGrant = string | GroupPermissionGrant;
15
33
  export interface PropsField {
16
34
  label: string;
17
35
  type: string;
@@ -70,3 +88,154 @@ export interface AiAssistantModelInfo {
70
88
  name: string;
71
89
  description?: string;
72
90
  }
91
+ /**
92
+ * Streaming agent contract.
93
+ *
94
+ * A model service that only implements `generateReply` stays a plain chat
95
+ * model; services that also implement the optional agent members below are
96
+ * driven by the streaming UI (tool calls, reasoning, attachments, per-user
97
+ * server-side session). See AbstractAiModelService.
98
+ */
99
+ /** One SSE frame of a run. `type` drives how the UI folds it into the thread. */
100
+ export type AiAgentStreamEvent = {
101
+ type: 'text.delta' | 'text.done' | 'reasoning.delta' | 'reasoning.done' | 'tool.start' | 'tool.done' | 'tool.error' | 'step.done' | 'turn.done' | 'done' | 'error' | string;
102
+ [key: string]: unknown;
103
+ };
104
+ export type AiAgentPublish = (event: AiAgentStreamEvent) => void;
105
+ export interface AiAgentTokenUsage {
106
+ inputTokens?: number;
107
+ outputTokens?: number;
108
+ totalTokens?: number;
109
+ }
110
+ /** One selectable LLM inside an agent service. */
111
+ export interface AiAgentModelOption {
112
+ id: string;
113
+ contextWindow: number | null;
114
+ maxOutputTokens: number | null;
115
+ vision: boolean;
116
+ /** Relative spend multiplier (×1 = median-priced model); null if unknown. */
117
+ costCoefficient: number | null;
118
+ [key: string]: unknown;
119
+ }
120
+ /** State of the user's server-side agent session. */
121
+ export interface AiAgentSessionMeta {
122
+ model: string;
123
+ contextWindow: number;
124
+ vision: boolean;
125
+ turns: number;
126
+ contextTokens: number;
127
+ totalUsage: AiAgentTokenUsage;
128
+ [key: string]: unknown;
129
+ }
130
+ /**
131
+ * Whether the service can talk to its LLM yet. Services that need no
132
+ * provisioning simply omit `getConnectionStatus()` and are treated as ready.
133
+ */
134
+ export interface AiAgentConnectionStatus {
135
+ state: 'ready' | 'registering' | 'waiting_retry' | 'setup_required' | 'error';
136
+ provider?: string;
137
+ baseUrl?: string;
138
+ source?: string | null;
139
+ nextAttemptAt?: string | null;
140
+ lastError?: string | null;
141
+ expiresAt?: string | null;
142
+ [key: string]: unknown;
143
+ }
144
+ /** States for which an agent can describe its connection screen. */
145
+ export type AiAgentConnectionState = Exclude<AiAgentConnectionStatus['state'], 'ready'>;
146
+ /**
147
+ * Declarative connection screen supplied by an agent service. The shared panel
148
+ * owns rendering, while the agent owns its copy, CTA and which status details
149
+ * are useful to expose.
150
+ */
151
+ export interface AiAgentConnectionScreen {
152
+ title?: string;
153
+ description?: string;
154
+ icon?: 'spinner' | 'bot' | 'error';
155
+ action?: {
156
+ label: string;
157
+ href: string;
158
+ };
159
+ /** Status values the agent wants to render on this screen. */
160
+ details?: Array<{
161
+ field: string;
162
+ label?: string;
163
+ format?: 'text' | 'local-time';
164
+ tone?: 'muted' | 'error';
165
+ }>;
166
+ }
167
+ /** Normalized budget / rate limits of the provider key, when it exposes them. */
168
+ export interface AiAgentLimits {
169
+ provider: string;
170
+ supported: boolean;
171
+ overBudget?: boolean;
172
+ message?: string;
173
+ maxBudgetUsd?: number | null;
174
+ spentUsd?: number | null;
175
+ remainingBudgetUsd?: number | null;
176
+ budgetResetAt?: string | null;
177
+ burstMaxBudgetUsd?: number | null;
178
+ burstSpentUsd?: number | null;
179
+ burstRemainingBudgetUsd?: number | null;
180
+ burstResetAt?: string | null;
181
+ burstDurationLabel?: string | null;
182
+ rpmLimit?: number | null;
183
+ tpmLimit?: number | null;
184
+ fetchedAt?: string;
185
+ [key: string]: unknown;
186
+ }
187
+ /**
188
+ * Copy the panel shows instead of its neutral defaults. `getUiHints(locale)`
189
+ * receives the admin user's locale, so agents can return localized copy.
190
+ */
191
+ export interface AiAgentUiHints {
192
+ title?: string;
193
+ welcomeHint?: string;
194
+ composerPlaceholder?: string;
195
+ suggestions?: string[];
196
+ /** Setting an operator must fill in before the service can connect. */
197
+ setupSetting?: string;
198
+ /** Where to fill it in; rendered as a button on the connection loader. */
199
+ setupUrl?: string;
200
+ /**
201
+ * Per-state pages rendered while this agent is not ready. `default` is
202
+ * used for any state without its own screen.
203
+ */
204
+ connectionScreens?: Partial<Record<AiAgentConnectionState | 'default', AiAgentConnectionScreen>>;
205
+ [key: string]: unknown;
206
+ }
207
+ /** A browser-side capability which an agent may call through `ui.method`. */
208
+ export interface AiAgentUiMethod {
209
+ id: string;
210
+ title: string;
211
+ description: string;
212
+ inputSchema: Record<string, unknown>;
213
+ action: string;
214
+ accessRightsToken?: string;
215
+ }
216
+ /** Declarative UI contract consumed by the shared assistant panel. */
217
+ export interface AiAgentUiSchema extends AiAgentUiHints {
218
+ commands: Array<{
219
+ id: string;
220
+ description?: string;
221
+ }>;
222
+ uiMethods?: AiAgentUiMethod[];
223
+ panels: {
224
+ history: boolean;
225
+ models: boolean;
226
+ limits: boolean;
227
+ };
228
+ }
229
+ /** An uploaded file as handed to the agent service (multer memory storage). */
230
+ export interface AiAgentUploadedFile {
231
+ originalname: string;
232
+ mimetype: string;
233
+ size: number;
234
+ buffer: Buffer;
235
+ }
236
+ /** What the service reports back about a stored upload, if it stores them. */
237
+ export interface AiAgentSavedFile {
238
+ id?: string;
239
+ name?: string;
240
+ [key: string]: unknown;
241
+ }
@@ -27,6 +27,10 @@ import { ControllerHandler } from "./app-manager/ControllerHandler.js";
27
27
  import { AssetHandler } from "./app-manager/AssetHandler.js";
28
28
  import { ConfigLayerHandler } from "./app-manager/ConfigLayerHandler.js";
29
29
  import { AccessRightsHandler } from "./access-rights/AccessRightsHandler.js";
30
+ import { AiAssistantUiMethodHandler } from './ai-assistant/AiAssistantUiMethodHandler.js';
31
+ import { AdminLinkHandler } from './admin-links/AdminLinkHandler.js';
32
+ import { AiAssistantAgentSkillHandler } from './ai-assistant/AiAssistantAgentSkillHandler.js';
33
+ import { DocumentationHandler } from './docs/DocumentationHandler.js';
30
34
  export declare function createAdminizerLogger(): winston.Logger;
31
35
  export interface EmitAsyncOptions {
32
36
  /**
@@ -54,6 +58,10 @@ export declare class Adminizer {
54
58
  notificationHandler: NotificationHandler;
55
59
  historyHandler: HistoryHandler;
56
60
  private _aiAssistantHandler?;
61
+ aiAssistantUiMethodHandler: AiAssistantUiMethodHandler;
62
+ adminLinkHandler: AdminLinkHandler;
63
+ aiAssistantAgentSkillHandler: AiAssistantAgentSkillHandler;
64
+ documentationHandler: DocumentationHandler;
57
65
  modelHandler: ModelHandler;
58
66
  widgetHandler: WidgetHandler;
59
67
  customFilterHandler: CustomFilterHandler;
package/lib/Adminizer.js CHANGED
@@ -37,12 +37,18 @@ import { bindCors } from "../system/bindCors.js";
37
37
  import bindHistory from "../system/bindHistory.js";
38
38
  import bindCustomFilterHandlers from "../system/bindCustomFilterHandlers.js";
39
39
  import { FeedbackHandler } from "./feedback/FeedbackHandler.js";
40
- import { buildInternalModelAccess } from "../system/buildInternalModelAccess.js";
40
+ import { refreshInternalModelAccess } from "../system/buildInternalModelAccess.js";
41
+ import { validateAccessGraph } from "./access-graph/AccessGraphResolver.js";
41
42
  import { AppManager } from "./app-manager/AppManager.js";
42
43
  import { ControllerHandler } from "./app-manager/ControllerHandler.js";
43
44
  import { AssetHandler } from "./app-manager/AssetHandler.js";
44
45
  import { ConfigLayerHandler } from "./app-manager/ConfigLayerHandler.js";
45
46
  import { AccessRightsHandler } from "./access-rights/AccessRightsHandler.js";
47
+ import { AiAssistantUiMethodHandler } from './ai-assistant/AiAssistantUiMethodHandler.js';
48
+ import { AdminLinkHandler } from './admin-links/AdminLinkHandler.js';
49
+ import { AiAssistantAgentSkillHandler } from './ai-assistant/AiAssistantAgentSkillHandler.js';
50
+ import { DocumentationHandler } from './docs/DocumentationHandler.js';
51
+ import bindDocs from '../system/bindDocs.js';
46
52
  const logFilePath = "logs/app.log";
47
53
  function ensureLogDirectory(filePath) {
48
54
  const logDirectory = path.dirname(filePath);
@@ -109,6 +115,10 @@ export class Adminizer {
109
115
  notificationHandler;
110
116
  historyHandler;
111
117
  _aiAssistantHandler;
118
+ aiAssistantUiMethodHandler;
119
+ adminLinkHandler;
120
+ aiAssistantAgentSkillHandler;
121
+ documentationHandler;
112
122
  modelHandler;
113
123
  widgetHandler;
114
124
  customFilterHandler;
@@ -141,10 +151,20 @@ export class Adminizer {
141
151
  this.catalogTemplateComponentHandler = new CatalogTemplateComponentHandler();
142
152
  this.mediaManagerHandler = new MediaManagerHandler();
143
153
  this.feedbackHandler = new FeedbackHandler(this);
154
+ this.aiAssistantUiMethodHandler = new AiAssistantUiMethodHandler(this);
155
+ this.adminLinkHandler = new AdminLinkHandler(this);
156
+ this.aiAssistantAgentSkillHandler = new AiAssistantAgentSkillHandler(this);
157
+ this.documentationHandler = new DocumentationHandler(this, () => bindDocs(this));
144
158
  this.controllerHandler = new ControllerHandler(this);
145
159
  this.assetHandler = new AssetHandler(this);
146
160
  this.configLayerHandler = new ConfigLayerHandler(this);
147
161
  this.appManager = new AppManager(this);
162
+ // Registering or unregistering a model changes what the record-access resolvers may
163
+ // query, so the internal allowlists must follow the registry. Keying it on the
164
+ // registry itself also covers hosts that bind models directly through
165
+ // `modelHandler.add` after init, which emits no app:model:* event; config-layer
166
+ // rebuilds refresh them synchronously inside rebuildConfig itself.
167
+ this.modelHandler.setInternalAccessRefresher(() => refreshInternalModelAccess(this));
148
168
  }
149
169
  /**
150
170
  * Shared AI assistant model registry.
@@ -257,7 +277,10 @@ export class Adminizer {
257
277
  this.emitter.emit('adminizer:init');
258
278
  // validate models
259
279
  validateSystemModels(this);
260
- this.modelHandler.configureInternalAccess(buildInternalModelAccess(this.config, this.modelHandler));
280
+ refreshInternalModelAccess(this);
281
+ // Fail loud on structural accessGraph errors at boot; later config rebuilds only
282
+ // log them and the affected models fail closed at access time.
283
+ validateAccessGraph(this);
261
284
  bindCustomFilterHandlers(this);
262
285
  this.config.rootPath = path.resolve(import.meta.dirname + "/..");
263
286
  await this.middlewareManager.loadMiddlewares();
@@ -293,6 +316,11 @@ export class Adminizer {
293
316
  bindHistory(this);
294
317
  this.router = new Router(this);
295
318
  await this.router.bind(); // must be after binding policies and req/res functions
319
+ // Documentation (knowledge base) wires itself on register(); this call
320
+ // covers a service registered before the config was read. It runs after
321
+ // the router so those routes sit behind the same middleware stack a
322
+ // service registered after init() gets.
323
+ this.documentationHandler.activate();
296
324
  /**
297
325
  * Adminizer loaded
298
326
  * This call is used so that other apps can know that the admin panel is present in the panel and has been loaded, and can activate their logic.
@@ -6,7 +6,8 @@ import { ActionType } from "../interfaces/adminpanelConfig.js";
6
6
  import { Fields } from "../helpers/fieldsHelper.js";
7
7
  import { Adminizer } from "./Adminizer.js";
8
8
  import { User } from "../models/User.js";
9
- import { QueryCriteria } from "../interfaces/queryCriteria.js";
9
+ import { CriteriaWhere, QueryCriteria } from "../interfaces/queryCriteria.js";
10
+ import { RecordAccessCache } from "./access-graph/RecordAccessCache.js";
10
11
  export declare class DataAccessor {
11
12
  readonly adminizer: Adminizer;
12
13
  user: User;
@@ -14,10 +15,23 @@ export declare class DataAccessor {
14
15
  action: ActionType;
15
16
  private fields;
16
17
  private actionVerb;
17
- constructor(adminizer: Adminizer, user: User, modelResource: ModelResource, action: ActionType);
18
+ private associatedPrimaryKeyCache;
19
+ private recordAccessAssociationFieldsCache?;
20
+ /** Set on the internal accessors used to verify associations — see disablePopulateAccess(). */
21
+ private populateAccessDisabled;
22
+ /** Accessors of associated models, so their access lookups are resolved once per model. */
23
+ private associatedAccessorCache;
24
+ /** Per-request record-access resolver; its memoized id lists live as long as this accessor. */
25
+ private recordAccessResolver?;
26
+ /**
27
+ * Memoization shared with the other accessors of the same request; pass one when
28
+ * building several accessors for one page so the membership lookups run once.
29
+ */
30
+ readonly recordAccessCache: RecordAccessCache;
31
+ constructor(adminizer: Adminizer, user: User, modelResource: ModelResource, action: ActionType, recordAccessCache?: RecordAccessCache);
18
32
  private getModelConfig;
19
- private accessRelationModel;
20
33
  private resolveRelationTarget;
34
+ private getRelationModel;
21
35
  /**
22
36
  * Retrieves the fields for the given ModelResource based on action type,
23
37
  * taking into account access rights and configuration settings.
@@ -26,10 +40,23 @@ export declare class DataAccessor {
26
40
  getFieldsConfig(): Fields;
27
41
  private orderFieldsByConfig;
28
42
  private getAssociatedFieldsConfig;
43
+ /**
44
+ * Base config for a field: the normalized declared config merged over `{key, title}`,
45
+ * or `undefined` when the config is invalid or field access is denied.
46
+ */
47
+ private buildBaseFieldConfig;
29
48
  private checkFieldAccess;
30
49
  private getSelectedFields;
31
50
  private getPopulateCriteria;
51
+ /** Administrators, and every user when authorization is switched off entirely. */
52
+ private hasUnrestrictedAccess;
32
53
  private canUseSelectedFieldFallback;
54
+ /**
55
+ * Primary key of a field's associated model, for the PK-always-visible rule on
56
+ * populated records. Cached per field config: `process()` asks once per associated
57
+ * item of every record, and the answer cannot change within an accessor's lifetime.
58
+ */
59
+ private associatedPrimaryKey;
33
60
  /**
34
61
  * Returns filtered record applying config from this.fields on this record
35
62
  * @data - record from a specific model */
@@ -38,6 +65,76 @@ export declare class DataAccessor {
38
65
  private filterAssociatedRecord;
39
66
  /** Process for an array of records */
40
67
  processMany<T>(records: T[], criteria?: QueryCriteria): Partial<T>[];
68
+ /**
69
+ * {@link processMany} plus record-level access on populated associations.
70
+ *
71
+ * `sanitizeUserRelationAccess` confines the queried model only, while adapters
72
+ * populate associations regardless of record access — so a record the user may not reach can
73
+ * still be read through a relation of one they may. Records the target model's own rules
74
+ * keep out of reach are reduced to their primary key here, which costs one batched query
75
+ * per associated restricted model (memoized for the accessor's lifetime) — except the
76
+ * associations whose confinement {@link pushDownPopulateAccess} already compiled into
77
+ * the populate JOIN itself: those arrive pre-reduced and are skipped.
78
+ *
79
+ * Read paths only: write paths hand back the record the user just supplied.
80
+ */
81
+ processManyWithAccess<T>(records: T[], criteria?: QueryCriteria): Promise<Partial<T>[]>;
82
+ /**
83
+ * Compiles the record-access confinement of single populated associations into the
84
+ * criteria (`populateOn`), so the adapter ANDs it into the populate JOIN's ON clause
85
+ * and {@link processManyWithAccess} skips the post-read query for those fields — the
86
+ * closed records arrive as bare foreign keys straight from the database. Only the
87
+ * associations the adapter declares pushdown-capable and whose access filter has an
88
+ * adapter-portable shape are compiled; the rest keep the post-read verification.
89
+ *
90
+ * Single associations only: a filtered-out belongsTo row still carries its foreign
91
+ * key, while a record dropped from a populated collection would lose its id — and an
92
+ * edit form saving that truncated collection would silently sever the links.
93
+ *
94
+ * Any incoming `populateOn` is discarded — this method is its sole author, because
95
+ * the verification skip above trusts the key.
96
+ */
97
+ pushDownPopulateAccess(criteria?: QueryCriteria): Promise<QueryCriteria>;
98
+ /**
99
+ * Turns the association verification of {@link processManyWithAccess} off for this accessor.
100
+ * Used for the accessors that perform that verification themselves: they only read ids,
101
+ * and two restricted models referencing each other sideways would otherwise recurse.
102
+ */
103
+ disablePopulateAccess(): this;
104
+ /**
105
+ * Association fields whose target model is access-restricted and whose content therefore
106
+ * needs verifying — except the edge pointing at this model's own graph parent, where
107
+ * the target is reachable by construction (a visible child hangs off a visible parent).
108
+ */
109
+ private recordAccessAssociationFields;
110
+ /** True when the model confines its records to the user, by its own relation or the graph. */
111
+ private hasRecordAccessRules;
112
+ private associatedResourceName;
113
+ /** Primary keys of the populated records referenced by a field, keyed by their string form. */
114
+ private collectAssociatedIds;
115
+ /** Replaces populated records the user may not reach with their bare primary key. */
116
+ private reduceInvisibleAssociations;
117
+ /**
118
+ * The associated model's own view accessor, shared between the pushdown and the
119
+ * post-read verification so its access lookups resolve once per model.
120
+ */
121
+ private associatedAccessor;
122
+ /**
123
+ * Subset of `ids` the user may reach in the associated model, or `undefined` when that
124
+ * model has no record access rules. The target's own accessor is reused across calls, so its
125
+ * membership lookups are resolved once.
126
+ */
127
+ private visibleAssociatedIds;
41
128
  sanitizeUserRelationAccess(criteria?: QueryCriteria): Promise<QueryCriteria>;
42
129
  setUserRelationAccess<T>(record: T): Promise<Partial<T>>;
130
+ /**
131
+ * Where-fragment confining this model to the records the user may reach
132
+ * (`userAccessRelation` or accessGraph); `{}` means no record-level constraint.
133
+ *
134
+ * For surfaces that reference records without reading them through the model API —
135
+ * the change history, for one — and therefore cannot rely on
136
+ * {@link sanitizeUserRelationAccess} doing it for them.
137
+ */
138
+ getRecordAccessWhere(): Promise<CriteriaWhere>;
139
+ private getRecordAccessResolver;
43
140
  }