@jmruthers/pace-core 0.6.4 → 0.6.6

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 (387) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/core-usage-manifest.json +93 -0
  4. package/cursor-rules/00-pace-core-compliance.mdc +128 -26
  5. package/cursor-rules/01-standards-compliance.mdc +49 -8
  6. package/cursor-rules/02-project-structure.mdc +6 -0
  7. package/cursor-rules/03-solid-principles.mdc +2 -0
  8. package/cursor-rules/04-testing-standards.mdc +2 -0
  9. package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
  10. package/cursor-rules/06-code-quality.mdc +2 -0
  11. package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
  12. package/cursor-rules/08-markup-quality.mdc +52 -27
  13. package/cursor-rules/09-rbac-compliance.mdc +462 -0
  14. package/cursor-rules/10-error-handling-patterns.mdc +179 -0
  15. package/cursor-rules/11-performance-optimization.mdc +169 -0
  16. package/cursor-rules/12-ci-cd-integration.mdc +150 -0
  17. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  18. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
  19. package/dist/DataTable-LRJL4IRV.js +15 -0
  20. package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
  21. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  22. package/dist/api-Y4MQWOFW.js +4 -0
  23. package/dist/audit-MYQXYZFU.js +3 -0
  24. package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
  25. package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
  26. package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
  27. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  28. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  29. package/dist/chunk-4T7OBVTU.js +62 -0
  30. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  31. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  32. package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
  33. package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
  34. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  35. package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
  36. package/dist/chunk-C7NSAPTL.js +1 -0
  37. package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
  38. package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
  39. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  40. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  41. package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
  42. package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
  43. package/dist/chunk-MBADTM7L.js +64 -0
  44. package/dist/chunk-OHIK3MIO.js +994 -0
  45. package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
  46. package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
  47. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  48. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  49. package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
  50. package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
  51. package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
  52. package/dist/components.d.ts +6 -6
  53. package/dist/components.js +57 -267
  54. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  55. package/dist/eslint-rules/index.cjs +22 -0
  56. package/dist/eslint-rules/rules/compliance.cjs +348 -0
  57. package/dist/eslint-rules/rules/components.cjs +113 -0
  58. package/dist/eslint-rules/rules/imports.cjs +102 -0
  59. package/dist/eslint-rules/rules/rbac.cjs +790 -0
  60. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  61. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  62. package/dist/hooks.d.ts +5 -5
  63. package/dist/hooks.js +62 -270
  64. package/dist/icons/index.d.ts +1 -0
  65. package/dist/icons/index.js +1 -0
  66. package/dist/index.d.ts +36 -26
  67. package/dist/index.js +87 -690
  68. package/dist/providers.d.ts +2 -2
  69. package/dist/providers.js +8 -35
  70. package/dist/rbac/eslint-rules.d.ts +46 -44
  71. package/dist/rbac/eslint-rules.js +7 -4
  72. package/dist/rbac/index.d.ts +124 -594
  73. package/dist/rbac/index.js +14 -207
  74. package/dist/styles/index.js +2 -12
  75. package/dist/theming/runtime.js +3 -19
  76. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  77. package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
  78. package/dist/types-t9H8qKRw.d.ts +55 -0
  79. package/dist/types.d.ts +1 -1
  80. package/dist/types.js +7 -94
  81. package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
  82. package/dist/utils.d.ts +24 -117
  83. package/dist/utils.js +54 -392
  84. package/docs/README.md +16 -6
  85. package/docs/api/README.md +4 -402
  86. package/docs/api/modules.md +454 -930
  87. package/docs/api-reference/components.md +3 -1
  88. package/docs/api-reference/deprecated.md +31 -6
  89. package/docs/api-reference/rpc-functions.md +78 -3
  90. package/docs/best-practices/accessibility.md +6 -3
  91. package/docs/getting-started/cursor-rules.md +3 -23
  92. package/docs/getting-started/dependencies.md +650 -0
  93. package/docs/getting-started/installation-guide.md +20 -7
  94. package/docs/getting-started/quick-start.md +23 -12
  95. package/docs/implementation-guides/permission-enforcement.md +4 -0
  96. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  97. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  98. package/docs/rbac/README.md +12 -3
  99. package/docs/rbac/edge-functions-guide.md +376 -0
  100. package/docs/rbac/secure-client-protection.md +0 -34
  101. package/docs/standards/00-pace-core-compliance.md +967 -0
  102. package/docs/standards/01-standards-compliance.md +188 -0
  103. package/docs/standards/02-project-structure.md +985 -0
  104. package/docs/standards/03-solid-principles.md +39 -0
  105. package/docs/standards/04-testing-standards.md +36 -0
  106. package/docs/standards/05-bug-reports-and-features.md +27 -0
  107. package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
  108. package/docs/standards/07-tech-stack-compliance.md +30 -0
  109. package/docs/standards/08-markup-quality.md +345 -0
  110. package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
  111. package/docs/standards/10-error-handling-patterns.md +401 -0
  112. package/docs/standards/11-performance-optimization.md +348 -0
  113. package/docs/standards/12-ci-cd-integration.md +370 -0
  114. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
  115. package/docs/standards/README.md +62 -33
  116. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  117. package/eslint-config-pace-core.cjs +20 -4
  118. package/package.json +31 -21
  119. package/scripts/audit/audit-compliance.cjs +1295 -0
  120. package/scripts/audit/audit-components.cjs +260 -0
  121. package/scripts/audit/audit-dependencies.cjs +395 -0
  122. package/scripts/audit/audit-rbac.cjs +954 -0
  123. package/scripts/audit/audit-standards.cjs +1268 -0
  124. package/scripts/audit/index.cjs +1898 -194
  125. package/scripts/install-cursor-rules.cjs +259 -8
  126. package/scripts/validate-master.js +1 -1
  127. package/src/__tests__/fixtures/supabase.ts +1 -1
  128. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
  129. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  130. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  131. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
  132. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  133. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  134. package/src/__tests__/public-recipe-view.test.ts +38 -9
  135. package/src/components/Button/Button.tsx +5 -1
  136. package/src/components/ContextSelector/ContextSelector.tsx +42 -39
  137. package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
  138. package/src/components/DataTable/components/DataTableBody.tsx +55 -31
  139. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  140. package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
  141. package/src/components/DataTable/components/EditFields.tsx +23 -3
  142. package/src/components/DataTable/components/EditableRow.tsx +7 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +4 -6
  144. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  145. package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
  146. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
  147. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
  148. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  149. package/src/components/DataTable/core/DataTableContext.tsx +1 -1
  150. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  151. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  152. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  153. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  154. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  155. package/src/components/DataTable/types.ts +5 -0
  156. package/src/components/DateTimeField/DateTimeField.tsx +20 -20
  157. package/src/components/DateTimeField/README.md +5 -2
  158. package/src/components/Dialog/Dialog.test.tsx +361 -318
  159. package/src/components/Dialog/Dialog.tsx +1154 -323
  160. package/src/components/Dialog/index.ts +3 -3
  161. package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
  162. package/src/components/FileDisplay/FileDisplay.tsx +28 -22
  163. package/src/components/Form/Form.test.tsx +9 -10
  164. package/src/components/Form/Form.tsx +369 -9
  165. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
  166. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
  167. package/src/components/LoginForm/LoginForm.tsx +2 -2
  168. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  169. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
  170. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  171. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  172. package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
  173. package/src/components/PaceAppLayout/README.md +10 -9
  174. package/src/components/PaceAppLayout/test-setup.tsx +40 -31
  175. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  176. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  177. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
  178. package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
  179. package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
  180. package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
  181. package/src/components/Select/Select.tsx +23 -21
  182. package/src/components/Select/types.ts +1 -1
  183. package/src/components/UserMenu/UserMenu.test.tsx +38 -6
  184. package/src/components/UserMenu/UserMenu.tsx +39 -34
  185. package/src/components/index.ts +3 -4
  186. package/src/eslint-rules/index.cjs +22 -0
  187. package/src/eslint-rules/rules/compliance.cjs +348 -0
  188. package/src/eslint-rules/rules/components.cjs +113 -0
  189. package/src/eslint-rules/rules/imports.cjs +102 -0
  190. package/src/eslint-rules/rules/rbac.cjs +790 -0
  191. package/src/eslint-rules/utils/helpers.cjs +42 -0
  192. package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
  193. package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
  194. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  195. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  196. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  197. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  198. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  199. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  200. package/src/hooks/public/usePublicEvent.ts +62 -190
  201. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  202. package/src/hooks/public/usePublicEventLogo.ts +19 -9
  203. package/src/hooks/useAppConfig.ts +26 -24
  204. package/src/hooks/useEventTheme.test.ts +211 -233
  205. package/src/hooks/useEventTheme.ts +19 -28
  206. package/src/hooks/useEvents.ts +11 -7
  207. package/src/hooks/useKeyboardShortcuts.ts +1 -1
  208. package/src/hooks/useOrganisationPermissions.ts +9 -11
  209. package/src/hooks/useOrganisations.ts +13 -7
  210. package/src/hooks/useQueryCache.ts +0 -1
  211. package/src/hooks/useSessionDraft.ts +380 -0
  212. package/src/hooks/useSessionRestoration.ts +3 -1
  213. package/src/icons/index.ts +27 -0
  214. package/src/index.ts +16 -1
  215. package/src/providers/OrganisationProvider.tsx +23 -14
  216. package/src/providers/services/EventServiceProvider.tsx +1 -24
  217. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  218. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
  219. package/src/rbac/README.md +20 -20
  220. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  221. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  222. package/src/rbac/adapters.tsx +7 -295
  223. package/src/rbac/api.test.ts +44 -56
  224. package/src/rbac/api.ts +10 -17
  225. package/src/rbac/cache-invalidation.ts +0 -1
  226. package/src/rbac/compliance/index.ts +10 -0
  227. package/src/rbac/compliance/pattern-detector.ts +553 -0
  228. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  229. package/src/rbac/components/AccessDenied.tsx +150 -0
  230. package/src/rbac/components/NavigationGuard.tsx +12 -20
  231. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  232. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  233. package/src/rbac/components/index.ts +3 -41
  234. package/src/rbac/eslint-rules.js +1 -1
  235. package/src/rbac/hooks/index.ts +0 -3
  236. package/src/rbac/hooks/permissions/index.ts +0 -3
  237. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  238. package/src/rbac/hooks/usePermissions.ts +0 -3
  239. package/src/rbac/hooks/useRBAC.test.ts +21 -3
  240. package/src/rbac/hooks/useRBAC.ts +4 -3
  241. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  242. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  243. package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
  244. package/src/rbac/hooks/useResourcePermissions.ts +182 -63
  245. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  246. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  247. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  248. package/src/rbac/index.ts +7 -9
  249. package/src/rbac/permissions.ts +17 -17
  250. package/src/rbac/utils/contextValidator.ts +45 -7
  251. package/src/services/AuthService.ts +132 -23
  252. package/src/services/EventService.ts +4 -97
  253. package/src/services/InactivityService.ts +155 -58
  254. package/src/services/OrganisationService.ts +7 -44
  255. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  256. package/src/services/base/BaseService.ts +0 -3
  257. package/src/styles/core.css +4 -0
  258. package/src/types/database.generated.ts +4733 -3809
  259. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  260. package/src/utils/context/organisationContext.test.ts +13 -28
  261. package/src/utils/context/organisationContext.ts +21 -52
  262. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  263. package/src/utils/file-reference/index.ts +39 -15
  264. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  265. package/src/utils/formatting/formatTime.test.ts +3 -2
  266. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  267. package/src/utils/index.ts +4 -1
  268. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  269. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  270. package/src/utils/persistence/keyDerivation.ts +304 -0
  271. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  272. package/src/utils/security/secureStorage.ts +5 -5
  273. package/src/utils/storage/helpers.ts +3 -3
  274. package/src/utils/supabase/createBaseClient.ts +147 -0
  275. package/src/utils/timezone/timezone.test.ts +1 -2
  276. package/src/utils/timezone/timezone.ts +1 -1
  277. package/src/utils/validation/csrf.ts +4 -4
  278. package/cursor-rules/CHANGELOG.md +0 -119
  279. package/cursor-rules/README.md +0 -192
  280. package/dist/DataTable-E7YQZD7D.js +0 -175
  281. package/dist/DataTable-E7YQZD7D.js.map +0 -1
  282. package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
  283. package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
  284. package/dist/api-6LVZTHDS.js +0 -52
  285. package/dist/api-6LVZTHDS.js.map +0 -1
  286. package/dist/audit-V53FV5AG.js +0 -17
  287. package/dist/audit-V53FV5AG.js.map +0 -1
  288. package/dist/chunk-36LVWXB2.js +0 -227
  289. package/dist/chunk-36LVWXB2.js.map +0 -1
  290. package/dist/chunk-3LPHPB62.js.map +0 -1
  291. package/dist/chunk-5DRSZLL2.js.map +0 -1
  292. package/dist/chunk-5EC5MEWX.js.map +0 -1
  293. package/dist/chunk-63FOKYGO.js.map +0 -1
  294. package/dist/chunk-6SOIHG6Z.js.map +0 -1
  295. package/dist/chunk-7JPAB3T5.js.map +0 -1
  296. package/dist/chunk-ATKZM7RX.js +0 -2053
  297. package/dist/chunk-ATKZM7RX.js.map +0 -1
  298. package/dist/chunk-AVMLPIM7.js.map +0 -1
  299. package/dist/chunk-DGUM43GV.js.map +0 -1
  300. package/dist/chunk-E66EQZE6.js.map +0 -1
  301. package/dist/chunk-FFQEQTNW.js.map +0 -1
  302. package/dist/chunk-FMUCXFII.js.map +0 -1
  303. package/dist/chunk-G37KK66H.js.map +0 -1
  304. package/dist/chunk-I6DAQMWX.js.map +0 -1
  305. package/dist/chunk-J36DSWQK.js.map +0 -1
  306. package/dist/chunk-KQCRWDSA.js +0 -1
  307. package/dist/chunk-KQCRWDSA.js.map +0 -1
  308. package/dist/chunk-L4OXEN46.js.map +0 -1
  309. package/dist/chunk-LMC26NLJ.js +0 -84
  310. package/dist/chunk-LMC26NLJ.js.map +0 -1
  311. package/dist/chunk-M43Y4SSO.js.map +0 -1
  312. package/dist/chunk-M7MPQISP.js.map +0 -1
  313. package/dist/chunk-NN6WWZ5U.js.map +0 -1
  314. package/dist/chunk-OEWDTMG7.js.map +0 -1
  315. package/dist/chunk-PWLANIRT.js.map +0 -1
  316. package/dist/chunk-QXHPKYJV.js.map +0 -1
  317. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  318. package/dist/chunk-YKRAFF5K.js.map +0 -1
  319. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  320. package/dist/components.js.map +0 -1
  321. package/dist/contextValidator-OOPCLPZW.js +0 -9
  322. package/dist/contextValidator-OOPCLPZW.js.map +0 -1
  323. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  324. package/dist/hooks.js.map +0 -1
  325. package/dist/index.js.map +0 -1
  326. package/dist/providers.js.map +0 -1
  327. package/dist/rbac/eslint-rules.js.map +0 -1
  328. package/dist/rbac/index.js.map +0 -1
  329. package/dist/styles/index.js.map +0 -1
  330. package/dist/theming/runtime.js.map +0 -1
  331. package/dist/types.js.map +0 -1
  332. package/dist/utils.js.map +0 -1
  333. package/docs/standards/01-architecture-standard.md +0 -44
  334. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  335. package/docs/standards/03-component-standard.md +0 -32
  336. package/docs/standards/05-security-standard.md +0 -44
  337. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  338. package/docs/standards/pace-core-compliance.md +0 -432
  339. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  340. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  341. package/scripts/audit/core/checks/bundle.cjs +0 -142
  342. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  343. package/scripts/audit/core/checks/config.cjs +0 -54
  344. package/scripts/audit/core/checks/coverage.cjs +0 -84
  345. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  346. package/scripts/audit/core/checks/documentation.cjs +0 -268
  347. package/scripts/audit/core/checks/environment.cjs +0 -116
  348. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  349. package/scripts/audit/core/checks/forms.cjs +0 -172
  350. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  351. package/scripts/audit/core/checks/hooks.cjs +0 -334
  352. package/scripts/audit/core/checks/imports.cjs +0 -244
  353. package/scripts/audit/core/checks/performance.cjs +0 -325
  354. package/scripts/audit/core/checks/routes.cjs +0 -117
  355. package/scripts/audit/core/checks/state.cjs +0 -130
  356. package/scripts/audit/core/checks/structure.cjs +0 -65
  357. package/scripts/audit/core/checks/style.cjs +0 -584
  358. package/scripts/audit/core/checks/testing.cjs +0 -122
  359. package/scripts/audit/core/checks/typescript.cjs +0 -61
  360. package/scripts/audit/core/scanner.cjs +0 -199
  361. package/scripts/audit/core/utils.cjs +0 -137
  362. package/scripts/audit/reporters/console.cjs +0 -151
  363. package/scripts/audit/reporters/json.cjs +0 -54
  364. package/scripts/audit/reporters/markdown.cjs +0 -124
  365. package/scripts/audit-consuming-app.cjs +0 -86
  366. package/src/eslint-rules/pace-core-compliance.cjs +0 -510
  367. package/src/eslint-rules/pace-core-compliance.js +0 -638
  368. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  369. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  370. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  371. package/src/rbac/components/NavigationProvider.tsx +0 -345
  372. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  373. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  374. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  375. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  376. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  377. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  378. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  379. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  380. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  381. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  382. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  383. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  384. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  385. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  386. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  387. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -20,7 +20,7 @@
