@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.
- package/CHANGELOG.md +104 -0
- package/README.md +5 -403
- package/core-usage-manifest.json +93 -0
- package/cursor-rules/00-pace-core-compliance.mdc +128 -26
- package/cursor-rules/01-standards-compliance.mdc +49 -8
- package/cursor-rules/02-project-structure.mdc +6 -0
- package/cursor-rules/03-solid-principles.mdc +2 -0
- package/cursor-rules/04-testing-standards.mdc +2 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
- package/cursor-rules/06-code-quality.mdc +2 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
- package/cursor-rules/08-markup-quality.mdc +52 -27
- package/cursor-rules/09-rbac-compliance.mdc +462 -0
- package/cursor-rules/10-error-handling-patterns.mdc +179 -0
- package/cursor-rules/11-performance-optimization.mdc +169 -0
- package/cursor-rules/12-ci-cd-integration.mdc +150 -0
- package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
- package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
- package/dist/DataTable-LRJL4IRV.js +15 -0
- package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
- package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
- package/dist/api-Y4MQWOFW.js +4 -0
- package/dist/audit-MYQXYZFU.js +3 -0
- package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
- package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
- package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
- package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
- package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
- package/dist/chunk-4T7OBVTU.js +62 -0
- package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
- package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
- package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
- package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
- package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
- package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
- package/dist/chunk-C7NSAPTL.js +1 -0
- package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
- package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
- package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
- package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
- package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
- package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
- package/dist/chunk-MBADTM7L.js +64 -0
- package/dist/chunk-OHIK3MIO.js +994 -0
- package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
- package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
- package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
- package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
- package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
- package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
- package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
- package/dist/components.d.ts +6 -6
- package/dist/components.js +57 -267
- package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
- package/dist/eslint-rules/index.cjs +22 -0
- package/dist/eslint-rules/rules/compliance.cjs +348 -0
- package/dist/eslint-rules/rules/components.cjs +113 -0
- package/dist/eslint-rules/rules/imports.cjs +102 -0
- package/dist/eslint-rules/rules/rbac.cjs +790 -0
- package/dist/eslint-rules/utils/helpers.cjs +42 -0
- package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +62 -270
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +36 -26
- package/dist/index.js +87 -690
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +8 -35
- package/dist/rbac/eslint-rules.d.ts +46 -44
- package/dist/rbac/eslint-rules.js +7 -4
- package/dist/rbac/index.d.ts +124 -594
- package/dist/rbac/index.js +14 -207
- package/dist/styles/index.js +2 -12
- package/dist/theming/runtime.js +3 -19
- package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
- package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
- package/dist/types-t9H8qKRw.d.ts +55 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +7 -94
- package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
- package/dist/utils.d.ts +24 -117
- package/dist/utils.js +54 -392
- package/docs/README.md +16 -6
- package/docs/api/README.md +4 -402
- package/docs/api/modules.md +454 -930
- package/docs/api-reference/components.md +3 -1
- package/docs/api-reference/deprecated.md +31 -6
- package/docs/api-reference/rpc-functions.md +78 -3
- package/docs/best-practices/accessibility.md +6 -3
- package/docs/getting-started/cursor-rules.md +3 -23
- package/docs/getting-started/dependencies.md +650 -0
- package/docs/getting-started/installation-guide.md +20 -7
- package/docs/getting-started/quick-start.md +23 -12
- package/docs/implementation-guides/permission-enforcement.md +4 -0
- package/docs/rbac/MIGRATION_GUIDE.md +819 -0
- package/docs/rbac/RBAC_CONTRACT.md +724 -0
- package/docs/rbac/README.md +12 -3
- package/docs/rbac/edge-functions-guide.md +376 -0
- package/docs/rbac/secure-client-protection.md +0 -34
- package/docs/standards/00-pace-core-compliance.md +967 -0
- package/docs/standards/01-standards-compliance.md +188 -0
- package/docs/standards/02-project-structure.md +985 -0
- package/docs/standards/03-solid-principles.md +39 -0
- package/docs/standards/04-testing-standards.md +36 -0
- package/docs/standards/05-bug-reports-and-features.md +27 -0
- package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
- package/docs/standards/07-tech-stack-compliance.md +30 -0
- package/docs/standards/08-markup-quality.md +345 -0
- package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
- package/docs/standards/10-error-handling-patterns.md +401 -0
- package/docs/standards/11-performance-optimization.md +348 -0
- package/docs/standards/12-ci-cd-integration.md +370 -0
- package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
- package/docs/standards/README.md +62 -33
- package/docs/troubleshooting/organisation-context-setup.md +42 -19
- package/eslint-config-pace-core.cjs +20 -4
- package/package.json +31 -21
- package/scripts/audit/audit-compliance.cjs +1295 -0
- package/scripts/audit/audit-components.cjs +260 -0
- package/scripts/audit/audit-dependencies.cjs +395 -0
- package/scripts/audit/audit-rbac.cjs +954 -0
- package/scripts/audit/audit-standards.cjs +1268 -0
- package/scripts/audit/index.cjs +1898 -194
- package/scripts/install-cursor-rules.cjs +259 -8
- package/scripts/validate-master.js +1 -1
- package/src/__tests__/fixtures/supabase.ts +1 -1
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
- package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
- package/src/__tests__/helpers/component-test-utils.tsx +1 -1
- package/src/__tests__/helpers/supabaseMock.ts +2 -2
- package/src/__tests__/public-recipe-view.test.ts +38 -9
- package/src/components/Button/Button.tsx +5 -1
- package/src/components/ContextSelector/ContextSelector.tsx +42 -39
- package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
- package/src/components/DataTable/components/DataTableBody.tsx +55 -31
- package/src/components/DataTable/components/DataTableCore.tsx +186 -13
- package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
- package/src/components/DataTable/components/EditFields.tsx +23 -3
- package/src/components/DataTable/components/EditableRow.tsx +7 -2
- package/src/components/DataTable/components/ImportModal.tsx +4 -6
- package/src/components/DataTable/components/RowComponent.tsx +12 -0
- package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
- package/src/components/DataTable/core/DataTableContext.tsx +1 -1
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
- package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
- package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
- package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
- package/src/components/DataTable/types.ts +5 -0
- package/src/components/DateTimeField/DateTimeField.tsx +20 -20
- package/src/components/DateTimeField/README.md +5 -2
- package/src/components/Dialog/Dialog.test.tsx +361 -318
- package/src/components/Dialog/Dialog.tsx +1154 -323
- package/src/components/Dialog/index.ts +3 -3
- package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
- package/src/components/FileDisplay/FileDisplay.tsx +28 -22
- package/src/components/Form/Form.test.tsx +9 -10
- package/src/components/Form/Form.tsx +369 -9
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
- package/src/components/LoginForm/LoginForm.tsx +2 -2
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
- package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
- package/src/components/PaceAppLayout/README.md +10 -9
- package/src/components/PaceAppLayout/test-setup.tsx +40 -31
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
- package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
- package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
- package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
- package/src/components/Select/Select.tsx +23 -21
- package/src/components/Select/types.ts +1 -1
- package/src/components/UserMenu/UserMenu.test.tsx +38 -6
- package/src/components/UserMenu/UserMenu.tsx +39 -34
- package/src/components/index.ts +3 -4
- package/src/eslint-rules/index.cjs +22 -0
- package/src/eslint-rules/rules/compliance.cjs +348 -0
- package/src/eslint-rules/rules/components.cjs +113 -0
- package/src/eslint-rules/rules/imports.cjs +102 -0
- package/src/eslint-rules/rules/rbac.cjs +790 -0
- package/src/eslint-rules/utils/helpers.cjs +42 -0
- package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
- package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
- package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
- package/src/hooks/public/usePublicEvent.ts +62 -190
- package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
- package/src/hooks/public/usePublicEventLogo.ts +19 -9
- package/src/hooks/useAppConfig.ts +26 -24
- package/src/hooks/useEventTheme.test.ts +211 -233
- package/src/hooks/useEventTheme.ts +19 -28
- package/src/hooks/useEvents.ts +11 -7
- package/src/hooks/useKeyboardShortcuts.ts +1 -1
- package/src/hooks/useOrganisationPermissions.ts +9 -11
- package/src/hooks/useOrganisations.ts +13 -7
- package/src/hooks/useQueryCache.ts +0 -1
- package/src/hooks/useSessionDraft.ts +380 -0
- package/src/hooks/useSessionRestoration.ts +3 -1
- package/src/icons/index.ts +27 -0
- package/src/index.ts +16 -1
- package/src/providers/OrganisationProvider.tsx +23 -14
- package/src/providers/services/EventServiceProvider.tsx +1 -24
- package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
- package/src/rbac/README.md +20 -20
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
- package/src/rbac/adapters.tsx +7 -295
- package/src/rbac/api.test.ts +44 -56
- package/src/rbac/api.ts +10 -17
- package/src/rbac/cache-invalidation.ts +0 -1
- package/src/rbac/compliance/index.ts +10 -0
- package/src/rbac/compliance/pattern-detector.ts +553 -0
- package/src/rbac/compliance/runtime-compliance.ts +22 -0
- package/src/rbac/components/AccessDenied.tsx +150 -0
- package/src/rbac/components/NavigationGuard.tsx +12 -20
- package/src/rbac/components/PagePermissionGuard.tsx +4 -24
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
- package/src/rbac/components/index.ts +3 -41
- package/src/rbac/eslint-rules.js +1 -1
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/permissions/index.ts +0 -3
- package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
- package/src/rbac/hooks/usePermissions.ts +0 -3
- package/src/rbac/hooks/useRBAC.test.ts +21 -3
- package/src/rbac/hooks/useRBAC.ts +4 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
- package/src/rbac/hooks/useResolvedScope.ts +58 -140
- package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
- package/src/rbac/hooks/useResourcePermissions.ts +182 -63
- package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
- package/src/rbac/hooks/useRoleManagement.ts +147 -19
- package/src/rbac/hooks/useSecureSupabase.ts +4 -8
- package/src/rbac/index.ts +7 -9
- package/src/rbac/permissions.ts +17 -17
- package/src/rbac/utils/contextValidator.ts +45 -7
- package/src/services/AuthService.ts +132 -23
- package/src/services/EventService.ts +4 -97
- package/src/services/InactivityService.ts +155 -58
- package/src/services/OrganisationService.ts +7 -44
- package/src/services/__tests__/OrganisationService.test.ts +26 -8
- package/src/services/base/BaseService.ts +0 -3
- package/src/styles/core.css +4 -0
- package/src/types/database.generated.ts +4733 -3809
- package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
- package/src/utils/context/organisationContext.test.ts +13 -28
- package/src/utils/context/organisationContext.ts +21 -52
- package/src/utils/dynamic/dynamicUtils.ts +1 -1
- package/src/utils/file-reference/index.ts +39 -15
- package/src/utils/formatting/formatDateTime.test.ts +3 -2
- package/src/utils/formatting/formatTime.test.ts +3 -2
- package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
- package/src/utils/index.ts +4 -1
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
- package/src/utils/persistence/keyDerivation.ts +304 -0
- package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
- package/src/utils/security/secureStorage.ts +5 -5
- package/src/utils/storage/helpers.ts +3 -3
- package/src/utils/supabase/createBaseClient.ts +147 -0
- package/src/utils/timezone/timezone.test.ts +1 -2
- package/src/utils/timezone/timezone.ts +1 -1
- package/src/utils/validation/csrf.ts +4 -4
- package/cursor-rules/CHANGELOG.md +0 -119
- package/cursor-rules/README.md +0 -192
- package/dist/DataTable-E7YQZD7D.js +0 -175
- package/dist/DataTable-E7YQZD7D.js.map +0 -1
- package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
- package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
- package/dist/api-6LVZTHDS.js +0 -52
- package/dist/api-6LVZTHDS.js.map +0 -1
- package/dist/audit-V53FV5AG.js +0 -17
- package/dist/audit-V53FV5AG.js.map +0 -1
- package/dist/chunk-36LVWXB2.js +0 -227
- package/dist/chunk-36LVWXB2.js.map +0 -1
- package/dist/chunk-3LPHPB62.js.map +0 -1
- package/dist/chunk-5DRSZLL2.js.map +0 -1
- package/dist/chunk-5EC5MEWX.js.map +0 -1
- package/dist/chunk-63FOKYGO.js.map +0 -1
- package/dist/chunk-6SOIHG6Z.js.map +0 -1
- package/dist/chunk-7JPAB3T5.js.map +0 -1
- package/dist/chunk-ATKZM7RX.js +0 -2053
- package/dist/chunk-ATKZM7RX.js.map +0 -1
- package/dist/chunk-AVMLPIM7.js.map +0 -1
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-E66EQZE6.js.map +0 -1
- package/dist/chunk-FFQEQTNW.js.map +0 -1
- package/dist/chunk-FMUCXFII.js.map +0 -1
- package/dist/chunk-G37KK66H.js.map +0 -1
- package/dist/chunk-I6DAQMWX.js.map +0 -1
- package/dist/chunk-J36DSWQK.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js +0 -1
- package/dist/chunk-KQCRWDSA.js.map +0 -1
- package/dist/chunk-L4OXEN46.js.map +0 -1
- package/dist/chunk-LMC26NLJ.js +0 -84
- package/dist/chunk-LMC26NLJ.js.map +0 -1
- package/dist/chunk-M43Y4SSO.js.map +0 -1
- package/dist/chunk-M7MPQISP.js.map +0 -1
- package/dist/chunk-NN6WWZ5U.js.map +0 -1
- package/dist/chunk-OEWDTMG7.js.map +0 -1
- package/dist/chunk-PWLANIRT.js.map +0 -1
- package/dist/chunk-QXHPKYJV.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js.map +0 -1
- package/dist/chunk-YKRAFF5K.js.map +0 -1
- package/dist/chunk-ZSAAAMVR.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/contextValidator-OOPCLPZW.js +0 -9
- package/dist/contextValidator-OOPCLPZW.js.map +0 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
- package/dist/hooks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/rbac/eslint-rules.js.map +0 -1
- package/dist/rbac/index.js.map +0 -1
- package/dist/styles/index.js.map +0 -1
- package/dist/theming/runtime.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/docs/standards/01-architecture-standard.md +0 -44
- package/docs/standards/02-api-and-rpc-standard.md +0 -39
- package/docs/standards/03-component-standard.md +0 -32
- package/docs/standards/05-security-standard.md +0 -44
- package/docs/standards/06-testing-and-docs-standard.md +0 -29
- package/docs/standards/pace-core-compliance.md +0 -432
- package/scripts/audit/core/checks/accessibility.cjs +0 -197
- package/scripts/audit/core/checks/api-usage.cjs +0 -191
- package/scripts/audit/core/checks/bundle.cjs +0 -142
- package/scripts/audit/core/checks/compliance.cjs +0 -2706
- package/scripts/audit/core/checks/config.cjs +0 -54
- package/scripts/audit/core/checks/coverage.cjs +0 -84
- package/scripts/audit/core/checks/dependencies.cjs +0 -994
- package/scripts/audit/core/checks/documentation.cjs +0 -268
- package/scripts/audit/core/checks/environment.cjs +0 -116
- package/scripts/audit/core/checks/error-handling.cjs +0 -340
- package/scripts/audit/core/checks/forms.cjs +0 -172
- package/scripts/audit/core/checks/heuristics.cjs +0 -68
- package/scripts/audit/core/checks/hooks.cjs +0 -334
- package/scripts/audit/core/checks/imports.cjs +0 -244
- package/scripts/audit/core/checks/performance.cjs +0 -325
- package/scripts/audit/core/checks/routes.cjs +0 -117
- package/scripts/audit/core/checks/state.cjs +0 -130
- package/scripts/audit/core/checks/structure.cjs +0 -65
- package/scripts/audit/core/checks/style.cjs +0 -584
- package/scripts/audit/core/checks/testing.cjs +0 -122
- package/scripts/audit/core/checks/typescript.cjs +0 -61
- package/scripts/audit/core/scanner.cjs +0 -199
- package/scripts/audit/core/utils.cjs +0 -137
- package/scripts/audit/reporters/console.cjs +0 -151
- package/scripts/audit/reporters/json.cjs +0 -54
- package/scripts/audit/reporters/markdown.cjs +0 -124
- package/scripts/audit-consuming-app.cjs +0 -86
- package/src/eslint-rules/pace-core-compliance.cjs +0 -510
- package/src/eslint-rules/pace-core-compliance.js +0 -638
- package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
- package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
- package/src/rbac/components/NavigationProvider.test.tsx +0 -481
- package/src/rbac/components/NavigationProvider.tsx +0 -345
- package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
- package/src/rbac/components/PagePermissionProvider.tsx +0 -279
- package/src/rbac/components/PermissionEnforcer.tsx +0 -312
- package/src/rbac/components/RoleBasedRouter.tsx +0 -440
- package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
- package/src/rbac/components/SecureDataProvider.tsx +0 -339
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
- 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
|
-
//
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
//
|
|
112
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
|
|
259
|
-
|
|
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
|
-
|
|
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
|
-
|
|
365
|
-
|
|
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
|
-
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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,
|
|
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';
|