@jmruthers/pace-core 0.6.7 → 0.6.8
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/audit-tool/00-dependencies.cjs +215 -9
- package/audit-tool/audits/02-project-structure.cjs +3 -18
- package/audit-tool/audits/03-architecture.cjs +34 -6
- package/audit-tool/audits/06-security-rbac.cjs +10 -0
- package/audit-tool/audits/07-api-tech-stack.cjs +55 -1
- package/audit-tool/index.cjs +23 -19
- package/audit-tool/utils/report-utils.cjs +141 -2
- package/dist/{DataTable-7PMH7XN7.js → DataTable-6RMSCQJ6.js} +5 -5
- package/dist/{PublicPageProvider-DlsCaR5v.d.ts → PublicPageProvider-CIGSujI2.d.ts} +14 -8
- package/dist/{UnifiedAuthProvider-ZT6TIGM7.js → UnifiedAuthProvider-7SNDOWYD.js} +2 -2
- package/dist/{api-Y4MQWOFW.js → api-7P7DI652.js} +1 -1
- package/dist/{chunk-L4XMVJKY.js → chunk-4DDCYDQ3.js} +8 -7
- package/dist/{chunk-ZKAWKYT4.js → chunk-5W2A3DRC.js} +2 -1
- package/dist/{chunk-VBCS3DUA.js → chunk-EF2UGZWY.js} +3 -3
- package/dist/{chunk-JGWDVX64.js → chunk-EURB7QFZ.js} +123 -53
- package/dist/{chunk-BM4CQ5P3.js → chunk-GS5672WG.js} +6 -6
- package/dist/{chunk-ZFYPMX46.js → chunk-LX6U42O3.js} +1 -1
- package/dist/{chunk-5X4QLXRG.js → chunk-MPBLMWVR.js} +5 -3
- package/dist/{chunk-Q7Q7V5NV.js → chunk-NKHKXPI4.js} +7 -7
- package/dist/{chunk-6F3IILHI.js → chunk-S6ZQKDY6.js} +1 -1
- package/dist/{chunk-FTCRZOG2.js → chunk-T5CVK4R3.js} +5 -5
- package/dist/{chunk-GHYHJTYV.js → chunk-Z2FNRKF3.js} +13 -13
- package/dist/components.d.ts +1 -1
- package/dist/components.js +12 -12
- package/dist/eslint-rules/rules/04-code-quality.cjs +66 -10
- package/dist/eslint-rules/rules/06-security-rbac.cjs +8 -3
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +190 -68
- package/dist/{functions-DHebl8-F.d.ts → functions-lBy5L2ry.d.ts} +1 -1
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +15 -15
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +1 -1
- package/dist/rbac/index.js +6 -6
- package/dist/theming/runtime.d.ts +48 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/utils.js +1 -1
- package/docs/api/modules.md +63 -14
- package/docs/getting-started/dependencies.md +23 -0
- package/docs/implementation-guides/app-layout.md +1 -1
- package/docs/implementation-guides/data-tables.md +1 -1
- package/docs/standards/1-pace-core-compliance-standards.md +38 -1
- package/eslint-config-pace-core.cjs +30 -11
- package/package.json +45 -15
- package/scripts/eslint-audit.cjs +123 -0
- package/scripts/install-eslint-config.cjs +67 -2
- package/scripts/validate-dependencies.cjs +248 -0
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +20 -8
- package/src/__tests__/templates/accessibility.test.template.tsx +1 -0
- package/src/components/AddressField/AddressField.tsx +26 -1
- package/src/components/Alert/Alert.test.tsx +86 -22
- package/src/components/Alert/Alert.tsx +19 -11
- package/src/components/Badge/Badge.tsx +1 -1
- package/src/components/Checkbox/Checkbox.test.tsx +2 -1
- package/src/components/ContextSelector/ContextSelector.tsx +39 -41
- package/src/components/DataTable/DataTable.tsx +1 -19
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +6 -10
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +18 -9
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +3 -2
- package/src/components/DataTable/components/EmptyState.tsx +1 -1
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +3 -3
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +33 -29
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -2
- package/src/components/FileUpload/FileUpload.test.tsx +22 -31
- package/src/components/FileUpload/FileUpload.tsx +29 -0
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +48 -12
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +9 -9
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +30 -30
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +4 -4
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +7 -1
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +8 -5
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +4 -0
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +3 -3
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +45 -8
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +22 -2
- package/src/hooks/public/usePublicRouteParams.ts +8 -4
- package/src/hooks/useAddressAutocomplete.test.ts +18 -18
- package/src/hooks/useEventTheme.ts +5 -1
- package/src/hooks/useFileUrl.ts +52 -8
- package/src/hooks/useOrganisationSecurity.test.ts +2 -1
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +1 -1
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +15 -6
- package/src/rbac/__tests__/rbac-functions.test.ts +3 -3
- package/src/rbac/api.test.ts +104 -0
- package/src/rbac/engine.ts +1 -1
- package/src/rbac/hooks/useCan.test.ts +2 -2
- package/src/rbac/secureClient.ts +1 -1
- package/src/rbac/types/functions.ts +1 -1
- package/src/theming/__tests__/parseEventColours.test.ts +117 -8
- package/src/theming/parseEventColours.ts +56 -2
- package/src/types/supabase.ts +2 -3
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +9 -9
- package/src/utils/file-reference/__tests__/file-reference.test.ts +4 -0
- package/src/utils/formatting/formatDate.test.ts +3 -2
- package/src/utils/formatting/formatDateTime.test.ts +2 -2
- package/src/utils/google-places/googlePlacesUtils.test.ts +36 -24
- package/src/utils/storage/__tests__/helpers.unit.test.ts +19 -12
- package/src/utils/storage/helpers.test.ts +69 -3
|
@@ -13,12 +13,21 @@
|
|
|
13
13
|
* Supports input formats:
|
|
14
14
|
* - Object with 'main', 'sec', 'acc' keys (standard format)
|
|
15
15
|
* - Object with 'ev-main', 'ev-sec', 'ev-acc' keys (database format with prefix)
|
|
16
|
+
* - Shade names with 'ev-' prefix (e.g., 'ev-acc-500' -> 'acc-500', 'ev-main-raw' -> 'main-raw')
|
|
16
17
|
* - JSON string that will be parsed
|
|
17
18
|
*
|
|
18
19
|
* Only includes explicitly defined color values. Does not fill
|
|
19
20
|
* missing shades - only shades that are present in the input will
|
|
20
21
|
* be included in the output.
|
|
21
22
|
*
|
|
23
|
+
* The parser automatically strips 'ev-' prefixes from BOTH palette keys and shade names
|
|
24
|
+
* for future-proofing, allowing distinction between event colors and organization colors
|
|
25
|
+
* (org colors not yet implemented).
|
|
26
|
+
*
|
|
27
|
+
* Normalization rules:
|
|
28
|
+
* - Palette keys: 'ev-main' -> 'main', 'ev-sec' -> 'sec', 'ev-acc' -> 'acc'
|
|
29
|
+
* - Shade names: 'ev-main-raw' -> 'main-raw', 'ev-sec-200' -> 'sec-200', 'ev-acc-800' -> 'acc-800'
|
|
30
|
+
*
|
|
22
31
|
* @param input - Event colours from database (JSONB field)
|
|
23
32
|
* @returns Normalized palette data with main, sec, acc palettes, or null if invalid
|
|
24
33
|
*
|
|
@@ -36,7 +45,7 @@
|
|
|
36
45
|
*
|
|
37
46
|
* @example
|
|
38
47
|
* ```ts
|
|
39
|
-
* // Database format with ev- prefix
|
|
48
|
+
* // Database format with ev- prefix on palette keys
|
|
40
49
|
* const colours = {
|
|
41
50
|
* 'ev-main': { 500: { L: 0.5, C: 0.2, H: 0 } },
|
|
42
51
|
* 'ev-sec': { 500: { L: 0.5, C: 0.2, H: 120 } },
|
|
@@ -46,6 +55,44 @@
|
|
|
46
55
|
* // Returns: { main: { 500: {...} }, sec: { 500: {...} }, acc: { 500: {...} } }
|
|
47
56
|
* ```
|
|
48
57
|
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* // Future-proofing: ev- prefix on shade names
|
|
61
|
+
* const colours = {
|
|
62
|
+
* main: {
|
|
63
|
+
* 'ev-main-500': { L: 0.5, C: 0.2, H: 0 },
|
|
64
|
+
* 'ev-main-raw': { L: 0.55, C: 0.25, H: 5 }
|
|
65
|
+
* },
|
|
66
|
+
* sec: {
|
|
67
|
+
* 'ev-sec-200': { L: 0.8, C: 0.15, H: 120 }
|
|
68
|
+
* },
|
|
69
|
+
* acc: {
|
|
70
|
+
* 'ev-acc-800': { L: 0.3, C: 0.2, H: 240 }
|
|
71
|
+
* }
|
|
72
|
+
* };
|
|
73
|
+
* const palette = parseAndNormalizeEventColours(colours);
|
|
74
|
+
* // Returns: { main: { 'main-500': {...}, 'main-raw': {...} }, sec: { 'sec-200': {...} }, acc: { 'acc-800': {...} } }
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // Both palette keys and shade names with ev- prefix
|
|
80
|
+
* const colours = {
|
|
81
|
+
* 'ev-main': {
|
|
82
|
+
* 'ev-main-raw': { L: 0.55, C: 0.25, H: 5 },
|
|
83
|
+
* 'ev-main-200': { L: 0.8, C: 0.15, H: 0 }
|
|
84
|
+
* },
|
|
85
|
+
* 'ev-sec': {
|
|
86
|
+
* 'ev-sec-500': { L: 0.5, C: 0.2, H: 120 }
|
|
87
|
+
* },
|
|
88
|
+
* 'ev-acc': {
|
|
89
|
+
* 'ev-acc-800': { L: 0.3, C: 0.2, H: 240 }
|
|
90
|
+
* }
|
|
91
|
+
* };
|
|
92
|
+
* const palette = parseAndNormalizeEventColours(colours);
|
|
93
|
+
* // Returns: { main: { 'main-raw': {...}, 'main-200': {...} }, sec: { 'sec-500': {...} }, acc: { 'acc-800': {...} } }
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
49
96
|
*/
|
|
50
97
|
declare function parseAndNormalizeEventColours(input: unknown): {
|
|
51
98
|
main: any;
|
package/dist/theming/runtime.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { applyPalette, clearPalette, generateSSRThemeCSS, getCurrentThemeData, isDynamicThemingActive, parseAndNormalizeEventColours } from '../chunk-
|
|
1
|
+
export { applyPalette, clearPalette, generateSSRThemeCSS, getCurrentThemeData, isDynamicThemingActive, parseAndNormalizeEventColours } from '../chunk-5W2A3DRC.js';
|
|
2
2
|
import '../chunk-TTRFSOKR.js';
|
|
3
3
|
import '../chunk-3RG5ZIWI.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { g as BucketInfo, B as BulkUploadResult, F as FileCategory, b as FileMet
|
|
|
7
7
|
export { C as ChangePasswordFormValues, o as ContactFormData, F as FormData, k as LoginFormData, L as LoginFormValues, P as ProfileFormData, m as RegistrationFormData, R as RegistrationFormValues, S as SecureLoginFormValues, j as SecureRegistrationFormValues, U as UserProfileFormValues, V as ValidationError, a as ValidationResult, g as changePasswordSchema, t as combineSchemas, i as contactFormSchema, d as dateSchema, e as emailSchema, l as loginSchema, n as nameSchema, f as passwordResetSchema, b as passwordSchema, p as phoneSchema, q as pickSchema, r as registrationSchema, c as secureLoginSchema, s as securePasswordSchema, u as urlSchema, h as userProfileSchema } from './validation-643vUDZW.js';
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
9
|
export { D as Database, J as Json } from './database.generated-CcnC_DRc.js';
|
|
10
|
-
export { A as AccessLevelContext, s as AuditEventType, P as PermissionSource, d as RBACAccessValidateParams, e as RBACAccessValidateResult, q as RBACAuditLogParams, r as RBACAuditLogResult, t as RBACContext, w as RBACErrorCode, v as RBACFunctionResponse, f as RBACPageAccessCheckParams, R as RBACPermissionCheckParams, a as RBACPermissionCheckResult, b as RBACPermissionsGetParams, c as RBACPermissionsGetResult, u as RBACResult, g as RBACRoleGrantParams, h as RBACRoleGrantResult, i as RBACRoleRevokeParams, j as RBACRoleRevokeResult, m as RBACRoleValidateParams, n as RBACRoleValidateResult, k as RBACRolesListParams, l as RBACRolesListResult, o as RBACSessionTrackParams, p as RBACSessionTrackResult, S as SessionType } from './functions-
|
|
10
|
+
export { A as AccessLevelContext, s as AuditEventType, P as PermissionSource, d as RBACAccessValidateParams, e as RBACAccessValidateResult, q as RBACAuditLogParams, r as RBACAuditLogResult, t as RBACContext, w as RBACErrorCode, v as RBACFunctionResponse, f as RBACPageAccessCheckParams, R as RBACPermissionCheckParams, a as RBACPermissionCheckResult, b as RBACPermissionsGetParams, c as RBACPermissionsGetResult, u as RBACResult, g as RBACRoleGrantParams, h as RBACRoleGrantResult, i as RBACRoleRevokeParams, j as RBACRoleRevokeResult, m as RBACRoleValidateParams, n as RBACRoleValidateResult, k as RBACRolesListParams, l as RBACRolesListResult, o as RBACSessionTrackParams, p as RBACSessionTrackResult, S as SessionType } from './functions-lBy5L2ry.js';
|
|
11
11
|
import 'zod';
|
|
12
12
|
import './types-BeoeWV5I.js';
|
|
13
13
|
|
|
@@ -185,7 +185,7 @@ type TableName = 'users' | 'rbac_global_roles' | 'rbac_organisation_roles' | 'rb
|
|
|
185
185
|
* - Utility (3): Helper functions supporting RBAC operations
|
|
186
186
|
* - Legacy (2): Deprecated functions to be removed
|
|
187
187
|
*/
|
|
188
|
-
type RPCFunction = 'rbac_permission_check' | 'rbac_permissions_get' | 'rbac_access_validate' | 'rbac_page_access_check' | 'rbac_role_grant' | 'rbac_role_revoke' | '
|
|
188
|
+
type RPCFunction = 'rbac_permission_check' | 'rbac_permissions_get' | 'rbac_access_validate' | 'rbac_page_access_check' | 'rbac_role_grant' | 'rbac_role_revoke' | 'data_rbac_roles_list' | 'rbac_role_validate' | 'rbac_session_track' | 'rbac_audit_log' | 'data_user_events_get' | 'data_user_organisation_roles_get' | 'data_user_organisations_get' | 'data_cake_meals_get' | 'data_app_resolve' | 'debug_auth_context' | 'handle_new_user' | 'get_pace_user_events';
|
|
189
189
|
/**
|
|
190
190
|
* Helper type for Supabase filter operations
|
|
191
191
|
*/
|
package/dist/utils.js
CHANGED
|
@@ -759,7 +759,7 @@ function createLazyComponent(importFn, componentName, options = {}) {
|
|
|
759
759
|
return WrappedComponent;
|
|
760
760
|
}
|
|
761
761
|
var LazyDataTable = createLazyComponent(
|
|
762
|
-
() => import('./DataTable-
|
|
762
|
+
() => import('./DataTable-6RMSCQJ6.js').then((module) => ({ default: module.DataTable })),
|
|
763
763
|
"DataTable"
|
|
764
764
|
);
|
|
765
765
|
|
package/docs/api/modules.md
CHANGED
|
@@ -795,7 +795,7 @@ Props for the ContextSelector component.
|
|
|
795
795
|
|
|
796
796
|
#### Defined in
|
|
797
797
|
|
|
798
|
-
[packages/core/src/components/ContextSelector/ContextSelector.tsx:
|
|
798
|
+
[packages/core/src/components/ContextSelector/ContextSelector.tsx:65](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/ContextSelector/ContextSelector.tsx#L65)
|
|
799
799
|
|
|
800
800
|
___
|
|
801
801
|
|
|
@@ -813,7 +813,7 @@ Enhanced DataTable props with performance features
|
|
|
813
813
|
|
|
814
814
|
#### Defined in
|
|
815
815
|
|
|
816
|
-
[packages/core/src/components/DataTable/DataTable.tsx:
|
|
816
|
+
[packages/core/src/components/DataTable/DataTable.tsx:297](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/DataTable/DataTable.tsx#L297)
|
|
817
817
|
|
|
818
818
|
___
|
|
819
819
|
|
|
@@ -3134,7 +3134,7 @@ ___
|
|
|
3134
3134
|
|
|
3135
3135
|
| Name | Type |
|
|
3136
3136
|
| :------ | :------ |
|
|
3137
|
-
| `props` | HTMLAttributes\<
|
|
3137
|
+
| `props` | HTMLAttributes\<HTMLParagraphElement\> & Object & RefAttributes\<HTMLParagraphElement\> |
|
|
3138
3138
|
|
|
3139
3139
|
#### Returns
|
|
3140
3140
|
|
|
@@ -3142,7 +3142,7 @@ ReactNode
|
|
|
3142
3142
|
|
|
3143
3143
|
#### Defined in
|
|
3144
3144
|
|
|
3145
|
-
[packages/core/src/components/Alert/Alert.tsx:
|
|
3145
|
+
[packages/core/src/components/Alert/Alert.tsx:72](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Alert/Alert.tsx#L72)
|
|
3146
3146
|
|
|
3147
3147
|
___
|
|
3148
3148
|
|
|
@@ -3162,7 +3162,7 @@ ReactNode
|
|
|
3162
3162
|
|
|
3163
3163
|
#### Defined in
|
|
3164
3164
|
|
|
3165
|
-
[packages/core/src/components/Alert/Alert.tsx:
|
|
3165
|
+
[packages/core/src/components/Alert/Alert.tsx:102](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Alert/Alert.tsx#L102)
|
|
3166
3166
|
|
|
3167
3167
|
___
|
|
3168
3168
|
|
|
@@ -3182,7 +3182,7 @@ ReactNode
|
|
|
3182
3182
|
|
|
3183
3183
|
#### Defined in
|
|
3184
3184
|
|
|
3185
|
-
[packages/core/src/components/Alert/Alert.tsx:
|
|
3185
|
+
[packages/core/src/components/Alert/Alert.tsx:122](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Alert/Alert.tsx#L122)
|
|
3186
3186
|
|
|
3187
3187
|
___
|
|
3188
3188
|
|
|
@@ -3487,7 +3487,7 @@ null \| Element
|
|
|
3487
3487
|
|
|
3488
3488
|
#### Defined in
|
|
3489
3489
|
|
|
3490
|
-
[packages/core/src/components/ContextSelector/ContextSelector.tsx:
|
|
3490
|
+
[packages/core/src/components/ContextSelector/ContextSelector.tsx:107](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/ContextSelector/ContextSelector.tsx#L107)
|
|
3491
3491
|
|
|
3492
3492
|
___
|
|
3493
3493
|
|
|
@@ -3518,7 +3518,7 @@ The rendered DataTable component
|
|
|
3518
3518
|
|
|
3519
3519
|
#### Defined in
|
|
3520
3520
|
|
|
3521
|
-
[packages/core/src/components/DataTable/DataTable.tsx:
|
|
3521
|
+
[packages/core/src/components/DataTable/DataTable.tsx:479](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/DataTable/DataTable.tsx#L479)
|
|
3522
3522
|
|
|
3523
3523
|
___
|
|
3524
3524
|
|
|
@@ -6011,7 +6011,7 @@ Object
|
|
|
6011
6011
|
|
|
6012
6012
|
#### Defined in
|
|
6013
6013
|
|
|
6014
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
6014
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:220](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L220)
|
|
6015
6015
|
|
|
6016
6016
|
___
|
|
6017
6017
|
|
|
@@ -6034,7 +6034,7 @@ string
|
|
|
6034
6034
|
|
|
6035
6035
|
#### Defined in
|
|
6036
6036
|
|
|
6037
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
6037
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:256](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L256)
|
|
6038
6038
|
|
|
6039
6039
|
___
|
|
6040
6040
|
|
|
@@ -6057,7 +6057,7 @@ string \| null
|
|
|
6057
6057
|
|
|
6058
6058
|
#### Defined in
|
|
6059
6059
|
|
|
6060
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
6060
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:271](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L271)
|
|
6061
6061
|
|
|
6062
6062
|
___
|
|
6063
6063
|
|
|
@@ -6155,7 +6155,7 @@ void
|
|
|
6155
6155
|
|
|
6156
6156
|
#### Defined in
|
|
6157
6157
|
|
|
6158
|
-
[packages/core/src/hooks/useEventTheme.ts:
|
|
6158
|
+
[packages/core/src/hooks/useEventTheme.ts:101](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventTheme.ts#L101)
|
|
6159
6159
|
|
|
6160
6160
|
___
|
|
6161
6161
|
|
|
@@ -8611,12 +8611,21 @@ Parse and normalize event_colours to PaletteData
|
|
|
8611
8611
|
Supports input formats:
|
|
8612
8612
|
- Object with 'main', 'sec', 'acc' keys (standard format)
|
|
8613
8613
|
- Object with 'ev-main', 'ev-sec', 'ev-acc' keys (database format with prefix)
|
|
8614
|
+
- Shade names with 'ev-' prefix (e.g., 'ev-acc-500' -> 'acc-500', 'ev-main-raw' -> 'main-raw')
|
|
8614
8615
|
- JSON string that will be parsed
|
|
8615
8616
|
|
|
8616
8617
|
Only includes explicitly defined color values. Does not fill
|
|
8617
8618
|
missing shades - only shades that are present in the input will
|
|
8618
8619
|
be included in the output.
|
|
8619
8620
|
|
|
8621
|
+
The parser automatically strips 'ev-' prefixes from BOTH palette keys and shade names
|
|
8622
|
+
for future-proofing, allowing distinction between event colors and organization colors
|
|
8623
|
+
(org colors not yet implemented).
|
|
8624
|
+
|
|
8625
|
+
Normalization rules:
|
|
8626
|
+
- Palette keys: 'ev-main' -> 'main', 'ev-sec' -> 'sec', 'ev-acc' -> 'acc'
|
|
8627
|
+
- Shade names: 'ev-main-raw' -> 'main-raw', 'ev-sec-200' -> 'sec-200', 'ev-acc-800' -> 'acc-800'
|
|
8628
|
+
|
|
8620
8629
|
#### Parameters
|
|
8621
8630
|
|
|
8622
8631
|
| Name | Type | Description |
|
|
@@ -8645,7 +8654,7 @@ const palette = parseAndNormalizeEventColours(colours);
|
|
|
8645
8654
|
**`Example`**
|
|
8646
8655
|
|
|
8647
8656
|
```ts
|
|
8648
|
-
// Database format with ev- prefix
|
|
8657
|
+
// Database format with ev- prefix on palette keys
|
|
8649
8658
|
const colours = {
|
|
8650
8659
|
'ev-main': { 500: { L: 0.5, C: 0.2, H: 0 } },
|
|
8651
8660
|
'ev-sec': { 500: { L: 0.5, C: 0.2, H: 120 } },
|
|
@@ -8655,9 +8664,49 @@ const palette = parseAndNormalizeEventColours(colours);
|
|
|
8655
8664
|
// Returns: { main: { 500: {...} }, sec: { 500: {...} }, acc: { 500: {...} } }
|
|
8656
8665
|
```
|
|
8657
8666
|
|
|
8667
|
+
**`Example`**
|
|
8668
|
+
|
|
8669
|
+
```ts
|
|
8670
|
+
// Future-proofing: ev- prefix on shade names
|
|
8671
|
+
const colours = {
|
|
8672
|
+
main: {
|
|
8673
|
+
'ev-main-500': { L: 0.5, C: 0.2, H: 0 },
|
|
8674
|
+
'ev-main-raw': { L: 0.55, C: 0.25, H: 5 }
|
|
8675
|
+
},
|
|
8676
|
+
sec: {
|
|
8677
|
+
'ev-sec-200': { L: 0.8, C: 0.15, H: 120 }
|
|
8678
|
+
},
|
|
8679
|
+
acc: {
|
|
8680
|
+
'ev-acc-800': { L: 0.3, C: 0.2, H: 240 }
|
|
8681
|
+
}
|
|
8682
|
+
};
|
|
8683
|
+
const palette = parseAndNormalizeEventColours(colours);
|
|
8684
|
+
// Returns: { main: { 'main-500': {...}, 'main-raw': {...} }, sec: { 'sec-200': {...} }, acc: { 'acc-800': {...} } }
|
|
8685
|
+
```
|
|
8686
|
+
|
|
8687
|
+
**`Example`**
|
|
8688
|
+
|
|
8689
|
+
```ts
|
|
8690
|
+
// Both palette keys and shade names with ev- prefix
|
|
8691
|
+
const colours = {
|
|
8692
|
+
'ev-main': {
|
|
8693
|
+
'ev-main-raw': { L: 0.55, C: 0.25, H: 5 },
|
|
8694
|
+
'ev-main-200': { L: 0.8, C: 0.15, H: 0 }
|
|
8695
|
+
},
|
|
8696
|
+
'ev-sec': {
|
|
8697
|
+
'ev-sec-500': { L: 0.5, C: 0.2, H: 120 }
|
|
8698
|
+
},
|
|
8699
|
+
'ev-acc': {
|
|
8700
|
+
'ev-acc-800': { L: 0.3, C: 0.2, H: 240 }
|
|
8701
|
+
}
|
|
8702
|
+
};
|
|
8703
|
+
const palette = parseAndNormalizeEventColours(colours);
|
|
8704
|
+
// Returns: { main: { 'main-raw': {...}, 'main-200': {...} }, sec: { 'sec-500': {...} }, acc: { 'acc-800': {...} } }
|
|
8705
|
+
```
|
|
8706
|
+
|
|
8658
8707
|
#### Defined in
|
|
8659
8708
|
|
|
8660
|
-
[packages/core/src/theming/parseEventColours.ts:
|
|
8709
|
+
[packages/core/src/theming/parseEventColours.ts:99](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/theming/parseEventColours.ts#L99)
|
|
8661
8710
|
|
|
8662
8711
|
___
|
|
8663
8712
|
|
|
@@ -31,6 +31,29 @@ reviewedBy: dependency-clarity-audit
|
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
|
34
|
+
## 📋 Source of Truth: package.json
|
|
35
|
+
|
|
36
|
+
**IMPORTANT:** The `package.json` file in `@jmruthers/pace-core` is the **single source of truth** for all dependency information.
|
|
37
|
+
|
|
38
|
+
- **Peer dependencies** are defined in `package.json.peerDependencies`
|
|
39
|
+
- **Required vs optional** peers are marked in `package.json.peerDependenciesMeta`
|
|
40
|
+
- **Included dependencies** are listed in `package.json.dependencies`
|
|
41
|
+
- The **audit tool** reads directly from `package.json` - no hardcoded lists
|
|
42
|
+
- This **documentation** provides additional context and guidance, but version numbers and dependency lists come from `package.json`
|
|
43
|
+
|
|
44
|
+
**For pace-core maintainers:**
|
|
45
|
+
- Always update `package.json` when adding/removing dependencies
|
|
46
|
+
- Run `npm run validate:dependencies` to ensure consistency
|
|
47
|
+
- The validation script checks that `package.json`, audit tool, and documentation are in sync
|
|
48
|
+
- Validation runs automatically before publishing via `prepublishOnly` hook
|
|
49
|
+
|
|
50
|
+
**For consuming apps:**
|
|
51
|
+
- Use the audit tool (`npm run audit:pace-core`) to check your dependencies
|
|
52
|
+
- The audit tool reads the current `package.json` from the installed pace-core package
|
|
53
|
+
- Version requirements shown by the audit tool come directly from `package.json`
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
34
57
|
## ⚠️ CRITICAL: pace-core Version Requirement
|
|
35
58
|
|
|
36
59
|
**You MUST use `@jmruthers/pace-core@^0.6.5` or later.** Older versions may have incompatible dependencies or missing features.
|
|
@@ -963,7 +963,7 @@ test('renders mobile layout correctly', () => {
|
|
|
963
963
|
### 1. Layout Structure
|
|
964
964
|
|
|
965
965
|
- Use semantic HTML elements (header, nav, main, aside, footer)
|
|
966
|
-
- Implement proper heading hierarchy
|
|
966
|
+
- Implement proper heading hierarchy (heading levels can skip when semantically appropriate)
|
|
967
967
|
- Provide clear navigation structure
|
|
968
968
|
- Use consistent spacing and typography
|
|
969
969
|
|
|
@@ -2658,7 +2658,7 @@ The DataTable component is designed with accessibility in mind and meets WCAG 2.
|
|
|
2658
2658
|
2. **Provide alt text for images** - Any images in cells should have alt text
|
|
2659
2659
|
3. **Test with screen readers** - Verify table is navigable with screen readers
|
|
2660
2660
|
4. **Maintain focus visibility** - Ensure focus indicators are visible
|
|
2661
|
-
5. **Use proper heading hierarchy** - Use appropriate heading levels for table context
|
|
2661
|
+
5. **Use proper heading hierarchy** - Use appropriate heading levels for table context (heading levels can skip when semantically appropriate, e.g., h2 → h5)
|
|
2662
2662
|
|
|
2663
2663
|
## ⚠️ Edge Cases
|
|
2664
2664
|
|
|
@@ -131,6 +131,18 @@ export default [
|
|
|
131
131
|
];
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
+
**Example with `tseslint.config()` wrapper:**
|
|
135
|
+
```javascript
|
|
136
|
+
// eslint.config.js
|
|
137
|
+
import tseslint from 'typescript-eslint';
|
|
138
|
+
import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
|
|
139
|
+
|
|
140
|
+
export default tseslint.config(
|
|
141
|
+
...paceCoreConfig, // Spread pace-core config as first arguments
|
|
142
|
+
// your other config objects
|
|
143
|
+
);
|
|
144
|
+
```
|
|
145
|
+
|
|
134
146
|
### Step 3: Setup Cursor Rules (Optional but Recommended)
|
|
135
147
|
|
|
136
148
|
**Automated Setup (Easiest)**
|
|
@@ -924,6 +936,31 @@ During audits, documented exceptions will be:
|
|
|
924
936
|
|
|
925
937
|
## Troubleshooting
|
|
926
938
|
|
|
939
|
+
### ESLint Setup Issues
|
|
940
|
+
|
|
941
|
+
**Error: "Could not find 'no-restricted-imports' in plugin 'pace-core-compliance'"**
|
|
942
|
+
- **Cause**: This rule was removed from the plugin (it's now handled by standard ESLint `no-restricted-imports`)
|
|
943
|
+
- **Fix**: Update to the latest version of `@jmruthers/pace-core` and run `npm run setup:eslint --force`
|
|
944
|
+
|
|
945
|
+
**Error: "TypeError: Unexpected array" when using `tseslint.config()`**
|
|
946
|
+
- **Cause**: Incorrect spreading of `paceCoreConfig` in `tseslint.config()` wrapper
|
|
947
|
+
- **Fix**: Run `npm run setup:eslint --force` to fix the config structure, or manually ensure `paceCoreConfig` is spread correctly:
|
|
948
|
+
```javascript
|
|
949
|
+
import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
|
|
950
|
+
|
|
951
|
+
export default tseslint.config(
|
|
952
|
+
...paceCoreConfig, // Spread here, not nested
|
|
953
|
+
// your other config
|
|
954
|
+
);
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
**ESLint rules not loading**
|
|
958
|
+
- **Cause**: Path resolution issues or rules not copied to `dist/`
|
|
959
|
+
- **Fix**:
|
|
960
|
+
1. Ensure `@jmruthers/pace-core` is built: `npm run build` in pace-core
|
|
961
|
+
2. Check that `node_modules/@jmruthers/pace-core/dist/eslint-rules/` exists
|
|
962
|
+
3. Run `npm run setup:eslint --force` to regenerate config
|
|
963
|
+
|
|
927
964
|
### ESLint Rules Not Working
|
|
928
965
|
|
|
929
966
|
1. **Verify plugin is loaded**: Check that the config is imported correctly
|
|
@@ -931,7 +968,7 @@ During audits, documented exceptions will be:
|
|
|
931
968
|
3. **Verify manifest exists**: Rules load from `core-usage-manifest.json` in the pace-core package
|
|
932
969
|
4. **CommonJS/ES Module issues**: If you're using ES modules and rules aren't loading, ensure you're using the config preset which handles this automatically
|
|
933
970
|
5. **Verify rules are available**: Check that the rules file exists
|
|
934
|
-
6. **Check rule count**: Verify all
|
|
971
|
+
6. **Check rule count**: Verify all rules are loaded
|
|
935
972
|
|
|
936
973
|
### Static Analysis Script Errors
|
|
937
974
|
|
|
@@ -33,38 +33,43 @@ try {
|
|
|
33
33
|
|
|
34
34
|
// Load pace-core ESLint rules
|
|
35
35
|
let paceCoreRules = {};
|
|
36
|
+
const sourceRulesPath = path.resolve(__dirname, 'eslint-rules/index.cjs');
|
|
37
|
+
const distRulesPath = path.resolve(__dirname, 'dist/eslint-rules/index.cjs');
|
|
38
|
+
const cwdRulesPath = path.resolve(process.cwd(), 'node_modules/@jmruthers/pace-core/dist/eslint-rules/index.cjs');
|
|
39
|
+
|
|
36
40
|
try {
|
|
37
41
|
// Try source path first (for development) - new location at package root
|
|
38
|
-
const sourceRulesPath = path.resolve(__dirname, 'eslint-rules/index.cjs');
|
|
39
42
|
if (fs.existsSync(sourceRulesPath)) {
|
|
40
43
|
paceCoreRules = require(sourceRulesPath).rules;
|
|
41
44
|
} else {
|
|
42
45
|
// Try dist path (for published package)
|
|
43
|
-
const distRulesPath = path.resolve(__dirname, 'dist/eslint-rules/index.cjs');
|
|
44
46
|
if (fs.existsSync(distRulesPath)) {
|
|
45
47
|
paceCoreRules = require(distRulesPath).rules;
|
|
46
48
|
} else {
|
|
47
49
|
// Try relative to current working directory (for consuming apps)
|
|
48
|
-
const cwdRulesPath = path.resolve(process.cwd(), 'node_modules/@jmruthers/pace-core/dist/eslint-rules/index.cjs');
|
|
49
50
|
if (fs.existsSync(cwdRulesPath)) {
|
|
50
51
|
paceCoreRules = require(cwdRulesPath).rules;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
} catch (error) {
|
|
55
|
-
//
|
|
56
|
+
// Log warning in development but don't fail - rules will be empty, but config will still work
|
|
56
57
|
// This allows the config to be used even if rules aren't available
|
|
58
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
59
|
+
console.warn(`Warning: Could not load pace-core ESLint rules: ${error.message}`);
|
|
60
|
+
console.warn(` Tried paths: ${sourceRulesPath}, ${distRulesPath}, ${cwdRulesPath}`);
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
// Build restricted imports for no-restricted-imports rule (ESLint 9 flat config format)
|
|
60
|
-
// ESLint 9 expects an
|
|
61
|
-
const
|
|
65
|
+
// ESLint 9 expects an object with 'paths' array - all restrictions use 'name' property
|
|
66
|
+
const restrictedPaths = restrictedImports.map(({ module, reason }) => ({
|
|
62
67
|
name: module,
|
|
63
68
|
message: reason || `Use pace-core alternative instead of direct import of '${module}'`
|
|
64
69
|
}));
|
|
65
70
|
|
|
66
|
-
//
|
|
67
|
-
|
|
71
|
+
// Add @radix-ui/* pattern (also uses 'name' property, wildcards work with 'name')
|
|
72
|
+
restrictedPaths.push({
|
|
68
73
|
name: '@radix-ui/*',
|
|
69
74
|
message: 'Use pace-core components instead of direct Radix UI imports'
|
|
70
75
|
});
|
|
@@ -78,7 +83,6 @@ module.exports = [
|
|
|
78
83
|
},
|
|
79
84
|
rules: {
|
|
80
85
|
// Standard 1: pace-core Compliance
|
|
81
|
-
'pace-core-compliance/no-restricted-imports': 'error',
|
|
82
86
|
'pace-core-compliance/prefer-pace-core-components': 'warn',
|
|
83
87
|
'pace-core-compliance/prefer-pace-core-hooks': 'warn',
|
|
84
88
|
'pace-core-compliance/prefer-pace-core-utils': 'warn',
|
|
@@ -112,8 +116,23 @@ module.exports = [
|
|
|
112
116
|
'pace-core-compliance/test-file-naming': 'warn',
|
|
113
117
|
|
|
114
118
|
// Also use standard no-restricted-imports (ESLint 9 flat config format)
|
|
115
|
-
//
|
|
116
|
-
'no-restricted-imports': ['error',
|
|
119
|
+
// ESLint 9 expects an object with 'paths' array containing objects with 'name' property
|
|
120
|
+
'no-restricted-imports': ['error', {
|
|
121
|
+
paths: restrictedPaths
|
|
122
|
+
}]
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
// Override for Edge Functions (Deno runtime)
|
|
126
|
+
// Edge Functions run in Deno, not React, so they cannot use React hooks
|
|
127
|
+
// They need direct Supabase client access and console.log for debugging
|
|
128
|
+
{
|
|
129
|
+
files: ['**/supabase/functions/**/*.{ts,js}'],
|
|
130
|
+
rules: {
|
|
131
|
+
// Allow console.log in Edge Functions for debugging and monitoring
|
|
132
|
+
'no-console': 'off',
|
|
133
|
+
// Edge Functions cannot use React hooks, so they must use createClient directly
|
|
134
|
+
// The rule already excludes Edge Functions, but we explicitly allow it here for clarity
|
|
135
|
+
'pace-core-compliance/no-direct-supabase-client': 'off',
|
|
117
136
|
}
|
|
118
137
|
}
|
|
119
138
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmruthers/pace-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
4
4
|
"description": "React component library with Tailwind v4",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -166,7 +166,8 @@
|
|
|
166
166
|
"link": "npm run build && npm link",
|
|
167
167
|
"unlink": "npm unlink",
|
|
168
168
|
"validate:theme": "node scripts/validate-theme.js",
|
|
169
|
-
"prepublishOnly": "npm run build",
|
|
169
|
+
"prepublishOnly": "npm run validate:dependencies && npm run build",
|
|
170
|
+
"validate:dependencies": "node scripts/validate-dependencies.cjs",
|
|
170
171
|
"clean": "rimraf dist",
|
|
171
172
|
"_comment_test": "Test suite with various configurations",
|
|
172
173
|
"test": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192 --max-semi-space-size=128\" vitest run --config ../../vitest.config.ts",
|
|
@@ -218,38 +219,67 @@
|
|
|
218
219
|
"clsx": "^2.0.0",
|
|
219
220
|
"date-fns": "^3.0.0",
|
|
220
221
|
"date-fns-tz": "^3.0.0",
|
|
221
|
-
"react": "^19.
|
|
222
|
+
"react": "^19.2.3",
|
|
222
223
|
"react-day-picker": "^9.0.0",
|
|
223
|
-
"react-dom": "^19.
|
|
224
|
+
"react-dom": "^19.2.3",
|
|
224
225
|
"react-hook-form": "^7.0.0",
|
|
225
226
|
"react-router-dom": "^6.0.0",
|
|
226
227
|
"tailwind-merge": "^2.0.0",
|
|
227
|
-
"tailwindcss": "^4.
|
|
228
|
+
"tailwindcss": "^4.1.16",
|
|
228
229
|
"zod": "^3.20.0"
|
|
229
230
|
},
|
|
231
|
+
"peerDependenciesMeta": {
|
|
232
|
+
"@tanstack/react-query": {
|
|
233
|
+
"optional": true
|
|
234
|
+
},
|
|
235
|
+
"@tanstack/react-table": {
|
|
236
|
+
"optional": true
|
|
237
|
+
},
|
|
238
|
+
"clsx": {
|
|
239
|
+
"optional": true
|
|
240
|
+
},
|
|
241
|
+
"date-fns": {
|
|
242
|
+
"optional": true
|
|
243
|
+
},
|
|
244
|
+
"date-fns-tz": {
|
|
245
|
+
"optional": true
|
|
246
|
+
},
|
|
247
|
+
"react-hook-form": {
|
|
248
|
+
"optional": true
|
|
249
|
+
},
|
|
250
|
+
"react-day-picker": {
|
|
251
|
+
"optional": true
|
|
252
|
+
},
|
|
253
|
+
"zod": {
|
|
254
|
+
"optional": true
|
|
255
|
+
},
|
|
256
|
+
"tailwind-merge": {
|
|
257
|
+
"optional": true
|
|
258
|
+
}
|
|
259
|
+
},
|
|
230
260
|
"devDependencies": {
|
|
231
261
|
"@testing-library/jest-dom": "^6.6.3",
|
|
232
|
-
"@testing-library/react": "^16.
|
|
233
|
-
"@testing-library/user-event": "^14.
|
|
262
|
+
"@testing-library/react": "^16.3.0",
|
|
263
|
+
"@testing-library/user-event": "^14.6.1",
|
|
234
264
|
"@types/papaparse": "^5.3.16",
|
|
235
|
-
"@types/react": "^19.
|
|
236
|
-
"@types/react-dom": "^19.
|
|
265
|
+
"@types/react": "^19.2.7",
|
|
266
|
+
"@types/react-dom": "^19.2.3",
|
|
237
267
|
"@types/react-window": "^1.8.8",
|
|
238
|
-
"@vitejs/plugin-react": "^
|
|
239
|
-
"@vitest/coverage-v8": "^
|
|
268
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
269
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
240
270
|
"esbuild": "^0.20.0",
|
|
241
271
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
242
272
|
"eslint-plugin-react-refresh": "^0.4.20",
|
|
243
273
|
"globals": "^16.3.0",
|
|
244
274
|
"jsdom": "^25.0.1",
|
|
245
275
|
"react-router-dom": "^6.26.2",
|
|
246
|
-
"tsup": "^8.5.
|
|
247
|
-
"typedoc": "^0.
|
|
276
|
+
"tsup": "^8.5.1",
|
|
277
|
+
"typedoc": "^0.27.0",
|
|
248
278
|
"typedoc-plugin-markdown": "^3.17.1",
|
|
249
279
|
"typedoc-plugin-merge-modules": "^5.1.0",
|
|
250
|
-
"typescript": "^5.
|
|
280
|
+
"typescript": "^5.9.3",
|
|
251
281
|
"typescript-eslint": "^8.39.0",
|
|
252
|
-
"vite": "^
|
|
282
|
+
"vite": "^7.2.7"
|
|
253
283
|
},
|
|
254
284
|
"dependencies": {
|
|
255
285
|
"@hookform/resolvers": "^3.9.0",
|