@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
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Comprehensive Audit Script for Consuming Apps
5
+ * @package @jmruthers/pace-core
6
+ * @module Audit
7
+ *
8
+ * Audits consuming apps against pace-core standards and generates a markdown report.
9
+ * Organized by the 10-file standards structure (Standards 1-9).
10
+ *
11
+ * This is Layer 4 of the quality enforcement strategy:
12
+ * - Layer 1: Standards Documents (Source of Truth)
13
+ * - Layer 2: Cursor Rules (Real-time Guidance)
14
+ * - Layer 3: ESLint (Fast, Local Static Analysis)
15
+ * - Layer 4: Audit Tool (Deep, System-Level Analysis) ← You are here
16
+ *
17
+ * Usage:
18
+ * node packages/core/audit-tool/index.cjs [path-to-consuming-app] [--output report.md]
19
+ * npm run audit:pace-core [path-to-consuming-app] [--output report.md]
20
+ *
21
+ * If no path provided, assumes current directory is consuming app.
22
+ */
23
+
24
+ const fs = require('fs');
25
+ const path = require('path');
26
+
27
+ // Import dependency audit (runs before standards)
28
+ const { runDependencyAudit } = require('./00-dependencies.cjs');
29
+
30
+ // Import new standard-aligned audit modules
31
+ const { runStandard1Audit } = require('./audits/01-pace-core-compliance.cjs');
32
+ const { runStandard2Audit } = require('./audits/02-project-structure.cjs');
33
+ const { runStandard3Audit } = require('./audits/03-architecture.cjs');
34
+ const { runStandard4Audit } = require('./audits/04-code-quality.cjs');
35
+ const { runStandard5Audit } = require('./audits/05-styling.cjs');
36
+ const { runStandard6Audit } = require('./audits/06-security-rbac.cjs');
37
+ const { runStandard7Audit } = require('./audits/07-api-tech-stack.cjs');
38
+ const { runStandard8Audit } = require('./audits/08-testing-documentation.cjs');
39
+ const { runStandard9Audit } = require('./audits/09-operations.cjs');
40
+
41
+ // Import report utilities
42
+ const { generateMarkdownReport, generateSummary } = require('./utils/report-utils.cjs');
43
+
44
+ // Colors for terminal output
45
+ const colors = {
46
+ reset: '\x1b[0m',
47
+ red: '\x1b[31m',
48
+ green: '\x1b[32m',
49
+ yellow: '\x1b[33m',
50
+ blue: '\x1b[34m',
51
+ cyan: '\x1b[36m',
52
+ bold: '\x1b[1m',
53
+ };
54
+
55
+ /**
56
+ * Run all standard audits
57
+ */
58
+ function runAllAudits(consumingAppPath, showProgress = false) {
59
+ const results = {};
60
+
61
+ const standardNames = {
62
+ '01-pace-core-compliance': 'pace-core Compliance',
63
+ '02-project-structure': 'Project Structure',
64
+ '03-architecture': 'Architecture',
65
+ '04-code-quality': 'Code Quality',
66
+ '05-styling': 'Styling',
67
+ '06-security-rbac': 'Security & RBAC',
68
+ '07-api-tech-stack': 'API & Tech Stack',
69
+ '08-testing-documentation': 'Testing & Documentation',
70
+ '09-operations': 'Operations',
71
+ };
72
+
73
+ const auditFunctions = [
74
+ { key: '01-pace-core-compliance', name: standardNames['01-pace-core-compliance'], fn: runStandard1Audit },
75
+ { key: '02-project-structure', name: standardNames['02-project-structure'], fn: runStandard2Audit },
76
+ { key: '03-architecture', name: standardNames['03-architecture'], fn: runStandard3Audit },
77
+ { key: '04-code-quality', name: standardNames['04-code-quality'], fn: runStandard4Audit },
78
+ { key: '05-styling', name: standardNames['05-styling'], fn: runStandard5Audit },
79
+ { key: '06-security-rbac', name: standardNames['06-security-rbac'], fn: runStandard6Audit },
80
+ { key: '07-api-tech-stack', name: standardNames['07-api-tech-stack'], fn: runStandard7Audit },
81
+ { key: '08-testing-documentation', name: standardNames['08-testing-documentation'], fn: runStandard8Audit },
82
+ { key: '09-operations', name: standardNames['09-operations'], fn: runStandard9Audit },
83
+ ];
84
+
85
+ auditFunctions.forEach(({ key, name, fn }) => {
86
+ if (showProgress) {
87
+ console.log(`${colors.blue}Running ${name} audit...${colors.reset}`);
88
+ }
89
+
90
+ try {
91
+ const result = fn(consumingAppPath);
92
+ results[key] = result;
93
+
94
+ if (result.error && showProgress) {
95
+ console.warn(`${colors.yellow}Warning: ${name} audit failed: ${result.error}${colors.reset}`);
96
+ }
97
+ } catch (error) {
98
+ if (showProgress) {
99
+ console.warn(`${colors.yellow}Warning: ${name} audit encountered an error: ${error.message}${colors.reset}`);
100
+ }
101
+ results[key] = {
102
+ standard: key,
103
+ issues: [],
104
+ error: error.message,
105
+ };
106
+ }
107
+ });
108
+
109
+ return results;
110
+ }
111
+
112
+ /**
113
+ * Main function
114
+ */
115
+ function main() {
116
+ const args = process.argv.slice(2);
117
+ const outputArg = args.find(arg => arg.startsWith('--output'));
118
+ const outputPath = outputArg ? (outputArg.includes('=') ? outputArg.split('=')[1] : args[args.indexOf(outputArg) + 1] || 'audit-report.md') : null;
119
+ const consumingAppPath = args.find(arg => !arg.startsWith('--') && arg !== outputPath) || process.cwd();
120
+
121
+ console.log(`${colors.bold}${colors.cyan}pace-core Comprehensive Audit${colors.reset}\n`);
122
+ console.log(`${colors.cyan}${'='.repeat(50)}${colors.reset}\n`);
123
+
124
+ // Get project info from package.json
125
+ const packageJsonPath = path.join(consumingAppPath, 'package.json');
126
+ let projectName = 'unknown';
127
+ let paceCoreVersion = 'unknown';
128
+
129
+ if (fs.existsSync(packageJsonPath)) {
130
+ try {
131
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
132
+ projectName = packageJson.name || 'unknown';
133
+
134
+ // Find pace-core version
135
+ const allDeps = {
136
+ ...(packageJson.dependencies || {}),
137
+ ...(packageJson.devDependencies || {}),
138
+ };
139
+ paceCoreVersion = allDeps['@jmruthers/pace-core'] || 'not found in package.json';
140
+ } catch (error) {
141
+ // Skip if package.json can't be parsed
142
+ }
143
+ }
144
+
145
+ console.log(`Project: ${colors.bold}${projectName}${colors.reset}`);
146
+ console.log(`pace-core: ${colors.bold}${paceCoreVersion}${colors.reset}\n`);
147
+
148
+ // Run dependency audit
149
+ console.log(`${colors.blue}Running dependency audit...${colors.reset}`);
150
+ const dependencyResult = runDependencyAudit(consumingAppPath);
151
+
152
+ // Run all standard audits
153
+ const standardResults = runAllAudits(consumingAppPath, true);
154
+
155
+ // Combine results
156
+ const allResults = {
157
+ ...standardResults,
158
+ dependencies: dependencyResult,
159
+ };
160
+
161
+ // Generate summary
162
+ const summary = generateSummary(standardResults);
163
+
164
+ // Display audit results summary
165
+ console.log(`\n${colors.bold}Audit Results:${colors.reset}\n`);
166
+
167
+ // Display each standard
168
+ Object.entries(standardResults).forEach(([key, result]) => {
169
+ const standardNames = {
170
+ '01-pace-core-compliance': 'pace-core Compliance',
171
+ '02-project-structure': 'Project Structure',
172
+ '03-architecture': 'Architecture',
173
+ '04-code-quality': 'Code Quality',
174
+ '05-styling': 'Styling',
175
+ '06-security-rbac': 'Security & RBAC',
176
+ '07-api-tech-stack': 'API & Tech Stack',
177
+ '08-testing-documentation': 'Testing & Documentation',
178
+ '09-operations': 'Operations',
179
+ };
180
+
181
+ const name = standardNames[key] || key;
182
+ const issues = Array.isArray(result.issues) ? result.issues : Object.values(result.issues || {}).flat();
183
+ const count = issues.length;
184
+
185
+ if (count === 0) {
186
+ console.log(` ${colors.green}✅ ${name}: 0 issues${colors.reset}`);
187
+ } else {
188
+ console.log(` ${colors.red}❌ ${name}: ${count} issue(s)${colors.reset}`);
189
+ }
190
+ });
191
+
192
+ // Display dependency audit
193
+ if (dependencyResult.error) {
194
+ console.log(` ${colors.red}❌ Dependency Audit: Error - ${dependencyResult.error}${colors.reset}`);
195
+ } else {
196
+ const depIssues = dependencyResult.issues || {};
197
+ const depCount = (depIssues.includedDeps?.length || 0) +
198
+ (depIssues.missingRequired?.length || 0) +
199
+ (depIssues.versionIssues?.length || 0) +
200
+ (depIssues.wrongLocation?.length || 0);
201
+
202
+ if (depCount === 0) {
203
+ console.log(` ${colors.green}✅ Dependency Audit: 0 issues${colors.reset}`);
204
+ } else {
205
+ console.log(` ${colors.red}❌ Dependency Audit: ${depCount} issue(s)${colors.reset}`);
206
+ }
207
+ }
208
+
209
+ // Total summary
210
+ const totalIssues = summary.total + (dependencyResult.error ? 0 :
211
+ ((dependencyResult.issues?.includedDeps?.length || 0) +
212
+ (dependencyResult.issues?.missingRequired?.length || 0) +
213
+ (dependencyResult.issues?.versionIssues?.length || 0) +
214
+ (dependencyResult.issues?.wrongLocation?.length || 0)));
215
+
216
+ console.log(`\n${colors.bold}Total Issues: ${totalIssues === 0 ? colors.green + '0 (All checks passed!)' : colors.red + totalIssues}${colors.reset}\n`);
217
+
218
+ // Generate and save markdown report
219
+ const markdownReport = generateMarkdownReport(standardResults, consumingAppPath);
220
+
221
+ // Generate timestamp in yyyymmddHHMM format
222
+ const now = new Date();
223
+ const year = now.getFullYear();
224
+ const month = String(now.getMonth() + 1).padStart(2, '0');
225
+ const day = String(now.getDate()).padStart(2, '0');
226
+ const hours = String(now.getHours()).padStart(2, '0');
227
+ const minutes = String(now.getMinutes()).padStart(2, '0');
228
+ const timestamp = `${year}${month}${day}${hours}${minutes}`;
229
+
230
+ // Helper function to add timestamp to filename
231
+ function addTimestampToFilename(filePath) {
232
+ const dir = path.dirname(filePath);
233
+ const ext = path.extname(filePath);
234
+ const name = path.basename(filePath, ext);
235
+ return path.join(dir, `${name}-${timestamp}${ext}`);
236
+ }
237
+
238
+ // Determine report path
239
+ let reportPath;
240
+ if (outputPath) {
241
+ reportPath = addTimestampToFilename(path.join(consumingAppPath, outputPath));
242
+ } else {
243
+ // Default: save to audit/ directory
244
+ const auditDir = path.join(consumingAppPath, 'audit');
245
+ if (!fs.existsSync(auditDir)) {
246
+ fs.mkdirSync(auditDir, { recursive: true });
247
+ }
248
+ reportPath = path.join(auditDir, `pace-core-audit-${timestamp}.md`);
249
+ }
250
+
251
+ // Save report
252
+ fs.writeFileSync(reportPath, markdownReport, 'utf8');
253
+
254
+ // Display report location
255
+ const relativeReportPath = path.relative(consumingAppPath, reportPath);
256
+ console.log(`${colors.bold}Report saved to:${colors.reset} ${colors.cyan}${relativeReportPath}${colors.reset}\n`);
257
+
258
+ // Exit with error code if issues found
259
+ process.exit(totalIssues > 0 ? 1 : 0);
260
+ }
261
+
262
+ // Export for programmatic usage
263
+ module.exports = {
264
+ runAudit: main,
265
+ runAllAudits,
266
+ runStandardAudit: (standardNumber, consumingAppPath) => {
267
+ const auditFunctions = {
268
+ '1': runStandard1Audit,
269
+ '2': runStandard2Audit,
270
+ '3': runStandard3Audit,
271
+ '4': runStandard4Audit,
272
+ '5': runStandard5Audit,
273
+ '6': runStandard6Audit,
274
+ '7': runStandard7Audit,
275
+ '8': runStandard8Audit,
276
+ '9': runStandard9Audit,
277
+ };
278
+
279
+ const fn = auditFunctions[standardNumber];
280
+ if (!fn) {
281
+ throw new Error(`Invalid standard number: ${standardNumber}. Must be 1-9.`);
282
+ }
283
+
284
+ return fn(consumingAppPath);
285
+ },
286
+ };
287
+
288
+ // Run if called directly
289
+ if (require.main === module) {
290
+ main();
291
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Code Analysis Utilities for Audit Tool
3
+ * @package @jmruthers/pace-core
4
+ * @module Audit/utils/code-utils
5
+ */
6
+
7
+ /**
8
+ * Get line number from index in content
9
+ * @param {string} content - File content
10
+ * @param {number} index - Character index
11
+ * @returns {number} - Line number (1-indexed)
12
+ */
13
+ function getLineNumber(content, index) {
14
+ return content.substring(0, index).split('\n').length;
15
+ }
16
+
17
+ /**
18
+ * Get code snippet around a match for context
19
+ * @param {string} content - File content
20
+ * @param {number} index - Character index
21
+ * @param {number} before - Characters before index
22
+ * @param {number} after - Characters after index
23
+ * @returns {string} - Code snippet
24
+ */
25
+ function getCodeSnippet(content, index, before = 30, after = 50) {
26
+ const start = Math.max(0, index - before);
27
+ const end = Math.min(content.length, index + after);
28
+ return content.substring(start, end).trim();
29
+ }
30
+
31
+ /**
32
+ * Check if content is in a comment or string (for TypeScript/JavaScript)
33
+ * @param {string} content - File content
34
+ * @param {number} index - Character index
35
+ * @returns {boolean} - True if in comment or string
36
+ */
37
+ function isInCommentOrString(content, index) {
38
+ const before = content.substring(0, index);
39
+
40
+ // Check for line comments
41
+ const lastLineComment = before.lastIndexOf('//');
42
+ const lastNewline = before.lastIndexOf('\n');
43
+ if (lastLineComment > lastNewline) {
44
+ return true;
45
+ }
46
+
47
+ // Check for block comments
48
+ const lastBlockCommentStart = before.lastIndexOf('/*');
49
+ const lastBlockCommentEnd = before.lastIndexOf('*/');
50
+ if (lastBlockCommentStart > lastBlockCommentEnd) {
51
+ return true;
52
+ }
53
+
54
+ // Check for string literals (simple check)
55
+ const singleQuoteMatches = [...before.matchAll(/'/g)];
56
+ const doubleQuoteMatches = [...before.matchAll(/"/g)];
57
+ const backtickMatches = [...before.matchAll(/`/g)];
58
+
59
+ // Simple heuristic: if odd number of quotes before, might be in string
60
+ const inSingleQuote = singleQuoteMatches.length % 2 === 1;
61
+ const inDoubleQuote = doubleQuoteMatches.length % 2 === 1;
62
+ const inBacktick = backtickMatches.length % 2 === 1;
63
+
64
+ return inSingleQuote || inDoubleQuote || inBacktick;
65
+ }
66
+
67
+ /**
68
+ * Check if content is in a comment or string (for SQL)
69
+ * @param {string} content - SQL content
70
+ * @param {number} index - Character index
71
+ * @returns {boolean} - True if in comment or string
72
+ */
73
+ function isInCommentOrStringSQL(content, index) {
74
+ const before = content.substring(0, index);
75
+
76
+ // Check for SQL line comments
77
+ const lastLineComment = before.lastIndexOf('--');
78
+ const lastNewline = before.lastIndexOf('\n');
79
+ if (lastLineComment > lastNewline && !before.substring(lastLineComment, index).includes('\n')) {
80
+ return true;
81
+ }
82
+
83
+ // Check for block comments
84
+ const lastBlockCommentStart = before.lastIndexOf('/*');
85
+ const lastBlockCommentEnd = before.lastIndexOf('*/');
86
+ if (lastBlockCommentStart > lastBlockCommentEnd) {
87
+ return true;
88
+ }
89
+
90
+ // Check for string literals (SQL uses single quotes)
91
+ const singleQuoteMatches = [...before.matchAll(/'/g)];
92
+ const inSingleQuote = singleQuoteMatches.length % 2 === 1;
93
+
94
+ return inSingleQuote;
95
+ }
96
+
97
+ /**
98
+ * Extract import statements from content
99
+ * @param {string} content - File content
100
+ * @returns {Array} - Array of import objects { source, specifiers, line }
101
+ */
102
+ function parseImports(content) {
103
+ const imports = [];
104
+ const lines = content.split('\n');
105
+
106
+ lines.forEach((line, index) => {
107
+ // Match various import patterns
108
+ const importPatterns = [
109
+ /^import\s+.*\s+from\s+['"]([^'"]+)['"]/,
110
+ /^import\s+['"]([^'"]+)['"]/,
111
+ ];
112
+
113
+ for (const pattern of importPatterns) {
114
+ const match = line.match(pattern);
115
+ if (match) {
116
+ const source = match[1];
117
+ const specifiers = [];
118
+
119
+ // Try to extract named imports
120
+ const namedMatch = line.match(/import\s+{([^}]+)}\s+from/);
121
+ if (namedMatch) {
122
+ namedMatch[1].split(',').forEach(spec => {
123
+ const trimmed = spec.trim();
124
+ if (trimmed) {
125
+ specifiers.push(trimmed);
126
+ }
127
+ });
128
+ }
129
+
130
+ // Check for default import
131
+ const defaultMatch = line.match(/import\s+(\w+)\s+from/);
132
+ if (defaultMatch && !line.includes('{')) {
133
+ specifiers.push('default');
134
+ }
135
+
136
+ imports.push({
137
+ source,
138
+ specifiers,
139
+ line: index + 1,
140
+ fullLine: line.trim(),
141
+ });
142
+ break;
143
+ }
144
+ }
145
+ });
146
+
147
+ return imports;
148
+ }
149
+
150
+ /**
151
+ * Extract export statements from content
152
+ * @param {string} content - File content
153
+ * @returns {Array} - Array of export objects { name, type, line }
154
+ */
155
+ function parseExports(content) {
156
+ const exports = [];
157
+ const lines = content.split('\n');
158
+
159
+ lines.forEach((line, index) => {
160
+ // Match export patterns
161
+ const exportPatterns = [
162
+ /^export\s+(?:function|const|class|interface|type)\s+(\w+)/,
163
+ /^export\s+default\s+(?:function\s+)?(\w+)?/,
164
+ /^export\s+{\s*(\w+)/,
165
+ ];
166
+
167
+ for (const pattern of exportPatterns) {
168
+ const match = line.match(pattern);
169
+ if (match) {
170
+ const name = match[1] || 'default';
171
+ const type = line.includes('function') ? 'function' :
172
+ line.includes('const') ? 'const' :
173
+ line.includes('class') ? 'class' :
174
+ line.includes('interface') ? 'interface' :
175
+ line.includes('type') ? 'type' :
176
+ 'other';
177
+
178
+ exports.push({
179
+ name,
180
+ type,
181
+ line: index + 1,
182
+ fullLine: line.trim(),
183
+ });
184
+ break;
185
+ }
186
+ }
187
+ });
188
+
189
+ return exports;
190
+ }
191
+
192
+ /**
193
+ * Check if file imports from pace-core
194
+ * @param {string} content - File content
195
+ * @param {string} name - Component/hook/util name to check
196
+ * @returns {boolean} - True if imports from pace-core
197
+ */
198
+ function importsFromPaceCore(content, name) {
199
+ const patterns = [
200
+ new RegExp(`import\\s+.*\\b${name}\\b.*from\\s+['"]@jmruthers/pace-core`),
201
+ new RegExp(`import\\s+.*\\b${name}\\b.*from\\s+['"]@jmruthers/pace-core/components`),
202
+ new RegExp(`import\\s+.*\\b${name}\\b.*from\\s+['"]@jmruthers/pace-core/hooks`),
203
+ new RegExp(`import\\s+.*\\b${name}\\b.*from\\s+['"]@jmruthers/pace-core/utils`),
204
+ new RegExp(`import\\s+.*\\b${name}\\b.*from\\s+['"]@jmruthers/pace-core/rbac`),
205
+ ];
206
+
207
+ return patterns.some(pattern => pattern.test(content));
208
+ }
209
+
210
+ module.exports = {
211
+ getLineNumber,
212
+ getCodeSnippet,
213
+ isInCommentOrString,
214
+ isInCommentOrStringSQL,
215
+ parseImports,
216
+ parseExports,
217
+ importsFromPaceCore,
218
+ };