@jmruthers/pace-core 0.6.6 → 0.6.7
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/{scripts/audit/audit-dependencies.cjs → audit-tool/00-dependencies.cjs} +12 -13
- package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
- package/audit-tool/audits/02-project-structure.cjs +255 -0
- package/audit-tool/audits/03-architecture.cjs +196 -0
- package/audit-tool/audits/04-code-quality.cjs +149 -0
- package/audit-tool/audits/05-styling.cjs +224 -0
- package/audit-tool/audits/06-security-rbac.cjs +544 -0
- package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
- package/audit-tool/audits/08-testing-documentation.cjs +202 -0
- package/audit-tool/audits/09-operations.cjs +208 -0
- package/audit-tool/index.cjs +291 -0
- package/audit-tool/utils/code-utils.cjs +218 -0
- package/audit-tool/utils/file-utils.cjs +230 -0
- package/audit-tool/utils/report-utils.cjs +241 -0
- package/cursor-rules/00-standards-overview.mdc +156 -0
- package/cursor-rules/{00-pace-core-compliance.mdc → 01-pace-core-compliance.mdc} +187 -34
- package/cursor-rules/02-project-structure.mdc +37 -5
- package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +125 -11
- package/cursor-rules/04-code-quality.mdc +419 -0
- package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +55 -10
- package/cursor-rules/{09-rbac-compliance.mdc → 06-security-rbac.mdc} +62 -6
- package/cursor-rules/07-api-tech-stack.mdc +377 -0
- package/cursor-rules/08-testing-documentation.mdc +324 -0
- package/cursor-rules/09-operations.mdc +365 -0
- package/dist/DataTable-7PMH7XN7.js +15 -0
- package/dist/{DataTable-2N_tqbfq.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
- package/dist/{PublicPageProvider-BBH6Vqg7.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +26 -16
- package/dist/{chunk-FENMYN2U.js → chunk-5X4QLXRG.js} +1 -3
- package/dist/{chunk-4T7OBVTU.js → chunk-6F3IILHI.js} +1 -1
- package/dist/{chunk-SD6WQY43.js → chunk-7ILTDCL2.js} +9 -1
- package/dist/{chunk-3QC3KRHK.js → chunk-A3W6LW53.js} +16 -1
- package/dist/{chunk-7TYHROIV.js → chunk-BM4CQ5P3.js} +50 -8
- package/dist/{chunk-2HGJFNAH.js → chunk-FEJLJNWA.js} +1 -15
- package/dist/{chunk-OHIK3MIO.js → chunk-GHYHJTYV.js} +2 -2
- package/dist/{chunk-UIYSCEV7.js → chunk-IUBRCBSY.js} +1 -1
- package/dist/{chunk-LAZMKTTF.js → chunk-JGWDVX64.js} +281 -347
- package/dist/{chunk-MAGBIDNS.js → chunk-L4XMVJKY.js} +2 -2
- package/dist/{chunk-A55DK444.js → chunk-OJ4SKRSV.js} +1 -7
- package/dist/{chunk-ZS5VO5JB.js → chunk-Q7Q7V5NV.js} +406 -451
- package/dist/{chunk-3O3WHILE.js → chunk-VBCS3DUA.js} +236 -60
- package/dist/{chunk-BVP2BCJF.js → chunk-ZKAWKYT4.js} +8 -8
- package/dist/components.d.ts +5 -4
- package/dist/components.js +27 -32
- package/dist/eslint-rules/index.cjs +22 -9
- package/{src/eslint-rules/rules/compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +184 -23
- package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
- package/dist/eslint-rules/rules/05-styling.cjs +61 -0
- package/dist/eslint-rules/rules/{rbac.cjs → 06-security-rbac.cjs} +26 -10
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
- package/dist/eslint-rules/rules/08-testing.cjs +94 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +18 -17
- package/dist/rbac/index.js +6 -6
- package/dist/theming/runtime.d.ts +14 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/{types-B-K_5VnO.d.ts → types-DXstZpNI.d.ts} +0 -17
- package/dist/{usePublicRouteParams-COZ28Mvq.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +19 -19
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +8 -8
- package/docs/README.md +1 -1
- package/docs/api/modules.md +47 -31
- package/docs/api-reference/components.md +18 -20
- package/docs/api-reference/hooks.md +80 -80
- package/docs/api-reference/types.md +1 -1
- package/docs/api-reference/utilities.md +1 -1
- package/docs/architecture/README.md +1 -1
- package/docs/core-concepts/events.md +3 -3
- package/docs/core-concepts/organisations.md +6 -6
- package/docs/core-concepts/permissions.md +6 -6
- package/docs/documentation-index.md +12 -18
- package/docs/getting-started/documentation-index.md +1 -1
- package/docs/getting-started/examples/README.md +4 -4
- package/docs/getting-started/examples/full-featured-app.md +1 -1
- package/docs/getting-started/faq.md +2 -2
- package/docs/getting-started/quick-reference.md +4 -4
- package/docs/implementation-guides/authentication.md +15 -15
- package/docs/implementation-guides/component-styling.md +1 -1
- package/docs/implementation-guides/data-tables.md +126 -33
- package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
- package/docs/implementation-guides/dynamic-colors.md +3 -3
- package/docs/implementation-guides/file-upload-storage.md +2 -2
- package/docs/implementation-guides/hierarchical-datatable.md +40 -60
- package/docs/implementation-guides/inactivity-tracking.md +3 -3
- package/docs/implementation-guides/large-datasets.md +3 -2
- package/docs/implementation-guides/organisation-security.md +2 -2
- package/docs/implementation-guides/performance.md +2 -2
- package/docs/implementation-guides/permission-enforcement.md +1 -1
- package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
- package/docs/migration/V0.4.0_rbac-migration.md +6 -6
- package/docs/rbac/README.md +5 -5
- package/docs/rbac/advanced-patterns.md +6 -6
- package/docs/rbac/api-reference.md +20 -20
- package/docs/rbac/event-based-apps.md +3 -3
- package/docs/rbac/examples.md +41 -41
- package/docs/rbac/getting-started.md +37 -37
- package/docs/rbac/performance.md +1 -1
- package/docs/rbac/quick-start.md +52 -52
- package/docs/rbac/secure-client-protection.md +1 -1
- package/docs/rbac/troubleshooting.md +1 -1
- package/docs/security/README.md +5 -5
- package/docs/standards/0-standards-overview.md +220 -0
- package/docs/standards/{00-pace-core-compliance.md → 1-pace-core-compliance-standards.md} +204 -185
- package/docs/standards/{02-project-structure.md → 2-project-structure-standards.md} +11 -47
- package/docs/standards/3-architecture-standards.md +606 -0
- package/docs/standards/4-code-quality-standards.md +728 -0
- package/docs/standards/{08-markup-quality.md → 5-styling-standards.md} +12 -9
- package/docs/standards/{09-rbac-compliance.md → 6-security-rbac-standards.md} +126 -18
- package/docs/standards/7-api-tech-stack-standards.md +662 -0
- package/docs/standards/8-testing-documentation-standards.md +401 -0
- package/docs/standards/9-operations-standards.md +1102 -0
- package/docs/standards/README.md +203 -104
- package/docs/troubleshooting/README.md +4 -4
- package/docs/troubleshooting/common-issues.md +2 -2
- package/docs/troubleshooting/debugging.md +9 -9
- package/docs/troubleshooting/migration.md +4 -4
- package/eslint-config-pace-core.cjs +21 -10
- package/package.json +6 -5
- package/scripts/install-cursor-rules.cjs +11 -243
- package/scripts/install-eslint-config.cjs +284 -0
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +10 -10
- package/src/__tests__/integration/UserProfile.test.tsx +14 -14
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
- package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
- package/src/__tests__/templates/component.test.template.tsx +18 -15
- package/src/components/Calendar/Calendar.tsx +201 -47
- package/src/components/ContextSelector/ContextSelector.tsx +137 -153
- package/src/components/DataTable/AUDIT_REPORT.md +293 -0
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
- package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
- package/src/components/DataTable/components/DataTableLayout.tsx +5 -16
- package/src/components/DataTable/components/EditableRow.tsx +5 -7
- package/src/components/DataTable/components/EmptyState.tsx +10 -9
- package/src/components/DataTable/components/FilterRow.tsx +2 -4
- package/src/components/DataTable/components/ImportModal.tsx +124 -126
- package/src/components/DataTable/components/LoadingState.tsx +5 -6
- package/src/components/DataTable/components/SortIndicator.tsx +50 -0
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
- package/src/components/DataTable/components/index.ts +2 -1
- package/src/components/DataTable/types.ts +0 -18
- package/src/components/DataTable/utils/a11yUtils.ts +17 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
- package/src/components/DateTimeField/DateTimeField.tsx +7 -8
- package/src/components/Dialog/Dialog.test.tsx +1 -0
- package/src/components/Dialog/Dialog.tsx +25 -8
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
- package/src/components/FileUpload/FileUpload.test.tsx +52 -14
- package/src/components/FileUpload/FileUpload.tsx +112 -130
- package/src/components/Progress/Progress.tsx +2 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
- package/src/components/Select/Select.tsx +86 -77
- package/src/components/Select/types.ts +3 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
- package/src/hooks/__tests__/hooks.integration.test.tsx +49 -49
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
- package/src/hooks/public/usePublicEvent.ts +5 -5
- package/src/hooks/public/usePublicEventLogo.ts +5 -5
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/public/usePublicRouteParams.ts +5 -5
- package/src/hooks/useAppConfig.ts +2 -2
- package/src/hooks/useEventTheme.test.ts +7 -7
- package/src/hooks/useEventTheme.ts +1 -4
- package/src/hooks/useFileDisplay.ts +2 -2
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
- package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
- package/src/providers/__tests__/EventProvider.test.tsx +61 -61
- package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
- package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +10 -10
- package/src/styles/core.css +7 -0
- package/src/theming/__tests__/parseEventColours.test.ts +9 -3
- package/src/theming/parseEventColours.ts +22 -10
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
- package/src/utils/storage/README.md +1 -1
- package/cursor-rules/01-standards-compliance.mdc +0 -285
- package/cursor-rules/04-testing-standards.mdc +0 -270
- package/cursor-rules/05-bug-reports-and-features.mdc +0 -248
- package/cursor-rules/06-code-quality.mdc +0 -311
- package/cursor-rules/07-tech-stack-compliance.mdc +0 -216
- package/cursor-rules/10-error-handling-patterns.mdc +0 -179
- package/cursor-rules/11-performance-optimization.mdc +0 -169
- package/cursor-rules/12-ci-cd-integration.mdc +0 -150
- package/dist/DataTable-LRJL4IRV.js +0 -15
- package/dist/eslint-rules/rules/compliance.cjs +0 -348
- package/dist/eslint-rules/rules/components.cjs +0 -113
- package/dist/eslint-rules/rules/imports.cjs +0 -102
- package/docs/best-practices/README.md +0 -472
- package/docs/best-practices/accessibility.md +0 -604
- package/docs/best-practices/common-patterns.md +0 -516
- package/docs/best-practices/deployment.md +0 -1103
- package/docs/best-practices/performance.md +0 -1328
- package/docs/best-practices/security.md +0 -940
- package/docs/best-practices/testing.md +0 -1034
- package/docs/rbac/compliance/compliance-guide.md +0 -544
- package/docs/standards/01-standards-compliance.md +0 -188
- package/docs/standards/03-solid-principles.md +0 -39
- package/docs/standards/04-testing-standards.md +0 -36
- package/docs/standards/05-bug-reports-and-features.md +0 -27
- package/docs/standards/06-code-quality.md +0 -34
- package/docs/standards/07-tech-stack-compliance.md +0 -30
- package/docs/standards/10-error-handling-patterns.md +0 -401
- package/docs/standards/11-performance-optimization.md +0 -348
- package/docs/standards/12-ci-cd-integration.md +0 -370
- package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +0 -192
- package/scripts/audit/audit-compliance.cjs +0 -1295
- package/scripts/audit/audit-components.cjs +0 -260
- package/scripts/audit/audit-rbac.cjs +0 -954
- package/scripts/audit/audit-standards.cjs +0 -1268
- package/scripts/audit/index.cjs +0 -1927
- package/src/components/DataTable/components/DataTableBody.tsx +0 -478
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
- package/src/components/DataTable/components/ExpandButton.tsx +0 -113
- package/src/components/DataTable/components/GroupHeader.tsx +0 -54
- package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
- package/src/components/DataTable/core/DataTableContext.tsx +0 -216
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
- package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
- package/src/components/DataTable/utils/debugTools.ts +0 -514
- package/src/eslint-rules/index.cjs +0 -22
- package/src/eslint-rules/rules/components.cjs +0 -113
- package/src/eslint-rules/rules/imports.cjs +0 -102
- package/src/eslint-rules/rules/rbac.cjs +0 -790
- package/src/eslint-rules/utils/helpers.cjs +0 -42
- package/src/eslint-rules/utils/manifest-loader.cjs +0 -75
|
@@ -1,514 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Advanced Debugging Tools for DataTable Performance
|
|
3
|
-
* @package @jmruthers/pace-core
|
|
4
|
-
* @module Components/DataTable/Utils/DebugTools
|
|
5
|
-
* @since 0.3.0
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import type {
|
|
10
|
-
DataRecord,
|
|
11
|
-
PaginationMode,
|
|
12
|
-
ServerSideParams
|
|
13
|
-
} from '../types';
|
|
14
|
-
import { createLogger } from '../../../utils/core/logger';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Debug levels for controlling verbosity (internal use only)
|
|
18
|
-
*/
|
|
19
|
-
enum DebugLevel {
|
|
20
|
-
NONE = 0,
|
|
21
|
-
ERROR = 1,
|
|
22
|
-
WARN = 2,
|
|
23
|
-
INFO = 3,
|
|
24
|
-
DEBUG = 4,
|
|
25
|
-
TRACE = 5,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Performance debug configuration (internal use only)
|
|
30
|
-
*/
|
|
31
|
-
interface DebugConfig {
|
|
32
|
-
enabled: boolean;
|
|
33
|
-
level: DebugLevel;
|
|
34
|
-
logToConsole: boolean;
|
|
35
|
-
logToStorage: boolean;
|
|
36
|
-
maxLogEntries: number;
|
|
37
|
-
enablePerformanceMarks: boolean;
|
|
38
|
-
enableMemoryTracking: boolean;
|
|
39
|
-
enableRenderTracking: boolean;
|
|
40
|
-
enableNetworkTracking: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Default debug configuration (internal use only)
|
|
45
|
-
*/
|
|
46
|
-
const DEFAULT_DEBUG_CONFIG: DebugConfig = {
|
|
47
|
-
enabled: import.meta.env.MODE === 'development',
|
|
48
|
-
level: DebugLevel.INFO,
|
|
49
|
-
logToConsole: true,
|
|
50
|
-
logToStorage: false,
|
|
51
|
-
maxLogEntries: 1000,
|
|
52
|
-
enablePerformanceMarks: true,
|
|
53
|
-
enableMemoryTracking: true,
|
|
54
|
-
enableRenderTracking: true,
|
|
55
|
-
enableNetworkTracking: true,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Debug log entry interface (internal use only)
|
|
60
|
-
*/
|
|
61
|
-
interface DebugLogEntry {
|
|
62
|
-
timestamp: number;
|
|
63
|
-
level: DebugLevel;
|
|
64
|
-
category: string;
|
|
65
|
-
message: string;
|
|
66
|
-
data?: unknown;
|
|
67
|
-
stackTrace?: string;
|
|
68
|
-
performanceMarks?: string[];
|
|
69
|
-
memoryUsage?: number;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Performance timeline entry (internal use only)
|
|
74
|
-
*/
|
|
75
|
-
interface PerformanceTimelineEntry {
|
|
76
|
-
id: string;
|
|
77
|
-
operation: string;
|
|
78
|
-
startTime: number;
|
|
79
|
-
endTime?: number;
|
|
80
|
-
duration?: number;
|
|
81
|
-
metadata?: Record<string, unknown>;
|
|
82
|
-
children?: PerformanceTimelineEntry[];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Memory snapshot (internal use only)
|
|
87
|
-
*/
|
|
88
|
-
interface MemorySnapshot {
|
|
89
|
-
timestamp: number;
|
|
90
|
-
heapUsed: number;
|
|
91
|
-
heapTotal: number;
|
|
92
|
-
external: number;
|
|
93
|
-
arrayBuffers?: number;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Render performance data (internal use only)
|
|
98
|
-
*/
|
|
99
|
-
interface RenderPerformanceData {
|
|
100
|
-
componentName: string;
|
|
101
|
-
renderCount: number;
|
|
102
|
-
totalRenderTime: number;
|
|
103
|
-
averageRenderTime: number;
|
|
104
|
-
lastRenderTime: number;
|
|
105
|
-
propsChanges: number;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Advanced DataTable debugger (internal use only)
|
|
110
|
-
*/
|
|
111
|
-
class DataTableDebugger {
|
|
112
|
-
private config: DebugConfig
|
|
113
|
-
private logger = createLogger('DataTableDebugger');
|
|
114
|
-
private logEntries: DebugLogEntry[] = [];
|
|
115
|
-
private performanceTimeline: Map<string, PerformanceTimelineEntry> = new Map();
|
|
116
|
-
private memorySnapshots: MemorySnapshot[] = [];
|
|
117
|
-
private renderPerformance: Map<string, RenderPerformanceData> = new Map();
|
|
118
|
-
private activeOperations: Set<string> = new Set();
|
|
119
|
-
|
|
120
|
-
constructor(config: Partial<DebugConfig> = {}) {
|
|
121
|
-
this.config = { ...DEFAULT_DEBUG_CONFIG, ...config };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Log a debug message
|
|
126
|
-
*/
|
|
127
|
-
log(
|
|
128
|
-
level: DebugLevel,
|
|
129
|
-
category: string,
|
|
130
|
-
message: string,
|
|
131
|
-
data?: unknown,
|
|
132
|
-
includeStackTrace: boolean = false
|
|
133
|
-
): void {
|
|
134
|
-
if (!this.config.enabled || level > this.config.level) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const entry: DebugLogEntry = {
|
|
139
|
-
timestamp: Date.now(),
|
|
140
|
-
level,
|
|
141
|
-
category,
|
|
142
|
-
message,
|
|
143
|
-
data,
|
|
144
|
-
stackTrace: includeStackTrace ? new Error().stack : undefined,
|
|
145
|
-
memoryUsage: this.config.enableMemoryTracking ? this.getCurrentMemoryUsage() : undefined,
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
this.logEntries.push(entry);
|
|
149
|
-
|
|
150
|
-
// Maintain log size
|
|
151
|
-
if (this.logEntries.length > this.config.maxLogEntries) {
|
|
152
|
-
this.logEntries.shift();
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Console logging
|
|
156
|
-
if (this.config.logToConsole) {
|
|
157
|
-
this.logToConsole(entry);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Storage logging
|
|
161
|
-
if (this.config.logToStorage) {
|
|
162
|
-
this.logToStorage(entry);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Start performance tracking for an operation
|
|
168
|
-
*/
|
|
169
|
-
startOperation(operationId: string, operation: string, metadata?: Record<string, unknown>): void {
|
|
170
|
-
if (!this.config.enabled || !this.config.enableRenderTracking) return;
|
|
171
|
-
|
|
172
|
-
const entry: PerformanceTimelineEntry = {
|
|
173
|
-
id: operationId,
|
|
174
|
-
operation,
|
|
175
|
-
startTime: performance.now(),
|
|
176
|
-
metadata,
|
|
177
|
-
children: [],
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
this.performanceTimeline.set(operationId, entry);
|
|
181
|
-
this.activeOperations.add(operationId);
|
|
182
|
-
|
|
183
|
-
// Performance marks
|
|
184
|
-
if (this.config.enablePerformanceMarks) {
|
|
185
|
-
performance.mark(`${operationId}_start`);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
this.log(DebugLevel.DEBUG, 'Performance', `Started operation: ${operation}`, { operationId, metadata });
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* End performance tracking for an operation
|
|
193
|
-
*/
|
|
194
|
-
endOperation(operationId: string, metadata?: Record<string, unknown>): void {
|
|
195
|
-
if (!this.config.enabled || !this.config.enableRenderTracking) return;
|
|
196
|
-
|
|
197
|
-
const entry = this.performanceTimeline.get(operationId);
|
|
198
|
-
if (!entry) {
|
|
199
|
-
this.log(DebugLevel.WARN, 'Performance', `Operation not found: ${operationId}`);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
entry.endTime = performance.now();
|
|
204
|
-
entry.duration = entry.endTime - entry.startTime;
|
|
205
|
-
if (metadata) {
|
|
206
|
-
entry.metadata = { ...entry.metadata, ...metadata };
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
this.activeOperations.delete(operationId);
|
|
210
|
-
|
|
211
|
-
// Performance marks and measures
|
|
212
|
-
if (this.config.enablePerformanceMarks) {
|
|
213
|
-
performance.mark(`${operationId}_end`);
|
|
214
|
-
performance.measure(operationId, `${operationId}_start`, `${operationId}_end`);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
this.log(DebugLevel.DEBUG, 'Performance', `Completed operation: ${entry.operation}`, {
|
|
218
|
-
operationId,
|
|
219
|
-
duration: entry.duration,
|
|
220
|
-
metadata: entry.metadata,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Track render performance
|
|
226
|
-
*/
|
|
227
|
-
trackRender(componentName: string, renderTime: number, propsChanged: boolean = false): void {
|
|
228
|
-
if (!this.config.enabled || !this.config.enableRenderTracking) return;
|
|
229
|
-
|
|
230
|
-
const existing = this.renderPerformance.get(componentName) || {
|
|
231
|
-
componentName,
|
|
232
|
-
renderCount: 0,
|
|
233
|
-
totalRenderTime: 0,
|
|
234
|
-
averageRenderTime: 0,
|
|
235
|
-
lastRenderTime: 0,
|
|
236
|
-
propsChanges: 0,
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
existing.renderCount++;
|
|
240
|
-
existing.totalRenderTime += renderTime;
|
|
241
|
-
existing.averageRenderTime = existing.totalRenderTime / existing.renderCount;
|
|
242
|
-
existing.lastRenderTime = renderTime;
|
|
243
|
-
|
|
244
|
-
if (propsChanged) {
|
|
245
|
-
existing.propsChanges++;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
this.renderPerformance.set(componentName, existing);
|
|
249
|
-
|
|
250
|
-
this.log(DebugLevel.TRACE, 'Render', `Component rendered: ${componentName}`, {
|
|
251
|
-
renderTime,
|
|
252
|
-
propsChanged,
|
|
253
|
-
averageRenderTime: existing.averageRenderTime,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Take a memory snapshot
|
|
259
|
-
*/
|
|
260
|
-
takeMemorySnapshot(label?: string): MemorySnapshot {
|
|
261
|
-
const snapshot: MemorySnapshot = {
|
|
262
|
-
timestamp: Date.now(),
|
|
263
|
-
heapUsed: 0,
|
|
264
|
-
heapTotal: 0,
|
|
265
|
-
external: 0,
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
if ('memory' in performance) {
|
|
269
|
-
interface PerformanceMemory {
|
|
270
|
-
usedJSHeapSize: number;
|
|
271
|
-
totalJSHeapSize: number;
|
|
272
|
-
jsHeapSizeLimit: number;
|
|
273
|
-
}
|
|
274
|
-
const memory = (performance as unknown as { memory: PerformanceMemory }).memory;
|
|
275
|
-
snapshot.heapUsed = memory.usedJSHeapSize;
|
|
276
|
-
snapshot.heapTotal = memory.totalJSHeapSize;
|
|
277
|
-
snapshot.external = memory.usedJSHeapSize;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.memorySnapshots.push(snapshot);
|
|
281
|
-
|
|
282
|
-
// Keep last 100 snapshots
|
|
283
|
-
if (this.memorySnapshots.length > 100) {
|
|
284
|
-
this.memorySnapshots.shift();
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
this.log(DebugLevel.DEBUG, 'Memory', `Memory snapshot${label ? ` (${label})` : ''}`, snapshot);
|
|
288
|
-
|
|
289
|
-
return snapshot;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Analyze performance bottlenecks
|
|
294
|
-
*/
|
|
295
|
-
analyzePerformance(): {
|
|
296
|
-
slowestOperations: PerformanceTimelineEntry[];
|
|
297
|
-
memoryTrends: { increasing: boolean; trend: number };
|
|
298
|
-
renderHotspots: RenderPerformanceData[];
|
|
299
|
-
recommendations: string[];
|
|
300
|
-
} {
|
|
301
|
-
const timeline = Array.from(this.performanceTimeline.values())
|
|
302
|
-
.filter(entry => entry.duration !== undefined)
|
|
303
|
-
.sort((a, b) => (b.duration || 0) - (a.duration || 0));
|
|
304
|
-
|
|
305
|
-
const slowestOperations = timeline.slice(0, 10);
|
|
306
|
-
|
|
307
|
-
// Memory trend analysis
|
|
308
|
-
const recentSnapshots = this.memorySnapshots.slice(-10);
|
|
309
|
-
const memoryTrend = recentSnapshots.length > 1
|
|
310
|
-
? (recentSnapshots[recentSnapshots.length - 1].heapUsed - recentSnapshots[0].heapUsed) / recentSnapshots.length
|
|
311
|
-
: 0;
|
|
312
|
-
|
|
313
|
-
// Render hotspots
|
|
314
|
-
const renderHotspots = Array.from(this.renderPerformance.values())
|
|
315
|
-
.sort((a, b) => b.averageRenderTime - a.averageRenderTime)
|
|
316
|
-
.slice(0, 5);
|
|
317
|
-
|
|
318
|
-
// Generate recommendations
|
|
319
|
-
const recommendations: string[] = [];
|
|
320
|
-
|
|
321
|
-
if (slowestOperations.length > 0 && slowestOperations[0].duration! > 100) {
|
|
322
|
-
recommendations.push(`Consider optimizing ${slowestOperations[0].operation} (${slowestOperations[0].duration!.toFixed(2)}ms)`);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
if (memoryTrend > 1024 * 1024) { // 1MB increase per snapshot
|
|
326
|
-
recommendations.push('Memory usage is increasing rapidly - check for memory leaks');
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (renderHotspots.length > 0 && renderHotspots[0].averageRenderTime > 16.67) { // 60fps threshold
|
|
330
|
-
recommendations.push(`${renderHotspots[0].componentName} is rendering slowly - consider memoization`);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
slowestOperations,
|
|
335
|
-
memoryTrends: {
|
|
336
|
-
increasing: memoryTrend > 0,
|
|
337
|
-
trend: memoryTrend,
|
|
338
|
-
},
|
|
339
|
-
renderHotspots,
|
|
340
|
-
recommendations,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Generate performance report
|
|
346
|
-
*/
|
|
347
|
-
generateReport(): {
|
|
348
|
-
summary: {
|
|
349
|
-
totalOperations: number;
|
|
350
|
-
averageOperationTime: number;
|
|
351
|
-
totalRenders: number;
|
|
352
|
-
memorySnapshots: number;
|
|
353
|
-
logEntries: number;
|
|
354
|
-
};
|
|
355
|
-
performance: {
|
|
356
|
-
slowestOperations: PerformanceTimelineEntry[];
|
|
357
|
-
memoryTrends: { increasing: boolean; trend: number };
|
|
358
|
-
renderHotspots: RenderPerformanceData[];
|
|
359
|
-
recommendations: string[];
|
|
360
|
-
};
|
|
361
|
-
logs: DebugLogEntry[];
|
|
362
|
-
timeline: PerformanceTimelineEntry[];
|
|
363
|
-
} {
|
|
364
|
-
const completedOperations = Array.from(this.performanceTimeline.values())
|
|
365
|
-
.filter(op => op.duration !== undefined);
|
|
366
|
-
|
|
367
|
-
const averageOperationTime = completedOperations.length > 0
|
|
368
|
-
? completedOperations.reduce((sum, op) => sum + (op.duration || 0), 0) / completedOperations.length
|
|
369
|
-
: 0;
|
|
370
|
-
|
|
371
|
-
const totalRenders = Array.from(this.renderPerformance.values())
|
|
372
|
-
.reduce((sum, data) => sum + data.renderCount, 0);
|
|
373
|
-
|
|
374
|
-
return {
|
|
375
|
-
summary: {
|
|
376
|
-
totalOperations: completedOperations.length,
|
|
377
|
-
averageOperationTime,
|
|
378
|
-
totalRenders,
|
|
379
|
-
memorySnapshots: this.memorySnapshots.length,
|
|
380
|
-
logEntries: this.logEntries.length,
|
|
381
|
-
},
|
|
382
|
-
performance: this.analyzePerformance(),
|
|
383
|
-
logs: this.logEntries.slice(-50), // Last 50 logs
|
|
384
|
-
timeline: Array.from(this.performanceTimeline.values()),
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Export debug data
|
|
390
|
-
*/
|
|
391
|
-
exportDebugData(): string {
|
|
392
|
-
const report = this.generateReport();
|
|
393
|
-
return JSON.stringify(report, null, 2);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Clear all debug data
|
|
398
|
-
*/
|
|
399
|
-
clear(): void {
|
|
400
|
-
this.logEntries = [];
|
|
401
|
-
this.performanceTimeline.clear();
|
|
402
|
-
this.memorySnapshots = [];
|
|
403
|
-
this.renderPerformance.clear();
|
|
404
|
-
this.activeOperations.clear();
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Get current memory usage
|
|
409
|
-
*/
|
|
410
|
-
private getCurrentMemoryUsage(): number {
|
|
411
|
-
if ('memory' in performance) {
|
|
412
|
-
interface PerformanceMemory {
|
|
413
|
-
usedJSHeapSize: number;
|
|
414
|
-
totalJSHeapSize: number;
|
|
415
|
-
jsHeapSizeLimit: number;
|
|
416
|
-
}
|
|
417
|
-
const memory = (performance as unknown as { memory: PerformanceMemory }).memory;
|
|
418
|
-
return memory.usedJSHeapSize / (1024 * 1024); // MB
|
|
419
|
-
}
|
|
420
|
-
return 0;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Log to console with appropriate styling
|
|
425
|
-
*/
|
|
426
|
-
private logToConsole(entry: DebugLogEntry): void {
|
|
427
|
-
const timestamp = new Date(entry.timestamp).toISOString();
|
|
428
|
-
const levelName = DebugLevel[entry.level];
|
|
429
|
-
const message = `[${timestamp}] [${levelName}] [${entry.category}] ${entry.message}`;
|
|
430
|
-
|
|
431
|
-
switch (entry.level) {
|
|
432
|
-
case DebugLevel.ERROR:
|
|
433
|
-
this.logger.error(message, entry.data);
|
|
434
|
-
break;
|
|
435
|
-
case DebugLevel.WARN:
|
|
436
|
-
this.logger.warn(message, entry.data);
|
|
437
|
-
break;
|
|
438
|
-
case DebugLevel.INFO:
|
|
439
|
-
this.logger.info(message, entry.data);
|
|
440
|
-
break;
|
|
441
|
-
case DebugLevel.DEBUG:
|
|
442
|
-
case DebugLevel.TRACE:
|
|
443
|
-
this.logger.debug(message, entry.data);
|
|
444
|
-
break;
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* Log to local storage
|
|
450
|
-
*/
|
|
451
|
-
private logToStorage(entry: DebugLogEntry): void {
|
|
452
|
-
if (typeof window === 'undefined') return;
|
|
453
|
-
|
|
454
|
-
try {
|
|
455
|
-
const stored = localStorage.getItem('datatable-debug-logs');
|
|
456
|
-
const logs = stored ? JSON.parse(stored) : [];
|
|
457
|
-
logs.push(entry);
|
|
458
|
-
|
|
459
|
-
// Keep last 500 entries
|
|
460
|
-
if (logs.length > 500) {
|
|
461
|
-
logs.splice(0, logs.length - 500);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
localStorage.setItem('datatable-debug-logs', JSON.stringify(logs));
|
|
465
|
-
} catch (error) {
|
|
466
|
-
this.logger.warn('Failed to store debug log:', error);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
/**
|
|
472
|
-
* Global debugger instance (internal use only)
|
|
473
|
-
*/
|
|
474
|
-
const dataTableDebugger = new DataTableDebugger();
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Development tools integration
|
|
478
|
-
*/
|
|
479
|
-
export function setupDevTools(): void {
|
|
480
|
-
if (typeof window === 'undefined' || import.meta.env.MODE !== 'development') {
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Expose debugger to global scope for browser dev tools
|
|
485
|
-
interface WindowWithDataTableDebugger extends Window {
|
|
486
|
-
__DATATABLE_DEBUGGER__: typeof dataTableDebugger;
|
|
487
|
-
dataTableDebug: {
|
|
488
|
-
getReport: () => ReturnType<typeof dataTableDebugger.generateReport>;
|
|
489
|
-
exportData: () => ReturnType<typeof dataTableDebugger.exportDebugData>;
|
|
490
|
-
clearLogs: () => void;
|
|
491
|
-
takeSnapshot: (label?: string) => ReturnType<typeof dataTableDebugger.takeMemorySnapshot>;
|
|
492
|
-
analyze: () => ReturnType<typeof dataTableDebugger.analyzePerformance>;
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
const windowWithDebugger = window as unknown as WindowWithDataTableDebugger;
|
|
497
|
-
windowWithDebugger.__DATATABLE_DEBUGGER__ = dataTableDebugger;
|
|
498
|
-
|
|
499
|
-
// Add console commands
|
|
500
|
-
windowWithDebugger.dataTableDebug = {
|
|
501
|
-
getReport: () => dataTableDebugger.generateReport(),
|
|
502
|
-
exportData: () => dataTableDebugger.exportDebugData(),
|
|
503
|
-
clearLogs: () => dataTableDebugger.clear(),
|
|
504
|
-
takeSnapshot: (label?: string) => dataTableDebugger.takeMemorySnapshot(label),
|
|
505
|
-
analyze: () => dataTableDebugger.analyzePerformance(),
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
createLogger('DataTableDebugTools').info('Debug Tools loaded. Use window.dataTableDebug for debugging.');
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Initialize debugging tools
|
|
513
|
-
*/
|
|
514
|
-
setupDevTools();
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main entry point for pace-core ESLint rules
|
|
3
|
-
* @package @jmruthers/pace-core
|
|
4
|
-
* @module ESLintRules
|
|
5
|
-
*
|
|
6
|
-
* This module exports all pace-core compliance ESLint rules organized by category.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const complianceRules = require('./rules/compliance.cjs');
|
|
10
|
-
const componentRules = require('./rules/components.cjs');
|
|
11
|
-
const rbacRules = require('./rules/rbac.cjs');
|
|
12
|
-
const importRules = require('./rules/imports.cjs');
|
|
13
|
-
|
|
14
|
-
module.exports = {
|
|
15
|
-
rules: {
|
|
16
|
-
...complianceRules.rules,
|
|
17
|
-
...componentRules.rules,
|
|
18
|
-
...rbacRules.rules,
|
|
19
|
-
...importRules.rules,
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component usage rules
|
|
3
|
-
* @package @jmruthers/pace-core
|
|
4
|
-
* @module ESLintRules/rules/components
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { isPaceCoreSourceFile } = require('../utils/helpers.cjs');
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
rules: {
|
|
11
|
-
/**
|
|
12
|
-
* Prefer pace-core Form component over plain form tags and direct react-hook-form usage
|
|
13
|
-
*/
|
|
14
|
-
'prefer-pace-core-form': {
|
|
15
|
-
meta: {
|
|
16
|
-
type: 'problem',
|
|
17
|
-
docs: {
|
|
18
|
-
description: 'Disallow plain <form> tags and direct react-hook-form imports. Use pace-core Form component instead.',
|
|
19
|
-
category: 'Best Practices',
|
|
20
|
-
recommended: true
|
|
21
|
-
},
|
|
22
|
-
messages: {
|
|
23
|
-
plainFormTag: "Plain <form> tag detected. Use pace-core Form component instead.",
|
|
24
|
-
reactHookFormImport: "Direct import from 'react-hook-form' detected: {{imports}}. Use pace-core Form component instead. useFormContext is allowed when Form is imported from pace-core."
|
|
25
|
-
},
|
|
26
|
-
hasSuggestions: true
|
|
27
|
-
},
|
|
28
|
-
create(context) {
|
|
29
|
-
const filename = context.getFilename();
|
|
30
|
-
|
|
31
|
-
// Exclude pace-core source files - these rules are for consuming apps
|
|
32
|
-
if (isPaceCoreSourceFile(filename)) {
|
|
33
|
-
return {};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let hasPaceCoreForm = false;
|
|
37
|
-
const problematicImports = ['useForm', 'FormProvider', 'Controller', 'useWatch', 'useFieldArray', 'useController'];
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
ImportDeclaration(node) {
|
|
41
|
-
const importSource = node.source.value;
|
|
42
|
-
|
|
43
|
-
// Check if Form is imported from pace-core
|
|
44
|
-
if (importSource === '@jmruthers/pace-core' ||
|
|
45
|
-
importSource === '@jmruthers/pace-core/components') {
|
|
46
|
-
const hasForm = node.specifiers.some(spec => {
|
|
47
|
-
if (spec.type === 'ImportSpecifier') {
|
|
48
|
-
return spec.imported.name === 'Form';
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
});
|
|
52
|
-
if (hasForm) {
|
|
53
|
-
hasPaceCoreForm = true;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Check for react-hook-form imports
|
|
58
|
-
if (importSource === 'react-hook-form') {
|
|
59
|
-
const importedItems = node.specifiers
|
|
60
|
-
.filter(spec => spec.type === 'ImportSpecifier')
|
|
61
|
-
.map(spec => spec.imported.name);
|
|
62
|
-
|
|
63
|
-
const foundProblematic = importedItems.filter(item => problematicImports.includes(item));
|
|
64
|
-
|
|
65
|
-
// Allow useFormContext when Form is imported from pace-core
|
|
66
|
-
const isAcceptable = hasPaceCoreForm &&
|
|
67
|
-
foundProblematic.length === 1 &&
|
|
68
|
-
foundProblematic[0] === 'useFormContext';
|
|
69
|
-
|
|
70
|
-
if (foundProblematic.length > 0 && !isAcceptable) {
|
|
71
|
-
context.report({
|
|
72
|
-
node: node.source,
|
|
73
|
-
messageId: 'reactHookFormImport',
|
|
74
|
-
data: {
|
|
75
|
-
imports: foundProblematic.join(', ')
|
|
76
|
-
},
|
|
77
|
-
suggest: [{
|
|
78
|
-
desc: 'Use pace-core Form component instead',
|
|
79
|
-
fix(fixer) {
|
|
80
|
-
return fixer.remove(node);
|
|
81
|
-
}
|
|
82
|
-
}]
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
JSXOpeningElement(node) {
|
|
89
|
-
// Check for plain <form> tags (lowercase, not Form component)
|
|
90
|
-
if (node.name.type === 'JSXIdentifier') {
|
|
91
|
-
const elementName = node.name.name;
|
|
92
|
-
// Check if it's lowercase 'form' (not 'Form' component)
|
|
93
|
-
if (elementName === 'form') {
|
|
94
|
-
context.report({
|
|
95
|
-
node,
|
|
96
|
-
messageId: 'plainFormTag',
|
|
97
|
-
suggest: [{
|
|
98
|
-
desc: 'Replace with pace-core Form component',
|
|
99
|
-
fix(fixer) {
|
|
100
|
-
// This is complex to auto-fix, so we'll just report
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
}]
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|