@jmruthers/pace-core 0.6.5 → 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.
Files changed (473) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/audit-tool/00-dependencies.cjs +394 -0
  4. package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
  5. package/audit-tool/audits/02-project-structure.cjs +255 -0
  6. package/audit-tool/audits/03-architecture.cjs +196 -0
  7. package/audit-tool/audits/04-code-quality.cjs +149 -0
  8. package/audit-tool/audits/05-styling.cjs +224 -0
  9. package/audit-tool/audits/06-security-rbac.cjs +544 -0
  10. package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
  11. package/audit-tool/audits/08-testing-documentation.cjs +202 -0
  12. package/audit-tool/audits/09-operations.cjs +208 -0
  13. package/audit-tool/index.cjs +291 -0
  14. package/audit-tool/utils/code-utils.cjs +218 -0
  15. package/audit-tool/utils/file-utils.cjs +230 -0
  16. package/audit-tool/utils/report-utils.cjs +241 -0
  17. package/core-usage-manifest.json +93 -0
  18. package/cursor-rules/00-standards-overview.mdc +156 -0
  19. package/cursor-rules/01-pace-core-compliance.mdc +586 -0
  20. package/cursor-rules/02-project-structure.mdc +42 -4
  21. package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +126 -10
  22. package/cursor-rules/04-code-quality.mdc +419 -0
  23. package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +104 -34
  24. package/cursor-rules/06-security-rbac.mdc +518 -0
  25. package/cursor-rules/07-api-tech-stack.mdc +377 -0
  26. package/cursor-rules/08-testing-documentation.mdc +324 -0
  27. package/cursor-rules/09-operations.mdc +365 -0
  28. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  29. package/dist/DataTable-7PMH7XN7.js +15 -0
  30. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
  31. package/dist/{PublicPageProvider-QTFVrL-Z.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +33 -72
  32. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  33. package/dist/api-Y4MQWOFW.js +4 -0
  34. package/dist/audit-MYQXYZFU.js +3 -0
  35. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  36. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  37. package/dist/{chunk-UPPMRMYG.js → chunk-5X4QLXRG.js} +73 -151
  38. package/dist/chunk-6F3IILHI.js +62 -0
  39. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  40. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  41. package/dist/{chunk-FMUCXFII.js → chunk-7ILTDCL2.js} +9 -5
  42. package/dist/{chunk-M43Y4SSO.js → chunk-A3W6LW53.js} +15 -13
  43. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  44. package/dist/{chunk-HU2C6SSC.js → chunk-BM4CQ5P3.js} +606 -559
  45. package/dist/chunk-C7NSAPTL.js +1 -0
  46. package/dist/{chunk-J36DSWQK.js → chunk-FEJLJNWA.js} +7 -41
  47. package/dist/{chunk-IHB5DR3H.js → chunk-FTCRZOG2.js} +188 -387
  48. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  49. package/dist/chunk-GHYHJTYV.js +994 -0
  50. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  51. package/dist/{chunk-FFQEQTNW.js → chunk-IUBRCBSY.js} +134 -45
  52. package/dist/{chunk-6COVEUS7.js → chunk-JGWDVX64.js} +983 -1034
  53. package/dist/{chunk-RGAWHO7N.js → chunk-L4XMVJKY.js} +77 -222
  54. package/dist/chunk-MBADTM7L.js +64 -0
  55. package/dist/{chunk-M7MPQISP.js → chunk-OJ4SKRSV.js} +3 -16
  56. package/dist/{chunk-IVOFDYWT.js → chunk-Q7Q7V5NV.js} +2109 -1604
  57. package/dist/{chunk-JGRYX5UX.js → chunk-S7DKJPLT.js} +29 -58
  58. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  59. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  60. package/dist/{chunk-NTM7ZSB6.js → chunk-VBCS3DUA.js} +261 -168
  61. package/dist/{chunk-EFN2EIMK.js → chunk-ZFYPMX46.js} +271 -87
  62. package/dist/{chunk-L4OXEN46.js → chunk-ZKAWKYT4.js} +10 -24
  63. package/dist/components.d.ts +7 -5
  64. package/dist/components.js +46 -257
  65. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  66. package/dist/eslint-rules/index.cjs +35 -0
  67. package/{src/eslint-rules/pace-core-compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +234 -235
  68. package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
  69. package/dist/eslint-rules/rules/05-styling.cjs +61 -0
  70. package/dist/eslint-rules/rules/06-security-rbac.cjs +806 -0
  71. package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
  72. package/dist/eslint-rules/rules/08-testing.cjs +94 -0
  73. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  74. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  75. package/dist/hooks.d.ts +6 -6
  76. package/dist/hooks.js +62 -172
  77. package/dist/icons/index.d.ts +1 -0
  78. package/dist/icons/index.js +1 -0
  79. package/dist/index.d.ts +12 -11
  80. package/dist/index.js +67 -660
  81. package/dist/providers.d.ts +2 -2
  82. package/dist/providers.js +8 -35
  83. package/dist/rbac/eslint-rules.d.ts +46 -44
  84. package/dist/rbac/eslint-rules.js +7 -4
  85. package/dist/rbac/index.d.ts +109 -586
  86. package/dist/rbac/index.js +14 -207
  87. package/dist/styles/index.js +2 -12
  88. package/dist/theming/runtime.d.ts +14 -1
  89. package/dist/theming/runtime.js +3 -19
  90. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  91. package/dist/{types-CkbwOr4Y.d.ts → types-DXstZpNI.d.ts} +4 -17
  92. package/dist/types-t9H8qKRw.d.ts +55 -0
  93. package/dist/types.d.ts +1 -1
  94. package/dist/types.js +7 -94
  95. package/dist/{usePublicRouteParams-ClnV4tnv.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +20 -20
  96. package/dist/utils.d.ts +24 -117
  97. package/dist/utils.js +54 -392
  98. package/docs/README.md +17 -7
  99. package/docs/api/README.md +4 -402
  100. package/docs/api/modules.md +301 -871
  101. package/docs/api-reference/components.md +21 -21
  102. package/docs/api-reference/deprecated.md +31 -6
  103. package/docs/api-reference/hooks.md +80 -80
  104. package/docs/api-reference/rpc-functions.md +78 -3
  105. package/docs/api-reference/types.md +1 -1
  106. package/docs/api-reference/utilities.md +1 -1
  107. package/docs/architecture/README.md +1 -1
  108. package/docs/core-concepts/events.md +3 -3
  109. package/docs/core-concepts/organisations.md +6 -6
  110. package/docs/core-concepts/permissions.md +6 -6
  111. package/docs/documentation-index.md +12 -18
  112. package/docs/getting-started/cursor-rules.md +3 -23
  113. package/docs/getting-started/dependencies.md +650 -0
  114. package/docs/getting-started/documentation-index.md +1 -1
  115. package/docs/getting-started/examples/README.md +4 -4
  116. package/docs/getting-started/examples/full-featured-app.md +1 -1
  117. package/docs/getting-started/faq.md +2 -2
  118. package/docs/getting-started/installation-guide.md +20 -7
  119. package/docs/getting-started/quick-reference.md +4 -4
  120. package/docs/getting-started/quick-start.md +23 -12
  121. package/docs/implementation-guides/authentication.md +15 -15
  122. package/docs/implementation-guides/component-styling.md +1 -1
  123. package/docs/implementation-guides/data-tables.md +126 -33
  124. package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
  125. package/docs/implementation-guides/dynamic-colors.md +3 -3
  126. package/docs/implementation-guides/file-upload-storage.md +2 -2
  127. package/docs/implementation-guides/hierarchical-datatable.md +40 -60
  128. package/docs/implementation-guides/inactivity-tracking.md +3 -3
  129. package/docs/implementation-guides/large-datasets.md +3 -2
  130. package/docs/implementation-guides/organisation-security.md +2 -2
  131. package/docs/implementation-guides/performance.md +2 -2
  132. package/docs/implementation-guides/permission-enforcement.md +5 -1
  133. package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
  134. package/docs/migration/V0.4.0_rbac-migration.md +6 -6
  135. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  136. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  137. package/docs/rbac/README.md +17 -8
  138. package/docs/rbac/advanced-patterns.md +6 -6
  139. package/docs/rbac/api-reference.md +20 -20
  140. package/docs/rbac/edge-functions-guide.md +376 -0
  141. package/docs/rbac/event-based-apps.md +3 -3
  142. package/docs/rbac/examples.md +41 -41
  143. package/docs/rbac/getting-started.md +37 -37
  144. package/docs/rbac/performance.md +1 -1
  145. package/docs/rbac/quick-start.md +52 -52
  146. package/docs/rbac/secure-client-protection.md +1 -35
  147. package/docs/rbac/troubleshooting.md +1 -1
  148. package/docs/security/README.md +5 -5
  149. package/docs/standards/0-standards-overview.md +220 -0
  150. package/docs/standards/1-pace-core-compliance-standards.md +986 -0
  151. package/docs/standards/2-project-structure-standards.md +949 -0
  152. package/docs/standards/3-architecture-standards.md +606 -0
  153. package/docs/standards/4-code-quality-standards.md +728 -0
  154. package/docs/standards/5-styling-standards.md +348 -0
  155. package/docs/standards/{07-rbac-and-rls-standard.md → 6-security-rbac-standards.md} +269 -66
  156. package/docs/standards/7-api-tech-stack-standards.md +662 -0
  157. package/docs/standards/8-testing-documentation-standards.md +401 -0
  158. package/docs/standards/9-operations-standards.md +1102 -0
  159. package/docs/standards/README.md +185 -57
  160. package/docs/troubleshooting/README.md +4 -4
  161. package/docs/troubleshooting/common-issues.md +2 -2
  162. package/docs/troubleshooting/debugging.md +9 -9
  163. package/docs/troubleshooting/migration.md +4 -4
  164. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  165. package/eslint-config-pace-core.cjs +33 -6
  166. package/package.json +35 -23
  167. package/scripts/install-cursor-rules.cjs +25 -6
  168. package/scripts/install-eslint-config.cjs +284 -0
  169. package/src/__tests__/fixtures/supabase.ts +1 -1
  170. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +3 -3
  171. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  172. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  173. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
  174. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +13 -13
  175. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  176. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  177. package/src/__tests__/integration/UserProfile.test.tsx +14 -14
  178. package/src/__tests__/public-recipe-view.test.ts +38 -9
  179. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
  180. package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
  181. package/src/__tests__/templates/component.test.template.tsx +18 -15
  182. package/src/components/Button/Button.tsx +5 -1
  183. package/src/components/Calendar/Calendar.tsx +201 -47
  184. package/src/components/ContextSelector/ContextSelector.tsx +106 -119
  185. package/src/components/DataTable/AUDIT_REPORT.md +293 -0
  186. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
  187. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
  188. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
  189. package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
  190. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
  191. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  192. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
  193. package/src/components/DataTable/components/DataTableLayout.tsx +35 -21
  194. package/src/components/DataTable/components/EditFields.tsx +23 -3
  195. package/src/components/DataTable/components/EditableRow.tsx +12 -9
  196. package/src/components/DataTable/components/EmptyState.tsx +10 -9
  197. package/src/components/DataTable/components/FilterRow.tsx +2 -4
  198. package/src/components/DataTable/components/ImportModal.tsx +124 -126
  199. package/src/components/DataTable/components/LoadingState.tsx +5 -6
  200. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  201. package/src/components/DataTable/components/SortIndicator.tsx +50 -0
  202. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
  203. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
  204. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
  205. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
  206. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
  207. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
  208. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  209. package/src/components/DataTable/components/index.ts +2 -1
  210. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  211. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  212. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  213. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  214. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  215. package/src/components/DataTable/types.ts +5 -18
  216. package/src/components/DataTable/utils/a11yUtils.ts +17 -0
  217. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
  218. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
  219. package/src/components/DateTimeField/DateTimeField.tsx +10 -9
  220. package/src/components/Dialog/Dialog.test.tsx +128 -104
  221. package/src/components/Dialog/Dialog.tsx +742 -24
  222. package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
  223. package/src/components/FileDisplay/FileDisplay.test.tsx +4 -2
  224. package/src/components/FileDisplay/FileDisplay.tsx +23 -17
  225. package/src/components/FileUpload/FileUpload.test.tsx +52 -14
  226. package/src/components/FileUpload/FileUpload.tsx +112 -130
  227. package/src/components/Form/Form.test.tsx +6 -8
  228. package/src/components/Form/Form.tsx +365 -4
  229. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  230. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  231. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  232. package/src/components/PaceAppLayout/PaceAppLayout.tsx +11 -15
  233. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  234. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  235. package/src/components/Progress/Progress.tsx +2 -4
  236. package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
  237. package/src/components/Select/Select.tsx +109 -98
  238. package/src/components/Select/types.ts +4 -1
  239. package/src/components/UserMenu/UserMenu.tsx +9 -6
  240. package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
  241. package/src/hooks/__tests__/hooks.integration.test.tsx +55 -57
  242. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  243. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
  244. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  245. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  246. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  247. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  248. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  249. package/src/hooks/public/usePublicEvent.ts +67 -195
  250. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  251. package/src/hooks/public/usePublicEventLogo.ts +24 -14
  252. package/src/hooks/public/usePublicFileDisplay.ts +2 -2
  253. package/src/hooks/public/usePublicRouteParams.ts +5 -5
  254. package/src/hooks/useAppConfig.ts +28 -26
  255. package/src/hooks/useEventTheme.test.ts +217 -239
  256. package/src/hooks/useEventTheme.ts +16 -28
  257. package/src/hooks/useFileDisplay.ts +2 -2
  258. package/src/hooks/useOrganisationPermissions.ts +5 -7
  259. package/src/hooks/useQueryCache.ts +0 -1
  260. package/src/hooks/useSessionDraft.ts +380 -0
  261. package/src/hooks/useSessionRestoration.ts +3 -1
  262. package/src/icons/index.ts +27 -0
  263. package/src/index.ts +5 -0
  264. package/src/providers/OrganisationProvider.tsx +23 -14
  265. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
  266. package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
  267. package/src/providers/__tests__/EventProvider.test.tsx +61 -61
  268. package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
  269. package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
  270. package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
  271. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
  272. package/src/providers/services/EventServiceProvider.tsx +1 -24
  273. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  274. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
  275. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +13 -10
  276. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  277. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  278. package/src/rbac/adapters.tsx +7 -295
  279. package/src/rbac/api.test.ts +44 -56
  280. package/src/rbac/api.ts +10 -17
  281. package/src/rbac/cache-invalidation.ts +0 -1
  282. package/src/rbac/compliance/index.ts +10 -0
  283. package/src/rbac/compliance/pattern-detector.ts +553 -0
  284. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  285. package/src/rbac/components/AccessDenied.tsx +150 -0
  286. package/src/rbac/components/NavigationGuard.tsx +12 -20
  287. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  288. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  289. package/src/rbac/components/index.ts +3 -41
  290. package/src/rbac/eslint-rules.js +1 -1
  291. package/src/rbac/hooks/index.ts +0 -3
  292. package/src/rbac/hooks/permissions/index.ts +0 -3
  293. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  294. package/src/rbac/hooks/usePermissions.ts +0 -3
  295. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  296. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  297. package/src/rbac/hooks/useResourcePermissions.test.ts +124 -38
  298. package/src/rbac/hooks/useResourcePermissions.ts +139 -48
  299. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  300. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  301. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  302. package/src/rbac/index.ts +7 -9
  303. package/src/rbac/utils/contextValidator.ts +9 -7
  304. package/src/services/AuthService.ts +130 -18
  305. package/src/services/EventService.ts +4 -97
  306. package/src/services/InactivityService.ts +16 -0
  307. package/src/services/OrganisationService.ts +7 -44
  308. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  309. package/src/services/base/BaseService.ts +0 -3
  310. package/src/styles/core.css +7 -0
  311. package/src/theming/__tests__/parseEventColours.test.ts +9 -3
  312. package/src/theming/parseEventColours.ts +22 -10
  313. package/src/types/database.generated.ts +4733 -3809
  314. package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
  315. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  316. package/src/utils/context/organisationContext.test.ts +13 -28
  317. package/src/utils/context/organisationContext.ts +21 -52
  318. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  319. package/src/utils/file-reference/index.ts +39 -15
  320. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  321. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  322. package/src/utils/index.ts +4 -1
  323. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  324. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  325. package/src/utils/persistence/keyDerivation.ts +304 -0
  326. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  327. package/src/utils/security/secureStorage.ts +5 -5
  328. package/src/utils/storage/README.md +1 -1
  329. package/src/utils/storage/helpers.ts +3 -3
  330. package/src/utils/supabase/createBaseClient.ts +147 -0
  331. package/src/utils/timezone/timezone.test.ts +1 -2
  332. package/src/utils/timezone/timezone.ts +1 -1
  333. package/src/utils/validation/csrf.ts +4 -4
  334. package/cursor-rules/00-pace-core-compliance.mdc +0 -331
  335. package/cursor-rules/01-standards-compliance.mdc +0 -244
  336. package/cursor-rules/04-testing-standards.mdc +0 -268
  337. package/cursor-rules/05-bug-reports-and-features.mdc +0 -246
  338. package/cursor-rules/06-code-quality.mdc +0 -309
  339. package/cursor-rules/07-tech-stack-compliance.mdc +0 -214
  340. package/cursor-rules/CHANGELOG.md +0 -119
  341. package/cursor-rules/README.md +0 -192
  342. package/dist/DataTable-AOVNCPTX.js +0 -175
  343. package/dist/DataTable-AOVNCPTX.js.map +0 -1
  344. package/dist/UnifiedAuthProvider-4SBX4LU5.js +0 -18
  345. package/dist/UnifiedAuthProvider-4SBX4LU5.js.map +0 -1
  346. package/dist/api-O6HTBX5Y.js +0 -52
  347. package/dist/api-O6HTBX5Y.js.map +0 -1
  348. package/dist/audit-V53FV5AG.js +0 -17
  349. package/dist/audit-V53FV5AG.js.map +0 -1
  350. package/dist/chunk-5DRSZLL2.js.map +0 -1
  351. package/dist/chunk-63FOKYGO.js.map +0 -1
  352. package/dist/chunk-6COVEUS7.js.map +0 -1
  353. package/dist/chunk-AFVQODI2.js +0 -263
  354. package/dist/chunk-AFVQODI2.js.map +0 -1
  355. package/dist/chunk-DGUM43GV.js.map +0 -1
  356. package/dist/chunk-E66EQZE6.js.map +0 -1
  357. package/dist/chunk-EFN2EIMK.js.map +0 -1
  358. package/dist/chunk-FFQEQTNW.js.map +0 -1
  359. package/dist/chunk-FMUCXFII.js.map +0 -1
  360. package/dist/chunk-G37KK66H.js.map +0 -1
  361. package/dist/chunk-G7QEZTYQ.js +0 -2053
  362. package/dist/chunk-G7QEZTYQ.js.map +0 -1
  363. package/dist/chunk-HU2C6SSC.js.map +0 -1
  364. package/dist/chunk-IHB5DR3H.js.map +0 -1
  365. package/dist/chunk-IVOFDYWT.js.map +0 -1
  366. package/dist/chunk-J36DSWQK.js.map +0 -1
  367. package/dist/chunk-JGRYX5UX.js.map +0 -1
  368. package/dist/chunk-KQCRWDSA.js +0 -1
  369. package/dist/chunk-KQCRWDSA.js.map +0 -1
  370. package/dist/chunk-L4OXEN46.js.map +0 -1
  371. package/dist/chunk-LMC26NLJ.js +0 -84
  372. package/dist/chunk-LMC26NLJ.js.map +0 -1
  373. package/dist/chunk-M43Y4SSO.js.map +0 -1
  374. package/dist/chunk-M7MPQISP.js.map +0 -1
  375. package/dist/chunk-NTM7ZSB6.js.map +0 -1
  376. package/dist/chunk-PWLANIRT.js.map +0 -1
  377. package/dist/chunk-QXHPKYJV.js.map +0 -1
  378. package/dist/chunk-RGAWHO7N.js.map +0 -1
  379. package/dist/chunk-UPPMRMYG.js.map +0 -1
  380. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  381. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  382. package/dist/components.js.map +0 -1
  383. package/dist/contextValidator-5OGXSPKS.js +0 -9
  384. package/dist/contextValidator-5OGXSPKS.js.map +0 -1
  385. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  386. package/dist/hooks.js.map +0 -1
  387. package/dist/index.js.map +0 -1
  388. package/dist/providers.js.map +0 -1
  389. package/dist/rbac/eslint-rules.js.map +0 -1
  390. package/dist/rbac/index.js.map +0 -1
  391. package/dist/styles/index.js.map +0 -1
  392. package/dist/theming/runtime.js.map +0 -1
  393. package/dist/types.js.map +0 -1
  394. package/dist/utils.js.map +0 -1
  395. package/docs/best-practices/README.md +0 -472
  396. package/docs/best-practices/accessibility.md +0 -601
  397. package/docs/best-practices/common-patterns.md +0 -516
  398. package/docs/best-practices/deployment.md +0 -1103
  399. package/docs/best-practices/performance.md +0 -1328
  400. package/docs/best-practices/security.md +0 -940
  401. package/docs/best-practices/testing.md +0 -1034
  402. package/docs/rbac/compliance/compliance-guide.md +0 -544
  403. package/docs/standards/01-architecture-standard.md +0 -44
  404. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  405. package/docs/standards/03-component-standard.md +0 -32
  406. package/docs/standards/04-code-style-standard.md +0 -32
  407. package/docs/standards/05-security-standard.md +0 -44
  408. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  409. package/docs/standards/pace-core-compliance.md +0 -432
  410. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  411. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  412. package/scripts/audit/core/checks/bundle.cjs +0 -142
  413. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  414. package/scripts/audit/core/checks/config.cjs +0 -54
  415. package/scripts/audit/core/checks/coverage.cjs +0 -84
  416. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  417. package/scripts/audit/core/checks/documentation.cjs +0 -268
  418. package/scripts/audit/core/checks/environment.cjs +0 -116
  419. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  420. package/scripts/audit/core/checks/forms.cjs +0 -172
  421. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  422. package/scripts/audit/core/checks/hooks.cjs +0 -334
  423. package/scripts/audit/core/checks/imports.cjs +0 -244
  424. package/scripts/audit/core/checks/performance.cjs +0 -325
  425. package/scripts/audit/core/checks/routes.cjs +0 -117
  426. package/scripts/audit/core/checks/state.cjs +0 -130
  427. package/scripts/audit/core/checks/structure.cjs +0 -65
  428. package/scripts/audit/core/checks/style.cjs +0 -584
  429. package/scripts/audit/core/checks/testing.cjs +0 -122
  430. package/scripts/audit/core/checks/typescript.cjs +0 -61
  431. package/scripts/audit/core/scanner.cjs +0 -199
  432. package/scripts/audit/core/utils.cjs +0 -137
  433. package/scripts/audit/index.cjs +0 -223
  434. package/scripts/audit/reporters/console.cjs +0 -151
  435. package/scripts/audit/reporters/json.cjs +0 -54
  436. package/scripts/audit/reporters/markdown.cjs +0 -124
  437. package/scripts/audit-consuming-app.cjs +0 -86
  438. package/src/components/DataTable/components/DataTableBody.tsx +0 -454
  439. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
  440. package/src/components/DataTable/components/ExpandButton.tsx +0 -113
  441. package/src/components/DataTable/components/GroupHeader.tsx +0 -54
  442. package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
  443. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
  444. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
  445. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
  446. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
  447. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
  448. package/src/components/DataTable/core/DataTableContext.tsx +0 -216
  449. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
  450. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
  451. package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
  452. package/src/components/DataTable/utils/debugTools.ts +0 -514
  453. package/src/eslint-rules/pace-core-compliance.js +0 -638
  454. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  455. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  456. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  457. package/src/rbac/components/NavigationProvider.tsx +0 -345
  458. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  459. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  460. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  461. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  462. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  463. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  464. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  465. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  466. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  467. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  468. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  469. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  470. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  471. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  472. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  473. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -5,8 +5,16 @@
5
5
  * @package @jmruthers/pace-core
6
6
  * @module Scripts/install-cursor-rules
7
7
  *
8
- * Copies cursor rules from pace-core to consuming app's .cursor/rules/ directory.
8
+ * Sets up cursor rules:
9
+ * - Copies cursor rules from pace-core to consuming app's .cursor/rules/ directory
10
+ *
9
11
  * This is an opt-in script - it does NOT run automatically via postinstall.
12
+ *
13
+ * For ESLint setup, use install-eslint-config.cjs separately.
14
+ *
15
+ * Usage:
16
+ * node install-cursor-rules.cjs # Install cursor rules
17
+ * node install-cursor-rules.cjs --force # Force update even if already configured
10
18
  */
11
19
 
12
20
  const fs = require('fs');
@@ -171,9 +179,11 @@ function installCursorRules(force = false) {
171
179
  const sourcePath = path.join(sourceDir, file);
172
180
  const targetPath = path.join(targetDir, file);
173
181
 
174
- // Check if this is a pace-core rule (00-09) or app rule (50+)
182
+ // Check if this is a pace-core rule (00-49) or app rule (50+)
183
+ // pace-core rules: 00-49 (currently 00-12, but leaving room for expansion)
184
+ // app rules: 50+ (custom rules for consuming apps)
175
185
  const ruleNumber = parseInt(file.match(/^(\d+)-/)?.[1] || '99');
176
- const isPaceCoreRule = ruleNumber >= 0 && ruleNumber <= 9;
186
+ const isPaceCoreRule = ruleNumber >= 0 && ruleNumber <= 49;
177
187
 
178
188
  if (fs.existsSync(targetPath)) {
179
189
  if (isPaceCoreRule) {
@@ -208,18 +218,24 @@ function installCursorRules(force = false) {
208
218
  console.log(`${colors.cyan}Restart Cursor to load the new rules.${colors.reset}`);
209
219
  }
210
220
 
221
+
211
222
  // Main execution
212
223
  function main() {
213
224
  const force = process.argv.includes('--force');
214
225
 
215
226
  if (force) {
216
- console.log(`${colors.yellow}Warning: --force flag is set. This will overwrite existing pace-core rules.${colors.reset}\n`);
227
+ console.log(`${colors.yellow}Warning: --force flag is set. This will overwrite existing configurations.${colors.reset}\n`);
217
228
  }
218
229
 
219
230
  try {
220
231
  installCursorRules(force);
232
+
233
+ console.log(`\n${colors.cyan}Next steps:${colors.reset}`);
234
+ console.log(` • Restart Cursor to load the new rules`);
235
+ console.log(` • For ESLint setup, run: ${colors.bold}node node_modules/@jmruthers/pace-core/scripts/install-eslint-config.cjs${colors.reset}`);
236
+
221
237
  } catch (error) {
222
- console.error(`${colors.red}Error installing cursor rules:${colors.reset}`);
238
+ console.error(`${colors.red}Error during setup:${colors.reset}`);
223
239
  console.error(error.message);
224
240
  if (error.stack) {
225
241
  console.error(error.stack);
@@ -233,4 +249,7 @@ if (require.main === module) {
233
249
  main();
234
250
  }
235
251
 
236
- module.exports = { installCursorRules, getCursorRulesTarget };
252
+ module.exports = {
253
+ installCursorRules,
254
+ getCursorRulesTarget
255
+ };
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Installation Script for pace-core ESLint Config
5
+ * @package @jmruthers/pace-core
6
+ * @module Scripts/install-eslint-config
7
+ *
8
+ * Sets up pace-core ESLint configuration in consuming apps.
9
+ * Adds pace-core ESLint config to consuming app's ESLint configuration.
10
+ *
11
+ * This is an opt-in script - it does NOT run automatically via postinstall.
12
+ *
13
+ * Usage:
14
+ * node install-eslint-config.cjs # Setup ESLint config
15
+ * node install-eslint-config.cjs --force # Force update even if already configured
16
+ */
17
+
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+
21
+ // Check for safety guards
22
+ function checkSafetyGuards() {
23
+ // Check environment variable
24
+ if (process.env.PACE_ESLINT_CONFIG_DISABLED === '1') {
25
+ console.log(`${colors.yellow}Skipping ESLint config installation: PACE_ESLINT_CONFIG_DISABLED=1${colors.reset}`);
26
+ process.exit(0);
27
+ }
28
+
29
+ // Check for .git folder (safety guard for CI)
30
+ const cwd = process.cwd();
31
+ if (!fs.existsSync(path.join(cwd, '.git'))) {
32
+ console.log(`${colors.yellow}Skipping ESLint config installation: No .git folder found${colors.reset}`);
33
+ console.log(`${colors.yellow}This is a safety guard. If you want to install anyway, run with --force${colors.reset}`);
34
+ if (!process.argv.includes('--force')) {
35
+ process.exit(0);
36
+ }
37
+ }
38
+ }
39
+
40
+ // ANSI color codes for terminal output
41
+ const colors = {
42
+ reset: '\x1b[0m',
43
+ green: '\x1b[32m',
44
+ yellow: '\x1b[33m',
45
+ blue: '\x1b[34m',
46
+ cyan: '\x1b[36m',
47
+ bold: '\x1b[1m',
48
+ red: '\x1b[31m'
49
+ };
50
+
51
+ // Find existing ESLint config file
52
+ function findESLintConfig() {
53
+ const cwd = process.cwd();
54
+ const possibleConfigs = [
55
+ 'eslint.config.js',
56
+ 'eslint.config.cjs',
57
+ 'eslint.config.mjs',
58
+ '.eslintrc.js',
59
+ '.eslintrc.cjs',
60
+ '.eslintrc.json',
61
+ '.eslintrc.yaml',
62
+ '.eslintrc.yml',
63
+ ];
64
+
65
+ for (const configFile of possibleConfigs) {
66
+ const configPath = path.join(cwd, configFile);
67
+ if (fs.existsSync(configPath)) {
68
+ return { path: configPath, name: configFile, isESM: configFile.endsWith('.js') || configFile.endsWith('.mjs') };
69
+ }
70
+ }
71
+
72
+ return null;
73
+ }
74
+
75
+ // Check if pace-core config is already included
76
+ function hasPaceCoreConfig(configContent) {
77
+ // Check for pace-core config import/require
78
+ const paceCorePatterns = [
79
+ /@jmruthers\/pace-core\/eslint-config/,
80
+ /pace-core\/eslint-config/,
81
+ /paceCoreConfig/,
82
+ /pace-core-compliance/,
83
+ ];
84
+
85
+ return paceCorePatterns.some(pattern => pattern.test(configContent));
86
+ }
87
+
88
+ // Detect if file is ES module
89
+ function isESModule(filePath, content) {
90
+ if (filePath.endsWith('.mjs')) return true;
91
+ if (filePath.endsWith('.cjs')) return false;
92
+ if (filePath.endsWith('.js')) {
93
+ // Check for ES module indicators
94
+ return /^import\s+.*from|^export\s+default/.test(content.trim());
95
+ }
96
+ return false;
97
+ }
98
+
99
+ // Backup file before modification
100
+ function backupFile(filePath) {
101
+ const backupPath = `${filePath}.backup.${Date.now()}`;
102
+ fs.copyFileSync(filePath, backupPath);
103
+ return backupPath;
104
+ }
105
+
106
+ // Setup ESLint configuration
107
+ function setupESLintConfig(force = false) {
108
+ const cwd = process.cwd();
109
+ const existingConfig = findESLintConfig();
110
+
111
+ if (existingConfig) {
112
+ // Read existing config
113
+ let content = fs.readFileSync(existingConfig.path, 'utf8');
114
+ const isESM = isESModule(existingConfig.path, content);
115
+ const format = isESM ? 'ES Module' : 'CommonJS';
116
+
117
+ console.log(`${colors.cyan}Found ESLint config:${colors.reset} ${existingConfig.name} (${format})`);
118
+
119
+ // Check if already configured
120
+ if (hasPaceCoreConfig(content)) {
121
+ if (!force) {
122
+ console.log(`${colors.blue}○${colors.reset} ${existingConfig.name} already includes pace-core rules`);
123
+ console.log(`${colors.blue} Use --force to update.${colors.reset}`);
124
+ return { action: 'skipped', file: existingConfig.name, format };
125
+ }
126
+
127
+ console.log(`${colors.yellow}Updating existing ESLint config...${colors.reset}`);
128
+ } else {
129
+ console.log(`${colors.cyan}Adding pace-core config to ${existingConfig.name}...${colors.reset}`);
130
+ }
131
+
132
+ // Backup before modification
133
+ const backupPath = backupFile(existingConfig.path);
134
+ console.log(`${colors.cyan} Backed up to ${path.basename(backupPath)}${colors.reset}`);
135
+
136
+ // Add pace-core config
137
+ if (isESM) {
138
+ // ES Module format
139
+ if (!content.includes('import paceCoreConfig')) {
140
+ // Add import at top (after other imports if they exist)
141
+ const importLines = content.match(/^(import\s+[^;]+;?\s*\n)+/m);
142
+ if (importLines) {
143
+ // Add after existing imports
144
+ content = content.replace(
145
+ importLines[0],
146
+ `${importLines[0]}import paceCoreConfig from '@jmruthers/pace-core/eslint-config';\n`
147
+ );
148
+ } else {
149
+ // Add at the beginning
150
+ content = `import paceCoreConfig from '@jmruthers/pace-core/eslint-config';\n${content}`;
151
+ }
152
+ }
153
+
154
+ // Add to export default array
155
+ if (content.includes('export default [')) {
156
+ // Already an array, add paceCoreConfig at the beginning
157
+ if (!content.includes('...paceCoreConfig')) {
158
+ content = content.replace(
159
+ /(export\s+default\s*\[)\s*/,
160
+ '$1\n ...paceCoreConfig,'
161
+ );
162
+ }
163
+ } else if (content.includes('export default')) {
164
+ // Not an array, wrap it
165
+ const exportMatch = content.match(/(export\s+default\s+)(.+?)(;?\s*$)/s);
166
+ if (exportMatch) {
167
+ content = content.replace(
168
+ exportMatch[0],
169
+ `${exportMatch[1]}[\n ...paceCoreConfig,\n ${exportMatch[2]}\n];`
170
+ );
171
+ }
172
+ }
173
+ } else {
174
+ // CommonJS format
175
+ if (!content.includes('require(\'@jmruthers/pace-core/eslint-config\')')) {
176
+ // Add require at top (after other requires if they exist)
177
+ const requireLines = content.match(/^(const\s+\w+\s*=\s*require\([^)]+\);\s*\n)+/m);
178
+ if (requireLines) {
179
+ content = content.replace(
180
+ requireLines[0],
181
+ `${requireLines[0]}const paceCoreConfig = require('@jmruthers/pace-core/eslint-config');\n`
182
+ );
183
+ } else {
184
+ content = `const paceCoreConfig = require('@jmruthers/pace-core/eslint-config');\n${content}`;
185
+ }
186
+ }
187
+
188
+ // Add to module.exports
189
+ if (content.includes('module.exports = [')) {
190
+ // Already an array, add paceCoreConfig at the beginning
191
+ if (!content.includes('...paceCoreConfig')) {
192
+ content = content.replace(
193
+ /(module\.exports\s*=\s*\[)\s*/,
194
+ '$1\n ...paceCoreConfig,'
195
+ );
196
+ }
197
+ } else if (content.includes('module.exports =')) {
198
+ // Not an array, wrap it
199
+ const exportMatch = content.match(/(module\.exports\s*=\s*)(.+?)(;?\s*$)/s);
200
+ if (exportMatch) {
201
+ content = content.replace(
202
+ exportMatch[0],
203
+ `${exportMatch[1]}[\n ...paceCoreConfig,\n ${exportMatch[2]}\n];`
204
+ );
205
+ }
206
+ }
207
+ }
208
+
209
+ // Write updated config
210
+ fs.writeFileSync(existingConfig.path, content, 'utf8');
211
+ console.log(`${colors.green}✓${colors.reset} Updated ${existingConfig.name}`);
212
+ return { action: 'updated', file: existingConfig.name, backup: backupPath, format };
213
+ } else {
214
+ // Create new ESLint config (default to ES modules)
215
+ const configPath = path.join(cwd, 'eslint.config.js');
216
+ const configContent = `import paceCoreConfig from '@jmruthers/pace-core/eslint-config';
217
+
218
+ export default [
219
+ ...paceCoreConfig,
220
+ // Your app-specific ESLint configuration
221
+ {
222
+ // Add your rules here
223
+ },
224
+ ];
225
+ `;
226
+
227
+ console.log(`${colors.cyan}No ESLint config found. Creating eslint.config.js...${colors.reset}`);
228
+ fs.writeFileSync(configPath, configContent, 'utf8');
229
+ console.log(`${colors.green}✓${colors.reset} Created eslint.config.js`);
230
+ console.log(`${colors.cyan} Edit eslint.config.js to add your app-specific ESLint rules.${colors.reset}`);
231
+ return { action: 'created', file: 'eslint.config.js', format: 'ES Module' };
232
+ }
233
+ }
234
+
235
+ // Main execution
236
+ function main() {
237
+ checkSafetyGuards();
238
+
239
+ const force = process.argv.includes('--force');
240
+
241
+ if (force) {
242
+ console.log(`${colors.yellow}Warning: --force flag is set. This will overwrite existing configurations.${colors.reset}\n`);
243
+ }
244
+
245
+ try {
246
+ console.log(`${colors.cyan}Setting up ESLint configuration from pace-core...${colors.reset}\n`);
247
+ const result = setupESLintConfig(force);
248
+
249
+ // Summary
250
+ console.log(`\n${colors.bold}Setup Summary:${colors.reset}`);
251
+ if (result.action === 'created') {
252
+ console.log(` ${colors.green}ESLint Config:${colors.reset} Created ${result.file} (${result.format})`);
253
+ } else if (result.action === 'updated') {
254
+ console.log(` ${colors.green}ESLint Config:${colors.reset} Updated ${result.file} (${result.format})`);
255
+ console.log(` ${colors.yellow}Backup:${colors.reset} ${path.basename(result.backup)}`);
256
+ } else {
257
+ console.log(` ${colors.blue}ESLint Config:${colors.reset} Already configured (${result.file}, ${result.format})`);
258
+ }
259
+
260
+ console.log(`\n${colors.cyan}ESLint configuration is now available${colors.reset}`);
261
+ console.log(`\n${colors.cyan}Next steps:${colors.reset}`);
262
+ console.log(` • Run ${colors.bold}npm run lint${colors.reset} to verify ESLint is working`);
263
+ console.log(` • Edit your ESLint config to add app-specific rules`);
264
+ console.log(` • See ${colors.bold}packages/core/docs/standards/${colors.reset} for complete standards documentation`);
265
+
266
+ } catch (error) {
267
+ console.error(`${colors.red}Error during setup:${colors.reset}`);
268
+ console.error(error.message);
269
+ if (error.stack) {
270
+ console.error(error.stack);
271
+ }
272
+ process.exit(1);
273
+ }
274
+ }
275
+
276
+ // Run if called directly
277
+ if (require.main === module) {
278
+ main();
279
+ }
280
+
281
+ module.exports = {
282
+ setupESLintConfig,
283
+ findESLintConfig
284
+ };
@@ -8,7 +8,7 @@
8
8
  * Reduces repeated mock setup across test files.
9
9
  */
10
10
 
11
- import { createMockSupabaseClient, createMockQueryBuilder } from '../helpers/supabaseMock';
11
+ import { createMockSupabaseClient } from '../helpers/supabaseMock';
12
12
  import type { User, Session } from '@supabase/supabase-js';
13
13
  import { TEST_FIXTURES } from './test-data';
14
14
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  import React from 'react';
9
9
  import { render, screen } from '@testing-library/react';
10
- import { describe, it, expect, vi, beforeEach } from 'vitest';
10
+ import { describe, it, expect, vi } from 'vitest';
11
11
  import userEvent from '@testing-library/user-event';
12
12
  import {
13
13
  componentTestPatterns,
@@ -23,7 +23,7 @@ vi.mock('../test-utils', () => ({
23
23
  describe('[helpers] componentTestPatterns', () => {
24
24
  describe('testRenders', () => {
25
25
  it('creates test that renders component without crashing', () => {
26
- const TestComponent = () => <div data-testid="test-component">Test</div>;
26
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
27
27
  const testFn = componentTestPatterns.testRenders(TestComponent);
28
28
 
29
29
  expect(typeof testFn).toBe('function');
@@ -33,7 +33,7 @@ describe('[helpers] componentTestPatterns', () => {
33
33
  });
34
34
 
35
35
  it('creates test that renders component with props', () => {
36
- const TestComponent = ({ name }: { name: string }) => <div data-testid="test-component">{name}</div>;
36
+ const TestComponent = ({ name }: { name: string }) => <p data-testid="test-component">{name}</p>;
37
37
  const testFn = componentTestPatterns.testRenders(TestComponent, { name: 'Test Name' });
38
38
 
39
39
  expect(typeof testFn).toBe('function');
@@ -5,7 +5,7 @@
5
5
  * @since 1.0.0
6
6
  */
7
7
 
8
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
+ import { describe, it, expect, vi } from 'vitest';
9
9
  import {
10
10
  createFastMock,
11
11
  createFastErrorMock,
@@ -5,7 +5,7 @@
5
5
  * @since 1.0.0
6
6
  */
7
7
 
8
- import { describe, it, expect, vi, beforeEach } from 'vitest';
8
+ import { describe, it, expect, vi } from 'vitest';
9
9
  import {
10
10
  createMockQueryBuilder,
11
11
  createMockSupabaseClient,
@@ -14,11 +14,11 @@ import { TestProviderWrapper, renderWithProviders, createMockUseUnifiedAuth, use
14
14
  function TestComponent() {
15
15
  const auth = useUnifiedAuth();
16
16
  return (
17
- <div>
17
+ <p>
18
18
  <span data-testid="user-email">{auth.user?.email}</span>
19
19
  <span data-testid="is-authenticated">{auth.isAuthenticated ? 'true' : 'false'}</span>
20
20
  <span data-testid="app-name">{auth.appName}</span>
21
- </div>
21
+ </p>
22
22
  );
23
23
  }
24
24
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  import React from 'react';
9
9
  import { render, screen } from '@testing-library/react';
10
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
10
+ import { describe, it, expect, vi } from 'vitest';
11
11
  import { QueryClient } from '@tanstack/react-query';
12
12
  import {
13
13
  renderWithProviders,
@@ -41,32 +41,32 @@ vi.mock('../fixtures/test-data', () => ({
41
41
 
42
42
  describe('[helpers] renderWithProviders', () => {
43
43
  it('renders component with QueryClient provider by default', () => {
44
- const TestComponent = () => <div data-testid="test-component">Test</div>;
44
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
45
45
 
46
46
  renderWithProviders(<TestComponent />);
47
47
 
48
- expect(screen.getByTestId('test-component')).toBeInTheDocument();
48
+ expect(screen.getByTestId('test-component')).toBeDefined();
49
49
  });
50
50
 
51
51
  it('renders component without QueryClient when withQueryClient is false', () => {
52
- const TestComponent = () => <div data-testid="test-component">Test</div>;
52
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
53
53
 
54
54
  renderWithProviders(<TestComponent />, { withQueryClient: false });
55
55
 
56
- expect(screen.getByTestId('test-component')).toBeInTheDocument();
56
+ expect(screen.getByTestId('test-component')).toBeDefined();
57
57
  });
58
58
 
59
59
  it('uses custom QueryClient when provided', () => {
60
60
  const customQueryClient = new QueryClient();
61
- const TestComponent = () => <div data-testid="test-component">Test</div>;
61
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
62
62
 
63
63
  renderWithProviders(<TestComponent />, { queryClient: customQueryClient });
64
64
 
65
- expect(screen.getByTestId('test-component')).toBeInTheDocument();
65
+ expect(screen.getByTestId('test-component')).toBeDefined();
66
66
  });
67
67
 
68
68
  it('forwards additional render options', () => {
69
- const TestComponent = () => <div data-testid="test-component">Test</div>;
69
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
70
70
 
71
71
  const { container } = renderWithProviders(<TestComponent />, {
72
72
  container: document.body
@@ -273,7 +273,7 @@ describe('[helpers] createMockSupabaseClient', () => {
273
273
 
274
274
  it('creates mock query builder with chaining methods', () => {
275
275
  const mockClient = createMockSupabaseClient();
276
- const queryBuilder = mockClient.from('test_table');
276
+ const queryBuilder = (mockClient.from as any)('test_table');
277
277
 
278
278
  expect(queryBuilder).toHaveProperty('select');
279
279
  expect(queryBuilder).toHaveProperty('insert');
@@ -302,7 +302,7 @@ describe('[helpers] createMockSupabaseClient', () => {
302
302
 
303
303
  describe('[helpers] TestWrapper', () => {
304
304
  it('renders children with QueryClient provider', () => {
305
- const TestComponent = () => <div data-testid="test-component">Test</div>;
305
+ const TestComponent = () => <p data-testid="test-component">Test</p>;
306
306
 
307
307
  render(
308
308
  <TestWrapper>
@@ -310,7 +310,7 @@ describe('[helpers] TestWrapper', () => {
310
310
  </TestWrapper>
311
311
  );
312
312
 
313
- expect(screen.getByTestId('test-component')).toBeInTheDocument();
313
+ expect(screen.getByTestId('test-component')).toBeDefined();
314
314
  });
315
315
  });
316
316
 
@@ -387,8 +387,8 @@ describe('[helpers] testHelpers', () => {
387
387
 
388
388
  describe('[helpers] setupTest', () => {
389
389
  it('sets up test environment', () => {
390
- const mockClearAllMocks = vi.spyOn(vi, 'clearAllMocks');
391
- const mockRestoreAllMocks = vi.spyOn(vi, 'restoreAllMocks');
390
+ vi.spyOn(vi, 'clearAllMocks');
391
+ vi.spyOn(vi, 'restoreAllMocks');
392
392
 
393
393
  setupTest();
394
394
 
@@ -3,7 +3,7 @@
3
3
  * @description Specialized utilities for component testing
4
4
  */
5
5
 
6
- import { render, screen, RenderResult, cleanup } from '@testing-library/react';
6
+ import { screen, cleanup } from '@testing-library/react';
7
7
  import userEvent from '@testing-library/user-event';
8
8
  import { vi } from 'vitest';
9
9
  import { renderWithProviders } from './test-utils';
@@ -28,7 +28,7 @@ export const createMockQueryBuilder = (defaultData: any = { data: [], error: nul
28
28
 
29
29
  // Create a thenable range function that returns self
30
30
  const createRangeFunction = (builder: any) => {
31
- return vi.fn().mockImplementation(function(min: number, max: number) {
31
+ return vi.fn().mockImplementation(function(_min: number, _max: number) {
32
32
  // Return builder with thenable interface
33
33
  return Object.assign(builder, {
34
34
  then: vi.fn().mockImplementation((resolve, reject) => {
@@ -132,7 +132,7 @@ export const createMockQueryBuilderWithData = (data: any, error: any = null) =>
132
132
  });
133
133
 
134
134
  // Ensure range() is available and returns a thenable
135
- mockQueryBuilder.range = vi.fn().mockImplementation(function(min: number, max: number) {
135
+ mockQueryBuilder.range = vi.fn().mockImplementation(function(_min: number, _max: number) {
136
136
  // Return a thenable builder for range() that can be awaited
137
137
  const rangedBuilder = Object.assign(this, {
138
138
  then: vi.fn().mockImplementation((resolve, reject) => {
@@ -37,18 +37,18 @@ const UserProfile = ({ userId }: { userId: string }) => {
37
37
  fetchUser();
38
38
  }, [userId]);
39
39
 
40
- if (loading) return <div>Loading...</div>;
41
- if (error) return <div>Error: {error}</div>;
42
- if (!user) return <div>No user found</div>;
40
+ if (loading) return <p>Loading...</p>;
41
+ if (error) return <p>Error: {error}</p>;
42
+ if (!user) return <p>No user found</p>;
43
43
 
44
44
  return (
45
- <div data-testid="user-profile">
45
+ <section data-testid="user-profile">
46
46
  <h1>{user.name}</h1>
47
47
  <p>{user.email}</p>
48
48
  <button onClick={() => setUser({ ...user, name: 'Updated Name' })}>
49
49
  Update Name
50
50
  </button>
51
- </div>
51
+ </section>
52
52
  );
53
53
  };
54
54
 
@@ -59,17 +59,17 @@ describe('User Profile Integration Tests', () => {
59
59
 
60
60
  // The component loads data synchronously in this mock, so we just check the final state
61
61
  await waitFor(() => {
62
- expect(screen.getByText('John Doe')).toBeInTheDocument();
62
+ expect(screen.getByText('John Doe')).toBeDefined();
63
63
  });
64
64
 
65
- expect(screen.getByText('john@example.com')).toBeInTheDocument();
65
+ expect(screen.getByText('john@example.com')).toBeDefined();
66
66
  });
67
67
 
68
68
  it('handles user not found', async () => {
69
69
  renderWithProviders(<UserProfile userId="999" />);
70
70
 
71
71
  await waitFor(() => {
72
- expect(screen.getByText('Error: User not found')).toBeInTheDocument();
72
+ expect(screen.getByText('Error: User not found')).toBeDefined();
73
73
  });
74
74
  });
75
75
  });
@@ -80,13 +80,13 @@ describe('User Profile Integration Tests', () => {
80
80
  renderWithProviders(<UserProfile userId="1" />);
81
81
 
82
82
  await waitFor(() => {
83
- expect(screen.getByText('John Doe')).toBeInTheDocument();
83
+ expect(screen.getByText('John Doe')).toBeDefined();
84
84
  });
85
85
 
86
86
  await user.click(screen.getByText('Update Name'));
87
87
 
88
- expect(screen.getByText('Updated Name')).toBeInTheDocument();
89
- expect(screen.queryByText('John Doe')).not.toBeInTheDocument();
88
+ expect(screen.getByText('Updated Name')).toBeDefined();
89
+ expect(screen.queryByText('John Doe')).toBeNull();
90
90
  });
91
91
  });
92
92
 
@@ -95,12 +95,12 @@ describe('User Profile Integration Tests', () => {
95
95
  const { rerender } = renderWithProviders(<UserProfile userId="1" />);
96
96
 
97
97
  await waitFor(() => {
98
- expect(screen.getByText('John Doe')).toBeInTheDocument();
98
+ expect(screen.getByText('John Doe')).toBeDefined();
99
99
  });
100
100
 
101
101
  rerender(<UserProfile userId="1" />);
102
102
 
103
- expect(screen.getByText('John Doe')).toBeInTheDocument();
103
+ expect(screen.getByText('John Doe')).toBeDefined();
104
104
  });
105
105
  });
106
106
  });
@@ -117,7 +117,7 @@ describe('User Profile - Different Users', () => {
117
117
  renderWithProviders(<UserProfile userId={userId} />);
118
118
 
119
119
  await waitFor(() => {
120
- expect(screen.getByText(expectedName)).toBeInTheDocument();
120
+ expect(screen.getByText(expectedName)).toBeDefined();
121
121
  });
122
122
  });
123
123
  });