@jmruthers/pace-core 0.5.189 → 0.5.190

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 (420) hide show
  1. package/core-usage-manifest.json +0 -4
  2. package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
  3. package/dist/{DataTable-GUFUNZ3N.js → DataTable-ON3IXISJ.js} +8 -8
  4. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-C4uxosp6.d.ts} +83 -24
  5. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  6. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-X5NXANVI.js} +4 -2
  7. package/dist/{api-YP7XD5L6.js → api-I6UCQ5S6.js} +4 -2
  8. package/dist/{chunk-DDM4CCYT.js → chunk-4QYC5L4K.js} +60 -35
  9. package/dist/chunk-4QYC5L4K.js.map +1 -0
  10. package/dist/{chunk-IM4QE42D.js → chunk-73HSNNOQ.js} +141 -326
  11. package/dist/chunk-73HSNNOQ.js.map +1 -0
  12. package/dist/{chunk-YHCN776L.js → chunk-DZWK57KZ.js} +2 -75
  13. package/dist/chunk-DZWK57KZ.js.map +1 -0
  14. package/dist/{chunk-3GOZZZYH.js → chunk-HQVPB5MZ.js} +238 -301
  15. package/dist/chunk-HQVPB5MZ.js.map +1 -0
  16. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  17. package/dist/chunk-HW3OVDUF.js.map +1 -0
  18. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  19. package/dist/chunk-I7PSE6JW.js.map +1 -0
  20. package/dist/{chunk-VGZZXKBR.js → chunk-J2XXC7R5.js} +280 -52
  21. package/dist/chunk-J2XXC7R5.js.map +1 -0
  22. package/dist/{chunk-UCQSRW7Z.js → chunk-NIU6J6OX.js} +425 -378
  23. package/dist/chunk-NIU6J6OX.js.map +1 -0
  24. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  25. package/dist/{chunk-HEHYGYOX.js → chunk-RUYZKXOD.js} +401 -46
  26. package/dist/chunk-RUYZKXOD.js.map +1 -0
  27. package/dist/{chunk-2UUZZJFT.js → chunk-SDMHPX3X.js} +176 -160
  28. package/dist/{chunk-2UUZZJFT.js.map → chunk-SDMHPX3X.js.map} +1 -1
  29. package/dist/{chunk-MX64ZF6I.js → chunk-STYK4OH2.js} +11 -11
  30. package/dist/chunk-STYK4OH2.js.map +1 -0
  31. package/dist/{chunk-YGPFYGA6.js → chunk-VVBAW5A5.js} +822 -498
  32. package/dist/chunk-VVBAW5A5.js.map +1 -0
  33. package/dist/chunk-Y4BUBBHD.js +614 -0
  34. package/dist/chunk-Y4BUBBHD.js.map +1 -0
  35. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  36. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  37. package/dist/components.d.ts +3 -4
  38. package/dist/components.js +19 -19
  39. package/dist/components.js.map +1 -1
  40. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  41. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  42. package/dist/hooks.d.ts +10 -5
  43. package/dist/hooks.js +14 -8
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +13 -11
  46. package/dist/index.js +79 -69
  47. package/dist/index.js.map +1 -1
  48. package/dist/providers.d.ts +3 -3
  49. package/dist/providers.js +3 -1
  50. package/dist/rbac/index.d.ts +76 -12
  51. package/dist/rbac/index.js +12 -9
  52. package/dist/types.d.ts +1 -1
  53. package/dist/types.js +1 -1
  54. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-DxIDS4bC.d.ts} +16 -9
  55. package/dist/utils.js +16 -16
  56. package/docs/README.md +2 -2
  57. package/docs/api/classes/ColumnFactory.md +1 -1
  58. package/docs/api/classes/ErrorBoundary.md +1 -1
  59. package/docs/api/classes/InvalidScopeError.md +2 -2
  60. package/docs/api/classes/Logger.md +1 -1
  61. package/docs/api/classes/MissingUserContextError.md +2 -2
  62. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  63. package/docs/api/classes/PermissionDeniedError.md +1 -1
  64. package/docs/api/classes/RBACAuditManager.md +1 -1
  65. package/docs/api/classes/RBACCache.md +1 -1
  66. package/docs/api/classes/RBACEngine.md +4 -4
  67. package/docs/api/classes/RBACError.md +1 -1
  68. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  69. package/docs/api/classes/SecureSupabaseClient.md +21 -16
  70. package/docs/api/classes/StorageUtils.md +7 -4
  71. package/docs/api/enums/FileCategory.md +1 -1
  72. package/docs/api/enums/LogLevel.md +1 -1
  73. package/docs/api/enums/RBACErrorCode.md +1 -1
  74. package/docs/api/enums/RPCFunction.md +1 -1
  75. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  76. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  77. package/docs/api/interfaces/AggregateConfig.md +1 -1
  78. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  79. package/docs/api/interfaces/AvatarProps.md +1 -1
  80. package/docs/api/interfaces/BadgeProps.md +1 -1
  81. package/docs/api/interfaces/ButtonProps.md +1 -1
  82. package/docs/api/interfaces/CalendarProps.md +20 -6
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/ComplianceResult.md +1 -1
  87. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  88. package/docs/api/interfaces/DataRecord.md +1 -1
  89. package/docs/api/interfaces/DataTableAction.md +1 -1
  90. package/docs/api/interfaces/DataTableColumn.md +1 -1
  91. package/docs/api/interfaces/DataTableProps.md +1 -1
  92. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  93. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  94. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  95. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  96. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  97. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  98. package/docs/api/interfaces/ExportColumn.md +1 -1
  99. package/docs/api/interfaces/ExportOptions.md +1 -1
  100. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  101. package/docs/api/interfaces/FileMetadata.md +1 -1
  102. package/docs/api/interfaces/FileReference.md +2 -2
  103. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  104. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  105. package/docs/api/interfaces/FileUploadProps.md +30 -19
  106. package/docs/api/interfaces/FooterProps.md +1 -1
  107. package/docs/api/interfaces/FormFieldProps.md +1 -1
  108. package/docs/api/interfaces/FormProps.md +1 -1
  109. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  110. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  111. package/docs/api/interfaces/InputProps.md +1 -1
  112. package/docs/api/interfaces/LabelProps.md +1 -1
  113. package/docs/api/interfaces/LoggerConfig.md +1 -1
  114. package/docs/api/interfaces/LoginFormProps.md +1 -1
  115. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  116. package/docs/api/interfaces/NavigationContextType.md +9 -9
  117. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  118. package/docs/api/interfaces/NavigationItem.md +1 -1
  119. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  120. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  121. package/docs/api/interfaces/Organisation.md +1 -1
  122. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  123. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  124. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  125. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  126. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  127. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  128. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  129. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  130. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  131. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  132. package/docs/api/interfaces/PaletteData.md +1 -1
  133. package/docs/api/interfaces/ParsedAddress.md +1 -1
  134. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  135. package/docs/api/interfaces/ProgressProps.md +3 -11
  136. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  137. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  138. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  139. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  140. package/docs/api/interfaces/QuickFix.md +1 -1
  141. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  142. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  143. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  144. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  145. package/docs/api/interfaces/RBACConfig.md +1 -1
  146. package/docs/api/interfaces/RBACContext.md +1 -1
  147. package/docs/api/interfaces/RBACLogger.md +1 -1
  148. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  149. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  150. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  151. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  152. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  153. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  154. package/docs/api/interfaces/RBACResult.md +1 -1
  155. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  156. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  157. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  158. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  161. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  162. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  163. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  164. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  165. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  166. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  167. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  168. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  169. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  170. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  171. package/docs/api/interfaces/RouteConfig.md +10 -10
  172. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  173. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  174. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  175. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  176. package/docs/api/interfaces/SetupIssue.md +1 -1
  177. package/docs/api/interfaces/StorageConfig.md +4 -4
  178. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  179. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  180. package/docs/api/interfaces/StorageListOptions.md +22 -9
  181. package/docs/api/interfaces/StorageListResult.md +4 -4
  182. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  183. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  184. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  185. package/docs/api/interfaces/StyleImport.md +1 -1
  186. package/docs/api/interfaces/SwitchProps.md +1 -1
  187. package/docs/api/interfaces/TabsContentProps.md +1 -1
  188. package/docs/api/interfaces/TabsListProps.md +1 -1
  189. package/docs/api/interfaces/TabsProps.md +1 -1
  190. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  191. package/docs/api/interfaces/TextareaProps.md +1 -1
  192. package/docs/api/interfaces/ToastActionElement.md +1 -1
  193. package/docs/api/interfaces/ToastProps.md +1 -1
  194. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  195. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  196. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  197. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  198. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  199. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  200. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  201. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  202. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  203. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  205. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  207. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  208. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  209. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  210. package/docs/api/interfaces/UserEventAccess.md +11 -11
  211. package/docs/api/interfaces/UserMenuProps.md +1 -1
  212. package/docs/api/interfaces/UserProfile.md +1 -1
  213. package/docs/api/modules.md +151 -92
  214. package/docs/api-reference/components.md +15 -7
  215. package/docs/api-reference/providers.md +2 -2
  216. package/docs/api-reference/rpc-functions.md +1 -0
  217. package/docs/best-practices/README.md +1 -1
  218. package/docs/best-practices/deployment.md +8 -8
  219. package/docs/getting-started/examples/README.md +2 -2
  220. package/docs/getting-started/installation-guide.md +4 -4
  221. package/docs/getting-started/quick-start.md +3 -3
  222. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  223. package/docs/rbac/compliance/compliance-guide.md +2 -2
  224. package/docs/rbac/event-based-apps.md +2 -2
  225. package/docs/rbac/getting-started.md +2 -2
  226. package/docs/rbac/quick-start.md +2 -2
  227. package/docs/security/README.md +4 -4
  228. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  229. package/docs/troubleshooting/README.md +2 -2
  230. package/docs/troubleshooting/migration.md +3 -3
  231. package/package.json +1 -3
  232. package/scripts/check-pace-core-compliance.cjs +1 -1
  233. package/scripts/check-pace-core-compliance.js +1 -1
  234. package/src/__tests__/fixtures/supabase.ts +301 -0
  235. package/src/__tests__/public-recipe-view.test.ts +9 -9
  236. package/src/__tests__/rls-policies.test.ts +197 -61
  237. package/src/components/AddressField/AddressField.test.tsx +42 -0
  238. package/src/components/AddressField/AddressField.tsx +71 -60
  239. package/src/components/AddressField/README.md +1 -0
  240. package/src/components/Alert/Alert.test.tsx +50 -10
  241. package/src/components/Alert/Alert.tsx +5 -3
  242. package/src/components/Avatar/Avatar.test.tsx +95 -43
  243. package/src/components/Avatar/Avatar.tsx +16 -16
  244. package/src/components/Button/Button.test.tsx +2 -1
  245. package/src/components/Button/Button.tsx +3 -3
  246. package/src/components/Calendar/Calendar.test.tsx +53 -37
  247. package/src/components/Calendar/Calendar.tsx +409 -82
  248. package/src/components/Card/Card.test.tsx +7 -4
  249. package/src/components/Card/Card.tsx +3 -6
  250. package/src/components/Checkbox/Checkbox.tsx +2 -2
  251. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  252. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  253. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  254. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  255. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  256. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  257. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  258. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  259. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  260. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  261. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  262. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  264. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  265. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  266. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  267. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  268. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  269. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  270. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  271. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  272. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  273. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  274. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  275. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  276. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  277. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  278. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  280. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  281. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  282. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  283. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  284. package/src/components/Dialog/Dialog.tsx +2 -2
  285. package/src/components/EventSelector/EventSelector.tsx +7 -7
  286. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  287. package/src/components/FileUpload/FileUpload.tsx +7 -4
  288. package/src/components/Header/Header.test.tsx +28 -0
  289. package/src/components/Header/Header.tsx +22 -9
  290. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  291. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  292. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  293. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  294. package/src/components/OrganisationSelector/OrganisationSelector.tsx +8 -8
  295. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  296. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  297. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  298. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  299. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  300. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  301. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  302. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  303. package/src/components/Progress/Progress.test.tsx +18 -19
  304. package/src/components/Progress/Progress.tsx +31 -32
  305. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  306. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  307. package/src/components/Select/Select.tsx +5 -5
  308. package/src/components/Switch/Switch.test.tsx +2 -1
  309. package/src/components/Switch/Switch.tsx +1 -1
  310. package/src/components/Toast/Toast.tsx +1 -1
  311. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  312. package/src/components/UserMenu/UserMenu.tsx +3 -3
  313. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  314. package/src/eslint-rules/pace-core-compliance.js +0 -2
  315. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  316. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  317. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  318. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  319. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  320. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  321. package/src/hooks/__tests__/{usePublicEvent.unit.test.ts → usePublicEvent.test.ts} +28 -1
  322. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  323. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +58 -16
  324. package/src/hooks/index.ts +1 -1
  325. package/src/hooks/public/usePublicEvent.ts +2 -2
  326. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  327. package/src/hooks/useAppConfig.ts +24 -5
  328. package/src/hooks/useFileDisplay.ts +297 -34
  329. package/src/hooks/useFileReference.ts +56 -11
  330. package/src/hooks/useFileUrl.ts +1 -1
  331. package/src/hooks/useInactivityTracker.ts +16 -7
  332. package/src/hooks/usePermissionCache.test.ts +85 -8
  333. package/src/hooks/useQueryCache.ts +21 -0
  334. package/src/hooks/useSecureDataAccess.test.ts +80 -35
  335. package/src/hooks/useSecureDataAccess.ts +80 -37
  336. package/src/providers/services/EventServiceProvider.tsx +37 -17
  337. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  338. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  339. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  340. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  341. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  342. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  343. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  344. package/src/rbac/api.ts +240 -36
  345. package/src/rbac/cache-invalidation.ts +21 -7
  346. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  347. package/src/rbac/components/NavigationGuard.tsx +23 -63
  348. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  349. package/src/rbac/components/NavigationProvider.tsx +13 -11
  350. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  351. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  352. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  353. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  354. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  355. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  356. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  357. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  358. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  359. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  360. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  361. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  362. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  363. package/src/rbac/engine.ts +4 -2
  364. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  365. package/src/rbac/hooks/index.ts +3 -0
  366. package/src/rbac/hooks/useCan.test.ts +101 -53
  367. package/src/rbac/hooks/usePermissions.ts +108 -41
  368. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  369. package/src/rbac/hooks/useRBAC.ts +83 -40
  370. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  371. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  372. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  373. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  374. package/src/rbac/request-deduplication.ts +1 -1
  375. package/src/rbac/secureClient.ts +72 -12
  376. package/src/rbac/security.ts +29 -23
  377. package/src/rbac/types.ts +10 -0
  378. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  379. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  380. package/src/rbac/utils/__tests__/eventContext.test.ts +6 -1
  381. package/src/rbac/utils/contextValidator.ts +288 -0
  382. package/src/rbac/utils/eventContext.ts +48 -2
  383. package/src/services/EventService.ts +165 -21
  384. package/src/services/OrganisationService.ts +37 -2
  385. package/src/services/__tests__/EventService.test.ts +26 -21
  386. package/src/types/file-reference.ts +13 -10
  387. package/src/utils/app/appNameResolver.test.ts +346 -73
  388. package/src/utils/context/superAdminOverride.ts +58 -0
  389. package/src/utils/file-reference/index.ts +61 -33
  390. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  391. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  392. package/src/utils/storage/helpers.test.ts +1 -1
  393. package/src/utils/storage/helpers.ts +38 -19
  394. package/src/utils/storage/types.ts +15 -8
  395. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  396. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  397. package/src/vite-env.d.ts +2 -2
  398. package/dist/chunk-3GOZZZYH.js.map +0 -1
  399. package/dist/chunk-DDM4CCYT.js.map +0 -1
  400. package/dist/chunk-E7UAOUMY.js +0 -75
  401. package/dist/chunk-E7UAOUMY.js.map +0 -1
  402. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  403. package/dist/chunk-HEHYGYOX.js.map +0 -1
  404. package/dist/chunk-IM4QE42D.js.map +0 -1
  405. package/dist/chunk-MX64ZF6I.js.map +0 -1
  406. package/dist/chunk-SAUPYVLF.js.map +0 -1
  407. package/dist/chunk-THRPYOFK.js.map +0 -1
  408. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  409. package/dist/chunk-VGZZXKBR.js.map +0 -1
  410. package/dist/chunk-YGPFYGA6.js.map +0 -1
  411. package/dist/chunk-YHCN776L.js.map +0 -1
  412. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
  413. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
  414. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +0 -703
  415. package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
  416. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
  417. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-ON3IXISJ.js.map} +0 -0
  418. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-X5NXANVI.js.map} +0 -0
  419. /package/dist/{api-YP7XD5L6.js.map → api-I6UCQ5S6.js.map} +0 -0
  420. /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
