@jmruthers/pace-core 0.5.74 → 0.5.75
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.
- package/dist/{DataTable-2QR5TER5.js → DataTable-HWZQGASI.js} +8 -8
- package/dist/{PublicLoadingSpinner-DLpF5bbs.d.ts → PublicLoadingSpinner-BKNBT6b6.d.ts} +2 -2
- package/dist/RBACService-C4udt_Zp.d.ts +528 -0
- package/dist/{UnifiedAuthProvider-K4NRGXL4.js → UnifiedAuthProvider-3NKDOSOK.js} +6 -4
- package/dist/UnifiedAuthProvider-Bj6YCf7c.d.ts +113 -0
- package/dist/{chunk-UJMCGBLS.js → chunk-2CHATWBF.js} +5 -7
- package/dist/chunk-2CHATWBF.js.map +1 -0
- package/dist/{chunk-BKVGJVUR.js → chunk-2DFZ432F.js} +496 -30
- package/dist/chunk-2DFZ432F.js.map +1 -0
- package/dist/{chunk-LVQ26TCN.js → chunk-33PHABLB.js} +36 -3
- package/dist/chunk-33PHABLB.js.map +1 -0
- package/dist/chunk-5F3NDPJV.js +232 -0
- package/dist/chunk-5F3NDPJV.js.map +1 -0
- package/dist/chunk-A4FUBC7B.js +17 -0
- package/dist/chunk-A4FUBC7B.js.map +1 -0
- package/dist/{chunk-SMJZMKYN.js → chunk-A6HBIY5P.js} +2 -11
- package/dist/{chunk-SMJZMKYN.js.map → chunk-A6HBIY5P.js.map} +1 -1
- package/dist/{chunk-IHMMNKNA.js → chunk-CY3AHGO4.js} +6256 -1937
- package/dist/chunk-CY3AHGO4.js.map +1 -0
- package/dist/{chunk-H2TNUICK.js → chunk-DAXLNIDY.js} +47 -49
- package/dist/chunk-DAXLNIDY.js.map +1 -0
- package/dist/{chunk-VKOCWWVY.js → chunk-L3RV2ALE.js} +1 -6
- package/dist/{chunk-VKOCWWVY.js.map → chunk-L3RV2ALE.js.map} +1 -1
- package/dist/chunk-LW7MMEAQ.js +59 -0
- package/dist/chunk-LW7MMEAQ.js.map +1 -0
- package/dist/{chunk-DG5Z55HH.js → chunk-NTNILOBC.js} +7 -9
- package/dist/chunk-NTNILOBC.js.map +1 -0
- package/dist/chunk-PYUXFQJ3.js +11 -0
- package/dist/chunk-PYUXFQJ3.js.map +1 -0
- package/dist/chunk-URUTVZ7N.js +27 -0
- package/dist/chunk-URUTVZ7N.js.map +1 -0
- package/dist/chunk-WN6XJWOS.js +2468 -0
- package/dist/chunk-WN6XJWOS.js.map +1 -0
- package/dist/{chunk-3SP4P7NS.js → chunk-XLZ7U46Z.js} +59 -1
- package/dist/chunk-XLZ7U46Z.js.map +1 -0
- package/dist/{chunk-ORSMVXO2.js → chunk-ZTT2AXMX.js} +9 -14
- package/dist/chunk-ZTT2AXMX.js.map +1 -0
- package/dist/components.d.ts +4 -5
- package/dist/components.js +32 -39
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +9 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +156 -10
- package/dist/index.js +188 -93
- package/dist/index.js.map +1 -1
- package/dist/{organisation-t-vvQC3g.d.ts → organisation-BtshODVF.d.ts} +4 -3
- package/dist/providers.d.ts +27 -38
- package/dist/providers.js +33 -23
- package/dist/rbac/index.d.ts +61 -5
- package/dist/rbac/index.js +13 -14
- package/dist/styles/index.js +2 -2
- package/dist/theming/runtime.js +1 -3
- package/dist/types.d.ts +3 -3
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/{unified-CMPjE_fv.d.ts → unified-CM7T0aTK.d.ts} +1 -1
- package/dist/useInactivityTracker-MRUU55XI.js +10 -0
- package/dist/useInactivityTracker-MRUU55XI.js.map +1 -0
- package/dist/{usePublicRouteParams-Ua1Vz-HG.d.ts → usePublicRouteParams-B-CumWRc.d.ts} +3 -3
- package/dist/utils.js +7 -9
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +3 -3
- package/docs/api/interfaces/CardProps.md +2 -2
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +2 -2
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +2 -2
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +28 -17
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +2 -2
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +2 -2
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +5 -11
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +524 -440
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +14 -14
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +179 -52
- package/docs/architecture/services.md +30 -32
- package/docs/breaking-changes.md +2 -5
- package/docs/migration/service-architecture.md +121 -260
- package/docs/rbac/README-rbac-rls-integration.md +48 -38
- package/{src/rbac/examples → examples/RBAC}/CompleteRBACExample.tsx +3 -2
- package/{src/rbac/examples → examples/RBAC}/EventBasedApp.tsx +5 -4
- package/{src/components/examples → examples/RBAC}/PermissionExample.tsx +7 -6
- package/examples/RBAC/__tests__/PermissionExample.test.tsx +150 -0
- package/examples/RBAC/index.ts +13 -0
- package/examples/README.md +37 -0
- package/examples/index.ts +22 -0
- package/{src/examples → examples/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicEventPage.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicPageApp.tsx +1 -1
- package/{src/examples → examples/public-pages}/PublicPageUsageExample.tsx +1 -1
- package/examples/public-pages/__tests__/PublicPageUsageExample.test.tsx +159 -0
- package/examples/public-pages/index.ts +14 -0
- package/package.json +22 -18
- package/src/__tests__/TEST_GUIDE_CURSOR.md +650 -9
- package/src/__tests__/helpers/README.md +255 -0
- package/src/__tests__/helpers/index.ts +62 -0
- package/src/__tests__/helpers/supabaseMock.ts +27 -3
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -8
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +55 -0
- package/src/components/DataTable/core/ColumnManager.ts +10 -0
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +254 -0
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +193 -0
- package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +45 -0
- package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +117 -0
- package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +71 -0
- package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +122 -0
- package/src/components/EventSelector/EventSelector.tsx +1 -1
- package/src/components/Header/Header.test.tsx +35 -1
- package/src/components/Header/Header.tsx +3 -1
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -3
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +24 -4
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +3 -2
- package/src/hooks/__tests__/useFocusManagement.unit.test.ts +220 -0
- package/src/hooks/__tests__/useIsMobile.unit.test.ts +117 -0
- package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +295 -0
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +29 -19
- package/src/hooks/__tests__/useRBAC.unit.test.ts +7 -3
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +115 -19
- package/src/hooks/useEventTheme.test.ts +350 -0
- package/src/hooks/useEventTheme.ts +1 -1
- package/src/hooks/useEvents.ts +61 -0
- package/src/hooks/useOrganisationSecurity.test.ts +4 -4
- package/src/hooks/useOrganisationSecurity.ts +2 -2
- package/src/hooks/useOrganisations.ts +64 -0
- package/src/hooks/useSecureDataAccess.test.ts +9 -5
- package/src/hooks/useSecureDataAccess.ts +2 -2
- package/src/index.ts +18 -3
- package/src/providers/AuthProvider.tsx +8 -292
- package/src/providers/EventProvider.tsx +15 -425
- package/src/providers/InactivityProvider.tsx +8 -231
- package/src/providers/OrganisationProvider.test.simple.tsx +3 -2
- package/src/providers/OrganisationProvider.tsx +11 -890
- package/src/providers/UnifiedAuthProvider.tsx +8 -320
- package/src/providers/__tests__/AuthProvider.test.tsx +18 -17
- package/src/providers/__tests__/EventProvider.test.tsx +253 -2
- package/src/providers/__tests__/InactivityProvider.test-helper.tsx +65 -0
- package/src/providers/__tests__/InactivityProvider.test.tsx +46 -114
- package/src/providers/__tests__/OrganisationProvider.test.tsx +313 -3
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +383 -2
- package/src/providers/index.ts +8 -7
- package/src/providers/services/EventServiceProvider.tsx +3 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +3 -0
- package/src/rbac/hooks/usePermissions.test.ts +296 -0
- package/src/rbac/hooks/useRBAC.test.ts +9 -5
- package/src/rbac/hooks/useRBAC.ts +3 -3
- package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +688 -0
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +507 -0
- package/src/services/AuthService.ts +19 -4
- package/src/services/__tests__/AuthService.test.ts +288 -0
- package/src/styles/core.css +2 -0
- package/src/types/__tests__/guards.test.ts +246 -0
- package/src/types/guards.ts +1 -0
- package/src/types/organisation.ts +3 -2
- package/src/validation/__tests__/sanitization.unit.test.ts +250 -0
- package/src/validation/__tests__/schemaUtils.unit.test.ts +451 -0
- package/src/validation/__tests__/user.unit.test.ts +440 -0
- package/dist/RBACProvider-BO4ilsQB.d.ts +0 -63
- package/dist/UnifiedAuthProvider-D02AMXgO.d.ts +0 -103
- package/dist/chunk-3SP4P7NS.js.map +0 -1
- package/dist/chunk-B5LK25HV.js +0 -953
- package/dist/chunk-B5LK25HV.js.map +0 -1
- package/dist/chunk-BKVGJVUR.js.map +0 -1
- package/dist/chunk-C5Q5LRU5.js +0 -5691
- package/dist/chunk-C5Q5LRU5.js.map +0 -1
- package/dist/chunk-CDDYJCYU.js +0 -79
- package/dist/chunk-CDDYJCYU.js.map +0 -1
- package/dist/chunk-DG5Z55HH.js.map +0 -1
- package/dist/chunk-H2TNUICK.js.map +0 -1
- package/dist/chunk-IHMMNKNA.js.map +0 -1
- package/dist/chunk-LVQ26TCN.js.map +0 -1
- package/dist/chunk-ORSMVXO2.js.map +0 -1
- package/dist/chunk-UJMCGBLS.js.map +0 -1
- package/dist/chunk-V6BHACCH.js +0 -17
- package/dist/chunk-V6BHACCH.js.map +0 -1
- package/dist/rbac/cli/policy-manager.js +0 -278
- package/dist/rbac/cli/policy-manager.js.map +0 -1
- package/docs/api/interfaces/EventContextType.md +0 -96
- package/docs/api/interfaces/EventProviderProps.md +0 -19
- package/src/providers/OrganisationProvider.test.tsx +0 -164
- package/src/providers/UnifiedAuthProvider.test.tsx +0 -124
- package/src/providers/__tests__/AuthProvider.test.tsx.backup +0 -771
- package/src/providers/__tests__/EventProvider.test.tsx.backup +0 -824
- package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +0 -820
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +0 -911
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +0 -166
- package/src/rbac/cli/__tests__/policy-manager.test.ts +0 -339
- package/src/rbac/cli/policy-manager.ts +0 -443
- package/dist/{DataTable-2QR5TER5.js.map → DataTable-HWZQGASI.js.map} +0 -0
- package/dist/{UnifiedAuthProvider-K4NRGXL4.js.map → UnifiedAuthProvider-3NKDOSOK.js.map} +0 -0
- package/dist/{validation-PM_iOaTI.d.ts → validation-D8VcbTzC.d.ts} +2 -2
- /package/src/utils/{appNameResolver.test.ts.backup → appNameResolver.test 2.ts} +0 -0
|
@@ -82,11 +82,11 @@ export abstract class BaseService {
|
|
|
82
82
|
### Basic Setup
|
|
83
83
|
|
|
84
84
|
```tsx
|
|
85
|
-
import {
|
|
85
|
+
import { UnifiedAuthProvider, useUnifiedAuth } from '@jmruthers/pace-core';
|
|
86
86
|
|
|
87
87
|
function App() {
|
|
88
88
|
return (
|
|
89
|
-
<
|
|
89
|
+
<UnifiedAuthProvider
|
|
90
90
|
supabaseClient={supabase}
|
|
91
91
|
appName="MY_APP"
|
|
92
92
|
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
@@ -94,7 +94,7 @@ function App() {
|
|
|
94
94
|
onIdleLogout={() => window.location.href = '/login'}
|
|
95
95
|
>
|
|
96
96
|
<YourAppContent />
|
|
97
|
-
</
|
|
97
|
+
</UnifiedAuthProvider>
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
```
|
|
@@ -102,10 +102,10 @@ function App() {
|
|
|
102
102
|
### Using Services in Components
|
|
103
103
|
|
|
104
104
|
```tsx
|
|
105
|
-
import {
|
|
105
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
106
106
|
|
|
107
107
|
function MyComponent() {
|
|
108
|
-
const auth =
|
|
108
|
+
const auth = useUnifiedAuth();
|
|
109
109
|
|
|
110
110
|
return (
|
|
111
111
|
<div>
|
|
@@ -121,24 +121,26 @@ function MyComponent() {
|
|
|
121
121
|
### Using Individual Service Hooks
|
|
122
122
|
|
|
123
123
|
```tsx
|
|
124
|
-
import {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
import {
|
|
125
|
+
useAuthService,
|
|
126
|
+
useOrganisationService,
|
|
127
|
+
useEventService,
|
|
128
|
+
useRBACService
|
|
129
|
+
} from '@jmruthers/pace-core';
|
|
128
130
|
|
|
129
131
|
function MyComponent() {
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const
|
|
132
|
+
const authService = useAuthService();
|
|
133
|
+
const orgService = useOrganisationService();
|
|
134
|
+
const eventService = useEventService();
|
|
135
|
+
const rbacService = useRBACService();
|
|
134
136
|
|
|
135
137
|
return (
|
|
136
138
|
<div>
|
|
137
|
-
{
|
|
139
|
+
{authService.isAuthenticated() && (
|
|
138
140
|
<div>
|
|
139
|
-
<h1>{
|
|
140
|
-
{
|
|
141
|
-
<EventList events={
|
|
141
|
+
<h1>{orgService.getSelectedOrganisation()?.display_name}</h1>
|
|
142
|
+
{rbacService.hasPermission('events:read') && (
|
|
143
|
+
<EventList events={eventService.getEvents()} />
|
|
142
144
|
)}
|
|
143
145
|
</div>
|
|
144
146
|
)}
|
|
@@ -238,17 +240,13 @@ describe('AuthServiceProvider Integration', () => {
|
|
|
238
240
|
|
|
239
241
|
### From Old Architecture
|
|
240
242
|
|
|
241
|
-
The
|
|
243
|
+
The architecture is backward compatible. The `UnifiedAuthProvider` now uses the service-based architecture internally:
|
|
242
244
|
|
|
243
245
|
```tsx
|
|
244
|
-
|
|
245
|
-
import { UnifiedAuthProvider } from '@core/providers';
|
|
246
|
+
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
246
247
|
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// Same API, better architecture
|
|
251
|
-
<NewUnifiedAuthProvider
|
|
248
|
+
// Same API, service-based architecture internally
|
|
249
|
+
<UnifiedAuthProvider
|
|
252
250
|
supabaseClient={supabase}
|
|
253
251
|
appName="MY_APP"
|
|
254
252
|
idleTimeoutMs={30 * 60 * 1000}
|
|
@@ -256,17 +254,17 @@ import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthP
|
|
|
256
254
|
onIdleLogout={() => window.location.href = '/login'}
|
|
257
255
|
>
|
|
258
256
|
<YourAppContent />
|
|
259
|
-
</
|
|
257
|
+
</UnifiedAuthProvider>
|
|
260
258
|
```
|
|
261
259
|
|
|
262
|
-
###
|
|
260
|
+
### How It Works
|
|
263
261
|
|
|
264
|
-
|
|
262
|
+
All providers use the service-based architecture:
|
|
265
263
|
|
|
266
|
-
1. **
|
|
267
|
-
2. **
|
|
268
|
-
3. **
|
|
269
|
-
4. **
|
|
264
|
+
1. **UnifiedAuthProvider**: Uses service architecture internally
|
|
265
|
+
2. **Individual Services**: Available for advanced usage via hooks
|
|
266
|
+
3. **Backward Compatible**: Existing code works without changes
|
|
267
|
+
4. **Performance**: All providers instantiate services once and reuse them
|
|
270
268
|
|
|
271
269
|
## File Structure
|
|
272
270
|
|
package/docs/breaking-changes.md
CHANGED
|
@@ -87,14 +87,11 @@ The library now uses a service-based architecture with pure TypeScript service c
|
|
|
87
87
|
|
|
88
88
|
#### Migration
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
The service architecture is now the default. Existing code continues to work without changes:
|
|
91
91
|
|
|
92
92
|
```tsx
|
|
93
|
-
//
|
|
93
|
+
// Works out of the box - uses service architecture internally
|
|
94
94
|
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
95
|
-
|
|
96
|
-
// New way (optional)
|
|
97
|
-
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
98
95
|
```
|
|
99
96
|
|
|
100
97
|
See [Service Architecture Guide](./architecture/services.md) for details.
|
|
@@ -1,257 +1,151 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Provider Architecture: Service-Based Design
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
pace-core now uses a **service-based architecture** for all providers. This provides better testability, maintainability, and follows SOLID principles by separating business logic (services) from React context (providers).
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
### 1. Update Provider Import
|
|
10
|
-
|
|
11
|
-
Replace the old provider with the new one:
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
// Old way
|
|
15
|
-
import { UnifiedAuthProvider } from '@core/providers';
|
|
16
|
-
|
|
17
|
-
// New way
|
|
18
|
-
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. Update Provider Usage
|
|
7
|
+
## Architecture Benefits
|
|
22
8
|
|
|
23
|
-
|
|
9
|
+
- **Separation of Concerns**: Business logic in pure TypeScript services
|
|
10
|
+
- **Better Testability**: Services can be tested without React
|
|
11
|
+
- **Improved Performance**: Services instantiated once and reused
|
|
12
|
+
- **Type Safety**: Full TypeScript support with clear interfaces
|
|
24
13
|
|
|
25
|
-
|
|
26
|
-
// Old way
|
|
27
|
-
<UnifiedAuthProvider supabaseClient={supabase} appName="MY_APP">
|
|
28
|
-
<YourAppContent />
|
|
29
|
-
</UnifiedAuthProvider>
|
|
30
|
-
|
|
31
|
-
// New way
|
|
32
|
-
<NewUnifiedAuthProvider
|
|
33
|
-
supabaseClient={supabase}
|
|
34
|
-
appName="MY_APP"
|
|
35
|
-
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
36
|
-
warnBeforeMs={60 * 1000} // 60 seconds
|
|
37
|
-
onIdleLogout={() => {
|
|
38
|
-
// Handle idle logout - redirect to login
|
|
39
|
-
window.location.href = '/login';
|
|
40
|
-
}}
|
|
41
|
-
>
|
|
42
|
-
<YourAppContent />
|
|
43
|
-
</NewUnifiedAuthProvider>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 3. Update Hook Imports
|
|
47
|
-
|
|
48
|
-
Replace the old hook with the new one:
|
|
49
|
-
|
|
50
|
-
```tsx
|
|
51
|
-
// Old way
|
|
52
|
-
import { useUnifiedAuth } from '@core/providers';
|
|
53
|
-
|
|
54
|
-
// New way
|
|
55
|
-
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Detailed Migration Steps
|
|
59
|
-
|
|
60
|
-
### Step 1: Update Main App Setup
|
|
14
|
+
## Quick Start
|
|
61
15
|
|
|
62
|
-
|
|
16
|
+
### Basic Usage
|
|
63
17
|
|
|
64
18
|
```tsx
|
|
65
|
-
|
|
66
|
-
import { UnifiedAuthProvider, OrganisationProvider, EventProvider } from '@core/providers';
|
|
19
|
+
import { UnifiedAuthProvider, useUnifiedAuth } from '@jmruthers/pace-core';
|
|
67
20
|
|
|
68
21
|
function App() {
|
|
69
22
|
return (
|
|
70
|
-
<UnifiedAuthProvider
|
|
71
|
-
<OrganisationProvider>
|
|
72
|
-
<EventProvider>
|
|
73
|
-
<YourAppContent />
|
|
74
|
-
</EventProvider>
|
|
75
|
-
</OrganisationProvider>
|
|
76
|
-
</UnifiedAuthProvider>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// After
|
|
81
|
-
import { NewUnifiedAuthProvider } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
82
|
-
|
|
83
|
-
function App() {
|
|
84
|
-
return (
|
|
85
|
-
<NewUnifiedAuthProvider
|
|
23
|
+
<UnifiedAuthProvider
|
|
86
24
|
supabaseClient={supabase}
|
|
87
25
|
appName="MY_APP"
|
|
88
|
-
idleTimeoutMs={30 * 60 * 1000}
|
|
89
|
-
warnBeforeMs={60 * 1000}
|
|
90
|
-
onIdleLogout={() =>
|
|
26
|
+
idleTimeoutMs={30 * 60 * 1000} // 30 minutes
|
|
27
|
+
warnBeforeMs={60 * 1000} // 60 seconds
|
|
28
|
+
onIdleLogout={() => {
|
|
29
|
+
// Handle idle logout - redirect to login
|
|
30
|
+
window.location.href = '/login';
|
|
31
|
+
}}
|
|
91
32
|
>
|
|
92
33
|
<YourAppContent />
|
|
93
|
-
</
|
|
34
|
+
</UnifiedAuthProvider>
|
|
94
35
|
);
|
|
95
36
|
}
|
|
96
37
|
```
|
|
97
38
|
|
|
98
|
-
###
|
|
99
|
-
|
|
100
|
-
Update components that use the old hooks:
|
|
39
|
+
### Using Hooks
|
|
101
40
|
|
|
102
41
|
```tsx
|
|
103
|
-
|
|
104
|
-
import { useUnifiedAuth } from '@core/providers';
|
|
42
|
+
import { useUnifiedAuth, useEvents, useOrganisations } from '@jmruthers/pace-core';
|
|
105
43
|
|
|
106
44
|
function MyComponent() {
|
|
107
45
|
const { user, isAuthenticated, signOut } = useUnifiedAuth();
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
113
|
-
|
|
114
|
-
function MyComponent() {
|
|
115
|
-
const { user, isAuthenticated, signOut } = useNewUnifiedAuth();
|
|
116
|
-
// ... component logic (same API)
|
|
46
|
+
const { events, selectedEvent, setSelectedEvent } = useEvents();
|
|
47
|
+
const { selectedOrganisation, organisations } = useOrganisations();
|
|
48
|
+
|
|
49
|
+
// Use the hooks as needed
|
|
117
50
|
}
|
|
118
51
|
```
|
|
119
52
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
If you were using individual providers, you can now use individual service hooks:
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
// Before
|
|
126
|
-
import { useAuth } from '@core/providers';
|
|
127
|
-
import { useOrganisations } from '@core/providers';
|
|
128
|
-
import { useEvents } from '@core/providers';
|
|
53
|
+
## Service Architecture Overview
|
|
129
54
|
|
|
130
|
-
|
|
131
|
-
const auth = useAuth();
|
|
132
|
-
const orgs = useOrganisations();
|
|
133
|
-
const events = useEvents();
|
|
134
|
-
// ... component logic
|
|
135
|
-
}
|
|
55
|
+
### How It Works
|
|
136
56
|
|
|
137
|
-
|
|
138
|
-
|
|
57
|
+
1. **Services** (`src/services/`) - Pure TypeScript classes containing business logic
|
|
58
|
+
2. **Service Providers** (`src/providers/services/`) - React context providers that create service instances
|
|
59
|
+
3. **Hooks** - Convenience hooks that access services from context
|
|
139
60
|
|
|
140
|
-
|
|
141
|
-
const auth = useNewUnifiedAuth();
|
|
142
|
-
// ... component logic (same API)
|
|
143
|
-
}
|
|
61
|
+
### Service Layer
|
|
144
62
|
|
|
145
|
-
|
|
146
|
-
import { useAuth } from '@core/hooks/services/useAuth';
|
|
147
|
-
import { useCurrentOrganisation } from '@core/hooks/services/useCurrentOrganisation';
|
|
148
|
-
import { useCurrentEvent } from '@core/hooks/services/useCurrentEvent';
|
|
63
|
+
Each service is a pure TypeScript class:
|
|
149
64
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// ...
|
|
65
|
+
```typescript
|
|
66
|
+
class AuthService extends BaseService {
|
|
67
|
+
signIn(email: string, password: string): Promise<AuthResult> { /* ... */ }
|
|
68
|
+
signOut(): Promise<AuthResult> { /* ... */ }
|
|
69
|
+
// ... other methods
|
|
155
70
|
}
|
|
156
71
|
```
|
|
157
72
|
|
|
158
|
-
|
|
73
|
+
### Provider Layer
|
|
159
74
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
The new provider requires additional props for inactivity management:
|
|
75
|
+
Service providers create and manage service instances:
|
|
163
76
|
|
|
164
77
|
```tsx
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
onIdleLogout: (reason: 'inactivity') => void; // REQUIRED: App handles redirect/navigation
|
|
78
|
+
function AuthServiceProvider({ children, supabaseClient }) {
|
|
79
|
+
const authService = useMemo(() => new AuthService(supabaseClient), [supabaseClient]);
|
|
80
|
+
// Initialize and manage service lifecycle
|
|
81
|
+
return <AuthServiceContext.Provider value={{ authService }}>{children}</AuthServiceContext.Provider>;
|
|
170
82
|
}
|
|
171
83
|
```
|
|
172
84
|
|
|
173
|
-
###
|
|
85
|
+
### Hook Layer
|
|
174
86
|
|
|
175
|
-
|
|
87
|
+
Convenience hooks provide easy access to services:
|
|
176
88
|
|
|
177
89
|
```tsx
|
|
178
|
-
|
|
179
|
-
const
|
|
90
|
+
function useAuth() {
|
|
91
|
+
const context = useContext(AuthServiceContext);
|
|
92
|
+
return context.authService;
|
|
93
|
+
}
|
|
180
94
|
```
|
|
181
95
|
|
|
182
|
-
##
|
|
96
|
+
## Available Hooks
|
|
183
97
|
|
|
184
|
-
###
|
|
185
|
-
|
|
186
|
-
For better performance, use individual service hooks instead of the unified hook:
|
|
98
|
+
### Unified Hook (Recommended for Most Use Cases)
|
|
187
99
|
|
|
188
100
|
```tsx
|
|
189
|
-
|
|
190
|
-
const auth = useNewUnifiedAuth();
|
|
191
|
-
|
|
192
|
-
// More efficient - only re-renders when auth state changes
|
|
193
|
-
const auth = useAuth();
|
|
194
|
-
const permissions = usePermissions();
|
|
195
|
-
const organisation = useCurrentOrganisation();
|
|
196
|
-
const events = useCurrentEvent();
|
|
197
|
-
```
|
|
101
|
+
import { useUnifiedAuth } from '@jmruthers/pace-core';
|
|
198
102
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
103
|
+
function MyComponent() {
|
|
104
|
+
const {
|
|
105
|
+
user,
|
|
106
|
+
isAuthenticated,
|
|
107
|
+
signOut,
|
|
108
|
+
selectedOrganisation,
|
|
109
|
+
events,
|
|
110
|
+
selectedEvent,
|
|
111
|
+
permissions,
|
|
112
|
+
hasRole,
|
|
113
|
+
hasPermission
|
|
114
|
+
} = useUnifiedAuth();
|
|
115
|
+
|
|
116
|
+
// Access all features from one hook
|
|
117
|
+
}
|
|
207
118
|
```
|
|
208
119
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
### Update Test Imports
|
|
120
|
+
### Individual Hooks (For Performance)
|
|
212
121
|
|
|
213
|
-
|
|
122
|
+
For better performance, use individual hooks:
|
|
214
123
|
|
|
215
124
|
```tsx
|
|
216
|
-
|
|
217
|
-
|
|
125
|
+
import {
|
|
126
|
+
useEvents,
|
|
127
|
+
useOrganisations,
|
|
128
|
+
useAuthService,
|
|
129
|
+
useRBACService
|
|
130
|
+
} from '@jmruthers/pace-core';
|
|
218
131
|
|
|
219
|
-
|
|
220
|
-
|
|
132
|
+
function MyComponent() {
|
|
133
|
+
const events = useEvents();
|
|
134
|
+
const orgs = useOrganisations();
|
|
135
|
+
const auth = useAuthService();
|
|
136
|
+
const rbac = useRBACService();
|
|
137
|
+
|
|
138
|
+
// Only re-renders when relevant service state changes
|
|
139
|
+
}
|
|
221
140
|
```
|
|
222
141
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Update your test setup to use the new provider:
|
|
226
|
-
|
|
227
|
-
```tsx
|
|
228
|
-
// Before
|
|
229
|
-
render(
|
|
230
|
-
<UnifiedAuthProvider supabaseClient={mockSupabase} appName="TEST_APP">
|
|
231
|
-
<TestComponent />
|
|
232
|
-
</UnifiedAuthProvider>
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
// After
|
|
236
|
-
render(
|
|
237
|
-
<NewUnifiedAuthProvider
|
|
238
|
-
supabaseClient={mockSupabase}
|
|
239
|
-
appName="TEST_APP"
|
|
240
|
-
idleTimeoutMs={30000}
|
|
241
|
-
warnBeforeMs={5000}
|
|
242
|
-
onIdleLogout={() => {}}
|
|
243
|
-
>
|
|
244
|
-
<TestComponent />
|
|
245
|
-
</NewUnifiedAuthProvider>
|
|
246
|
-
);
|
|
247
|
-
```
|
|
142
|
+
## Testing
|
|
248
143
|
|
|
249
|
-
###
|
|
144
|
+
### Testing Services
|
|
250
145
|
|
|
251
|
-
|
|
146
|
+
Services are pure TypeScript classes, making them easy to unit test:
|
|
252
147
|
|
|
253
|
-
```
|
|
254
|
-
// Test services in isolation
|
|
148
|
+
```typescript
|
|
255
149
|
describe('AuthService', () => {
|
|
256
150
|
let authService: AuthService;
|
|
257
151
|
|
|
@@ -266,86 +160,53 @@ describe('AuthService', () => {
|
|
|
266
160
|
});
|
|
267
161
|
```
|
|
268
162
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
### Issue 1: Missing Required Props
|
|
272
|
-
|
|
273
|
-
**Error**: `Missing required prop: idleTimeoutMs`
|
|
163
|
+
### Testing Providers
|
|
274
164
|
|
|
275
|
-
|
|
165
|
+
Providers can be tested with React Testing Library:
|
|
276
166
|
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
167
|
+
```typescript
|
|
168
|
+
render(
|
|
169
|
+
<UnifiedAuthProvider
|
|
170
|
+
supabaseClient={mockSupabase}
|
|
171
|
+
appName="TEST_APP"
|
|
172
|
+
idleTimeoutMs={30000}
|
|
173
|
+
warnBeforeMs={5000}
|
|
174
|
+
onIdleLogout={() => {}}
|
|
175
|
+
>
|
|
176
|
+
<TestComponent />
|
|
177
|
+
</UnifiedAuthProvider>
|
|
178
|
+
);
|
|
287
179
|
```
|
|
288
180
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
**Error**: `useUnifiedAuth must be used within a UnifiedAuthProvider`
|
|
292
|
-
|
|
293
|
-
**Solution**: Update the hook import:
|
|
294
|
-
|
|
295
|
-
```tsx
|
|
296
|
-
// Change this
|
|
297
|
-
import { useUnifiedAuth } from '@core/providers';
|
|
298
|
-
|
|
299
|
-
// To this
|
|
300
|
-
import { useNewUnifiedAuth } from '@core/providers/services/NewUnifiedAuthProvider';
|
|
301
|
-
```
|
|
181
|
+
## Common Issues
|
|
302
182
|
|
|
303
|
-
###
|
|
183
|
+
### Missing Required Props
|
|
304
184
|
|
|
305
|
-
**Error**: `
|
|
185
|
+
**Error**: `Missing required prop: idleTimeoutMs`
|
|
306
186
|
|
|
307
|
-
|
|
187
|
+
Add the required inactivity management props:
|
|
308
188
|
|
|
309
189
|
```tsx
|
|
310
|
-
|
|
311
|
-
|
|
190
|
+
<UnifiedAuthProvider
|
|
191
|
+
supabaseClient={supabase}
|
|
192
|
+
appName="MY_APP"
|
|
193
|
+
idleTimeoutMs={30 * 60 * 1000}
|
|
194
|
+
warnBeforeMs={60 * 1000}
|
|
195
|
+
onIdleLogout={() => window.location.href = '/login'}
|
|
196
|
+
>
|
|
312
197
|
<YourAppContent />
|
|
313
|
-
</
|
|
198
|
+
</UnifiedAuthProvider>
|
|
314
199
|
```
|
|
315
200
|
|
|
316
|
-
##
|
|
317
|
-
|
|
318
|
-
- [ ] Update provider import from `UnifiedAuthProvider` to `NewUnifiedAuthProvider`
|
|
319
|
-
- [ ] Add required inactivity management props (`idleTimeoutMs`, `warnBeforeMs`, `onIdleLogout`)
|
|
320
|
-
- [ ] Update hook import from `useUnifiedAuth` to `useNewUnifiedAuth`
|
|
321
|
-
- [ ] Update test imports and setup
|
|
322
|
-
- [ ] Test the application to ensure everything works
|
|
323
|
-
- [ ] Consider using individual service hooks for better performance
|
|
324
|
-
- [ ] Remove old provider imports once migration is complete
|
|
325
|
-
|
|
326
|
-
## Rollback Plan
|
|
327
|
-
|
|
328
|
-
If you need to rollback:
|
|
329
|
-
|
|
330
|
-
1. **Revert imports**: Change back to old provider imports
|
|
331
|
-
2. **Revert provider usage**: Remove the new required props
|
|
332
|
-
3. **Revert hook usage**: Change back to old hook imports
|
|
333
|
-
4. **Test**: Ensure the application works with the old architecture
|
|
334
|
-
|
|
335
|
-
## Support
|
|
336
|
-
|
|
337
|
-
If you encounter issues during migration:
|
|
338
|
-
|
|
339
|
-
1. **Check the documentation**: Review the service architecture documentation
|
|
340
|
-
2. **Check the examples**: Look at the updated example app
|
|
341
|
-
3. **Check the tests**: Review the test files for usage examples
|
|
342
|
-
4. **Open an issue**: Report bugs or ask questions
|
|
201
|
+
## Performance Tips
|
|
343
202
|
|
|
344
|
-
|
|
203
|
+
1. **Use individual hooks** when you only need specific data
|
|
204
|
+
2. **Avoid unnecessary re-renders** by selecting only what you need
|
|
205
|
+
3. **Memoize expensive computations** in components
|
|
206
|
+
4. **Test services in isolation** for better unit tests
|
|
345
207
|
|
|
346
|
-
|
|
208
|
+
## Additional Resources
|
|
347
209
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
4. **Contribute**: Help improve the service architecture
|
|
210
|
+
- [API Reference](../../api-reference/providers.md)
|
|
211
|
+
- [Architecture Documentation](../../architecture/services.md)
|
|
212
|
+
- [Example Apps](../../getting-started/examples/)
|