@quazardous/qdadm 1.19.3

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 (291) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/package.json +101 -0
  4. package/src/assets/logo.svg +6 -0
  5. package/src/auth/SessionAuthAdapter.ts +459 -0
  6. package/src/auth/index.ts +15 -0
  7. package/src/chain/ActiveStack.ts +154 -0
  8. package/src/chain/StackHydrator.ts +292 -0
  9. package/src/chain/index.ts +25 -0
  10. package/src/chain/useActiveStack.ts +120 -0
  11. package/src/chain/useStackHydrator.ts +155 -0
  12. package/src/components/BoolCell.vue +34 -0
  13. package/src/components/InfoBanner.vue +73 -0
  14. package/src/components/QdadmRoot.vue +52 -0
  15. package/src/components/SeverityTag.vue +86 -0
  16. package/src/components/dialogs/BulkStatusDialog.vue +60 -0
  17. package/src/components/dialogs/MultiStepDialog.vue +331 -0
  18. package/src/components/dialogs/SimpleDialog.vue +122 -0
  19. package/src/components/dialogs/UnsavedChangesDialog.vue +80 -0
  20. package/src/components/display/BannerZone.vue +65 -0
  21. package/src/components/display/CardsGrid.vue +72 -0
  22. package/src/components/display/CopyableId.vue +84 -0
  23. package/src/components/display/EmptyState.vue +62 -0
  24. package/src/components/display/IntensityBar.vue +190 -0
  25. package/src/components/display/RichCardsGrid.vue +101 -0
  26. package/src/components/edit/FormActions.vue +78 -0
  27. package/src/components/edit/FormField.vue +82 -0
  28. package/src/components/edit/FormInput.vue +158 -0
  29. package/src/components/edit/FormPage.vue +260 -0
  30. package/src/components/edit/FormTab.vue +217 -0
  31. package/src/components/edit/FormTabs.vue +120 -0
  32. package/src/components/edit/LookupField.vue +406 -0
  33. package/src/components/edit/LookupPickerDialog.vue +230 -0
  34. package/src/components/editors/JsonEditorFoldable.vue +470 -0
  35. package/src/components/editors/JsonStructuredField.vue +264 -0
  36. package/src/components/editors/JsonViewer.vue +51 -0
  37. package/src/components/editors/KeyValueEditor.vue +314 -0
  38. package/src/components/editors/LanguageEditor.vue +259 -0
  39. package/src/components/editors/PermissionEditor.vue +558 -0
  40. package/src/components/editors/ScopeEditor.vue +372 -0
  41. package/src/components/editors/VanillaJsonEditor.vue +183 -0
  42. package/src/components/index.ts +83 -0
  43. package/src/components/item/FieldGroups.vue +392 -0
  44. package/src/components/layout/AppLayout.vue +1032 -0
  45. package/src/components/layout/BaseLayout.vue +190 -0
  46. package/src/components/layout/Breadcrumb.vue +55 -0
  47. package/src/components/layout/DashboardLayout.vue +104 -0
  48. package/src/components/layout/FormLayout.vue +256 -0
  49. package/src/components/layout/ListLayout.vue +278 -0
  50. package/src/components/layout/PageHeader.vue +156 -0
  51. package/src/components/layout/PageLayout.vue +126 -0
  52. package/src/components/layout/PageNav.vue +192 -0
  53. package/src/components/layout/SidebarBox.vue +87 -0
  54. package/src/components/layout/Zone.vue +182 -0
  55. package/src/components/layout/defaults/DefaultBreadcrumb.vue +149 -0
  56. package/src/components/layout/defaults/DefaultFooter.vue +89 -0
  57. package/src/components/layout/defaults/DefaultFormActions.vue +67 -0
  58. package/src/components/layout/defaults/DefaultHeader.vue +78 -0
  59. package/src/components/layout/defaults/DefaultMenu.vue +188 -0
  60. package/src/components/layout/defaults/DefaultPagination.vue +75 -0
  61. package/src/components/layout/defaults/DefaultTable.vue +137 -0
  62. package/src/components/layout/defaults/DefaultUserInfo.vue +111 -0
  63. package/src/components/layout/defaults/index.ts +16 -0
  64. package/src/components/lists/ActionButtons.vue +49 -0
  65. package/src/components/lists/ActionColumn.vue +40 -0
  66. package/src/components/lists/FilterBar.vue +54 -0
  67. package/src/components/lists/ListPage.vue +467 -0
  68. package/src/components/pages/LoginPage.vue +334 -0
  69. package/src/components/pages/NotFoundPage.vue +98 -0
  70. package/src/components/show/ShowDisplay.vue +343 -0
  71. package/src/components/show/ShowField.vue +67 -0
  72. package/src/components/show/ShowPage.vue +431 -0
  73. package/src/composables/index.ts +155 -0
  74. package/src/composables/useApp.ts +67 -0
  75. package/src/composables/useAuth.ts +98 -0
  76. package/src/composables/useBareForm.ts +319 -0
  77. package/src/composables/useBreadcrumb.ts +252 -0
  78. package/src/composables/useChildPage.ts +113 -0
  79. package/src/composables/useCurrentEntity.ts +60 -0
  80. package/src/composables/useDeferred.ts +94 -0
  81. package/src/composables/useDirtyState.ts +138 -0
  82. package/src/composables/useEntityItemFormPage.ts +942 -0
  83. package/src/composables/useEntityItemFormPage.types.ts +451 -0
  84. package/src/composables/useEntityItemPage.ts +438 -0
  85. package/src/composables/useEntityItemShowPage.ts +722 -0
  86. package/src/composables/useFieldManager.ts +692 -0
  87. package/src/composables/useForm.ts +544 -0
  88. package/src/composables/useGuardStore.ts +53 -0
  89. package/src/composables/useHooks.ts +56 -0
  90. package/src/composables/useInfoBanner.ts +217 -0
  91. package/src/composables/useJsonSyntax.ts +122 -0
  92. package/src/composables/useLayoutResolver.ts +329 -0
  93. package/src/composables/useListPage.ts +1535 -0
  94. package/src/composables/useListPage.types.ts +437 -0
  95. package/src/composables/useListPage.utils.ts +101 -0
  96. package/src/composables/useNavContext.ts +439 -0
  97. package/src/composables/useNavigation.ts +216 -0
  98. package/src/composables/useOptionsLookup.ts +323 -0
  99. package/src/composables/usePageTitle.ts +84 -0
  100. package/src/composables/useSSEBridge.ts +142 -0
  101. package/src/composables/useSemanticBreadcrumb.ts +222 -0
  102. package/src/composables/useSidebarState.ts +24 -0
  103. package/src/composables/useSignals.ts +52 -0
  104. package/src/composables/useUnsavedChangesGuard.ts +155 -0
  105. package/src/composables/useUserImpersonator.ts +317 -0
  106. package/src/composables/useZoneRegistry.ts +252 -0
  107. package/src/core/bundles.ts +558 -0
  108. package/src/core/decorator.ts +420 -0
  109. package/src/core/extension.ts +470 -0
  110. package/src/core/index.ts +59 -0
  111. package/src/deferred/DeferredRegistry.ts +353 -0
  112. package/src/deferred/index.ts +15 -0
  113. package/src/editors/index.ts +12 -0
  114. package/src/entity/EntityManager.cache.ts +530 -0
  115. package/src/entity/EntityManager.crud.ts +615 -0
  116. package/src/entity/EntityManager.interface.ts +78 -0
  117. package/src/entity/EntityManager.query.ts +221 -0
  118. package/src/entity/EntityManager.relations.ts +151 -0
  119. package/src/entity/EntityManager.ts +944 -0
  120. package/src/entity/EntityManager.types.ts +288 -0
  121. package/src/entity/auth/CompositeAuthAdapter.ts +194 -0
  122. package/src/entity/auth/EntityAuthAdapter.ts +119 -0
  123. package/src/entity/auth/PermissiveAdapter.ts +43 -0
  124. package/src/entity/auth/RoleHierarchy.ts +128 -0
  125. package/src/entity/auth/SecurityChecker.ts +202 -0
  126. package/src/entity/auth/factory.ts +203 -0
  127. package/src/entity/auth/index.ts +47 -0
  128. package/src/entity/factory.test.js +189 -0
  129. package/src/entity/factory.ts +146 -0
  130. package/src/entity/index.ts +49 -0
  131. package/src/entity/storage/ApiStorage.ts +228 -0
  132. package/src/entity/storage/IStorage.ts +100 -0
  133. package/src/entity/storage/LocalStorage.ts +200 -0
  134. package/src/entity/storage/MemoryStorage.ts +184 -0
  135. package/src/entity/storage/MockApiStorage.ts +318 -0
  136. package/src/entity/storage/SdkStorage.ts +377 -0
  137. package/src/entity/storage/factory.test.js +159 -0
  138. package/src/entity/storage/factory.ts +209 -0
  139. package/src/entity/storage/index.ts +75 -0
  140. package/src/gen/FieldMapper.ts +122 -0
  141. package/src/gen/StorageProfileFactory.ts +93 -0
  142. package/src/gen/connectors/BaseConnector.ts +150 -0
  143. package/src/gen/connectors/ManualConnector.test.js +499 -0
  144. package/src/gen/connectors/ManualConnector.ts +414 -0
  145. package/src/gen/connectors/OpenAPIConnector.test.js +836 -0
  146. package/src/gen/connectors/OpenAPIConnector.ts +693 -0
  147. package/src/gen/connectors/__fixtures__/sample-openapi.json +311 -0
  148. package/src/gen/connectors/index.ts +27 -0
  149. package/src/gen/createManagers.ts +245 -0
  150. package/src/gen/decorators.ts +134 -0
  151. package/src/gen/generateManagers.test.js +540 -0
  152. package/src/gen/generateManagers.ts +398 -0
  153. package/src/gen/index.ts +66 -0
  154. package/src/gen/schema.ts +248 -0
  155. package/src/gen/vite-plugin.ts +114 -0
  156. package/src/generated/managers/testManager.js +45 -0
  157. package/src/generated/managers/testManager.ts +46 -0
  158. package/src/hooks/HookRegistry.ts +16 -0
  159. package/src/hooks/index.ts +15 -0
  160. package/src/i18n/I18n.ts +344 -0
  161. package/src/i18n/IncrementalDomainProvider.ts +153 -0
  162. package/src/i18n/InlineTranslationProvider.ts +4 -0
  163. package/src/i18n/LazyTranslationProvider.ts +102 -0
  164. package/src/i18n/MessagesRegistry.ts +4 -0
  165. package/src/i18n/Resolver.ts +4 -0
  166. package/src/i18n/__tests__/I18n.test.ts +169 -0
  167. package/src/i18n/__tests__/IncrementalDomainProvider.test.ts +146 -0
  168. package/src/i18n/__tests__/LazyTranslationProvider.test.ts +100 -0
  169. package/src/i18n/__tests__/Resolver.test.ts +271 -0
  170. package/src/i18n/defaults/DefaultCoreProvider.ts +28 -0
  171. package/src/i18n/defaults/core.en.yml +55 -0
  172. package/src/i18n/defaults/core.fr.yml +55 -0
  173. package/src/i18n/index.ts +55 -0
  174. package/src/i18n/loaders/raw-modules.d.ts +15 -0
  175. package/src/i18n/loaders/yaml.ts +35 -0
  176. package/src/i18n/strategies.ts +4 -0
  177. package/src/i18n/types.ts +34 -0
  178. package/src/i18n/useI18n.ts +34 -0
  179. package/src/index.ts +453 -0
  180. package/src/kernel/EventRouter.ts +23 -0
  181. package/src/kernel/Kernel.api.ts +79 -0
  182. package/src/kernel/Kernel.auth.ts +120 -0
  183. package/src/kernel/Kernel.i18n.ts +29 -0
  184. package/src/kernel/Kernel.modules.ts +170 -0
  185. package/src/kernel/Kernel.registries.ts +237 -0
  186. package/src/kernel/Kernel.routing.ts +334 -0
  187. package/src/kernel/Kernel.ts +460 -0
  188. package/src/kernel/Kernel.types.ts +263 -0
  189. package/src/kernel/Kernel.vue.ts +304 -0
  190. package/src/kernel/KernelContext.entities.ts +80 -0
  191. package/src/kernel/KernelContext.events.ts +57 -0
  192. package/src/kernel/KernelContext.i18n.ts +37 -0
  193. package/src/kernel/KernelContext.permissions.ts +38 -0
  194. package/src/kernel/KernelContext.routing.ts +280 -0
  195. package/src/kernel/KernelContext.ts +252 -0
  196. package/src/kernel/KernelContext.types.ts +173 -0
  197. package/src/kernel/KernelContext.zones.ts +54 -0
  198. package/src/kernel/Module.ts +169 -0
  199. package/src/kernel/ModuleLoader.ts +645 -0
  200. package/src/kernel/SSEBridge.ts +11 -0
  201. package/src/kernel/SignalBus.ts +48 -0
  202. package/src/kernel/index.ts +56 -0
  203. package/src/module/index.ts +33 -0
  204. package/src/module/moduleRegistry.ts +492 -0
  205. package/src/modules/debug/AuthCollector.ts +501 -0
  206. package/src/modules/debug/Collector.ts +20 -0
  207. package/src/modules/debug/DebugBridge.ts +14 -0
  208. package/src/modules/debug/DebugModule.ts +220 -0
  209. package/src/modules/debug/EntitiesCollector.ts +839 -0
  210. package/src/modules/debug/ErrorCollector.ts +4 -0
  211. package/src/modules/debug/I18nCollector.ts +9 -0
  212. package/src/modules/debug/LocalStorageAdapter.ts +7 -0
  213. package/src/modules/debug/RouterCollector.ts +449 -0
  214. package/src/modules/debug/SignalCollector.ts +4 -0
  215. package/src/modules/debug/ToastCollector.ts +4 -0
  216. package/src/modules/debug/ZonesCollector.ts +447 -0
  217. package/src/modules/debug/components/DebugBar.vue +31 -0
  218. package/src/modules/debug/components/adminPanelsConfig.ts +42 -0
  219. package/src/modules/debug/components/index.ts +9 -0
  220. package/src/modules/debug/components/panels/AuthPanel.vue +267 -0
  221. package/src/modules/debug/components/panels/EntitiesPanel.vue +572 -0
  222. package/src/modules/debug/components/panels/I18nPanel.vue +738 -0
  223. package/src/modules/debug/components/panels/RouterPanel.vue +440 -0
  224. package/src/modules/debug/components/panels/ZonesPanel.vue +133 -0
  225. package/src/modules/debug/components/panels/index.ts +16 -0
  226. package/src/modules/debug/index.ts +58 -0
  227. package/src/modules/debug/styles.scss +2671 -0
  228. package/src/notifications/NotificationBadge.vue +35 -0
  229. package/src/notifications/NotificationListener.vue +71 -0
  230. package/src/notifications/NotificationModule.ts +76 -0
  231. package/src/notifications/NotificationPanel.vue +478 -0
  232. package/src/notifications/NotificationStore.ts +288 -0
  233. package/src/notifications/index.ts +42 -0
  234. package/src/notifications/styles.scss +32 -0
  235. package/src/orchestrator/Orchestrator.ts +427 -0
  236. package/src/orchestrator/index.ts +8 -0
  237. package/src/orchestrator/useOrchestrator.ts +80 -0
  238. package/src/plugin.ts +251 -0
  239. package/src/query/FilterQuery.ts +306 -0
  240. package/src/query/QueryExecutor.ts +341 -0
  241. package/src/query/index.ts +16 -0
  242. package/src/security/EntityRolesProvider.ts +385 -0
  243. package/src/security/PermissionMatcher.ts +152 -0
  244. package/src/security/PermissionRegistry.ts +273 -0
  245. package/src/security/PersistableRolesProvider.ts +584 -0
  246. package/src/security/RolesManager.ts +136 -0
  247. package/src/security/RolesProvider.ts +167 -0
  248. package/src/security/RolesProviderStorage.ts +211 -0
  249. package/src/security/SecurityModule.ts +94 -0
  250. package/src/security/StaticRolesProvider.ts +117 -0
  251. package/src/security/UsersManager.ts +163 -0
  252. package/src/security/index.ts +77 -0
  253. package/src/security/pages/RoleForm.vue +276 -0
  254. package/src/security/pages/RoleList.vue +123 -0
  255. package/src/styles/_alerts.scss +95 -0
  256. package/src/styles/_buttons.scss +391 -0
  257. package/src/styles/_cards.scss +241 -0
  258. package/src/styles/_code.scss +78 -0
  259. package/src/styles/_dialogs.scss +55 -0
  260. package/src/styles/_filter-bar.scss +70 -0
  261. package/src/styles/_forms.scss +434 -0
  262. package/src/styles/_helpers.scss +153 -0
  263. package/src/styles/_lists.scss +225 -0
  264. package/src/styles/_main.scss +356 -0
  265. package/src/styles/_markdown.scss +88 -0
  266. package/src/styles/_responsive.scss +255 -0
  267. package/src/styles/_show-pages.scss +186 -0
  268. package/src/styles/_sidebar.scss +380 -0
  269. package/src/styles/_states.scss +115 -0
  270. package/src/styles/_stats.scss +47 -0
  271. package/src/styles/_variables.scss +224 -0
  272. package/src/styles/index.scss +38 -0
  273. package/src/styles/theme/_components.scss +331 -0
  274. package/src/styles/theme/_index.scss +10 -0
  275. package/src/styles/theme/_tokens.scss +147 -0
  276. package/src/styles/theme/_utilities.scss +175 -0
  277. package/src/toast/ToastBridgeModule.ts +68 -0
  278. package/src/toast/ToastListener.vue +55 -0
  279. package/src/toast/index.ts +26 -0
  280. package/src/toast/useSignalToast.ts +154 -0
  281. package/src/types/index.ts +285 -0
  282. package/src/types/pluralize.d.ts +19 -0
  283. package/src/types/quarkernel.d.ts +50 -0
  284. package/src/utils/formatters.ts +174 -0
  285. package/src/utils/index.ts +35 -0
  286. package/src/utils/transformers.ts +131 -0
  287. package/src/vite/qdadmDebugPlugin.ts +401 -0
  288. package/src/vite-env.d.ts +50 -0
  289. package/src/zones/ZoneRegistry.ts +934 -0
  290. package/src/zones/index.ts +29 -0
  291. package/src/zones/zones.ts +191 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Patch Kernel prototype with i18n-related methods.