@@ -96,7 +96,8 @@ export function useDataTablePermissions<TData extends DataRecord>(
96
96
 
97
97
  // Only update the stable scope if the resolved scope has actually changed
98
98
  // This prevents unnecessary re-renders while maintaining up-to-date permission checks
99
- if (rawResolvedScope && rawResolvedScope.organisationId) {
99
+ // Allow scope updates even when organisationId is undefined (for users without orgs, like profile pages)
100
+ if (rawResolvedScope) {
100
101
  const newScope = {
101
102
  organisationId: rawResolvedScope.organisationId,
102
103
  appId: rawResolvedScope.appId,
@@ -113,8 +114,8 @@ export function useDataTablePermissions<TData extends DataRecord>(
113
114
  eventId: newScope.eventId
114
115
  };
115
116
  }
116
- } else if (!rawResolvedScope) {
117
- // Reset to empty scope when no resolved scope (e.g., user logged out)
117
+ } else if (!rawResolvedScope && !scopeLoading) {
118
+ // Reset to empty scope when no resolved scope and resolution is complete (e.g., user logged out)
118
119
  stableScopeRef.current = { organisationId: undefined, appId: undefined, eventId: undefined };
119
120
  }
120
121
 
@@ -123,10 +124,28 @@ export function useDataTablePermissions<TData extends DataRecord>(
123
124
  /**
124
125
  * Effective scope for permission checks.
125
126
  *
126
- * Only use the resolved scope if it has a valid organisationId and scope resolution is complete.
127
- * This ensures permission checks only happen when we have proper context.
127
+ * Use the resolved scope once scope resolution is complete, even if organisationId is undefined.
128
+ * This allows permission checks for users without organisations (e.g., profile pages).
129
+ * The database function rbac_check_permission_simplified can handle NULL organisation_id.
130
+ *
131
+ * IMPORTANT: When using pageName (not pageId), we MUST wait for appId to be resolved,
132
+ * because the RPC function needs appId to resolve the pageName to a pageId UUID.
133
+ * If we have a pageId (UUID), we can proceed even without appId.
134
+ *
135
+ * The key issue: When pageName is used without appId, the RPC function cannot resolve
136
+ * the pageName to a pageId, which causes permission checks to fail initially, showing
137
+ * "Access Denied" before the scope resolves and permissions are re-checked.
128
138
  */
129
- const effectiveScope = (!scopeLoading && stableScope.organisationId) ? stableScope : null;
139
+ const isPageName = !pageId && !!pageName; // We're using pageName, not a UUID pageId
140
+ const needsAppIdForResolution = isPageName; // Only need appId if we're resolving a pageName
141
+
142
+ // Wait for scope resolution if:
143
+ // 1. Scope is still loading, OR
144
+ // 2. We're using pageName and don't have appId yet (needed to resolve pageName to pageId)
145
+ // This prevents premature permission checks that would fail and show "Access Denied"
146
+ const shouldWaitForScope = scopeLoading || (needsAppIdForResolution && !stableScope.appId);
147
+
148
+ const effectiveScope = (!shouldWaitForScope) ? stableScope : null;
130
149
 
131
150
  // Always call hooks with consistent parameters to avoid React hooks order violations
132
151
  const userId = user?.id || '';
@@ -136,7 +155,9 @@ export function useDataTablePermissions<TData extends DataRecord>(
136
155
  const deletePermission = `delete:page.${effectivePageId}` as unknown as Permission;
137
156
 
138
157
  // Always use a consistent scope object to prevent hooks order violations
139
- // When scope is loading or invalid, use empty scope which will cause useCan to return false
158
+ // When scope is loading or we need appId for pageName resolution, use empty scope which will cause useCan to wait
159
+ // When scope resolution is complete (even with undefined organisationId), use the resolved scope
160
+ // This allows permission checks for users without organisations (e.g., profile pages)
140
161
  const consistentScope = effectiveScope || { organisationId: undefined, eventId: undefined, appId: undefined };
141
162
 
142
163
  const permissions = {
@@ -281,10 +281,39 @@ describe('[unit] getRowDepth', () => {
281
281
 
282
282
  const childDepth = getRowDepth(nestedData[1], nestedData);
283
283
  const grandchildDepth = getRowDepth(nestedData[2], nestedData);
284
-
284
+
285
285
  expect(childDepth).toBe(1);
286
286
  expect(grandchildDepth).toBe(2);
287
287
  });
288
+
289
+ it('caps traversal at the provided maximum depth', () => {
290
+ const deepHierarchy = [
291
+ { id: 'root', name: 'Root', value: 0, isParent: true },
292
+ ...Array.from({ length: 120 }, (_, index) => ({
293
+ id: `child-${index}`,
294
+ name: `Child ${index}`,
295
+ value: index,
296
+ parentId: index === 0 ? 'root' : `child-${index - 1}`,
297
+ isParent: false,
298
+ })),
299
+ ];
300
+
301
+ const deepestChild = deepHierarchy[deepHierarchy.length - 1];
302
+ const depth = getRowDepth(deepestChild, deepHierarchy, 50);
303
+
304
+ expect(depth).toBe(50);
305
+ });
306
+
307
+ it('breaks traversal on circular references', () => {
308
+ const cyclicHierarchy = [
309
+ { id: 'node1', name: 'Node 1', value: 1, parentId: 'node2', isParent: false },
310
+ { id: 'node2', name: 'Node 2', value: 2, parentId: 'node1', isParent: false }
311
+ ];
312
+
313
+ const depth = getRowDepth(cyclicHierarchy[0], cyclicHierarchy, 10);
314
+
315
+ expect(depth).toBe(2);
316
+ });
288
317
  });
289
318
 
290
319
  describe('[unit] shouldShowColumnForRow', () => {
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { HierarchicalDataRow, DataTableColumn, DataRecord } from '../types';
9
+ import { createLogger } from '../../../utils/core/logger';
9
10
 
10
11
  /**
11
12
  * Validates that data conforms to hierarchical structure
@@ -83,7 +84,9 @@ export function groupHierarchicalData<TData extends HierarchicalDataRow>(
83
84
  * Optimized depth cache to avoid recalculating depth for the same row
84
85
  * This prevents O(n²) behavior when calculating depths for all rows
85
86
  */
86
- const depthCache = new WeakMap<unknown[], Map<string, number>>();
87
+ const depthCache = new WeakMap<unknown[], Map<number, Map<string, number>>>();
88
+
89
+ const logger = createLogger('HierarchicalUtils');
87
90
 
88
91
  /**
89
92
  * Gets the depth level of a row in the hierarchy
@@ -102,13 +105,20 @@ const depthCache = new WeakMap<unknown[], Map<string, number>>();
102
105
  */
103
106
  export function getRowDepth<TData extends HierarchicalDataRow>(
104
107
  row: TData,
105
- allData: TData[]
108
+ allData: TData[],
109
+ maxDepth: number = 100
106
110
  ): number {
107
111
  // Check cache first
108
- let cachedDepths = depthCache.get(allData);
112
+ let cachedDepthsByLimit = depthCache.get(allData);
113
+ if (!cachedDepthsByLimit) {
114
+ cachedDepthsByLimit = new Map();
115
+ depthCache.set(allData, cachedDepthsByLimit);
116
+ }
117
+
118
+ let cachedDepths = cachedDepthsByLimit.get(maxDepth);
109
119
  if (!cachedDepths) {
110
120
  cachedDepths = new Map();
111
- depthCache.set(allData, cachedDepths);
121
+ cachedDepthsByLimit.set(maxDepth, cachedDepths);
112
122
  }
113
123
 
114
124
  // Return cached depth if available
@@ -118,7 +128,7 @@ export function getRowDepth<TData extends HierarchicalDataRow>(
118
128
 
119
129
  // Calculate depth
120
130
  let depth = 0;
121
-
131
+
122
132
  if (row.isParent) {
123
133
  depth = 0;
124
134
  } else if (!row.parentId) {
@@ -131,25 +141,43 @@ export function getRowDepth<TData extends HierarchicalDataRow>(
131
141
  parentMap.set(item.id, item);
132
142
  }
133
143
  });
134
-
144
+
145
+ const visited = new Set<string>();
146
+
135
147
  // Walk up the parent chain
136
148
  let current = row;
137
- while (current.parentId) {
149
+ while (current.parentId && depth < maxDepth) {
150
+ if (visited.has(current.id)) {
151
+ logger.warn('Circular reference detected while calculating row depth', {
152
+ rowId: row.id,
153
+ currentId: current.id,
154
+ });
155
+ break;
156
+ }
157
+
158
+ visited.add(current.id);
138
159
  depth++;
139
160
  const parent = parentMap.get(current.parentId);
140
-
161
+
141
162
  if (!parent || parent.isParent) {
142
163
  break;
143
164
  }
144
-
165
+
145
166
  current = parent;
146
-
167
+
147
168
  // Check cache during traversal
148
169
  if (cachedDepths.has(current.id)) {
149
170
  depth += cachedDepths.get(current.id)!;
150
171
  break;
151
172
  }
152
173
  }
174
+
175
+ if (depth >= maxDepth && current.parentId) {
176
+ logger.warn('Maximum hierarchy depth reached while calculating row depth', {
177
+ rowId: row.id,
178
+ maxDepth,
179
+ });
180
+ }
153
181
  }
154
182
 
155
183
  // Cache the result
@@ -301,13 +301,18 @@ describe('DatePickerWithTimezone Component', () => {
301
301
  selected: selected,
302
302
  onSelect: onSelect,
303
303
  initialFocus: true,
304
- captionLayout: 'dropdown-buttons',
305
- fromYear: 1900,
306
- toYear: 2100,
304
+ captionLayout: 'dropdown',
305
+ startMonth: expect.any(Date),
306
+ endMonth: expect.any(Date),
307
307
  className: 'p-0'
308
308
  }),
309
309
  expect.anything()
310
310
  );
311
+
312
+ // Verify the date range is correct
313
+ const callArgs = MockedCalendar.mock.calls[0][0];
314
+ expect(callArgs.startMonth).toEqual(new Date(1900, 0));
315
+ expect(callArgs.endMonth).toEqual(new Date(2100, 11));
311
316
  });
312
317
  });
313
318
  });
