@jmruthers/pace-core 0.5.76 → 0.5.78

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 (447) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
  3. package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
  4. package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
  5. package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
  6. package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
  7. package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
  8. package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
  9. package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
  10. package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
  11. package/dist/chunk-2OGV6IRV.js.map +1 -0
  12. package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
  13. package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
  14. package/dist/chunk-CVMVPYAL.js.map +1 -0
  15. package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
  16. package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
  17. package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
  18. package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
  19. package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
  20. package/dist/chunk-LRQ6RBJC.js.map +1 -0
  21. package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
  22. package/dist/chunk-MNJXXD6C.js.map +1 -0
  23. package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
  24. package/dist/chunk-PTR5PMPE.js.map +1 -0
  25. package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
  26. package/dist/chunk-Q7APDV6H.js.map +1 -0
  27. package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
  28. package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
  29. package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
  30. package/dist/chunk-S63MFSY6.js.map +1 -0
  31. package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
  32. package/dist/chunk-WUXCWRL6.js +20 -0
  33. package/dist/chunk-WUXCWRL6.js.map +1 -0
  34. package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
  35. package/dist/chunk-YVVGHRGI.js.map +1 -0
  36. package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
  37. package/dist/chunk-ZMNXIJP4.js.map +1 -0
  38. package/dist/components.d.ts +6 -6
  39. package/dist/components.js +14 -18
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
  42. package/dist/hooks.d.ts +5 -5
  43. package/dist/hooks.js +8 -9
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +19 -27
  46. package/dist/index.js +21 -29
  47. package/dist/index.js.map +1 -1
  48. package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
  49. package/dist/providers.d.ts +7 -21
  50. package/dist/providers.js +3 -10
  51. package/dist/rbac/index.d.ts +71 -221
  52. package/dist/rbac/index.js +15 -16
  53. package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +61 -18
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
  58. package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
  59. package/dist/utils.d.ts +2 -2
  60. package/dist/utils.js +52 -9
  61. package/dist/utils.js.map +1 -1
  62. package/docs/CONTENT_AUDIT_REPORT.md +253 -0
  63. package/docs/DOCUMENTATION_AUDIT.md +172 -0
  64. package/docs/README.md +142 -147
  65. package/docs/STYLE_GUIDE.md +37 -0
  66. package/docs/api/classes/ColumnFactory.md +17 -17
  67. package/docs/api/classes/ErrorBoundary.md +1 -1
  68. package/docs/api/classes/InvalidScopeError.md +4 -4
  69. package/docs/api/classes/MissingUserContextError.md +4 -4
  70. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  71. package/docs/api/classes/PermissionDeniedError.md +5 -5
  72. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  73. package/docs/api/classes/RBACAuditManager.md +8 -8
  74. package/docs/api/classes/RBACCache.md +35 -5
  75. package/docs/api/classes/RBACEngine.md +49 -20
  76. package/docs/api/classes/RBACError.md +4 -4
  77. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  78. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  79. package/docs/api/classes/StorageUtils.md +1 -1
  80. package/docs/api/enums/FileCategory.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +4 -4
  82. package/docs/api/interfaces/ButtonProps.md +1 -1
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +11 -0
  88. package/docs/api/interfaces/DataTableAction.md +65 -29
  89. package/docs/api/interfaces/DataTableColumn.md +36 -23
  90. package/docs/api/interfaces/DataTableProps.md +80 -38
  91. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  92. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  93. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  94. package/docs/api/interfaces/EventLogoProps.md +1 -1
  95. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  96. package/docs/api/interfaces/FileMetadata.md +1 -1
  97. package/docs/api/interfaces/FileReference.md +1 -1
  98. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  99. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
  107. package/docs/api/interfaces/NavigationContextType.md +9 -9
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACLogger.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  134. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  135. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  136. package/docs/api/interfaces/RouteConfig.md +2 -2
  137. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  138. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  139. package/docs/api/interfaces/StorageConfig.md +1 -1
  140. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  141. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  142. package/docs/api/interfaces/StorageListOptions.md +1 -1
  143. package/docs/api/interfaces/StorageListResult.md +1 -1
  144. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  145. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  146. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  147. package/docs/api/interfaces/StyleImport.md +1 -1
  148. package/docs/api/interfaces/SwitchProps.md +1 -1
  149. package/docs/api/interfaces/ToastActionElement.md +1 -1
  150. package/docs/api/interfaces/ToastProps.md +1 -1
  151. package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
  152. package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
  153. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  159. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  160. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  161. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  162. package/docs/api/interfaces/UserEventAccess.md +11 -11
  163. package/docs/api/interfaces/UserMenuProps.md +1 -1
  164. package/docs/api/interfaces/UserProfile.md +1 -1
  165. package/docs/api/modules.md +251 -269
  166. package/docs/api-reference/components.md +193 -0
  167. package/docs/api-reference/hooks.md +265 -0
  168. package/docs/api-reference/providers.md +6 -0
  169. package/docs/api-reference/types.md +6 -0
  170. package/docs/api-reference/utilities.md +207 -0
  171. package/docs/architecture/README.md +6 -0
  172. package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
  173. package/docs/architecture/rbac-security-architecture.md +258 -0
  174. package/docs/architecture/services.md +9 -1
  175. package/docs/best-practices/README.md +6 -0
  176. package/docs/best-practices/accessibility.md +6 -0
  177. package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
  178. package/docs/best-practices/deployment.md +6 -0
  179. package/docs/best-practices/performance.md +475 -2
  180. package/docs/best-practices/security.md +6 -0
  181. package/docs/best-practices/testing.md +6 -0
  182. package/docs/core-concepts/authentication.md +6 -0
  183. package/docs/core-concepts/events.md +6 -0
  184. package/docs/core-concepts/organisations.md +6 -0
  185. package/docs/core-concepts/permissions.md +6 -0
  186. package/docs/core-concepts/rbac-system.md +8 -0
  187. package/docs/documentation-index.md +121 -182
  188. package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
  189. package/docs/getting-started/documentation-index.md +40 -0
  190. package/docs/getting-started/examples/README.md +878 -35
  191. package/docs/{faq.md → getting-started/faq.md} +7 -1
  192. package/docs/getting-started/installation-guide.md +6 -0
  193. package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
  194. package/docs/implementation-guides/app-layout.md +6 -0
  195. package/docs/implementation-guides/authentication.md +1021 -0
  196. package/docs/implementation-guides/component-styling.md +6 -0
  197. package/docs/implementation-guides/data-tables.md +1264 -2076
  198. package/docs/implementation-guides/dynamic-colors.md +6 -0
  199. package/docs/implementation-guides/event-theming-summary.md +6 -0
  200. package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
  201. package/docs/implementation-guides/file-upload-storage.md +6 -0
  202. package/docs/implementation-guides/forms.md +6 -0
  203. package/docs/implementation-guides/inactivity-tracking.md +6 -0
  204. package/docs/implementation-guides/navigation.md +6 -0
  205. package/docs/implementation-guides/organisation-security.md +6 -0
  206. package/docs/implementation-guides/permission-enforcement.md +6 -0
  207. package/docs/implementation-guides/public-pages-advanced.md +6 -0
  208. package/docs/implementation-guides/public-pages.md +6 -0
  209. package/docs/migration/MIGRATION_GUIDE.md +827 -351
  210. package/docs/migration/README.md +7 -1
  211. package/docs/migration/organisation-context-timing-fix.md +6 -0
  212. package/docs/migration/rbac-migration.md +44 -1
  213. package/docs/migration/service-architecture.md +6 -0
  214. package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
  215. package/docs/migration/v0.4.16-css-first-approach.md +6 -0
  216. package/docs/migration/v0.4.17-source-path-fix.md +6 -0
  217. package/docs/rbac/README-rbac-rls-integration.md +6 -0
  218. package/docs/rbac/README.md +6 -0
  219. package/docs/rbac/advanced-patterns.md +6 -0
  220. package/docs/rbac/api-reference.md +7 -1
  221. package/docs/rbac/breaking-changes-v3.md +222 -0
  222. package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
  223. package/docs/rbac/examples.md +6 -0
  224. package/docs/rbac/getting-started.md +6 -0
  225. package/docs/rbac/migration-guide.md +260 -0
  226. package/docs/rbac/quick-start.md +70 -13
  227. package/docs/rbac/rbac-rls-integration.md +6 -0
  228. package/docs/rbac/super-admin-guide.md +6 -0
  229. package/docs/rbac/troubleshooting.md +6 -0
  230. package/docs/security/README.md +6 -0
  231. package/docs/security/checklist.md +6 -0
  232. package/docs/styles/README.md +7 -1
  233. package/docs/{usage.md → styles/usage.md} +6 -0
  234. package/docs/testing/README.md +6 -0
  235. package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
  236. package/docs/troubleshooting/README.md +387 -5
  237. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
  238. package/docs/troubleshooting/common-issues.md +6 -0
  239. package/docs/troubleshooting/database-view-compatibility.md +6 -0
  240. package/docs/troubleshooting/organisation-context-setup.md +6 -0
  241. package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
  242. package/docs/troubleshooting/styling-issues.md +6 -0
  243. package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
  244. package/package.json +1 -1
  245. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
  246. package/src/__tests__/helpers/test-providers.tsx +3 -53
  247. package/src/components/DataTable/DataTable.test.tsx +319 -0
  248. package/src/components/DataTable/DataTable.tsx +32 -11
  249. package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
  250. package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
  251. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
  252. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
  253. package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
  254. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
  255. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
  256. package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
  257. package/src/components/DataTable/components/ActionButtons.tsx +88 -104
  258. package/src/components/DataTable/components/DataTableCore.tsx +309 -337
  259. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
  260. package/src/components/DataTable/components/DataTableModals.tsx +22 -1
  261. package/src/components/DataTable/components/EditableRow.tsx +69 -84
  262. package/src/components/DataTable/components/EmptyState.tsx +5 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +65 -36
  264. package/src/components/DataTable/components/PaginationControls.tsx +40 -100
  265. package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
  266. package/src/components/DataTable/context/DataTableContext.tsx +1 -1
  267. package/src/components/DataTable/core/ColumnFactory.ts +5 -0
  268. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
  269. package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
  270. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
  271. package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
  272. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
  273. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
  274. package/src/components/DataTable/hooks/index.ts +7 -0
  275. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
  276. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
  277. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
  278. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
  280. package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
  281. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
  282. package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
  283. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
  284. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
  285. package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
  286. package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
  287. package/src/components/DataTable/index.ts +12 -3
  288. package/src/components/DataTable/types.ts +129 -9
  289. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
  290. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
  291. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
  292. package/src/components/DataTable/utils/a11yUtils.ts +244 -0
  293. package/src/components/DataTable/utils/debugTools.ts +609 -0
  294. package/src/components/DataTable/utils/exportUtils.ts +114 -16
  295. package/src/components/DataTable/utils/flexibleImport.ts +202 -32
  296. package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
  297. package/src/components/DataTable/utils/index.ts +2 -0
  298. package/src/components/DataTable/utils/paginationUtils.ts +350 -0
  299. package/src/components/DataTable/utils/rowUtils.ts +6 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
  301. package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
  302. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
  303. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
  304. package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
  305. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
  306. package/src/components/Select/Select.tsx +1 -0
  307. package/src/components/examples/PermissionExample.tsx +173 -0
  308. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  309. package/src/examples/PublicEventPage.tsx +274 -0
  310. package/src/examples/PublicPageApp.tsx +308 -0
  311. package/src/examples/PublicPageUsageExample.tsx +216 -0
  312. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
  313. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
  314. package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
  315. package/src/hooks/useOrganisationPermissions.test.ts +42 -18
  316. package/src/hooks/useOrganisationPermissions.ts +12 -6
  317. package/src/hooks/useOrganisationSecurity.test.ts +138 -85
  318. package/src/hooks/useOrganisationSecurity.ts +41 -10
  319. package/src/index.ts +0 -1
  320. package/src/providers/AuthProvider.simplified.tsx +880 -0
  321. package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
  322. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
  323. package/src/providers/index.ts +0 -1
  324. package/src/providers/services/EventServiceProvider.tsx +19 -15
  325. package/src/providers/services/InactivityServiceProvider.tsx +19 -15
  326. package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
  327. package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
  328. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
  329. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
  330. package/src/rbac/README.md +1 -1
  331. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
  332. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
  333. package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
  334. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
  335. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
  336. package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
  337. package/src/rbac/adapters.tsx +26 -69
  338. package/src/rbac/api.test.ts +90 -27
  339. package/src/rbac/api.ts +61 -10
  340. package/src/rbac/audit.test.ts +33 -38
  341. package/src/rbac/audit.ts +21 -6
  342. package/src/rbac/cache.ts +33 -1
  343. package/src/rbac/components/NavigationGuard.tsx +11 -11
  344. package/src/rbac/components/NavigationProvider.test.tsx +11 -5
  345. package/src/rbac/components/NavigationProvider.tsx +37 -13
  346. package/src/rbac/components/PagePermissionGuard.tsx +111 -50
  347. package/src/rbac/components/PagePermissionProvider.tsx +5 -5
  348. package/src/rbac/components/PermissionEnforcer.tsx +11 -11
  349. package/src/rbac/components/RoleBasedRouter.tsx +5 -5
  350. package/src/rbac/components/SecureDataProvider.tsx +5 -5
  351. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
  352. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
  353. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
  354. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
  355. package/src/rbac/engine.test.simple.ts +19 -13
  356. package/src/rbac/engine.test.ts +1 -0
  357. package/src/rbac/engine.ts +330 -766
  358. package/src/rbac/errors.ts +156 -0
  359. package/src/rbac/hooks/usePermissions.ts +32 -10
  360. package/src/rbac/hooks/useRBAC.test.ts +126 -512
  361. package/src/rbac/hooks/useRBAC.ts +147 -193
  362. package/src/rbac/hooks/useResolvedScope.ts +12 -0
  363. package/src/rbac/index.ts +7 -4
  364. package/src/rbac/security.ts +109 -18
  365. package/src/rbac/types.ts +12 -1
  366. package/src/services/AuthService.ts +2 -15
  367. package/src/services/EventService.ts +43 -46
  368. package/src/services/OrganisationService.ts +51 -31
  369. package/src/services/__tests__/AuthService.test.ts +1 -1
  370. package/src/services/__tests__/EventService.test.ts +1 -1
  371. package/src/services/__tests__/OrganisationService.test.ts +1 -1
  372. package/src/services/base/BaseService.ts +8 -0
  373. package/src/styles/base.css +208 -0
  374. package/src/styles/semantic.css +24 -0
  375. package/src/types/database.generated.ts +7347 -0
  376. package/src/types/database.ts +20 -0
  377. package/src/utils/logger.ts +179 -0
  378. package/src/utils/organisationContext.ts +11 -4
  379. package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
  380. package/dist/appNameResolver-UURKN7NF.js +0 -22
  381. package/dist/audit-6TOCAMKO.js.map +0 -1
  382. package/dist/chunk-B2WTCLCV.js.map +0 -1
  383. package/dist/chunk-FGMFQSHX.js.map +0 -1
  384. package/dist/chunk-K34IM5CT.js.map +0 -1
  385. package/dist/chunk-KHJS6VIA.js.map +0 -1
  386. package/dist/chunk-KK73ZB4E.js.map +0 -1
  387. package/dist/chunk-M5IWZRBT.js.map +0 -1
  388. package/dist/chunk-ULBI5JGB.js +0 -109
  389. package/dist/chunk-ULBI5JGB.js.map +0 -1
  390. package/dist/chunk-WN6XJWOS.js.map +0 -1
  391. package/dist/chunk-XLZ7U46Z.js.map +0 -1
  392. package/dist/chunk-Y6TXWPJO.js.map +0 -1
  393. package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
  394. package/docs/TERMINOLOGY.md +0 -231
  395. package/docs/api/interfaces/RBACContextType.md +0 -468
  396. package/docs/api/interfaces/RBACProviderProps.md +0 -107
  397. package/docs/best-practices/performance-expansion.md +0 -473
  398. package/docs/breaking-changes.md +0 -179
  399. package/docs/consuming-app-example.md +0 -290
  400. package/docs/documentation-templates.md +0 -539
  401. package/docs/examples/navigation-menu-auth-fix.md +0 -344
  402. package/docs/getting-started/examples/basic-auth-app.md +0 -520
  403. package/docs/getting-started/examples/full-featured-app.md +0 -616
  404. package/docs/getting-started/quick-start.md +0 -376
  405. package/docs/implementation-guides/datatable-filtering.md +0 -313
  406. package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
  407. package/docs/implementation-guides/hierarchical-datatable.md +0 -850
  408. package/docs/implementation-guides/large-datasets.md +0 -281
  409. package/docs/implementation-guides/performance.md +0 -403
  410. package/docs/migration/quick-migration-guide.md +0 -320
  411. package/docs/migration-guide.md +0 -193
  412. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
  413. package/docs/performance/README.md +0 -551
  414. package/docs/style-guide.md +0 -964
  415. package/docs/troubleshooting/authentication-issues.md +0 -334
  416. package/docs/troubleshooting/debugging.md +0 -1117
  417. package/docs/troubleshooting/migration.md +0 -918
  418. package/src/__tests__/hooks/usePermissions.test.ts +0 -261
  419. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
  420. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
  421. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
  422. package/src/hooks/services/usePermissions.ts +0 -70
  423. package/src/hooks/services/useRBACService.ts +0 -30
  424. package/src/hooks/usePermissionCheck.ts +0 -150
  425. package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
  426. package/src/providers/services/RBACServiceProvider.tsx +0 -79
  427. package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
  428. package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
  429. package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
  430. package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
  431. package/src/rbac/providers/RBACProvider.tsx +0 -645
  432. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
  433. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
  434. package/src/rbac/providers/index.ts +0 -11
  435. package/src/services/RBACService.ts +0 -522
  436. package/src/services/__tests__/RBACService.test.ts +0 -492
  437. package/src/services/interfaces/IRBACService.ts +0 -62
  438. package/src/utils/appNameResolver.test 2.ts +0 -494
  439. /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
  440. /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
  441. /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
  442. /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
  443. /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
  444. /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
  445. /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
  446. /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
  447. /package/docs/{app.css.example → styles/app.css.example} +0 -0
