@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
@@ -1,584 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Code Style Check Module
5
- * @package @jmruthers/pace-core
6
- * @module Audit/Checks/Style
7
- *
8
- * Checks for:
9
- * - Inline styles usage
10
- * - Inconsistent naming conventions
11
- * - Missing TypeScript types
12
- * - any type usage
13
- * - Console.log statements
14
- */
15
-
16
- const fs = require('fs');
17
- const path = require('path');
18
- const { getRelativePath, getLineNumber } = require('../utils.cjs');
19
-
20
- const styleCheck = {
21
- name: 'style',
22
- description: 'Code style issues (inline styles, any types, console.log)',
23
- severity: 'warning',
24
-
25
- async run(context) {
26
- const { projectRoot, files } = context;
27
- const issues = [];
28
- const warnings = [];
29
- const suggestions = [];
30
-
31
- if (!files || files.length === 0) {
32
- return { issues, warnings, suggestions };
33
- }
34
-
35
- for (const filePath of files) {
36
- try {
37
- const content = fs.readFileSync(filePath, 'utf8');
38
- const relativePath = getRelativePath(filePath, projectRoot);
39
- const normalizedPath = relativePath.replace(/\\/g, '/');
40
-
41
- // Skip root-level src directory - in pace-core repository, this is a demo/showcase app
42
- // Note: We DO check packages/core/ files because style issues (any types, console.log, inline styles) are real issues that should be fixed
43
- const isRootSrc = normalizedPath.startsWith('src/') && !normalizedPath.includes('packages/');
44
- if (isRootSrc) {
45
- continue; // Skip demo app files
46
- }
47
-
48
- // Skip scripts directory - utility scripts don't need style validation
49
- const isScript = normalizedPath.startsWith('scripts/') || normalizedPath.includes('/scripts/');
50
- if (isScript) {
51
- continue; // Skip script files
52
- }
53
-
54
- // Skip test setup, teardown, and configuration files - these are test infrastructure
55
- // Test setup/teardown files legitimately use 'any' types for mocking and may have simpler type annotations
56
- const fileName = path.basename(normalizedPath);
57
- const isTestInfrastructure = normalizedPath.includes('.setup.') ||
58
- normalizedPath.includes('.teardown.') ||
59
- normalizedPath.includes('.config.') ||
60
- normalizedPath.includes('setupTests') ||
61
- normalizedPath.includes('test-setup') ||
62
- normalizedPath.includes('test-setup.') ||
63
- fileName.match(/^(vitest|jest|setupTests)\.(setup|teardown)\.(ts|js|tsx|jsx)$/i) ||
64
- fileName.match(/\.(setup|teardown)\.(ts|js|tsx|jsx)$/i) ||
65
- fileName.match(/^test-setup\.(ts|js|tsx|jsx)$/i);
66
- if (isTestInfrastructure) {
67
- continue; // Skip test infrastructure files
68
- }
69
-
70
- // Skip example files - these are demo/showcase code, not production code
71
- const isExample = normalizedPath.includes('/examples/') ||
72
- normalizedPath.includes('/example/') ||
73
- fileName.includes('Example');
74
- if (isExample) {
75
- continue; // Skip example files
76
- }
77
-
78
- // Skip logger utility files - they intentionally use console.* and any[] for variadic arguments
79
- const isLogger = normalizedPath.includes('/utils/core/logger') ||
80
- normalizedPath.includes('/utils/core/debugLogger') ||
81
- (normalizedPath.includes('/rbac/config') && content.includes('createLogger') && content.includes('RBACLogger'));
82
- if (isLogger) {
83
- continue; // Skip logger utilities
84
- }
85
-
86
- // Skip development utility files - these are meant to log to console for development/debugging
87
- const isDevUtility = normalizedPath.includes('/utils/performance/') ||
88
- normalizedPath.includes('/utils/debug/') ||
89
- normalizedPath.includes('/utils/development/');
90
- if (isDevUtility) {
91
- continue; // Skip development utilities
92
- }
93
-
94
- // Check for inline styles
95
- const inlineStylePattern = /style\s*=\s*\{\{/g;
96
- let styleMatch;
97
- while ((styleMatch = inlineStylePattern.exec(content)) !== null) {
98
- // Get context around the inline style to check if it's necessary
99
- const contextStart = Math.max(0, styleMatch.index - 100);
100
- const contextEnd = Math.min(content.length, styleMatch.index + 300);
101
- const context = content.substring(contextStart, contextEnd);
102
-
103
- // Skip empty style objects - these are harmless placeholders
104
- // Check if the style attribute contains only empty braces: style={{}}
105
- // Look ahead from the match position to find the closing braces
106
- const afterMatch = content.substring(styleMatch.index, Math.min(content.length, styleMatch.index + 50));
107
- // Match patterns like: style={{}} or style={{ }} or style={{ }}
108
- const isEmptyStyle = /style\s*=\s*\{\s*\{\s*\}\s*\}/.test(afterMatch);
109
- if (isEmptyStyle) {
110
- continue; // Skip empty style objects
111
- }
112
-
113
- // Skip legitimate inline styles that can't be replaced with Tailwind:
114
- // 1. Dynamic positioning (top/bottom based on direction)
115
- // 2. Dynamic maxHeight/maxWidth from props
116
- // 3. Virtual scrolling styles (transform, position: absolute with dynamic values)
117
- // 4. Dynamic height/width from props or calculations
118
- // 5. Dynamic indentation/padding for hierarchical data
119
- const isDynamicPositioning = context.includes('[opensUpward') ||
120
- context.includes('direction') ||
121
- context.includes('opensUpward ?') ||
122
- context.includes('direction ===');
123
-
124
- const isVirtualization = context.includes('transform') &&
125
- (context.includes('translateY') || context.includes('translateX')) &&
126
- (context.includes('virtualRow') || context.includes('virtualItem') || context.includes('virtualizer'));
127
-
128
- const isDynamicSize = (context.includes('maxHeight') || context.includes('maxWidth') ||
129
- context.includes('minHeight') || context.includes('minWidth') ||
130
- context.includes('height:') || context.includes('width:') ||
131
- context.includes('totalSize') || context.includes('virtualRow.size')) &&
132
- !context.includes('style={{}}'); // But not empty objects
133
-
134
- // Skip dynamic indentation/padding for hierarchical rows
135
- const isDynamicIndentation = (context.includes('paddingLeft') || context.includes('paddingRight') ||
136
- context.includes('indentation') || context.includes('indent')) &&
137
- (context.includes('px') || context.includes('${'));
138
-
139
- // Skip if it's just pointerEvents and className already has pointer-events-none
140
- const isRedundantPointerEvents = context.includes('pointerEvents') &&
141
- context.includes('pointer-events-none');
142
-
143
- // Skip text overflow styles that are necessary for ellipsis
144
- const isTextOverflow = context.includes('textOverflow') ||
145
- context.includes('whiteSpace') ||
146
- context.includes('overflow:') && context.includes('hidden');
147
-
148
- if (isDynamicPositioning || isVirtualization || (isDynamicSize && !isEmptyStyle) || isTextOverflow || isDynamicIndentation) {
149
- continue; // Skip dynamic styles that require runtime values
150
- }
151
-
152
- if (isRedundantPointerEvents) {
153
- continue; // Skip redundant pointer events
154
- }
155
-
156
- warnings.push({
157
- type: 'inline-style',
158
- file: relativePath,
159
- line: getLineNumber(content, styleMatch.index),
160
- message: 'Inline style detected',
161
- recommendation: 'Use Tailwind classes or pace-core component props instead of inline styles'
162
- });
163
- }
164
-
165
- // Check for console.log in non-test files, but exclude CLI scripts and development utilities
166
- if (!relativePath.includes('.test.') && !relativePath.includes('.spec.')) {
167
- // Check if this is a CLI script (has shebang or is in scripts/ directory)
168
- const isCLIScript = content.startsWith('#!/usr/bin/env node') ||
169
- content.startsWith('#!/bin/node') ||
170
- content.startsWith('#!/bin/env node') ||
171
- relativePath.includes('/scripts/') ||
172
- relativePath.startsWith('scripts/');
173
-
174
- // Skip RBAC config - it's a logger utility that intentionally uses console methods
175
- const isRBACConfig = normalizedPath.includes('/rbac/config');
176
-
177
- // Skip development utilities - these are meant to log to console
178
- const isDevUtility = normalizedPath.includes('/utils/performance/') ||
179
- normalizedPath.includes('/utils/debug/') ||
180
- normalizedPath.includes('/utils/development/');
181
-
182
- if (!isCLIScript && !isRBACConfig && !isDevUtility) {
183
- const consoleLogPattern = /console\.(log|debug|info)\s*\(/g;
184
- let consoleMatch;
185
- while ((consoleMatch = consoleLogPattern.exec(content)) !== null) {
186
- // Skip if it's in a comment (JSDoc examples, etc.)
187
- const beforeMatch = content.substring(Math.max(0, consoleMatch.index - 150), consoleMatch.index);
188
- const afterMatch = content.substring(consoleMatch.index, Math.min(content.length, consoleMatch.index + 50));
189
-
190
- // Check if it's in a comment block (JSDoc, regular comments)
191
- // Look for JSDoc comment markers (* at start of line) or regular comment markers
192
- const isInJSDocComment = beforeMatch.match(/\n\s*\*\s/) || beforeMatch.match(/\/\*\*/);
193
- const isInRegularComment = beforeMatch.includes('//') || beforeMatch.includes('/*');
194
- const isInComment = isInJSDocComment || isInRegularComment;
195
-
196
- // Check if it's in a code example within JSDoc (between ``` markers or in @example blocks)
197
- const beforeCode = content.substring(Math.max(0, consoleMatch.index - 500), consoleMatch.index);
198
- const isInCodeBlock = beforeCode.includes('```') &&
199
- (beforeCode.match(/```/g) || []).length % 2 === 1; // Odd number of ``` means we're inside a code block
200
- const isInJSDocExample = beforeMatch.match(/\*\s*@example/) ||
201
- beforeMatch.match(/\*\s*```/) ||
202
- beforeMatch.match(/\*\s*</); // JSX in JSDoc examples
203
- const isInCodeExample = isInCodeBlock || isInJSDocExample;
204
-
205
- // Check if it's wrapped in a development check (process.env.NODE_ENV === 'development')
206
- const contextForDevCheck = content.substring(Math.max(0, consoleMatch.index - 200), Math.min(content.length, consoleMatch.index + 200));
207
- const isInDevCheck = contextForDevCheck.includes('process.env.NODE_ENV') &&
208
- (contextForDevCheck.includes("=== 'development'") ||
209
- contextForDevCheck.includes('=== "development"') ||
210
- contextForDevCheck.includes("== 'development'") ||
211
- contextForDevCheck.includes('== "development"'));
212
-
213
- if (isInComment || isInCodeExample || isInDevCheck) {
214
- continue; // Skip console.log in comments/documentation/code examples or development checks
215
- }
216
-
217
- warnings.push({
218
- type: 'console-log',
219
- file: relativePath,
220
- line: getLineNumber(content, consoleMatch.index),
221
- message: `console.${consoleMatch[1]} found in production code`,
222
- recommendation: 'Remove console.log statements or use a proper logging utility. CLI scripts in scripts/ directory are allowed to use console output.'
223
- });
224
- }
225
- }
226
- }
227
-
228
- // Check for 'any' type usage in TypeScript files
229
- if (filePath.match(/\.(ts|tsx)$/)) {
230
- const anyTypePattern = /:\s*any\b|<\s*any\s*>|any\[\]/g;
231
- let anyMatch;
232
- while ((anyMatch = anyTypePattern.exec(content)) !== null) {
233
- // Skip if it's in a comment or string
234
- const beforeMatch = content.substring(Math.max(0, anyMatch.index - 50), anyMatch.index);
235
- const isInComment = beforeMatch.includes('//') || beforeMatch.includes('/*');
236
-
237
- if (isInComment) {
238
- continue;
239
- }
240
-
241
- // Skip legitimate any[] usage in variadic function arguments (e.g., logger utilities)
242
- const contextMatch = content.substring(Math.max(0, anyMatch.index - 100), Math.min(content.length, anyMatch.index + 50));
243
- const isVariadicArg = contextMatch.match(/\.\.\.\s*args?\s*:\s*any\[\]/) ||
244
- contextMatch.match(/\.\.\.\s*args?\s*:\s*any\b/);
245
- if (isVariadicArg) {
246
- continue; // Skip variadic arguments - these are legitimate uses of any[]
247
- }
248
-
249
- // Skip generic cache implementations where any is used for value types
250
- const isCacheGeneric = contextMatch.includes('CacheEntry<any>') ||
251
- contextMatch.includes('Map<string, any>') ||
252
- (contextMatch.includes('Map<') && contextMatch.includes('any>')) ||
253
- (contextMatch.includes('Map<') && contextMatch.includes('any')) ||
254
- (contextMatch.includes('cache') && (contextMatch.includes('data: any') || contextMatch.includes('{ data: any'))) ||
255
- (contextMatch.includes('Cache') && contextMatch.includes('any')) ||
256
- (contextMatch.includes('new Map') && contextMatch.includes('any'));
257
- if (isCacheGeneric) {
258
- continue; // Skip generic cache types - these are legitimate
259
- }
260
-
261
- // Skip generic component types (React.ComponentType<any>, etc.)
262
- const isGenericComponentType = contextMatch.includes('ComponentType<any>') ||
263
- contextMatch.includes('React.ComponentType<any>') ||
264
- (contextMatch.includes('ComponentType') && contextMatch.includes('<any>'));
265
- if (isGenericComponentType) {
266
- continue; // Skip generic component types - necessary for dynamic components
267
- }
268
-
269
- // Skip generic Promise callbacks
270
- const isPromiseCallback = contextMatch.includes('Promise<any>') ||
271
- contextMatch.includes('Promise<') && contextMatch.includes('any>') ||
272
- (contextMatch.includes('Promise') && contextMatch.includes('() => Promise<any>'));
273
- if (isPromiseCallback) {
274
- continue; // Skip Promise callbacks with any - necessary for generic async operations
275
- }
276
-
277
- // Skip props: any in generic wrapper components
278
- const isGenericProps = (contextMatch.includes('props: any') || contextMatch.includes('props?: any')) &&
279
- (normalizedPath.includes('/utils/') || normalizedPath.includes('/components/'));
280
- if (isGenericProps) {
281
- continue; // Skip generic props - necessary for wrapper components
282
- }
283
-
284
- // Skip this: any in utility functions (throttle, debounce, etc.) - necessary for preserving context
285
- const isThisContext = contextMatch.includes('this: any') &&
286
- (normalizedPath.includes('/hooks/') || normalizedPath.includes('/utils/'));
287
- if (isThisContext) {
288
- continue; // Skip this: any - necessary for function binding utilities
289
- }
290
-
291
- // Skip any types in generic library components (DataTable, RBAC, etc.)
292
- // These are necessary for flexibility when working with unknown data structures
293
- const isGenericLibraryCode =
294
- // DataTable components - any is necessary for row data flexibility and generic components
295
- (normalizedPath.includes('/DataTable/') || normalizedPath.includes('/DataTable.tsx')) ||
296
- // RBAC code - needs any to work with Supabase's dynamic types and unknown data structures
297
- (normalizedPath.includes('/rbac/')) ||
298
- // Generic utility functions that need to work with unknown types
299
- (normalizedPath.includes('/utils/') && (
300
- contextMatch.includes('unknown') ||
301
- contextMatch.includes('Record<string') ||
302
- contextMatch.includes('lazyLoad') ||
303
- contextMatch.includes('dynamic')
304
- )) ||
305
- // Form components that work with generic form data
306
- (normalizedPath.includes('/Form/') && (
307
- contextMatch.includes('formData') ||
308
- contextMatch.includes('values:')
309
- )) ||
310
- // React.ReactElement<any> - common React pattern for generic elements
311
- contextMatch.includes('React.ReactElement<any>') ||
312
- contextMatch.includes('ReactElement<any>') ||
313
- // Icon props - common pattern for icon components (can be any icon type)
314
- (contextMatch.includes('icon') && (contextMatch.includes('?: any') || contextMatch.includes(': any'))) ||
315
- // Callback functions with generic row/data parameters
316
- (contextMatch.includes('onClick') && contextMatch.includes('(row: any)')) ||
317
- (contextMatch.includes('onClick') && contextMatch.includes('(data: any)')) ||
318
- (contextMatch.includes('callback') && contextMatch.includes(': any')) ||
319
- // Generic hooks that work with unknown data - exclude all hooks in /hooks/public/ and specific hook files
320
- (normalizedPath.includes('/hooks/public/')) ||
321
- (normalizedPath.includes('/hooks/useDataTable')) ||
322
- (normalizedPath.includes('/hooks/useFileDisplay')) ||
323
- (normalizedPath.includes('/hooks/useQueryCache')) ||
324
- (normalizedPath.includes('/hooks/useDataTablePerformance')) ||
325
- (normalizedPath.includes('/hooks/useDataTableState')) ||
326
- (normalizedPath.includes('/hooks/useInactivityTracker')) ||
327
- (normalizedPath.includes('/hooks/') && (
328
- contextMatch.includes('useDataTable') ||
329
- contextMatch.includes('useFileDisplay') ||
330
- contextMatch.includes('usePublic') ||
331
- contextMatch.includes('useQueryCache') ||
332
- contextMatch.includes('useInactivityTracker')
333
- )) ||
334
- // Calendar component - works with generic event data
335
- (normalizedPath.includes('/Calendar/')) ||
336
- // Select component - works with generic option values
337
- (normalizedPath.includes('/Select/') && (
338
- contextMatch.includes('value:') ||
339
- contextMatch.includes('option')
340
- )) ||
341
- // OrganisationProvider - works with dynamic organisation data
342
- (normalizedPath.includes('OrganisationProvider')) ||
343
- // Theming utilities - work with dynamic color data
344
- (normalizedPath.includes('/theming/')) ||
345
- // Services that work with Supabase data - exclude all services working with dynamic data
346
- (normalizedPath.includes('/services/') && (
347
- contextMatch.includes('Supabase') ||
348
- contextMatch.includes('Database') ||
349
- contextMatch.includes('forEach') ||
350
- contextMatch.includes('role: any') ||
351
- contextMatch.includes('data: any') ||
352
- contextMatch.includes(': any)')
353
- )) ||
354
- // Utils directory - many generic utilities, exclude dynamic and request utilities
355
- (normalizedPath.includes('/utils/dynamic/')) ||
356
- (normalizedPath.includes('/utils/request-')) ||
357
- (normalizedPath.includes('/utils/') && (
358
- contextMatch.includes('lazyLoad') ||
359
- contextMatch.includes('createLazyComponent') ||
360
- contextMatch.includes('request-deduplication')
361
- ));
362
-
363
- if (isGenericLibraryCode) {
364
- continue; // Skip legitimate any usage in generic library code
365
- }
366
-
367
- warnings.push({
368
- type: 'any-type',
369
- file: relativePath,
370
- line: getLineNumber(content, anyMatch.index),
371
- message: 'TypeScript any type usage detected',
372
- recommendation: 'Replace any with proper types for better type safety'
373
- });
374
- }
375
-
376
- // Check for missing return types on exported functions
377
- // Skip React components and hooks where TypeScript inference is sufficient
378
- const exportedFunctionPattern = /export\s+(?:default\s+)?(?:async\s+)?(function|const)\s+(\w+)\s*[=\(]/g;
379
- let funcMatch;
380
- while ((funcMatch = exportedFunctionPattern.exec(content)) !== null) {
381
- const funcName = funcMatch[2];
382
- // Get more context to handle multi-line function signatures
383
- const startPos = funcMatch.index;
384
- const afterMatch = content.substring(startPos, Math.min(content.length, startPos + 800));
385
-
386
- // For const declarations, check if it's actually a function (arrow function)
387
- // Skip const declarations that are just values (zod schemas, objects, etc.)
388
- if (funcMatch[1] === 'const') {
389
- // Extract the part after the equals sign to check what follows
390
- const equalsIndex = afterMatch.indexOf('=');
391
- if (equalsIndex === -1) {
392
- continue; // No equals sign found, skip
393
- }
394
-
395
- const afterEquals = afterMatch.substring(equalsIndex + 1).trim();
396
-
397
- // Check if it's an arrow function: const name = (...) => ... or const name = async (...) => ...
398
- const isArrowFunction = /^\s*(?:async\s+)?\([^)]*\)\s*=>/.test(afterEquals) ||
399
- /^\s*(?:async\s+)?\w+\s*=>/.test(afterEquals) ||
400
- /^\s*\([^)]*\)\s*:\s*\w+\s*=>/.test(afterEquals);
401
-
402
- // If it's not an arrow function, it's a const value (zod schema, object, etc.)
403
- if (!isArrowFunction) {
404
- continue; // Skip const values - not functions
405
- }
406
-
407
- // Additional check: if it looks like a value assignment before the arrow function
408
- // Pattern: const name = z.string()... or const name = new Class()... or const name = {...}
409
- // But only if there's no arrow function syntax
410
- const looksLikeValueBeforeArrow = /=\s*(z\.|new\s+\w+\(|\[|{|\d+|'|"|`|true|false|null)/.test(afterMatch);
411
- if (looksLikeValueBeforeArrow && !isArrowFunction) {
412
- continue; // Skip const values
413
- }
414
- }
415
-
416
- // Skip React hooks - TypeScript infers return types well for hooks
417
- if (funcName.startsWith('use') && funcName.length > 3) {
418
- continue; // Skip hooks - inference is sufficient
419
- }
420
-
421
- // Skip React components - TypeScript infers JSX.Element well
422
- // Check if function returns JSX (has return statement with JSX or is a component pattern)
423
- const hasJSXReturn = afterMatch.includes('return (') ||
424
- afterMatch.includes('return <') ||
425
- afterMatch.includes('return React') ||
426
- (afterMatch.includes('React.') && afterMatch.includes('createElement'));
427
-
428
- // Check if it's a React component by name pattern (PascalCase, ends with Provider, etc.)
429
- const isComponentName = /^[A-Z]/.test(funcName) ||
430
- funcName.endsWith('Provider') ||
431
- funcName.endsWith('Layout') ||
432
- funcName.endsWith('Modal') ||
433
- funcName.endsWith('Form') ||
434
- funcName.endsWith('Button') ||
435
- funcName.endsWith('Input') ||
436
- funcName.endsWith('Select');
437
-
438
- if (hasJSXReturn || isComponentName) {
439
- continue; // Skip React components - inference is sufficient
440
- }
441
-
442
- // Skip simple utility functions where return type is obvious
443
- // (e.g., getX, isX, hasX, createX, parseX, validateX, etc.)
444
- const isSimpleUtility = /^(get|is|has|create|parse|validate|format|to|from|can|should|will|do|make|build|generate|find|search|filter|map|reduce|sort|compare|check|test|verify|ensure|normalize|sanitize|escape|unescape|encode|decode)/i.test(funcName);
445
- if (isSimpleUtility && afterMatch.length < 150) {
446
- // Only skip if function is relatively simple (short context)
447
- continue; // Skip simple utilities - inference is usually sufficient
448
- }
449
-
450
- // Check if function has explicit return type
451
- if (funcMatch[1] === 'function') {
452
- // function name(...): returnType
453
- // Look for closing paren followed by colon and then any type annotation
454
- // This matches: ): Type, ): Promise<Type>, ): 'type' | 'type', ): { ... }, etc.
455
- // Handle both single-line and multi-line function signatures
456
-
457
- // Find the function body opening brace
458
- const braceIndex = afterMatch.indexOf('{');
459
- if (braceIndex === -1) {
460
- continue; // No function body found, might be a type declaration
461
- }
462
-
463
- // Get everything before the opening brace (the function signature)
464
- const funcSignature = afterMatch.substring(0, braceIndex);
465
-
466
- // Check if there's a return type annotation
467
- // Look for closing paren followed by colon (allowing whitespace/newlines)
468
- // Then check for any non-whitespace character (start of return type)
469
- // This handles:
470
- // - ): Type
471
- // - ): Promise<void>
472
- // - ): 'type' | 'type'
473
- // - ): { ... }
474
- // - Multi-line: )\n: Type
475
- // - Multi-line async: )\n: Promise<Type>
476
-
477
- // Find the last closing paren (end of parameter list)
478
- // Then check if there's a colon after it (return type annotation)
479
- let lastParenIndex = -1;
480
- let depth = 0;
481
- let inString = false;
482
- let stringChar = '';
483
-
484
- // Find the last closing paren that's not inside nested parens (parameter list end)
485
- // Start from the function name position to find the opening paren of the parameter list
486
- const funcNameMatch = funcSignature.match(new RegExp(`\\b${funcName}\\s*\\(`));
487
- const startSearchIndex = funcNameMatch ? funcNameMatch.index + funcNameMatch[0].length - 1 : 0;
488
-
489
- for (let i = startSearchIndex; i < funcSignature.length; i++) {
490
- const char = funcSignature[i];
491
-
492
- // Handle string literals
493
- if ((char === '"' || char === "'" || char === '`') && (i === 0 || funcSignature[i - 1] !== '\\')) {
494
- if (!inString) {
495
- inString = true;
496
- stringChar = char;
497
- } else if (char === stringChar) {
498
- inString = false;
499
- stringChar = '';
500
- }
501
- }
502
-
503
- if (!inString) {
504
- if (char === '(') depth++;
505
- else if (char === ')') {
506
- depth--;
507
- if (depth === 0) {
508
- lastParenIndex = i; // This is the end of the parameter list
509
- }
510
- }
511
- }
512
- }
513
-
514
- // Check if there's a return type after the last closing paren
515
- let hasReturnType = false;
516
- if (lastParenIndex >= 0) {
517
- const afterLastParen = funcSignature.substring(lastParenIndex);
518
- // Look for colon followed by non-whitespace (return type)
519
- // Normalize whitespace to handle multi-line signatures
520
- const normalizedAfterParen = afterLastParen.replace(/\s+/g, ' ');
521
- hasReturnType = /\)\s*:\s*\S/.test(normalizedAfterParen);
522
- } else {
523
- // Fallback: check if there's a colon anywhere in the signature (might be a return type)
524
- // This handles edge cases where paren tracking might fail
525
- const hasColonBeforeBrace = funcSignature.includes(':') &&
526
- funcSignature.lastIndexOf(':') < braceIndex &&
527
- funcSignature.lastIndexOf(':') > funcSignature.indexOf('(');
528
- if (hasColonBeforeBrace) {
529
- // Check if the colon is followed by a type (not a default value)
530
- const colonIndex = funcSignature.lastIndexOf(':');
531
- const afterColon = funcSignature.substring(colonIndex + 1, braceIndex).trim();
532
- // If after colon we see a type-like pattern (starts with letter, Promise, {, [, etc.)
533
- hasReturnType = /^[A-Za-z_$]|^Promise|^\{|^\[|^'|^"/.test(afterColon);
534
- }
535
- }
536
-
537
- if (!hasReturnType) {
538
- suggestions.push({
539
- type: 'missing-return-type',
540
- file: relativePath,
541
- line: getLineNumber(content, funcMatch.index),
542
- message: `Exported function '${funcName}' missing explicit return type`,
543
- recommendation: 'Add explicit return type annotation for better type safety'
544
- });
545
- }
546
- } else {
547
- // const name = (...) => ...
548
- // Check if arrow function has return type
549
- // Match: const name = (...): ReturnType => ...
550
- // Look for ): before the => arrow
551
- const arrowIndex = afterMatch.indexOf('=>');
552
- if (arrowIndex > 0) {
553
- const beforeArrow = afterMatch.substring(0, arrowIndex);
554
- // Check if there's a return type annotation (): Type) before the arrow
555
- // Normalize newlines to spaces for matching
556
- const hasArrowReturnType = /\)\s*:\s*\S/.test(beforeArrow.replace(/\n/g, ' '));
557
-
558
- if (!hasArrowReturnType) {
559
- suggestions.push({
560
- type: 'missing-return-type',
561
- file: relativePath,
562
- line: getLineNumber(content, funcMatch.index),
563
- message: `Exported function '${funcName}' missing explicit return type`,
564
- recommendation: 'Add explicit return type annotation: const name = (...): ReturnType => ...'
565
- });
566
- }
567
- }
568
- }
569
- }
570
- }
571
-
572
- // Check for inconsistent naming (simplified)
573
- // This would need more sophisticated analysis
574
-
575
- } catch (error) {
576
- // Skip files with errors
577
- }
578
- }
579
-
580
- return { issues, warnings, suggestions };
581
- }
582
- };
583
-
584
- module.exports = styleCheck;