20
20
  * // Automatically applies event colors when event is selected via EventProvider
21
21
  * useEventTheme();
22
22
  *
23
- * return <div>Your app content</div>;
23
+ * return <main>Your app content</main>;
24
24
  * }
25
25
  * ```
26
26
  *
@@ -33,14 +33,14 @@
33
33
  * // Applies event colors directly from event prop
34
34
  * useEventTheme(event);
35
35
  *
36
- * return <div>Public page content</div>;
36
+ * return <main>Public page content</main>;
37
37
  * }
38
38
  * ```
39
39
  */
40
40
 
41
- import { useEffect } from 'react';
41
+ import { useEffect, useContext } from 'react';
42
42
  import { useLocation } from 'react-router-dom';
43
- import { useEvents } from './useEvents';
43
+ import { EventServiceContext } from '../providers/services/EventServiceProvider';
44
44
  import { applyPalette, clearPalette } from '../theming/runtime';
45
45
  import { parseAndNormalizeEventColours } from '../theming/parseEventColours';
46
46
  import type { Event } from '../types/event';
@@ -79,7 +79,7 @@ const log = createLogger('useEventTheme');
79
79
  * // Authenticated mode - uses EventProvider
80
80
  * function MyApp() {
81
81
  * useEventTheme(); // Watches selectedEvent from EventProvider
82
- * return <div>App content</div>;
82
+ * return <main>App content</main>;
83
83
  * }
