@jmruthers/pace-core 0.5.68 → 0.5.69

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 (375) hide show
  1. package/dist/{DataTable-4IUY7BXB.js → DataTable-MPBSXUC6.js} +5 -6
  2. package/dist/{PublicLoadingSpinner-DdKXTkCZ.d.ts → PublicLoadingSpinner-BOdyU3u-.d.ts} +1 -1
  3. package/dist/{chunk-PXWEDX7Y.js → chunk-2ARQW6VX.js} +3 -3
  4. package/dist/{chunk-MOJXHWDE.js → chunk-6JILXFEA.js} +335 -5
  5. package/dist/chunk-6JILXFEA.js.map +1 -0
  6. package/dist/{chunk-D7ARGIA3.js → chunk-6RBH67W7.js} +23 -6
  7. package/dist/chunk-6RBH67W7.js.map +1 -0
  8. package/dist/{chunk-ZMS23NS5.js → chunk-FJTAWPAQ.js} +3 -5
  9. package/dist/{chunk-ZMS23NS5.js.map → chunk-FJTAWPAQ.js.map} +1 -1
  10. package/dist/{chunk-OPCWH3A4.js → chunk-NO5QHMDX.js} +7 -6
  11. package/dist/chunk-NO5QHMDX.js.map +1 -0
  12. package/dist/{chunk-ZPK5656W.js → chunk-O3NWNXDY.js} +4 -5
  13. package/dist/chunk-O3NWNXDY.js.map +1 -0
  14. package/dist/{chunk-UYA6U6H7.js → chunk-Q2UP3ZWQ.js} +4 -4
  15. package/dist/{chunk-KRCRNXPD.js → chunk-RVYGJPOD.js} +79 -18
  16. package/dist/chunk-RVYGJPOD.js.map +1 -0
  17. package/dist/{chunk-NN45OBIS.js → chunk-UCMHBF7Y.js} +3 -5
  18. package/dist/{chunk-NN45OBIS.js.map → chunk-UCMHBF7Y.js.map} +1 -1
  19. package/dist/{chunk-ZPG4XPV5.js → chunk-V3QO3LL7.js} +5 -7
  20. package/dist/chunk-V3QO3LL7.js.map +1 -0
  21. package/dist/{chunk-U6GPOF6J.js → chunk-ZXJGZLLO.js} +17 -17
  22. package/dist/{chunk-U6GPOF6J.js.map → chunk-ZXJGZLLO.js.map} +1 -1
  23. package/dist/components.d.ts +1 -1
  24. package/dist/components.js +8 -9
  25. package/dist/components.js.map +1 -1
  26. package/dist/hooks.d.ts +1 -1
  27. package/dist/hooks.js +9 -6
  28. package/dist/hooks.js.map +1 -1
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.js +16 -16
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers.js +5 -7
  33. package/dist/rbac/index.js +5 -6
  34. package/dist/{usePublicRouteParams-CdoFxnJK.d.ts → usePublicRouteParams-Ua1Vz-HG.d.ts} +35 -1
  35. package/dist/utils.d.ts +4 -1
  36. package/dist/utils.js +3 -3
  37. package/docs/DOCUMENTATION_CHECKLIST.md +281 -0
  38. package/docs/README.md +22 -10
  39. package/docs/api/classes/ColumnFactory.md +1 -1
  40. package/docs/api/classes/ErrorBoundary.md +1 -1
  41. package/docs/api/classes/InvalidScopeError.md +1 -1
  42. package/docs/api/classes/MissingUserContextError.md +1 -1
  43. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  44. package/docs/api/classes/PermissionDeniedError.md +1 -1
  45. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  46. package/docs/api/classes/RBACAuditManager.md +1 -1
  47. package/docs/api/classes/RBACCache.md +1 -1
  48. package/docs/api/classes/RBACEngine.md +1 -1
  49. package/docs/api/classes/RBACError.md +1 -1
  50. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  51. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  52. package/docs/api/classes/StorageUtils.md +1 -1
  53. package/docs/api/interfaces/AggregateConfig.md +1 -1
  54. package/docs/api/interfaces/ButtonProps.md +1 -1
  55. package/docs/api/interfaces/CardProps.md +1 -1
  56. package/docs/api/interfaces/ColorPalette.md +1 -1
  57. package/docs/api/interfaces/ColorShade.md +1 -1
  58. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  59. package/docs/api/interfaces/DataTableAction.md +1 -1
  60. package/docs/api/interfaces/DataTableColumn.md +1 -1
  61. package/docs/api/interfaces/DataTableProps.md +1 -1
  62. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  63. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  64. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  65. package/docs/api/interfaces/EventContextType.md +1 -1
  66. package/docs/api/interfaces/EventLogoProps.md +1 -1
  67. package/docs/api/interfaces/EventProviderProps.md +1 -1
  68. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  69. package/docs/api/interfaces/FileUploadProps.md +1 -1
  70. package/docs/api/interfaces/FooterProps.md +1 -1
  71. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  72. package/docs/api/interfaces/InputProps.md +1 -1
  73. package/docs/api/interfaces/LabelProps.md +1 -1
  74. package/docs/api/interfaces/LoginFormProps.md +1 -1
  75. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  76. package/docs/api/interfaces/NavigationContextType.md +1 -1
  77. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  78. package/docs/api/interfaces/NavigationItem.md +1 -1
  79. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  80. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  81. package/docs/api/interfaces/Organisation.md +1 -1
  82. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  83. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  84. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  85. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  86. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  87. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  88. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  89. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  90. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  91. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  92. package/docs/api/interfaces/PaletteData.md +1 -1
  93. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  94. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  95. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  96. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  97. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  98. package/docs/api/interfaces/PublicPageHeaderProps.md +2 -2
  99. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  100. package/docs/api/interfaces/RBACConfig.md +1 -1
  101. package/docs/api/interfaces/RBACContextType.md +1 -1
  102. package/docs/api/interfaces/RBACLogger.md +1 -1
  103. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  104. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  105. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  106. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  107. package/docs/api/interfaces/RouteConfig.md +1 -1
  108. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  109. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  110. package/docs/api/interfaces/StorageConfig.md +1 -1
  111. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  112. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  113. package/docs/api/interfaces/StorageListOptions.md +1 -1
  114. package/docs/api/interfaces/StorageListResult.md +1 -1
  115. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  116. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  117. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  118. package/docs/api/interfaces/StyleImport.md +1 -1
  119. package/docs/api/interfaces/SwitchProps.md +1 -1
  120. package/docs/api/interfaces/ToastActionElement.md +1 -1
  121. package/docs/api/interfaces/ToastProps.md +1 -1
  122. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  123. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  124. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  125. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  126. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  127. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  128. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  129. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  130. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  131. package/docs/api/interfaces/UserEventAccess.md +1 -1
  132. package/docs/api/interfaces/UserMenuProps.md +1 -1
  133. package/docs/api/interfaces/UserProfile.md +1 -1
  134. package/docs/api/modules.md +39 -14
  135. package/docs/architecture/services.md +374 -0
  136. package/docs/best-practices/README.md +1 -1
  137. package/docs/best-practices/testing.md +1 -1
  138. package/docs/breaking-changes.md +182 -0
  139. package/docs/common-patterns.md +445 -0
  140. package/docs/core-concepts/authentication.md +26 -11
  141. package/docs/core-concepts/events.md +2 -0
  142. package/docs/core-concepts/organisations.md +2 -0
  143. package/docs/core-concepts/permissions.md +2 -0
  144. package/docs/{INDEX.md → documentation-index.md} +26 -38
  145. package/docs/faq.md +286 -0
  146. package/docs/{FILE_REFERENCE_SYSTEM.md → file-reference-system.md} +1 -1
  147. package/docs/getting-started/installation-guide.md +284 -0
  148. package/docs/getting-started/quick-start.md +8 -1
  149. package/docs/implementation-guides/app-layout.md +3 -1
  150. package/docs/implementation-guides/data-tables.md +2 -0
  151. package/docs/implementation-guides/dynamic-colors.md +47 -2
  152. package/docs/implementation-guides/event-theming-summary.md +220 -0
  153. package/docs/implementation-guides/forms.md +9 -7
  154. package/docs/implementation-guides/navigation.md +2 -0
  155. package/docs/migration/service-architecture.md +351 -0
  156. package/docs/rbac/README-rbac-rls-integration.md +2 -2
  157. package/docs/rbac/README.md +1 -1
  158. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  159. package/docs/rbac/quick-start.md +2 -0
  160. package/docs/rbac/rbac-rls-integration.md +2 -2
  161. package/docs/style-guide.md +136 -1
  162. package/docs/testing/README.md +1 -1
  163. package/docs/troubleshooting/authentication-issues.md +334 -0
  164. package/docs/troubleshooting/common-issues.md +2 -0
  165. package/docs/troubleshooting/styling-issues.md +199 -144
  166. package/docs/usage.md +23 -2
  167. package/package.json +1 -1
  168. package/src/__tests__/{TESTING_GUIDELINES.md → TEST_GUIDE_CURSOR.md} +20 -0
  169. package/src/__tests__/TEST_GUIDE_HUMAN.md +103 -0
  170. package/src/__tests__/fixtures/test-data.ts +90 -0
  171. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +260 -0
  172. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +224 -0
  173. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +273 -0
  174. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +98 -0
  175. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +436 -0
  176. package/src/__tests__/helpers/__tests__/timer-utils.test.ts +371 -0
  177. package/src/__tests__/helpers/component-test-utils.tsx +14 -4
  178. package/src/__tests__/helpers/optimized-test-setup.ts +68 -0
  179. package/src/__tests__/helpers/test-providers.tsx +329 -0
  180. package/src/__tests__/helpers/test-utils.tsx +91 -45
  181. package/src/__tests__/helpers/timer-utils.ts +71 -0
  182. package/src/__tests__/hooks/usePermissions.test.ts +1 -5
  183. package/src/__tests__/integration/UserProfile.test.tsx +1 -5
  184. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +42 -12
  185. package/src/__tests__/setup.ts +34 -28
  186. package/src/components/Alert/Alert.test.tsx +1 -5
  187. package/src/components/Avatar/Avatar.test.tsx +1 -5
  188. package/src/components/Button/Button.test.tsx +4 -20
  189. package/src/components/Card/Card.test.tsx +1 -5
  190. package/src/components/Checkbox/Checkbox.test.tsx +1 -5
  191. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -5
  192. package/src/components/DataTable/__tests__/DataTable.test.tsx +45 -49
  193. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +1 -5
  194. package/src/components/DataTable/__tests__/styles.test.ts +382 -0
  195. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +409 -0
  196. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +634 -0
  197. package/src/components/DataTable/core/__tests__/DataManager.test.ts +519 -0
  198. package/src/components/DataTable/core/__tests__/StateManager.test.ts +714 -0
  199. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +592 -0
  200. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +354 -0
  201. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +539 -0
  202. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -5
  203. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +1 -8
  204. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +34 -38
  205. package/src/components/Footer/Footer.test.tsx +1 -5
  206. package/src/components/Form/Form.test.tsx +22 -35
  207. package/src/components/Header/Header.test.tsx +1 -9
  208. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +1 -5
  209. package/src/components/Input/Input.test.tsx +2 -10
  210. package/src/components/LoginForm/LoginForm.test.tsx +1 -5
  211. package/src/components/NavigationMenu/NavigationMenu.test.tsx +24 -24
  212. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +1 -6
  213. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -16
  214. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +1 -5
  215. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +1 -5
  216. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +1 -7
  217. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +1 -9
  218. package/src/components/PasswordReset/PasswordResetForm.test.tsx +1 -9
  219. package/src/components/PublicLayout/PublicErrorBoundary.tsx +4 -5
  220. package/src/components/PublicLayout/PublicPageHeader.tsx +13 -9
  221. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +666 -0
  222. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +457 -0
  223. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +393 -0
  224. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +351 -0
  225. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +374 -0
  226. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +388 -0
  227. package/src/components/Select/Select.bug-test.tsx +69 -0
  228. package/src/components/Select/Select.refactored.tsx +497 -0
  229. package/src/components/Select/Select.test.tsx +42 -49
  230. package/src/components/Select/Select.tsx +5 -2
  231. package/src/components/Select/hooks.ts +254 -0
  232. package/src/components/Switch/Switch.test.tsx +1 -5
  233. package/src/components/Table/__tests__/Table.test.tsx +775 -0
  234. package/src/components/Toast/Toast.test.tsx +15 -8
  235. package/src/components/Tooltip/Tooltip.test.tsx +1 -5
  236. package/src/components/UserMenu/UserMenu.test.tsx +3 -15
  237. package/src/components/__tests__/FileDisplay.test.tsx +575 -0
  238. package/src/components/__tests__/FileUpload.test.tsx +446 -0
  239. package/src/components/__tests__/SuperAdminGuard.test.tsx +422 -354
  240. package/src/hooks/__tests__/ServiceHooks.test.tsx +613 -0
  241. package/src/hooks/__tests__/hooks.integration.test.tsx +1 -10
  242. package/src/hooks/__tests__/useApiFetch.unit.test.ts +10 -14
  243. package/src/hooks/__tests__/useAppConfig.unit.test.ts +307 -0
  244. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +1 -6
  245. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +1 -5
  246. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +6 -9
  247. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +321 -0
  248. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
  249. package/src/hooks/__tests__/usePublicEventLogo.unit.test.ts +640 -0
  250. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +435 -0
  251. package/src/hooks/__tests__/useRBAC.unit.test.ts +10 -10
  252. package/src/hooks/__tests__/useStorage.unit.test.ts +751 -0
  253. package/src/hooks/index.ts +3 -0
  254. package/src/hooks/public/usePublicEvent.ts +30 -9
  255. package/src/hooks/public/usePublicRouteParams.ts +13 -3
  256. package/src/hooks/services/useAuth.ts +50 -0
  257. package/src/hooks/services/useAuthService.ts +30 -0
  258. package/src/hooks/services/useCurrentEvent.ts +36 -0
  259. package/src/hooks/services/useCurrentOrganisation.ts +52 -0
  260. package/src/hooks/services/useEventService.ts +30 -0
  261. package/src/hooks/services/useInactivityService.ts +30 -0
  262. package/src/hooks/services/useOrganisationService.ts +30 -0
  263. package/src/hooks/services/usePermissions.ts +70 -0
  264. package/src/hooks/services/useRBACService.ts +30 -0
  265. package/src/hooks/useCounter.test.ts +1 -5
  266. package/src/hooks/useEventTheme.ts +86 -0
  267. package/src/hooks/useOrganisationPermissions.test.ts +2 -5
  268. package/src/hooks/useOrganisationSecurity.test.ts +1 -5
  269. package/src/hooks/usePermissionCache.test.ts +1 -5
  270. package/src/hooks/usePermissionCheck.ts +150 -0
  271. package/src/hooks/useSecureDataAccess.test.ts +1 -5
  272. package/src/index.ts +1 -0
  273. package/src/providers/OrganisationProvider.test.tsx +1 -5
  274. package/src/providers/OrganisationProvider.tsx +56 -4
  275. package/src/providers/UnifiedAuthProvider.test.tsx +1 -5
  276. package/src/providers/__tests__/AuthProvider.test.tsx +105 -439
  277. package/src/providers/__tests__/AuthProvider.test.tsx.backup +771 -0
  278. package/src/providers/__tests__/EventProvider.test.tsx +211 -110
  279. package/src/providers/__tests__/EventProvider.test.tsx.backup +824 -0
  280. package/src/providers/__tests__/InactivityProvider.test.tsx +1 -5
  281. package/src/providers/__tests__/OrganisationProvider.test.tsx +97 -261
  282. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +820 -0
  283. package/src/providers/__tests__/ServiceProviders.test.tsx +477 -0
  284. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +72 -504
  285. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +911 -0
  286. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +166 -0
  287. package/src/providers/services/AuthServiceProvider.tsx +65 -0
  288. package/src/providers/services/EventServiceProvider.tsx +83 -0
  289. package/src/providers/services/InactivityServiceProvider.tsx +83 -0
  290. package/src/providers/services/OrganisationServiceProvider.tsx +77 -0
  291. package/src/providers/services/RBACServiceProvider.tsx +79 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +368 -0
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +210 -0
  294. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +269 -0
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +892 -0
  296. package/src/rbac/__tests__/engine.comprehensive.test.ts +954 -0
  297. package/src/rbac/__tests__/integration.authflow.test.tsx +1 -5
  298. package/src/rbac/__tests__/integration.navigation.test.tsx +1 -4
  299. package/src/rbac/__tests__/rbac-core.test.tsx +2 -7
  300. package/src/rbac/__tests__/rbac-functions.test.ts +1 -9
  301. package/src/rbac/__tests__/rbac-integration.test.ts +1 -9
  302. package/src/rbac/api.test.ts +1 -9
  303. package/src/rbac/cache.test.ts +10 -8
  304. package/src/rbac/cli/__tests__/policy-manager.test.ts +339 -0
  305. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -5
  306. package/src/rbac/components/NavigationProvider.test.tsx +1 -5
  307. package/src/rbac/components/PagePermissionProvider.test.tsx +1 -5
  308. package/src/rbac/components/SecureDataProvider.test.tsx +1 -5
  309. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +25 -29
  310. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +27 -30
  311. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +23 -27
  312. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +18 -22
  313. package/src/rbac/config.test.ts +1 -5
  314. package/src/rbac/hooks/useCan.test.ts +262 -9
  315. package/src/rbac/hooks/usePermissions.test.ts +246 -6
  316. package/src/rbac/hooks/useRBAC.simple.test.ts +1 -5
  317. package/src/rbac/hooks/useRBAC.test.ts +472 -198
  318. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +1 -9
  319. package/src/services/AuthService.ts +416 -0
  320. package/src/services/EventService.ts +366 -0
  321. package/src/services/InactivityService.ts +388 -0
  322. package/src/services/OrganisationService.ts +592 -0
  323. package/src/services/RBACService.ts +522 -0
  324. package/src/services/__tests__/AuthService.test.ts +356 -0
  325. package/src/services/__tests__/BaseService.test.ts +314 -0
  326. package/src/services/__tests__/EventService.test.ts +489 -0
  327. package/src/services/__tests__/InactivityService.test.ts +403 -0
  328. package/src/services/__tests__/OrganisationService.test.ts +660 -0
  329. package/src/services/__tests__/RBACService.test.ts +492 -0
  330. package/src/services/base/BaseService.ts +87 -0
  331. package/src/services/interfaces/IAuthService.ts +39 -0
  332. package/src/services/interfaces/IEventService.ts +30 -0
  333. package/src/services/interfaces/IInactivityService.ts +31 -0
  334. package/src/services/interfaces/IOrganisationService.ts +41 -0
  335. package/src/services/interfaces/IRBACService.ts +62 -0
  336. package/src/theming/__tests__/runtime.test.ts +540 -0
  337. package/src/types/__tests__/file-reference.test.ts +447 -0
  338. package/src/types/__tests__/organisation.test.ts +1133 -0
  339. package/src/types/__tests__/theme.test.ts +830 -0
  340. package/src/types/__tests__/type-validation.test.ts +527 -0
  341. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +1 -5
  342. package/src/utils/__tests__/debugLogger.test.ts +417 -0
  343. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -6
  344. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -5
  345. package/src/utils/__tests__/lazyLoad.unit.test.tsx +35 -35
  346. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -5
  347. package/src/utils/__tests__/performanceBudgets.unit.test.ts +5 -11
  348. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -6
  349. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -5
  350. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -5
  351. package/src/utils/__tests__/sessionTracking.unit.test.ts +1 -5
  352. package/src/utils/appIdResolver.test.ts +6 -10
  353. package/src/utils/appNameResolver.simple.test.ts +142 -0
  354. package/src/utils/appNameResolver.test.ts +31 -458
  355. package/src/utils/appNameResolver.test.ts.backup +494 -0
  356. package/src/utils/debugLogger.ts +26 -5
  357. package/src/utils/formatDate.test.ts +1 -5
  358. package/src/utils/organisationContext.test.ts +1 -5
  359. package/src/utils/performanceBudgets.ts +3 -4
  360. package/src/utils/secureDataAccess.test.ts +1 -5
  361. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -5
  362. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +1 -5
  363. package/dist/chunk-D7ARGIA3.js.map +0 -1
  364. package/dist/chunk-IPCH4YPT.js +0 -315
  365. package/dist/chunk-IPCH4YPT.js.map +0 -1
  366. package/dist/chunk-KRCRNXPD.js.map +0 -1
  367. package/dist/chunk-MOJXHWDE.js.map +0 -1
  368. package/dist/chunk-OPCWH3A4.js.map +0 -1
  369. package/dist/chunk-ZPG4XPV5.js.map +0 -1
  370. package/dist/chunk-ZPK5656W.js.map +0 -1
  371. package/docs/getting-started/installation.md +0 -269
  372. package/src/__tests__/REBUILD_PLAN.md +0 -223
  373. /package/dist/{DataTable-4IUY7BXB.js.map → DataTable-MPBSXUC6.js.map} +0 -0
  374. /package/dist/{chunk-PXWEDX7Y.js.map → chunk-2ARQW6VX.js.map} +0 -0
  375. /package/dist/{chunk-UYA6U6H7.js.map → chunk-Q2UP3ZWQ.js.map} +0 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @file Organisation Service Interface
