@jmruthers/pace-core 0.5.135 → 0.5.137

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 (544) hide show
  1. package/dist/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
  2. package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
  3. package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
  4. package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
  5. package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
  6. package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
  7. package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
  8. package/dist/{chunk-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
  9. package/dist/chunk-22WKWKRX.js.map +1 -0
  10. package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
  11. package/dist/chunk-4C7EXCAR.js.map +1 -0
  12. package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
  13. package/dist/chunk-56XJ3TU6.js.map +1 -0
  14. package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
  15. package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
  16. package/dist/chunk-7QCC6MCP.js.map +1 -0
  17. package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
  18. package/dist/chunk-ANBQRTPX.js.map +1 -0
  19. package/dist/{chunk-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
  20. package/dist/chunk-BCIBECNB.js.map +1 -0
  21. package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
  22. package/dist/chunk-BESYRHQM.js.map +1 -0
  23. package/dist/chunk-BJPBT3CU.js +21 -0
  24. package/dist/chunk-BJPBT3CU.js.map +1 -0
  25. package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
  26. package/dist/chunk-BLCXZEYF.js.map +1 -0
  27. package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
  28. package/dist/chunk-BVYWGZVV.js.map +1 -0
  29. package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
  30. package/dist/chunk-ERISIBYU.js.map +1 -0
  31. package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
  32. package/dist/chunk-FMUCXFII.js.map +1 -0
  33. package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
  34. package/dist/chunk-HAWZXGR2.js.map +1 -0
  35. package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
  36. package/dist/chunk-JISYG63F.js +70 -0
  37. package/dist/chunk-JISYG63F.js.map +1 -0
  38. package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
  39. package/dist/chunk-KYRHUBIU.js.map +1 -0
  40. package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
  41. package/dist/chunk-LS353YLY.js.map +1 -0
  42. package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
  43. package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
  44. package/dist/chunk-OWAG3GSU.js +58 -0
  45. package/dist/chunk-OWAG3GSU.js.map +1 -0
  46. package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
  47. package/dist/chunk-Q5QRDWKI.js.map +1 -0
  48. package/dist/chunk-S5OFRT4M.js +94 -0
  49. package/dist/chunk-S5OFRT4M.js.map +1 -0
  50. package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
  51. package/dist/chunk-SBVILCCA.js.map +1 -0
  52. package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
  53. package/dist/chunk-T6JN6LH6.js.map +1 -0
  54. package/dist/chunk-XDNLUEXI.js +138 -0
  55. package/dist/chunk-XDNLUEXI.js.map +1 -0
  56. package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
  57. package/dist/chunk-YCWDTTUK.js.map +1 -0
  58. package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
  59. package/dist/chunk-ZZ2SS7NI.js.map +1 -0
  60. package/dist/components.d.ts +7 -287
  61. package/dist/components.js +27 -157
  62. package/dist/components.js.map +1 -1
  63. package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
  64. package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
  65. package/dist/hooks.d.ts +3 -3
  66. package/dist/hooks.js +21 -16
  67. package/dist/hooks.js.map +1 -1
  68. package/dist/index.d.ts +101 -9
  69. package/dist/index.js +44 -31
  70. package/dist/index.js.map +1 -1
  71. package/dist/providers.d.ts +1 -1
  72. package/dist/providers.js +4 -4
  73. package/dist/rbac/index.js +12 -12
  74. package/dist/schema-DTDZQe2u.d.ts +28 -0
  75. package/dist/styles/index.js +2 -1
  76. package/dist/theming/runtime.d.ts +2 -19
  77. package/dist/theming/runtime.js +2 -1
  78. package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
  79. package/dist/types.d.ts +153 -4
  80. package/dist/types.js +51 -16
  81. package/dist/types.js.map +1 -1
  82. package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
  83. package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
  84. package/dist/utils.d.ts +221 -173
  85. package/dist/utils.js +185 -225
  86. package/dist/utils.js.map +1 -1
  87. package/dist/validation.d.ts +24 -115
  88. package/dist/validation.js +19 -474
  89. package/dist/validation.js.map +1 -1
  90. package/docs/api/classes/ColumnFactory.md +1 -1
  91. package/docs/api/classes/ErrorBoundary.md +6 -6
  92. package/docs/api/classes/InvalidScopeError.md +1 -1
  93. package/docs/api/classes/MissingUserContextError.md +1 -1
  94. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  95. package/docs/api/classes/PermissionDeniedError.md +1 -1
  96. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  97. package/docs/api/classes/RBACAuditManager.md +6 -6
  98. package/docs/api/classes/RBACCache.md +1 -1
  99. package/docs/api/classes/RBACEngine.md +7 -7
  100. package/docs/api/classes/RBACError.md +1 -1
  101. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  102. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  103. package/docs/api/classes/StorageUtils.md +1 -1
  104. package/docs/api/enums/FileCategory.md +1 -1
  105. package/docs/api/interfaces/AggregateConfig.md +4 -4
  106. package/docs/api/interfaces/BadgeProps.md +27 -0
  107. package/docs/api/interfaces/ButtonProps.md +1 -1
  108. package/docs/api/interfaces/CardProps.md +1 -1
  109. package/docs/api/interfaces/ColorPalette.md +1 -1
  110. package/docs/api/interfaces/ColorShade.md +29 -4
  111. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  112. package/docs/api/interfaces/DataRecord.md +1 -1
  113. package/docs/api/interfaces/DataTableAction.md +18 -18
  114. package/docs/api/interfaces/DataTableColumn.md +61 -1
  115. package/docs/api/interfaces/DataTableProps.md +1 -1
  116. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  117. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  118. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
  119. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  120. package/docs/api/interfaces/EventLogoProps.md +152 -0
  121. package/docs/api/interfaces/ExportColumn.md +1 -1
  122. package/docs/api/interfaces/ExportOptions.md +8 -8
  123. package/docs/api/interfaces/FileDisplayProps.md +15 -15
  124. package/docs/api/interfaces/FileMetadata.md +1 -1
  125. package/docs/api/interfaces/FileReference.md +1 -1
  126. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  127. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  128. package/docs/api/interfaces/FileUploadProps.md +1 -1
  129. package/docs/api/interfaces/FooterProps.md +1 -1
  130. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  131. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  132. package/docs/api/interfaces/InputProps.md +1 -1
  133. package/docs/api/interfaces/LabelProps.md +1 -1
  134. package/docs/api/interfaces/LoginFormProps.md +1 -1
  135. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  136. package/docs/api/interfaces/NavigationContextType.md +9 -9
  137. package/docs/api/interfaces/NavigationGuardProps.md +10 -10
  138. package/docs/api/interfaces/NavigationItem.md +1 -1
  139. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  140. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  141. package/docs/api/interfaces/Organisation.md +1 -1
  142. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  143. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  144. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  145. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  146. package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
  147. package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
  148. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  149. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  150. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  151. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  152. package/docs/api/interfaces/PaletteData.md +4 -4
  153. package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
  154. package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
  155. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  156. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  157. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  158. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  159. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  160. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  161. package/docs/api/interfaces/RBACConfig.md +1 -1
  162. package/docs/api/interfaces/RBACLogger.md +1 -1
  163. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  164. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  165. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  166. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  167. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  168. package/docs/api/interfaces/RouteConfig.md +10 -10
  169. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  170. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  171. package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
  172. package/docs/api/interfaces/StorageConfig.md +1 -1
  173. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  174. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  175. package/docs/api/interfaces/StorageListOptions.md +1 -1
  176. package/docs/api/interfaces/StorageListResult.md +1 -1
  177. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  178. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  179. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  180. package/docs/api/interfaces/StyleImport.md +1 -1
  181. package/docs/api/interfaces/SwitchProps.md +1 -1
  182. package/docs/api/interfaces/ToastActionElement.md +1 -1
  183. package/docs/api/interfaces/ToastProps.md +1 -1
  184. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  185. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  186. package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
  187. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  188. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  189. package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
  190. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  191. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
  192. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  193. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  194. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  195. package/docs/api/interfaces/UserEventAccess.md +11 -11
  196. package/docs/api/interfaces/UserMenuProps.md +1 -1
  197. package/docs/api/interfaces/UserProfile.md +1 -1
  198. package/docs/api/modules.md +591 -220
  199. package/docs/api-reference/components.md +106 -26
  200. package/docs/architecture/README.md +0 -3
  201. package/docs/implementation-guides/data-tables.md +277 -13
  202. package/docs/implementation-guides/forms.md +1 -16
  203. package/docs/implementation-guides/permission-enforcement.md +8 -2
  204. package/docs/styles/README.md +0 -2
  205. package/examples/README.md +30 -14
  206. package/examples/STRUCTURE.md +125 -0
  207. package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
  208. package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
  209. package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
  210. package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
  211. package/examples/components 2/DataTable/index.ts +13 -0
  212. package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
  213. package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
  214. package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
  215. package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
  216. package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
  217. package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
  218. package/examples/components 2/Dialog/index.ts +15 -0
  219. package/examples/components 2/index.ts +11 -0
  220. package/examples/features/index.ts +12 -0
  221. package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
  222. package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
  223. package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
  224. package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
  225. package/examples/features/public-pages/index.ts +14 -0
  226. package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
  227. package/examples/features/rbac/EventBasedApp.tsx +239 -0
  228. package/examples/features/rbac/PermissionExample.tsx +151 -0
  229. package/examples/features/rbac/index.ts +13 -0
  230. package/examples/index.ts +11 -3
  231. package/package.json +30 -19
  232. package/src/__tests__/TEST_STANDARD.md +92 -0
  233. package/src/components/Alert/Alert.tsx +1 -1
  234. package/src/components/Avatar/Avatar.tsx +1 -1
  235. package/src/components/Badge/Badge.test.tsx +314 -0
  236. package/src/components/Badge/Badge.tsx +304 -0
  237. package/src/components/Badge/index.ts +3 -0
  238. package/src/components/Button/Button.tsx +1 -1
  239. package/src/components/Card/Card.tsx +1 -1
  240. package/src/components/Checkbox/Checkbox.tsx +1 -1
  241. package/src/components/DataTable/DataTable.test.tsx +1 -1
  242. package/src/components/DataTable/DataTable.tsx +1 -30
  243. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
  244. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
  245. package/src/components/DataTable/__tests__/styles.test.ts +3 -3
  246. package/src/components/DataTable/components/ActionButtons.tsx +0 -15
  247. package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
  248. package/src/components/DataTable/components/DataTableBody.tsx +461 -0
  249. package/src/components/DataTable/components/DataTableCore.tsx +4 -185
  250. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
  251. package/src/components/DataTable/components/DataTableModals.tsx +1 -27
  252. package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
  253. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  254. package/src/components/DataTable/components/FilterRow.tsx +9 -3
  255. package/src/components/DataTable/components/ImportModal.tsx +2 -14
  256. package/src/components/DataTable/components/PaginationControls.tsx +2 -1
  257. package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
  258. package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
  259. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
  260. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
  261. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
  262. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
  263. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
  264. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
  265. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
  266. package/src/components/DataTable/core/ActionManager.ts +235 -0
  267. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  268. package/src/components/DataTable/core/DataManager.ts +188 -0
  269. package/src/components/DataTable/core/DataTableContext.tsx +181 -0
  270. package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
  271. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  272. package/src/components/DataTable/core/StateManager.ts +311 -0
  273. package/src/components/DataTable/core/interfaces.ts +338 -0
  274. package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
  275. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
  276. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
  277. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
  278. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
  280. package/src/components/DataTable/index.ts +4 -0
  281. package/src/components/DataTable/styles.ts +28 -7
  282. package/src/components/DataTable/types.ts +13 -0
  283. package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
  284. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
  285. package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
  286. package/src/components/DataTable/utils/columnUtils.ts +40 -0
  287. package/src/components/DataTable/utils/debugTools.ts +609 -0
  288. package/src/components/DataTable/utils/exportUtils.ts +1 -1
  289. package/src/components/DataTable/utils/flexibleImport.ts +1 -11
  290. package/src/components/DataTable/utils/index.ts +2 -0
  291. package/src/components/DataTable/utils/paginationUtils.ts +1 -1
  292. package/src/components/Dialog/Dialog.tsx +2 -2
  293. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
  294. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
  295. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
  296. package/src/components/EventSelector/EventSelector.tsx +3 -2
  297. package/src/components/FileDisplay/FileDisplay.tsx +2 -36
  298. package/src/components/FileUpload/FileUpload.test.tsx +2 -2
  299. package/src/components/FileUpload/FileUpload.tsx +2 -2
  300. package/src/components/Footer/Footer.test.tsx +1 -1
  301. package/src/components/Footer/Footer.tsx +1 -1
  302. package/src/components/Form/Form.test.tsx +5 -510
  303. package/src/components/Form/Form.tsx +1 -1
  304. package/src/components/Form/FormField.tsx +1 -1
  305. package/src/components/Form/index.ts +0 -12
  306. package/src/components/Header/Header.tsx +1 -1
  307. package/src/components/Input/Input.tsx +1 -1
  308. package/src/components/Label/Label.tsx +1 -1
  309. package/src/components/LoginForm/LoginForm.test.tsx +1 -1
  310. package/src/components/LoginForm/LoginForm.tsx +1 -1
  311. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
  312. package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
  313. package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
  314. package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
  315. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
  316. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
  317. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
  318. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
  319. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
  320. package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
  321. package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
  322. package/src/components/PasswordReset/index.ts +0 -2
  323. package/src/components/Progress/Progress.tsx +1 -1
  324. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
  325. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
  326. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  327. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
  328. package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
  329. package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
  330. package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
  331. package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
  332. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
  333. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
  334. package/src/components/PublicLayout/index.ts +4 -2
  335. package/src/components/Select/Select.test.tsx +1 -1
  336. package/src/components/Select/Select.tsx +21 -9
  337. package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
  338. package/src/components/SessionRestorationLoader/index.ts +3 -0
  339. package/src/components/Switch/Switch.tsx +1 -1
  340. package/src/components/Table/Table.tsx +1 -1
  341. package/src/components/Table/__tests__/Table.test.tsx +1 -1
  342. package/src/components/Toast/Toast.tsx +1 -1
  343. package/src/components/Tooltip/Tooltip.tsx +1 -1
  344. package/src/components/index.ts +7 -10
  345. package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
  346. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
  347. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
  348. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
  349. package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
  350. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
  351. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
  352. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
  353. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
  354. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
  355. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
  356. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
  357. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
  358. package/src/hooks/public/usePublicEvent.ts +7 -6
  359. package/src/hooks/public/usePublicEventLogo.ts +7 -4
  360. package/src/hooks/public/usePublicFileDisplay.ts +6 -150
  361. package/src/hooks/useComponentPerformance.ts +4 -1
  362. package/src/hooks/useDataTablePerformance.ts +4 -3
  363. package/src/hooks/useEventTheme.test.ts +18 -5
  364. package/src/hooks/useEventTheme.ts +4 -1
  365. package/src/hooks/useEvents.ts +2 -0
  366. package/src/hooks/useFileDisplay.ts +9 -8
  367. package/src/hooks/useFileReference.ts +4 -1
  368. package/src/hooks/useFileUrl.ts +4 -1
  369. package/src/hooks/useInactivityTracker.ts +5 -4
  370. package/src/hooks/useOrganisationSecurity.test.ts +33 -12
  371. package/src/hooks/useOrganisationSecurity.ts +8 -7
  372. package/src/hooks/usePerformanceMonitor.ts +6 -3
  373. package/src/hooks/usePermissionCache.ts +13 -6
  374. package/src/hooks/useSecureDataAccess.test.ts +2 -2
  375. package/src/hooks/useSecureDataAccess.ts +9 -8
  376. package/src/hooks/useSessionRestoration.ts +4 -1
  377. package/src/hooks/useStorage.ts +4 -1
  378. package/src/index.ts +20 -7
  379. package/src/providers/services/AuthServiceProvider.tsx +3 -2
  380. package/src/providers/services/EventServiceProvider.tsx +2 -1
  381. package/src/providers/services/InactivityServiceProvider.tsx +2 -1
  382. package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
  383. package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
  384. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
  385. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
  386. package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
  387. package/src/rbac/api.ts +5 -2
  388. package/src/rbac/audit-enhanced.ts +6 -6
  389. package/src/rbac/audit.test.ts +60 -38
  390. package/src/rbac/audit.ts +8 -8
  391. package/src/rbac/cache-invalidation.ts +7 -4
  392. package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
  393. package/src/rbac/components/NavigationGuard.tsx +7 -3
  394. package/src/rbac/components/NavigationProvider.tsx +6 -3
  395. package/src/rbac/components/PagePermissionGuard.tsx +28 -16
  396. package/src/rbac/components/PagePermissionProvider.tsx +4 -1
  397. package/src/rbac/components/PermissionEnforcer.tsx +9 -3
  398. package/src/rbac/components/RoleBasedRouter.tsx +3 -1
  399. package/src/rbac/components/SecureDataProvider.tsx +7 -3
  400. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
  401. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
  402. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
  403. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
  404. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
  405. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
  406. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
  407. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
  408. package/src/rbac/engine.ts +15 -7
  409. package/src/rbac/hooks/usePermissions.ts +7 -3
  410. package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
  411. package/src/rbac/hooks/useResolvedScope.ts +10 -7
  412. package/src/rbac/permissions.ts +5 -2
  413. package/src/rbac/security.test.ts +27 -16
  414. package/src/rbac/security.ts +5 -4
  415. package/src/services/AuthService.ts +22 -21
  416. package/src/services/EventService.ts +12 -12
  417. package/src/services/InactivityService.ts +5 -4
  418. package/src/services/OrganisationService.ts +26 -25
  419. package/src/services/__tests__/AuthService.test.ts +51 -19
  420. package/src/services/__tests__/EventService.test.ts +37 -5
  421. package/src/services/__tests__/InactivityService.test.ts +38 -4
  422. package/src/services/__tests__/OrganisationService.test.ts +3 -8
  423. package/src/services/base/BaseService.ts +3 -1
  424. package/src/styles/core.css +3 -0
  425. package/src/theming/__tests__/runtime.test.ts +21 -12
  426. package/src/theming/parseEventColours.ts +5 -19
  427. package/src/theming/runtime.ts +8 -4
  428. package/src/types/validation.ts +2 -29
  429. package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
  430. package/src/utils/__tests__/audit.unit.test.ts +1 -1
  431. package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
  432. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
  433. package/src/utils/__tests__/cn.unit.test.ts +1 -1
  434. package/src/utils/__tests__/debugLogger.test.ts +1 -1
  435. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
  436. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
  437. package/src/utils/__tests__/formatting.unit.test.ts +1 -1
  438. package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
  439. package/src/utils/__tests__/logger.unit.test.ts +1 -1
  440. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
  441. package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
  442. package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
  443. package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
  444. package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
  445. package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
  446. package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
  447. package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
  448. package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
  449. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
  450. package/src/utils/__tests__/security.unit.test.ts +40 -18
  451. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
  452. package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
  453. package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
  454. package/src/utils/app/appConfig.ts +47 -0
  455. package/src/utils/app/appIdResolver.test.ts +497 -0
  456. package/src/utils/app/appIdResolver.ts +133 -0
  457. package/src/utils/app/appNameResolver.simple.test.ts +212 -0
  458. package/src/utils/app/appNameResolver.test.ts +121 -0
  459. package/src/utils/app/appNameResolver.ts +195 -0
  460. package/src/utils/audit/audit.ts +127 -0
  461. package/src/utils/context/organisationContext.test.ts +322 -0
  462. package/src/utils/context/organisationContext.ts +156 -0
  463. package/src/utils/context/sessionTracking.ts +125 -0
  464. package/src/utils/core/cn.ts +7 -0
  465. package/src/utils/core/debugLogger.ts +67 -0
  466. package/src/utils/core/logger.ts +181 -0
  467. package/src/utils/device/deviceFingerprint.ts +215 -0
  468. package/src/utils/dynamic/dynamicUtils.ts +105 -0
  469. package/src/utils/dynamic/lazyLoad.tsx +44 -0
  470. package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
  471. package/src/utils/file-reference/index.ts +501 -0
  472. package/src/utils/formatting/formatDate.test.ts +237 -0
  473. package/src/utils/formatting/formatting.ts +133 -0
  474. package/src/utils/index.ts +39 -54
  475. package/src/utils/performance/bundleAnalysis.ts +129 -0
  476. package/src/utils/performance/performanceBenchmark.ts +64 -0
  477. package/src/utils/performance/performanceBudgets.ts +110 -0
  478. package/src/utils/permissions/permissionTypes.ts +37 -0
  479. package/src/utils/permissions/permissionUtils.test.ts +393 -0
  480. package/src/utils/permissions/permissionUtils.ts +34 -0
  481. package/src/utils/security/auth-utils.ts +96 -0
  482. package/src/utils/security/secureDataAccess.test.ts +711 -0
  483. package/src/utils/security/secureDataAccess.ts +377 -0
  484. package/src/utils/security/secureErrors.ts +82 -0
  485. package/src/utils/security/secureStorage.ts +244 -0
  486. package/src/utils/security/security.ts +159 -0
  487. package/src/utils/security/securityMonitor.ts +45 -0
  488. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
  489. package/src/utils/storage/helpers.ts +15 -8
  490. package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
  491. package/src/{validation → utils/validation}/csrf.ts +1 -1
  492. package/src/utils/validation/htmlSanitization.ts +184 -0
  493. package/src/utils/validation/index.ts +79 -0
  494. package/src/utils/validation/sanitization.ts +333 -0
  495. package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
  496. package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
  497. package/src/utils/validation/validation.ts +111 -0
  498. package/src/utils/validation/validationUtils.ts +123 -0
  499. package/src/validation/index.ts +3 -34
  500. package/dist/chunk-24MKLB7U.js +0 -81
  501. package/dist/chunk-24MKLB7U.js.map +0 -1
  502. package/dist/chunk-3CG5L6RN.js.map +0 -1
  503. package/dist/chunk-3DBFLLLU.js.map +0 -1
  504. package/dist/chunk-5F3NDPJV.js.map +0 -1
  505. package/dist/chunk-66C4BSAY.js.map +0 -1
  506. package/dist/chunk-BDZUMRBD.js +0 -87
  507. package/dist/chunk-BDZUMRBD.js.map +0 -1
  508. package/dist/chunk-BYXRHAIF.js.map +0 -1
  509. package/dist/chunk-CDQ3PX7L.js +0 -18
  510. package/dist/chunk-CDQ3PX7L.js.map +0 -1
  511. package/dist/chunk-CQZU6TFE.js.map +0 -1
  512. package/dist/chunk-F64FFPOZ.js.map +0 -1
  513. package/dist/chunk-GEVIB2UB.js.map +0 -1
  514. package/dist/chunk-GKHF54DI.js.map +0 -1
  515. package/dist/chunk-GVDR7WNV.js.map +0 -1
  516. package/dist/chunk-HMNOSGVA.js.map +0 -1
  517. package/dist/chunk-JCQZ6LA7.js.map +0 -1
  518. package/dist/chunk-M6DDYFUD.js.map +0 -1
  519. package/dist/chunk-O3NWNXDY.js.map +0 -1
  520. package/dist/chunk-PYUXFQJ3.js.map +0 -1
  521. package/dist/chunk-UJI6WSMD.js.map +0 -1
  522. package/dist/chunk-VZ5OR6HD.js.map +0 -1
  523. package/dist/chunk-WP5I5GLN.js.map +0 -1
  524. package/dist/chunk-ZYZCRSBD.js.map +0 -1
  525. package/dist/validation-DnhrNMju.d.ts +0 -159
  526. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
  527. package/src/validation/__tests__/common.unit.test.ts +0 -101
  528. package/src/validation/__tests__/csrf.unit.test.ts +0 -365
  529. package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
  530. package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
  531. package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
  532. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
  533. package/src/validation/__tests__/user.unit.test.ts +0 -440
  534. package/src/validation/sanitization.ts +0 -96
  535. /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
  536. /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
  537. /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
  538. /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
  539. /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
  540. /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
  541. /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
  542. /package/src/{validation → utils/validation}/common.ts +0 -0
  543. /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
  544. /package/src/{validation → utils/validation}/user.ts +0 -0
@@ -12,8 +12,19 @@ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
12
12
  import { EventService } from '../EventService';
13
13
  import { Event } from '../../types/unified';
14
14
 
15
+ // Don't mock the logger - it now works in test mode
16
+ // We'll spy on the Logger class methods in beforeEach to verify calls
17
+ import { Logger } from '../../utils/core/logger';
18
+
19
+ let mockLoggerFunctions: {
20
+ debug: ReturnType<typeof vi.spyOn>;
21
+ error: ReturnType<typeof vi.spyOn>;
22
+ warn: ReturnType<typeof vi.spyOn>;
23
+ info: ReturnType<typeof vi.spyOn>;
24
+ };
25
+
15
26
  // Mock secureStorage - must be defined inline in vi.mock due to hoisting
16
- vi.mock('../../utils/secureStorage', () => {
27
+ vi.mock('../../utils/security/secureStorage', () => {
17
28
  const mockSecureStorage = {
18
29
  setItem: vi.fn().mockResolvedValue(undefined),
19
30
  getItem: vi.fn().mockResolvedValue(null),
@@ -25,7 +36,7 @@ vi.mock('../../utils/secureStorage', () => {
25
36
  });
26
37
 
27
38
  // Get reference to mocked secureStorage for test assertions
28
- import { secureStorage } from '../../utils/secureStorage';
39
+ import { secureStorage } from '../../utils/security/secureStorage';
29
40
  const mockSecureStorage = secureStorage as any;
30
41
 
31
42
  // Mock Supabase client
@@ -86,6 +97,14 @@ describe('EventService', () => {
86
97
  let eventService: EventService;
87
98
 
88
99
  beforeEach(() => {
100
+ // Spy on Logger methods to verify calls (logger now works in test mode)
101
+ mockLoggerFunctions = {
102
+ debug: vi.spyOn(Logger, 'debug'),
103
+ error: vi.spyOn(Logger, 'error'),
104
+ warn: vi.spyOn(Logger, 'warn'),
105
+ info: vi.spyOn(Logger, 'info'),
106
+ };
107
+
89
108
  vi.clearAllMocks();
90
109
  mockSupabase = createMockSupabaseClient();
91
110
  eventService = new EventService(
@@ -100,6 +119,11 @@ describe('EventService', () => {
100
119
 
101
120
  afterEach(() => {
102
121
  eventService.cleanup();
122
+ // Restore spies
123
+ mockLoggerFunctions.debug.mockRestore();
124
+ mockLoggerFunctions.error.mockRestore();
125
+ mockLoggerFunctions.warn.mockRestore();
126
+ mockLoggerFunctions.info.mockRestore();
103
127
  vi.clearAllMocks();
104
128
  // Clear localStorage
105
129
  localStorage.clear();
@@ -880,7 +904,7 @@ describe('EventService', () => {
880
904
 
881
905
  describe('Event Validation', () => {
882
906
  it('should handle validation error gracefully', () => {
883
- const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
907
+ vi.clearAllMocks();
884
908
 
885
909
  const eventFromDifferentOrg: Event = {
886
910
  ...mockEvent,
@@ -890,8 +914,16 @@ describe('EventService', () => {
890
914
  // Should not throw error
891
915
  eventService.setSelectedEvent(eventFromDifferentOrg);
892
916
 
893
- expect(consoleErrorSpy).toHaveBeenCalled();
894
- consoleErrorSpy.mockRestore();
917
+ // The logger should be called synchronously when validation fails
918
+ expect(mockLoggerFunctions.error).toHaveBeenCalledWith(
919
+ 'EventService',
920
+ 'Event organisation_id does not match selected organisation',
921
+ expect.objectContaining({
922
+ eventOrganisationId: 'org-2',
923
+ selectedOrganisationId: 'org-1',
924
+ eventName: expect.any(String)
925
+ })
926
+ );
895
927
  });
896
928
 
897
929
  it('should handle missing organisation during validation', () => {
@@ -11,6 +11,17 @@
11
11
  import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
12
12
  import { InactivityService } from '../InactivityService';
13
13
 
14
+ // Don't mock the logger - it now works in test mode
15
+ // We'll spy on the Logger class methods in beforeEach to verify calls
16
+ import { Logger } from '../../utils/core/logger';
17
+
18
+ let mockLoggerFunctions: {
19
+ debug: ReturnType<typeof vi.spyOn>;
20
+ error: ReturnType<typeof vi.spyOn>;
21
+ warn: ReturnType<typeof vi.spyOn>;
22
+ info: ReturnType<typeof vi.spyOn>;
23
+ };
24
+
14
25
  // Mock Supabase client
15
26
  const createMockSupabaseClient = () => ({
16
27
  auth: {
@@ -48,6 +59,14 @@ describe('InactivityService', () => {
48
59
  let mockOnIdleLogout: ReturnType<typeof vi.fn>;
49
60
 
50
61
  beforeEach(() => {
62
+ // Spy on Logger methods to verify calls (logger now works in test mode)
63
+ mockLoggerFunctions = {
64
+ debug: vi.spyOn(Logger, 'debug'),
65
+ error: vi.spyOn(Logger, 'error'),
66
+ warn: vi.spyOn(Logger, 'warn'),
67
+ info: vi.spyOn(Logger, 'info'),
68
+ };
69
+
51
70
  mockSupabase = createMockSupabaseClient();
52
71
  mockOnIdleLogout = vi.fn();
53
72
 
@@ -64,6 +83,11 @@ describe('InactivityService', () => {
64
83
 
65
84
  afterEach(() => {
66
85
  inactivityService.cleanup();
86
+ // Restore spies
87
+ mockLoggerFunctions.debug.mockRestore();
88
+ mockLoggerFunctions.error.mockRestore();
89
+ mockLoggerFunctions.warn.mockRestore();
90
+ mockLoggerFunctions.info.mockRestore();
67
91
  vi.clearAllMocks();
68
92
  });
69
93
 
@@ -498,8 +522,15 @@ describe('InactivityService', () => {
498
522
  });
499
523
 
500
524
  it('should log production warning when enabled', async () => {
501
- const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
525
+ vi.clearAllMocks();
502
526
  const originalMode = import.meta.env.MODE;
527
+ const originalWindow = global.window;
528
+
529
+ // Ensure window is defined for the test
530
+ if (typeof global.window === 'undefined') {
531
+ (global as any).window = {};
532
+ }
533
+
503
534
  (import.meta.env as any).MODE = 'production';
504
535
 
505
536
  const service = new InactivityService(
@@ -514,12 +545,15 @@ describe('InactivityService', () => {
514
545
  await service.initialize();
515
546
 
516
547
  // Should log warning in production
517
- expect(consoleWarnSpy).toHaveBeenCalledWith(
518
- expect.stringContaining('[InactivityService] Inactivity feature enabled in production')
548
+ expect(mockLoggerFunctions.warn).toHaveBeenCalledWith(
549
+ 'InactivityService',
550
+ 'Inactivity feature enabled in production'
519
551
  );
520
552
 
521
553
  (import.meta.env as any).MODE = originalMode;
522
- consoleWarnSpy.mockRestore();
554
+ if (originalWindow === undefined) {
555
+ delete (global as any).window;
556
+ }
523
557
  service.cleanup();
524
558
  });
525
559
  });
@@ -74,7 +74,7 @@ const mockMembership2: OrganisationMembership = {
74
74
  };
75
75
 
76
76
  // Mock the organisationContext utility
77
- vi.mock('../../utils/organisationContext', () => ({
77
+ vi.mock('../../utils/context/organisationContext', () => ({
78
78
  setOrganisationContext: vi.fn().mockResolvedValue(undefined)
79
79
  }));
80
80
 
@@ -157,11 +157,6 @@ describe('OrganisationService', () => {
157
157
  p_user_id: mockUser.id,
158
158
  p_organisation_id: null
159
159
  });
160
-
161
- // Debug: Check if state was populated
162
- console.log('Memberships:', organisationService.getUserMemberships());
163
- console.log('Organisations:', organisationService.getOrganisations());
164
- console.log('Selected:', organisationService.getSelectedOrganisation());
165
160
  });
166
161
 
167
162
  it('should handle missing dependencies gracefully', async () => {
@@ -706,7 +701,7 @@ describe('OrganisationService', () => {
706
701
  it('should handle database context setting timeout', async () => {
707
702
  vi.useFakeTimers();
708
703
 
709
- const { setOrganisationContext } = await import('../../utils/organisationContext');
704
+ const { setOrganisationContext } = await import('../../utils/context/organisationContext');
710
705
  vi.mocked(setOrganisationContext).mockImplementation(() => {
711
706
  return new Promise(() => {
712
707
  // Never resolves, will timeout after 5 seconds
@@ -729,7 +724,7 @@ describe('OrganisationService', () => {
729
724
  });
730
725
 
731
726
  it('should handle database context setting error', async () => {
732
- const { setOrganisationContext } = await import('../../utils/organisationContext');
727
+ const { setOrganisationContext } = await import('../../utils/context/organisationContext');
733
728
  vi.mocked(setOrganisationContext).mockRejectedValue(new Error('Database error'));
734
729
 
735
730
  organisationService.setSelectedOrganisation(mockOrganisation);
@@ -8,6 +8,8 @@
8
8
  * All services extend this class to provide state change notifications.
9
9
  */
10
10
 
11
+ import { logger } from '../../utils/core/logger';
12
+
11
13
  export type StateChangeCallback = () => void;
12
14
 
13
15
  export abstract class BaseService {
@@ -40,7 +42,7 @@ export abstract class BaseService {
40
42
  try {
41
43
  callback();
42
44
  } catch (error) {
43
- console.error('[BaseService] Error in subscriber callback:', error);
45
+ logger.error('BaseService', 'Error in subscriber callback:', error);
44
46
  }
45
47
  });
46
48
  }
@@ -7,6 +7,8 @@
7
7
  --font-serif: "Open Sans", sans-serif;
8
8
  --font-mono: "Reddit Mono", monospace;
9
9
  --font-heading: "Georama", sans-serif;
10
+ --shadow-badge-soft: 0 0 0 0.1rem var(--color-main-600), 0 0 0 5rem var(--color-main-600) inset, 0 0 0.25rem 0.25rem var(--color-main-600);
11
+ --shadow-badge-soft-xl: 0 0 0 0.1rem var(--color-main-600), 0 0 0 5rem var(--color-main-600) inset, 0 0 0.25rem 0.75rem var(--color-main-600);
10
12
  }
11
13
 
12
14
  @layer base {
@@ -237,6 +239,7 @@
237
239
  @layer utilities {
238
240
  /* Custom utility styles go here */
239
241
 
242
+
240
243
  /* Hide spinner arrows on number inputs in DataTable */
241
244
  .datatable-number-no-spinners::-webkit-inner-spin-button,
242
245
  .datatable-number-no-spinners::-webkit-outer-spin-button {
@@ -17,6 +17,20 @@ import {
17
17
  type PaletteData
18
18
  } from '../runtime';
19
19
 
20
+ // Mock the Logger module
21
+ vi.mock('../../utils/core/logger', () => {
22
+ const mockLoggerInstance = {
23
+ warn: vi.fn(),
24
+ };
25
+ return {
26
+ createLogger: vi.fn(() => mockLoggerInstance),
27
+ };
28
+ });
29
+
30
+ // Get the mock instance after mock is set up
31
+ import { createLogger } from '../../utils/core/logger';
32
+ const getMockLogger = () => createLogger('test');
33
+
20
34
  // Create proper mock for style object that mimics CSSStyleDeclaration
21
35
  const createMockStyle = () => {
22
36
  const data = {
@@ -69,25 +83,18 @@ const mockDocument = {
69
83
  get documentElement() { return mockDocumentElement; },
70
84
  head: {
71
85
  appendChild: vi.fn()
86
+ },
87
+ body: {
88
+ innerHTML: ''
72
89
  }
73
90
  };
74
91
 
75
- const mockConsole = {
76
- warn: vi.fn(),
77
- log: vi.fn()
78
- };
79
-
80
92
  // Mock global objects
81
93
  Object.defineProperty(global, 'document', {
82
94
  value: mockDocument,
83
95
  writable: true
84
96
  });
85
97
 
86
- Object.defineProperty(global, 'console', {
87
- value: mockConsole,
88
- writable: true
89
- });
90
-
91
98
  describe('[theming] applyPalette', () => {
92
99
  beforeEach(() => {
93
100
  vi.clearAllMocks();
@@ -154,7 +161,8 @@ describe('[theming] applyPalette', () => {
154
161
  };
155
162
 
156
163
  expect(() => applyPalette(palette)).not.toThrow();
157
- expect(mockConsole.warn).toHaveBeenCalledWith('applyPalette: Document not available (SSR)');
164
+ const logger = getMockLogger();
165
+ expect(vi.mocked(logger.warn)).toHaveBeenCalledWith('Document not available (SSR) - palette not applied');
158
166
 
159
167
  // Restore document
160
168
  Object.defineProperty(global, 'document', {
@@ -177,7 +185,8 @@ describe('[theming] applyPalette', () => {
177
185
  };
178
186
 
179
187
  expect(() => applyPalette(palette)).not.toThrow();
180
- expect(mockConsole.warn).toHaveBeenCalledWith('applyPalette: Document not available (SSR)');
188
+ const logger = getMockLogger();
189
+ expect(vi.mocked(logger.warn)).toHaveBeenCalledWith('Document not available (SSR) - palette not applied');
181
190
 
182
191
  // Restore document
183
192
  Object.defineProperty(global, 'document', {
@@ -6,26 +6,12 @@
6
6
  *
7
7
  * Shared utility for parsing and normalizing event_colours from database.
8
8
  * Handles multiple input formats and ensures consistent palette structure.
9
- *
10
- * Supports:
11
- * - Object format: { main: {...}, sec: {...}, acc: {...} }
12
- * - String format: JSON string that will be parsed
13
- * - Legacy format: { "ev-main": {...}, "ev-sec": {...}, "ev-acc": {...} }
14
- *
15
- * The function only includes explicitly defined color values, ensuring
16
- * that undefined shades are not included in the palette.
17
- *
18
- * @example
19
- * ```ts
20
- * import { parseAndNormalizeEventColours } from '@jmruthers/pace-core/theming/parseEventColours';
21
- *
22
- * const palette = parseAndNormalizeEventColours(event.event_colours);
23
- * if (palette) {
24
- * applyPalette(palette);
25
- * }
26
- * ```
27
9
  */
28
10
 
11
+ import { createLogger } from '../utils/core/logger';
12
+
13
+ const log = createLogger('ParseEventColours');
14
+
29
15
  /**
30
16
  * Parse and normalize event_colours to PaletteData
31
17
  *
@@ -116,7 +102,7 @@ export function parseAndNormalizeEventColours(input: unknown): { main: any; sec:
116
102
  acc: fill(acc)
117
103
  };
118
104
  } catch (error) {
119
- console.warn('[parseEventColours] Failed to parse/normalize event colours:', error);
105
+ log.warn('Failed to parse/normalize event colours:', error);
120
106
  return null;
121
107
  }
122
108
  }
@@ -6,7 +6,13 @@
6
6
  *
7
7
  * Runtime helpers for palette replacement from organisation/event payloads.
8
8
  * Provides simple applyPalette() and clearPalette() API with SSR support.
9
- *
9
+ */
10
+
11
+ import { createLogger } from '../utils/core/logger';
12
+
13
+ const log = createLogger('ThemingRuntime');
14
+
15
+ /**
10
16
  * @example
11
17
  * ```ts
12
18
  * import { applyPalette, clearPalette } from '@jmruthers/pace-core/theming/runtime';
@@ -63,9 +69,7 @@ function formatOklchCss(color: ColorShade): string {
63
69
  */
64
70
  export function applyPalette(palette: PaletteData): void {
65
71
  if (typeof document === 'undefined' || document === null) {
66
- if (typeof console !== 'undefined' && console?.warn) {
67
- console.warn('applyPalette: Document not available (SSR)');
68
- }
72
+ log.warn('Document not available (SSR) - palette not applied');
69
73
  return;
70
74
  }
71
75
 
@@ -102,7 +102,6 @@ export const contactFormSchema = z.object({
102
102
 
103
103
  export type LoginFormValues = z.infer<typeof loginSchema>;
104
104
  export type RegistrationFormValues = z.infer<typeof registrationSchema>;
105
- export type PasswordResetFormValues = z.infer<typeof passwordResetSchema>;
106
105
  export type ChangePasswordFormValues = z.infer<typeof changePasswordSchema>;
107
106
  export type UserProfileFormValues = z.infer<typeof userProfileSchema>;
108
107
 
@@ -120,11 +119,6 @@ export type SecureRegistrationFormValues = {
120
119
  csrfToken?: string;
121
120
  };
122
121
 
123
- export type SecurePasswordResetFormValues = {
124
- email: string;
125
- csrfToken?: string;
126
- };
127
-
128
122
  // ============================================================================
129
123
  // Utility Types
130
124
  // ============================================================================
@@ -139,26 +133,5 @@ export type ContactFormData = z.infer<typeof contactFormSchema>;
139
133
  // ============================================================================
140
134
  // Schema Utility Functions
141
135
  // ============================================================================
142
-
143
- export function pickSchema<T extends z.ZodObject<any, any, any>, K extends keyof z.infer<T>>(
144
- schema: T,
145
- keys: K[]
146
- ): z.ZodObject<Pick<z.infer<T>, K>> {
147
- const shape = Object.entries(schema.shape)
148
- .filter(([key]) => keys.includes(key as K))
149
- .reduce((acc, [key, value]) => {
150
- (acc as Record<string, unknown>)[key] = value as unknown;
151
- return acc;
152
- }, {} as Record<string, unknown>);
153
-
154
- return z.object(shape as Record<string, z.ZodTypeAny>) as z.ZodObject<Pick<z.infer<T>, K>>;
155
- }
156
-
157
- export function combineSchemas<T extends z.ZodObject<any, any, any>[]>(
158
- schemas: T
159
- ): z.ZodObject<any, any, any> {
160
- return schemas.reduce(
161
- (merged, schema) => merged.merge(schema),
162
- z.object({})
163
- );
164
- }
136
+ // Re-exported from utils/validation/schema.ts
137
+ export { pickSchema, combineSchemas } from '../utils/validation/schema';
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from '../appConfig';
2
+ import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from '../app/appConfig';
3
3
 
4
4
  describe('App Configuration Utilities', () => {
5
5
  beforeEach(() => {
@@ -4,7 +4,7 @@ import {
4
4
  logAuthEvent,
5
5
  logPermissionEvent,
6
6
  logSecurityEvent
7
- } from '../audit';
7
+ } from '../audit/audit';
8
8
 
9
9
  describe('Audit Logger Utility', () => {
10
10
  beforeEach(() => {
@@ -5,7 +5,7 @@ import {
5
5
  resetPassword,
6
6
  updatePassword,
7
7
  auditLogger
8
- } from '../auth-utils';
8
+ } from '../security/auth-utils';
9
9
 
10
10
  describe('Auth Utils', () => {
11
11
  beforeEach(() => {
@@ -25,7 +25,7 @@ describe('bundleAnalysis', () => {
25
25
 
26
26
  // Clear module cache and re-import
27
27
  vi.resetModules();
28
- const { bundleAnalyzer } = await import('../bundleAnalysis');
28
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
29
29
  const result = bundleAnalyzer.analyzeBundle();
30
30
 
31
31
  expect(result).toBeNull();
@@ -39,7 +39,7 @@ describe('bundleAnalysis', () => {
39
39
 
40
40
  // Clear module cache and re-import to pick up environment change
41
41
  vi.resetModules();
42
- const { bundleAnalyzer } = await import('../bundleAnalysis');
42
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
43
43
  const result = bundleAnalyzer.analyzeBundle();
44
44
 
45
45
  expect(result).toEqual({
@@ -59,7 +59,7 @@ describe('bundleAnalysis', () => {
59
59
  // Clear module cache and re-import to pick up environment change
60
60
  vi.resetModules();
61
61
  const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
62
- const { bundleAnalyzer } = await import('../bundleAnalysis');
62
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
63
63
  bundleAnalyzer.analyzeBundle();
64
64
 
65
65
  expect(consoleSpy).toHaveBeenCalledWith('Bundle analysis would run here in development');
@@ -79,7 +79,7 @@ describe('bundleAnalysis', () => {
79
79
  process.env.NODE_ENV = 'production';
80
80
 
81
81
  vi.resetModules();
82
- const { bundleAnalyzer } = await import('../bundleAnalysis');
82
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
83
83
  bundleAnalyzer.checkTreeshaking();
84
84
 
85
85
  expect(consoleSpy.group).not.toHaveBeenCalled();
@@ -96,7 +96,7 @@ describe('bundleAnalysis', () => {
96
96
  const consoleSpy = vi.spyOn(console, 'group').mockImplementation(() => {});
97
97
  const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
98
98
  const consoleGroupEndSpy = vi.spyOn(console, 'groupEnd').mockImplementation(() => {});
99
- const { bundleAnalyzer } = await import('../bundleAnalysis');
99
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
100
100
  bundleAnalyzer.checkTreeshaking();
101
101
 
102
102
  expect(consoleSpy).toHaveBeenCalledWith('Tree-shaking Analysis');
@@ -119,7 +119,7 @@ describe('bundleAnalysis', () => {
119
119
  process.env.NODE_ENV = 'production';
120
120
 
121
121
  vi.resetModules();
122
- const { bundleAnalyzer } = await import('../bundleAnalysis');
122
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
123
123
  bundleAnalyzer.validateExports();
124
124
 
125
125
  expect(consoleSpy.group).not.toHaveBeenCalled();
@@ -136,7 +136,7 @@ describe('bundleAnalysis', () => {
136
136
  const consoleSpy = vi.spyOn(console, 'group').mockImplementation(() => {});
137
137
  const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
138
138
  const consoleGroupEndSpy = vi.spyOn(console, 'groupEnd').mockImplementation(() => {});
139
- const { bundleAnalyzer } = await import('../bundleAnalysis');
139
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
140
140
  bundleAnalyzer.validateExports();
141
141
 
142
142
  expect(consoleSpy).toHaveBeenCalledWith('Export Validation');
@@ -156,7 +156,7 @@ describe('bundleAnalysis', () => {
156
156
  describe('bundleAnalyzer.generateReport', () => {
157
157
  it('should generate a comprehensive bundle analysis report', async () => {
158
158
  vi.resetModules();
159
- const { bundleAnalyzer } = await import('../bundleAnalysis');
159
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
160
160
  const report = bundleAnalyzer.generateReport();
161
161
 
162
162
  expect(report).toContain('# Bundle Analysis Report');
@@ -173,7 +173,7 @@ describe('bundleAnalysis', () => {
173
173
 
174
174
  it('should include specific recommendations', async () => {
175
175
  vi.resetModules();
176
- const { bundleAnalyzer } = await import('../bundleAnalysis');
176
+ const { bundleAnalyzer } = await import('../performance/bundleAnalysis');
177
177
  const report = bundleAnalyzer.generateReport();
178
178
 
179
179
  expect(report).toContain('Lazy load heavy UI components (charts, complex forms)');
@@ -190,7 +190,7 @@ describe('bundleAnalysis', () => {
190
190
  process.env.NODE_ENV = 'production';
191
191
 
192
192
  vi.resetModules();
193
- const { validateImportPattern } = await import('../bundleAnalysis');
193
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
194
194
  validateImportPattern('lodash', ['debounce', 'throttle']);
195
195
 
196
196
  expect(consoleSpy.warn).not.toHaveBeenCalled();
@@ -204,7 +204,7 @@ describe('bundleAnalysis', () => {
204
204
 
205
205
  vi.resetModules();
206
206
  const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
207
- const { validateImportPattern } = await import('../bundleAnalysis');
207
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
208
208
  validateImportPattern('lodash', ['debounce', 'throttle', 'map', 'filter', 'reduce', 'forEach']);
209
209
 
210
210
  expect(consoleSpy).toHaveBeenCalledWith(
@@ -221,7 +221,7 @@ describe('bundleAnalysis', () => {
221
221
  process.env.NODE_ENV = 'development';
222
222
 
223
223
  vi.resetModules();
224
- const { validateImportPattern } = await import('../bundleAnalysis');
224
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
225
225
  validateImportPattern('lodash', ['debounce', 'throttle']);
226
226
 
227
227
  expect(consoleSpy.warn).not.toHaveBeenCalled();
@@ -234,7 +234,7 @@ describe('bundleAnalysis', () => {
234
234
  process.env.NODE_ENV = 'development';
235
235
 
236
236
  vi.resetModules();
237
- const { validateImportPattern } = await import('../bundleAnalysis');
237
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
238
238
  validateImportPattern('small-module', ['func1', 'func2', 'func3', 'func4', 'func5', 'func6']);
239
239
 
240
240
  expect(consoleSpy.warn).not.toHaveBeenCalled();
@@ -248,7 +248,7 @@ describe('bundleAnalysis', () => {
248
248
 
249
249
  vi.resetModules();
250
250
  const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
251
- const { validateImportPattern } = await import('../bundleAnalysis');
251
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
252
252
  validateImportPattern('lodash-es', ['debounce', 'throttle', 'map', 'filter', 'reduce', 'forEach']);
253
253
 
254
254
  expect(consoleSpy).toHaveBeenCalled();
@@ -263,7 +263,7 @@ describe('bundleAnalysis', () => {
263
263
 
264
264
  vi.resetModules();
265
265
  const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
266
- const { validateImportPattern } = await import('../bundleAnalysis');
266
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
267
267
  validateImportPattern('moment', ['format', 'parse', 'add', 'subtract', 'diff', 'isValid']);
268
268
 
269
269
  expect(consoleSpy).toHaveBeenCalled();
@@ -278,7 +278,7 @@ describe('bundleAnalysis', () => {
278
278
 
279
279
  vi.resetModules();
280
280
  const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
281
- const { validateImportPattern } = await import('../bundleAnalysis');
281
+ const { validateImportPattern } = await import('../performance/bundleAnalysis');
282
282
  validateImportPattern('rxjs', ['Observable', 'Subject', 'BehaviorSubject', 'map', 'filter', 'switchMap']);
283
283
 
284
284
  expect(consoleSpy).toHaveBeenCalled();
@@ -294,7 +294,7 @@ describe('bundleAnalysis', () => {
294
294
  process.env.NODE_ENV = 'production';
295
295
 
296
296
  vi.resetModules();
297
- const { trackDynamicImport } = await import('../bundleAnalysis');
297
+ const { trackDynamicImport } = await import('../performance/bundleAnalysis');
298
298
  trackDynamicImport('some-module');
299
299
 
300
300
  expect(consoleSpy.log).not.toHaveBeenCalled();
@@ -308,7 +308,7 @@ describe('bundleAnalysis', () => {
308
308
 
309
309
  vi.resetModules();
310
310
  const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
311
- const { trackDynamicImport } = await import('../bundleAnalysis');
311
+ const { trackDynamicImport } = await import('../performance/bundleAnalysis');
312
312
  trackDynamicImport('react-hook-form');
313
313
 
314
314
  expect(consoleSpy).toHaveBeenCalledWith(
@@ -325,7 +325,7 @@ describe('bundleAnalysis', () => {
325
325
 
326
326
  vi.resetModules();
327
327
  const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
328
- const { trackDynamicImport } = await import('../bundleAnalysis');
328
+ const { trackDynamicImport } = await import('../performance/bundleAnalysis');
329
329
  trackDynamicImport('date-fns');
330
330
 
331
331
  expect(consoleSpy).toHaveBeenCalledWith(
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { cn } from '../cn';
2
+ import { cn } from '../core/cn';
3
3
 
4
4
  describe('cn utility', () => {
5
5
  it('should merge class names correctly', () => {
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
16
- import { DebugLogger } from '../debugLogger';
16
+ import { DebugLogger } from '../core/debugLogger';
17
17
 
18
18
  describe('[unit] DebugLogger Tests', () => {
19
19
  let originalConsoleLog: typeof console.log;
@@ -10,7 +10,7 @@ import {
10
10
  generateDeviceFingerprint,
11
11
  validateDeviceFingerprint,
12
12
  DeviceFingerprint,
13
- } from '../deviceFingerprint';
13
+ } from '../device/deviceFingerprint';
14
14
 
15
15
  // Mock browser APIs
16
16
  const mockNavigator = {
@@ -11,7 +11,7 @@ import {
11
11
  lazyChartUtils,
12
12
  lazyFormUtils,
13
13
  lazyCSVUtils
14
- } from '../dynamicUtils';
14
+ } from '../dynamic/dynamicUtils';
15
15
 
16
16
  // Mock dynamic imports
17
17
  vi.mock('lodash.debounce', () => ({
@@ -5,7 +5,7 @@ import {
5
5
  formatPercent,
6
6
  formatCompactNumber,
7
7
  formatFileSize
8
- } from '../formatting';
8
+ } from '../formatting/formatting';
9
9
 
10
10
  describe('formatting utilities', () => {
11
11
  describe('formatDate', () => {