84
84
  * ```
85
85
  *
@@ -88,7 +88,7 @@ const log = createLogger('useEventTheme');
88
88
  * // Public page mode - uses event prop
89
89
  * function PublicPageLayout({ event }) {
90
90
  * useEventTheme(event); // Uses event prop directly
91
- * return <div>Public content</div>;
91
+ * return <main>Public content</main>;
92
92
  * }
93
93
  * ```
94
94
  */
@@ -99,30 +99,21 @@ const log = createLogger('useEventTheme');
99
99
  * @param event - Optional event object for public page mode. If not provided, uses EventProvider context.
100
100
  */
101
101
  export function useEventTheme(event?: Event | null): void {
102
+ // Call all hooks unconditionally at the top level
103
+ // Hooks must be called in the same order on every render
102
104
  const location = useLocation();
103
105
 
104
- // Try to get event from EventProvider context (authenticated mode)
105
- // Only use useEvents() if event prop is not provided
106
- let selectedEvent: Event | null | undefined;
107
- try {
108
- if (event === undefined) {
109
- // No event prop provided, try to use EventProvider context
110
- const eventsContext = useEvents();
111
- selectedEvent = eventsContext.selectedEvent;
112
- } else {
113
- // Event prop provided, use it directly (public page mode)
114
- selectedEvent = event;
115
- }
116
- } catch (error) {
117
- // useEvents() throws if EventProvider is not available
118
- // This is expected for public pages - use the event prop if provided
119
- if (event !== undefined) {
120
- selectedEvent = event;
121
- } else {
122
- // No event prop and no EventProvider - can't apply theme
123
- selectedEvent = null;
124
- }
125
- }
106
+ // Use EventServiceContext directly to handle missing provider gracefully
107
+ // This allows the hook to work in public pages without EventProvider
108
+ const eventServiceContext = useContext(EventServiceContext);
109
+ const eventsContextSelectedEvent = eventServiceContext?.eventService?.getSelectedEvent() ?? null;
110
+
111
+ // Determine which event to use: event prop (public mode) or EventProvider context (authenticated mode)
112
+ // If event prop is provided, use it (public page mode)
113
+ // Otherwise, use EventProvider context (authenticated mode)
114
+ const selectedEvent = event !== undefined
115
+ ? event // Public page mode - use event prop
116
+ : eventsContextSelectedEvent; // Authenticated mode - use EventProvider context
126
117
 
127
118
  useEffect(() => {
128
119
  // Skip theme application when on login route
@@ -37,13 +37,17 @@ export interface EventContextType {
37
37
  * const { events, selectedEvent, setSelectedEvent } = useEvents();
38
38
  *
39
39
  * return (
40
- * <div>
41
- * {events.map(event => (
42
- * <button key={event.id} onClick={() => setSelectedEvent(event)}>
43
- * {event.event_name}
44
- * </button>
45
- * ))}
46
- * </div>
40
+ * <nav>
41
+ * <ul>
42
+ * {events.map(event => (
43
+ * <li key={event.id}>
44
+ * <button onClick={() => setSelectedEvent(event)}>
45
+ * {event.event_name}
46
+ * </button>
47
+ * </li>
48
+ * ))}
49
+ * </ul>
50
+ * </nav>
47
51
  * );
48
52
  * }
49
53
  * ```
@@ -86,7 +86,7 @@ function matchesKeyCombo(event: KeyboardEvent, combo: string): boolean {
86
86
  *
87
87
  * useKeyboardShortcuts(shortcuts);
88
88
  *
89
- * return <div>Content</div>;
89
+ * return <main>Content</main>;
90
90
  * }
91
91
  * ```
92
92
  */
@@ -18,11 +18,11 @@
18
18
  * } = useOrganisationPermissions();
19
19
  *
20
20
  * return (
21
- * <div>
21
+ * <section>
22
22
  * {isOrgAdmin && <AdminPanel />}
23
23
  * {canManageMembers && <MemberManagement />}
24
24
  * <p>Your role: {userRole}</p>
25
- * </div>
25
+ * </section>
26
26
  * );
27
27
  * }
28
28
  *
@@ -31,10 +31,10 @@
31
31
  * const permissions = useOrganisationPermissions('org-123');
32
32
  *
33
33
  * if (!permissions.hasOrganisationAccess) {
34
- * return <div>No access to this organisation</div>;
34
+ * return <main>No access to this organisation</main>;
35
35
  * }
36
36
  *
37
- * return <div>Role in org-123: {permissions.userRole}</div>;
37
+ * return <main>Role in org-123: {permissions.userRole}</main>;
38
38
  * }
