@jmruthers/pace-core 0.6.10 → 0.6.11

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 (726) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/audit-tool/00-dependencies.cjs +46 -13
  3. package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
  4. package/audit-tool/audits/02-project-structure.cjs +13 -3
  5. package/audit-tool/audits/03-architecture.cjs +78 -4
  6. package/audit-tool/audits/04-code-quality.cjs +9 -2
  7. package/audit-tool/audits/05-styling.cjs +19 -7
  8. package/audit-tool/audits/06-security-rbac.cjs +105 -14
  9. package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
  10. package/audit-tool/audits/08-testing-documentation.cjs +11 -3
  11. package/audit-tool/audits/09-operations.cjs +19 -7
  12. package/audit-tool/index.cjs +22 -11
  13. package/audit-tool/utils/report-utils.cjs +4 -0
  14. package/cursor-rules/01-pace-core-compliance.mdc +1 -0
  15. package/cursor-rules/02-project-structure.mdc +1 -0
  16. package/cursor-rules/03-architecture.mdc +3 -1
  17. package/cursor-rules/04-code-quality.mdc +1 -0
  18. package/cursor-rules/05-styling.mdc +41 -7
  19. package/cursor-rules/06-security-rbac.mdc +2 -1
  20. package/cursor-rules/07-api-tech-stack.mdc +1 -0
  21. package/cursor-rules/08-testing-documentation.mdc +1 -0
  22. package/cursor-rules/09-operations.mdc +1 -0
  23. package/dist/{DataTable-SAXFG4XI.js → DataTable-EFYP2QLE.js} +10 -7
  24. package/dist/{InactivityServiceProvider-DHryoh6K.d.ts → InactivityServiceProvider-BbxwwDz1.d.ts} +10 -1
  25. package/dist/{UnifiedAuthProvider-CiBAl9-s.d.ts → UnifiedAuthProvider-Bkt_tzdS.d.ts} +56 -24
  26. package/dist/{api-F47QJ7FX.js → api-BZR2CYXL.js} +3 -2
  27. package/dist/api-result-USV1Czr-.d.ts +51 -0
  28. package/dist/{audit-Z6ZZBWLU.js → audit-HI2DHUVU.js} +2 -1
  29. package/dist/{auth-BZOJqrdd.d.ts → auth-JvdRVaud.d.ts} +1 -1
  30. package/dist/{chunk-KSNLMI7N.js → chunk-2DL2WSOE.js} +1 -155
  31. package/dist/{chunk-MPY44PWB.js → chunk-2OEVOGGR.js} +4648 -3560
  32. package/dist/chunk-44CNXN4P.js +15 -0
  33. package/dist/{chunk-Y4PF6HIM.js → chunk-4R3T5ENU.js} +867 -786
  34. package/dist/{chunk-LNHFAF4X.js → chunk-7A6IMHH2.js} +289 -247
  35. package/dist/chunk-CU2BU2MQ.js +2 -0
  36. package/dist/{chunk-JJEYZ3DX.js → chunk-D6BMFMQZ.js} +37 -2
  37. package/dist/{chunk-BCTXBU6U.js → chunk-ENLXB7GP.js} +88 -71
  38. package/dist/{chunk-FBZ7U3ID.js → chunk-J2KQK6DG.js} +937 -987
  39. package/dist/{chunk-TFIPNIPE.js → chunk-KJXRL3XE.js} +3300 -2245
  40. package/dist/{chunk-3GWSPISD.js → chunk-L5LFKKLJ.js} +1 -1
  41. package/dist/{chunk-X5EAU5G7.js → chunk-PCSHBLPB.js} +132 -114
  42. package/dist/{chunk-NIU6DPQV.js → chunk-QRYSEPHB.js} +2 -0
  43. package/dist/{chunk-KYURMOQM.js → chunk-V7FTM2LU.js} +423 -320
  44. package/dist/chunk-WY6Y7KC3.js +264 -0
  45. package/dist/{chunk-FN52B75D.js → chunk-XOJME5T7.js} +176 -15
  46. package/dist/{chunk-7YDC7LMU.js → chunk-XPFVT3GN.js} +71 -66
  47. package/dist/{chunk-66R6RLUZ.js → chunk-YFTFFJIV.js} +3 -3
  48. package/dist/{chunk-W46INAVW.js → chunk-YYTWKVHO.js} +688 -570
  49. package/dist/components.d.ts +8 -7
  50. package/dist/components.js +17 -15
  51. package/dist/{database.generated-DT8JTZiP.d.ts → database.generated-qkdoiVrJ.d.ts} +45 -10
  52. package/dist/eslint-rules/index.cjs +3 -0
  53. package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
  54. package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
  55. package/dist/{event-WTAQuGcq.d.ts → event-BfCox3N2.d.ts} +36 -10
  56. package/dist/{file-reference-BavO2eQj.d.ts → file-reference-DU1hcawx.d.ts} +29 -13
  57. package/dist/hooks.d.ts +22 -9
  58. package/dist/hooks.js +34 -25
  59. package/dist/icons/index.d.ts +1 -0
  60. package/dist/icons/index.js +1 -0
  61. package/dist/index.d.ts +66 -177
  62. package/dist/index.js +316 -340
  63. package/dist/pagination-BW1mqywp.d.ts +201 -0
  64. package/dist/providers.d.ts +6 -5
  65. package/dist/providers.js +5 -3
  66. package/dist/rbac/index.d.ts +123 -138
  67. package/dist/rbac/index.js +10 -8
  68. package/dist/theming/runtime.d.ts +19 -2
  69. package/dist/theming/runtime.js +1 -1
  70. package/dist/{timezone-K-ptz3HO.d.ts → timezone-BTWWXKVY.d.ts} +1 -1
  71. package/dist/types.d.ts +17 -10
  72. package/dist/types.js +1 -0
  73. package/dist/{usePublicPageContext-vxBlEHO9.d.ts → usePublicPageContext-B91dGYW1.d.ts} +433 -356
  74. package/dist/{usePublicRouteParams-G3Ks53mk.d.ts → usePublicRouteParams-BgV6VhMi.d.ts} +73 -4
  75. package/dist/utils.d.ts +163 -145
  76. package/dist/utils.js +42 -25
  77. package/docs/api/modules.md +782 -643
  78. package/docs/api-reference/rpc-functions.md +12 -3
  79. package/docs/core-concepts/rbac-system.md +8 -0
  80. package/docs/getting-started/cursor-rules.md +17 -20
  81. package/docs/getting-started/dependencies.md +1 -1
  82. package/docs/getting-started/setup.md +235 -0
  83. package/docs/implementation-guides/authentication.md +27 -0
  84. package/docs/implementation-guides/data-tables.md +176 -3
  85. package/docs/migration/ApiResult-migration.md +25 -0
  86. package/docs/rbac/api-reference.md +33 -31
  87. package/docs/standards/0-standards-overview.md +50 -15
  88. package/docs/standards/1-pace-core-compliance-standards.md +62 -57
  89. package/docs/standards/2-project-structure-standards.md +33 -16
  90. package/docs/standards/3-architecture-standards.md +41 -1
  91. package/docs/standards/4-code-quality-standards.md +26 -6
  92. package/docs/standards/5-styling-standards.md +35 -1
  93. package/docs/standards/6-security-rbac-standards.md +66 -0
  94. package/docs/standards/7-api-tech-stack-standards.md +25 -14
  95. package/docs/standards/8-testing-documentation-standards.md +31 -0
  96. package/docs/standards/9-operations-standards.md +19 -0
  97. package/docs/standards/README.md +20 -201
  98. package/docs/testing/test-setup-for-consumers.md +2 -0
  99. package/docs/troubleshooting/common-issues.md +17 -1
  100. package/docs/troubleshooting/organisation-context-setup.md +8 -0
  101. package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
  102. package/eslint-config-pace-core.cjs +20 -0
  103. package/package.json +14 -20
  104. package/scripts/{build-docs-incremental.js → build-docs.js} +3 -2
  105. package/scripts/setup.cjs +536 -0
  106. package/scripts/validate.cjs +480 -0
  107. package/src/__tests__/helpers/{__tests__/component-test-utils.test.tsx → component-test-utils.test.tsx} +3 -3
  108. package/src/__tests__/helpers/{__tests__/optimized-test-setup.test.ts → optimized-test-setup.test.ts} +2 -2
  109. package/src/__tests__/helpers/{__tests__/supabaseMock.test.ts → supabaseMock.test.ts} +2 -2
  110. package/src/__tests__/helpers/{__tests__/test-providers.test.tsx → test-providers.test.tsx} +1 -1
  111. package/src/__tests__/helpers/test-providers.tsx +37 -39
  112. package/src/__tests__/helpers/{__tests__/test-utils.test.tsx → test-utils.test.tsx} +4 -3
  113. package/src/__tests__/helpers/{__tests__/timer-utils.test.ts → timer-utils.test.ts} +2 -2
  114. package/src/assets/app-icons/index.test.ts +304 -0
  115. package/src/components/AddressField/AddressField.test.tsx +1 -1
  116. package/src/components/AddressField/AddressField.tsx +238 -212
  117. package/src/components/Button/Button.tsx +1 -1
  118. package/src/components/Card/Card.test.tsx +172 -17
  119. package/src/components/Card/Card.tsx +19 -10
  120. package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
  121. package/src/components/ContextSelector/{__tests__/ContextSelector.test.tsx → ContextSelector.test.tsx} +6 -6
  122. package/src/components/ContextSelector/ContextSelector.tsx +66 -280
  123. package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
  124. package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
  125. package/src/components/DataTable/AUDIT_REPORT.md +59 -44
  126. package/src/components/DataTable/{__tests__/DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx} +6 -6
  127. package/src/components/DataTable/{__tests__/DataTable.default-state.test.tsx → DataTable.default-state.test.tsx} +5 -5
  128. package/src/components/DataTable/{__tests__/DataTable.export.test.tsx → DataTable.export.test.tsx} +10 -10
  129. package/src/components/DataTable/{__tests__/DataTable.grouping-aggregation.test.tsx → DataTable.grouping-aggregation.test.tsx} +6 -6
  130. package/src/components/DataTable/{__tests__/DataTable.hooks.test.tsx → DataTable.hooks.test.tsx} +6 -6
  131. package/src/components/DataTable/{__tests__/DataTable.select-label-display.test.tsx → DataTable.select-label-display.test.tsx} +6 -6
  132. package/src/components/DataTable/DataTable.test.tsx +787 -416
  133. package/src/components/DataTable/DataTable.tsx +12 -12
  134. package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
  135. package/src/components/DataTable/{__tests__/DataTableCore.test-setup.ts → DataTableCore.test-setup.ts} +10 -9
  136. package/src/components/DataTable/{__tests__/DataTableCore.test.tsx → DataTableCore.test.tsx} +8 -8
  137. package/src/components/DataTable/{__tests__/README.md → README.md} +17 -7
  138. package/src/components/DataTable/TESTING.md +101 -0
  139. package/src/components/DataTable/{__tests__/a11y.basic.test.tsx → a11y.basic.test.tsx} +34 -34
  140. package/src/components/DataTable/components/DataTableCore.tsx +104 -864
  141. package/src/components/DataTable/components/{__tests__/GroupingDropdown.test.tsx → GroupingDropdown.test.tsx} +17 -8
  142. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +61 -559
  144. package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
  145. package/src/components/DataTable/context/{__tests__/DataTableContext.test.tsx → DataTableContext.test.tsx} +2 -2
  146. package/src/components/DataTable/context/DataTableContext.tsx +7 -6
  147. package/src/components/DataTable/core/{__tests__/ColumnFactory.test.ts → ColumnFactory.test.ts} +2 -2
  148. package/src/components/DataTable/hooks/{__tests__/useColumnOrderPersistence.test.ts → useColumnOrderPersistence.test.ts} +2 -2
  149. package/src/components/DataTable/hooks/{__tests__/useColumnVisibilityPersistence.test.ts → useColumnVisibilityPersistence.test.ts} +2 -2
  150. package/src/components/DataTable/hooks/{__tests__/useDataTableConfiguration.test.ts → useDataTableConfiguration.test.ts} +3 -3
  151. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
  152. package/src/components/DataTable/hooks/{__tests__/useDataTableDataPipeline.test.ts → useDataTableDataPipeline.test.ts} +6 -6
  153. package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
  154. package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
  155. package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
  156. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +238 -0
  157. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
  158. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
  159. package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
  160. package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
  161. package/src/components/DataTable/hooks/{__tests__/useDataTablePermissions.test.ts → useDataTablePermissions.test.ts} +11 -11
  162. package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
  163. package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
  164. package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
  165. package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
  166. package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
  167. package/src/components/DataTable/hooks/useDataTableScope.test.ts +110 -0
  168. package/src/components/DataTable/hooks/useDataTableScope.ts +123 -0
  169. package/src/components/DataTable/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +47 -5
  170. package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
  171. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
  172. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
  173. package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
  174. package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
  175. package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
  176. package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
  177. package/src/components/DataTable/hooks/{__tests__/useEffectiveColumnOrder.test.ts → useEffectiveColumnOrder.test.ts} +2 -2
  178. package/src/components/DataTable/hooks/{__tests__/useHierarchicalState.test.ts → useHierarchicalState.test.ts} +2 -2
  179. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.test.ts +3 -3
  180. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.ts +2 -2
  181. package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
  182. package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
  183. package/src/components/DataTable/hooks/{__tests__/useKeyboardNavigation.test.ts → useKeyboardNavigation.test.ts} +3 -3
  184. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
  185. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.test.ts +3 -3
  186. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.ts +3 -3
  187. package/src/components/DataTable/hooks/{__tests__/useServerSideDataEffect.test.ts → useServerSideDataEffect.test.ts} +2 -2
  188. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
  189. package/src/components/DataTable/hooks/{__tests__/useTableColumns.test.ts → useTableColumns.test.ts} +2 -2
  190. package/src/components/DataTable/hooks/{__tests__/useTableHandlers.test.ts → useTableHandlers.test.ts} +25 -4
  191. package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
  192. package/src/components/DataTable/index.ts +18 -17
  193. package/src/components/DataTable/{__tests__/keyboard.test.tsx → keyboard.test.tsx} +41 -63
  194. package/src/components/DataTable/{__tests__/mocks → mocks}/MockRBACProvider.tsx +1 -1
  195. package/src/components/DataTable/{__tests__/pagination.modes.test.tsx → pagination.modes.test.tsx} +6 -6
  196. package/src/components/DataTable/{__tests__/ssr.strict-mode.test.tsx → ssr.strict-mode.test.tsx} +2 -2
  197. package/src/components/DataTable/{__tests__/styles.test.ts → styles.test.ts} +1 -4
  198. package/src/components/DataTable/styles.ts +0 -1
  199. package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
  200. package/src/components/DataTable/{__tests__/test-utils → test-utils}/dataFactories.ts +2 -2
  201. package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
  202. package/src/components/DataTable/{__tests__/test-utils/sharedTestUtils.tsx → test-utils/sharedTestUtils.ts} +97 -66
  203. package/src/components/DataTable/{__tests__/test-utils.ts → test-utils.ts} +1 -1
  204. package/src/components/DataTable/types/actions.ts +71 -0
  205. package/src/components/DataTable/types/base.ts +39 -0
  206. package/src/components/DataTable/types/columns.ts +125 -0
  207. package/src/components/DataTable/types/export.ts +32 -0
  208. package/src/components/DataTable/types/features.ts +81 -0
  209. package/src/components/DataTable/types/hierarchical.ts +44 -0
  210. package/src/components/DataTable/types/index.ts +43 -0
  211. package/src/components/DataTable/types/pagination.ts +85 -0
  212. package/src/components/DataTable/types/performance.ts +47 -0
  213. package/src/components/DataTable/types/props.ts +62 -0
  214. package/src/components/DataTable/types/rbac.ts +45 -0
  215. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableCore.test.tsx +430 -28
  216. package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
  217. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableErrorBoundary.test.tsx +4 -4
  218. package/src/components/DataTable/{components → ui/layout}/DataTableErrorBoundary.tsx +7 -7
  219. package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
  220. package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
  221. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
  222. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
  223. package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
  224. package/src/components/DataTable/{components → ui/modals}/DataTableModals.tsx +36 -28
  225. package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
  226. package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
  227. package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
  228. package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
  229. package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
  230. package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
  231. package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
  232. package/src/components/DataTable/{components/__tests__ → ui/shared}/AccessDeniedPage.test.tsx +2 -2
  233. package/src/components/DataTable/{components → ui/shared}/AccessDeniedPage.tsx +2 -2
  234. package/src/components/DataTable/{components/__tests__ → ui/shared}/ActionButtons.test.tsx +6 -4
  235. package/src/components/DataTable/{components → ui/shared}/ActionButtons.tsx +4 -4
  236. package/src/components/DataTable/{components/__tests__ → ui/shared}/ColumnFilter.test.tsx +29 -16
  237. package/src/components/DataTable/{components → ui/shared}/ColumnFilter.tsx +4 -4
  238. package/src/components/DataTable/{components/__tests__ → ui/shared}/PaginationControls.test.tsx +38 -16
  239. package/src/components/DataTable/{components → ui/shared}/PaginationControls.tsx +21 -15
  240. package/src/components/DataTable/{components/__tests__ → ui/shared}/SortIndicator.test.tsx +2 -2
  241. package/src/components/DataTable/{components → ui/shared}/SortIndicator.tsx +1 -1
  242. package/src/components/DataTable/{components/__tests__ → ui/table}/EditFields.test.tsx +3 -3
  243. package/src/components/DataTable/{components → ui/table}/EditFields.tsx +138 -69
  244. package/src/components/DataTable/{components/__tests__ → ui/table}/EditableRow.test.tsx +36 -27
  245. package/src/components/DataTable/{components → ui/table}/EditableRow.tsx +86 -104
  246. package/src/components/DataTable/{components/__tests__ → ui/table}/EmptyState.test.tsx +2 -62
  247. package/src/components/DataTable/{components → ui/table}/EmptyState.tsx +7 -15
  248. package/src/components/DataTable/{components/__tests__ → ui/table}/FilterRow.test.tsx +5 -4
  249. package/src/components/DataTable/{components → ui/table}/FilterRow.tsx +3 -3
  250. package/src/components/DataTable/{components/__tests__ → ui/table}/LoadingState.test.tsx +6 -10
  251. package/src/components/DataTable/{components → ui/table}/LoadingState.tsx +4 -4
  252. package/src/components/DataTable/{components/__tests__ → ui/table}/RowComponent.test.tsx +412 -17
  253. package/src/components/DataTable/{components → ui/table}/RowComponent.tsx +183 -177
  254. package/src/components/DataTable/{components/__tests__ → ui/table}/UnifiedTableBody.test.tsx +425 -16
  255. package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
  256. package/src/components/DataTable/{components/__tests__ → ui/table}/cellValueUtils.test.ts +2 -2
  257. package/src/components/DataTable/{components → ui/table}/cellValueUtils.ts +1 -1
  258. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/BulkOperationsDropdown.test.tsx +12 -5
  259. package/src/components/DataTable/{components → ui/toolbar}/BulkOperationsDropdown.tsx +3 -3
  260. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/ColumnVisibilityDropdown.test.tsx +7 -4
  261. package/src/components/DataTable/{components → ui/toolbar}/ColumnVisibilityDropdown.tsx +7 -7
  262. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/DataTableToolbar.test.tsx +4 -4
  263. package/src/components/DataTable/{components → ui/toolbar}/DataTableToolbar.tsx +4 -4
  264. package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
  265. package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
  266. package/src/components/DataTable/utils/{__tests__/a11yUtils.test.ts → a11yUtils.test.ts} +2 -2
  267. package/src/components/DataTable/utils/{__tests__/aggregationUtils.test.ts → aggregationUtils.test.ts} +3 -3
  268. package/src/components/DataTable/utils/{__tests__/columnUtils.test.ts → columnUtils.test.ts} +2 -2
  269. package/src/components/DataTable/utils/csvParse.test.ts +74 -0
  270. package/src/components/DataTable/utils/csvParse.ts +65 -0
  271. package/src/components/DataTable/utils/{__tests__/errorHandling.test.ts → errorHandling.test.ts} +2 -2
  272. package/src/components/DataTable/utils/{__tests__/exportUtils.test.ts → exportUtils.test.ts} +3 -3
  273. package/src/components/DataTable/utils/{__tests__/flexibleImport.test.ts → flexibleImport.test.ts} +2 -2
  274. package/src/components/DataTable/utils/flexibleImport.ts +3 -186
  275. package/src/components/DataTable/utils/{__tests__/hierarchicalSorting.test.ts → hierarchicalSorting.test.ts} +3 -3
  276. package/src/components/DataTable/utils/{__tests__/hierarchicalUtils.test.ts → hierarchicalUtils.test.ts} +3 -3
  277. package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
  278. package/src/components/DataTable/utils/importDateParser.ts +114 -0
  279. package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
  280. package/src/components/DataTable/utils/importValueParser.ts +91 -0
  281. package/src/components/DataTable/utils/{__tests__/paginationUtils.test.ts → paginationUtils.test.ts} +2 -2
  282. package/src/components/DataTable/utils/paginationUtils.ts +6 -3
  283. package/src/components/DataTable/utils/{__tests__/performanceUtils.test.ts → performanceUtils.test.ts} +3 -3
  284. package/src/components/DataTable/utils/{__tests__/rowUtils.test.ts → rowUtils.test.ts} +3 -3
  285. package/src/components/DataTable/utils/{__tests__/selectFieldUtils.test.ts → selectFieldUtils.test.ts} +66 -3
  286. package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
  287. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
  288. package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
  289. package/src/components/Dialog/Dialog.test-utils.ts +49 -0
  290. package/src/components/Dialog/Dialog.test.tsx +896 -89
  291. package/src/components/Dialog/Dialog.tsx +174 -882
  292. package/src/components/Dialog/dialogLock.test.ts +238 -0
  293. package/src/components/Dialog/dialogLock.ts +98 -0
  294. package/src/components/Dialog/index.ts +2 -0
  295. package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
  296. package/src/components/Dialog/useDialogDimensions.ts +140 -0
  297. package/src/components/Dialog/useDialogLifecycle.test.ts +358 -0
  298. package/src/components/Dialog/useDialogLifecycle.ts +135 -0
  299. package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
  300. package/src/components/Dialog/useDialogPersistence.ts +357 -0
  301. package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
  302. package/src/components/FileDisplay/FileDisplay.tsx +24 -656
  303. package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
  304. package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
  305. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
  306. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
  307. package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
  308. package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
  309. package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
  310. package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
  311. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
  312. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
  313. package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
  314. package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
  315. package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
  316. package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
  317. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
  318. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
  319. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
  320. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
  321. package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
  322. package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
  323. package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
  324. package/src/components/FileDisplay/fallbackUtils.ts +44 -0
  325. package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
  326. package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
  327. package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
  328. package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
  329. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.test.ts +40 -42
  330. package/src/components/FileDisplay/useFileDisplay.ts +515 -0
  331. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.unit.test.ts +406 -77
  332. package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
  333. package/src/{hooks/public → components/FileDisplay}/usePublicFileDisplay.test.ts +94 -88
  334. package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
  335. package/src/components/FileUpload/FileUpload.test.tsx +16 -10
  336. package/src/components/FileUpload/FileUpload.tsx +107 -525
  337. package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
  338. package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
  339. package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
  340. package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
  341. package/src/components/FileUpload/useFileUploadManager.ts +454 -0
  342. package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
  343. package/src/components/FileUpload/useResolvedAppId.ts +77 -0
  344. package/src/components/Footer/Footer.test.tsx +6 -292
  345. package/src/components/Footer/Footer.tsx +8 -125
  346. package/src/components/Form/Form.test.tsx +44 -27
  347. package/src/components/Form/Form.tsx +64 -287
  348. package/src/components/Form/useFormPersistence.ts +257 -0
  349. package/src/components/Header/Header.test.tsx +17 -18
  350. package/src/components/Header/Header.tsx +10 -1
  351. package/src/components/Input/Input.tsx +1 -1
  352. package/src/components/Label/Label.test.tsx +1 -1
  353. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
  354. package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
  355. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
  356. package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
  357. package/src/components/NavigationMenu/index.ts +6 -1
  358. package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
  359. package/src/components/NavigationMenu/{__tests__/useNavigationFiltering.test.ts → useNavigationFiltering.test.ts} +68 -53
  360. package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
  361. package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
  362. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +77 -62
  363. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
  364. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
  365. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
  366. package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
  367. package/src/components/PaceAppLayout/useFilteredNavItems.ts +304 -0
  368. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +142 -0
  369. package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
  370. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
  371. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +79 -0
  372. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
  373. package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
  374. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
  376. package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
  377. package/src/components/Progress/Progress.tsx +1 -2
  378. package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
  379. package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
  380. package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
  381. package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
  382. package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
  383. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
  384. package/src/components/Select/Select.test.tsx +1 -1
  385. package/src/components/Select/Select.tsx +28 -18
  386. package/src/components/Select/{__tests__/context.test.tsx → context.test.tsx} +3 -3
  387. package/src/components/Select/{utils/__tests__/text.test.tsx → text.test.tsx} +2 -2
  388. package/src/components/Select/{utils/text.ts → text.ts} +1 -1
  389. package/src/components/Select/{hooks/__tests__/useSelectEvents.test.ts → useSelectEvents.test.ts} +5 -5
  390. package/src/components/Select/{hooks/useSelectEvents.ts → useSelectEvents.ts} +2 -2
  391. package/src/components/Select/{hooks/__tests__/useSelectSearch.test.tsx → useSelectSearch.test.tsx} +7 -7
  392. package/src/components/Select/{hooks/useSelectSearch.ts → useSelectSearch.ts} +2 -2
  393. package/src/components/Select/{hooks/__tests__/useSelectState.test.ts → useSelectState.test.ts} +16 -2
  394. package/src/components/Select/{hooks/useSelectState.ts → useSelectState.ts} +3 -3
  395. package/src/components/Table/Table.test.tsx +348 -0
  396. package/src/components/Tabs/Tabs.test.tsx +270 -0
  397. package/src/components/Tabs/Tabs.tsx +1 -1
  398. package/src/components/Toast/Toast.test.tsx +420 -0
  399. package/src/components/{__tests__/index.test.ts → index.test.ts} +2 -2
  400. package/src/constants/{__tests__/performance.test.ts → performance.test.ts} +2 -2
  401. package/src/hooks/{__tests__/ServiceHooks.test.tsx → ServiceHooks.test.tsx} +8 -8
  402. package/src/hooks/{__tests__/hooks.integration.test.tsx → hooks.integration.test.tsx} +11 -11
  403. package/src/hooks/index.ts +7 -4
  404. package/src/hooks/{__tests__/index.unit.test.ts → index.unit.test.ts} +2 -2
  405. package/src/hooks/public/usePublicEvent.test.ts +1 -1
  406. package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
  407. package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
  408. package/src/hooks/services/useAuth.ts +9 -7
  409. package/src/hooks/useAddressAutocomplete.test.ts +22 -22
  410. package/src/hooks/useAddressAutocomplete.ts +90 -75
  411. package/src/hooks/{__tests__/useAppConfig.unit.test.ts → useAppConfig.unit.test.ts} +328 -22
  412. package/src/hooks/{__tests__/useComponentPerformance.unit.test.tsx → useComponentPerformance.unit.test.tsx} +27 -41
  413. package/src/hooks/useDataTablePerformance.ts +100 -120
  414. package/src/hooks/{__tests__/useDataTablePerformance.unit.test.ts → useDataTablePerformance.unit.test.ts} +5 -5
  415. package/src/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +2 -2
  416. package/src/hooks/{__tests__/useDebounce.unit.test.ts → useDebounce.unit.test.ts} +2 -2
  417. package/src/hooks/useEventTheme.test.ts +4 -1
  418. package/src/hooks/useEventTheme.ts +49 -21
  419. package/src/hooks/useEvents.ts +41 -1
  420. package/src/hooks/{__tests__/useEvents.unit.test.ts → useEvents.unit.test.ts} +5 -5
  421. package/src/hooks/useFileReference.test.ts +44 -41
  422. package/src/hooks/useFileReference.ts +182 -173
  423. package/src/hooks/useFileUrl.ts +1 -1
  424. package/src/hooks/{__tests__/useFileUrl.unit.test.ts → useFileUrl.unit.test.ts} +26 -36
  425. package/src/hooks/{__tests__/useFileUrlCache.test.ts → useFileUrlCache.test.ts} +8 -8
  426. package/src/hooks/useFileUrlCache.ts +1 -1
  427. package/src/hooks/{__tests__/useFocusManagement.unit.test.ts → useFocusManagement.unit.test.ts} +2 -2
  428. package/src/hooks/{__tests__/useFocusTrap.unit.test.tsx → useFocusTrap.unit.test.tsx} +2 -2
  429. package/src/hooks/{__tests__/useFormDialog.test.ts → useFormDialog.test.ts} +2 -2
  430. package/src/hooks/useInactivityTracker.ts +138 -131
  431. package/src/hooks/{__tests__/useInactivityTracker.unit.test.ts → useInactivityTracker.unit.test.ts} +3 -3
  432. package/src/hooks/{__tests__/useIsMobile.unit.test.ts → useIsMobile.unit.test.ts} +2 -2
  433. package/src/hooks/useIsPrint.ts +62 -0
  434. package/src/hooks/useIsPrint.unit.test.ts +545 -0
  435. package/src/hooks/{__tests__/useKeyboardShortcuts.unit.test.ts → useKeyboardShortcuts.unit.test.ts} +2 -2
  436. package/src/hooks/{__tests__/useOrganisationPermissions.unit.test.tsx → useOrganisationPermissions.unit.test.tsx} +4 -4
  437. package/src/hooks/useOrganisationSecurity.test.ts +3 -3
  438. package/src/hooks/useOrganisationSecurity.ts +190 -201
  439. package/src/hooks/{__tests__/useOrganisationSecurity.unit.test.tsx → useOrganisationSecurity.unit.test.tsx} +61 -63
  440. package/src/hooks/{__tests__/useOrganisations.unit.test.ts → useOrganisations.unit.test.ts} +5 -5
  441. package/src/hooks/{__tests__/usePerformanceMonitor.unit.test.ts → usePerformanceMonitor.unit.test.ts} +13 -14
  442. package/src/hooks/{__tests__/usePermissionCache.test.ts → usePermissionCache.test.ts} +26 -27
  443. package/src/hooks/usePermissionCache.ts +276 -271
  444. package/src/hooks/{__tests__/usePreventTabReload.test.ts → usePreventTabReload.test.ts} +2 -2
  445. package/src/hooks/{__tests__/usePublicEvent.simple.test.ts → usePublicEvent.simple.test.ts} +4 -4
  446. package/src/hooks/{__tests__/usePublicEvent.test.ts → usePublicEvent.test.ts} +4 -4
  447. package/src/hooks/{__tests__/usePublicEvent.unit.test.ts → usePublicEvent.unit.test.ts} +4 -4
  448. package/src/hooks/{__tests__/usePublicFileDisplay.test.ts → usePublicFileDisplay.test.ts} +12 -12
  449. package/src/hooks/{__tests__/usePublicRouteParams.unit.test.ts → usePublicRouteParams.unit.test.ts} +3 -3
  450. package/src/hooks/{__tests__/useQueryCache.test.ts → useQueryCache.test.ts} +2 -2
  451. package/src/hooks/useQueryCache.ts +0 -2
  452. package/src/hooks/{__tests__/useRBAC.unit.test.ts → useRBAC.unit.test.ts} +55 -38
  453. package/src/hooks/{__tests__/useSessionDraft.test.ts → useSessionDraft.test.ts} +2 -2
  454. package/src/hooks/{__tests__/useSessionRestoration.unit.test.tsx → useSessionRestoration.unit.test.tsx} +10 -19
  455. package/src/hooks/useStorage.ts +21 -16
  456. package/src/hooks/{__tests__/useStorage.unit.test.ts → useStorage.unit.test.ts} +38 -75
  457. package/src/hooks/{__tests__/useToast.test.ts → useToast.test.ts} +2 -2
  458. package/src/hooks/{__tests__/useToast.unit.test.tsx → useToast.unit.test.tsx} +2 -2
  459. package/src/hooks/{__tests__/useZodForm.unit.test.tsx → useZodForm.unit.test.tsx} +2 -2
  460. package/src/icons/{__tests__/index.test.ts → index.test.ts} +2 -2
  461. package/src/icons/index.ts +2 -0
  462. package/src/{__tests__/index.test.ts → index.test.ts} +3 -7
  463. package/src/index.ts +15 -7
  464. package/src/providers/{__tests__/AuthProvider.test.tsx → AuthProvider.test.tsx} +3 -3
  465. package/src/providers/{__tests__/EventProvider.test.tsx → EventProvider.test.tsx} +3 -3
  466. package/src/providers/InactivityProvider.test-helper.tsx +40 -0
  467. package/src/providers/{__tests__/InactivityProvider.test.tsx → InactivityProvider.test.tsx} +14 -21
  468. package/src/providers/{__tests__/ProviderLifecycle.test.tsx → ProviderLifecycle.test.tsx} +4 -4
  469. package/src/providers/{__tests__/UnifiedAuthProvider.test.tsx → UnifiedAuthProvider.test.tsx} +1 -1
  470. package/src/providers/{__tests__/index.test.ts → index.test.ts} +2 -2
  471. package/src/providers/services/{__tests__/AuthServiceProvider.integration.test.tsx → AuthServiceProvider.integration.test.tsx} +4 -4
  472. package/src/providers/services/{__tests__/AuthServiceProvider.test.tsx → AuthServiceProvider.test.tsx} +7 -7
  473. package/src/providers/services/{__tests__/EventServiceProvider.test.tsx → EventServiceProvider.test.tsx} +7 -7
  474. package/src/providers/services/{__tests__/InactivityServiceProvider.test.tsx → InactivityServiceProvider.test.tsx} +5 -5
  475. package/src/providers/services/{__tests__/OrganisationServiceProvider.test.tsx → OrganisationServiceProvider.test.tsx} +6 -6
  476. package/src/providers/services/UnifiedAuthContext.ts +30 -27
  477. package/src/providers/services/{__tests__/UnifiedAuthProvider.advanced.test.tsx → UnifiedAuthProvider.advanced.test.tsx} +8 -9
  478. package/src/providers/services/{__tests__/UnifiedAuthProvider.appId.test.tsx → UnifiedAuthProvider.appId.test.tsx} +25 -25
  479. package/src/providers/services/{__tests__/UnifiedAuthProvider.integration.test.tsx → UnifiedAuthProvider.integration.test.tsx} +14 -11
  480. package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
  481. package/src/providers/services/{__tests__/contexts.test.tsx → contexts.test.tsx} +6 -6
  482. package/src/providers/services/{__tests__/useUnifiedAuth.test.tsx → useUnifiedAuth.test.tsx} +6 -6
  483. package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
  484. package/src/providers/useInactivity.test-helper.ts +27 -0
  485. package/src/rbac/{__tests__/adapters.comprehensive.test.tsx → adapters.comprehensive.test.tsx} +24 -24
  486. package/src/rbac/adapters.test.tsx +22 -22
  487. package/src/rbac/adapters.tsx +29 -29
  488. package/src/rbac/api.test.ts +973 -42
  489. package/src/rbac/api.ts +228 -253
  490. package/src/rbac/{__tests__/audit-batched.test.ts → audit-batched.test.ts} +6 -6
  491. package/src/rbac/audit.ts +4 -1
  492. package/src/rbac/{__tests__/auth-rbac-security.integration.test.tsx → auth-rbac-security.integration.test.tsx} +1 -1
  493. package/src/rbac/{__tests__/auth-rbac.e2e.test.tsx → auth-rbac.e2e.test.tsx} +27 -34
  494. package/src/rbac/cache-invalidation.test.ts +715 -0
  495. package/src/rbac/components/{__tests__/AccessDenied.test.tsx → AccessDenied.test.tsx} +3 -3
  496. package/src/rbac/components/{__tests__/NavigationGuard.test.tsx → NavigationGuard.test.tsx} +13 -11
  497. package/src/{__tests__/rbac/PagePermissionGuard.test.tsx → rbac/components/PagePermissionGuard.guard.test.tsx} +33 -19
  498. package/src/rbac/components/{__tests__/PagePermissionGuard.performance.test.tsx → PagePermissionGuard.performance.test.tsx} +30 -9
  499. package/src/rbac/components/{__tests__/PagePermissionGuard.race-condition.test.tsx → PagePermissionGuard.race-condition.test.tsx} +7 -7
  500. package/src/rbac/components/{__tests__/PagePermissionGuard.test.tsx → PagePermissionGuard.test.tsx} +10 -10
  501. package/src/rbac/components/PagePermissionGuard.tsx +177 -372
  502. package/src/rbac/components/{__tests__/PagePermissionGuard.verification.test.tsx → PagePermissionGuard.verification.test.tsx} +7 -7
  503. package/src/rbac/config.ts +58 -18
  504. package/src/rbac/{__tests__/engine.comprehensive.test.ts → engine.comprehensive.test.ts} +3 -3
  505. package/src/rbac/engine.test.ts +494 -0
  506. package/src/rbac/errors.ts +89 -55
  507. package/src/rbac/hooks/permissions/runPermissionCheck.ts +77 -0
  508. package/src/rbac/hooks/permissions/{__tests__/useAccessLevel.test.ts → useAccessLevel.test.ts} +40 -40
  509. package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
  510. package/src/rbac/hooks/permissions/{__tests__/useCan.test.ts → useCan.test.ts} +41 -41
  511. package/src/rbac/hooks/permissions/useCan.ts +170 -252
  512. package/src/rbac/hooks/permissions/{__tests__/useMultiplePermissions.test.ts → useMultiplePermissions.test.ts} +49 -49
  513. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +6 -2
  514. package/src/rbac/hooks/permissions/{__tests__/usePermissions.test.ts → usePermissions.test.ts} +10 -12
  515. package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
  516. package/src/rbac/hooks/useCan.test.ts +42 -42
  517. package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
  518. package/src/rbac/hooks/usePageGuardScope.ts +117 -0
  519. package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
  520. package/src/rbac/hooks/{__tests__/usePermissions.integration.test.ts → usePermissions.integration.test.ts} +9 -9
  521. package/src/{__tests__/hooks/usePermissions.test.ts → rbac/hooks/usePermissions.stability.test.ts} +18 -18
  522. package/src/rbac/hooks/usePermissions.test.ts +54 -54
  523. package/src/rbac/hooks/useRBAC.test.ts +313 -217
  524. package/src/rbac/hooks/useRBAC.ts +145 -81
  525. package/src/rbac/hooks/useResourcePermissions.test.ts +25 -25
  526. package/src/rbac/hooks/useResourcePermissions.ts +68 -134
  527. package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
  528. package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
  529. package/src/rbac/hooks/useRoleManagement.ts +153 -585
  530. package/src/rbac/hooks/{__tests__/useSecureSupabase.test.ts → useSecureSupabase.test.ts} +17 -17
  531. package/src/rbac/hooks/useSecureSupabase.ts +10 -2
  532. package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
  533. package/src/rbac/{__tests__/performance.test.ts → performance.test.ts} +1 -1
  534. package/src/rbac/{__tests__/rbac-core.test.tsx → rbac-core.test.tsx} +3 -3
  535. package/src/rbac/{__tests__/rbac-engine-core-logic.test.ts → rbac-engine-core-logic.test.ts} +2 -2
  536. package/src/rbac/{__tests__/rbac-engine-simplified.test.ts → rbac-engine-simplified.test.ts} +3 -3
  537. package/src/rbac/{__tests__/rbac-functions.test.ts → rbac-functions.test.ts} +57 -0
  538. package/src/rbac/{__tests__/rbac-role-isolation.test.ts → rbac-role-isolation.test.ts} +2 -2
  539. package/src/rbac/request-deduplication.test.ts +14 -9
  540. package/src/rbac/request-deduplication.ts +5 -4
  541. package/src/rbac/{__tests__/scenarios.user-role.test.tsx → scenarios.user-role.test.tsx} +23 -23
  542. package/src/rbac/secureClient.test.ts +514 -83
  543. package/src/rbac/secureClient.ts +8 -2
  544. package/src/rbac/security.test.ts +323 -0
  545. package/src/rbac/types/roleManagement.ts +66 -0
  546. package/src/rbac/utils/{__tests__/clientSecurity.test.ts → clientSecurity.test.ts} +4 -4
  547. package/src/rbac/utils/{__tests__/contextValidator.test.ts → contextValidator.test.ts} +4 -4
  548. package/src/rbac/utils/contextValidator.ts +5 -1
  549. package/src/rbac/utils/{__tests__/deep-equal.test.ts → deep-equal.test.ts} +1 -1
  550. package/src/rbac/utils/{__tests__/eventContext.test.ts → eventContext.test.ts} +36 -21
  551. package/src/rbac/utils/eventContext.ts +37 -33
  552. package/src/rbac/utils/fetchPermissionMap.ts +13 -0
  553. package/src/rbac/utils/permissionMapHelpers.ts +34 -0
  554. package/src/rbac/utils/roleManagementRpc.ts +303 -0
  555. package/src/services/{__tests__/AuthService.edge-cases.test.ts → AuthService.edge-cases.test.ts} +19 -19
  556. package/src/services/{__tests__/AuthService.restoreSession.test.ts → AuthService.restoreSession.test.ts} +2 -2
  557. package/src/services/{__tests__/AuthService.test.ts → AuthService.test.ts} +89 -55
  558. package/src/services/AuthService.ts +184 -205
  559. package/src/services/{__tests__/BaseService.edge-cases.test.ts → BaseService.edge-cases.test.ts} +3 -3
  560. package/src/services/{__tests__/BaseService.test.ts → BaseService.test.ts} +2 -2
  561. package/src/services/{__tests__/EventService.edge-cases.test.ts → EventService.edge-cases.test.ts} +27 -24
  562. package/src/services/{__tests__/EventService.eventColours.test.ts → EventService.eventColours.test.ts} +1 -1
  563. package/src/services/{__tests__/EventService.test.ts → EventService.test.ts} +256 -24
  564. package/src/services/EventService.ts +242 -312
  565. package/src/services/{__tests__/InactivityService.edge-cases.test.ts → InactivityService.edge-cases.test.ts} +3 -3
  566. package/src/services/{__tests__/InactivityService.lifecycle.test.ts → InactivityService.lifecycle.test.ts} +2 -2
  567. package/src/services/{__tests__/InactivityService.test.ts → InactivityService.test.ts} +179 -4
  568. package/src/services/InactivityService.ts +172 -213
  569. package/src/services/{__tests__/OrganisationService.edge-cases.test.ts → OrganisationService.edge-cases.test.ts} +5 -5
  570. package/src/services/{__tests__/OrganisationService.pagination.test.ts → OrganisationService.pagination.test.ts} +4 -4
  571. package/src/services/{__tests__/OrganisationService.test.ts → OrganisationService.test.ts} +410 -7
  572. package/src/services/OrganisationService.ts +184 -238
  573. package/src/services/base/BaseService.test.ts +1 -1
  574. package/src/services/interfaces/{__tests__/IAuthService.test.ts → IAuthService.test.ts} +21 -27
  575. package/src/services/interfaces/IAuthService.ts +10 -9
  576. package/src/services/interfaces/{__tests__/IEventService.test.ts → IEventService.test.ts} +4 -4
  577. package/src/services/interfaces/{__tests__/IInactivityService.test.ts → IInactivityService.test.ts} +3 -3
  578. package/src/services/interfaces/{__tests__/IOrganisationService.test.ts → IOrganisationService.test.ts} +3 -3
  579. package/src/styles/core.css +243 -12
  580. package/src/theming/{__tests__/parseEventColours.test.ts → parseEventColours.test.ts} +1 -1
  581. package/src/theming/{__tests__/runtime.test.ts → runtime.test.ts} +8 -17
  582. package/src/theming/runtime.ts +71 -2
  583. package/src/types/api-result.ts +53 -0
  584. package/src/types/{__tests__/core.test.ts → core.test.ts} +2 -2
  585. package/src/types/{__tests__/database-generated.test.ts → database-generated.test.ts} +3 -3
  586. package/src/types/database.generated.ts +45 -10
  587. package/src/types/event.ts +38 -18
  588. package/src/types/{__tests__/file-reference.test.ts → file-reference.test.ts} +13 -13
  589. package/src/types/file-reference.ts +37 -12
  590. package/src/types/{__tests__/guards.test.ts → guards.test.ts} +2 -2
  591. package/src/types/{__tests__/index.test.ts → index.test.ts} +2 -2
  592. package/src/types/index.ts +3 -0
  593. package/src/types/{__tests__/organisation.roles.test.ts → organisation.roles.test.ts} +1 -1
  594. package/src/types/{__tests__/organisation.test.ts → organisation.test.ts} +3 -31
  595. package/src/types/organisation.ts +15 -15
  596. package/src/types/supabase.ts +13 -4
  597. package/src/types/{__tests__/theme.test.ts → theme.test.ts} +1 -1
  598. package/src/types/{__tests__/type-validation.test.ts → type-validation.test.ts} +1 -1
  599. package/src/types/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  600. package/src/utils/app/appIdResolver.test.ts +98 -71
  601. package/src/utils/app/appIdResolver.ts +31 -20
  602. package/src/utils/{__tests__/appConfig.unit.test.ts → appConfig.unit.test.ts} +1 -1
  603. package/src/utils/{__tests__/audit.unit.test.ts → audit.unit.test.ts} +1 -1
  604. package/src/utils/{__tests__/auth-utils.unit.test.ts → auth-utils.unit.test.ts} +16 -17
  605. package/src/utils/{__tests__/bundleAnalysis.unit.test.ts → bundleAnalysis.unit.test.ts} +35 -35
  606. package/src/utils/{__tests__/cn.unit.test.ts → cn.unit.test.ts} +1 -1
  607. package/src/utils/context/organisationContext.test.ts +105 -91
  608. package/src/utils/context/organisationContext.ts +29 -40
  609. package/src/utils/core/{__tests__/cn.test.ts → cn.test.ts} +3 -3
  610. package/src/utils/core/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +2 -2
  611. package/src/utils/core/{__tests__/logger.test.ts → logger.test.ts} +2 -2
  612. package/src/utils/core/mergeRefs.ts +24 -0
  613. package/src/utils/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +1 -1
  614. package/src/utils/{__tests__/deviceFingerprint.unit.test.ts → deviceFingerprint.unit.test.ts} +1 -1
  615. package/src/utils/dynamic/createLazyComponent.tsx +9 -1
  616. package/src/utils/dynamic/{__tests__/dynamicUtils.test.ts → dynamicUtils.test.ts} +2 -2
  617. package/src/utils/dynamic/{__tests__/lazyLoad.test.tsx → lazyLoad.test.tsx} +2 -2
  618. package/src/utils/{__tests__/dynamicUtils.unit.test.ts → dynamicUtils.unit.test.ts} +1 -1
  619. package/src/utils/file-reference/{__tests__/file-reference.test.ts → file-reference.test.ts} +214 -289
  620. package/src/utils/file-reference/index.ts +330 -347
  621. package/src/utils/{__tests__/formatDate.unit.test.ts → formatDate.unit.test.ts} +2 -2
  622. package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
  623. package/src/utils/formatting/formatNumber.test.ts +1 -1
  624. package/src/utils/{__tests__/formatting.unit.test.ts → formatting.unit.test.ts} +1 -1
  625. package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
  626. package/src/utils/google-places/googlePlacesUtils.ts +67 -99
  627. package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
  628. package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
  629. package/src/utils/{__tests__/index.unit.test.ts → index.unit.test.ts} +1 -1
  630. package/src/utils/{__tests__/lazyLoad.unit.test.tsx → lazyLoad.unit.test.tsx} +13 -14
  631. package/src/utils/location/location.test.ts +1 -1
  632. package/src/utils/{__tests__/logger.unit.test.ts → logger.unit.test.ts} +1 -1
  633. package/src/utils/{__tests__/organisationContext.unit.test.ts → organisationContext.unit.test.ts} +37 -48
  634. package/src/utils/performance/{__tests__/bundleAnalysis.test.ts → bundleAnalysis.test.ts} +2 -2
  635. package/src/utils/performance/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  636. package/src/utils/performance/{__tests__/performanceBudgets.test.ts → performanceBudgets.test.ts} +2 -2
  637. package/src/utils/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  638. package/src/utils/{__tests__/performanceBudgets.unit.test.ts → performanceBudgets.unit.test.ts} +2 -2
  639. package/src/utils/{__tests__/permissionTypes.unit.test.ts → permissionTypes.unit.test.ts} +1 -1
  640. package/src/utils/{__tests__/permissionUtils.unit.test.ts → permissionUtils.unit.test.ts} +1 -1
  641. package/src/utils/permissions/{__tests__/permissionTypes.test.ts → permissionTypes.test.ts} +2 -2
  642. package/src/utils/persistence/{__tests__/keyDerivation.test.ts → keyDerivation.test.ts} +2 -2
  643. package/src/utils/persistence/{__tests__/sensitiveFieldDetection.test.ts → sensitiveFieldDetection.test.ts} +2 -2
  644. package/src/utils/{__tests__/request-deduplication.test.ts → request-deduplication.test.ts} +2 -2
  645. package/src/utils/{__tests__/sanitization.unit.test.ts → sanitization.unit.test.ts} +1 -1
  646. package/src/utils/{__tests__/schemaUtils.unit.test.ts → schemaUtils.unit.test.ts} +1 -1
  647. package/src/utils/{__tests__/secureDataAccess.unit.test.ts → secureDataAccess.unit.test.ts} +2 -2
  648. package/src/utils/{__tests__/secureErrors.unit.test.ts → secureErrors.unit.test.ts} +4 -4
  649. package/src/utils/{__tests__/secureStorage.unit.test.ts → secureStorage.unit.test.ts} +1 -1
  650. package/src/utils/security/auth-utils.ts +34 -23
  651. package/src/utils/security/secureDataAccess.ts +241 -281
  652. package/src/utils/security/secureErrors.test.ts +1 -1
  653. package/src/utils/security/secureStorage.test.ts +1 -1
  654. package/src/utils/security/security.test.ts +25 -17
  655. package/src/utils/security/security.ts +15 -18
  656. package/src/utils/security/securityMonitor.test.ts +1 -1
  657. package/src/utils/{__tests__/security.unit.test.ts → security.unit.test.ts} +21 -15
  658. package/src/utils/{__tests__/securityMonitor.unit.test.ts → securityMonitor.unit.test.ts} +1 -1
  659. package/src/utils/{__tests__/sessionTracking.unit.test.ts → sessionTracking.unit.test.ts} +12 -12
  660. package/src/utils/storage/{__tests__/config.unit.test.ts → config.unit.test.ts} +2 -2
  661. package/src/utils/storage/helpers.test.ts +88 -102
  662. package/src/utils/storage/helpers.ts +173 -251
  663. package/src/utils/storage/{__tests__/index.unit.test.ts → index.unit.test.ts} +3 -3
  664. package/src/utils/storage/types.ts +7 -0
  665. package/src/utils/supabase/createBaseClient.test.ts +1 -1
  666. package/src/utils/timezone/timezone.test.ts +1 -1
  667. package/src/utils/{__tests__/timezone.test.ts → timezone.test.ts} +2 -2
  668. package/src/utils/validation/{__tests__/common.test.ts → common.test.ts} +2 -2
  669. package/src/utils/validation/{__tests__/csrf.test.ts → csrf.test.ts} +56 -28
  670. package/src/utils/validation/csrf.ts +42 -41
  671. package/src/utils/validation/{__tests__/htmlSanitization.unit.test.ts → htmlSanitization.unit.test.ts} +2 -2
  672. package/src/utils/validation/{__tests__/passwordSchema.test.ts → passwordSchema.test.ts} +2 -2
  673. package/src/utils/validation/{__tests__/schema.test.ts → schema.test.ts} +2 -2
  674. package/src/utils/validation/{__tests__/sqlInjectionProtection.test.ts → sqlInjectionProtection.test.ts} +2 -2
  675. package/src/utils/validation/{__tests__/user.test.ts → user.test.ts} +2 -2
  676. package/src/utils/validation/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  677. package/src/utils/validation/{__tests__/validationUtils.test.ts → validationUtils.test.ts} +2 -2
  678. package/src/utils/{__tests__/validation.unit.test.ts → validation.unit.test.ts} +1 -1
  679. package/src/utils/{__tests__/validationUtils.unit.test.ts → validationUtils.unit.test.ts} +5 -2
  680. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
  681. package/dist/chunk-KPYQWGFQ.js +0 -183
  682. package/dist/types-D05dCGma.d.ts +0 -521
  683. package/scripts/eslint-audit.cjs +0 -222
  684. package/scripts/generate-docs.js +0 -157
  685. package/scripts/install-cursor-rules.cjs +0 -255
  686. package/scripts/install-eslint-config.cjs +0 -349
  687. package/scripts/setup-build-cache.js +0 -73
  688. package/scripts/validate-pre-publish.js +0 -145
  689. package/src/__tests__/integration/UserProfile.test.tsx +0 -124
  690. package/src/__tests__/public-recipe-view.test.ts +0 -228
  691. package/src/__tests__/rls-policies.test.ts +0 -472
  692. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
  693. package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
  694. package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
  695. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
  696. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
  697. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
  698. package/src/components/DataTable/core/ActionManager.ts +0 -235
  699. package/src/components/DataTable/core/ColumnManager.ts +0 -204
  700. package/src/components/DataTable/core/DataManager.ts +0 -190
  701. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
  702. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  703. package/src/components/DataTable/core/StateManager.ts +0 -312
  704. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
  705. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
  706. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
  707. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
  708. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
  709. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
  710. package/src/components/DataTable/core/interfaces.ts +0 -338
  711. package/src/components/DataTable/types.ts +0 -764
  712. package/src/hooks/public/usePublicFileDisplay.ts +0 -534
  713. package/src/hooks/useFileDisplay.ts +0 -748
  714. package/src/providers/OrganisationProvider.test.tsx +0 -40
  715. package/src/providers/OrganisationProvider.tsx +0 -92
  716. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
  717. package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
  718. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
  719. package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
  720. /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
  721. /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
  722. /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
  723. /package/src/providers/{__tests__/README.md → README.md} +0 -0
  724. /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
  725. /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
  726. /package/src/types/{__tests__/README.md → README.md} +0 -0
