@jmruthers/pace-core 0.6.11 → 0.6.12

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 (533) hide show
  1. package/dist/{DataTable-EFYP2QLE.js → DataTable-AQAHSFLM.js} +7 -6
  2. package/dist/{api-BZR2CYXL.js → api-6OQXYT67.js} +2 -1
  3. package/dist/{chunk-L5LFKKLJ.js → chunk-2GBDPPUC.js} +1 -1
  4. package/dist/{chunk-J2KQK6DG.js → chunk-AP5FG7W4.js} +2 -2
  5. package/dist/{chunk-UZNAFKGW.js → chunk-GHCUP64P.js} +1 -21
  6. package/dist/{chunk-V7FTM2LU.js → chunk-H6RTU4DZ.js} +37 -19
  7. package/dist/{chunk-KJXRL3XE.js → chunk-HQTYP6BX.js} +79 -45
  8. package/dist/{chunk-YFTFFJIV.js → chunk-M7QE7XOA.js} +3 -3
  9. package/dist/{chunk-YYTWKVHO.js → chunk-MVVWZ7JV.js} +25 -30
  10. package/dist/{chunk-PCSHBLPB.js → chunk-NJ7FGQWB.js} +5 -5
  11. package/dist/{chunk-WY6Y7KC3.js → chunk-QWIG36BZ.js} +3 -3
  12. package/dist/{chunk-4R3T5ENU.js → chunk-S57OLCLO.js} +9 -6
  13. package/dist/chunk-VFLR5K2H.js +23 -0
  14. package/dist/{chunk-2OEVOGGR.js → chunk-Y2LWSLLB.js} +41 -25
  15. package/dist/{chunk-7A6IMHH2.js → chunk-YFGNMB67.js} +75 -6
  16. package/dist/components.d.ts +3 -3
  17. package/dist/components.js +13 -12
  18. package/dist/{functions-DH45k8ec.d.ts → functions-hF5ImHCr.d.ts} +1 -1
  19. package/dist/hooks.js +8 -7
  20. package/dist/index.d.ts +5 -5
  21. package/dist/index.js +17 -16
  22. package/dist/providers.js +3 -2
  23. package/dist/rbac/index.d.ts +10 -10
  24. package/dist/rbac/index.js +9 -8
  25. package/dist/{types-BE2sEHKd.d.ts → types-Besvoyzb.d.ts} +1 -1
  26. package/dist/{types-CvOPXWWZ.d.ts → types-CGHrxfqc.d.ts} +3 -0
  27. package/dist/types.d.ts +2 -2
  28. package/dist/{usePublicPageContext-B91dGYW1.d.ts → usePublicPageContext-BQrHf95t.d.ts} +1 -1
  29. package/dist/utils.js +4 -3
  30. package/docs/api/@jmruthers/namespaces/DialogPortal/README.md +14 -0
  31. package/docs/api/@jmruthers/namespaces/DialogPortal/variables/displayName.md +11 -0
  32. package/docs/api/README.md +6 -2
  33. package/docs/api/_media/README.md +186 -0
  34. package/docs/api/classes/ColumnFactory.md +225 -0
  35. package/docs/api/classes/Logger.md +246 -0
  36. package/docs/api/classes/RBACAuditManager.md +299 -0
  37. package/docs/api/classes/RBACCache.md +389 -0
  38. package/docs/api/classes/RBACEngine.md +181 -0
  39. package/docs/api/classes/SecureSupabaseClient.md +168 -0
  40. package/docs/api/classes/StorageUtils.md +324 -0
  41. package/docs/api/enumerations/FileCategory.md +137 -0
  42. package/docs/api/enumerations/LogLevel.md +43 -0
  43. package/docs/api/enumerations/RBACErrorCode.md +169 -0
  44. package/docs/api/enumerations/RPCFunction.md +89 -0
  45. package/docs/api/functions/AccessDenied.md +30 -0
  46. package/docs/api/functions/AppSwitcher.md +21 -0
  47. package/docs/api/functions/Badge.md +42 -0
  48. package/docs/api/functions/ContextSelector.md +43 -0
  49. package/docs/api/functions/DataTable.md +36 -0
  50. package/docs/api/functions/DatePickerWithTimezone.md +28 -0
  51. package/docs/api/functions/DialogBody.md +24 -0
  52. package/docs/api/functions/DialogFooter.md +24 -0
  53. package/docs/api/functions/DialogHeader.md +24 -0
  54. package/docs/api/functions/ErrorBoundaryProvider.md +28 -0
  55. package/docs/api/functions/EventServiceProvider.md +28 -0
  56. package/docs/api/functions/FileDisplay.md +25 -0
  57. package/docs/api/functions/FileUpload.md +21 -0
  58. package/docs/api/functions/Form.md +50 -0
  59. package/docs/api/functions/FormField.md +102 -0
  60. package/docs/api/functions/Header.md +21 -0
  61. package/docs/api/functions/InactivityServiceProvider.md +28 -0
  62. package/docs/api/functions/InactivityWarningModal.md +21 -0
  63. package/docs/api/functions/Input.md +49 -0
  64. package/docs/api/functions/NavigationGuard.md +31 -0
  65. package/docs/api/functions/OrganisationServiceProvider.md +28 -0
  66. package/docs/api/functions/PaceAppLayout.md +169 -0
  67. package/docs/api/functions/PasswordChangeForm.md +21 -0
  68. package/docs/api/functions/ProtectedRoute.md +37 -0
  69. package/docs/api/functions/PublicPageFooter.md +21 -0
  70. package/docs/api/functions/PublicPageHeader.md +21 -0
  71. package/docs/api/functions/PublicPageLayout.md +33 -0
  72. package/docs/api/functions/PublicPageProvider.md +30 -0
  73. package/docs/api/functions/Textarea.md +49 -0
  74. package/docs/api/functions/Toaster.md +34 -0
  75. package/docs/api/functions/UnifiedAuthProvider.md +28 -0
  76. package/docs/api/functions/applyPalette.md +33 -0
  77. package/docs/api/functions/archiveFile.md +47 -0
  78. package/docs/api/functions/average.md +63 -0
  79. package/docs/api/functions/buildAppUrl.md +46 -0
  80. package/docs/api/functions/clearInFlightRequests.md +17 -0
  81. package/docs/api/functions/clearPalette.md +18 -0
  82. package/docs/api/functions/clearPublicEventCache.md +18 -0
  83. package/docs/api/functions/clearPublicFileDisplayCache.md +18 -0
  84. package/docs/api/functions/clearPublicLogoCache.md +18 -0
  85. package/docs/api/functions/cn.md +21 -0
  86. package/docs/api/functions/count.md +56 -0
  87. package/docs/api/functions/createAuditManager.md +45 -0
  88. package/docs/api/functions/createBaseClient.md +75 -0
  89. package/docs/api/functions/createLogger.md +95 -0
  90. package/docs/api/functions/createRBACConfig.md +21 -0
  91. package/docs/api/functions/createRBACEngine.md +33 -0
  92. package/docs/api/functions/createRBACExpressMiddleware.md +84 -0
  93. package/docs/api/functions/createRBACMiddleware.md +88 -0
  94. package/docs/api/functions/createSecureClient.md +80 -0
  95. package/docs/api/functions/createSecureDataAccess.md +39 -0
  96. package/docs/api/functions/deleteFile.md +33 -0
  97. package/docs/api/functions/disablePerformanceMonitoring.md +17 -0
  98. package/docs/api/functions/downloadFile.md +33 -0
  99. package/docs/api/functions/emitAuditEvent.md +27 -0
  100. package/docs/api/functions/enablePerformanceMonitoring.md +17 -0
  101. package/docs/api/functions/err.md +23 -0
  102. package/docs/api/functions/exportToCSV.md +56 -0
  103. package/docs/api/functions/exportToCSVWithTableRows.md +46 -0
  104. package/docs/api/functions/extractEventCodeFromPath.md +24 -0
  105. package/docs/api/functions/extractFileMetadata.md +33 -0
  106. package/docs/api/functions/formatCompactNumber.md +27 -0
  107. package/docs/api/functions/formatCurrency.md +31 -0
  108. package/docs/api/functions/formatDate.md +23 -0
  109. package/docs/api/functions/formatDateTime.md +24 -0
  110. package/docs/api/functions/formatFileSize.md +23 -0
  111. package/docs/api/functions/formatInTimeZone.md +46 -0
  112. package/docs/api/functions/formatNumber.md +31 -0
  113. package/docs/api/functions/formatPercent.md +64 -0
  114. package/docs/api/functions/formatTime.md +24 -0
  115. package/docs/api/functions/formatTimeInTimeZone.md +40 -0
  116. package/docs/api/functions/fromSupabaseClient.md +49 -0
  117. package/docs/api/functions/fromZonedTime.md +41 -0
  118. package/docs/api/functions/generateCSVContent.md +55 -0
  119. package/docs/api/functions/generateFilePath.md +29 -0
  120. package/docs/api/functions/generateFileUrlsBatch.md +33 -0
  121. package/docs/api/functions/generatePublicRoutePath.md +27 -0
  122. package/docs/api/functions/generateUniqueFileName.md +24 -0
  123. package/docs/api/functions/getAccessLevel.md +48 -0
  124. package/docs/api/functions/getAllAppPorts.md +19 -0
  125. package/docs/api/functions/getAllStylePaths.md +15 -0
  126. package/docs/api/functions/getAppConfig.md +17 -0
  127. package/docs/api/functions/getAppPort.md +34 -0
  128. package/docs/api/functions/getBucketName.md +27 -0
  129. package/docs/api/functions/getCurrentAppId.md +17 -0
  130. package/docs/api/functions/getCurrentAppName.md +17 -0
  131. package/docs/api/functions/getFileSizeLimit.md +23 -0
  132. package/docs/api/functions/getGlobalAuditManager.md +19 -0
  133. package/docs/api/functions/getInFlightRequestCount.md +19 -0
  134. package/docs/api/functions/getPerformanceMetrics.md +17 -0
  135. package/docs/api/functions/getPerformanceSummary.md +17 -0
  136. package/docs/api/functions/getPermissionMap.md +52 -0
  137. package/docs/api/functions/getPublicEventCacheStats.md +25 -0
  138. package/docs/api/functions/getPublicFileDisplayCacheStats.md +25 -0
  139. package/docs/api/functions/getPublicLogoCacheStats.md +25 -0
  140. package/docs/api/functions/getPublicUrl.md +39 -0
  141. package/docs/api/functions/getRBACConfig.md +15 -0
  142. package/docs/api/functions/getRBACLogger.md +15 -0
  143. package/docs/api/functions/getRoleContext.md +31 -0
  144. package/docs/api/functions/getSignedUrl.md +34 -0
  145. package/docs/api/functions/getStylePath.md +21 -0
  146. package/docs/api/functions/getTimeZoneDifference.md +40 -0
  147. package/docs/api/functions/getTimezoneAbbreviation.md +40 -0
  148. package/docs/api/functions/getUserTimeZone.md +26 -0
  149. package/docs/api/functions/hasAllPermissions.md +41 -0
  150. package/docs/api/functions/hasAnyPermission.md +41 -0
  151. package/docs/api/functions/isDebugMode.md +15 -0
  152. package/docs/api/functions/isDevelopmentMode.md +15 -0
  153. package/docs/api/functions/isErr.md +29 -0
  154. package/docs/api/functions/isOk.md +29 -0
  155. package/docs/api/functions/isPerformanceMonitoringEnabled.md +17 -0
  156. package/docs/api/functions/isPermitted.md +58 -0
  157. package/docs/api/functions/isPermittedCached.md +36 -0
  158. package/docs/api/functions/isRBACInitialized.md +19 -0
  159. package/docs/api/functions/isSecureClient.md +38 -0
  160. package/docs/api/functions/isValidPermission.md +27 -0
  161. package/docs/api/functions/listFiles.md +29 -0
  162. package/docs/api/functions/max.md +63 -0
  163. package/docs/api/functions/min.md +63 -0
  164. package/docs/api/functions/ok.md +29 -0
  165. package/docs/api/functions/parseAndNormalizeEventColours.md +105 -0
  166. package/docs/api/functions/recordAuditEvent.md +23 -0
  167. package/docs/api/functions/recordPermissionCheck.md +31 -0
  168. package/docs/api/functions/resetPerformanceMetrics.md +17 -0
  169. package/docs/api/functions/resolveAppContext.md +27 -0
  170. package/docs/api/functions/roundToNearestMinutes.md +41 -0
  171. package/docs/api/functions/sanitizeFormData.md +49 -0
  172. package/docs/api/functions/sanitizeHtml.md +39 -0
  173. package/docs/api/functions/sanitizeUserInput.md +27 -0
  174. package/docs/api/functions/setAppConfig.md +23 -0
  175. package/docs/api/functions/setGlobalAuditManager.md +25 -0
  176. package/docs/api/functions/setupRBAC.md +31 -0
  177. package/docs/api/functions/sum.md +63 -0
  178. package/docs/api/functions/toZonedTime.md +41 -0
  179. package/docs/api/functions/uploadFile.md +32 -0
  180. package/docs/api/functions/useAccessLevel.md +71 -0
  181. package/docs/api/functions/useAccessibleApps.md +55 -0
  182. package/docs/api/functions/useAppConfig.md +20 -0
  183. package/docs/api/functions/useAuthService.md +15 -0
  184. package/docs/api/functions/useCan.md +99 -0
  185. package/docs/api/functions/useEventService.md +15 -0
  186. package/docs/api/functions/useEventTheme.md +26 -0
  187. package/docs/api/functions/useEvents.md +45 -0
  188. package/docs/api/functions/useFileReference.md +264 -0
  189. package/docs/api/functions/useFileReferenceById.md +63 -0
  190. package/docs/api/functions/useFileReferenceForRecord.md +129 -0
  191. package/docs/api/functions/useFilesByCategory.md +80 -0
  192. package/docs/api/functions/useFormDialog.md +62 -0
  193. package/docs/api/functions/useInactivityService.md +15 -0
  194. package/docs/api/functions/useInactivityTracker.md +21 -0
  195. package/docs/api/functions/useIsPublicPage.md +19 -0
  196. package/docs/api/functions/useMultiplePermissions.md +88 -0
  197. package/docs/api/functions/useOptionalEvents.md +31 -0
  198. package/docs/api/functions/useOrganisationPermissions.md +27 -0
  199. package/docs/api/functions/useOrganisationSecurity.md +15 -0
  200. package/docs/api/functions/useOrganisationService.md +15 -0
  201. package/docs/api/functions/useOrganisations.md +48 -0
  202. package/docs/api/functions/usePermissions.md +130 -0
  203. package/docs/api/functions/usePublicEvent.md +36 -0
  204. package/docs/api/functions/usePublicEventCode.md +32 -0
  205. package/docs/api/functions/usePublicEventLogo.md +48 -0
  206. package/docs/api/functions/usePublicFileDisplay.md +54 -0
  207. package/docs/api/functions/usePublicPageContext.md +19 -0
  208. package/docs/api/functions/usePublicRouteParams.md +31 -0
  209. package/docs/api/functions/useRBAC.md +21 -0
  210. package/docs/api/functions/useResolvedScope.md +46 -0
  211. package/docs/api/functions/useResourcePermissions.md +25 -0
  212. package/docs/api/functions/useRoleManagement.md +121 -0
  213. package/docs/api/functions/useSecureSupabase.md +51 -0
  214. package/docs/api/functions/useSessionRestoration.md +15 -0
  215. package/docs/api/functions/useSessionTracking.md +62 -0
  216. package/docs/api/functions/useToast.md +83 -0
  217. package/docs/api/functions/useUnifiedAuth.md +24 -0
  218. package/docs/api/functions/useZodForm.md +27 -0
  219. package/docs/api/functions/validateFileSize.md +31 -0
  220. package/docs/api/functions/warnIfInsecureClient.md +40 -0
  221. package/docs/api/functions/withAccessLevelGuard.md +67 -0
  222. package/docs/api/functions/withPermissionGuard.md +73 -0
  223. package/docs/api/functions/withRoleGuard.md +86 -0
  224. package/docs/api/globals.md +502 -0
  225. package/docs/api/interfaces/AccessDeniedProps.md +87 -0
  226. package/docs/api/interfaces/AccessibleApp.md +41 -0
  227. package/docs/api/interfaces/AddressFieldProps.md +195 -0
  228. package/docs/api/interfaces/AddressFieldRef.md +67 -0
  229. package/docs/api/interfaces/AggregateConfig.md +35 -0
  230. package/docs/api/interfaces/AppSwitcherProps.md +51 -0
  231. package/docs/api/interfaces/AuthSessionData.md +27 -0
  232. package/docs/api/interfaces/AutocompleteOptions.md +61 -0
  233. package/docs/api/interfaces/AvatarProps.md +97 -0
  234. package/docs/api/interfaces/BadgeProps.md +30 -0
  235. package/docs/api/interfaces/BuildAppUrlOptions.md +41 -0
  236. package/docs/api/interfaces/ButtonProps.md +46 -0
  237. package/docs/api/interfaces/CalendarProps.md +60 -0
  238. package/docs/api/interfaces/CardProps.md +56 -0
  239. package/docs/api/interfaces/ColorPalette.md +13 -0
  240. package/docs/api/interfaces/ColorShade.md +58 -0
  241. package/docs/api/interfaces/ContextSelectorProps.md +131 -0
  242. package/docs/api/interfaces/DataRecord.md +16 -0
  243. package/docs/api/interfaces/DataTableAction.md +198 -0
  244. package/docs/api/interfaces/DataTableColumn.md +422 -0
  245. package/docs/api/interfaces/DataTableProps.md +511 -0
  246. package/docs/api/interfaces/DataTableToolbarButton.md +75 -0
  247. package/docs/api/interfaces/DatePickerWithTimezoneProps.md +75 -0
  248. package/docs/api/interfaces/DialogBodyProps.md +55 -0
  249. package/docs/api/interfaces/DialogCloseProps.md +25 -0
  250. package/docs/api/interfaces/DialogContentProps.md +160 -0
  251. package/docs/api/interfaces/DialogFooterProps.md +25 -0
  252. package/docs/api/interfaces/DialogHeaderProps.md +25 -0
  253. package/docs/api/interfaces/DialogPortalProps.md +19 -0
  254. package/docs/api/interfaces/DialogProps.md +53 -0
  255. package/docs/api/interfaces/DialogTriggerProps.md +53 -0
  256. package/docs/api/interfaces/EmptyStateConfig.md +55 -0
  257. package/docs/api/interfaces/ErrorBoundaryProps.md +131 -0
  258. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +31 -0
  259. package/docs/api/interfaces/ErrorBoundaryState.md +61 -0
  260. package/docs/api/interfaces/EventAppRoleData.md +54 -0
  261. package/docs/api/interfaces/ExportColumn.md +69 -0
  262. package/docs/api/interfaces/ExportOptions.md +109 -0
  263. package/docs/api/interfaces/FileDisplayProps.md +192 -0
  264. package/docs/api/interfaces/FileMetadata.md +97 -0
  265. package/docs/api/interfaces/FileReference.md +89 -0
  266. package/docs/api/interfaces/FileSizeLimits.md +13 -0
  267. package/docs/api/interfaces/FileUploadOptions.md +107 -0
  268. package/docs/api/interfaces/FooterProps.md +37 -0
  269. package/docs/api/interfaces/FormFieldProps.md +171 -0
  270. package/docs/api/interfaces/FormProps.md +93 -0
  271. package/docs/api/interfaces/GrantEventAppRoleParams.md +97 -0
  272. package/docs/api/interfaces/ImportSummary.md +49 -0
  273. package/docs/api/interfaces/InactivityWarningModalProps.md +87 -0
  274. package/docs/api/interfaces/InputProps.md +46 -0
  275. package/docs/api/interfaces/InvalidScopeError.md +37 -0
  276. package/docs/api/interfaces/LabelProps.md +85 -0
  277. package/docs/api/interfaces/LoggerConfig.md +51 -0
  278. package/docs/api/interfaces/LoginFormProps.md +146 -0
  279. package/docs/api/interfaces/MissingUserContextError.md +37 -0
  280. package/docs/api/interfaces/NavigationGuardProps.md +109 -0
  281. package/docs/api/interfaces/NavigationItem.md +91 -0
  282. package/docs/api/interfaces/NavigationMenuProps.md +169 -0
  283. package/docs/api/interfaces/Organisation.md +105 -0
  284. package/docs/api/interfaces/OrganisationContextRequiredError.md +37 -0
  285. package/docs/api/interfaces/OrganisationMembership.md +105 -0
  286. package/docs/api/interfaces/OrganisationSecurityError.md +49 -0
  287. package/docs/api/interfaces/PaceAppLayoutPermissionConfig.md +127 -0
  288. package/docs/api/interfaces/PaceAppLayoutRouteConfigItem.md +91 -0
  289. package/docs/api/interfaces/PaceAppLayoutRoutingConfig.md +79 -0
  290. package/docs/api/interfaces/PaceLoginPageProps.md +41 -0
  291. package/docs/api/interfaces/PagePermissionGuardProps.md +143 -0
  292. package/docs/api/interfaces/PaletteData.md +33 -0
  293. package/docs/api/interfaces/ParsedAddress.md +91 -0
  294. package/docs/api/interfaces/PermissionDeniedError.md +37 -0
  295. package/docs/api/interfaces/ProgressProps.md +35 -0
  296. package/docs/api/interfaces/ProtectedRouteProps.md +67 -0
  297. package/docs/api/interfaces/PublicPageFooterProps.md +97 -0
  298. package/docs/api/interfaces/PublicPageHeaderProps.md +99 -0
  299. package/docs/api/interfaces/PublicPageLayoutProps.md +153 -0
  300. package/docs/api/interfaces/RBACAccessValidateParams.md +41 -0
  301. package/docs/api/interfaces/RBACAccessValidateResult.md +33 -0
  302. package/docs/api/interfaces/RBACAuditLogParams.md +65 -0
  303. package/docs/api/interfaces/RBACAuditLogResult.md +41 -0
  304. package/docs/api/interfaces/RBACContext.md +41 -0
  305. package/docs/api/interfaces/RBACError.md +37 -0
  306. package/docs/api/interfaces/RBACLogger.md +97 -0
  307. package/docs/api/interfaces/RBACNotInitializedError.md +37 -0
  308. package/docs/api/interfaces/RBACPageAccessCheckParams.md +57 -0
  309. package/docs/api/interfaces/RBACPerformanceMetrics.md +109 -0
  310. package/docs/api/interfaces/RBACPermissionCheckParams.md +57 -0
  311. package/docs/api/interfaces/RBACPermissionCheckResult.md +41 -0
  312. package/docs/api/interfaces/RBACPermissionsGetParams.md +49 -0
  313. package/docs/api/interfaces/RBACPermissionsGetResult.md +49 -0
  314. package/docs/api/interfaces/RBACResult.md +47 -0
  315. package/docs/api/interfaces/RBACRoleGrantParams.md +49 -0
  316. package/docs/api/interfaces/RBACRoleGrantResult.md +41 -0
  317. package/docs/api/interfaces/RBACRoleRevokeParams.md +49 -0
  318. package/docs/api/interfaces/RBACRoleRevokeResult.md +41 -0
  319. package/docs/api/interfaces/RBACRoleValidateParams.md +41 -0
  320. package/docs/api/interfaces/RBACRoleValidateResult.md +49 -0
  321. package/docs/api/interfaces/RBACRolesListParams.md +41 -0
  322. package/docs/api/interfaces/RBACRolesListResult.md +57 -0
  323. package/docs/api/interfaces/RBACSessionTrackParams.md +57 -0
  324. package/docs/api/interfaces/RBACSessionTrackResult.md +41 -0
  325. package/docs/api/interfaces/ResourcePermissions.md +119 -0
  326. package/docs/api/interfaces/RevokeEventAppRoleParams.md +81 -0
  327. package/docs/api/interfaces/RoleManagementResult.md +41 -0
  328. package/docs/api/interfaces/SessionRestorationLoaderProps.md +29 -0
  329. package/docs/api/interfaces/StorageConfig.md +33 -0
  330. package/docs/api/interfaces/StorageFileInfo.md +57 -0
  331. package/docs/api/interfaces/StorageFileMetadata.md +113 -0
  332. package/docs/api/interfaces/StorageListOptions.md +79 -0
  333. package/docs/api/interfaces/StorageListResult.md +33 -0
  334. package/docs/api/interfaces/StorageUploadOptions.md +81 -0
  335. package/docs/api/interfaces/StorageUploadResult.md +49 -0
  336. package/docs/api/interfaces/StorageUploadSuccess.md +35 -0
  337. package/docs/api/interfaces/StorageUrlOptions.md +49 -0
  338. package/docs/api/interfaces/StyleImport.md +17 -0
  339. package/docs/api/interfaces/SwitchProps.md +30 -0
  340. package/docs/api/interfaces/TabsContentProps.md +13 -0
  341. package/docs/api/interfaces/TabsListProps.md +13 -0
  342. package/docs/api/interfaces/TabsProps.md +13 -0
  343. package/docs/api/interfaces/TabsTriggerProps.md +41 -0
  344. package/docs/api/interfaces/TextareaProps.md +43 -0
  345. package/docs/api/interfaces/ToastActionElement.md +16 -0
  346. package/docs/api/interfaces/ToastProps.md +13 -0
  347. package/docs/api/interfaces/UnifiedAuthProviderProps.md +129 -0
  348. package/docs/api/interfaces/UseAccessibleAppsReturn.md +55 -0
  349. package/docs/api/interfaces/UseFormDialogOptions.md +49 -0
  350. package/docs/api/interfaces/UseFormDialogReturn.md +95 -0
  351. package/docs/api/interfaces/UseInactivityTrackerOptions.md +103 -0
  352. package/docs/api/interfaces/UseInactivityTrackerReturn.md +91 -0
  353. package/docs/api/interfaces/UsePublicEventLogoOptions.md +69 -0
  354. package/docs/api/interfaces/UsePublicEventLogoReturn.md +66 -0
  355. package/docs/api/interfaces/UsePublicEventOptions.md +29 -0
  356. package/docs/api/interfaces/UsePublicEventReturn.md +56 -0
  357. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +39 -0
  358. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +96 -0
  359. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +76 -0
  360. package/docs/api/interfaces/UseResolvedScopeOptions.md +49 -0
  361. package/docs/api/interfaces/UseResolvedScopeReturn.md +39 -0
  362. package/docs/api/interfaces/UseResourcePermissionsOptions.md +29 -0
  363. package/docs/api/interfaces/UserEventAccess.md +92 -0
  364. package/docs/api/interfaces/UserMenuProps.md +69 -0
  365. package/docs/api/interfaces/UserProfile.md +49 -0
  366. package/docs/api/type-aliases/AccessLevel.md +11 -0
  367. package/docs/api/type-aliases/AccessLevelContext.md +14 -0
  368. package/docs/api/type-aliases/AllPermissions.md +11 -0
  369. package/docs/api/type-aliases/ApiError.md +37 -0
  370. package/docs/api/type-aliases/ApiResult.md +19 -0
  371. package/docs/api/type-aliases/AuditEventType.md +11 -0
  372. package/docs/api/type-aliases/BadgeVariant.md +18 -0
  373. package/docs/api/type-aliases/DataTableFeatureConfig.md +14 -0
  374. package/docs/api/type-aliases/DialogSize.md +13 -0
  375. package/docs/api/type-aliases/EventAppRole.md +11 -0
  376. package/docs/api/type-aliases/FileUploadProps.md +15 -0
  377. package/docs/api/type-aliases/GetRowId.md +33 -0
  378. package/docs/api/type-aliases/GlobalErrorHandler.md +35 -0
  379. package/docs/api/type-aliases/GlobalRole.md +11 -0
  380. package/docs/api/type-aliases/ImportHandlerResult.md +13 -0
  381. package/docs/api/type-aliases/NavigationMode.md +13 -0
  382. package/docs/api/type-aliases/Operation.md +11 -0
  383. package/docs/api/type-aliases/OrganisationContextType.md +13 -0
  384. package/docs/api/type-aliases/OrganisationRole.md +11 -0
  385. package/docs/api/type-aliases/PaceAppLayoutProps.md +14 -0
  386. package/docs/api/type-aliases/Permission.md +11 -0
  387. package/docs/api/type-aliases/PermissionCheck.md +46 -0
  388. package/docs/api/type-aliases/PermissionMap.md +11 -0
  389. package/docs/api/type-aliases/PermissionSource.md +13 -0
  390. package/docs/api/type-aliases/RBACConfig.md +13 -0
  391. package/docs/api/type-aliases/RBACFunctionResponse.md +57 -0
  392. package/docs/api/type-aliases/Scope.md +41 -0
  393. package/docs/api/type-aliases/SessionType.md +11 -0
  394. package/docs/api/type-aliases/UUID.md +11 -0
  395. package/docs/api/type-aliases/UnifiedAuthContextType.md +13 -0
  396. package/docs/api/type-aliases/UseFileReferenceForRecordReturn.md +161 -0
  397. package/docs/api/type-aliases/UseFileReferenceOptions.md +35 -0
  398. package/docs/api/type-aliases/UseFileReferenceReturn.md +13 -0
  399. package/docs/api/variables/ALL_PERMISSIONS.md +281 -0
  400. package/docs/api/variables/APP_PATH_MAPPING.md +14 -0
  401. package/docs/api/variables/AddressField.md +41 -0
  402. package/docs/api/variables/Alert.md +11 -0
  403. package/docs/api/variables/AlertDescription.md +11 -0
  404. package/docs/api/variables/AlertTitle.md +11 -0
  405. package/docs/api/variables/Avatar.md +13 -0
  406. package/docs/api/variables/Button.md +31 -0
  407. package/docs/api/variables/CACHE_PATTERNS.md +89 -0
  408. package/docs/api/variables/Calendar.md +74 -0
  409. package/docs/api/variables/Card.md +11 -0
  410. package/docs/api/variables/CardActions.md +11 -0
  411. package/docs/api/variables/CardContent.md +11 -0
  412. package/docs/api/variables/CardDescription.md +11 -0
  413. package/docs/api/variables/CardFooter.md +11 -0
  414. package/docs/api/variables/CardHeader.md +11 -0
  415. package/docs/api/variables/CardTitle.md +11 -0
  416. package/docs/api/variables/Checkbox.md +11 -0
  417. package/docs/api/variables/DEFAULT_APP_PORT_MAP.md +14 -0
  418. package/docs/api/variables/DEFAULT_FILE_SIZE_LIMIT.md +13 -0
  419. package/docs/api/variables/Dialog.md +14 -0
  420. package/docs/api/variables/DialogClose.md +14 -0
  421. package/docs/api/variables/DialogContent.md +28 -0
  422. package/docs/api/variables/DialogDescription.md +14 -0
  423. package/docs/api/variables/DialogPortal.md +14 -0
  424. package/docs/api/variables/DialogTitle.md +14 -0
  425. package/docs/api/variables/DialogTrigger.md +14 -0
  426. package/docs/api/variables/EVENT_APP_PERMISSIONS.md +109 -0
  427. package/docs/api/variables/ErrorBoundary.md +15 -0
  428. package/docs/api/variables/FILE_SIZE_LIMITS.md +13 -0
  429. package/docs/api/variables/Footer.md +11 -0
  430. package/docs/api/variables/GLOBAL_PERMISSIONS.md +29 -0
  431. package/docs/api/variables/Label.md +34 -0
  432. package/docs/api/variables/LoadingSpinner.md +28 -0
  433. package/docs/api/variables/LoginForm.md +34 -0
  434. package/docs/api/variables/NavigationMenu.md +203 -0
  435. package/docs/api/variables/ORGANISATION_PERMISSIONS.md +89 -0
  436. package/docs/api/variables/PAGE_PERMISSIONS.md +93 -0
  437. package/docs/api/variables/PaceLoginPage.md +40 -0
  438. package/docs/api/variables/PagePermissionGuard.md +11 -0
  439. package/docs/api/variables/Progress.md +32 -0
  440. package/docs/api/variables/SECURE_CLIENT_SYMBOL.md +14 -0
  441. package/docs/api/variables/STORAGE_CONFIG.md +13 -0
  442. package/docs/api/variables/Select.md +26 -0
  443. package/docs/api/variables/SelectContent.md +26 -0
  444. package/docs/api/variables/SelectGroup.md +26 -0
  445. package/docs/api/variables/SelectItem.md +26 -0
  446. package/docs/api/variables/SelectLabel.md +26 -0
  447. package/docs/api/variables/SelectSeparator.md +26 -0
  448. package/docs/api/variables/SelectTrigger.md +26 -0
  449. package/docs/api/variables/SelectValue.md +26 -0
  450. package/docs/api/variables/SessionRestorationLoader.md +11 -0
  451. package/docs/api/variables/Switch.md +23 -0
  452. package/docs/api/variables/Table.md +35 -0
  453. package/docs/api/variables/TableBody.md +11 -0
  454. package/docs/api/variables/TableCaption.md +11 -0
  455. package/docs/api/variables/TableCell.md +11 -0
  456. package/docs/api/variables/TableFooter.md +11 -0
  457. package/docs/api/variables/TableHead.md +11 -0
  458. package/docs/api/variables/TableHeader.md +11 -0
  459. package/docs/api/variables/TableRow.md +11 -0
  460. package/docs/api/variables/Tabs.md +25 -0
  461. package/docs/api/variables/TabsContent.md +24 -0
  462. package/docs/api/variables/TabsList.md +25 -0
  463. package/docs/api/variables/TabsTrigger.md +34 -0
  464. package/docs/api/variables/Toast.md +36 -0
  465. package/docs/api/variables/ToastAction.md +32 -0
  466. package/docs/api/variables/ToastClose.md +32 -0
  467. package/docs/api/variables/ToastDescription.md +32 -0
  468. package/docs/api/variables/ToastProvider.md +11 -0
  469. package/docs/api/variables/ToastTitle.md +32 -0
  470. package/docs/api/variables/ToastViewport.md +26 -0
  471. package/docs/api/variables/Tooltip.md +34 -0
  472. package/docs/api/variables/TooltipContent.md +34 -0
  473. package/docs/api/variables/TooltipProvider.md +11 -0
  474. package/docs/api/variables/TooltipRoot.md +11 -0
  475. package/docs/api/variables/TooltipTrigger.md +11 -0
  476. package/docs/api/variables/UserMenu.md +11 -0
  477. package/docs/api/variables/emailSchema.md +13 -0
  478. package/docs/api/variables/logger.md +203 -0
  479. package/docs/api/variables/nameSchema.md +13 -0
  480. package/docs/api/variables/passwordSchema.md +13 -0
  481. package/docs/api/variables/phoneSchema.md +13 -0
  482. package/docs/api/variables/rbacCache.md +16 -0
  483. package/docs/api/variables/styleConfig.md +25 -0
  484. package/docs/api/variables/urlSchema.md +13 -0
  485. package/docs/api-reference/hooks.md +2 -0
  486. package/docs/implementation-guides/data-tables.md +8 -0
  487. package/docs/rbac/getting-started.md +7 -0
  488. package/docs/rbac/troubleshooting.md +5 -1
  489. package/package.json +3 -3
  490. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +29 -19
  491. package/src/components/DataTable/hooks/useDataTableScope.test.ts +5 -13
  492. package/src/components/DataTable/hooks/useDataTableScope.ts +16 -14
  493. package/src/components/Dialog/useDialogLifecycle.test.ts +4 -1
  494. package/src/components/FileDisplay/useFileDisplay.unit.test.ts +12 -8
  495. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +33 -9
  496. package/src/components/PaceAppLayout/useFilteredNavItems.ts +22 -7
  497. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +44 -23
  498. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +1 -1
  499. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +6 -4
  500. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +2 -2
  501. package/src/hooks/useAppConfig.unit.test.ts +74 -66
  502. package/src/hooks/useComponentPerformance.unit.test.tsx +6 -4
  503. package/src/hooks/useFileUrl.unit.test.ts +1 -3
  504. package/src/hooks/useInactivityTracker.unit.test.ts +6 -2
  505. package/src/hooks/usePerformanceMonitor.unit.test.ts +6 -16
  506. package/src/hooks/usePublicEvent.simple.test.ts +32 -47
  507. package/src/hooks/usePublicEvent.test.ts +9 -15
  508. package/src/providers/services/AuthServiceProvider.test.tsx +10 -5
  509. package/src/providers/services/EventServiceProvider.test.tsx +8 -3
  510. package/src/providers/services/InactivityServiceProvider.test.tsx +8 -3
  511. package/src/providers/services/OrganisationServiceProvider.test.tsx +8 -3
  512. package/src/rbac/README.md +7 -5
  513. package/src/rbac/api.test.ts +113 -56
  514. package/src/rbac/api.ts +80 -10
  515. package/src/rbac/components/NavigationGuard.tsx +2 -1
  516. package/src/rbac/components/PagePermissionGuard.test.tsx +23 -10
  517. package/src/rbac/engine.ts +23 -1
  518. package/src/rbac/hooks/permissions/runPermissionCheck.ts +18 -4
  519. package/src/rbac/hooks/permissions/useCan.test.ts +59 -20
  520. package/src/rbac/hooks/permissions/useCan.ts +7 -3
  521. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +18 -9
  522. package/src/rbac/hooks/useCan.test.ts +2 -3
  523. package/src/rbac/hooks/usePageGuardScope.ts +6 -4
  524. package/src/rbac/hooks/usePagePermissionCheck.ts +4 -4
  525. package/src/rbac/hooks/useResolvedScope.ts +16 -10
  526. package/src/rbac/hooks/useResourcePermissions.test.ts +48 -58
  527. package/src/rbac/hooks/useResourcePermissions.ts +11 -20
  528. package/src/rbac/types.ts +3 -0
  529. package/src/services/AuthService.edge-cases.test.ts +2 -2
  530. package/src/services/EventService.ts +9 -4
  531. package/src/utils/file-reference/file-reference.test.ts +25 -14
  532. package/src/utils/supabase/createBaseClient.test.ts +30 -13
  533. package/docs/api/modules.md +0 -10028