3
+ *
4
+ * Adds:
5
+ * - kernel.i18n : I18n instance
6
+ * - _createI18n() : init step
7
+ * - _bootstrapI18n() : warmup step (loads default + fallback locales)
8
+ */
9
+
10
+ import { I18n } from '../i18n/I18n'
11
+ import type { I18nOptions } from '../i18n/types'
12
+
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ type Self = any
15
+
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ export function applyI18nMethods(KernelClass: { prototype: any }): void {
18
+ const proto = KernelClass.prototype as Self
19
+
20
+ proto._createI18n = function (this: Self): void {
21
+ const opts = (this.options.i18n as I18nOptions | undefined) ?? {}
22
+ this.i18nInstance = new I18n(opts, { signals: this.signals })
23
+ }
24
+
25
+ proto._bootstrapI18n = function (this: Self): Promise<void> {
26
+ if (!this.i18nInstance) return Promise.resolve()
27
+ return this.i18nInstance.bootstrap()
28
+ }
29
+ }
@@ -0,0 +1,170 @@
1
+ import { initModules, setSectionOrder } from '../module/moduleRegistry'
2
+ import { createModuleLoader, type ModuleLike } from './ModuleLoader'
3
+ import { createKernelContext, type KernelContext } from './KernelContext'
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ type Self = any
6
+
7
+ /**
8
+ * Patch Kernel prototype with module-related methods.
9
+ */
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ export function applyModuleMethods(KernelClass: { prototype: any }): void {
12
+ const proto = KernelClass.prototype as Self
13
+
14
+ /**
15
+ * Fire entity cache warmups
16
+ */
17
+ proto._fireWarmups = function (this: Self): void {
18
+ if (this.i18nInstance) {
19
+ // Fire-and-forget bootstrap; locale-sensitive pages await
20
+ // 'i18n:locale:{loc}:ready' via DeferredRegistry if needed.
21
+ void this._bootstrapI18n()
22
+ }
23
+
24
+ const warmup = this.options.warmup ?? true
25
+ if (!warmup) return
26
+
27
+ this.orchestrator!.fireWarmups()
28
+ }
29
+
30
+ /**
31
+ * Initialize legacy modules from glob import
32
+ */
33
+ proto._initModules = function (this: Self): void {
34
+ if (this.options.sectionOrder) {
35
+ setSectionOrder(this.options.sectionOrder)
36
+ }
37
+ if (this.options.modules) {
38
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
+ initModules(this.options.modules as any, {
40
+ ...this.options.modulesOptions,
41
+ zones: this.zoneRegistry,
42
+ signals: this.signals,
43
+ hooks: this.hookRegistry,
44
+ deferred: this.deferred,
45
+ } as any)
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Create KernelContext for module connection
51
+ */
52
+ proto._createModuleContext = function (this: Self, module: ModuleLike): KernelContext {
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ return createKernelContext(this as any, module as any)
55
+ }
56
+
57
+ /**
58
+ * Load new-style modules synchronously
59
+ */
60
+ proto._loadModulesSync = function (this: Self): void {
61
+ const { moduleDefs } = this.options
62
+ if (!moduleDefs?.length) return
63
+
64
+ this.moduleLoader = createModuleLoader()
65
+
66
+ for (const mod of moduleDefs) {
67
+ this.moduleLoader.add(mod as ModuleLike)
68
+ }
69
+
70
+ // Access private method for sorting
71
+ const sorted = (this.moduleLoader as unknown as { _topologicalSort(): string[] })._topologicalSort()
72
+ const registered = (this.moduleLoader as unknown as { _registered: Map<string, ModuleLike> })._registered
73
+ const loaded = (this.moduleLoader as unknown as { _loaded: Map<string, ModuleLike> })._loaded
74
+ const loadOrder = (this.moduleLoader as unknown as { _loadOrder: string[] })._loadOrder
75
+
76
+ for (const name of sorted) {
77
+ const module = registered.get(name)
78
+ if (!module) continue
79
+
80
+ const ctx = this._createModuleContext(module)
81
+
82
+ if (!module.enabled(ctx as unknown as Parameters<typeof module.enabled>[0])) {
83
+ continue
84
+ }
85
+
86
+ if (typeof module.loadStyles === 'function') {
87
+ const styleResult = module.loadStyles()
88
+ if (styleResult instanceof Promise) {
89
+ styleResult.catch((err) => {
90
+ console.warn(`[Kernel] Module '${name}' styles failed:`, err)
91
+ })
92
+ }
93
+ }
94
+
95
+ const result = module.connect(ctx as unknown as Parameters<typeof module.connect>[0])
96
+
97
+ if (result instanceof Promise) {
98
+ result.catch((err) => {
99
+ console.error(`[Kernel] Async module '${name}' failed:`, err)
100
+ })
101
+ }
102
+
103
+ loaded.set(name, module)
104
+ loadOrder.push(name)
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Load new-style modules asynchronously
110
+ */
111
+ proto._loadModules = async function (this: Self): Promise<void> {
112
+ const { moduleDefs } = this.options
113
+ if (!moduleDefs?.length) return
114
+
115
+ this.moduleLoader = createModuleLoader()
116
+
117
+ for (const mod of moduleDefs) {
118
+ this.moduleLoader.add(mod as ModuleLike)
119
+ }
120
+
121
+ const sorted = (this.moduleLoader as unknown as { _topologicalSort(): string[] })._topologicalSort()
122
+ const registered = (this.moduleLoader as unknown as { _registered: Map<string, ModuleLike> })._registered
123
+ const loaded = (this.moduleLoader as unknown as { _loaded: Map<string, ModuleLike> })._loaded
124
+ const loadOrder = (this.moduleLoader as unknown as { _loadOrder: string[] })._loadOrder
125
+
126
+ for (const name of sorted) {
127
+ const module = registered.get(name)
128
+ if (!module) continue
129
+
130
+ const ctx = this._createModuleContext(module)
131
+
132
+ if (!module.enabled(ctx as unknown as Parameters<typeof module.enabled>[0])) {
133
+ continue
134
+ }
135
+
136
+ if (typeof module.loadStyles === 'function') {
137
+ await module.loadStyles()
138
+ }
139
+
140
+ await module.connect(ctx as unknown as Parameters<typeof module.connect>[0])
141
+
142
+ loaded.set(name, module)
143
+ loadOrder.push(name)
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Wire modules that need orchestrator (phase 2)
149
+ */
150
+ proto._wireModules = function (this: Self): void {
151
+ if (!this.moduleLoader) return
152
+
153
+ const result = this.signals!.emit('kernel:ready', { ready: true })
154
+
155
+ if (result instanceof Promise) {
156
+ result.catch((err) => {
157
+ console.error('[Kernel] kernel:ready handler failed:', err)
158
+ })
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Wire modules that need orchestrator (phase 2) - async version
164
+ */
165
+ proto._wireModulesAsync = async function (this: Self): Promise<void> {
166
+ if (!this.moduleLoader) return
167
+
168
+ await this.signals!.emit('kernel:ready', { ready: true })
169
+ }
170
+ }
@@ -0,0 +1,237 @@
1
+ import { createSignalBus } from './SignalBus'
2
+ import { createZoneRegistry } from '../zones/ZoneRegistry'
3
+ import { createHookRegistry } from '../hooks/HookRegistry'
4
+ import { createSecurityChecker } from '../entity/auth/SecurityChecker'
5
+ import { PermissionRegistry } from '../security/PermissionRegistry'
6
+ import { StaticRoleProvider } from '../security/StaticRolesProvider'
7
+ import { createManagers, type ManagerFactoryContext } from '../entity/factory.js'
8
+ import { defaultStorageResolver } from '../entity/storage/factory'
9
+ import { createDeferredRegistry } from '../deferred/DeferredRegistry.js'
10
+ import { createEventRouter } from './EventRouter'
11
+ import { createSSEBridge } from './SSEBridge'
12
+ import { ActiveStack } from '../chain/ActiveStack.js'
13
+ import { StackHydrator } from '../chain/StackHydrator.js'
14
+ import { Orchestrator } from '../orchestrator/Orchestrator'
15
+ import type { EntityAuthAdapter } from '../entity/auth/EntityAuthAdapter'
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ type Self = any
18
+
19
+ /**
20
+ * Patch Kernel prototype with registry-related methods.
21
+ */
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ export function applyRegistryMethods(KernelClass: { prototype: any }): void {
24
+ const proto = KernelClass.prototype as Self
25
+
26
+ /**
27
+ * Create signal bus for event-driven communication.
28
+ *
29
+ * When `options.existingSignals` is provided (host shell already
30
+ * owns a bus), reuse it instead of spinning up a fresh one. This
31
+ * is what lets qdcms and qdadm share entity events when they're
32
+ * mounted on the same Vue app.
33
+ */
34
+ proto._createSignalBus = function (this: Self): void {
35
+ if (this.options.existingSignals) {
36
+ this.signals = this.options.existingSignals
37
+ return
38
+ }
39
+ const debug = this.options.debug ?? false
40
+ this.signals = createSignalBus({ debug })
41
+ }
42
+
43
+ /**
44
+ * Create hook registry for Drupal-inspired extensibility
45
+ */
46
+ proto._createHookRegistry = function (this: Self): void {
47
+ const debug = this.options.debug ?? false
48
+ this.hookRegistry = createHookRegistry({
49
+ kernel: this.signals!.getKernel(),
50
+ debug,
51
+ })
52
+ }
53
+
54
+ /**
55
+ * Create orchestrator with managers and signal bus
56
+ */
57
+ proto._createOrchestrator = function (this: Self): void {
58
+ const factoryContext = {
59
+ storageResolver: this.options.storageResolver || defaultStorageResolver,
60
+ managerResolver: this.options.managerResolver,
61
+ managerRegistry: this.options.managerRegistry || {},
62
+ } as ManagerFactoryContext
63
+
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ const managers = createManagers((this.options.managers || {}) as any, factoryContext)
66
+
67
+ this.orchestrator = new Orchestrator({
68
+ managers,
69
+ signals: this.signals,
70
+ hooks: this.hookRegistry,
71
+ deferred: this.deferred,
72
+ entityAuthAdapter: (this.options.entityAuthAdapter as EntityAuthAdapter) || null,
73
+ })
74
+
75
+ // Pass kernel options to orchestrator (avoid circular reference for Vue reactivity)
76
+ this.orchestrator.kernelOptions = {
77
+ defaultEntityCacheTtlMs: this.options.defaultEntityCacheTtlMs,
78
+ }
79
+
80
+ if (this.options.toast) {
81
+ this.orchestrator.setToastConfig(this.options.toast)
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Create PermissionRegistry early so modules can register permissions
87
+ */
88
+ proto._createPermissionRegistry = function (this: Self): void {
89
+ this.permissionRegistry = new PermissionRegistry()
90
+ this._registerCorePermissions()
91
+ }
92
+
93
+ /**
94
+ * Register core system permissions provided by the framework
95
+ */
96
+ proto._registerCorePermissions = function (this: Self): void {
97
+ this.permissionRegistry!.register('auth', {
98
+ impersonate: 'Impersonate other users',
99
+ manage: 'Manage authentication settings',
100
+ })
101
+
102
+ this.permissionRegistry!.register('admin', {
103
+ access: 'Access admin panel',
104
+ config: 'Edit system configuration',
105
+ })
106
+ }
107
+
108
+ /**
109
+ * Setup security layer (role hierarchy, permissions)
110
+ */
111
+ proto._setupSecurity = function (this: Self): void {
112
+ const { security, entityAuthAdapter } = this.options
113
+
114
+ if (!this.permissionRegistry) {
115
+ this.permissionRegistry = new PermissionRegistry()
116
+ }
117
+
118
+ if (!security) return
119
+
120
+ let rolesProvider = security.rolesProvider
121
+ if (!rolesProvider && (security.role_permissions || security.role_hierarchy)) {
122
+ rolesProvider = new StaticRoleProvider({
123
+ role_hierarchy: security.role_hierarchy || {},
124
+ role_permissions: security.role_permissions || {},
125
+ role_labels: security.role_labels || {},
126
+ })
127
+ }
128
+
129
+ this.securityChecker = createSecurityChecker({
130
+ rolesProvider: rolesProvider || undefined,
131
+ getCurrentUser: () =>
132
+ (entityAuthAdapter as EntityAuthAdapter | null)?.getCurrentUser?.() || null,
133
+ })
134
+
135
+ // Store entity_permissions config (augment securityChecker for EntityManager to use)
136
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
+ ;(this.securityChecker as any).entityPermissions = security.entity_permissions ?? false
138
+
139
+ const adapter = entityAuthAdapter as EntityAuthAdapter | null
140
+ if (adapter?.setSecurityChecker) {
141
+ adapter.setSecurityChecker(this.securityChecker)
142
+ }
143
+
144
+ if (rolesProvider?.install) {
145
+ const ctx = {
146
+ orchestrator: this.orchestrator,
147
+ signals: this.signals,
148
+ }
149
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
150
+ rolesProvider.install(ctx as any)
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Create zone registry for extensible UI composition
156
+ */
157
+ proto._createZoneRegistry = function (this: Self): void {
158
+ const debug = this.options.debug ?? false
159
+ this.zoneRegistry = createZoneRegistry({ debug })
160
+ }
161
+
162
+ /**
163
+ * Create active stack for navigation state
164
+ */
165
+ proto._createActiveStack = function (this: Self): void {
166
+ this.activeStack = new ActiveStack(this.signals!)
167
+ }
168
+
169
+ /**
170
+ * Create stack hydrator for async data loading
171
+ */
172
+ proto._createStackHydrator = function (this: Self): void {
173
+ this.stackHydrator = new StackHydrator(
174
+ this.activeStack!,
175
+ this.orchestrator!,
176
+ this.signals!
177
+ )
178
+ }
179
+
180
+ /**
181
+ * Create deferred registry for async service loading
182
+ */
183
+ proto._createDeferredRegistry = function (this: Self): void {
184
+ const debug = this.options.debug ?? false
185
+ this.deferred = createDeferredRegistry({
186
+ kernel: this.signals?.getKernel() || null,
187
+ debug,
188
+ })
189
+ }
190
+
191
+ /**
192
+ * Create EventRouter for declarative signal routing
193
+ */
194
+ proto._createEventRouter = function (this: Self): void {
195
+ const { eventRouter: routes } = this.options
196
+ if (!routes || Object.keys(routes).length === 0) return
197
+
198
+ const debug = this.options.debug ?? false
199
+ this.eventRouter = createEventRouter({
200
+ signals: this.signals!,
201
+ routes,
202
+ debug,
203
+ })
204
+ }
205
+
206
+ /**
207
+ * Create SSEBridge for Server-Sent Events to SignalBus integration
208
+ */
209
+ proto._createSSEBridge = function (this: Self): void {
210
+ const { sse, authAdapter } = this.options
211
+ if (!sse?.url) return
212
+
213
+ const debug = this.options.debug ?? false
214
+
215
+ const getToken = authAdapter?.getToken
216
+ ? () => authAdapter.getToken!()
217
+ : () => localStorage.getItem('auth_token')
218
+
219
+ this.sseBridge = createSSEBridge({
220
+ signals: this.signals!,
221
+ url: sse.url,
222
+ reconnectDelay: sse.reconnectDelay ?? 5000,
223
+ signalPrefix: sse.signalPrefix ?? 'sse',
224
+ autoConnect: sse.autoConnect ?? false,
225
+ withCredentials: sse.withCredentials ?? false,
226
+ tokenParam: sse.tokenParam ?? 'token',
227
+ getToken,
228
+ debug,
229
+ })
230
+
231
+ if (sse.events?.length) {
232
+ this.signals!.once('sse:connected', () => {
233
+ this.sseBridge!.registerEvents(sse.events!)
234
+ })
235
+ }
236
+ }
237
+ }