@jmruthers/pace-core 0.5.193 → 0.6.2

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 (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -11,13 +11,18 @@ import { renderHook, waitFor } from '@testing-library/react';
11
11
  import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
12
12
  import { useCan } from './usePermissions';
13
13
 
14
- // Mock the RBAC API
15
- vi.mock('../api', () => ({
16
- isPermitted: vi.fn(),
17
- isPermittedCached: vi.fn()
18
- }));
14
+ // Mock the RBAC API - use async factory to support dynamic imports
15
+ vi.mock('../api', async () => {
16
+ const actual = await vi.importActual('../api');
17
+ return {
18
+ ...actual,
19
+ isPermitted: vi.fn(),
20
+ isPermittedCached: vi.fn(),
21
+ isSuperAdmin: vi.fn()
22
+ };
23
+ });
19
24
 
20
- import { isPermitted, isPermittedCached } from '../api';
25
+ import { isPermitted, isPermittedCached, isSuperAdmin } from '../api';
21
26
 
22
27
  // Mock data
23
28
  const mockUserId = 'user-123';
@@ -32,12 +37,15 @@ const mockPageId = 'dashboard';
32
37
  describe('useCan Hook', () => {
33
38
  const mockIsPermitted = vi.mocked(isPermitted);
34
39
  const mockIsPermittedCached = vi.mocked(isPermittedCached);
40
+ const mockIsSuperAdmin = vi.mocked(isSuperAdmin);
35
41
 
36
42
  beforeEach(() => {
37
43
  vi.clearAllMocks();
38
44
  // Reset mocks to return resolved promises by default
39
45
  mockIsPermitted.mockResolvedValue(true);
40
46
  mockIsPermittedCached.mockResolvedValue(true);
47
+ // Default to not super admin for most tests
48
+ mockIsSuperAdmin.mockResolvedValue(false);
41
49
  });
42
50
 
43
51
  describe('Permission Checking', () => {
@@ -45,7 +53,7 @@ describe('useCan Hook', () => {
45
53
  mockIsPermitted.mockResolvedValue(true);
46
54
 
47
55
  const { result } = renderHook(() =>
48
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
56
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
49
57
  );
50
58
 
51
59
  expect(result.current.isLoading).toBe(true);
@@ -62,7 +70,7 @@ describe('useCan Hook', () => {
62
70
  mockIsPermitted.mockResolvedValue(false);
63
71
 
64
72
  const { result } = renderHook(() =>
65
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
73
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
66
74
  );
67
75
 
68
76
  await waitFor(() => {
@@ -76,7 +84,7 @@ describe('useCan Hook', () => {
76
84
  mockIsPermitted.mockImplementation(() => new Promise(() => {})); // Never resolves
77
85
 
78
86
  const { result } = renderHook(() =>
79
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
87
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
80
88
  );
81
89
 
82
90
  expect(result.current.isLoading).toBe(true);
@@ -89,7 +97,7 @@ describe('useCan Hook', () => {
89
97
  mockIsPermitted.mockRejectedValue(error);
90
98
 
91
99
  const { result } = renderHook(() =>
92
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
100
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
93
101
  );
94
102
 
95
103
  await waitFor(() => {
@@ -105,7 +113,7 @@ describe('useCan Hook', () => {
105
113
  mockIsPermittedCached.mockResolvedValue(true);
106
114
 
107
115
  const { result } = renderHook(() =>
108
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
116
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
109
117
  );
110
118
 
111
119
  await waitFor(() => {
@@ -129,7 +137,7 @@ describe('useCan Hook', () => {
129
137
  mockIsPermitted.mockResolvedValue(true);
130
138
 
131
139
  const { result } = renderHook(() =>
132
- useCan(mockUserId, mockScope, mockPermission, mockPageId, false)
140
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, false, false)
133
141
  );
134
142
 
135
143
  await waitFor(() => {
@@ -143,7 +151,8 @@ describe('useCan Hook', () => {
143
151
  pageId: mockPageId
144
152
  },
145
153
  undefined,
146
- undefined
154
+ undefined,
155
+ false
147
156
  );
148
157
  expect(mockIsPermittedCached).not.toHaveBeenCalled();
149
158
  });
@@ -153,7 +162,7 @@ describe('useCan Hook', () => {
153
162
  mockIsPermitted.mockResolvedValue(true);
154
163
 
155
164
  const { result } = renderHook(() =>
156
- useCan(mockUserId, mockScope, mockPermission, mockPageId, false)
165
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, false, false)
157
166
  );
158
167
 
159
168
  await waitFor(() => {
@@ -169,7 +178,7 @@ describe('useCan Hook', () => {
169
178
  mockIsPermitted.mockResolvedValue(true);
170
179
 
171
180
  const { result } = renderHook(() =>
172
- useCan(mockUserId, mockScope, mockPermission, 'custom-page', false)
181
+ useCan(mockUserId, mockScope, mockPermission, 'custom-page', false, false)
173
182
  );
174
183
 
175
184
  await waitFor(() => {
@@ -182,7 +191,8 @@ describe('useCan Hook', () => {
182
191
  pageId: 'custom-page'
183
192
  },
184
193
  undefined,
185
- undefined
194
+ undefined,
195
+ false
186
196
  );
187
197
  });
188
198
  });
@@ -191,7 +201,7 @@ describe('useCan Hook', () => {
191
201
  mockIsPermitted.mockResolvedValue(true);
192
202
 
193
203
  const { result } = renderHook(() =>
194
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
204
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
195
205
  );
196
206
 
197
207
  await waitFor(() => {
@@ -204,7 +214,8 @@ describe('useCan Hook', () => {
204
214
  pageId: undefined
205
215
  },
206
216
  undefined,
207
- undefined
217
+ undefined,
218
+ false
208
219
  );
209
220
  });
210
221
  });
@@ -215,7 +226,7 @@ describe('useCan Hook', () => {
215
226
  mockIsPermitted.mockResolvedValue(true);
216
227
 
217
228
  const { result, rerender } = renderHook(
218
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
229
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
219
230
  {
220
231
  initialProps: {
221
232
  userId: mockUserId,
@@ -246,7 +257,8 @@ describe('useCan Hook', () => {
246
257
  pageId: undefined
247
258
  },
248
259
  undefined,
249
- undefined
260
+ undefined,
261
+ false
250
262
  );
251
263
  });
252
264
  });
@@ -255,7 +267,7 @@ describe('useCan Hook', () => {
255
267
  mockIsPermitted.mockResolvedValue(true);
256
268
 
257
269
  const { result, rerender } = renderHook(
258
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
270
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
259
271
  {
260
272
  initialProps: {
261
273
  userId: mockUserId,
@@ -287,7 +299,8 @@ describe('useCan Hook', () => {
287
299
  pageId: undefined
288
300
  },
289
301
  undefined,
290
- undefined
302
+ undefined,
303
+ false
291
304
  );
292
305
  });
293
306
  });
@@ -296,7 +309,7 @@ describe('useCan Hook', () => {
296
309
  mockIsPermitted.mockResolvedValue(true);
297
310
 
298
311
  const { result, rerender } = renderHook(
299
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
312
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
300
313
  {
301
314
  initialProps: {
302
315
  userId: mockUserId,
@@ -327,7 +340,8 @@ describe('useCan Hook', () => {
327
340
  pageId: undefined
328
341
  },
329
342
  undefined,
330
- undefined
343
+ undefined,
344
+ false
331
345
  );
332
346
  });
333
347
  });
@@ -338,7 +352,7 @@ describe('useCan Hook', () => {
338
352
  mockIsPermitted.mockRejectedValue('String error');
339
353
 
340
354
  const { result } = renderHook(() =>
341
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
355
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
342
356
  );
343
357
 
344
358
  await waitFor(() => {
@@ -353,7 +367,7 @@ describe('useCan Hook', () => {
353
367
  .mockResolvedValueOnce(true);
354
368
 
355
369
  const { result, rerender } = renderHook(
356
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
370
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
357
371
  {
358
372
  initialProps: {
359
373
  userId: mockUserId,
@@ -383,10 +397,10 @@ describe('useCan Hook', () => {
383
397
 
384
398
  describe('Role-Based Permission Scenarios', () => {
385
399
  it('allows super admin permissions', async () => {
386
- mockIsPermitted.mockResolvedValue(true);
387
-
400
+ // When precomputedSuperAdmin is true, the hook bypasses permission checks
401
+ // Super admins get immediate access without calling isPermitted
388
402
  const { result } = renderHook(() =>
389
- useCan(mockUserId, mockScope, 'update:organisations', undefined, false)
403
+ useCan(mockUserId, mockScope, 'update:organisations', undefined, false, true)
390
404
  );
391
405
 
392
406
  await waitFor(() => {
@@ -395,23 +409,15 @@ describe('useCan Hook', () => {
395
409
  expect(result.current.error).toBeNull();
396
410
  });
397
411
 
398
- expect(mockIsPermitted).toHaveBeenCalledWith(
399
- {
400
- userId: mockUserId,
401
- scope: mockScope,
402
- permission: 'update:organisations',
403
- pageId: undefined
404
- },
405
- undefined,
406
- undefined
407
- );
412
+ // Super admins bypass permission checks - isPermitted should not be called
413
+ expect(mockIsPermitted).not.toHaveBeenCalled();
408
414
  });
409
415
 
410
416
  it('denies super admin permissions for regular users', async () => {
411
417
  mockIsPermitted.mockResolvedValue(false);
412
418
 
413
419
  const { result } = renderHook(() =>
414
- useCan(mockUserId, mockScope, 'super_admin', undefined, false)
420
+ useCan(mockUserId, mockScope, 'super_admin', undefined, false, false)
415
421
  );
416
422
 
417
423
  await waitFor(() => {
@@ -425,7 +431,7 @@ describe('useCan Hook', () => {
425
431
  mockIsPermitted.mockResolvedValue(true);
426
432
 
427
433
  const { result } = renderHook(() =>
428
- useCan(mockUserId, mockScope, 'org_admin', undefined, false)
434
+ useCan(mockUserId, mockScope, 'org_admin', undefined, false, false)
429
435
  );
430
436
 
431
437
  await waitFor(() => {
@@ -439,7 +445,7 @@ describe('useCan Hook', () => {
439
445
  mockIsPermitted.mockResolvedValue(false);
440
446
 
441
447
  const { result } = renderHook(() =>
442
- useCan(mockUserId, mockScope, 'org_admin', undefined, false)
448
+ useCan(mockUserId, mockScope, 'org_admin', undefined, false, false)
443
449
  );
444
450
 
445
451
  await waitFor(() => {
@@ -453,7 +459,7 @@ describe('useCan Hook', () => {
453
459
  mockIsPermitted.mockResolvedValue(true);
454
460
 
455
461
  const { result } = renderHook(() =>
456
- useCan(mockUserId, mockScope, 'event_admin', undefined, false)
462
+ useCan(mockUserId, mockScope, 'event_admin', undefined, false, false)
457
463
  );
458
464
 
459
465
  await waitFor(() => {
@@ -467,7 +473,7 @@ describe('useCan Hook', () => {
467
473
  mockIsPermitted.mockResolvedValue(false);
468
474
 
469
475
  const { result } = renderHook(() =>
470
- useCan(mockUserId, mockScope, 'event_admin', undefined, false)
476
+ useCan(mockUserId, mockScope, 'event_admin', undefined, false, false)
471
477
  );
472
478
 
473
479
  await waitFor(() => {
@@ -481,7 +487,7 @@ describe('useCan Hook', () => {
481
487
  mockIsPermitted.mockResolvedValue(true);
482
488
 
483
489
  const { result } = renderHook(() =>
484
- useCan(mockUserId, mockScope, 'read:users', undefined, false)
490
+ useCan(mockUserId, mockScope, 'read:users', undefined, false, false)
485
491
  );
486
492
 
487
493
  await waitFor(() => {
@@ -495,7 +501,7 @@ describe('useCan Hook', () => {
495
501
  mockIsPermitted.mockResolvedValue(false);
496
502
 
497
503
  const { result } = renderHook(() =>
498
- useCan(mockUserId, mockScope, 'read:users', undefined, false)
504
+ useCan(mockUserId, mockScope, 'read:users', undefined, false, false)
499
505
  );
500
506
 
501
507
  await waitFor(() => {
@@ -509,7 +515,7 @@ describe('useCan Hook', () => {
509
515
  mockIsPermitted.mockResolvedValue(true);
510
516
 
511
517
  const { result } = renderHook(() =>
512
- useCan(mockUserId, mockScope, 'participant', undefined, false)
518
+ useCan(mockUserId, mockScope, 'participant', undefined, false, false)
513
519
  );
514
520
 
515
521
  await waitFor(() => {
@@ -526,7 +532,7 @@ describe('useCan Hook', () => {
526
532
  mockIsPermittedCached.mockResolvedValue(true);
527
533
 
528
534
  const { result } = renderHook(() =>
529
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
535
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
530
536
  );
531
537
 
532
538
  await waitFor(() => {
@@ -552,7 +558,7 @@ describe('useCan Hook', () => {
552
558
  mockIsPermittedCached.mockResolvedValue(false);
553
559
 
554
560
  const { result } = renderHook(() =>
555
- useCan(mockUserId, mockScope, mockPermission, mockPageId, true)
561
+ useCan(mockUserId, mockScope, mockPermission, mockPageId, true, false)
556
562
  );
557
563
 
558
564
  await waitFor(() => {
@@ -569,7 +575,7 @@ describe('useCan Hook', () => {
569
575
  );
570
576
 
571
577
  const { result } = renderHook(() =>
572
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
578
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
573
579
  );
574
580
 
575
581
  // Should show loading initially
@@ -587,7 +593,7 @@ describe('useCan Hook', () => {
587
593
  mockIsPermitted.mockRejectedValue(networkError);
588
594
 
589
595
  const { result } = renderHook(() =>
590
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
596
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
591
597
  );
592
598
 
593
599
  await waitFor(() => {
@@ -603,7 +609,7 @@ describe('useCan Hook', () => {
603
609
  mockIsPermitted.mockResolvedValue(false);
604
610
 
605
611
  const { result } = renderHook(() =>
606
- useCan('', mockScope, mockPermission, undefined, false)
612
+ useCan('', mockScope, mockPermission, undefined, false, false)
607
613
  );
608
614
 
609
615
  await waitFor(() => {
@@ -617,7 +623,7 @@ describe('useCan Hook', () => {
617
623
  mockIsPermitted.mockResolvedValue(false);
618
624
 
619
625
  const { result } = renderHook(() =>
620
- useCan(mockUserId, mockScope, '', undefined, false)
626
+ useCan(mockUserId, mockScope, '', undefined, false, false)
621
627
  );
622
628
 
623
629
  await waitFor(() => {
@@ -631,14 +637,15 @@ describe('useCan Hook', () => {
631
637
  pageId: undefined
632
638
  },
633
639
  undefined,
634
- undefined
640
+ undefined,
641
+ false
635
642
  );
636
643
  });
637
644
  });
638
645
 
639
646
  it('handles empty scope', async () => {
640
647
  const { result } = renderHook(() =>
641
- useCan(mockUserId, {} as any, mockPermission, undefined, false)
648
+ useCan(mockUserId, {} as any, mockPermission, undefined, false, false)
642
649
  );
643
650
 
644
651
  await waitFor(() => {
@@ -654,7 +661,7 @@ describe('useCan Hook', () => {
654
661
 
655
662
  const emptyScope = {} as any;
656
663
  const { result } = renderHook(() =>
657
- useCan(mockUserId, emptyScope, mockPermission, undefined, false)
664
+ useCan(mockUserId, emptyScope, mockPermission, undefined, false, false)
658
665
  );
659
666
 
660
667
  // Initially loading
@@ -678,7 +685,7 @@ describe('useCan Hook', () => {
678
685
 
679
686
  it('handles null userId', async () => {
680
687
  const { result } = renderHook(() =>
681
- useCan(null as any, mockScope, mockPermission, undefined, false)
688
+ useCan(null as any, mockScope, mockPermission, undefined, false, false)
682
689
  );
683
690
 
684
691
  await waitFor(() => {
@@ -690,7 +697,7 @@ describe('useCan Hook', () => {
690
697
 
691
698
  it('handles undefined userId', async () => {
692
699
  const { result } = renderHook(() =>
693
- useCan(undefined as any, mockScope, mockPermission, undefined, false)
700
+ useCan(undefined as any, mockScope, mockPermission, undefined, false, false)
694
701
  );
695
702
 
696
703
  await waitFor(() => {
@@ -704,7 +711,7 @@ describe('useCan Hook', () => {
704
711
  const invalidScope = { organisationId: '', eventId: 'event-123' };
705
712
 
706
713
  const { result } = renderHook(() =>
707
- useCan(mockUserId, invalidScope, mockPermission, undefined, false)
714
+ useCan(mockUserId, invalidScope, mockPermission, undefined, false, false)
708
715
  );
709
716
 
710
717
  await waitFor(() => {
@@ -718,7 +725,7 @@ describe('useCan Hook', () => {
718
725
  const invalidScope = { organisationId: ' ', eventId: 'event-123' };
719
726
 
720
727
  const { result } = renderHook(() =>
721
- useCan(mockUserId, invalidScope, mockPermission, undefined, false)
728
+ useCan(mockUserId, invalidScope, mockPermission, undefined, false, false)
722
729
  );
723
730
 
724
731
  await waitFor(() => {
@@ -730,7 +737,7 @@ describe('useCan Hook', () => {
730
737
 
731
738
  it('handles undefined scope gracefully', async () => {
732
739
  const { result } = renderHook(() =>
733
- useCan(mockUserId, undefined as any, mockPermission, undefined, false)
740
+ useCan(mockUserId, undefined as any, mockPermission, undefined, false, false)
734
741
  );
735
742
 
736
743
  await waitFor(() => {
@@ -742,7 +749,7 @@ describe('useCan Hook', () => {
742
749
 
743
750
  it('handles null scope gracefully', async () => {
744
751
  const { result } = renderHook(() =>
745
- useCan(mockUserId, null as any, mockPermission, undefined, false)
752
+ useCan(mockUserId, null as any, mockPermission, undefined, false, false)
746
753
  );
747
754
 
748
755
  await waitFor(() => {
@@ -758,7 +765,7 @@ describe('useCan Hook', () => {
758
765
  mockIsPermitted.mockResolvedValue(true);
759
766
 
760
767
  const { result, rerender } = renderHook(() =>
761
- useCan(mockUserId, mockScope, mockPermission, undefined, false)
768
+ useCan(mockUserId, mockScope, mockPermission, undefined, false, false)
762
769
  );
763
770
 
764
771
  await waitFor(() => {
@@ -778,7 +785,7 @@ describe('useCan Hook', () => {
778
785
  mockIsPermitted.mockResolvedValue(true);
779
786
 
780
787
  const { result, rerender } = renderHook(
781
- ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false),
788
+ ({ userId, scope, permission }) => useCan(userId, scope, permission, undefined, false, false),
782
789
  {
783
790
  initialProps: {
784
791
  userId: mockUserId,