@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
@@ -9,31 +9,37 @@
9
9
  */
10
10
 
11
11
  import React from 'react';
12
- import { render, screen, within } from '@testing-library/react';
12
+ import { render, screen, within, waitFor } from '@testing-library/react';
13
13
  import userEvent from '@testing-library/user-event';
14
14
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
15
15
  import { ViewRowModal } from '../ViewRowModal';
16
16
 
17
- // Mock Dialog components - Use the same pattern as other tests
18
- // Note: Path must match the import in ViewRowModal.tsx exactly
19
- vi.mock('../../Dialog/Dialog', async () => {
20
- const actual = await vi.importActual('../../Dialog/Dialog');
21
- return {
22
- ...actual,
23
- Dialog: ({ children, open, onOpenChange }: any) => (
24
- open ? <div role="dialog" data-testid="dialog">{children}</div> : null
25
- ),
26
- DialogContent: ({ children, className }: any) => (
27
- <div data-testid="dialog-content" className={className}>{children}</div>
28
- ),
29
- DialogHeader: ({ children }: any) => (
30
- <div data-testid="dialog-header">{children}</div>
31
- ),
32
- DialogTitle: ({ children, className }: any) => (
33
- <h2 data-testid="dialog-title" className={className} role="heading" aria-level={2}>{children}</h2>
34
- ),
35
- };
36
- });
17
+ // Helper function to wait for dialog to be accessible
18
+ // Native dialog elements are only accessible after showModal() completes
19
+ // In test environments, we use querySelector as fallback since getByRole may not work
20
+ // Note: In test environments (jsdom), dialog.open may not be set even when dialog is rendered
21
+ const waitForDialog = async (): Promise<HTMLElement> => {
22
+ return await waitFor(
23
+ () => {
24
+ // Try getByRole first (works in browsers with full dialog support)
25
+ try {
26
+ const dialog = screen.getByRole('dialog');
27
+ expect(dialog).toBeInTheDocument();
28
+ return dialog;
29
+ } catch (e) {
30
+ // Fallback: use querySelector for test environments that don't fully support dialog accessibility
31
+ const dialog = document.querySelector('dialog[role="dialog"]') as HTMLDialogElement;
32
+ if (!dialog) {
33
+ throw new Error('Dialog not found in DOM');
34
+ }
35
+ // In test environments, dialog.open may not be set even when dialog is rendered
36
+ // Just check that dialog exists in DOM - that's sufficient for testing
37
+ return dialog;
38
+ }
39
+ },
40
+ { timeout: 3000 }
41
+ );
42
+ };
37
43
 
38
44
  // Mock Button component