39
39
  * ```
40
40
  *
@@ -106,13 +106,11 @@ export function useOrganisationPermissions(orgId?: string): UseOrganisationPermi
106
106
  ensureOrganisationContext
107
107
  } = useOrganisations();
108
108
 
109
- // Get super admin context if available (may not be available in all contexts)
110
- let superAdminContext: { isSuperAdmin: boolean } = { isSuperAdmin: false };
111
- try {
112
- superAdminContext = useOrganisationSecurity().superAdminContext;
113
- } catch {
114
- // Not available in this context, default to false
115
- }
109
+ // Call hook unconditionally - if provider is missing, it will throw
110
+ // Errors should be handled by error boundaries at a higher level
111
+ // We cannot conditionally call hooks
112
+ const organisationSecurity = useOrganisationSecurity();
113
+ const superAdminContext = organisationSecurity.superAdminContext;
116
114
 
117
115
  const organisationId = useMemo(() => {
118
116
  if (orgId) {
@@ -26,14 +26,20 @@ import { Organisation, OrganisationMembership, OrganisationContextType } from '.
26
26
  * const { selectedOrganisation, organisations, switchOrganisation } = useOrganisations();
27
27
  *
28
28
  * return (
29
- * <div>
29
+ * <main>
30
30
  * <h1>Current Organisation: {selectedOrganisation.display_name}</h1>
31
- * {organisations.map(org => (
32
- * <button key={org.id} onClick={() => switchOrganisation(org.id)}>
33
- * {org.display_name}
34
- * </button>
35
- * ))}
36
- * </div>
31
+ * <nav>
32
+ * <ul>
33
+ * {organisations.map(org => (
34
+ * <li key={org.id}>
35
+ * <button onClick={() => switchOrganisation(org.id)}>
36
+ * {org.display_name}
37
+ * </button>
38
+ * </li>
39
+ * ))}
40
+ * </ul>
41
+ * </nav>
42
+ * </main>
37
43
  * );
38
44
  * }
39
45
  * ```
