@jmruthers/pace-core 0.5.193 → 0.6.2

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 (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Config Files Check Module
5
+ * @package @jmruthers/pace-core
6
+ * @module Audit/Checks/Config
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const configCheck = {
13
+ name: 'config',
14
+ description: 'Config file checks (package.json, tsconfig.json, vite.config.ts, etc.)',
15
+ severity: 'error',
16
+
17
+ async run(context) {
18
+ const { projectRoot } = context;
19
+ const issues = [];
20
+ const warnings = [];
21
+
22
+ const requiredConfigs = [
23
+ { file: 'package.json', severity: 'error' },
24
+ { file: 'tsconfig.json', severity: 'error' },
25
+ { file: 'vite.config.ts', severity: 'warning' },
26
+ { file: 'vitest.config.ts', severity: 'warning' }
27
+ ];
28
+
29
+ requiredConfigs.forEach(({ file, severity }) => {
30
+ const filePath = path.join(projectRoot, file);
31
+ if (!fs.existsSync(filePath)) {
32
+ if (severity === 'error') {
33
+ issues.push({
34
+ type: 'missing-config',
35
+ file,
36
+ message: `Required config file '${file}' is missing`,
37
+ recommendation: `Create '${file}' file`
38
+ });
39
+ } else {
40
+ warnings.push({
41
+ type: 'missing-config',
42
+ file,
43
+ message: `Recommended config file '${file}' is missing`,
44
+ recommendation: `Consider creating '${file}' file`
45
+ });
46
+ }
47
+ }
48
+ });
49
+
50
+ return { issues, warnings, suggestions: [] };
51
+ }
52
+ };
53
+
54
+ module.exports = configCheck;
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test Coverage Check Module
5
+ * @package @jmruthers/pace-core
6
+ * @module Audit/Checks/Coverage
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const coverageCheck = {
13
+ name: 'coverage',
14
+ description: 'Test coverage checks',
15
+ severity: 'warning',
16
+
17
+ async run(context) {
18
+ const { projectRoot } = context;
19
+ const issues = [];
20
+ const warnings = [];
21
+
22
+ // Try to find coverage report
23
+ const coveragePaths = [
24
+ path.join(projectRoot, 'coverage', 'coverage-summary.json'),
25
+ path.join(projectRoot, 'coverage', 'coverage-final.json')
26
+ ];
27
+
28
+ let coverageData = null;
29
+ for (const coveragePath of coveragePaths) {
30
+ if (fs.existsSync(coveragePath)) {
31
+ try {
32
+ coverageData = JSON.parse(fs.readFileSync(coveragePath, 'utf8'));
33
+ break;
34
+ } catch (error) {
35
+ // Continue to next path
36
+ }
37
+ }
38
+ }
39
+
40
+ if (!coverageData) {
41
+ warnings.push({
42
+ type: 'coverage',
43
+ file: 'coverage/',
44
+ message: 'No coverage report found. Run tests with coverage to get accurate metrics.',
45
+ recommendation: 'Run tests with coverage: npm run test:coverage'
46
+ });
47
+ return { issues, warnings, suggestions: [], metrics: null };
48
+ }
49
+
50
+ // Check coverage thresholds
51
+ const total = coverageData.total || {};
52
+ const lines = total.lines?.pct || 0;
53
+ const functions = total.functions?.pct || 0;
54
+ const branches = total.branches?.pct || 0;
55
+ const statements = total.statements?.pct || 0;
56
+
57
+ if (lines < 70) {
58
+ warnings.push({
59
+ type: 'coverage',
60
+ file: 'coverage/',
61
+ message: `Line coverage is ${lines.toFixed(1)}%, below recommended 70%`,
62
+ recommendation: 'Increase test coverage to meet the 70% threshold'
63
+ });
64
+ }
65
+
66
+ if (functions < 70) {
67
+ warnings.push({
68
+ type: 'coverage',
69
+ file: 'coverage/',
70
+ message: `Function coverage is ${functions.toFixed(1)}%, below recommended 70%`,
71
+ recommendation: 'Increase test coverage to meet the 70% threshold'
72
+ });
73
+ }
74
+
75
+ return {
76
+ issues,
77
+ warnings,
78
+ suggestions: [],
79
+ metrics: { lines, functions, branches, statements }
80
+ };
81
+ }
82
+ };
83
+
84
+ module.exports = coverageCheck;
@@ -0,0 +1,454 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Dependencies Check Module
5
+ * @package @jmruthers/pace-core
6
+ * @module Audit/Checks/Dependencies
7
+ *
8
+ * Checks for:
9
+ * - Outdated pace-core version
10
+ * - Security vulnerabilities
11
+ * - Unused dependencies
12
+ * - Missing peer dependencies
13
+ * - Version mismatches
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const { getPackageInfo, findSourceFiles } = require('../utils.cjs');
19
+
20
+ /**
21
+ * Extract package name from import/require path
22
+ */
23
+ function extractPackageName(modulePath) {
24
+ if (modulePath.startsWith('@')) {
25
+ const parts = modulePath.split('/');
26
+ if (parts.length >= 2) {
27
+ return `${parts[0]}/${parts[1]}`;
28
+ }
29
+ } else {
30
+ return modulePath.split('/')[0];
31
+ }
32
+ return null;
33
+ }
34
+
35
+ /**
36
+ * Find all config files in the project
37
+ */
38
+ function findConfigFiles(projectRoot) {
39
+ const configFiles = [];
40
+ const configPatterns = [
41
+ 'vite.config.{ts,js,mjs,cjs}',
42
+ 'vitest.config.{ts,js,mjs,cjs}',
43
+ 'tsconfig.json',
44
+ '.eslintrc.{js,json,cjs}',
45
+ 'eslint.config.{js,mjs,cjs}',
46
+ 'tailwind.config.{ts,js}',
47
+ 'postcss.config.{js,cjs}',
48
+ 'babel.config.{js,json}',
49
+ 'jest.config.{js,ts}',
50
+ 'webpack.config.{js,ts}',
51
+ 'rollup.config.{js,ts}',
52
+ 'next.config.{js,mjs}',
53
+ 'remix.config.{js,ts}',
54
+ ];
55
+
56
+ // Check root directory
57
+ const rootFiles = fs.readdirSync(projectRoot);
58
+ rootFiles.forEach(file => {
59
+ configPatterns.forEach(pattern => {
60
+ const regex = new RegExp('^' + pattern.replace(/\{.*?\}/g, '.*') + '$');
61
+ if (regex.test(file)) {
62
+ const fullPath = path.join(projectRoot, file);
63
+ if (fs.existsSync(fullPath)) {
64
+ configFiles.push(fullPath);
65
+ }
66
+ }
67
+ });
68
+ });
69
+
70
+ return configFiles;
71
+ }
72
+
73
+ /**
74
+ * Get pace-core peer dependencies
75
+ */
76
+ function getPaceCorePeerDeps(projectRoot) {
77
+ try {
78
+ // Try to find pace-core in node_modules
79
+ const paceCorePath = path.join(projectRoot, 'node_modules', '@jmruthers', 'pace-core', 'package.json');
80
+ if (fs.existsSync(paceCorePath)) {
81
+ const paceCorePkg = JSON.parse(fs.readFileSync(paceCorePath, 'utf8'));
82
+ return paceCorePkg.peerDependencies || {};
83
+ }
84
+ } catch (error) {
85
+ // If we can't find it, return empty object
86
+ }
87
+ return {};
88
+ }
89
+
90
+ /**
91
+ * Check if a dependency is used in config files
92
+ */
93
+ function checkConfigFiles(configFiles, depName) {
94
+ for (const configFile of configFiles) {
95
+ try {
96
+ const content = fs.readFileSync(configFile, 'utf8');
97
+
98
+ // Check for direct imports/requires
99
+ const importPatterns = [
100
+ /from\s+['"]([^'"]+)['"]/g,
101
+ /require\(['"]([^'"]+)['"]\)/g,
102
+ /import\(['"]([^'"]+)['"]\)/g,
103
+ ];
104
+
105
+ for (const pattern of importPatterns) {
106
+ let match;
107
+ while ((match = pattern.exec(content)) !== null) {
108
+ const modulePath = match[1];
109
+ const pkgName = extractPackageName(modulePath);
110
+ if (pkgName === depName) {
111
+ return true;
112
+ }
113
+ }
114
+ }
115
+
116
+ // Check for string references (e.g., in optimizeDeps, plugins, etc.)
117
+ // This is a heuristic - check if the package name appears as a string
118
+ const depNameEscaped = depName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
119
+ const stringRefPattern = new RegExp(`['"]${depNameEscaped}['"]`, 'g');
120
+ if (stringRefPattern.test(content)) {
121
+ return true;
122
+ }
123
+ } catch (error) {
124
+ // Skip files we can't read
125
+ }
126
+ }
127
+ return false;
128
+ }
129
+
130
+ /**
131
+ * Check if a dependency is used in CSS or other non-JS files
132
+ */
133
+ function checkNonJsFiles(projectRoot, depName) {
134
+ const cssFiles = [];
135
+ const cssExtensions = ['.css', '.scss', '.sass', '.less', '.styl'];
136
+
137
+ try {
138
+ const srcPath = path.join(projectRoot, 'src');
139
+ if (fs.existsSync(srcPath)) {
140
+ const walkDir = (dir) => {
141
+ const files = fs.readdirSync(dir);
142
+ files.forEach(file => {
143
+ const fullPath = path.join(dir, file);
144
+ const stat = fs.statSync(fullPath);
145
+ if (stat.isDirectory() && !file.startsWith('.') && file !== 'node_modules') {
146
+ walkDir(fullPath);
147
+ } else if (stat.isFile()) {
148
+ const ext = path.extname(file);
149
+ if (cssExtensions.includes(ext)) {
150
+ cssFiles.push(fullPath);
151
+ }
152
+ }
153
+ });
154
+ };
155
+ walkDir(srcPath);
156
+ }
157
+ } catch (error) {
158
+ // Skip if can't read
159
+ }
160
+
161
+ // Check CSS files for @import statements
162
+ for (const cssFile of cssFiles) {
163
+ try {
164
+ const content = fs.readFileSync(cssFile, 'utf8');
165
+ // Check for @import statements that might reference packages
166
+ const importPattern = /@import\s+['"]([^'"]+)['"]/g;
167
+ let match;
168
+ while ((match = importPattern.exec(content)) !== null) {
169
+ const modulePath = match[1];
170
+ const pkgName = extractPackageName(modulePath);
171
+ if (pkgName === depName) {
172
+ return true;
173
+ }
174
+ }
175
+ } catch (error) {
176
+ // Skip files we can't read
177
+ }
178
+ }
179
+
180
+ return false;
181
+ }
182
+
183
+ const dependenciesCheck = {
184
+ name: 'dependencies',
185
+ description: 'Dependency analysis (outdated versions, security, unused deps)',
186
+ severity: 'warning',
187
+
188
+ async run(context) {
189
+ const { projectRoot } = context;
190
+ const issues = [];
191
+ const warnings = [];
192
+ const suggestions = [];
193
+
194
+ const packageJson = getPackageInfo(projectRoot);
195
+ if (!packageJson) {
196
+ return { issues, warnings, suggestions };
197
+ }
198
+
199
+ // Skip dependency checks if this is the pace-core repository itself
200
+ // Detect pace-core repository by checking if packages/core exists
201
+ const packagesCorePath = path.join(projectRoot, 'packages', 'core');
202
+ const isPaceCoreRepository = fs.existsSync(packagesCorePath);
203
+
204
+ const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
205
+ const devDeps = packageJson.devDependencies || {};
206
+
207
+ // Get pace-core peer dependencies
208
+ const paceCorePeerDeps = getPaceCorePeerDeps(projectRoot);
209
+
210
+ // Check pace-core version (skip if this is the pace-core repository itself)
211
+ if (!isPaceCoreRepository) {
212
+ const paceCoreVersion = allDeps['@jmruthers/pace-core'];
213
+ if (paceCoreVersion) {
214
+ // Check if version is outdated (simplified - would need to check npm registry)
215
+ if (paceCoreVersion.startsWith('^') || paceCoreVersion.startsWith('~')) {
216
+ // Version range - this is fine
217
+ } else if (paceCoreVersion.match(/^\d+\.\d+\.\d+$/)) {
218
+ // Exact version - suggest using range
219
+ suggestions.push({
220
+ type: 'exact-version',
221
+ file: 'package.json',
222
+ message: `pace-core is pinned to exact version ${paceCoreVersion}`,
223
+ recommendation: 'Consider using a version range (^ or ~) to receive patch/minor updates automatically'
224
+ });
225
+ }
226
+ } else {
227
+ issues.push({
228
+ type: 'missing-pace-core',
229
+ file: 'package.json',
230
+ message: '@jmruthers/pace-core is not in dependencies',
231
+ recommendation: 'Add @jmruthers/pace-core to your dependencies'
232
+ });
233
+ }
234
+ }
235
+
236
+ // Collect all files to scan
237
+ // Skip unused dependency checks if this is the pace-core repository itself
238
+ // The library's dependencies are used in packages/core/src/, not in the root src/
239
+ const sourceFiles = [];
240
+ if (!isPaceCoreRepository) {
241
+ try {
242
+ const srcPath = path.join(projectRoot, 'src');
243
+ if (fs.existsSync(srcPath)) {
244
+ sourceFiles.push(...findSourceFiles(srcPath));
245
+ }
246
+ } catch (error) {
247
+ // Skip if can't read source files
248
+ }
249
+ }
250
+
251
+ // Also scan config files
252
+ const configFiles = findConfigFiles(projectRoot);
253
+
254
+ // Build set of imported packages from source files
255
+ const importedPackages = new Set();
256
+
257
+ // Scan source files
258
+ sourceFiles.forEach(filePath => {
259
+ try {
260
+ const content = fs.readFileSync(filePath, 'utf8');
261
+ // Check for ES6 imports
262
+ const importPattern = /from\s+['"]([^'"]+)['"]/g;
263
+ let match;
264
+ while ((match = importPattern.exec(content)) !== null) {
265
+ const modulePath = match[1];
266
+ const pkgName = extractPackageName(modulePath);
267
+ if (pkgName) {
268
+ importedPackages.add(pkgName);
269
+ }
270
+ }
271
+ // Check for require() statements
272
+ const requirePattern = /require\(['"]([^'"]+)['"]\)/g;
273
+ while ((match = requirePattern.exec(content)) !== null) {
274
+ const modulePath = match[1];
275
+ const pkgName = extractPackageName(modulePath);
276
+ if (pkgName) {
277
+ importedPackages.add(pkgName);
278
+ }
279
+ }
280
+ } catch (error) {
281
+ // Skip files with errors
282
+ }
283
+ });
284
+
285
+ // Scan config files for imports
286
+ configFiles.forEach(filePath => {
287
+ try {
288
+ const content = fs.readFileSync(filePath, 'utf8');
289
+ const importPattern = /from\s+['"]([^'"]+)['"]/g;
290
+ let match;
291
+ while ((match = importPattern.exec(content)) !== null) {
292
+ const modulePath = match[1];
293
+ const pkgName = extractPackageName(modulePath);
294
+ if (pkgName) {
295
+ importedPackages.add(pkgName);
296
+ }
297
+ }
298
+ const requirePattern = /require\(['"]([^'"]+)['"]\)/g;
299
+ while ((match = requirePattern.exec(content)) !== null) {
300
+ const modulePath = match[1];
301
+ const pkgName = extractPackageName(modulePath);
302
+ if (pkgName) {
303
+ importedPackages.add(pkgName);
304
+ }
305
+ }
306
+ } catch (error) {
307
+ // Skip files with errors
308
+ }
309
+ });
310
+
311
+ // Known build tools and dev dependencies that are commonly used but not directly imported
312
+ const knownBuildTools = [
313
+ 'vite',
314
+ 'typescript',
315
+ 'eslint',
316
+ 'prettier',
317
+ 'vitest',
318
+ '@types',
319
+ '@vitejs',
320
+ '@testing-library',
321
+ 'jsdom',
322
+ 'globals',
323
+ 'tailwindcss',
324
+ '@tailwindcss',
325
+ 'postcss',
326
+ 'autoprefixer',
327
+ 'babel',
328
+ 'webpack',
329
+ 'rollup',
330
+ 'tsup',
331
+ 'esbuild',
332
+ 'lovable-tagger',
333
+ 'babel-plugin-react-compiler',
334
+ ];
335
+
336
+ // Check for potentially unused dependencies
337
+ // Skip this check if running on the pace-core repository itself
338
+ // The library's dependencies are used in packages/core/src/, not in the root src/ (demo app)
339
+ if (!isPaceCoreRepository) {
340
+ Object.keys(allDeps).forEach(dep => {
341
+ // Skip if it's a known build tool
342
+ if (knownBuildTools.some(tool => dep.includes(tool) || dep.startsWith(tool))) {
343
+ return;
344
+ }
345
+
346
+ // Skip if it's a peer dependency of pace-core
347
+ if (paceCorePeerDeps[dep]) {
348
+ return;
349
+ }
350
+
351
+ // Skip if it's pace-core itself
352
+ if (dep === '@jmruthers/pace-core') {
353
+ return;
354
+ }
355
+
356
+ // Check if package is imported in source files
357
+ if (importedPackages.has(dep)) {
358
+ return;
359
+ }
360
+
361
+ // Check if it's used in config files
362
+ if (checkConfigFiles(configFiles, dep)) {
363
+ return;
364
+ }
365
+
366
+ // Check if it's used in CSS or other non-JS files
367
+ if (checkNonJsFiles(projectRoot, dep)) {
368
+ return;
369
+ }
370
+
371
+ // For dev dependencies, provide more context
372
+ const isDevDep = dep in devDeps;
373
+ const context = [];
374
+
375
+ if (isDevDep) {
376
+ context.push('This is a dev dependency and may be used by build tools or test frameworks');
377
+ }
378
+
379
+ // Check if it might be a transitive dependency needed by pace-core
380
+ if (paceCoreVersion) {
381
+ context.push('This may be required by @jmruthers/pace-core as a transitive dependency');
382
+ }
383
+
384
+ // Only warn if we're reasonably sure it's unused
385
+ // For runtime dependencies, be more strict
386
+ if (!isDevDep) {
387
+ // Check if it's in vite.config.ts optimizeDeps (common for pace-core peer deps)
388
+ const viteConfigPath = path.join(projectRoot, 'vite.config.ts');
389
+ const viteConfigJsPath = path.join(projectRoot, 'vite.config.js');
390
+ let isInViteConfig = false;
391
+
392
+ for (const configPath of [viteConfigPath, viteConfigJsPath]) {
393
+ if (fs.existsSync(configPath)) {
394
+ try {
395
+ const viteContent = fs.readFileSync(configPath, 'utf8');
396
+ if (viteContent.includes(dep)) {
397
+ isInViteConfig = true;
398
+ break;
399
+ }
400
+ } catch (error) {
401
+ // Skip if can't read
402
+ }
403
+ }
404
+ }
405
+
406
+ const recommendation = `Verify if '${dep}' is actually used. ${context.length > 0 ? context.join(' ') : ''}${isInViteConfig ? 'This dependency is referenced in vite.config.ts, which suggests it may be required by pace-core components. ' : ''}If it's a peer dependency of @jmruthers/pace-core (check pace-core's package.json), it's required even if not directly imported. If confirmed unused, remove it to reduce bundle size.`;
407
+
408
+ warnings.push({
409
+ type: 'unused-dependency',
410
+ file: 'package.json',
411
+ message: `Runtime dependency '${dep}' may be unused`,
412
+ recommendation: recommendation
413
+ });
414
+ } else {
415
+ // For dev dependencies, only suggest (lower severity)
416
+ suggestions.push({
417
+ type: 'potentially-unused-dev-dependency',
418
+ file: 'package.json',
419
+ message: `Dev dependency '${dep}' may be unused`,
420
+ recommendation: `Check if '${dep}' is used in build configs, test files, or by pace-core. ${context.join(' ')}If confirmed unused, you can remove it.`
421
+ });
422
+ }
423
+ });
424
+ }
425
+
426
+ // Check for missing peer dependencies from pace-core
427
+ Object.keys(paceCorePeerDeps).forEach(peerDep => {
428
+ if (!allDeps[peerDep]) {
429
+ warnings.push({
430
+ type: 'missing-peer-dependency',
431
+ file: 'package.json',
432
+ message: `Peer dependency '${peerDep}' is missing but required by @jmruthers/pace-core`,
433
+ recommendation: `Install '${peerDep}' as it's required by pace-core. Run: npm install ${peerDep}`
434
+ });
435
+ }
436
+ });
437
+
438
+ // Check for version mismatches (e.g., React versions)
439
+ const reactVersion = allDeps.react;
440
+ const reactDomVersion = allDeps['react-dom'];
441
+ if (reactVersion && reactDomVersion && reactVersion !== reactDomVersion) {
442
+ issues.push({
443
+ type: 'version-mismatch',
444
+ file: 'package.json',
445
+ message: `React version mismatch: react@${reactVersion} vs react-dom@${reactDomVersion}`,
446
+ recommendation: 'React and react-dom versions must match exactly'
447
+ });
448
+ }
449
+
450
+ return { issues, warnings, suggestions };
451
+ }
452
+ };
453
+
454
+ module.exports = dependenciesCheck;