39
45
  vi.mock('../../Button/Button', () => ({
@@ -105,33 +111,40 @@ describe('[component] ViewRowModal', () => {
105
111
  expect(container.firstChild).toBeNull();
106
112
  });
107
113
 
108
- it('renders modal when open with data', () => {
114
+ it('renders modal when open with data', async () => {
109
115
  render(<ViewRowModal {...baseProps} />);
110
116
 
111
- // Dialog renders with role="dialog" from Radix UI
112
- expect(screen.getByRole('dialog')).toBeInTheDocument();
117
+ // Wait for dialog to be accessible (showModal() is async)
118
+ await waitForDialog();
113
119
  // DialogContent and DialogHeader are rendered but may not have testids in actual implementation
114
120
  // Check for content instead
115
121
  expect(screen.getByText('Row Details')).toBeInTheDocument();
116
122
  });
117
123
 
118
- it('renders default title when title prop is not provided', () => {
124
+ it('renders default title when title prop is not provided', async () => {
119
125
  render(<ViewRowModal {...baseProps} />);
120
126
 
121
- // DialogTitle renders as h2, check for text content
127
+ // Wait for dialog to be accessible
128
+ await waitForDialog();
129
+ // Title is rendered as h2 in DialogHeader, check for text content
122
130
  expect(screen.getByText('Row Details')).toBeInTheDocument();
123
131
  });
124
132
 
125
- it('renders custom title when title prop is provided', () => {
133
+ it('renders custom title when title prop is provided', async () => {
126
134
  render(<ViewRowModal {...baseProps} title="Custom Title" />);
127
135
 
128
- // DialogTitle renders as h2, check for text content
136
+ // Wait for dialog to be accessible
137
+ await waitForDialog();
138
+ // Title is rendered as h2 in DialogHeader, check for text content
129
139
  expect(screen.getByText('Custom Title')).toBeInTheDocument();
130
140
  });
131
141
 
132
- it('renders all data fields', () => {
142
+ it('renders all data fields', async () => {
133
143
  render(<ViewRowModal {...baseProps} />);
134
144
 
145
+ // Wait for dialog to be accessible
146
+ await waitForDialog();
147
+
135
148
  expect(screen.getByText(/id/i)).toBeInTheDocument();
136
149
  expect(screen.getByText(/name/i)).toBeInTheDocument();
137
150
  expect(screen.getByText(/email/i)).toBeInTheDocument();
@@ -139,9 +152,12 @@ describe('[component] ViewRowModal', () => {
139
152
  expect(screen.getByText(/active/i)).toBeInTheDocument();
140
153
  });
141
154
 
142
- it('renders field values correctly', () => {
155
+ it('renders field values correctly', async () => {
143
156
  render(<ViewRowModal {...baseProps} />);
144
157
 
158
+ // Wait for dialog to be accessible
159
+ await waitForDialog();
160
+
145
161
  expect(screen.getByText('1')).toBeInTheDocument();
146
162
  expect(screen.getByText('John Doe')).toBeInTheDocument();
147
163
  expect(screen.getByText('john@example.com')).toBeInTheDocument();
@@ -149,9 +165,12 @@ describe('[component] ViewRowModal', () => {
149
165
  expect(screen.getByText('true')).toBeInTheDocument();
150
166
  });
151
167
 
152
- it('formats Date values as locale date strings', () => {
168
+ it('formats Date values as locale date strings', async () => {
153
169
  render(<ViewRowModal {...baseProps} />);
154
170
 
171
+ // Wait for dialog to be accessible
172
+ await waitForDialog();
173
+
155
174
  const dateValue = screen.getByText(new Date('2024-01-01').toLocaleDateString());
156
175
  expect(dateValue).toBeInTheDocument();
157
176
  });
@@ -203,9 +222,18 @@ describe('[component] ViewRowModal', () => {
203
222
 
204
223
  render(<ViewRowModal {...baseProps} onClose={handleClose} />);
205
224
 
206
- // Get the main "Close" button (not the X icon button)
207
- const closeButtons = screen.getAllByRole('button', { name: /close/i });
208
- const mainCloseButton = closeButtons.find(btn => btn.textContent === 'Close');
225
+ // Wait for dialog title to ensure dialog is rendered
226
+ await waitFor(() => {
227
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
228
+ }, { timeout: 5000 });
229
+
230
+ // Find the main "Close" button (not the X icon button) - there are multiple Close buttons
231
+ const closeButtons = screen.getAllByText('Close');
232
+ // The main Close button is the one that's not inside a span with sr-only class
233
+ const mainCloseButton = closeButtons.find(btn => {
234
+ const button = btn.closest('button');
235
+ return button && !button.querySelector('.sr-only');
236
+ })?.closest('button');
209
237
  expect(mainCloseButton).toBeInTheDocument();
210
238
  if (mainCloseButton) {
211
239
  await user.click(mainCloseButton);
@@ -219,6 +247,12 @@ describe('[component] ViewRowModal', () => {
219
247
 
220
248
  render(<ViewRowModal {...baseProps} onClose={handleClose} />);
221
249
 
250
+ // Wait for dialog content to be rendered
251
+ await waitFor(() => {
252
+ const xButtons = screen.getAllByTestId('x-icon');
253
+ expect(xButtons.length).toBeGreaterThan(0);
254
+ }, { timeout: 5000 });
255
+
222
256
  // Get the X icon button specifically (first button with X icon)
223
257
  const xButtons = screen.getAllByTestId('x-icon');
224
258
  const xButton = xButtons[0].closest('button');
@@ -240,9 +274,18 @@ describe('[component] ViewRowModal', () => {
240
274
  />
241
275
  );
242
276
 
243
- // Get the main Close button (not the X icon button)
244
- const closeButtons = screen.getAllByRole('button', { name: /close/i });
245
- const mainCloseButton = closeButtons.find(btn => btn.textContent === 'Close');
277
+ // Wait for dialog title to ensure dialog is rendered
278
+ await waitFor(() => {
279
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
280
+ }, { timeout: 5000 });
281
+
282
+ // Find the main "Close" button (not the X icon button) - there are multiple Close buttons
283
+ const closeButtons = screen.getAllByText('Close');
284
+ // The main Close button is the one that's not inside a span with sr-only class
285
+ const mainCloseButton = closeButtons.find(btn => {
286
+ const button = btn.closest('button');
287
+ return button && !button.querySelector('.sr-only');
288
+ })?.closest('button');
246
289
  expect(mainCloseButton).toBeInTheDocument();
247
290
  if (mainCloseButton) {
248
291
  await user.click(mainCloseButton);
@@ -252,14 +295,20 @@ describe('[component] ViewRowModal', () => {
252
295
  });
253
296
 
254
297
  describe('Edge Cases', () => {
255
- it('handles empty data object', () => {
298
+ it('handles empty data object', async () => {
256
299
  render(<ViewRowModal {...baseProps} data={{}} />);
257
300
 
258
- expect(screen.getByRole('dialog')).toBeInTheDocument();
259
- expect(screen.getAllByRole('button', { name: /close/i }).length).toBeGreaterThan(0);
301
+ // Wait for dialog title to ensure dialog is rendered
302
+ await waitFor(() => {
303
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
304
+ }, { timeout: 5000 });
305
+
306
+ // Verify Close button exists (there are multiple, so use getAllByText)
307
+ const closeButtons = screen.getAllByText('Close');
308
+ expect(closeButtons.length).toBeGreaterThan(0);
260
309
  });
261
310
 
262
- it('handles data with undefined values', () => {
311
+ it('handles data with undefined values', async () => {
263
312
  const dataWithUndefined = {
264
313
  ...mockData,
265
314
  optionalField: undefined,
@@ -267,7 +316,7 @@ describe('[component] ViewRowModal', () => {
267
316
 
268
317
  render(<ViewRowModal {...baseProps} data={dataWithUndefined} />);
269
318
 
270
- expect(screen.getByRole('dialog')).toBeInTheDocument();
319
+ await waitForDialog();
271
320
  });
272
321
 
273
322
  it('handles data with array values', () => {
@@ -358,39 +407,54 @@ describe('[component] ViewRowModal', () => {
358
407
  });
359
408
 
360
409
  describe('Accessibility', () => {
361
- it('provides close button with aria-label', () => {
410
+ it('provides close button with aria-label', async () => {
362
411
  render(<ViewRowModal {...baseProps} />);
363
412
 
364
- const buttons = screen.getAllByRole('button');
365
- expect(buttons.length).toBeGreaterThan(0);
413
+ // Wait for dialog title to ensure dialog is rendered
414
+ await waitFor(() => {
415
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
416
+ }, { timeout: 5000 });
417
+
418
+ // Verify buttons exist (use querySelector as fallback since role queries may not work in test environments)
419
+ const dialog = document.querySelector('dialog[role="dialog"]');
420
+ expect(dialog).toBeInTheDocument();
421
+ const buttons = dialog?.querySelectorAll('button');
422
+ expect(buttons?.length).toBeGreaterThan(0);
366
423
  });
367
424
 
368
- it('provides main close button with accessible text', () => {
425
+ it('provides main close button with accessible text', async () => {
369
426
  render(<ViewRowModal {...baseProps} />);
370
427
 
371
- const closeButtons = screen.getAllByRole('button', { name: /close/i });
428
+ // Wait for dialog title to ensure dialog is rendered
429
+ await waitFor(() => {
430
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
431
+ }, { timeout: 5000 });
432
+
433
+ // Verify Close button exists (there are multiple, so use getAllByText)
434
+ const closeButtons = screen.getAllByText('Close');
372
435
  expect(closeButtons.length).toBeGreaterThan(0);
373
436
  });
374
437
 
375
- it('renders dialog with proper structure', () => {
438
+ it('renders dialog with proper structure', async () => {
376
439
  render(<ViewRowModal {...baseProps} />);
377
440
 
378
- expect(screen.getByRole('dialog')).toBeInTheDocument();
379
- // Check for content structure instead of testids
380
- expect(screen.getByText('Row Details')).toBeInTheDocument();
381
- expect(screen.getByText('John Doe')).toBeInTheDocument();
441
+ // Wait for dialog content to be rendered
442
+ await waitFor(() => {
443
+ expect(screen.getByText('Row Details')).toBeInTheDocument();
444
+ expect(screen.getByText('John Doe')).toBeInTheDocument();
445
+ }, { timeout: 5000 });
382
446
  });
383
447
  });
384
448
 
385
449
  describe('Layout and Styling', () => {
386
- it('applies max-width and max-height classes to dialog content', () => {
450
+ it('applies max-width and max-height classes to dialog content', async () => {
387
451
  render(<ViewRowModal {...baseProps} />);
388
452
 
389
- // DialogContent receives className prop, check if dialog has the classes
390
- const dialog = screen.getByRole('dialog');
391
- // The classes are applied to DialogContent which is inside the dialog
392
- // Check that dialog is rendered (classes are on the inner element)
393
- expect(dialog).toBeInTheDocument();
453
+ // Wait for dialog content to be rendered
454
+ await waitFor(() => {
455
+ const dialog = document.querySelector('dialog[role="dialog"]') || screen.getByRole('dialog');
456
+ expect(dialog).toBeInTheDocument();
457
+ }, { timeout: 5000 });
394
458
  });
395
459
 
396
460
  it('renders field labels with proper styling classes', () => {
@@ -40,10 +40,6 @@ export function usePermissionTracking({
40
40
  if (permissions.canRead.isLoading && !hasStartedTracking.current) {
41
41
  hasStartedTracking.current = true;
42
42
  permissionCheckStartTime.current = Date.now();
43
- logger.debug('DataTable: Permission check started', {
44
- pageId: effectivePageId,
45
- timestamp: permissionCheckStartTime.current,
46
- });
47
43
 
48
44
  if (permissionWarningTimeoutId.current) {
49
45
  clearTimeout(permissionWarningTimeoutId.current);
@@ -12,7 +12,7 @@ import { Button } from '../../Button/Button';
12
12
  import { Input } from '../../Input/Input';
13
13
  import { Checkbox } from '../../Checkbox/Checkbox';
14
14
  // DropdownMenu components have been merged into Select components
15
- import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '../../Dialog/Dialog';
15
+ import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../../Dialog/Dialog';
16
16
  import type { DataTableContext as IDataTableContext, DataTableConfig, DataTableUtils } from './interfaces';
17
17
  import type { DataRecord, DataTableAction } from '../types';
18
18
  import type { ColumnDef } from '@tanstack/react-table';