@jmruthers/pace-core 0.5.73 → 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.
Files changed (283) hide show
  1. package/dist/{DataTable-INW5YIFV.js → DataTable-HWZQGASI.js} +8 -8
  2. package/dist/{PublicLoadingSpinner-DLpF5bbs.d.ts → PublicLoadingSpinner-BKNBT6b6.d.ts} +2 -2
  3. package/dist/RBACService-C4udt_Zp.d.ts +528 -0
  4. package/dist/{UnifiedAuthProvider-6SYT5WFN.js → UnifiedAuthProvider-3NKDOSOK.js} +6 -4
  5. package/dist/UnifiedAuthProvider-Bj6YCf7c.d.ts +113 -0
  6. package/dist/{chunk-2PRPDH66.js → chunk-2CHATWBF.js} +5 -7
  7. package/dist/chunk-2CHATWBF.js.map +1 -0
  8. package/dist/{chunk-43C63KLH.js → chunk-2DFZ432F.js} +496 -30
  9. package/dist/chunk-2DFZ432F.js.map +1 -0
  10. package/dist/{chunk-M4UMXYNK.js → chunk-33PHABLB.js} +36 -3
  11. package/dist/chunk-33PHABLB.js.map +1 -0
  12. package/dist/chunk-5F3NDPJV.js +232 -0
  13. package/dist/chunk-5F3NDPJV.js.map +1 -0
  14. package/dist/chunk-A4FUBC7B.js +17 -0
  15. package/dist/chunk-A4FUBC7B.js.map +1 -0
  16. package/dist/{chunk-SMJZMKYN.js → chunk-A6HBIY5P.js} +2 -11
  17. package/dist/{chunk-SMJZMKYN.js.map → chunk-A6HBIY5P.js.map} +1 -1
  18. package/dist/{chunk-GBC5PC3N.js → chunk-CY3AHGO4.js} +6256 -1937
  19. package/dist/chunk-CY3AHGO4.js.map +1 -0
  20. package/dist/{chunk-BYG6OSTC.js → chunk-DAXLNIDY.js} +48 -50
  21. package/dist/chunk-DAXLNIDY.js.map +1 -0
  22. package/dist/{chunk-VKOCWWVY.js → chunk-L3RV2ALE.js} +1 -6
  23. package/dist/{chunk-VKOCWWVY.js.map → chunk-L3RV2ALE.js.map} +1 -1
  24. package/dist/chunk-LW7MMEAQ.js +59 -0
  25. package/dist/chunk-LW7MMEAQ.js.map +1 -0
  26. package/dist/{chunk-LANO5IFV.js → chunk-NTNILOBC.js} +7 -9
  27. package/dist/chunk-NTNILOBC.js.map +1 -0
  28. package/dist/chunk-PYUXFQJ3.js +11 -0
  29. package/dist/chunk-PYUXFQJ3.js.map +1 -0
  30. package/dist/chunk-URUTVZ7N.js +27 -0
  31. package/dist/chunk-URUTVZ7N.js.map +1 -0
  32. package/dist/chunk-WN6XJWOS.js +2468 -0
  33. package/dist/chunk-WN6XJWOS.js.map +1 -0
  34. package/dist/{chunk-3SP4P7NS.js → chunk-XLZ7U46Z.js} +59 -1
  35. package/dist/chunk-XLZ7U46Z.js.map +1 -0
  36. package/dist/{chunk-UC2BWIK7.js → chunk-ZTT2AXMX.js} +9 -14
  37. package/dist/chunk-ZTT2AXMX.js.map +1 -0
  38. package/dist/components.d.ts +4 -5
  39. package/dist/components.js +32 -39
  40. package/dist/components.js.map +1 -1
  41. package/dist/hooks.d.ts +3 -3
  42. package/dist/hooks.js +9 -8
  43. package/dist/hooks.js.map +1 -1
  44. package/dist/index.d.ts +156 -10
  45. package/dist/index.js +188 -93
  46. package/dist/index.js.map +1 -1
  47. package/dist/{organisation-t-vvQC3g.d.ts → organisation-BtshODVF.d.ts} +4 -3
  48. package/dist/providers.d.ts +27 -38
  49. package/dist/providers.js +33 -23
  50. package/dist/rbac/index.d.ts +61 -5
  51. package/dist/rbac/index.js +13 -14
  52. package/dist/styles/index.js +2 -2
  53. package/dist/theming/runtime.js +1 -3
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +1 -1
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CMPjE_fv.d.ts → unified-CM7T0aTK.d.ts} +1 -1
  58. package/dist/useInactivityTracker-MRUU55XI.js +10 -0
  59. package/dist/useInactivityTracker-MRUU55XI.js.map +1 -0
  60. package/dist/{usePublicRouteParams-Ua1Vz-HG.d.ts → usePublicRouteParams-B-CumWRc.d.ts} +3 -3
  61. package/dist/utils.js +7 -9
  62. package/dist/utils.js.map +1 -1
  63. package/dist/validation.d.ts +1 -1
  64. package/docs/api/classes/ColumnFactory.md +1 -1
  65. package/docs/api/classes/ErrorBoundary.md +1 -1
  66. package/docs/api/classes/InvalidScopeError.md +1 -1
  67. package/docs/api/classes/MissingUserContextError.md +1 -1
  68. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  69. package/docs/api/classes/PermissionDeniedError.md +1 -1
  70. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  71. package/docs/api/classes/RBACAuditManager.md +1 -1
  72. package/docs/api/classes/RBACCache.md +1 -1
  73. package/docs/api/classes/RBACEngine.md +1 -1
  74. package/docs/api/classes/RBACError.md +1 -1
  75. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  76. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  77. package/docs/api/classes/StorageUtils.md +1 -1
  78. package/docs/api/enums/FileCategory.md +1 -1
  79. package/docs/api/interfaces/AggregateConfig.md +1 -1
  80. package/docs/api/interfaces/ButtonProps.md +3 -3
  81. package/docs/api/interfaces/CardProps.md +2 -2
  82. package/docs/api/interfaces/ColorPalette.md +1 -1
  83. package/docs/api/interfaces/ColorShade.md +1 -1
  84. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  85. package/docs/api/interfaces/DataTableAction.md +1 -1
  86. package/docs/api/interfaces/DataTableColumn.md +1 -1
  87. package/docs/api/interfaces/DataTableProps.md +1 -1
  88. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  89. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  90. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  91. package/docs/api/interfaces/EventLogoProps.md +2 -2
  92. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  93. package/docs/api/interfaces/FileMetadata.md +1 -1
  94. package/docs/api/interfaces/FileReference.md +1 -1
  95. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  96. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  97. package/docs/api/interfaces/FileUploadProps.md +1 -1
  98. package/docs/api/interfaces/FooterProps.md +1 -1
  99. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  100. package/docs/api/interfaces/InputProps.md +2 -2
  101. package/docs/api/interfaces/LabelProps.md +1 -1
  102. package/docs/api/interfaces/LoginFormProps.md +1 -1
  103. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  104. package/docs/api/interfaces/NavigationContextType.md +1 -1
  105. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  106. package/docs/api/interfaces/NavigationItem.md +1 -1
  107. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  108. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  109. package/docs/api/interfaces/Organisation.md +1 -1
  110. package/docs/api/interfaces/OrganisationContextType.md +28 -17
  111. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  112. package/docs/api/interfaces/OrganisationProviderProps.md +2 -2
  113. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  114. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  115. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  116. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  117. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  118. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  119. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  120. package/docs/api/interfaces/PaletteData.md +1 -1
  121. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  122. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  123. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  124. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +2 -2
  125. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  126. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  127. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  128. package/docs/api/interfaces/RBACConfig.md +1 -1
  129. package/docs/api/interfaces/RBACContextType.md +5 -11
  130. package/docs/api/interfaces/RBACLogger.md +1 -1
  131. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  132. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  134. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  135. package/docs/api/interfaces/RouteConfig.md +1 -1
  136. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  137. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  138. package/docs/api/interfaces/StorageConfig.md +1 -1
  139. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  140. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  141. package/docs/api/interfaces/StorageListOptions.md +1 -1
  142. package/docs/api/interfaces/StorageListResult.md +1 -1
  143. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  144. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  145. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  146. package/docs/api/interfaces/StyleImport.md +1 -1
  147. package/docs/api/interfaces/SwitchProps.md +1 -1
  148. package/docs/api/interfaces/ToastActionElement.md +1 -1
  149. package/docs/api/interfaces/ToastProps.md +1 -1
  150. package/docs/api/interfaces/UnifiedAuthContextType.md +524 -440
  151. package/docs/api/interfaces/UnifiedAuthProviderProps.md +14 -14
  152. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  153. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  154. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  159. package/docs/api/interfaces/UserEventAccess.md +11 -11
  160. package/docs/api/interfaces/UserMenuProps.md +1 -1
  161. package/docs/api/interfaces/UserProfile.md +1 -1
  162. package/docs/api/modules.md +179 -52
  163. package/docs/architecture/services.md +30 -32
  164. package/docs/breaking-changes.md +2 -5
  165. package/docs/implementation-guides/data-tables.md +82 -1
  166. package/docs/migration/service-architecture.md +121 -260
  167. package/docs/rbac/README-rbac-rls-integration.md +48 -38
  168. package/{src/rbac/examples → examples/RBAC}/CompleteRBACExample.tsx +3 -2
  169. package/{src/rbac/examples → examples/RBAC}/EventBasedApp.tsx +5 -4
  170. package/{src/components/examples → examples/RBAC}/PermissionExample.tsx +7 -6
  171. package/examples/RBAC/__tests__/PermissionExample.test.tsx +150 -0
  172. package/examples/RBAC/index.ts +13 -0
  173. package/examples/README.md +37 -0
  174. package/examples/index.ts +22 -0
  175. package/{src/examples → examples/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
  176. package/{src/examples → examples/public-pages}/PublicEventPage.tsx +1 -1
  177. package/{src/examples → examples/public-pages}/PublicPageApp.tsx +1 -1
  178. package/{src/examples → examples/public-pages}/PublicPageUsageExample.tsx +1 -1
  179. package/examples/public-pages/__tests__/PublicPageUsageExample.test.tsx +159 -0
  180. package/examples/public-pages/index.ts +14 -0
  181. package/package.json +22 -18
  182. package/src/__tests__/TEST_GUIDE_CURSOR.md +650 -9
  183. package/src/__tests__/helpers/README.md +255 -0
  184. package/src/__tests__/helpers/index.ts +62 -0
  185. package/src/__tests__/helpers/supabaseMock.ts +27 -3
  186. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -8
  187. package/src/components/DataTable/components/DataTableCore.tsx +37 -3
  188. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +55 -0
  189. package/src/components/DataTable/core/ColumnManager.ts +10 -0
  190. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +254 -0
  191. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +193 -0
  192. package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +45 -0
  193. package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +117 -0
  194. package/src/components/Dialog/Dialog.tsx +2 -2
  195. package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +71 -0
  196. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +122 -0
  197. package/src/components/EventSelector/EventSelector.tsx +1 -1
  198. package/src/components/Header/Header.test.tsx +35 -1
  199. package/src/components/Header/Header.tsx +3 -1
  200. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -3
  201. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +24 -4
  202. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +3 -2
  203. package/src/components/Toast/Toast.test.tsx +1 -1
  204. package/src/components/Toast/Toast.tsx +1 -1
  205. package/src/hooks/__tests__/useFocusManagement.unit.test.ts +220 -0
  206. package/src/hooks/__tests__/useIsMobile.unit.test.ts +117 -0
  207. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +295 -0
  208. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +29 -19
  209. package/src/hooks/__tests__/useRBAC.unit.test.ts +7 -3
  210. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +115 -19
  211. package/src/hooks/useEventTheme.test.ts +350 -0
  212. package/src/hooks/useEventTheme.ts +1 -1
  213. package/src/hooks/useEvents.ts +61 -0
  214. package/src/hooks/useOrganisationSecurity.test.ts +4 -4
  215. package/src/hooks/useOrganisationSecurity.ts +2 -2
  216. package/src/hooks/useOrganisations.ts +64 -0
  217. package/src/hooks/useSecureDataAccess.test.ts +9 -5
  218. package/src/hooks/useSecureDataAccess.ts +2 -2
  219. package/src/index.ts +18 -3
  220. package/src/providers/AuthProvider.tsx +8 -292
  221. package/src/providers/EventProvider.tsx +15 -425
  222. package/src/providers/InactivityProvider.tsx +8 -231
  223. package/src/providers/OrganisationProvider.test.simple.tsx +3 -2
  224. package/src/providers/OrganisationProvider.tsx +11 -890
  225. package/src/providers/UnifiedAuthProvider.tsx +8 -320
  226. package/src/providers/__tests__/AuthProvider.test.tsx +18 -17
  227. package/src/providers/__tests__/EventProvider.test.tsx +253 -2
  228. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +65 -0
  229. package/src/providers/__tests__/InactivityProvider.test.tsx +46 -114
  230. package/src/providers/__tests__/OrganisationProvider.test.tsx +313 -3
  231. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +383 -2
  232. package/src/providers/index.ts +8 -7
  233. package/src/providers/services/EventServiceProvider.tsx +3 -0
  234. package/src/providers/services/UnifiedAuthProvider.tsx +3 -0
  235. package/src/rbac/hooks/usePermissions.test.ts +296 -0
  236. package/src/rbac/hooks/useRBAC.test.ts +9 -5
  237. package/src/rbac/hooks/useRBAC.ts +3 -3
  238. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +688 -0
  239. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +507 -0
  240. package/src/services/AuthService.ts +19 -4
  241. package/src/services/__tests__/AuthService.test.ts +288 -0
  242. package/src/styles/core.css +2 -0
  243. package/src/types/__tests__/guards.test.ts +246 -0
  244. package/src/types/guards.ts +1 -0
  245. package/src/types/organisation.ts +3 -2
  246. package/src/validation/__tests__/sanitization.unit.test.ts +250 -0
  247. package/src/validation/__tests__/schemaUtils.unit.test.ts +451 -0
  248. package/src/validation/__tests__/user.unit.test.ts +440 -0
  249. package/dist/RBACProvider-BO4ilsQB.d.ts +0 -63
  250. package/dist/UnifiedAuthProvider-D02AMXgO.d.ts +0 -103
  251. package/dist/chunk-2PRPDH66.js.map +0 -1
  252. package/dist/chunk-3SP4P7NS.js.map +0 -1
  253. package/dist/chunk-43C63KLH.js.map +0 -1
  254. package/dist/chunk-5A4RL4BC.js +0 -5670
  255. package/dist/chunk-5A4RL4BC.js.map +0 -1
  256. package/dist/chunk-BYG6OSTC.js.map +0 -1
  257. package/dist/chunk-CDDYJCYU.js +0 -79
  258. package/dist/chunk-CDDYJCYU.js.map +0 -1
  259. package/dist/chunk-F24P24TZ.js +0 -17
  260. package/dist/chunk-F24P24TZ.js.map +0 -1
  261. package/dist/chunk-GBC5PC3N.js.map +0 -1
  262. package/dist/chunk-LANO5IFV.js.map +0 -1
  263. package/dist/chunk-M4UMXYNK.js.map +0 -1
  264. package/dist/chunk-RJNE764D.js +0 -953
  265. package/dist/chunk-RJNE764D.js.map +0 -1
  266. package/dist/chunk-UC2BWIK7.js.map +0 -1
  267. package/dist/rbac/cli/policy-manager.js +0 -278
  268. package/dist/rbac/cli/policy-manager.js.map +0 -1
  269. package/docs/api/interfaces/EventContextType.md +0 -96
  270. package/docs/api/interfaces/EventProviderProps.md +0 -19
  271. package/src/providers/OrganisationProvider.test.tsx +0 -164
  272. package/src/providers/UnifiedAuthProvider.test.tsx +0 -124
  273. package/src/providers/__tests__/AuthProvider.test.tsx.backup +0 -771
  274. package/src/providers/__tests__/EventProvider.test.tsx.backup +0 -824
  275. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +0 -820
  276. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +0 -911
  277. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +0 -166
  278. package/src/rbac/cli/__tests__/policy-manager.test.ts +0 -339
  279. package/src/rbac/cli/policy-manager.ts +0 -443
  280. package/dist/{DataTable-INW5YIFV.js.map → DataTable-HWZQGASI.js.map} +0 -0
  281. package/dist/{UnifiedAuthProvider-6SYT5WFN.js.map → UnifiedAuthProvider-3NKDOSOK.js.map} +0 -0
  282. package/dist/{validation-PM_iOaTI.d.ts → validation-D8VcbTzC.d.ts} +2 -2
  283. /package/src/utils/{appNameResolver.test.ts.backup → appNameResolver.test 2.ts} +0 -0
@@ -0,0 +1,440 @@
1
+ /**
2
+ * @file User Validation Schema Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Validation/__tests__
5
+ * @since 0.4.0
6
+ *
7
+ * Comprehensive tests for user validation schemas following TEST_GUIDE_CURSOR.md
8
+ */
9
+
10
+ import { describe, it, expect } from 'vitest';
11
+ import { userProfileSchema, userSettingsSchema, userPreferencesSchema } from '../user';
12
+
13
+ describe('[unit] User Validation Schemas', () => {
14
+ describe('userProfileSchema', () => {
15
+ it('validates complete user profile', () => {
16
+ const result = userProfileSchema.safeParse({
17
+ name: 'John Doe',
18
+ email: 'john@example.com',
19
+ phone: '1234567890',
20
+ website: 'https://example.com',
21
+ bio: 'Software developer',
22
+ });
23
+
24
+ expect(result.success).toBe(true);
25
+ if (result.success) {
26
+ expect(result.data.name).toBe('John Doe');
27
+ expect(result.data.email).toBe('john@example.com');
28
+ expect(result.data.phone).toBe('1234567890');
29
+ expect(result.data.website).toBe('https://example.com');
30
+ expect(result.data.bio).toBe('Software developer');
31
+ }
32
+ });
33
+
34
+ it('validates minimal required fields', () => {
35
+ const result = userProfileSchema.safeParse({
36
+ name: 'Jane Smith',
37
+ email: 'jane@example.com',
38
+ });
39
+
40
+ expect(result.success).toBe(true);
41
+ if (result.success) {
42
+ expect(result.data.name).toBe('Jane Smith');
43
+ expect(result.data.email).toBe('jane@example.com');
44
+ expect(result.data.phone).toBeUndefined();
45
+ expect(result.data.website).toBeUndefined();
46
+ expect(result.data.bio).toBeUndefined();
47
+ }
48
+ });
49
+
50
+ it('requires name field', () => {
51
+ const result = userProfileSchema.safeParse({
52
+ email: 'test@example.com',
53
+ });
54
+
55
+ expect(result.success).toBe(false);
56
+ if (!result.success) {
57
+ expect(result.error.issues[0].path).toContain('name');
58
+ }
59
+ });
60
+
61
+ it('requires email field', () => {
62
+ const result = userProfileSchema.safeParse({
63
+ name: 'Test User',
64
+ });
65
+
66
+ expect(result.success).toBe(false);
67
+ if (!result.success) {
68
+ expect(result.error.issues[0].path).toContain('email');
69
+ }
70
+ });
71
+
72
+ it('validates name format', () => {
73
+ const validResult = userProfileSchema.safeParse({
74
+ name: 'Mary Jane',
75
+ email: 'mary@example.com',
76
+ });
77
+ expect(validResult.success).toBe(true);
78
+
79
+ const invalidResult = userProfileSchema.safeParse({
80
+ name: 'John123',
81
+ email: 'john@example.com',
82
+ });
83
+ expect(invalidResult.success).toBe(false);
84
+ });
85
+
86
+ it('validates email format', () => {
87
+ const validResult = userProfileSchema.safeParse({
88
+ name: 'John Doe',
89
+ email: 'john@example.com',
90
+ });
91
+ expect(validResult.success).toBe(true);
92
+
93
+ const invalidResult = userProfileSchema.safeParse({
94
+ name: 'John Doe',
95
+ email: 'invalid-email',
96
+ });
97
+ expect(invalidResult.success).toBe(false);
98
+ });
99
+
100
+ it('validates phone format when provided', () => {
101
+ const result = userProfileSchema.safeParse({
102
+ name: 'John Doe',
103
+ email: 'john@example.com',
104
+ phone: '+1234567890',
105
+ });
106
+
107
+ // Phone validation depends on common.ts implementation
108
+ expect(result.success).toBeDefined();
109
+ });
110
+
111
+ it('validates website URL format when provided', () => {
112
+ const validResult = userProfileSchema.safeParse({
113
+ name: 'John Doe',
114
+ email: 'john@example.com',
115
+ website: 'https://example.com',
116
+ });
117
+ expect(validResult.success).toBe(true);
118
+
119
+ const invalidResult = userProfileSchema.safeParse({
120
+ name: 'John Doe',
121
+ email: 'john@example.com',
122
+ website: 'not-a-url',
123
+ });
124
+ expect(invalidResult.success).toBe(false);
125
+ });
126
+
127
+ it('validates bio length when provided', () => {
128
+ const validResult = userProfileSchema.safeParse({
129
+ name: 'John Doe',
130
+ email: 'john@example.com',
131
+ bio: 'This is a reasonable bio',
132
+ });
133
+ expect(validResult.success).toBe(true);
134
+
135
+ const tooLongBio = 'a'.repeat(501);
136
+ const invalidResult = userProfileSchema.safeParse({
137
+ name: 'John Doe',
138
+ email: 'john@example.com',
139
+ bio: tooLongBio,
140
+ });
141
+ expect(invalidResult.success).toBe(false);
142
+ });
143
+
144
+ it('handles bio with maximum allowed length', () => {
145
+ const maxBio = 'a'.repeat(500);
146
+ const result = userProfileSchema.safeParse({
147
+ name: 'John Doe',
148
+ email: 'john@example.com',
149
+ bio: maxBio,
150
+ });
151
+
152
+ expect(result.success).toBe(true);
153
+ });
154
+
155
+ it('rejects empty string for optional fields', () => {
156
+ const result = userProfileSchema.safeParse({
157
+ name: 'John Doe',
158
+ email: 'john@example.com',
159
+ bio: '',
160
+ });
161
+
162
+ // Empty string might be treated differently
163
+ expect(result.success).toBeDefined();
164
+ });
165
+ });
166
+
167
+ describe('userSettingsSchema', () => {
168
+ it('validates complete settings', () => {
169
+ const result = userSettingsSchema.safeParse({
170
+ notifications: {
171
+ email: true,
172
+ push: false,
173
+ },
174
+ language: 'en',
175
+ });
176
+
177
+ expect(result.success).toBe(true);
178
+ if (result.success) {
179
+ expect(result.data.notifications.email).toBe(true);
180
+ expect(result.data.notifications.push).toBe(false);
181
+ expect(result.data.language).toBe('en');
182
+ }
183
+ });
184
+
185
+ it('requires notifications object', () => {
186
+ const result = userSettingsSchema.safeParse({
187
+ language: 'en',
188
+ });
189
+
190
+ expect(result.success).toBe(false);
191
+ if (!result.success) {
192
+ expect(result.error.issues[0].path).toContain('notifications');
193
+ }
194
+ });
195
+
196
+ it('requires both email and push in notifications', () => {
197
+ const incompleteResult = userSettingsSchema.safeParse({
198
+ notifications: {
199
+ email: true,
200
+ // push missing
201
+ },
202
+ language: 'en',
203
+ });
204
+ expect(incompleteResult.success).toBe(false);
205
+
206
+ const completeResult = userSettingsSchema.safeParse({
207
+ notifications: {
208
+ email: true,
209
+ push: true,
210
+ },
211
+ language: 'en',
212
+ });
213
+ expect(completeResult.success).toBe(true);
214
+ });
215
+
216
+ it('validates notification boolean values', () => {
217
+ const emailTrueResult = userSettingsSchema.safeParse({
218
+ notifications: {
219
+ email: true,
220
+ push: false,
221
+ },
222
+ language: 'en',
223
+ });
224
+ expect(emailTrueResult.success).toBe(true);
225
+
226
+ const pushTrueResult = userSettingsSchema.safeParse({
227
+ notifications: {
228
+ email: false,
229
+ push: true,
230
+ },
231
+ language: 'en',
232
+ });
233
+ expect(pushTrueResult.success).toBe(true);
234
+ });
235
+
236
+ it('rejects non-boolean notification values', () => {
237
+ const result = userSettingsSchema.safeParse({
238
+ notifications: {
239
+ email: 'true',
240
+ push: false,
241
+ },
242
+ language: 'en',
243
+ });
244
+
245
+ expect(result.success).toBe(false);
246
+ });
247
+
248
+ it('requires language field', () => {
249
+ const result = userSettingsSchema.safeParse({
250
+ notifications: {
251
+ email: true,
252
+ push: true,
253
+ },
254
+ });
255
+
256
+ expect(result.success).toBe(false);
257
+ });
258
+
259
+ it('accepts various language codes', () => {
260
+ const languages = ['en', 'es', 'fr', 'de', 'zh'];
261
+
262
+ languages.forEach(lang => {
263
+ const result = userSettingsSchema.safeParse({
264
+ notifications: {
265
+ email: true,
266
+ push: true,
267
+ },
268
+ language: lang,
269
+ });
270
+ expect(result.success).toBe(true);
271
+ });
272
+ });
273
+ });
274
+
275
+ describe('userPreferencesSchema', () => {
276
+ it('validates complete preferences', () => {
277
+ const result = userPreferencesSchema.safeParse({
278
+ displayName: 'John Doe',
279
+ timezone: 'America/New_York',
280
+ dateFormat: 'MM/DD/YYYY',
281
+ currency: 'USD',
282
+ });
283
+
284
+ expect(result.success).toBe(true);
285
+ if (result.success) {
286
+ expect(result.data.displayName).toBe('John Doe');
287
+ expect(result.data.timezone).toBe('America/New_York');
288
+ expect(result.data.dateFormat).toBe('MM/DD/YYYY');
289
+ expect(result.data.currency).toBe('USD');
290
+ }
291
+ });
292
+
293
+ it('validates displayName format', () => {
294
+ const validResult = userPreferencesSchema.safeParse({
295
+ displayName: 'Mary Jane',
296
+ timezone: 'UTC',
297
+ dateFormat: 'YYYY-MM-DD',
298
+ currency: 'USD',
299
+ });
300
+ expect(validResult.success).toBe(true);
301
+
302
+ const invalidResult = userPreferencesSchema.safeParse({
303
+ displayName: 'User123',
304
+ timezone: 'UTC',
305
+ dateFormat: 'YYYY-MM-DD',
306
+ currency: 'USD',
307
+ });
308
+ expect(invalidResult.success).toBe(false);
309
+ });
310
+
311
+ it('accepts various timezone formats', () => {
312
+ const timezones = ['UTC', 'America/New_York', 'Europe/London', 'Asia/Tokyo'];
313
+
314
+ timezones.forEach(tz => {
315
+ const result = userPreferencesSchema.safeParse({
316
+ displayName: 'Test User',
317
+ timezone: tz,
318
+ dateFormat: 'YYYY-MM-DD',
319
+ currency: 'USD',
320
+ });
321
+ expect(result.success).toBe(true);
322
+ });
323
+ });
324
+
325
+ it('accepts various date formats', () => {
326
+ const dateFormats = ['MM/DD/YYYY', 'DD/MM/YYYY', 'YYYY-MM-DD', 'DD.MM.YYYY'];
327
+
328
+ dateFormats.forEach(format => {
329
+ const result = userPreferencesSchema.safeParse({
330
+ displayName: 'Test User',
331
+ timezone: 'UTC',
332
+ dateFormat: format,
333
+ currency: 'USD',
334
+ });
335
+ expect(result.success).toBe(true);
336
+ });
337
+ });
338
+
339
+ it('accepts various currency codes', () => {
340
+ const currencies = ['USD', 'EUR', 'GBP', 'JPY', 'CAD'];
341
+
342
+ currencies.forEach(currency => {
343
+ const result = userPreferencesSchema.safeParse({
344
+ displayName: 'Test User',
345
+ timezone: 'UTC',
346
+ dateFormat: 'YYYY-MM-DD',
347
+ currency: currency,
348
+ });
349
+ expect(result.success).toBe(true);
350
+ });
351
+ });
352
+ });
353
+
354
+ describe('Edge Cases', () => {
355
+ it('userProfileSchema rejects invalid data types', () => {
356
+ const invalidResults = [
357
+ userProfileSchema.safeParse({
358
+ name: 123,
359
+ email: 'test@example.com',
360
+ }),
361
+ userProfileSchema.safeParse({
362
+ name: 'Test',
363
+ email: true,
364
+ }),
365
+ ];
366
+
367
+ invalidResults.forEach(result => {
368
+ expect(result.success).toBe(false);
369
+ });
370
+ });
371
+
372
+ it('userSettingsSchema rejects invalid notification structure', () => {
373
+ const result = userSettingsSchema.safeParse({
374
+ notifications: {
375
+ email: true,
376
+ push: false,
377
+ invalid: true,
378
+ },
379
+ language: 'en',
380
+ });
381
+
382
+ // May accept extra fields or reject them
383
+ expect(result.success).toBeDefined();
384
+ });
385
+
386
+ it('handles very long valid input', () => {
387
+ const longName = 'A'.repeat(100);
388
+ const result = userProfileSchema.safeParse({
389
+ name: longName,
390
+ email: 'test@example.com',
391
+ });
392
+
393
+ expect(result.success).toBe(true);
394
+ });
395
+ });
396
+
397
+ describe('Integration', () => {
398
+ it('validates all user schemas together', () => {
399
+ const profile = {
400
+ name: 'John Doe',
401
+ email: 'john@example.com',
402
+ };
403
+ const settings = {
404
+ notifications: {
405
+ email: true,
406
+ push: false,
407
+ },
408
+ language: 'en',
409
+ };
410
+ const preferences = {
411
+ displayName: 'John Doe',
412
+ timezone: 'America/New_York',
413
+ dateFormat: 'MM/DD/YYYY',
414
+ currency: 'USD',
415
+ };
416
+
417
+ const profileResult = userProfileSchema.safeParse(profile);
418
+ const settingsResult = userSettingsSchema.safeParse(settings);
419
+ const preferencesResult = userPreferencesSchema.safeParse(preferences);
420
+
421
+ expect(profileResult.success).toBe(true);
422
+ expect(settingsResult.success).toBe(true);
423
+ expect(preferencesResult.success).toBe(true);
424
+ });
425
+
426
+ it('handles realistic user data', () => {
427
+ const realisticProfile = {
428
+ name: 'Jane Smith',
429
+ email: 'jane.smith@example.com',
430
+ phone: '+1-555-123-4567',
431
+ website: 'https://janesmith.dev',
432
+ bio: 'Full-stack developer with a passion for clean code.',
433
+ };
434
+
435
+ const result = userProfileSchema.safeParse(realisticProfile);
436
+ expect(result.success).toBe(true);
437
+ });
438
+ });
439
+ });
440
+
@@ -1,63 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React__default from 'react';
3
- import { SupabaseClient, User, Session } from '@supabase/supabase-js';
4
- import { A as AccessLevel } from './unified-CMPjE_fv.js';
5
-
6
- interface AppConfig {
7
- supports_direct_access: boolean;
8
- requires_event: boolean;
9
- }
10
- interface UserEventAccess {
11
- event_id: string;
12
- event_name: string;
13
- event_description?: string | null;
14
- start_date: string;
15
- end_date: string;
16
- event_status: string;
17
- app_id: string;
18
- access_level: string;
19
- granted_at: string;
20
- organisation_id: string;
21
- }
22
- interface RBACContextType {
23
- permissions: Record<string, boolean>;
24
- roles: string[];
25
- accessLevel: AccessLevel;
26
- rbacLoading: boolean;
27
- rbacError: Error | null;
28
- selectedEventId: string | null;
29
- appConfig: AppConfig | null;
30
- userEventAccess: UserEventAccess[];
31
- eventAccessLoading: boolean;
32
- selectedOrganisationId: string | null;
33
- requireOrganisationContext: () => string;
34
- hasPermission: (permission: string, orgId?: string) => boolean;
35
- hasAnyPermission: (permissions: string[], orgId?: string) => boolean;
36
- hasAllPermissions: (permissions: string[], orgId?: string) => boolean;
37
- hasRole: (role: string) => boolean;
38
- hasAccessLevel: (level: AccessLevel) => boolean;
39
- canAccess: (resource: string, action: string, orgId?: string) => boolean;
40
- validatePermission: (permission: string, orgId?: string) => Promise<boolean>;
41
- validateAccess: (resource: string, action: string, orgId?: string) => Promise<boolean>;
42
- refreshPermissions: (eventId?: string, orgId?: string) => Promise<void>;
43
- setSelectedEventId: (eventId: string | null) => void;
44
- loadUserEventAccess: (orgId?: string) => Promise<void>;
45
- getUserEventAccess: (eventId: string) => UserEventAccess | undefined;
46
- rbacEnabled: boolean;
47
- rbacContext?: any;
48
- }
49
- declare const useRBAC: () => RBACContextType;
50
- interface RBACProviderProps {
51
- children: React__default.ReactNode;
52
- supabaseClient?: SupabaseClient;
53
- user: User | null;
54
- session: Session | null;
55
- appName: string;
56
- enableRBAC?: boolean;
57
- persistState?: boolean;
58
- enablePersistence?: boolean;
59
- requireOrganisationContext?: boolean;
60
- }
61
- declare function RBACProvider({ children, supabaseClient, user, session, appName, enableRBAC, persistState, enablePersistence, requireOrganisationContext: _requireOrganisationContext, }: RBACProviderProps): react_jsx_runtime.JSX.Element;
62
-
63
- export { type RBACContextType as R, type UserEventAccess as U, RBACProvider as a, type RBACProviderProps as b, useRBAC as u };
@@ -1,103 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React__default from 'react';
3
- import { User, Session, AuthError, SupabaseClient } from '@supabase/supabase-js';
4
- import { R as RBACContextType } from './RBACProvider-BO4ilsQB.js';
5
-
6
- interface AuthContextType {
7
- user: User | null;
8
- session: Session | null;
9
- isAuthenticated: boolean;
10
- authLoading: boolean;
11
- authError: AuthError | null;
12
- error: AuthError | null;
13
- supabase: SupabaseClient | null;
14
- signIn: (email: string, password?: string) => Promise<{
15
- error: AuthError | null;
16
- }>;
17
- signUp: (email: string, password: string) => Promise<{
18
- error: AuthError | null;
19
- }>;
20
- signOut: () => Promise<{
21
- error: AuthError | null;
22
- }>;
23
- resetPassword: (email: string) => Promise<{
24
- error: AuthError | null;
25
- }>;
26
- updatePassword: (password: string) => Promise<{
27
- error: AuthError | null;
28
- }>;
29
- refreshSession: () => Promise<{
30
- error: AuthError | null;
31
- }>;
32
- }
33
- interface AuthProviderProps {
34
- children: React__default.ReactNode;
35
- supabaseClient?: SupabaseClient;
36
- }
37
- declare function AuthProvider({ children, supabaseClient }: AuthProviderProps): react_jsx_runtime.JSX.Element;
38
- declare const useAuth: () => AuthContextType;
39
-
40
- interface InactivityContextType {
41
- showInactivityWarning: boolean;
42
- inactivityTimeRemaining: number;
43
- isIdle: boolean;
44
- timeRemaining: number;
45
- showWarning: boolean;
46
- isTracking: boolean;
47
- resetActivity: () => void;
48
- startTracking: () => void;
49
- stopTracking: () => void;
50
- handleIdleLogout: () => Promise<void>;
51
- handleStaySignedIn: () => void;
52
- handleSignOutNow: () => Promise<void>;
53
- }
54
- declare const useInactivity: () => InactivityContextType;
55
- interface InactivityProviderProps {
56
- children: React__default.ReactNode;
57
- user: any;
58
- session: any;
59
- supabaseClient: any;
60
- idleTimeoutMs?: number;
61
- warnBeforeMs?: number;
62
- onIdleLogout?: (reason: 'inactivity') => void;
63
- renderInactivityWarning?: (args: {
64
- timeRemaining: number;
65
- onStaySignedIn: () => void;
66
- onSignOutNow: () => void;
67
- }) => React__default.ReactNode;
68
- dangerouslyDisableInactivity?: boolean;
69
- }
70
- declare function InactivityProvider({ children, user, session, supabaseClient, idleTimeoutMs, // 30 minutes
71
- warnBeforeMs, // 60 seconds
72
- onIdleLogout, renderInactivityWarning, dangerouslyDisableInactivity }: InactivityProviderProps): react_jsx_runtime.JSX.Element;
73
-
74
- interface UnifiedAuthContextType extends AuthContextType, RBACContextType, InactivityContextType {
75
- appName: string;
76
- isLoading: boolean;
77
- hasErrors: boolean;
78
- }
79
- declare const useUnifiedAuth: () => UnifiedAuthContextType;
80
- interface UnifiedAuthProviderProps {
81
- children: React__default.ReactNode;
82
- supabaseClient?: SupabaseClient;
83
- appName: string;
84
- persistState?: boolean;
85
- enablePersistence?: boolean;
86
- requireOrganisationContext?: boolean;
87
- enableRBAC?: boolean;
88
- idleTimeoutMs: number;
89
- warnBeforeMs: number;
90
- onIdleLogout: (reason: 'inactivity') => void;
91
- renderInactivityWarning?: (args: {
92
- timeRemaining: number;
93
- onStaySignedIn: () => void;
94
- onSignOutNow: () => void;
95
- }) => React__default.ReactNode;
96
- dangerouslyDisableInactivity?: boolean;
97
- }
98
-
99
- declare function UnifiedAuthProvider({ children, supabaseClient, appName, persistState, enablePersistence, requireOrganisationContext, enableRBAC, idleTimeoutMs, // 30 minutes
100
- warnBeforeMs, // 60 seconds
101
- onIdleLogout, renderInactivityWarning, dangerouslyDisableInactivity }: UnifiedAuthProviderProps): react_jsx_runtime.JSX.Element;
102
-
103
- export { type AuthContextType as A, type InactivityContextType as I, UnifiedAuthProvider as U, type UnifiedAuthProviderProps as a, type UnifiedAuthContextType as b, type AuthProviderProps as c, AuthProvider as d, useAuth as e, useInactivity as f, type InactivityProviderProps as g, InactivityProvider as h, useUnifiedAuth as u };