@@ -365,7 +365,7 @@ describe('useResourcePermissions Hook', () => {
365
365
  );
366
366
  });
367
367
 
368
- it('uses fallback scope when resolvedScope is null', () => {
368
+ it('passes null scope to useCan when resolvedScope is null', () => {
369
369
  mockUseResolvedScope.mockReturnValue({
370
370
  resolvedScope: null,
371
371
  isLoading: false,
@@ -374,15 +374,9 @@ describe('useResourcePermissions Hook', () => {
374
374
 
375
375
  renderHook(() => useResourcePermissions('contacts'));
376
376
 
377
- const fallbackScope: Scope = {
378
- organisationId: 'org-123',
379
- eventId: 'event-123',
380
- appId: undefined,
381
- };
382
-
383
377
  expect(mockUseCan).toHaveBeenCalledWith(
384
378
  expect.any(String),
385
- fallbackScope,
379
+ null,
386
380
  expect.any(String),
387
381
  undefined,
388
382
  true,
@@ -391,7 +385,7 @@ describe('useResourcePermissions Hook', () => {
391
385
  );
392
386
  });
393
387
 
394
- it('handles missing organisation gracefully', () => {
388
+ it('handles missing organisation by passing null scope when resolvedScope is null', () => {
395
389
  mockUseOrganisations.mockReturnValue({
396
390
  selectedOrganisation: null,
397
391
  } as any);
@@ -404,15 +398,9 @@ describe('useResourcePermissions Hook', () => {
404
398
 
405
399
  renderHook(() => useResourcePermissions('contacts'));
406
400
 
407
- const fallbackScope: Scope = {
408
- organisationId: '',
409
- eventId: 'event-123',
410
- appId: undefined,
411
- };
412
-
413
401
  expect(mockUseCan).toHaveBeenCalledWith(
414
402
  expect.any(String),
415
- fallbackScope,
403
+ null,
416
404
  expect.any(String),
417
405
  undefined,
418
406
  true,
@@ -421,7 +409,7 @@ describe('useResourcePermissions Hook', () => {
421
409
  );
422
410
  });
423
411
 
424
- it('handles missing event gracefully', () => {
412
+ it('handles missing event by passing null scope when resolvedScope is null', () => {
425
413
  mockUseEvents.mockReturnValue({
426
414
  selectedEvent: null,
427
415
  } as any);
@@ -434,15 +422,38 @@ describe('useResourcePermissions Hook', () => {
434
422
 
435
423
  renderHook(() => useResourcePermissions('contacts'));
436
424
 
437
- const fallbackScope: Scope = {
425
+ expect(mockUseCan).toHaveBeenCalledWith(
426
+ expect.any(String),
427
+ null,
428
+ expect.any(String),
429
+ undefined,
430
+ true,
431
+ null,
432
+ undefined
433
+ );
434
+ });
435
+
436
+ it('handles missing event gracefully when resolvedScope is set', () => {
437
+ mockUseEvents.mockReturnValue({
438
+ selectedEvent: null,
439
+ } as any);
440
+
441
+ const scopeWithOrgOnly: Scope = {
438
442
  organisationId: 'org-123',
439
443
  eventId: undefined,
440
444
  appId: undefined,
441
445
  };
446
+ mockUseResolvedScope.mockReturnValue({
447
+ resolvedScope: scopeWithOrgOnly,
448
+ isLoading: false,
449
+ error: null,
450
+ });
451
+
452
+ renderHook(() => useResourcePermissions('contacts'));
442
453
 
443
454
  expect(mockUseCan).toHaveBeenCalledWith(
444
455
  expect.any(String),
445
- fallbackScope,
456
+ scopeWithOrgOnly,
446
457
  expect.any(String),
447
458
  undefined,
448
459
  true,
@@ -877,19 +888,12 @@ describe('useResourcePermissions Hook', () => {
877
888
 
878
889
  renderHook(() => useResourcePermissions('planning'));
879
890
 
880
- // During scope loading, should use resource-based permissions (no page. prefix)
881
- // because resolvedScope is null, so hasAppId is false
882
- const fallbackScope: Scope = {
883
- organisationId: 'org-123',
884
- eventId: 'event-123',
885
- appId: undefined,
886
- };
887
-
891
+ // When resolvedScope is null we pass null to useCan (no fallback)
888
892
  expect(mockUseCan).toHaveBeenCalledWith(
889
893
  'user-123',
890
- fallbackScope,
891
- 'create:planning', // Resource-based permission (no page. prefix) during loading
892
- undefined, // No pageId when appId is not available
894
+ null,
895
+ 'create:planning',
896
+ undefined,
893
897
  true,
894
898
  null,
895
899
  undefined
@@ -1348,17 +1352,11 @@ describe('useResourcePermissions Hook', () => {
1348
1352
 
1349
1353
  it('handles scope transition from resolved to null', async () => {
1350
1354
  mockIsSuperAdmin.mockResolvedValue(false);
1351
- mockUseResolvedScope
1352
- .mockReturnValueOnce({
1353
- resolvedScope: mockScope,
1354
- isLoading: false,
1355
- error: null,
1356
- })
1357
- .mockReturnValueOnce({
1358
- resolvedScope: null,
1359
- isLoading: false,
1360
- error: null,
1361
- });
1355
+ mockUseResolvedScope.mockReturnValue({
1356
+ resolvedScope: mockScope,
1357
+ isLoading: false,
1358
+ error: null,
1359
+ });
1362
1360
  mockUseCan.mockReturnValue({
1363
1361
  can: false,
1364
1362
  isLoading: false,
@@ -1370,27 +1368,19 @@ describe('useResourcePermissions Hook', () => {
1370
1368
 
1371
1369
  await waitFor(() => {
1372
1370
  expect(result.current.isLoading).toBe(false);
1373
- // Check scope properties individually to avoid issues with object reference comparison
1374
- expect(result.current.scope.organisationId).toBe(mockScope.organisationId);
1375
- expect(result.current.scope.eventId).toBe(mockScope.eventId);
1376
- // appId may be undefined in fallback scope, so only check if it exists in mockScope
1377
- // The hook may use fallback scope even when resolvedScope is provided, so be flexible
1378
- });
1371
+ expect(result.current.scope).toEqual(mockScope);
1372
+ }, { timeout: 3000 });
1379
1373
 
1380
- // Scope becomes null
1374
+ // Switch to null scope
1375
+ mockUseResolvedScope.mockReturnValue({
1376
+ resolvedScope: null,
1377
+ isLoading: false,
1378
+ error: null,
1379
+ });
1381
1380
  rerender();
1382
1381
 
1383
1382
  await waitFor(() => {
1384
- // Should handle null scope gracefully
1385
- // Scope falls back to selectedOrganisation/selectedEvent when resolvedScope is null
1386
- expect(result.current).toBeDefined();
1387
- expect(result.current.scope).toBeDefined();
1388
- // Scope should have organisationId from selectedOrganisation fallback
1389
- // The fallback scope has different structure (appId: undefined vs 'app-123'), so just check orgId and eventId
1390
- expect(result.current.scope.organisationId).toBe('org-123');
1391
- expect(result.current.scope.eventId).toBe('event-123');
1392
- // appId may be undefined in fallback scope, but the hook might still have the previous appId
1393
- // So just verify the scope is defined and has the expected orgId and eventId
1383
+ expect(result.current.scope).toBeNull();
1394
1384
  }, { timeout: 3000 });
1395
1385
  });
1396
1386
 
@@ -66,8 +66,8 @@ export interface ResourcePermissions {
66
66
  canDelete: (resource: string) => boolean;
67
67
  /** Check if user can read resources of this type */
68
68
  canRead: (resource: string) => boolean;
69
- /** The resolved scope object (for advanced use cases) */
70
- scope: Scope;
69
+ /** The resolved scope object (for advanced use cases); null when not yet resolved. */
70
+ scope: Scope | null;
71
71
  /** Whether any permission check is currently loading */
72
72
  isLoading: boolean;
73
73
  /** Error from any permission check or scope resolution */
@@ -147,7 +147,7 @@ function buildResourcePermissions(params: {
147
147
  canUpdateResult: boolean;
148
148
  canDeleteResult: boolean;
149
149
  canReadResult: boolean;
150
- scope: Scope;
150
+ scope: Scope | null;
151
151
  isLoading: boolean;
152
152
  error: Error | null;
153
153
  }): ResourcePermissions {
@@ -203,17 +203,8 @@ export function useResourcePermissions(
203
203
  selectedEventOrganisationId: selectedEvent?.organisation_id || null
204
204
  });
205
205
 
206
- // CRITICAL FIX: Only use resolvedScope when it's available (not during loading)
207
- // This ensures we wait for appId to be resolved before constructing permission strings
208
- // If resolvedScope is null (still loading), we can't determine if we should use page permissions
209
- // so we must wait for scope resolution to complete
210
- const scope: Scope = useMemo(() => {
211
- return resolvedScope || {
212
- organisationId: selectedOrganisation?.id || '',
213
- eventId: selectedEvent?.event_id || undefined,
214
- appId: undefined
215
- };
216
- }, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id]);
206
+ // Pass only resolvedScope to useCan — null when not ready; no fallback (avoids invalid_input).
207
+ const scopeForPermissionCheck: Scope | null = resolvedScope;
217
208
 
218
209
  // CRITICAL FIX: Only use page permissions when appId is actually available in resolvedScope
219
210
  // If scope is still loading (resolvedScope is null), we can't know if appId will be available
@@ -240,7 +231,7 @@ export function useResourcePermissions(
240
231
  // But we must ensure permission strings are correct before calling useCan
241
232
  const { can: canCreateResult, isLoading: createLoading, error: createError } = useCan(
242
233
  user?.id || '',
243
- scope,
234
+ scopeForPermissionCheck,
244
235
  createPermission as Permission,
245
236
  pageId, // Pass resource name as pageId when appId is available to enable page permission checks
246
237
  true, // useCache
@@ -250,7 +241,7 @@ export function useResourcePermissions(
250
241
 
251
242
  const { can: canUpdateResult, isLoading: updateLoading, error: updateError } = useCan(
252
243
  user?.id || '',
253
- scope,
244
+ scopeForPermissionCheck,
254
245
  updatePermission as Permission,
255
246
  pageId, // Pass resource name as pageId when appId is available to enable page permission checks
256
247
  true, // useCache
@@ -260,7 +251,7 @@ export function useResourcePermissions(
260
251
 
261
252
  const { can: canDeleteResult, isLoading: deleteLoading, error: deleteError } = useCan(
262
253
  user?.id || '',
263
- scope,
254
+ scopeForPermissionCheck,
264
255
  deletePermission as Permission,
265
256
  pageId, // Pass resource name as pageId when appId is available to enable page permission checks
266
257
  true, // useCache
@@ -271,7 +262,7 @@ export function useResourcePermissions(
271
262
  // Optional read permission check
272
263
  const { can: canReadResult, isLoading: readLoading, error: readError } = useCan(
273
264
  user?.id || '',
274
- scope,
265
+ scopeForPermissionCheck,
275
266
  readPermission as Permission,
276
267
  pageId, // Pass resource name as pageId when appId is available to enable page permission checks
277
268
  true, // useCache
@@ -313,7 +304,7 @@ export function useResourcePermissions(
313
304
  canUpdateResult,
314
305
  canDeleteResult,
315
306
  canReadResult,
316
- scope,
307
+ scope: scopeForPermissionCheck,
317
308
  isLoading,
318
309
  error,
319
310
  }),
@@ -326,7 +317,7 @@ export function useResourcePermissions(
326
317
  canUpdateResult,
327
318
  canDeleteResult,
328
319
  canReadResult,
329
- scope,
320
+ scopeForPermissionCheck,
330
321
  isLoading,
331
322
  error,
332
323
  ]
package/src/rbac/types.ts CHANGED
@@ -31,6 +31,9 @@ export type AccessLevel =
31
31
  /**
32
32
  * Scope defines the context for permission checks.
33
33
  * Can include organisation, event, and/or app identifiers.
34
+ *
35
+ * Convention: For permission-check APIs (e.g. useCan, useMultiplePermissions), pass Scope | null.
36
+ * null means scope not yet resolved — the hook stays in loading and does not call the RPC.
34
37
  */
35
38
  export type Scope = {
36
39
  organisationId?: UUID;
@@ -579,7 +579,7 @@ describe('AuthService Edge Cases and Complex Scenarios', () => {
579
579
  expect(authService.isAuthenticated()).toBe(false);
580
580
  });
581
581
 
582
- it('handles sign out during session restoration', async () => {
582
+ it('handles sign out during session restoration', { timeout: 15000 }, async () => {
583
583
  vi.useFakeTimers();
584
584
 
585
585
  mockSupabase.auth.getSession.mockImplementation(() => {
@@ -606,7 +606,7 @@ describe('AuthService Edge Cases and Complex Scenarios', () => {
606
606
  expect(authService.isAuthenticated()).toBe(false);
607
607
 
608
608
  vi.useRealTimers();
609
- }, { timeout: 15000 });
609
+ });
610
610
 
611
611
  it('handles refreshSession with invalid session data', async () => {
612
612
  mockSupabase.auth.refreshSession.mockResolvedValue({
@@ -228,10 +228,15 @@ export class EventService extends BaseService implements IEventService {
228
228
  // Event methods
229
229
  setSelectedEvent(event: Event | null): void {
230
230
  if (event) {
231
- // No validation needed: For event-required apps, org is derived from event
232
- // For org-required apps, event is optional and doesn't need validation
233
- // RLS policies handle security at the database level
234
- this.selectedEvent = event;
231
+ // Ensure organisation_id is set when we have selectedOrganisation, so scope resolution
232
+ // (useResolvedScope / useDataTableScope) gets org early and permission checks succeed.
233
+ const orgId = (event as { organisation_id?: string | null }).organisation_id;
234
+ const missingOrg = !orgId || (typeof orgId === 'string' && orgId.trim() === '');
235
+ const eventToStore: Event =
236
+ missingOrg && this.selectedOrganisation?.id
237
+ ? ({ ...event, organisation_id: this.selectedOrganisation.id } as Event)
238
+ : event;
239
+ this.selectedEvent = eventToStore;
235
240
  this.setSelectedEventId?.(event.event_id);
236
241
  // Persist asynchronously (don't await to avoid blocking)
237
242
  this.persistEventSelection(event.event_id).catch(error => {
@@ -675,15 +675,20 @@ describe('[service] FileReferenceServiceImpl', () => {
675
675
  tags: ['updated']
676
676
  }
677
677
  };
678
-
679
- // Simulate update chain resolving via shared query builder
680
- (mockSupabase.from() as any).single.mockResolvedValue({
681
- data: { ...mockFileReference, ...updates },
682
- error: null
683
- });
684
-
678
+
679
+ const updateChain = {
680
+ update: vi.fn().mockReturnThis(),
681
+ eq: vi.fn().mockReturnThis(),
682
+ select: vi.fn().mockReturnThis(),
683
+ single: vi.fn().mockResolvedValue({
684
+ data: { ...mockFileReference, ...updates },
685
+ error: null
686
+ })
687
+ };
688
+ (mockSupabase.from as any).mockReturnValue(updateChain);
689
+
685
690
  const result = await service.updateFileReference('file-ref-123', updates);
686
-
691
+
687
692
  expect(expectOk(result)).toEqual(expect.objectContaining(updates));
688
693
  });
689
694
 
@@ -1036,12 +1041,18 @@ describe('[service] FileReferenceServiceImpl', () => {
1036
1041
 
1037
1042
  it('handles updateFileReference errors', async () => {
1038
1043
  const updates = { file_metadata: { tags: ['updated'] } };
1039
-
1040
- (mockSupabase.from() as any).update().eq().select().single.mockResolvedValue({
1041
- data: null,
1042
- error: { message: 'Update failed', code: 'ERR' }
1043
- });
1044
-
1044
+
1045
+ const updateChain = {
1046
+ update: vi.fn().mockReturnThis(),
1047
+ eq: vi.fn().mockReturnThis(),
1048
+ select: vi.fn().mockReturnThis(),
1049
+ single: vi.fn().mockResolvedValue({
1050
+ data: null,
1051
+ error: { message: 'Update failed', code: 'ERR' }
1052
+ })
1053
+ };
1054
+ (mockSupabase.from as any).mockReturnValue(updateChain);
1055
+
1045
1056
  const result = await service.updateFileReference('file-ref-123', updates);
1046
1057
  expect(result.ok).toBe(false);
1047
1058
  if (!result.ok) expect(result.error.message).toContain('Update failed');
@@ -46,16 +46,21 @@ describe('[unit] createBaseClient', () => {
46
46
 
47
47
  beforeEach(() => {
48
48
  vi.clearAllMocks();
49
- // Set production mode by default to bypass stack check
50
49
  process.env.NODE_ENV = 'production';
51
- // @ts-expect-error - Testing production mode
52
- import.meta.env = { MODE: 'production', PROD: true };
50
+ Object.defineProperty(import.meta, 'env', {
51
+ value: { MODE: 'production', PROD: true },
52
+ writable: true,
53
+ configurable: true,
54
+ });
53
55
  });
54
56
 
55
57
  afterEach(() => {
56
58
  delete process.env.NODE_ENV;
57
- // @ts-expect-error - Restore
58
- import.meta.env = {};
59
+ Object.defineProperty(import.meta, 'env', {
60
+ value: {},
61
+ writable: true,
62
+ configurable: true,
63
+ });
59
64
  });
60
65
 
61
66
  describe('Client Creation', () => {
@@ -104,8 +109,11 @@ describe('[unit] createBaseClient', () => {
104
109
  describe('Context Validation', () => {
105
110
  it('allows creation in production mode', () => {
106
111
  process.env.NODE_ENV = 'production';
107
- // @ts-expect-error - Testing production mode
108
- import.meta.env = { MODE: 'production', PROD: true };
112
+ Object.defineProperty(import.meta, 'env', {
113
+ value: { MODE: 'production', PROD: true },
114
+ writable: true,
115
+ configurable: true,
116
+ });
109
117
 
110
118
  expect(() => {
111
119
  createBaseClient(mockSupabaseUrl, mockSupabaseKey);
@@ -114,8 +122,11 @@ describe('[unit] createBaseClient', () => {
114
122
 
115
123
  it('allows creation with null stack (production build)', () => {
116
124
  process.env.NODE_ENV = 'production';
117
- // @ts-expect-error - Testing production mode
118
- import.meta.env = { MODE: 'production', PROD: true };
125
+ Object.defineProperty(import.meta, 'env', {
126
+ value: { MODE: 'production', PROD: true },
127
+ writable: true,
128
+ configurable: true,
129
+ });
119
130
 
120
131
  // Mock Error to return null stack
121
132
  const originalError = Error;
@@ -141,8 +152,11 @@ describe('[unit] createBaseClient', () => {
141
152
  describe('Error Handling', () => {
142
153
  it('throws error when called from unauthorized location in development', () => {
143
154
  process.env.NODE_ENV = 'development';
144
- // @ts-expect-error - Testing development mode
145
- import.meta.env = { MODE: 'development' };
155
+ Object.defineProperty(import.meta, 'env', {
156
+ value: { MODE: 'development' },
157
+ writable: true,
158
+ configurable: true,
159
+ });
146
160
 
147
161
  // Mock Error to return unauthorized stack
148
162
  const originalError = Error;
@@ -167,8 +181,11 @@ describe('[unit] createBaseClient', () => {
167
181
  it('logs error to Logger when called from unauthorized location', () => {
168
182
  mockLoggerError.mockClear();
169
183
  process.env.NODE_ENV = 'development';
170
- // @ts-expect-error - Testing development mode
171
- import.meta.env = { MODE: 'development' };
184
+ Object.defineProperty(import.meta, 'env', {
185
+ value: { MODE: 'development' },
186
+ writable: true,
187
+ configurable: true,
188
+ });
172
189
 
173
190
  // Mock Error to return unauthorized stack
174
191
  const originalError = Error;