@@ -50,7 +50,6 @@ function runCacheCleanup() {
50
50
  // Initialize cleanup timer once
51
51
  if (typeof window !== 'undefined' && !cleanupTimer) {
52
52
  cleanupTimer = setInterval(runCacheCleanup, CLEANUP_INTERVAL_MS);
53
- log.debug('Query cache cleanup initialized.');
54
53
 
55
54
  // Cleanup on page unload to prevent memory leaks
56
55
  window.addEventListener('beforeunload', () => {
@@ -0,0 +1,380 @@
1
+ /**
2
+ * @file Session Draft Persistence Hook
3
+ * @package @jmruthers/pace-core
4
+ * @module Hooks/Persistence
5
+ * @since 1.0.0
6
+ *
7
+ * A React hook for persisting component state to sessionStorage.
8
+ * Provides automatic persistence that survives tab switching but clears on tab close.
9
+ *
10
+ * Features:
11
+ * - Debounced writes to prevent excessive storage operations
12
+ * - Automatic restoration on mount
13
+ * - Versioning support for schema migrations
14
+ * - Safe JSON serialization with error handling
15
+ * - Type-safe with generics
16
+ * - Handles storage quota errors gracefully
17
+ * - Optional cleanup on unmount
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { state, setState, clearDraft } = useSessionDraft('my-component', {
22
+ * filters: [],
23
+ * sortBy: 'name'
24
+ * });
25
+ *
26
+ * // State is automatically persisted on changes
27
+ * setState({ filters: ['active'], sortBy: 'email' });
28
+ *
29
+ * // Clear draft when done
30
+ * clearDraft();
31
+ * ```
32
+ *
33
+ * @dependencies
34
+ * - React 19+ - Hooks and effects
35
+ */
36
+
37
+ import { useState, useEffect, useCallback, useRef } from 'react';
38
+
39
+ /**
40
+ * Schema version for stored drafts
41
+ * Increment when the data structure changes
42
+ */
43
+ const DRAFT_SCHEMA_VERSION = 1;
44
+
45
+ /**
46
+ * Default debounce delay in milliseconds
47
+ */
48
+ const DEFAULT_DEBOUNCE_MS = 300;
49
+
50
+ /**
51
+ * Stored draft payload structure
52
+ */
53
+ interface StoredDraft<T> {
54
+ version: number;
55
+ data: T;
56
+ timestamp: number;
57
+ }
58
+
59
+ /**
60
+ * Options for useSessionDraft hook
61
+ */
62
+ export interface UseSessionDraftOptions {
63
+ /**
64
+ * Debounce delay in milliseconds
65
+ * @default 300
66
+ */
67
+ debounceMs?: number;
68
+
69
+ /**
70
+ * Whether to clear draft on component unmount
71
+ * @default false
72
+ */
73
+ clearOnUnmount?: boolean;
74
+
75
+ /**
76
+ * Whether to enable persistence (useful for conditional persistence)
77
+ * @default true
78
+ */
79
+ enabled?: boolean;
80
+
81
+ /**
82
+ * Custom storage key prefix
83
+ * @default 'pace-core:draft'
84
+ */
85
+ keyPrefix?: string;
86
+ }
87
+
88
+ /**
89
+ * Return value of useSessionDraft hook
90
+ */
91
+ export interface UseSessionDraftReturn<T> {
92
+ /**
93
+ * Current draft state
94
+ */
95
+ state: T;
96
+
97
+ /**
98
+ * Update draft state (triggers debounced save)
99
+ */
100
+ setState: (newState: T | ((prev: T) => T)) => void;
101
+
102
+ /**
103
+ * Clear the draft from storage
104
+ */
105
+ clearDraft: () => void;
106
+
107
+ /**
108
+ * Force immediate save (bypasses debounce)
109
+ */
110
+ saveImmediately: () => void;
111
+
112
+ /**
113
+ * Whether the draft was restored from storage
114
+ */
115
+ wasRestored: boolean;
116
+ }
117
+
118
+ /**
119
+ * Debounce function that matches lodash debounce API
120
+ */
121
+ function debounce<T extends (...args: any[]) => void>(
122
+ func: T,
123
+ wait: number
124
+ ): T & { cancel: () => void } {
125
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
126
+
127
+ const debounced = ((...args: Parameters<T>) => {
128
+ if (timeoutId !== null) {
129
+ clearTimeout(timeoutId);
130
+ }
131
+ timeoutId = setTimeout(() => {
132
+ func(...args);
133
+ }, wait);
134
+ }) as T & { cancel: () => void };
135
+
136
+ debounced.cancel = () => {
137
+ if (timeoutId !== null) {
138
+ clearTimeout(timeoutId);
139
+ timeoutId = null;
140
+ }
141
+ };
142
+
143
+ return debounced;
144
+ }
145
+
146
+ /**
147
+ * Get the full storage key with namespace
148
+ */
149
+ function getStorageKey(key: string, prefix: string): string {
150
+ return `${prefix}:${key}`;
151
+ }
152
+
153
+ /**
154
+ * Save draft to sessionStorage
155
+ */
156
+ function saveDraft<T>(storageKey: string, data: T): boolean {
157
+ if (typeof window === 'undefined' || !window.sessionStorage) {
158
+ return false;
159
+ }
160
+
161
+ try {
162
+ const payload: StoredDraft<T> = {
163
+ version: DRAFT_SCHEMA_VERSION,
164
+ data,
165
+ timestamp: Date.now(),
166
+ };
167
+
168
+ const serialized = JSON.stringify(payload);
169
+ window.sessionStorage.setItem(storageKey, serialized);
170
+ return true;
171
+ } catch (error) {
172
+ // Handle quota exceeded or other storage errors
173
+ if (error instanceof DOMException && error.name === 'QuotaExceededError') {
174
+ console.warn(`[useSessionDraft] Storage quota exceeded for key: ${storageKey}`);
175
+ } else {
176
+ console.warn(`[useSessionDraft] Failed to save draft for key: ${storageKey}`, error);
177
+ }
178
+ return false;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Load draft from sessionStorage
184
+ */
185
+ function loadDraft<T>(storageKey: string): T | null {
186
+ if (typeof window === 'undefined' || !window.sessionStorage) {
187
+ return null;
188
+ }
189
+
190
+ try {
191
+ const stored = window.sessionStorage.getItem(storageKey);
192
+ if (!stored) {
193
+ return null;
194
+ }
195
+
196
+ const parsed = JSON.parse(stored) as StoredDraft<T>;
197
+
198
+ // Validate version
199
+ if (parsed.version !== DRAFT_SCHEMA_VERSION) {
200
+ console.warn(
201
+ `[useSessionDraft] Schema version mismatch for key: ${storageKey}. Expected ${DRAFT_SCHEMA_VERSION}, got ${parsed.version}`
202
+ );
203
+ // Clear outdated draft
204
+ window.sessionStorage.removeItem(storageKey);
205
+ return null;
206
+ }
207
+
208
+ // Validate structure
209
+ if (!parsed.data) {
210
+ console.warn(`[useSessionDraft] Invalid draft structure for key: ${storageKey}`);
211
+ window.sessionStorage.removeItem(storageKey);
212
+ return null;
213
+ }
214
+
215
+ return parsed.data;
216
+ } catch (error) {
217
+ console.warn(`[useSessionDraft] Failed to load draft for key: ${storageKey}`, error);
218
+ // Clear corrupted draft
219
+ try {
220
+ if (typeof window !== 'undefined' && window.sessionStorage) {
221
+ window.sessionStorage.removeItem(storageKey);
222
+ }
223
+ } catch {
224
+ // Ignore cleanup errors
225
+ }
226
+ return null;
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Remove draft from sessionStorage
232
+ */
233
+ function removeDraft(storageKey: string): void {
234
+ if (typeof window === 'undefined' || !window.sessionStorage) {
235
+ return;
236
+ }
237
+
238
+ try {
239
+ window.sessionStorage.removeItem(storageKey);
240
+ } catch (error) {
241
+ console.warn(`[useSessionDraft] Failed to remove draft for key: ${storageKey}`, error);
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Hook for persisting component state to sessionStorage
247
+ *
248
+ * Automatically saves state changes with debouncing and restores state on mount.
249
+ * Data persists across tab switches but clears when the tab closes.
250
+ *
251
+ * @template T - The type of state to persist
252
+ * @param key - Unique key for this draft (will be namespaced automatically)
253
+ * @param initialState - Initial state if no draft exists
254
+ * @param options - Configuration options
255
+ * @returns Object containing state, setState, clearDraft, and utility functions
256
+ *
257
+ * @example
258
+ * ```tsx
259
+ * const { state, setState } = useSessionDraft('user-filters', {
260
+ * search: '',
261
+ * status: 'all'
262
+ * });
263
+ * ```
264
+ */
265
+ export function useSessionDraft<T>(
266
+ key: string,
267
+ initialState: T,
268
+ options: UseSessionDraftOptions = {}
269
+ ): UseSessionDraftReturn<T> {
270
+ const {
271
+ debounceMs = DEFAULT_DEBOUNCE_MS,
272
+ clearOnUnmount = false,
273
+ enabled = true,
274
+ keyPrefix = 'pace-core:draft',
275
+ } = options;
276
+
277
+ const storageKey = getStorageKey(key, keyPrefix);
278
+ const wasRestoredRef = useRef(false);
279
+
280
+ // Load draft on mount
281
+ const [state, setStateInternal] = useState<T>(() => {
282
+ if (!enabled) {
283
+ return initialState;
284
+ }
285
+
286
+ const restored = loadDraft<T>(storageKey);
287
+ if (restored !== null) {
288
+ wasRestoredRef.current = true;
289
+ return restored;
290
+ }
291
+
292
+ return initialState;
293
+ });
294
+
295
+ // Create debounced save function
296
+ const debouncedSaveRef = useRef<ReturnType<typeof debounce> | null>(null);
297
+
298
+ useEffect(() => {
299
+ if (!enabled) {
300
+ return;
301
+ }
302
+
303
+ // Create debounced save function
304
+ const debouncedSave = debounce((data: T) => {
305
+ saveDraft(storageKey, data);
306
+ }, debounceMs);
307
+
308
+ debouncedSaveRef.current = debouncedSave;
309
+
310
+ return () => {
311
+ // Cancel pending saves on unmount
312
+ debouncedSave.cancel();
313
+ };
314
+ }, [storageKey, debounceMs, enabled]);
315
+
316
+ // Save state changes
317
+ const setState = useCallback(
318
+ (newState: T | ((prev: T) => T)) => {
319
+ setStateInternal((prev) => {
320
+ const updated = typeof newState === 'function' ? (newState as (prev: T) => T)(prev) : newState;
321
+
322
+ // Save to storage (debounced)
323
+ if (enabled && debouncedSaveRef.current) {
324
+ debouncedSaveRef.current(updated);
325
+ }
326
+
327
+ return updated;
328
+ });
329
+ },
330
+ [enabled]
331
+ );
332
+
333
+ // Force immediate save
334
+ const saveImmediately = useCallback(() => {
335
+ if (!enabled) {
336
+ return;
337
+ }
338
+
339
+ // Cancel any pending debounced save
340
+ if (debouncedSaveRef.current) {
341
+ debouncedSaveRef.current.cancel();
342
+ }
343
+
344
+ // Save immediately
345
+ saveDraft(storageKey, state);
346
+ }, [storageKey, state, enabled]);
347
+
348
+ // Clear draft
349
+ const clearDraft = useCallback(() => {
350
+ removeDraft(storageKey);
351
+ setStateInternal(initialState);
352
+ wasRestoredRef.current = false;
353
+ }, [storageKey, initialState]);
354
+
355
+ // Cleanup on unmount if configured
356
+ useEffect(() => {
357
+ if (!enabled || !clearOnUnmount) {
358
+ return;
359
+ }
360
+
361
+ return () => {
362
+ // Cancel pending saves
363
+ if (debouncedSaveRef.current) {
364
+ debouncedSaveRef.current.cancel();
365
+ }
366
+
367
+ // Clear draft
368
+ removeDraft(storageKey);
369
+ };
370
+ }, [storageKey, clearOnUnmount, enabled]);
371
+
372
+ return {
373
+ state,
374
+ setState,
375
+ clearDraft,
376
+ saveImmediately,
377
+ wasRestored: wasRestoredRef.current,
378
+ };
379
+ }
380
+
@@ -16,7 +16,9 @@ import { createLogger } from '../utils/core/logger';
16
16
 
17
17
  const log = createLogger('useSessionRestoration');
18
18
 
19
- const SESSION_RESTORATION_TIMEOUT_MS = 5000;
19
+ // Increased timeout to handle hard refresh scenarios where localStorage access
20
+ // and session restoration may take longer, especially with organisation/event context
21
+ const SESSION_RESTORATION_TIMEOUT_MS = 10000; // 10 seconds (increased from 5)
20
22
 
21
23
  /**
22
24
  * Return value of the useSessionRestoration hook.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file Icon Exports
3
+ * @package @jmruthers/pace-core
4
+ * @module Icons
5
+ * @since 0.6.6
6
+ *
7
+ * Icon exports from lucide-react.
8
+ * Import icons from '@jmruthers/pace-core/icons' instead of 'lucide-react'.
9
+ *
10
+ * All lucide-react icons are exported to ensure consuming apps have access
11
+ * to all icons while enforcing consistent usage through pace-core.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * // ✅ CORRECT: Import icons from pace-core
16
+ * import { ChevronDown, Edit, Trash } from '@jmruthers/pace-core/icons';
17
+ *
18
+ * // ❌ WRONG: Direct import from lucide-react (will fail - lucide-react is not a peer dependency)
19
+ * import { ChevronDown } from 'lucide-react';
20
+ * ```
21
+ */
22
+
23
+ // Export all icons from lucide-react
24
+ // This ensures consuming apps have access to all icons while enforcing
25
+ // consistent usage through pace-core's icon export system
26
+ export * from 'lucide-react';
27
+
package/src/index.ts CHANGED
@@ -101,7 +101,6 @@ export type { ProgressProps } from './components/Progress';
101
101
  export {
102
102
  Dialog,
103
103
  DialogPortal,
104
- DialogOverlay,
105
104
  DialogTrigger,
106
105
  DialogClose,
107
106
  DialogContent,
@@ -111,6 +110,17 @@ export {
111
110
  DialogTitle,
112
111
  DialogDescription,
113
112
  } from './components/Dialog/Dialog';
113
+ export type {
114
+ DialogProps,
115
+ DialogTriggerProps,
116
+ DialogContentProps,
117
+ DialogPortalProps,
118
+ DialogCloseProps,
119
+ DialogHeaderProps,
120
+ DialogFooterProps,
121
+ DialogBodyProps,
122
+ DialogSize
123
+ } from './components/Dialog/Dialog';
114
124
 
115
125
  // Dropdown Menu exports
116
126
  // DropdownMenu components have been merged into Select components
@@ -202,6 +212,8 @@ export { z } from 'zod';
202
212
  // Common validation schemas
203
213
  export { emailSchema, nameSchema, phoneSchema, urlSchema } from './utils/validation/common';
204
214
  export { passwordSchema } from './utils/validation/passwordSchema';
215
+ // Sanitization utilities
216
+ export { sanitizeUserInput, sanitizeFormData, sanitizeHtml } from './utils/validation/sanitization';
205
217
 
206
218
  // LAYOUT COMPONENTS
207
219
  export { Header } from './components/Header/Header';
@@ -250,6 +262,9 @@ export { useEventTheme } from './hooks/useEventTheme';
250
262
  export { cn } from './utils/core/cn';
251
263
  export { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/app/appConfig';
252
264
 
265
+ // Supabase client creation (restricted wrapper - ONLY for base client creation)
266
+ export { createBaseClient } from './utils/supabase/createBaseClient';
267
+
253
268
  // LOGGING UTILITIES
254
269
  export { Logger, logger, createLogger, LogLevel } from './utils/core/logger';
255
270
  export type { LoggerConfig } from './utils/core/logger';