@@ -14,19 +14,19 @@
14
14
 
15
15
  import { renderHook, waitFor } from '@testing-library/react';
16
16
  import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
17
- import { useMultiplePermissions } from '../useMultiplePermissions';
17
+ import { useMultiplePermissions } from './useMultiplePermissions';
18
18
 
19
19
  // Following testing standards: use timeout parameter to prevent hanging
20
20
  const TEST_TIMEOUT = 10000; // 10 seconds per test
21
21
  const WAIT_FOR_TIMEOUT = 5000; // 5 seconds for waitFor calls
22
22
 
23
23
  // Mock the RBAC API
24
- vi.mock('../../../api', () => ({
24
+ vi.mock('../../api', () => ({
25
25
  isPermitted: vi.fn(),
26
26
  isPermittedCached: vi.fn(),
27
27
  }));
28
28
 
29
- import { isPermitted, isPermittedCached } from '../../../api';
29
+ import { isPermitted, isPermittedCached } from '../../api';
30
30
 
31
31
  const mockUserId = 'user-123';
32
32
  const mockScope = {
@@ -45,9 +45,9 @@ describe('useMultiplePermissions Hook', () => {
45
45
  // Reset mock implementations to ensure clean state
46
46
  mockIsPermitted.mockReset();
47
47
  mockIsPermittedCached.mockReset();
48
- // Set default implementations (will be overridden by mockResolvedValueOnce in tests)
49
- mockIsPermitted.mockResolvedValue(true);
50
- mockIsPermittedCached.mockResolvedValue(true);
48
+ // Set default implementations (ApiResult shape; will be overridden by mockResolvedValueOnce in tests)
49
+ mockIsPermitted.mockResolvedValue({ ok: true, data: true });
50
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
51
51
  });
52
52
 
53
53
  afterEach(() => {
@@ -57,9 +57,9 @@ describe('useMultiplePermissions Hook', () => {
57
57
  describe('Permission Checking', () => {
58
58
  it('checks multiple permissions successfully', async () => {
59
59
  mockIsPermittedCached
60
- .mockResolvedValueOnce(true) // read:users
61
- .mockResolvedValueOnce(true) // create:users
62
- .mockResolvedValueOnce(false); // update:users
60
+ .mockResolvedValueOnce({ ok: true, data: true }) // read:users
61
+ .mockResolvedValueOnce({ ok: true, data: true }) // create:users
62
+ .mockResolvedValueOnce({ ok: true, data: false }); // update:users
63
63
 
64
64
  const { result } = renderHook(() =>
65
65
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -87,10 +87,10 @@ describe('useMultiplePermissions Hook', () => {
87
87
  const currentCall = callCount++;
88
88
  // Return specific values for first 3 calls (one per permission)
89
89
  // After that, return true to prevent hanging if hook re-runs
90
- if (currentCall === 0) return true; // read:users
91
- if (currentCall === 1) return false; // create:users
92
- if (currentCall === 2) return true; // update:users
93
- return true; // Default for any additional calls
90
+ if (currentCall === 0) return { ok: true, data: true }; // read:users
91
+ if (currentCall === 1) return { ok: true, data: false }; // create:users
92
+ if (currentCall === 2) return { ok: true, data: true }; // update:users
93
+ return { ok: true, data: true }; // Default for any additional calls
94
94
  });
95
95
 
96
96
  const { result } = renderHook(() =>
@@ -127,7 +127,7 @@ describe('useMultiplePermissions Hook', () => {
127
127
  }, TEST_TIMEOUT);
128
128
 
129
129
  it('handles single permission', async () => {
130
- mockIsPermittedCached.mockResolvedValue(true);
130
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
131
131
 
132
132
  const { result } = renderHook(() =>
133
133
  useMultiplePermissions(mockUserId, mockScope, ['read:users'])
@@ -143,7 +143,7 @@ describe('useMultiplePermissions Hook', () => {
143
143
 
144
144
  it('handles large permission arrays', async () => {
145
145
  const largePermissions = Array.from({ length: 10 }, (_, i) => `permission:${i}` as const);
146
- mockIsPermittedCached.mockResolvedValue(true);
146
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
147
147
 
148
148
  const { result } = renderHook(() =>
149
149
  useMultiplePermissions(mockUserId, mockScope, largePermissions)
@@ -162,7 +162,7 @@ describe('useMultiplePermissions Hook', () => {
162
162
 
163
163
  describe('Caching Behavior', () => {
164
164
  it('uses cached permissions by default', async () => {
165
- mockIsPermittedCached.mockResolvedValue(true);
165
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
166
166
 
167
167
  const { result } = renderHook(() =>
168
168
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -177,7 +177,7 @@ describe('useMultiplePermissions Hook', () => {
177
177
  }, TEST_TIMEOUT);
178
178
 
179
179
  it('bypasses cache when useCache is false', async () => {
180
- mockIsPermitted.mockResolvedValue(true);
180
+ mockIsPermitted.mockResolvedValue({ ok: true, data: true });
181
181
 
182
182
  const { result } = renderHook(() =>
183
183
  useMultiplePermissions(mockUserId, mockScope, mockPermissions, false)
@@ -192,7 +192,7 @@ describe('useMultiplePermissions Hook', () => {
192
192
  }, TEST_TIMEOUT);
193
193
 
194
194
  it('calls permission checks with correct parameters', async () => {
195
- mockIsPermittedCached.mockResolvedValue(true);
195
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
196
196
 
197
197
  const { result } = renderHook(() =>
198
198
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -223,12 +223,12 @@ describe('useMultiplePermissions Hook', () => {
223
223
  describe('Refetch Functionality', () => {
224
224
  it('refetches permissions when refetch is called', async () => {
225
225
  mockIsPermittedCached
226
- .mockResolvedValueOnce(true)
227
- .mockResolvedValueOnce(true)
228
- .mockResolvedValueOnce(false)
229
- .mockResolvedValueOnce(true)
230
- .mockResolvedValueOnce(true)
231
- .mockResolvedValueOnce(true);
226
+ .mockResolvedValueOnce({ ok: true, data: true })
227
+ .mockResolvedValueOnce({ ok: true, data: true })
228
+ .mockResolvedValueOnce({ ok: true, data: false })
229
+ .mockResolvedValueOnce({ ok: true, data: true })
230
+ .mockResolvedValueOnce({ ok: true, data: true })
231
+ .mockResolvedValueOnce({ ok: true, data: true });
232
232
 
233
233
  const { result } = renderHook(() =>
234
234
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -249,7 +249,7 @@ describe('useMultiplePermissions Hook', () => {
249
249
  }, TEST_TIMEOUT);
250
250
 
251
251
  it('refetches when scope changes', async () => {
252
- mockIsPermittedCached.mockResolvedValue(true);
252
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
253
253
 
254
254
  const { result, rerender } = renderHook(
255
255
  ({ userId, scope, permissions }) =>
@@ -280,7 +280,7 @@ describe('useMultiplePermissions Hook', () => {
280
280
  }, TEST_TIMEOUT);
281
281
 
282
282
  it('refetches when permissions array changes', async () => {
283
- mockIsPermittedCached.mockResolvedValue(true);
283
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
284
284
 
285
285
  const { result, rerender } = renderHook(
286
286
  ({ userId, scope, permissions }) =>
@@ -313,7 +313,7 @@ describe('useMultiplePermissions Hook', () => {
313
313
  }, TEST_TIMEOUT);
314
314
 
315
315
  it('refetches when userId changes', async () => {
316
- mockIsPermittedCached.mockResolvedValue(true);
316
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
317
317
 
318
318
  const { result, rerender } = renderHook(
319
319
  ({ userId, scope, permissions }) =>
@@ -361,9 +361,9 @@ describe('useMultiplePermissions Hook', () => {
361
361
 
362
362
  it('handles partial failures during permission checks', async () => {
363
363
  mockIsPermittedCached
364
- .mockResolvedValueOnce(true)
364
+ .mockResolvedValueOnce({ ok: true, data: true })
365
365
  .mockRejectedValueOnce(new Error('Check failed'))
366
- .mockResolvedValueOnce(false);
366
+ .mockResolvedValueOnce({ ok: true, data: false });
367
367
 
368
368
  const { result } = renderHook(() =>
369
369
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -444,7 +444,7 @@ describe('useMultiplePermissions Hook', () => {
444
444
  });
445
445
 
446
446
  it('handles empty scope', async () => {
447
- mockIsPermittedCached.mockResolvedValue(true);
447
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
448
448
  const emptyScope = {};
449
449
 
450
450
  const { result } = renderHook(() =>
@@ -463,7 +463,7 @@ describe('useMultiplePermissions Hook', () => {
463
463
  }, TEST_TIMEOUT);
464
464
 
465
465
  it('handles scope with partial values', async () => {
466
- mockIsPermittedCached.mockResolvedValue(true);
466
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
467
467
  const partialScope = { organisationId: 'org-123' };
468
468
 
469
469
  const { result } = renderHook(() =>
@@ -476,7 +476,7 @@ describe('useMultiplePermissions Hook', () => {
476
476
  });
477
477
 
478
478
  it('handles duplicate permissions in array', async () => {
479
- mockIsPermittedCached.mockResolvedValue(true);
479
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
480
480
  const duplicatePermissions = ['read:users', 'read:users', 'create:users'] as const;
481
481
 
482
482
  const { result } = renderHook(() =>
@@ -492,7 +492,7 @@ describe('useMultiplePermissions Hook', () => {
492
492
  }, TEST_TIMEOUT);
493
493
 
494
494
  it('handles rapid refetch calls', async () => {
495
- mockIsPermittedCached.mockResolvedValue(true);
495
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
496
496
 
497
497
  const { result } = renderHook(() =>
498
498
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -516,7 +516,7 @@ describe('useMultiplePermissions Hook', () => {
516
516
 
517
517
  describe('Performance', () => {
518
518
  it('maintains stable references for same inputs', async () => {
519
- mockIsPermittedCached.mockResolvedValue(true);
519
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
520
520
 
521
521
  const { result, rerender } = renderHook(
522
522
  ({ userId, scope, permissions }) =>
@@ -551,7 +551,7 @@ describe('useMultiplePermissions Hook', () => {
551
551
  }, TEST_TIMEOUT);
552
552
 
553
553
  it('handles concurrent permission checks efficiently', async () => {
554
- mockIsPermittedCached.mockResolvedValue(true);
554
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
555
555
 
556
556
  const { result } = renderHook(() =>
557
557
  useMultiplePermissions(mockUserId, mockScope, mockPermissions)
@@ -583,7 +583,7 @@ describe('useMultiplePermissions Hook', () => {
583
583
  }, TEST_TIMEOUT);
584
584
 
585
585
  it('handles single permission array', async () => {
586
- mockIsPermittedCached.mockResolvedValue(true);
586
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
587
587
 
588
588
  const { result } = renderHook(() =>
589
589
  useMultiplePermissions(mockUserId, mockScope, ['read:users'] as any)
@@ -597,7 +597,7 @@ describe('useMultiplePermissions Hook', () => {
597
597
 
598
598
  it('handles very large permission arrays', async () => {
599
599
  const largePermissions = Array.from({ length: 100 }, (_, i) => `permission:${i}` as any);
600
- mockIsPermittedCached.mockResolvedValue(true);
600
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
601
601
 
602
602
  const { result } = renderHook(() =>
603
603
  useMultiplePermissions(mockUserId, mockScope, largePermissions)
@@ -614,7 +614,7 @@ describe('useMultiplePermissions Hook', () => {
614
614
  mockIsPermittedCached.mockImplementation(() => {
615
615
  const currentCall = callCount++;
616
616
  // Return true for even indices, false for odd
617
- return Promise.resolve(currentCall % 2 === 0);
617
+ return Promise.resolve({ ok: true, data: currentCall % 2 === 0 });
618
618
  });
619
619
 
620
620
  const { result } = renderHook(() =>
@@ -631,9 +631,9 @@ describe('useMultiplePermissions Hook', () => {
631
631
 
632
632
  it('handles permission check error for one permission', async () => {
633
633
  mockIsPermittedCached
634
- .mockResolvedValueOnce(true)
634
+ .mockResolvedValueOnce({ ok: true, data: true })
635
635
  .mockRejectedValueOnce(new Error('Permission check failed'))
636
- .mockResolvedValueOnce(true);
636
+ .mockResolvedValueOnce({ ok: true, data: true });
637
637
 
638
638
  const { result } = renderHook(() =>
639
639
  useMultiplePermissions(mockUserId, mockScope, ['read:users', 'create:users', 'update:users'] as any)
@@ -647,7 +647,7 @@ describe('useMultiplePermissions Hook', () => {
647
647
  }, TEST_TIMEOUT);
648
648
 
649
649
  it('handles rapid permission array changes', async () => {
650
- mockIsPermittedCached.mockResolvedValue(true);
650
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
651
651
 
652
652
  const { result, rerender } = renderHook(
653
653
  ({ permissions }) => useMultiplePermissions(mockUserId, mockScope, permissions),
@@ -686,7 +686,7 @@ describe('useMultiplePermissions Hook', () => {
686
686
  }, TEST_TIMEOUT);
687
687
 
688
688
  it('handles useCache=true correctly', async () => {
689
- mockIsPermittedCached.mockResolvedValue(true);
689
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
690
690
 
691
691
  const { result } = renderHook(() =>
692
692
  useMultiplePermissions(mockUserId, mockScope, mockPermissions, true) // useCache = true
@@ -701,7 +701,7 @@ describe('useMultiplePermissions Hook', () => {
701
701
  }, TEST_TIMEOUT);
702
702
 
703
703
  it('handles scope changes correctly', async () => {
704
- mockIsPermittedCached.mockResolvedValue(true);
704
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
705
705
 
706
706
  const { result, rerender } = renderHook(
707
707
  ({ scope }) => useMultiplePermissions(mockUserId, scope, mockPermissions),
@@ -725,7 +725,7 @@ describe('useMultiplePermissions Hook', () => {
725
725
  }, TEST_TIMEOUT);
726
726
 
727
727
  it('handles userId changes correctly', async () => {
728
- mockIsPermittedCached.mockResolvedValue(true);
728
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
729
729
 
730
730
  const { result, rerender } = renderHook(
731
731
  ({ userId }) => useMultiplePermissions(userId, mockScope, mockPermissions),
@@ -761,8 +761,8 @@ describe('useMultiplePermissions Hook', () => {
761
761
 
762
762
  it('handles refetch correctly', async () => {
763
763
  mockIsPermittedCached
764
- .mockResolvedValueOnce(true)
765
- .mockResolvedValueOnce(false);
764
+ .mockResolvedValueOnce({ ok: true, data: true })
765
+ .mockResolvedValueOnce({ ok: true, data: false });
766
766
 
767
767
  const { result } = renderHook(() =>
768
768
  useMultiplePermissions(mockUserId, mockScope, ['read:users'] as any)
@@ -783,7 +783,7 @@ describe('useMultiplePermissions Hook', () => {
783
783
 
784
784
  it('handles refetch error gracefully', async () => {
785
785
  mockIsPermittedCached
786
- .mockResolvedValueOnce(true)
786
+ .mockResolvedValueOnce({ ok: true, data: true })
787
787
  .mockRejectedValueOnce(new Error('Refetch error'));
788
788
 
789
789
  const { result } = renderHook(() =>
@@ -808,7 +808,7 @@ describe('useMultiplePermissions Hook', () => {
808
808
  let checkCount = 0;
809
809
  mockIsPermittedCached.mockImplementation(() => {
810
810
  checkCount++;
811
- return new Promise((resolve) => setTimeout(() => resolve(true), 100));
811
+ return new Promise((resolve) => setTimeout(() => resolve({ ok: true, data: true }), 100));
812
812
  });
813
813
 
814
814
  const { rerender } = renderHook(
@@ -827,7 +827,7 @@ describe('useMultiplePermissions Hook', () => {
827
827
  }, TEST_TIMEOUT);
828
828
 
829
829
  it('handles permission array with duplicate permissions', async () => {
830
- mockIsPermittedCached.mockResolvedValue(true);
830
+ mockIsPermittedCached.mockResolvedValue({ ok: true, data: true });
831
831
 
832
832
  const { result } = renderHook(() =>
833
833
  useMultiplePermissions(mockUserId, mockScope, ['read:users', 'read:users', 'read:users'] as any)
@@ -88,12 +88,16 @@ export function useMultiplePermissions(
88
88
 
89
89
  const permissionResults: Record<Permission, boolean> = {} as Record<Permission, boolean>;
90
90
 
91
- // Check each permission
92
91
  for (const permission of permissions) {
93
92
  const result = useCache
94
93
  ? await isPermittedCached({ userId, scope, permission })
95
94
  : await isPermitted({ userId, scope, permission });
96
- permissionResults[permission] = result;
95
+ if (!result.ok) {
96
+ setError(new Error(result.error.message));
97
+ setResults({} as Record<Permission, boolean>);
98
+ return;
99
+ }
100
+ permissionResults[permission] = result.data;
97
101
  }
98
102
 
99
103
  setResults(permissionResults);
@@ -24,7 +24,7 @@ const WAIT_FOR_TIMEOUT = 5000; // 5 seconds for waitFor calls
24
24
  const renderedHooks: Array<() => void> = [];
25
25
 
26
26
  // Mock the RBAC API
27
- vi.mock('../../../api', () => ({
27
+ vi.mock('../../api', () => ({
28
28
  getPermissionMap: vi.fn(),
29
29
  }));
30
30
 
@@ -36,11 +36,11 @@ const mockLogger = {
36
36
  debug: vi.fn(),
37
37
  };
38
38
 
39
- vi.mock('../../../config', () => ({
39
+ vi.mock('../../config', () => ({
40
40
  getRBACLogger: vi.fn(() => mockLogger), // Return same instance every time
41
41
  }));
42
42
 
43
- import { getPermissionMap } from '../../../api';
43
+ import { getPermissionMap } from '../../api';
44
44
 
45
45
  const mockUserId = 'user-123';
46
46
  const mockOrganisationId = 'org-123';
@@ -55,9 +55,7 @@ const mockPermissionMap = {
55
55
  } as const;
56
56
 
57
57
  // Helper to track and cleanup hooks
58
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
58
  function renderHookWithCleanup(callback: any, options?: any): any {
60
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
59
  const hook = renderHook(callback, options);
62
60
  renderedHooks.push(hook.unmount);
63
61
  return hook;
@@ -74,7 +72,7 @@ describe('usePermissions Hook', () => {
74
72
  mockLogger.info.mockClear();
75
73
  mockLogger.debug.mockClear();
76
74
  vi.useRealTimers(); // Use real timers for tests
77
- mockGetPermissionMap.mockResolvedValue(mockPermissionMap);
75
+ mockGetPermissionMap.mockResolvedValue({ ok: true, data: mockPermissionMap });
78
76
  });
79
77
 
80
78
  afterEach(() => {
@@ -123,7 +121,7 @@ describe('usePermissions Hook', () => {
123
121
 
124
122
  it('handles empty permission map', async () => {
125
123
  const emptyMap = {};
126
- mockGetPermissionMap.mockResolvedValue(emptyMap as any);
124
+ mockGetPermissionMap.mockResolvedValue({ ok: true, data: emptyMap });
127
125
 
128
126
  const { result } = renderHookWithCleanup(() =>
129
127
  usePermissions(mockUserId, mockOrganisationId, mockEventId, mockAppId)
@@ -299,7 +297,7 @@ describe('usePermissions Hook', () => {
299
297
  describe('Wildcard Permissions', () => {
300
298
  it('hasPermission returns true when wildcard permission exists', async () => {
301
299
  const wildcardMap = { '*': true };
302
- mockGetPermissionMap.mockResolvedValue(wildcardMap as any);
300
+ mockGetPermissionMap.mockResolvedValue({ ok: true, data: wildcardMap } as any);
303
301
 
304
302
  const { result } = renderHookWithCleanup(() =>
305
303
  usePermissions(mockUserId, mockOrganisationId, mockEventId, mockAppId)
@@ -314,7 +312,7 @@ describe('usePermissions Hook', () => {
314
312
 
315
313
  it('hasAnyPermission returns true when wildcard permission exists', async () => {
316
314
  const wildcardMap = { '*': true };
317
- mockGetPermissionMap.mockResolvedValue(wildcardMap as any);
315
+ mockGetPermissionMap.mockResolvedValue({ ok: true, data: wildcardMap } as any);
318
316
 
319
317
  const { result } = renderHookWithCleanup(() =>
320
318
  usePermissions(mockUserId, mockOrganisationId, mockEventId, mockAppId)
@@ -331,7 +329,7 @@ describe('usePermissions Hook', () => {
331
329
 
332
330
  it('hasAllPermissions returns true when wildcard permission exists', async () => {
333
331
  const wildcardMap = { '*': true };
334
- mockGetPermissionMap.mockResolvedValue(wildcardMap as any);
332
+ mockGetPermissionMap.mockResolvedValue({ ok: true, data: wildcardMap } as any);
335
333
 
336
334
  const { result } = renderHookWithCleanup(() =>
337
335
  usePermissions(mockUserId, mockOrganisationId, mockEventId, mockAppId)
@@ -354,8 +352,8 @@ describe('usePermissions Hook', () => {
354
352
  'update:users': true,
355
353
  };
356
354
  mockGetPermissionMap
357
- .mockResolvedValueOnce(mockPermissionMap)
358
- .mockResolvedValueOnce(updatedMap as any);
355
+ .mockResolvedValueOnce({ ok: true, data: mockPermissionMap })
356
+ .mockResolvedValueOnce({ ok: true, data: updatedMap } as any);
359
357
 
360
358
  const { result } = renderHookWithCleanup(() =>
361
359
  usePermissions(mockUserId, mockOrganisationId, mockEventId, mockAppId)
@@ -1,8 +1,9 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
- import { Permission, PermissionMap, Scope, UUID } from '../../types';
4
- import { getPermissionMap } from '../../api';
3
+ import { PermissionMap, Scope, UUID } from '../../types';
5
4
  import { getRBACLogger } from '../../config';
5
+ import { createPermissionMapHelpers } from '../../utils/permissionMapHelpers';
6
+ import { fetchPermissionMapForScope } from '../../utils/fetchPermissionMap';
6
7
 
7
8
  /**
8
9
  * Hook to get user's permissions in a scope
@@ -110,17 +111,7 @@ export function usePermissions(
110
111
  return;
111
112
  }
112
113
 
113
- // Don't fetch permissions if scope is invalid (e.g., organisationId is null/empty)
114
- // Wait for organisation context to resolve
115
- // IMPORTANT: Don't clear existing permissions here - keep them until we have new ones
116
- // OPTIMIZATION: If userId is null/undefined, immediately set loading to false
117
- // This indicates pre-filtered mode where we don't need to wait for organisation context
118
- if (!userId) {
119
- setPermissions({} as PermissionMap);
120
- setIsLoading(false);
121
- return;
122
- }
123
-
114
+ // Don't fetch if scope is invalid; wait for organisation context
124
115
  if (!orgId || orgId === null || (typeof orgId === 'string' && orgId.trim() === '')) {
125
116
  // Keep existing permissions, just mark as loading
126
117
  setIsLoading(true);
@@ -133,19 +124,22 @@ export function usePermissions(
133
124
  setIsLoading(true);
134
125
  setError(null);
135
126
 
136
- // Build scope object for API call
137
127
  const scope: Scope = {
138
128
  organisationId: orgId,
139
129
  eventId: eventId,
140
130
  appId: appId
141
131
  };
142
132
 
143
- // Fetch new permissions - don't clear old ones until we have new ones
144
- const permissionMap = await getPermissionMap({ userId, scope });
133
+ const result = await fetchPermissionMapForScope({ userId, scope });
134
+ if (!result.ok) {
135
+ setError(new Error(result.error.message));
136
+ setIsLoading(false);
137
+ isFetchingRef.current = false;
138
+ return;
139
+ }
140
+ const permissionMap = result.data;
145
141
 
146
- // Only log if there's a significant change or error
147
142
  const permissionCount = Object.keys(permissionMap).length;
148
- // Use a ref to track previous permissions count to avoid dependency on permissions state
149
143
  setPermissions(prevPermissions => {
150
144
  if (permissionCount === 0 && Object.keys(prevPermissions).length > 0) {
151
145
  logger.warn('[usePermissions] Permissions fetched but returned empty map', {
@@ -155,11 +149,8 @@ export function usePermissions(
155
149
  return permissionMap;
156
150
  });
157
151
  } catch (err) {
158
- // On error, keep existing permissions but set error state
159
- // This prevents the UI from losing all items when there's a transient error
160
152
  logger.error('[usePermissions] Failed to fetch permissions:', err);
161
153
  setError(err instanceof Error ? err : new Error('Failed to fetch permissions'));
162
- // Don't clear permissions on error - keep what we had
163
154
  } finally {
164
155
  setIsLoading(false);
165
156
  isFetchingRef.current = false;
@@ -169,29 +160,12 @@ export function usePermissions(
169
160
  fetchPermissions();
170
161
  }, [fetchTrigger, userId, organisationId, eventId, appId, logger, orgId]);
171
162
 
172
- const hasPermission = useCallback((permission: Permission): boolean => {
173
- if (permissions['*']) {
174
- return true;
175
- }
176
- return permissions[permission] === true;
177
- }, [permissions]);
178
-
179
- const hasAnyPermission = useCallback((permissionList: Permission[]): boolean => {
180
- if (permissions['*']) {
181
- return true;
182
- }
183
- return permissionList.some(p => permissions[p] === true);
184
- }, [permissions]);
185
-
186
- const hasAllPermissions = useCallback((permissionList: Permission[]): boolean => {
187
- if (permissions['*']) {
188
- return true;
189
- }
190
- return permissionList.every(p => permissions[p] === true);
191
- }, [permissions]);
163
+ const { hasPermission, hasAnyPermission, hasAllPermissions } = useMemo(
164
+ () => createPermissionMapHelpers(permissions),
165
+ [permissions]
166
+ );
192
167
 
193
168
  const refetch = useCallback(async () => {
194
- // Prevent multiple simultaneous fetches
195
169
  if (isFetchingRef.current) {
196
170
  return;
197
171
  }
@@ -202,10 +176,7 @@ export function usePermissions(
202
176
  return;
203
177
  }
204
178
 
205
- // Don't fetch permissions if scope is invalid (e.g., organisationId is null/empty)
206
- // IMPORTANT: Don't clear existing permissions - keep them until we have new ones
207
179
  if (!orgId || orgId === null || (typeof orgId === 'string' && orgId.trim() === '')) {
208
- // Keep existing permissions, just mark as loading
209
180
  setIsLoading(true);
210
181
  setError(null);
211
182
  return;
@@ -216,25 +187,22 @@ export function usePermissions(
216
187
  setIsLoading(true);
217
188
  setError(null);
218
189
 
219
- // Build scope object for API call
220
190
  const scope: Scope = {
221
191
  organisationId: orgId,
222
192
  eventId: eventId,
223
193
  appId: appId
224
194
  };
225
195
 
226
- // Fetch new permissions - don't clear old ones until we have new ones
227
- const permissionMap = await getPermissionMap({ userId, scope });
228
-
229
- // Only update permissions if fetch was successful
230
- setPermissions(permissionMap);
196
+ const result = await fetchPermissionMapForScope({ userId, scope });
197
+ if (!result.ok) {
198
+ setError(new Error(result.error.message));
199
+ return;
200
+ }
201
+ setPermissions(result.data);
231
202
  } catch (err) {
232
- // On error, keep existing permissions but set error state
233
- // This prevents the UI from losing all items when there's a transient error
234
- const logger = getRBACLogger();
235
- logger.error('Failed to refetch permissions:', err);
203
+ const refetchLogger = getRBACLogger();
204
+ refetchLogger.error('Failed to refetch permissions:', err);
236
205
  setError(err instanceof Error ? err : new Error('Failed to fetch permissions'));
237
- // Don't clear permissions on error - keep what we had
238
206
  } finally {
239
207
  setIsLoading(false);
240
208
  isFetchingRef.current = false;
@@ -242,13 +210,16 @@ export function usePermissions(
242
210
  }, [userId, eventId, appId, orgId]);
243
211
 
244
212
  // Memoize the return object to prevent unnecessary re-renders
245
- return useMemo(() => ({
246
- permissions,
247
- isLoading,
248
- error,
249
- hasPermission,
250
- hasAnyPermission,
251
- hasAllPermissions,
252
- refetch
253
- }), [permissions, isLoading, error, hasPermission, hasAnyPermission, hasAllPermissions, refetch]);
213
+ return useMemo(
214
+ () => ({
215
+ permissions,
216
+ isLoading,
217
+ error,
218
+ hasPermission,
219
+ hasAnyPermission,
220
+ hasAllPermissions,
221
+ refetch
222
+ }),
223
+ [permissions, isLoading, error, hasPermission, hasAnyPermission, hasAllPermissions, refetch]
224
+ );
254
225
  }