@@ -100,16 +100,16 @@ export function DatePickerWithTimezone({
100
100
  selected={selected}
101
101
  onSelect={onSelect}
102
102
  initialFocus
103
- captionLayout="dropdown-buttons"
104
- fromYear={1900}
105
- toYear={2100}
103
+ captionLayout="dropdown"
104
+ startMonth={new Date(1900, 0)}
105
+ endMonth={new Date(2100, 11)}
106
106
  className="p-0"
107
107
  />
108
108
  </div>
109
109
 
110
110
  <div className="flex items-center justify-between border-t border-border px-3 py-2">
111
111
  <div className="flex items-center gap-2 text-sm text-muted-foreground">
112
- <Clock className="h-4 w-4" aria-hidden="true" />
112
+ <Clock className="size-4" aria-hidden="true" />
113
113
  <span>
114
114
  Timezone: <span aria-label={`Timezone ${timezoneDisplay}`}>{timezoneDisplay}</span>
115
115
  </span>
@@ -280,7 +280,7 @@ const sizeClasses = {
280
280
  md: 'max-w-md',
281
281
  lg: 'max-w-lg',
282
282
  xl: 'max-w-xl',
283
- full: 'max-w-full h-full',
283
+ full: 'max-w-full size-full',
284
284
  auto: 'max-w-none w-auto min-w-0'
285
285
  };
286
286
 
@@ -527,7 +527,7 @@ const DialogContent = React.forwardRef<
527
527
  {children}
528
528
  {showCloseButton && (
529
529
  <DialogPrimitive.Close className="absolute right-4 top-4 z-10 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
530
- <X className="h-4 w-4" />
530
+ <X className="size-4" />
531
531
  <span className="sr-only">Close</span>
532
532
  </DialogPrimitive.Close>
533
533
  )}
@@ -296,7 +296,7 @@ export function EventSelector({
296
296
  return (
297
297
  <div className={className}>
298
298
  <Alert variant="destructive">
299
- <Lock className="h-4 w-4" />
299
+ <Lock className="size-4" />
300
300
  <AlertDescription className="flex items-center justify-between">
301
301
  <span>{error.message}</span>
302
302
  {showRetryButton && (
@@ -306,7 +306,7 @@ export function EventSelector({
306
306
  onClick={handleRetry}
307
307
  className="ml-2"
308
308
  >
309
- <RefreshCw className="h-3 w-3 mr-1" />
309
+ <RefreshCw className="size-3 mr-1" />
310
310
  Retry
311
311
  </Button>
312
312
  )}
@@ -322,7 +322,7 @@ export function EventSelector({
322
322
  return (
323
323
  <div className={className}>
324
324
  <Alert variant="inline">
325
- <AlertCircle className="h-4 w-4 text-acc-700" />
325
+ <AlertCircle className="size-4 text-acc-700" />
326
326
  <AlertDescription className="flex items-center justify-between">
327
327
  <span>No events available.</span>
328
328
  {showRetryButton && (
@@ -332,7 +332,7 @@ export function EventSelector({
332
332
  onClick={handleRetry}
333
333
  className="ml-2"
334
334
  >
335
- <RefreshCw className="h-3 w-3 mr-1" />
335
+ <RefreshCw className="size-3 mr-1" />
336
336
  Refresh
337
337
  </Button>
338
338
  )}
@@ -355,7 +355,7 @@ export function EventSelector({
355
355
  <SelectValue placeholder={placeholder}>
356
356
  {selectedEvent && (
357
357
  <div className="flex items-center gap-2">
358
- <Calendar className="h-4 w-4 flex-shrink-0" />
358
+ <Calendar className="size-4 flex-shrink-0" />
359
359
  <span className="truncate">{selectedEvent.event_name}</span>
360
360
  {selectedEvent.event_date && (
361
361
  <span className="text-xs text-muted-foreground flex-shrink-0">
@@ -380,7 +380,7 @@ export function EventSelector({
380
380
  >
381
381
  <div className="flex items-center gap-2 w-full">
382
382
  {showNextEventIndicator && isNext && (
383
- <Star className="h-3 w-3 text-acc-500" />
383
+ <Star className="size-3 text-acc-500" />
384
384
  )}
385
385
  <div className="flex-1">
386
386
  <div className="flex items-center gap-2">
@@ -395,7 +395,7 @@ export function EventSelector({
395
395
  </div>
396
396
  {showEventDetails && event.event_date && (
397
397
  <div className="flex items-center gap-1 text-xs text-muted-foreground">
398
- <Calendar className="h-3 w-3" />
398
+ <Calendar className="size-3" />
399
399
  <span>{formatEventDate(event.event_date)}</span>
400
400
  {showNextEventIndicator && isNext && (
401
401
  <span className="text-acc-600 font-medium">