@@ -1,477 +0,0 @@
1
- /**
2
- * @file Service Providers Unit Tests
3
- * @package @jmruthers/pace-core
4
- * @module Providers/__tests__
5
- * @since 0.1.0
6
- *
7
- * Unit tests for service provider components.
8
- * Tests React context providers and service instantiation.
9
- */
10
-
11
- import { describe, it, expect, beforeEach, vi } from 'vitest';
12
- import { render, screen } from '@testing-library/react';
13
- import React from 'react';
14
- import { AuthServiceProvider, useAuthService } from '../services/AuthServiceProvider';
15
- import { RBACServiceProvider, useRBACService } from '../services/RBACServiceProvider';
16
- import { OrganisationServiceProvider, useOrganisationService } from '../services/OrganisationServiceProvider';
17
- import { EventServiceProvider, useEventService } from '../services/EventServiceProvider';
18
- import { InactivityServiceProvider, useInactivityService } from '../services/InactivityServiceProvider';
19
-
20
- // Mock Supabase client
21
- const createMockSupabaseClient = () => ({
22
- auth: {
23
- getSession: vi.fn(),
24
- getUser: vi.fn(),
25
- onAuthStateChange: vi.fn(() => ({ data: { subscription: { unsubscribe: vi.fn() } } })),
26
- signInWithPassword: vi.fn(),
27
- signUp: vi.fn(),
28
- signOut: vi.fn(),
29
- resetPasswordForEmail: vi.fn(),
30
- updateUser: vi.fn(),
31
- refreshSession: vi.fn()
32
- },
33
- rpc: vi.fn(),
34
- from: vi.fn()
35
- });
36
-
37
- // Mock user and session
38
- const mockUser = {
39
- id: 'user-1',
40
- email: 'test@example.com'
41
- };
42
-
43
- const mockSession = {
44
- access_token: 'token',
45
- user: mockUser
46
- };
47
-
48
- const mockOrganisation = {
49
- id: 'org-1',
50
- display_name: 'Test Organisation'
51
- };
52
-
53
- // Test components for each service
54
- const AuthTestComponent = () => {
55
- const authService = useAuthService();
56
- return <div data-testid="service">{authService ? 'Service Available' : 'No Service'}</div>;
57
- };
58
-
59
- const RBACTestComponent = () => {
60
- const rbacService = useRBACService();
61
- return <div data-testid="service">{rbacService ? 'Service Available' : 'No Service'}</div>;
62
- };
63
-
64
- const OrganisationTestComponent = () => {
65
- const organisationService = useOrganisationService();
66
- return <div data-testid="service">{organisationService ? 'Service Available' : 'No Service'}</div>;
67
- };
68
-
69
- const EventTestComponent = () => {
70
- const eventService = useEventService();
71
- return <div data-testid="service">{eventService ? 'Service Available' : 'No Service'}</div>;
72
- };
73
-
74
- const InactivityTestComponent = () => {
75
- const inactivityService = useInactivityService();
76
- return <div data-testid="service">{inactivityService ? 'Service Available' : 'No Service'}</div>;
77
- };
78
-
79
- describe('Service Providers', () => {
80
- let mockSupabase: ReturnType<typeof createMockSupabaseClient>;
81
-
82
- beforeEach(() => {
83
- mockSupabase = createMockSupabaseClient();
84
- vi.clearAllMocks();
85
- });
86
-
87
- describe('AuthServiceProvider', () => {
88
- it('should provide AuthService to children', () => {
89
- render(
90
- <AuthServiceProvider supabaseClient={mockSupabase as any}>
91
- <AuthTestComponent />
92
- </AuthServiceProvider>
93
- );
94
-
95
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
96
- });
97
-
98
- it('should create new service instance when supabaseClient changes', () => {
99
- const { rerender } = render(
100
- <AuthServiceProvider supabaseClient={mockSupabase as any}>
101
- <AuthTestComponent />
102
- </AuthServiceProvider>
103
- );
104
-
105
- const newMockSupabase = createMockSupabaseClient();
106
- rerender(
107
- <AuthServiceProvider supabaseClient={newMockSupabase as any}>
108
- <AuthTestComponent />
109
- </AuthServiceProvider>
110
- );
111
-
112
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
113
- });
114
-
115
- it('should cleanup service on unmount', () => {
116
- const { unmount } = render(
117
- <AuthServiceProvider supabaseClient={mockSupabase as any}>
118
- <AuthTestComponent />
119
- </AuthServiceProvider>
120
- );
121
-
122
- unmount();
123
- // Service should be cleaned up (tested indirectly through cleanup calls)
124
- });
125
- });
126
-
127
- describe('RBACServiceProvider', () => {
128
- it('should provide RBACService to children', () => {
129
- render(
130
- <RBACServiceProvider
131
- supabaseClient={mockSupabase as any}
132
- user={mockUser}
133
- session={mockSession}
134
- appName="test-app"
135
- enableRBAC={true}
136
- >
137
- <RBACTestComponent />
138
- </RBACServiceProvider>
139
- );
140
-
141
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
142
- });
143
-
144
- it('should create new service instance when dependencies change', () => {
145
- const { rerender } = render(
146
- <RBACServiceProvider
147
- supabaseClient={mockSupabase as any}
148
- user={mockUser}
149
- session={mockSession}
150
- appName="test-app"
151
- enableRBAC={true}
152
- >
153
- <RBACTestComponent />
154
- </RBACServiceProvider>
155
- );
156
-
157
- const newUser = { ...mockUser, id: 'user-2' };
158
- rerender(
159
- <RBACServiceProvider
160
- supabaseClient={mockSupabase as any}
161
- user={newUser}
162
- session={mockSession}
163
- appName="test-app"
164
- enableRBAC={true}
165
- >
166
- <RBACTestComponent />
167
- </RBACServiceProvider>
168
- );
169
-
170
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
171
- });
172
-
173
- it('should handle missing user gracefully', () => {
174
- render(
175
- <RBACServiceProvider
176
- supabaseClient={mockSupabase as any}
177
- user={null}
178
- session={null}
179
- appName="test-app"
180
- enableRBAC={true}
181
- >
182
- <RBACTestComponent />
183
- </RBACServiceProvider>
184
- );
185
-
186
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
187
- });
188
- });
189
-
190
- describe('OrganisationServiceProvider', () => {
191
- it('should provide OrganisationService to children', () => {
192
- render(
193
- <OrganisationServiceProvider
194
- supabaseClient={mockSupabase as any}
195
- user={mockUser}
196
- session={mockSession}
197
- >
198
- <OrganisationTestComponent />
199
- </OrganisationServiceProvider>
200
- );
201
-
202
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
203
- });
204
-
205
- it('should create new service instance when dependencies change', () => {
206
- const { rerender } = render(
207
- <OrganisationServiceProvider
208
- supabaseClient={mockSupabase as any}
209
- user={mockUser}
210
- session={mockSession}
211
- >
212
- <OrganisationTestComponent />
213
- </OrganisationServiceProvider>
214
- );
215
-
216
- const newUser = { ...mockUser, id: 'user-2' };
217
- rerender(
218
- <OrganisationServiceProvider
219
- supabaseClient={mockSupabase as any}
220
- user={newUser}
221
- session={mockSession}
222
- >
223
- <OrganisationTestComponent />
224
- </OrganisationServiceProvider>
225
- );
226
-
227
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
228
- });
229
-
230
- it('should handle missing user gracefully', () => {
231
- render(
232
- <OrganisationServiceProvider
233
- supabaseClient={mockSupabase as any}
234
- user={null}
235
- session={null}
236
- >
237
- <OrganisationTestComponent />
238
- </OrganisationServiceProvider>
239
- );
240
-
241
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
242
- });
243
- });
244
-
245
- describe('EventServiceProvider', () => {
246
- it('should provide EventService to children', () => {
247
- render(
248
- <EventServiceProvider
249
- supabaseClient={mockSupabase as any}
250
- user={mockUser}
251
- session={mockSession}
252
- appName="test-app"
253
- selectedOrganisation={mockOrganisation}
254
- organisationService={{} as any}
255
- rbacService={{} as any}
256
- >
257
- <EventTestComponent />
258
- </EventServiceProvider>
259
- );
260
-
261
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
262
- });
263
-
264
- it('should create new service instance when dependencies change', () => {
265
- const { rerender } = render(
266
- <EventServiceProvider
267
- supabaseClient={mockSupabase as any}
268
- user={mockUser}
269
- session={mockSession}
270
- appName="test-app"
271
- selectedOrganisation={mockOrganisation}
272
- organisationService={{} as any}
273
- rbacService={{} as any}
274
- >
275
- <EventTestComponent />
276
- </EventServiceProvider>
277
- );
278
-
279
- const newOrganisation = { ...mockOrganisation, id: 'org-2' };
280
- rerender(
281
- <EventServiceProvider
282
- supabaseClient={mockSupabase as any}
283
- user={mockUser}
284
- session={mockSession}
285
- appName="test-app"
286
- selectedOrganisation={newOrganisation}
287
- organisationService={{} as any}
288
- rbacService={{} as any}
289
- >
290
- <EventTestComponent />
291
- </EventServiceProvider>
292
- );
293
-
294
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
295
- });
296
-
297
- it('should handle missing organisation gracefully', () => {
298
- render(
299
- <EventServiceProvider
300
- supabaseClient={mockSupabase as any}
301
- user={mockUser}
302
- session={mockSession}
303
- appName="test-app"
304
- selectedOrganisation={null}
305
- organisationService={{} as any}
306
- rbacService={{} as any}
307
- >
308
- <EventTestComponent />
309
- </EventServiceProvider>
310
- );
311
-
312
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
313
- });
314
- });
315
-
316
- describe('InactivityServiceProvider', () => {
317
- it('should provide InactivityService to children', () => {
318
- render(
319
- <InactivityServiceProvider
320
- supabaseClient={mockSupabase as any}
321
- user={mockUser}
322
- session={mockSession}
323
- idleTimeoutMs={300000}
324
- warnBeforeMs={60000}
325
- onIdleLogout={() => {}}
326
- dangerouslyDisableInactivity={false}
327
- >
328
- <InactivityTestComponent />
329
- </InactivityServiceProvider>
330
- );
331
-
332
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
333
- });
334
-
335
- it('should create new service instance when dependencies change', () => {
336
- const { rerender } = render(
337
- <InactivityServiceProvider
338
- supabaseClient={mockSupabase as any}
339
- user={mockUser}
340
- session={mockSession}
341
- idleTimeoutMs={300000}
342
- warnBeforeMs={60000}
343
- onIdleLogout={() => {}}
344
- dangerouslyDisableInactivity={false}
345
- >
346
- <InactivityTestComponent />
347
- </InactivityServiceProvider>
348
- );
349
-
350
- rerender(
351
- <InactivityServiceProvider
352
- supabaseClient={mockSupabase as any}
353
- user={mockUser}
354
- session={mockSession}
355
- idleTimeoutMs={600000} // Changed timeout
356
- warnBeforeMs={120000} // Changed warning time
357
- onIdleLogout={() => {}}
358
- dangerouslyDisableInactivity={false}
359
- >
360
- <InactivityTestComponent />
361
- </InactivityServiceProvider>
362
- );
363
-
364
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
365
- });
366
-
367
- it('should handle missing user gracefully', () => {
368
- render(
369
- <InactivityServiceProvider
370
- supabaseClient={mockSupabase as any}
371
- user={null}
372
- session={null}
373
- idleTimeoutMs={300000}
374
- warnBeforeMs={60000}
375
- onIdleLogout={() => {}}
376
- dangerouslyDisableInactivity={false}
377
- >
378
- <InactivityTestComponent />
379
- </InactivityServiceProvider>
380
- );
381
-
382
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
383
- });
384
-
385
- it('should handle missing onIdleLogout callback', () => {
386
- render(
387
- <InactivityServiceProvider
388
- supabaseClient={mockSupabase as any}
389
- user={mockUser}
390
- session={mockSession}
391
- idleTimeoutMs={300000}
392
- warnBeforeMs={60000}
393
- onIdleLogout={undefined}
394
- dangerouslyDisableInactivity={false}
395
- >
396
- <InactivityTestComponent />
397
- </InactivityServiceProvider>
398
- );
399
-
400
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
401
- });
402
- });
403
-
404
- describe('Provider Composition', () => {
405
- it('should work with multiple providers', () => {
406
- render(
407
- <AuthServiceProvider supabaseClient={mockSupabase as any}>
408
- <RBACServiceProvider
409
- supabaseClient={mockSupabase as any}
410
- user={mockUser}
411
- session={mockSession}
412
- appName="test-app"
413
- enableRBAC={true}
414
- >
415
- <OrganisationServiceProvider
416
- supabaseClient={mockSupabase as any}
417
- user={mockUser}
418
- session={mockSession}
419
- >
420
- <AuthTestComponent />
421
- </OrganisationServiceProvider>
422
- </RBACServiceProvider>
423
- </AuthServiceProvider>
424
- );
425
-
426
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
427
- });
428
-
429
- it('should handle provider unmounting gracefully', () => {
430
- const { unmount } = render(
431
- <AuthServiceProvider supabaseClient={mockSupabase as any}>
432
- <RBACServiceProvider
433
- supabaseClient={mockSupabase as any}
434
- user={mockUser}
435
- session={mockSession}
436
- appName="test-app"
437
- enableRBAC={true}
438
- >
439
- <AuthTestComponent />
440
- </RBACServiceProvider>
441
- </AuthServiceProvider>
442
- );
443
-
444
- unmount();
445
- // Should not throw errors during unmount
446
- });
447
- });
448
-
449
- describe('Error Handling', () => {
450
- it('should handle service creation errors gracefully', () => {
451
- // Mock service constructor to throw error
452
- const errorSupabase = {
453
- ...mockSupabase,
454
- auth: {
455
- ...mockSupabase.auth,
456
- getSession: vi.fn().mockRejectedValue(new Error('Service creation error'))
457
- }
458
- };
459
-
460
- render(
461
- <AuthServiceProvider supabaseClient={errorSupabase as any}>
462
- <AuthTestComponent />
463
- </AuthServiceProvider>
464
- );
465
-
466
- // Should still render without crashing
467
- expect(screen.getByTestId('service')).toHaveTextContent('Service Available');
468
- });
469
-
470
- it('should handle missing context gracefully', () => {
471
- // This should throw an error because there's no provider
472
- expect(() => {
473
- render(<AuthTestComponent />);
474
- }).toThrow('useAuthService must be used within AuthServiceProvider');
475
- });
476
- });
477
- });
@@ -1,79 +0,0 @@
1
- /**
2
- * @file RBAC Service Provider
3
- * @package @jmruthers/pace-core
4
- * @module Providers/Services
5
- * @since 0.1.0
6
- *
7
- * React provider for RBACService.
8
- * Provides RBAC service instance to React components.
9
- */
10
-
11
- import React, { createContext, useContext, useMemo, useEffect } from 'react';
12
- import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
13
- import { RBACService } from '../../services/RBACService';
14
-
15
- // Context type
16
- export interface RBACServiceContextType {
17
- rbacService: RBACService;
18
- }
19
-
20
- export const RBACServiceContext = createContext<RBACServiceContextType | null>(null);
21
-
22
- export interface RBACServiceProviderProps {
23
- children: React.ReactNode;
24
- supabaseClient: SupabaseClient;
25
- user: User | null;
26
- session: Session | null;
27
- appName: string;
28
- }
29
-
30
- export function RBACServiceProvider({
31
- children,
32
- supabaseClient,
33
- user,
34
- session,
35
- appName
36
- }: RBACServiceProviderProps) {
37
- // Create service instance with useMemo to prevent recreation on every render
38
- const rbacService = useMemo(
39
- () => new RBACService(supabaseClient, user, session, appName),
40
- [supabaseClient, user, session, appName]
41
- );
42
-
43
- // Update service dependencies when they change
44
- useEffect(() => {
45
- rbacService.updateDependencies(user, session, appName);
46
- }, [rbacService, user, session, appName]);
47
-
48
- // Initialize service on mount
49
- useEffect(() => {
50
- rbacService.initialize().catch(error => {
51
- console.error('[RBACServiceProvider] Failed to initialize RBAC service:', error);
52
- });
53
-
54
- // Cleanup on unmount
55
- return () => {
56
- rbacService.cleanup();
57
- };
58
- }, [rbacService]);
59
-
60
- const contextValue = useMemo(() => ({
61
- rbacService
62
- }), [rbacService]);
63
-
64
- return (
65
- <RBACServiceContext.Provider value={contextValue}>
66
- {children}
67
- </RBACServiceContext.Provider>
68
- );
69
- }
70
-
71
- export const useRBACService = (): RBACService => {
72
- const context = useContext(RBACServiceContext);
73
-
74
- if (!context) {
75
- throw new Error('useRBACService must be used within RBACServiceProvider');
76
- }
77
-
78
- return context.rbacService;
79
- };
@@ -1,119 +0,0 @@
1
- import React from 'react';
2
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
- import { render, screen, waitFor } from '@testing-library/react';
4
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
6
- import { UnifiedAuthProvider } from '../../providers/UnifiedAuthProvider';
7
- import { OrganisationProvider } from '../../providers/OrganisationProvider';
8
- import { RBACProvider } from '../providers/RBACProvider';
9
- import { useRBAC } from '../hooks/useRBAC';
10
- import type { SupabaseClient, User } from '@supabase/supabase-js';
11
-
12
- const mockSupabaseClient = {
13
- auth: {
14
- getUser: vi.fn(),
15
- },
16
- } as unknown as SupabaseClient;
17
-
18
- // Local lightweight mocks to avoid importing heavy RBAC modules during bisect
19
- vi.mock('../hooks/useRBAC', () => ({
20
- useRBAC: () => ({
21
- user: { email: 'test@example.com' },
22
- isAuthenticated: true,
23
- isLoading: false,
24
- }),
25
- }));
26
-
27
- vi.mock('../providers/RBACProvider', () => ({
28
- RBACProvider: ({ children }: any) => children,
29
- }));
30
-
31
- const mockUser: User = {
32
- id: 'user-123',
33
- email: 'test@example.com',
34
- created_at: '2023-01-01T00:00:00Z',
35
- updated_at: '2023-01-01T00:00:00Z',
36
- aud: 'authenticated',
37
- role: 'authenticated',
38
- app_metadata: {},
39
- user_metadata: {},
40
- identities: [],
41
- factors: [],
42
- } as User;
43
-
44
- const MinimalAuthComponent = () => {
45
- const { user, isAuthenticated, isLoading } = useRBAC();
46
- if (isLoading) return <div>Loading...</div>;
47
- if (!isAuthenticated) return <div>Not authenticated</div>;
48
- return (
49
- <div>
50
- <h1>AuthFlow Minimal</h1>
51
- <p>User: {user?.email}</p>
52
- </div>
53
- );
54
- };
55
-
56
- const Wrapper = ({ children }: { children: React.ReactNode }) => {
57
- const queryClient = new QueryClient({
58
- defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
59
- });
60
- return (
61
- <QueryClientProvider client={queryClient}>
62
- <UnifiedAuthProvider supabase={mockSupabaseClient}>
63
- <OrganisationProvider>
64
- <RBACProvider>{children}</RBACProvider>
65
- </OrganisationProvider>
66
- </UnifiedAuthProvider>
67
- </QueryClientProvider>
68
- );
69
- };
70
-
71
- describe('RBAC AuthFlow Minimal', () => {
72
- beforeEach(() => {
73
- vi.clearAllMocks();
74
- mockSupabaseClient.auth.getUser = vi
75
- .fn()
76
- .mockResolvedValue({ data: { user: mockUser }, error: null });
77
- });
78
-
79
- it('renders authenticated view', async () => {
80
- const router = createMemoryRouter([{ path: '/', element: <MinimalAuthComponent /> }]);
81
-
82
- render(
83
- <Wrapper>
84
- <RouterProvider router={router} />
85
- </Wrapper>
86
- );
87
-
88
- await waitFor(() => {
89
- expect(screen.getByText('AuthFlow Minimal')).toBeInTheDocument();
90
- });
91
- expect(screen.getByText('User: test@example.com')).toBeInTheDocument();
92
- });
93
-
94
- it('renders not authenticated view', async () => {
95
- const useRBACModule = await import('../hooks/useRBAC');
96
- vi.spyOn(useRBACModule, 'useRBAC').mockReturnValue({
97
- user: null,
98
- isAuthenticated: false,
99
- isLoading: false,
100
- } as any);
101
- mockSupabaseClient.auth.getUser = vi
102
- .fn()
103
- .mockResolvedValue({ data: { user: null }, error: null });
104
-
105
- const router = createMemoryRouter([{ path: '/', element: <MinimalAuthComponent /> }]);
106
-
107
- render(
108
- <Wrapper>
109
- <RouterProvider router={router} />
110
- </Wrapper>
111
- );
112
-
113
- await waitFor(() => {
114
- expect(screen.getByText('Not authenticated')).toBeInTheDocument();
115
- });
116
- });
117
- });
118
-
119
-