3
+ * @package @jmruthers/pace-core
4
+ * @module Services/Interfaces
5
+ * @since 0.1.0
6
+ *
7
+ * Interface for organisation service operations.
8
+ * Defines the contract for organisation management functionality.
9
+ */
10
+
11
+ import type {
12
+ Organisation,
13
+ OrganisationMembership,
14
+ OrganisationSecurityError,
15
+ OrganisationHierarchy
16
+ } from '../../types/organisation';
17
+
18
+ export interface IOrganisationService {
19
+ // Organisation state
20
+ getSelectedOrganisation(): Organisation | null;
21
+ getOrganisations(): Organisation[];
22
+ getUserMemberships(): OrganisationMembership[];
23
+ isLoading(): boolean;
24
+ getError(): Error | null;
25
+ hasValidOrganisationContext(): boolean;
26
+ isContextReady(): boolean;
27
+
28
+ // Organisation methods
29
+ switchOrganisation(orgId: string): Promise<void>;
30
+ getUserRole(orgId?: string): string;
31
+ validateOrganisationAccess(orgId: string): boolean;
32
+ refreshOrganisations(): Promise<void>;
33
+ ensureOrganisationContext(): Organisation;
34
+ isOrganisationSecure(): boolean;
35
+ getPrimaryOrganisation(): Organisation | null;
36
+ buildOrganisationHierarchy(orgs: Organisation[]): OrganisationHierarchy[];
37
+
38
+ // Lifecycle
39
+ initialize(): Promise<void>;
40
+ cleanup(): void;
41
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @file RBAC Service Interface
3
+ * @package @jmruthers/pace-core
4
+ * @module Services/Interfaces
5
+ * @since 0.1.0
6
+ *
7
+ * Interface for RBAC service operations.
8
+ * Defines the contract for role-based access control functionality.
9
+ */
10
+
11
+ import { AccessLevel } from '../../types/unified';
12
+
13
+ export interface UserEventAccess {
14
+ event_id: string;
15
+ event_name: string;
16
+ event_description?: string | null;
17
+ start_date: string;
18
+ end_date: string;
19
+ event_status: string;
20
+ app_id: string;
21
+ access_level: string;
22
+ granted_at: string;
23
+ organisation_id: string;
24
+ }
25
+
26
+ export interface AppConfig {
27
+ supports_direct_access: boolean;
28
+ requires_event: boolean;
29
+ }
30
+
31
+ export interface IRBACService {
32
+ // RBAC state
33
+ getPermissions(): Record<string, boolean>;
34
+ getRoles(): string[];
35
+ getAccessLevel(): AccessLevel;
36
+ isLoading(): boolean;
37
+ getError(): Error | null;
38
+ getSelectedEventId(): string | null;
39
+ getAppConfig(): AppConfig | null;
40
+ getUserEventAccess(): UserEventAccess[];
41
+ isEventAccessLoading(): boolean;
42
+ getSelectedOrganisationId(): string | null;
43
+
44
+ // RBAC methods
45
+ hasPermission(permission: string, orgId?: string): boolean;
46
+ hasAnyPermission(permissions: string[], orgId?: string): boolean;
47
+ hasAllPermissions(permissions: string[], orgId?: string): boolean;
48
+ hasRole(role: string): boolean;
49
+ hasAccessLevel(level: AccessLevel): boolean;
50
+ canAccess(resource: string, action: string, orgId?: string): boolean;
51
+ validatePermission(permission: string, orgId?: string): Promise<boolean>;
52
+ validateAccess(resource: string, action: string, orgId?: string): Promise<boolean>;
53
+ refreshPermissions(eventId?: string, orgId?: string): Promise<void>;
54
+ setSelectedEventId(eventId: string | null): void;
55
+ loadUserEventAccess(orgId?: string): Promise<void>;
56
+ getUserEventAccessById(eventId: string): UserEventAccess | undefined;
57
+ requireOrganisationContext(): string;
58
+
59
+ // Lifecycle
60
+ initialize(): Promise<void>;
61
+ cleanup(): void;
62
+ }
@@ -0,0 +1,540 @@
1
+ /**
2
+ * @file Theming Runtime Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Theming/__tests__
5
+ * @since 2.0.0
6
+ */
7
+
8
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
9
+ import {
10
+ applyPalette,
11
+ clearPalette,
12
+ generateSSRThemeCSS,
13
+ isDynamicThemingActive,
14
+ getCurrentThemeData,
15
+ type ColorShade,
16
+ type ColorPalette,
17
+ type PaletteData
18
+ } from '../runtime';
19
+
20
+ // Mock document and console
21
+ const mockDocument = {
22
+ createElement: vi.fn(),
23
+ getElementById: vi.fn(),
24
+ head: {
25
+ appendChild: vi.fn()
26
+ }
27
+ };
28
+
29
+ const mockConsole = {
30
+ warn: vi.fn()
31
+ };
32
+
33
+ // Mock global objects
34
+ Object.defineProperty(global, 'document', {
35
+ value: mockDocument,
36
+ writable: true
37
+ });
38
+
39
+ Object.defineProperty(global, 'console', {
40
+ value: mockConsole,
41
+ writable: true
42
+ });
43
+
44
+ describe('[theming] applyPalette', () => {
45
+ beforeEach(() => {
46
+ vi.clearAllMocks();
47
+ mockDocument.getElementById.mockReturnValue(null);
48
+ });
49
+
50
+ it('applies palette to document', () => {
51
+ const mockStyle = {
52
+ id: '',
53
+ textContent: ''
54
+ };
55
+ mockDocument.createElement.mockReturnValue(mockStyle);
56
+
57
+ const palette: PaletteData = {
58
+ main: {
59
+ 50: { L: 0.95, C: 0.02, H: 0 },
60
+ 500: { L: 0.5, C: 0.2, H: 0 }
61
+ },
62
+ sec: {
63
+ 50: { L: 0.95, C: 0.02, H: 120 },
64
+ 500: { L: 0.5, C: 0.2, H: 120 }
65
+ },
66
+ acc: {
67
+ 50: { L: 0.95, C: 0.02, H: 240 },
68
+ 500: { L: 0.5, C: 0.2, H: 240 }
69
+ }
70
+ };
71
+
72
+ applyPalette(palette);
73
+
74
+ expect(mockDocument.createElement).toHaveBeenCalledWith('style');
75
+ expect(mockDocument.head.appendChild).toHaveBeenCalled();
76
+ });
77
+
78
+ it('clears existing palette before applying new one', () => {
79
+ const existingStyle = { remove: vi.fn() };
80
+ const mockStyle = {
81
+ id: '',
82
+ textContent: ''
83
+ };
84
+ mockDocument.getElementById.mockReturnValue(existingStyle);
85
+ mockDocument.createElement.mockReturnValue(mockStyle);
86
+
87
+ const palette: PaletteData = {
88
+ main: { 500: { L: 0.5, C: 0.2, H: 0 } },
89
+ sec: { 500: { L: 0.5, C: 0.2, H: 120 } },
90
+ acc: { 500: { L: 0.5, C: 0.2, H: 240 } }
91
+ };
92
+
93
+ applyPalette(palette);
94
+
95
+ expect(mockDocument.getElementById).toHaveBeenCalledWith('pace-theme-dynamic');
96
+ expect(existingStyle.remove).toHaveBeenCalled();
97
+ });
98
+
99
+ it('handles SSR environment gracefully', () => {
100
+ // Mock SSR environment
101
+ Object.defineProperty(global, 'document', {
102
+ value: undefined,
103
+ writable: true
104
+ });
105
+
106
+ const palette: PaletteData = {
107
+ main: { 500: { L: 0.5, C: 0.2, H: 0 } },
108
+ sec: { 500: { L: 0.5, C: 0.2, H: 120 } },
109
+ acc: { 500: { L: 0.5, C: 0.2, H: 240 } }
110
+ };
111
+
112
+ expect(() => applyPalette(palette)).not.toThrow();
113
+ expect(mockConsole.warn).toHaveBeenCalledWith('applyPalette: Document not available (SSR)');
114
+
115
+ // Restore document
116
+ Object.defineProperty(global, 'document', {
117
+ value: mockDocument,
118
+ writable: true
119
+ });
120
+ });
121
+
122
+ it('handles null document gracefully', () => {
123
+ // Mock null document
124
+ Object.defineProperty(global, 'document', {
125
+ value: null,
126
+ writable: true
127
+ });
128
+
129
+ const palette: PaletteData = {
130
+ main: { 500: { L: 0.5, C: 0.2, H: 0 } },
131
+ sec: { 500: { L: 0.5, C: 0.2, H: 120 } },
132
+ acc: { 500: { L: 0.5, C: 0.2, H: 240 } }
133
+ };
134
+
135
+ expect(() => applyPalette(palette)).not.toThrow();
136
+ expect(mockConsole.warn).toHaveBeenCalledWith('applyPalette: Document not available (SSR)');
137
+
138
+ // Restore document
139
+ Object.defineProperty(global, 'document', {
140
+ value: mockDocument,
141
+ writable: true
142
+ });
143
+ });
144
+
145
+ it('generates correct CSS content', () => {
146
+ const palette: PaletteData = {
147
+ main: {
148
+ 50: { L: 0.95, C: 0.02, H: 0 },
149
+ 500: { L: 0.5, C: 0.2, H: 0 }
150
+ },
151
+ sec: {
152
+ 50: { L: 0.95, C: 0.02, H: 120 },
153
+ 500: { L: 0.5, C: 0.2, H: 120 }
154
+ },
155
+ acc: {
156
+ 50: { L: 0.95, C: 0.02, H: 240 },
157
+ 500: { L: 0.5, C: 0.2, H: 240 }
158
+ }
159
+ };
160
+
161
+ const mockStyle = {
162
+ id: '',
163
+ textContent: ''
164
+ };
165
+ mockDocument.createElement.mockReturnValue(mockStyle);
166
+
167
+ applyPalette(palette);
168
+
169
+ expect(mockStyle.id).toBe('pace-theme-dynamic');
170
+ expect(mockStyle.textContent).toContain('@theme static {');
171
+ expect(mockStyle.textContent).toContain('--color-main-50: oklch(0.95 0.02 0)');
172
+ expect(mockStyle.textContent).toContain('--color-main-500: oklch(0.5 0.2 0)');
173
+ expect(mockStyle.textContent).toContain('--color-sec-50: oklch(0.95 0.02 120)');
174
+ expect(mockStyle.textContent).toContain('--color-sec-500: oklch(0.5 0.2 120)');
175
+ expect(mockStyle.textContent).toContain('--color-acc-50: oklch(0.95 0.02 240)');
176
+ expect(mockStyle.textContent).toContain('--color-acc-500: oklch(0.5 0.2 240)');
177
+ });
178
+
179
+ it('handles raw color values', () => {
180
+ const palette: PaletteData = {
181
+ main: {
182
+ raw: { L: 0.5, C: 0.2, H: 0 },
183
+ 500: { L: 0.5, C: 0.2, H: 0 }
184
+ },
185
+ sec: { 500: { L: 0.5, C: 0.2, H: 120 } },
186
+ acc: { 500: { L: 0.5, C: 0.2, H: 240 } }
187
+ };
188
+
189
+ const mockStyle = {
190
+ id: '',
191
+ textContent: ''
192
+ };
193
+ mockDocument.createElement.mockReturnValue(mockStyle);
194
+
195
+ applyPalette(palette);
196
+
197
+ expect(mockStyle.textContent).toContain('--color-main-raw: oklch(0.5 0.2 0)');
198
+ });
199
+
200
+ it('handles empty palettes gracefully', () => {
201
+ const palette: PaletteData = {
202
+ main: {},
203
+ sec: {},
204
+ acc: {}
205
+ };
206
+
207
+ const mockStyle = {
208
+ id: '',
209
+ textContent: ''
210
+ };
211
+ mockDocument.createElement.mockReturnValue(mockStyle);
212
+
213
+ expect(() => applyPalette(palette)).not.toThrow();
214
+ expect(mockStyle.textContent).toContain('@theme static {');
215
+ });
216
+ });
217
+
218
+ describe('[theming] clearPalette', () => {
219
+ beforeEach(() => {
220
+ vi.clearAllMocks();
221
+ });
222
+
223
+ it('removes existing dynamic theme block', () => {
224
+ const existingStyle = { remove: vi.fn() };
225
+ mockDocument.getElementById.mockReturnValue(existingStyle);
226
+
227
+ clearPalette();
228
+
229
+ expect(mockDocument.getElementById).toHaveBeenCalledWith('pace-theme-dynamic');
230
+ expect(existingStyle.remove).toHaveBeenCalled();
231
+ });
232
+
233
+ it('handles no existing theme block', () => {
234
+ mockDocument.getElementById.mockReturnValue(null);
235
+
236
+ expect(() => clearPalette()).not.toThrow();
237
+ });
238
+
239
+ it('handles SSR environment gracefully', () => {
240
+ // Mock SSR environment
241
+ Object.defineProperty(global, 'document', {
242
+ value: undefined,
243
+ writable: true
244
+ });
245
+
246
+ expect(() => clearPalette()).not.toThrow();
247
+
248
+ // Restore document
249
+ Object.defineProperty(global, 'document', {
250
+ value: mockDocument,
251
+ writable: true
252
+ });
253
+ });
254
+
255
+ it('handles null document gracefully', () => {
256
+ // Mock null document
257
+ Object.defineProperty(global, 'document', {
258
+ value: null,
259
+ writable: true
260
+ });
261
+
262
+ expect(() => clearPalette()).not.toThrow();
263
+
264
+ // Restore document
265
+ Object.defineProperty(global, 'document', {
266
+ value: mockDocument,
267
+ writable: true
268
+ });
269
+ });
270
+ });
271
+
272
+ describe('[theming] generateSSRThemeCSS', () => {
273
+ it('generates CSS for SSR rendering', () => {
274
+ const palette: PaletteData = {
275
+ main: {
276
+ 50: { L: 0.95, C: 0.02, H: 0 },
277
+ 500: { L: 0.5, C: 0.2, H: 0 }
278
+ },
279
+ sec: {
280
+ 50: { L: 0.95, C: 0.02, H: 120 },
281
+ 500: { L: 0.5, C: 0.2, H: 120 }
282
+ },
283
+ acc: {
284
+ 50: { L: 0.95, C: 0.02, H: 240 },
285
+ 500: { L: 0.5, C: 0.2, H: 240 }
286
+ }
287
+ };
288
+
289
+ const css = generateSSRThemeCSS(palette);
290
+
291
+ expect(css).toContain('@theme static {');
292
+ expect(css).toContain('--color-main-50: oklch(0.95 0.02 0)');
293
+ expect(css).toContain('--color-main-500: oklch(0.5 0.2 0)');
294
+ expect(css).toContain('--color-sec-50: oklch(0.95 0.02 120)');
295
+ expect(css).toContain('--color-sec-500: oklch(0.5 0.2 120)');
296
+ expect(css).toContain('--color-acc-50: oklch(0.95 0.02 240)');
297
+ expect(css).toContain('--color-acc-500: oklch(0.5 0.2 240)');
298
+ });
299
+
300
+ it('throws error for null palette', () => {
301
+ expect(() => generateSSRThemeCSS(null as any)).toThrow('Palette data is required');
302
+ });
303
+
304
+ it('throws error for undefined palette', () => {
305
+ expect(() => generateSSRThemeCSS(undefined as any)).toThrow('Palette data is required');
306
+ });
307
+ });
308
+
309
+ describe('[theming] isDynamicThemingActive', () => {
310
+ beforeEach(() => {
311
+ vi.clearAllMocks();
312
+ });
313
+
314
+ it('returns true when dynamic theme is active', () => {
315
+ const existingStyle = { id: 'pace-theme-dynamic' };
316
+ mockDocument.getElementById.mockReturnValue(existingStyle);
317
+
318
+ const isActive = isDynamicThemingActive();
319
+
320
+ expect(isActive).toBe(true);
321
+ expect(mockDocument.getElementById).toHaveBeenCalledWith('pace-theme-dynamic');
322
+ });
323
+
324
+ it('returns false when dynamic theme is not active', () => {
325
+ mockDocument.getElementById.mockReturnValue(null);
326
+
327
+ const isActive = isDynamicThemingActive();
328
+
329
+ expect(isActive).toBe(false);
330
+ });
331
+
332
+ it('returns false in SSR environment', () => {
333
+ // Mock SSR environment
334
+ Object.defineProperty(global, 'document', {
335
+ value: undefined,
336
+ writable: true
337
+ });
338
+
339
+ const isActive = isDynamicThemingActive();
340
+
341
+ expect(isActive).toBe(false);
342
+
343
+ // Restore document
344
+ Object.defineProperty(global, 'document', {
345
+ value: mockDocument,
346
+ writable: true
347
+ });
348
+ });
349
+
350
+ it('returns false with null document', () => {
351
+ // Mock null document
352
+ Object.defineProperty(global, 'document', {
353
+ value: null,
354
+ writable: true
355
+ });
356
+
357
+ const isActive = isDynamicThemingActive();
358
+
359
+ expect(isActive).toBe(false);
360
+
361
+ // Restore document
362
+ Object.defineProperty(global, 'document', {
363
+ value: mockDocument,
364
+ writable: true
365
+ });
366
+ });
367
+ });
368
+
369
+ describe('[theming] getCurrentThemeData', () => {
370
+ beforeEach(() => {
371
+ vi.clearAllMocks();
372
+ });
373
+
374
+ it('returns null when no theme is active', () => {
375
+ mockDocument.getElementById.mockReturnValue(null);
376
+
377
+ const themeData = getCurrentThemeData();
378
+
379
+ expect(themeData).toBeNull();
380
+ });
381
+
382
+ it('returns null when theme is active but data cannot be extracted', () => {
383
+ const existingStyle = { id: 'pace-theme-dynamic' };
384
+ mockDocument.getElementById.mockReturnValue(existingStyle);
385
+
386
+ const themeData = getCurrentThemeData();
387
+
388
+ expect(themeData).toBeNull();
389
+ });
390
+
391
+ it('returns null in SSR environment', () => {
392
+ // Mock SSR environment
393
+ Object.defineProperty(global, 'document', {
394
+ value: undefined,
395
+ writable: true
396
+ });
397
+
398
+ const themeData = getCurrentThemeData();
399
+
400
+ expect(themeData).toBeNull();
401
+
402
+ // Restore document
403
+ Object.defineProperty(global, 'document', {
404
+ value: mockDocument,
405
+ writable: true
406
+ });
407
+ });
408
+
409
+ it('returns null with null document', () => {
410
+ // Mock null document
411
+ Object.defineProperty(global, 'document', {
412
+ value: null,
413
+ writable: true
414
+ });
415
+
416
+ const themeData = getCurrentThemeData();
417
+
418
+ expect(themeData).toBeNull();
419
+
420
+ // Restore document
421
+ Object.defineProperty(global, 'document', {
422
+ value: mockDocument,
423
+ writable: true
424
+ });
425
+ });
426
+ });
427
+
428
+ describe('[theming] Type Definitions', () => {
429
+ it('defines ColorShade interface correctly', () => {
430
+ const colorShade: ColorShade = {
431
+ L: 0.5,
432
+ C: 0.2,
433
+ H: 0
434
+ };
435
+
436
+ expect(colorShade).toHaveProperty('L');
437
+ expect(colorShade).toHaveProperty('C');
438
+ expect(colorShade).toHaveProperty('H');
439
+ expect(typeof colorShade.L).toBe('number');
440
+ expect(typeof colorShade.C).toBe('number');
441
+ expect(typeof colorShade.H).toBe('number');
442
+ });
443
+
444
+ it('defines ColorPalette interface correctly', () => {
445
+ const colorPalette: ColorPalette = {
446
+ '50': { L: 0.95, C: 0.02, H: 0 },
447
+ '500': { L: 0.5, C: 0.2, H: 0 }
448
+ };
449
+
450
+ expect(colorPalette).toHaveProperty('50');
451
+ expect(colorPalette).toHaveProperty('500');
452
+ expect(colorPalette['50']).toHaveProperty('L');
453
+ expect(colorPalette['500']).toHaveProperty('C');
454
+ });
455
+
456
+ it('defines PaletteData interface correctly', () => {
457
+ const paletteData: PaletteData = {
458
+ main: { '500': { L: 0.5, C: 0.2, H: 0 } },
459
+ sec: { '500': { L: 0.5, C: 0.2, H: 120 } },
460
+ acc: { '500': { L: 0.5, C: 0.2, H: 240 } }
461
+ };
462
+
463
+ expect(paletteData).toHaveProperty('main');
464
+ expect(paletteData).toHaveProperty('sec');
465
+ expect(paletteData).toHaveProperty('acc');
466
+ expect(typeof paletteData.main).toBe('object');
467
+ expect(typeof paletteData.sec).toBe('object');
468
+ expect(typeof paletteData.acc).toBe('object');
469
+ });
470
+ });
471
+
472
+ describe('[theming] Integration Tests', () => {
473
+ beforeEach(() => {
474
+ vi.clearAllMocks();
475
+ mockDocument.getElementById.mockReturnValue(null);
476
+ });
477
+
478
+ it('applies and clears palette correctly', () => {
479
+ const mockStyle = {
480
+ id: '',
481
+ textContent: ''
482
+ };
483
+ mockDocument.createElement.mockReturnValue(mockStyle);
484
+
485
+ const palette: PaletteData = {
486
+ main: { '500': { L: 0.5, C: 0.2, H: 0 } },
487
+ sec: { '500': { L: 0.5, C: 0.2, H: 120 } },
488
+ acc: { '500': { L: 0.5, C: 0.2, H: 240 } }
489
+ };
490
+
491
+ // Apply palette
492
+ applyPalette(palette);
493
+ expect(mockDocument.createElement).toHaveBeenCalledWith('style');
494
+ expect(mockDocument.head.appendChild).toHaveBeenCalled();
495
+
496
+ // Check if theming is active
497
+ const existingStyle = { id: 'pace-theme-dynamic', remove: vi.fn() };
498
+ mockDocument.getElementById.mockReturnValue(existingStyle);
499
+ expect(isDynamicThemingActive()).toBe(true);
500
+
501
+ // Clear palette
502
+ clearPalette();
503
+ expect(mockDocument.getElementById).toHaveBeenCalledWith('pace-theme-dynamic');
504
+ expect(existingStyle.remove).toHaveBeenCalled();
505
+ });
506
+
507
+ it('handles complete palette with all shades', () => {
508
+ const palette: PaletteData = {
509
+ main: {
510
+ raw: { L: 0.5, C: 0.2, H: 0 },
511
+ 50: { L: 0.95, C: 0.02, H: 0 },
512
+ 100: { L: 0.9, C: 0.04, H: 0 },
513
+ 200: { L: 0.8, C: 0.08, H: 0 },
514
+ 300: { L: 0.7, C: 0.12, H: 0 },
515
+ 400: { L: 0.6, C: 0.16, H: 0 },
516
+ 500: { L: 0.5, C: 0.2, H: 0 },
517
+ 600: { L: 0.4, C: 0.16, H: 0 },
518
+ 700: { L: 0.3, C: 0.12, H: 0 },
519
+ 800: { L: 0.2, C: 0.08, H: 0 },
520
+ 900: { L: 0.1, C: 0.04, H: 0 },
521
+ 950: { L: 0.05, C: 0.02, H: 0 }
522
+ },
523
+ sec: { '500': { L: 0.5, C: 0.2, H: 120 } },
524
+ acc: { '500': { L: 0.5, C: 0.2, H: 240 } }
525
+ };
526
+
527
+ const mockStyle = {
528
+ id: '',
529
+ textContent: ''
530
+ };
531
+ mockDocument.createElement.mockReturnValue(mockStyle);
532
+
533
+ applyPalette(palette);
534
+
535
+ expect(mockStyle.textContent).toContain('--color-main-raw: oklch(0.5 0.2 0)');
536
+ expect(mockStyle.textContent).toContain('--color-main-50: oklch(0.95 0.02 0)');
537
+ expect(mockStyle.textContent).toContain('--color-main-500: oklch(0.5 0.2 0)');
538
+ expect(mockStyle.textContent).toContain('--color-main-950: oklch(0.05 0.02 0)');
539
+ });
540
+ });