@jmruthers/pace-core 0.5.183 → 0.5.185

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 (307) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +60 -1
  3. package/core-usage-manifest.json +312 -0
  4. package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
  5. package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
  6. package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-BABf6JCh.d.ts} +21 -10
  7. package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
  8. package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
  9. package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
  10. package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
  11. package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
  12. package/dist/{chunk-CSOFYHAG.js → chunk-AISXLWGZ.js} +374 -60
  13. package/dist/chunk-AISXLWGZ.js.map +1 -0
  14. package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
  15. package/dist/chunk-FXFJRTKI.js.map +1 -0
  16. package/dist/{chunk-QETLRQI6.js → chunk-HC67NW5K.js} +380 -360
  17. package/dist/chunk-HC67NW5K.js.map +1 -0
  18. package/dist/chunk-HESYZWZW.js +388 -0
  19. package/dist/chunk-HESYZWZW.js.map +1 -0
  20. package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
  21. package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
  22. package/dist/{chunk-UHNYIBXL.js → chunk-IXSNYUCT.js} +1 -1
  23. package/dist/chunk-IXSNYUCT.js.map +1 -0
  24. package/dist/{chunk-MI7HBHN3.js → chunk-MX3EIJGQ.js} +4 -3
  25. package/dist/{chunk-MI7HBHN3.js.map → chunk-MX3EIJGQ.js.map} +1 -1
  26. package/dist/{chunk-PWAHJW4G.js → chunk-OKI34GZD.js} +86 -33
  27. package/dist/chunk-OKI34GZD.js.map +1 -0
  28. package/dist/{chunk-W22JP75J.js → chunk-STTZQK2I.js} +3 -3
  29. package/dist/chunk-THRPYOFK.js +215 -0
  30. package/dist/chunk-THRPYOFK.js.map +1 -0
  31. package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
  32. package/dist/chunk-U6WNSFX5.js.map +1 -0
  33. package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
  34. package/dist/components.d.ts +182 -6
  35. package/dist/components.js +157 -11
  36. package/dist/components.js.map +1 -1
  37. package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
  38. package/dist/{file-reference-D06mEEWW.d.ts → file-reference-BjR39ktt.d.ts} +7 -1
  39. package/dist/hooks.d.ts +7 -14
  40. package/dist/hooks.js +10 -22
  41. package/dist/hooks.js.map +1 -1
  42. package/dist/index.d.ts +11 -11
  43. package/dist/index.js +79 -16
  44. package/dist/index.js.map +1 -1
  45. package/dist/providers.d.ts +1 -1
  46. package/dist/providers.js +3 -1
  47. package/dist/rbac/index.d.ts +205 -14
  48. package/dist/rbac/index.js +28 -6
  49. package/dist/timezone-_pgH8qrY.d.ts +530 -0
  50. package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
  51. package/dist/types.d.ts +1 -1
  52. package/dist/types.js +1 -1
  53. package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-CvnC3d-e.d.ts} +113 -2
  54. package/dist/utils.d.ts +109 -151
  55. package/dist/utils.js +128 -138
  56. package/dist/utils.js.map +1 -1
  57. package/docs/api/README.md +60 -1
  58. package/docs/api/classes/ColumnFactory.md +1 -1
  59. package/docs/api/classes/ErrorBoundary.md +1 -1
  60. package/docs/api/classes/InvalidScopeError.md +1 -1
  61. package/docs/api/classes/Logger.md +178 -0
  62. package/docs/api/classes/MissingUserContextError.md +1 -1
  63. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  64. package/docs/api/classes/PermissionDeniedError.md +1 -1
  65. package/docs/api/classes/RBACAuditManager.md +2 -2
  66. package/docs/api/classes/RBACCache.md +1 -1
  67. package/docs/api/classes/RBACEngine.md +2 -2
  68. package/docs/api/classes/RBACError.md +1 -1
  69. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  70. package/docs/api/classes/SecureSupabaseClient.md +5 -5
  71. package/docs/api/classes/StorageUtils.md +1 -1
  72. package/docs/api/enums/FileCategory.md +1 -1
  73. package/docs/api/enums/LogLevel.md +54 -0
  74. package/docs/api/enums/RBACErrorCode.md +1 -1
  75. package/docs/api/enums/RPCFunction.md +1 -1
  76. package/docs/api/interfaces/AggregateConfig.md +1 -1
  77. package/docs/api/interfaces/BadgeProps.md +1 -1
  78. package/docs/api/interfaces/ButtonProps.md +1 -1
  79. package/docs/api/interfaces/CalendarProps.md +18 -2
  80. package/docs/api/interfaces/CardProps.md +1 -1
  81. package/docs/api/interfaces/ColorPalette.md +1 -1
  82. package/docs/api/interfaces/ColorShade.md +1 -1
  83. package/docs/api/interfaces/ComplianceResult.md +30 -0
  84. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  85. package/docs/api/interfaces/DataRecord.md +1 -1
  86. package/docs/api/interfaces/DataTableAction.md +1 -1
  87. package/docs/api/interfaces/DataTableColumn.md +1 -1
  88. package/docs/api/interfaces/DataTableProps.md +1 -1
  89. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  90. package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
  91. package/docs/api/interfaces/DatabaseIssue.md +41 -0
  92. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  93. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  94. package/docs/api/interfaces/EventAppRoleData.md +6 -6
  95. package/docs/api/interfaces/ExportColumn.md +1 -1
  96. package/docs/api/interfaces/ExportOptions.md +1 -1
  97. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  98. package/docs/api/interfaces/FileMetadata.md +1 -1
  99. package/docs/api/interfaces/FileReference.md +1 -1
  100. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  101. package/docs/api/interfaces/FileUploadOptions.md +24 -8
  102. package/docs/api/interfaces/FileUploadProps.md +24 -13
  103. package/docs/api/interfaces/FooterProps.md +1 -1
  104. package/docs/api/interfaces/FormFieldProps.md +1 -1
  105. package/docs/api/interfaces/FormProps.md +1 -1
  106. package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
  107. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  108. package/docs/api/interfaces/InputProps.md +1 -1
  109. package/docs/api/interfaces/LabelProps.md +1 -1
  110. package/docs/api/interfaces/LoggerConfig.md +62 -0
  111. package/docs/api/interfaces/LoginFormProps.md +1 -1
  112. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  113. package/docs/api/interfaces/NavigationContextType.md +1 -1
  114. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  115. package/docs/api/interfaces/NavigationItem.md +1 -1
  116. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  117. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  118. package/docs/api/interfaces/Organisation.md +1 -1
  119. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  120. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  121. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  122. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  123. package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
  124. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  125. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  126. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  127. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  128. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  129. package/docs/api/interfaces/PaletteData.md +1 -1
  130. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  131. package/docs/api/interfaces/ProgressProps.md +1 -1
  132. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  133. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  134. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  135. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  136. package/docs/api/interfaces/QuickFix.md +52 -0
  137. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  138. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  139. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  140. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  141. package/docs/api/interfaces/RBACConfig.md +4 -4
  142. package/docs/api/interfaces/RBACContext.md +1 -1
  143. package/docs/api/interfaces/RBACLogger.md +1 -1
  144. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  145. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  146. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  147. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  148. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  149. package/docs/api/interfaces/RBACResult.md +1 -1
  150. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  151. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  152. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  153. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  154. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  155. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  156. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  157. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  158. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  159. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  160. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  161. package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
  162. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  163. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  164. package/docs/api/interfaces/RoleManagementResult.md +5 -5
  165. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  166. package/docs/api/interfaces/RouteConfig.md +1 -1
  167. package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
  168. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  169. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  170. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  171. package/docs/api/interfaces/SetupIssue.md +41 -0
  172. package/docs/api/interfaces/StorageConfig.md +1 -1
  173. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  174. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  175. package/docs/api/interfaces/StorageListOptions.md +1 -1
  176. package/docs/api/interfaces/StorageListResult.md +1 -1
  177. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  178. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  179. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  180. package/docs/api/interfaces/StyleImport.md +1 -1
  181. package/docs/api/interfaces/SwitchProps.md +1 -1
  182. package/docs/api/interfaces/TabsContentProps.md +1 -1
  183. package/docs/api/interfaces/TabsListProps.md +1 -1
  184. package/docs/api/interfaces/TabsProps.md +1 -1
  185. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  186. package/docs/api/interfaces/TextareaProps.md +1 -1
  187. package/docs/api/interfaces/ToastActionElement.md +1 -1
  188. package/docs/api/interfaces/ToastProps.md +1 -1
  189. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  190. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  191. package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
  192. package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
  193. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  194. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  195. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  196. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  197. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  198. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  199. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  200. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  201. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  202. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  203. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  204. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  205. package/docs/api/interfaces/UserEventAccess.md +1 -1
  206. package/docs/api/interfaces/UserMenuProps.md +1 -1
  207. package/docs/api/interfaces/UserProfile.md +1 -1
  208. package/docs/api/modules.md +738 -42
  209. package/docs/api-reference/hooks.md +111 -0
  210. package/docs/api-reference/rpc-functions.md +1 -1
  211. package/docs/api-reference/utilities.md +184 -0
  212. package/docs/getting-started/installation-guide.md +75 -16
  213. package/docs/getting-started/quick-start.md +61 -11
  214. package/docs/implementation-guides/authentication.md +88 -12
  215. package/docs/implementation-guides/file-reference-system.md +2 -1
  216. package/docs/implementation-guides/file-upload-storage.md +21 -0
  217. package/docs/rbac/README.md +1 -0
  218. package/docs/rbac/compliance/compliance-guide.md +544 -0
  219. package/docs/rbac/getting-started.md +158 -33
  220. package/docs/standards/pace-core-compliance.md +432 -0
  221. package/eslint-config-pace-core.cjs +93 -0
  222. package/package.json +15 -3
  223. package/scripts/analyze-bundle.js +232 -0
  224. package/scripts/build-css.js +56 -0
  225. package/scripts/build-docs-incremental.js +1015 -0
  226. package/scripts/check-pace-core-compliance.cjs +2353 -0
  227. package/scripts/generate-docs.js +157 -0
  228. package/scripts/setup-build-cache.js +73 -0
  229. package/scripts/utils/command-runner.js +131 -0
  230. package/scripts/utils/env.js +33 -0
  231. package/scripts/utils/index.js +10 -0
  232. package/scripts/utils/logger.js +88 -0
  233. package/scripts/utils/path-helpers.js +37 -0
  234. package/scripts/validate-formats.js +133 -0
  235. package/scripts/validate-master.js +155 -0
  236. package/scripts/validate-pre-publish.js +140 -0
  237. package/scripts/validate-theme.js +142 -0
  238. package/src/components/Calendar/Calendar.tsx +8 -1
  239. package/src/components/Card/Card.tsx +47 -8
  240. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
  241. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
  242. package/src/components/DatePickerWithTimezone/README.md +135 -0
  243. package/src/components/DatePickerWithTimezone/index.ts +10 -0
  244. package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
  245. package/src/components/DateTimeField/DateTimeField.tsx +232 -0
  246. package/src/components/DateTimeField/README.md +148 -0
  247. package/src/components/DateTimeField/index.ts +10 -0
  248. package/src/components/FileUpload/FileUpload.tsx +3 -0
  249. package/src/components/Header/Header.test.tsx +47 -18
  250. package/src/components/Header/Header.tsx +24 -6
  251. package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
  252. package/src/components/PaceAppLayout/README.md +9 -0
  253. package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -1
  254. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
  255. package/src/components/ProtectedRoute/ProtectedRoute.tsx +12 -4
  256. package/src/components/index.ts +8 -0
  257. package/src/eslint-rules/pace-core-compliance.cjs +406 -0
  258. package/src/eslint-rules/pace-core-compliance.js +640 -0
  259. package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
  260. package/src/hooks/index.ts +2 -0
  261. package/src/hooks/useFileReference.test.ts +1 -0
  262. package/src/hooks/useFormDialog.ts +147 -0
  263. package/src/index.ts +27 -0
  264. package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
  265. package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
  266. package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
  267. package/src/rbac/compliance/database-validator.ts +165 -0
  268. package/src/rbac/compliance/index.ts +38 -0
  269. package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
  270. package/src/rbac/compliance/runtime-compliance.ts +77 -0
  271. package/src/rbac/compliance/setup-validator.ts +131 -0
  272. package/src/rbac/components/PagePermissionGuard.tsx +8 -64
  273. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
  274. package/src/rbac/docs/event-based-apps.md +285 -0
  275. package/src/rbac/errors.ts +11 -0
  276. package/src/rbac/hooks/useRoleManagement.ts +292 -12
  277. package/src/rbac/index.ts +30 -0
  278. package/src/services/OrganisationService.ts +4 -0
  279. package/src/types/file-reference.ts +6 -0
  280. package/src/utils/__tests__/timezone.test.ts +345 -0
  281. package/src/utils/file-reference/__tests__/file-reference.test.ts +2 -0
  282. package/src/utils/file-reference/index.ts +1 -0
  283. package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
  284. package/src/utils/formatting/formatting.ts +179 -0
  285. package/src/utils/index.ts +27 -1
  286. package/src/utils/location/index.ts +16 -0
  287. package/src/utils/location/location.test.ts +286 -0
  288. package/src/utils/location/location.ts +175 -0
  289. package/src/utils/timezone/index.ts +17 -0
  290. package/src/utils/timezone/timezone.test.ts +349 -0
  291. package/src/utils/timezone/timezone.ts +281 -0
  292. package/dist/chunk-CSOFYHAG.js.map +0 -1
  293. package/dist/chunk-FUEYYMX5.js.map +0 -1
  294. package/dist/chunk-HKIT6O7W.js +0 -198
  295. package/dist/chunk-HKIT6O7W.js.map +0 -1
  296. package/dist/chunk-KUEN3HFB.js +0 -94
  297. package/dist/chunk-KUEN3HFB.js.map +0 -1
  298. package/dist/chunk-M7W4CP3M.js.map +0 -1
  299. package/dist/chunk-PWAHJW4G.js.map +0 -1
  300. package/dist/chunk-QETLRQI6.js.map +0 -1
  301. package/dist/chunk-UHNYIBXL.js.map +0 -1
  302. package/dist/formatting-5wETwiGF.d.ts +0 -162
  303. /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
  304. /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
  305. /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
  306. /package/dist/{chunk-W22JP75J.js.map → chunk-STTZQK2I.js.map} +0 -0
  307. /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Master Validation Script
3
+ * Consolidated validation system for PACE Core package
4
+ * Now uses standardized test execution consistent with npm run test
5
+ */
6
+
7
+ import { join } from 'path';
8
+ import {
9
+ runCommand,
10
+ runStandardizedTests,
11
+ } from './utils/command-runner.js';
12
+ import { getPackageRoot, getRepoRoot } from './utils/path-helpers.js';
13
+ import { isCI, getDefaultTimeout, getTestTimeout } from './utils/env.js';
14
+ import { logger } from './utils/logger.js';
15
+
16
+ const packageRoot = getPackageRoot(import.meta.url);
17
+ const repoRoot = getRepoRoot(import.meta.url);
18
+ const DEFAULT_TIMEOUT = getDefaultTimeout(30000, 120000);
19
+ const TEST_TIMEOUT = getTestTimeout(300000, 300000);
20
+
21
+ // Individual validation steps - only include scripts that actually exist
22
+ const validationSteps = {
23
+ 'type-check': {
24
+ name: 'Type Check',
25
+ command: ['npm', 'run', 'type-check']
26
+ },
27
+ 'test': {
28
+ name: 'Test Suite',
29
+ customHandler: runStandardizedTestsWrapper,
30
+ skipInPrePublish: true
31
+ },
32
+ 'build': {
33
+ name: 'Package Build',
34
+ command: ['npm', 'run', 'build'],
35
+ timeout: isCI() ? 180000 : 60000
36
+ },
37
+ 'build:docs': {
38
+ name: 'Documentation Generation',
39
+ command: ['npm', 'run', 'build:docs'],
40
+ cwd: packageRoot,
41
+ timeout: isCI() ? 240000 : 120000
42
+ }
43
+ };
44
+
45
+ // Standardized test execution wrapper
46
+ async function runStandardizedTestsWrapper() {
47
+ return runStandardizedTests(packageRoot, repoRoot, TEST_TIMEOUT);
48
+ }
49
+
50
+ // Main validation orchestrator
51
+ async function runValidation(mode = 'standard') {
52
+ logger.header(`Running ${mode} validation`);
53
+ if (isCI()) {
54
+ logger.info('CI environment detected - using extended timeouts and live output');
55
+ logger.newline();
56
+ }
57
+
58
+ const results = [];
59
+ const startTime = Date.now();
60
+ let criticalFailures = 0;
61
+
62
+ for (const [stepKey, step] of Object.entries(validationSteps)) {
63
+ // Skip tests in pre-publish mode if configured to do so
64
+ if (mode === 'pre-publish' && step.skipInPrePublish) {
65
+ logger.skipped(`Skipping: ${step.name} (skipped in pre-publish mode)...`);
66
+ results.push({
67
+ step: stepKey,
68
+ name: step.name,
69
+ success: true,
70
+ duration: 0,
71
+ skipped: true
72
+ });
73
+ continue;
74
+ }
75
+
76
+ const stepStartTime = Date.now();
77
+ logger.step(`Running: ${step.name}...`);
78
+
79
+ const result = step.customHandler
80
+ ? await step.customHandler()
81
+ : await runCommand(step.command[0], step.command.slice(1), {
82
+ cwd: step.cwd || packageRoot,
83
+ timeout: step.timeout || DEFAULT_TIMEOUT,
84
+ });
85
+
86
+ const stepDuration = Date.now() - stepStartTime;
87
+ const status = result.success ? '✅' : '❌';
88
+
89
+ logger.info(`${status} ${step.name} - ${stepDuration}ms`);
90
+ logger.newline();
91
+
92
+ results.push({
93
+ step: stepKey,
94
+ name: step.name,
95
+ success: result.success,
96
+ duration: stepDuration,
97
+ skipped: false
98
+ });
99
+
100
+ if (!result.success) {
101
+ criticalFailures++;
102
+ }
103
+ }
104
+
105
+ const totalDuration = Date.now() - startTime;
106
+ const passedSteps = results.filter(r => r.success).length;
107
+ const skippedSteps = results.filter(r => r.skipped).length;
108
+
109
+ // Summary
110
+ logger.header('VALIDATION SUMMARY');
111
+ logger.info(`Total steps: ${results.length}`);
112
+ logger.info(`Passed: ${passedSteps}`);
113
+ logger.info(`Skipped: ${skippedSteps}`);
114
+ logger.info(`Failed: ${criticalFailures}`);
115
+ logger.info(`Total duration: ${totalDuration}ms`);
116
+ logger.newline();
117
+
118
+ logger.info('Step Results:');
119
+ results.forEach(result => {
120
+ const status = result.skipped ? '⏭️' : (result.success ? '✅' : '❌');
121
+ const statusText = result.skipped ? 'skipped' : `${result.duration}ms`;
122
+ logger.info(` ${status} ${result.step} - ${statusText}`);
123
+ });
124
+
125
+ logger.newline();
126
+ logger.separator();
127
+
128
+ if (criticalFailures === 0) {
129
+ logger.success('All validations passed!');
130
+ return true;
131
+ } else {
132
+ logger.error(`Validation failed! ${criticalFailures} validations failed`);
133
+ return false;
134
+ }
135
+ }
136
+
137
+ // CLI handling
138
+ (async () => {
139
+ const mode = process.argv[2] || 'standard';
140
+ const success = await runValidation(mode);
141
+
142
+ if (!success) {
143
+ logger.newline();
144
+ logger.error('Package validation failed!');
145
+ logger.info('Please fix the issues above before publishing');
146
+ process.exit(1);
147
+ } else {
148
+ logger.newline();
149
+ logger.success('Package validation successful!');
150
+ process.exit(0);
151
+ }
152
+ })().catch(error => {
153
+ logger.error(`Validation script error: ${error.message}`);
154
+ process.exit(1);
155
+ });
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Pre-publish Validation Script
5
+ * Now uses standardized test execution consistent with npm run test
6
+ * Simplified to rely on vitest exit codes rather than output parsing
7
+ */
8
+
9
+ import { join } from 'path';
10
+ import { existsSync } from 'fs';
11
+ import {
12
+ runCommand,
13
+ runStandardizedTests,
14
+ } from './utils/command-runner.js';
15
+ import { getPackageRoot, getRepoRoot } from './utils/path-helpers.js';
16
+ import { getDefaultTimeout, getTestTimeout } from './utils/env.js';
17
+ import { logger } from './utils/logger.js';
18
+
19
+ const packageRoot = getPackageRoot(import.meta.url);
20
+ const repoRoot = getRepoRoot(import.meta.url);
21
+ const DEFAULT_TIMEOUT = getDefaultTimeout(30000, 120000);
22
+ const TEST_TIMEOUT = getTestTimeout(300000, 300000);
23
+
24
+ logger.header('Running pre-publish validation');
25
+
26
+ // Check if typedoc and its plugins are installed
27
+ function checkTypedocInstallation() {
28
+ const requiredPackages = [
29
+ 'typedoc',
30
+ 'typedoc-plugin-markdown',
31
+ 'typedoc-plugin-merge-modules'
32
+ ];
33
+
34
+ logger.info('Checking TypeDoc installation...');
35
+
36
+ // Check for specific packages
37
+ const missingPackages = requiredPackages.filter(pkg => {
38
+ const pkgPath = join(packageRoot, 'node_modules', pkg);
39
+ return !existsSync(pkgPath);
40
+ });
41
+
42
+ if (missingPackages.length > 0) {
43
+ logger.error(`Missing required packages: ${missingPackages.join(', ')}`);
44
+ logger.info(`Please run: npm install --save-dev ${missingPackages.join(' ')}`);
45
+ return false;
46
+ }
47
+
48
+ logger.success('TypeDoc installation verified');
49
+ return true;
50
+ }
51
+
52
+ // Main validation function
53
+ async function runPrePublishValidation() {
54
+ logger.info('Running validation steps...');
55
+ logger.newline();
56
+
57
+ // Step 1: Type check
58
+ logger.step('Step 1: Type check');
59
+ const typeCheck = await runCommand('npm', ['run', 'type-check'], {
60
+ cwd: packageRoot,
61
+ timeout: DEFAULT_TIMEOUT,
62
+ });
63
+ if (!typeCheck.success) {
64
+ logger.error('Type check failed');
65
+ return false;
66
+ }
67
+
68
+ // Step 2: Build validation
69
+ logger.newline();
70
+ logger.step('Step 2: Build validation');
71
+ const build = await runCommand('npm', ['run', 'build'], {
72
+ cwd: packageRoot,
73
+ timeout: getDefaultTimeout(60000, 180000),
74
+ });
75
+ if (!build.success) {
76
+ logger.error('Build failed');
77
+ return false;
78
+ }
79
+
80
+ // Step 3: Test validation - now uses standardized test execution
81
+ logger.newline();
82
+ logger.step('Step 3: Test validation');
83
+ const tests = await runStandardizedTests(packageRoot, repoRoot, TEST_TIMEOUT);
84
+ if (!tests.success) {
85
+ logger.error('Tests failed');
86
+ return false;
87
+ }
88
+
89
+ // Step 4: Documentation generation
90
+ logger.newline();
91
+ logger.step('Step 4: Documentation generation');
92
+ if (!checkTypedocInstallation()) {
93
+ logger.error('TypeDoc validation failed');
94
+ return false;
95
+ }
96
+
97
+ const docs = await runCommand('npm', ['run', 'build:docs'], {
98
+ cwd: packageRoot,
99
+ timeout: getDefaultTimeout(120000, 240000),
100
+ });
101
+ if (!docs.success) {
102
+ logger.error('Documentation generation failed');
103
+ return false;
104
+ }
105
+
106
+ // Step 5: Format validation
107
+ logger.newline();
108
+ logger.step('Step 5: Format validation');
109
+ const format = await runCommand('npm', ['run', 'format:check'], {
110
+ cwd: packageRoot,
111
+ timeout: DEFAULT_TIMEOUT,
112
+ });
113
+ if (!format.success) {
114
+ logger.error('Format validation failed');
115
+ return false;
116
+ }
117
+
118
+ logger.newline();
119
+ logger.header('PRE-PUBLISH VALIDATION SUMMARY');
120
+ logger.success('All validation steps passed successfully!');
121
+ logger.success('Package meets publication requirements');
122
+ return true;
123
+ }
124
+
125
+ // Run the validation
126
+ (async () => {
127
+ const success = await runPrePublishValidation();
128
+ if (!success) {
129
+ logger.newline();
130
+ logger.info('Required fixes:');
131
+ logger.info('- Fix validation failures');
132
+ logger.info('- Resolve build or type check errors');
133
+ process.exit(1);
134
+ } else {
135
+ process.exit(0);
136
+ }
137
+ })().catch(error => {
138
+ logger.error(`Pre-publish validation error: ${error.message}`);
139
+ process.exit(1);
140
+ });
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Theme Validation Script
5
+ *
6
+ * Validates that the Tailwind v4 theme file is properly structured
7
+ * and doesn't have common issues like circular references or missing colors.
8
+ */
9
+
10
+ import { readFileSync } from 'fs';
11
+ import { join } from 'path';
12
+ import { getPackageRoot } from './utils/path-helpers.js';
13
+ import { logger } from './utils/logger.js';
14
+
15
+ const packageRoot = getPackageRoot(import.meta.url);
16
+ const THEME_FILE = join(packageRoot, 'src/styles/core.css');
17
+
18
+ // Required semantic colors for Tailwind v4
19
+ const REQUIRED_SEMANTIC_COLORS = [
20
+ '--color-ring',
21
+ '--color-border',
22
+ '--color-input',
23
+ '--color-background',
24
+ '--color-foreground',
25
+ '--color-primary',
26
+ '--color-primary-foreground',
27
+ '--color-secondary',
28
+ '--color-secondary-foreground',
29
+ '--color-destructive',
30
+ '--color-destructive-foreground',
31
+ '--color-muted',
32
+ '--color-muted-foreground',
33
+ '--color-accent',
34
+ '--color-accent-foreground',
35
+ '--color-popover',
36
+ '--color-popover-foreground',
37
+ '--color-card',
38
+ '--color-card-foreground',
39
+ '--color-ring-offset'
40
+ ];
41
+
42
+ // Component classes that should not have circular references
43
+ const COMPONENT_CLASSES = [
44
+ '.pace-button',
45
+ '.pace-button-primary',
46
+ '.pace-button-secondary',
47
+ '.pace-button-outline',
48
+ '.pace-button-ghost',
49
+ '.pace-button-destructive',
50
+ '.pace-input',
51
+ '.pace-card',
52
+ '.pace-card-header',
53
+ '.pace-card-title',
54
+ '.pace-card-description',
55
+ '.pace-card-content',
56
+ '.pace-card-footer'
57
+ ];
58
+
59
+ function validateThemeFile() {
60
+ logger.info('Validating Tailwind v4 theme file...');
61
+ logger.newline();
62
+
63
+ try {
64
+ const themeContent = readFileSync(THEME_FILE, 'utf8');
65
+ let errors = [];
66
+ let warnings = [];
67
+
68
+ // Check for required semantic colors
69
+ logger.success('Checking semantic colors...');
70
+ for (const color of REQUIRED_SEMANTIC_COLORS) {
71
+ if (!themeContent.includes(color)) {
72
+ errors.push(`Missing required semantic color: ${color}`);
73
+ }
74
+ }
75
+
76
+ // Check for circular @apply references
77
+ logger.success('Checking for circular @apply references...');
78
+ for (const className of COMPONENT_CLASSES) {
79
+ const classRegex = new RegExp(`${className}\\s*\\{[^}]*@apply[^}]*${className}[^}]*\\}`, 's');
80
+ if (classRegex.test(themeContent)) {
81
+ errors.push(`Circular @apply reference found in ${className}`);
82
+ }
83
+ }
84
+
85
+ // Check for undefined color references (skip if --color-*: initial is used)
86
+ logger.success('Checking for undefined color references...');
87
+ if (!themeContent.includes('--color-*: initial')) {
88
+ const colorRefs = themeContent.match(/--color-[a-zA-Z-]+/g) || [];
89
+ const definedColors = themeContent.match(/--color-[a-zA-Z-]+:/g) || [];
90
+ const definedColorNames = definedColors.map(c => c.replace(':', ''));
91
+
92
+ for (const ref of colorRefs) {
93
+ if (!definedColorNames.includes(ref)) {
94
+ warnings.push(`Potentially undefined color reference: ${ref}`);
95
+ }
96
+ }
97
+ }
98
+
99
+ // Check for @theme declaration
100
+ logger.success('Checking for @theme declaration...');
101
+ if (!themeContent.includes('@theme {')) {
102
+ errors.push('Missing @theme declaration');
103
+ }
104
+
105
+ // Check for @import tailwindcss
106
+ logger.success('Checking for Tailwind import...');
107
+ if (!themeContent.includes('@import "tailwindcss"')) {
108
+ errors.push('Missing @import "tailwindcss"');
109
+ }
110
+
111
+ // Report results
112
+ logger.newline();
113
+ logger.header('Validation Results');
114
+
115
+ if (errors.length === 0 && warnings.length === 0) {
116
+ logger.success('All checks passed! Theme file is valid.');
117
+ return true;
118
+ }
119
+
120
+ if (errors.length > 0) {
121
+ logger.newline();
122
+ logger.error('Errors found:');
123
+ errors.forEach(error => console.log(` - ${error}`));
124
+ }
125
+
126
+ if (warnings.length > 0) {
127
+ logger.newline();
128
+ logger.warning('Warnings:');
129
+ warnings.forEach(warning => console.log(` - ${warning}`));
130
+ }
131
+
132
+ return errors.length === 0;
133
+
134
+ } catch (error) {
135
+ logger.error(`Failed to read theme file: ${error.message}`);
136
+ return false;
137
+ }
138
+ }
139
+
140
+ // Run validation
141
+ const isValid = validateThemeFile();
142
+ process.exit(isValid ? 0 : 1);
@@ -63,7 +63,7 @@ import { cn } from '../../utils/core/cn';
63
63
  // CALENDAR COMPONENT
64
64
  // ============================================================================
65
65
 
66
- export interface CalendarProps extends Omit<DayPickerProps, 'className' | 'classNames' | 'styles'> {
66
+ export interface CalendarProps extends Omit<DayPickerProps, 'className' | 'classNames' | 'styles' | 'onSelect'> {
67
67
  /**
68
68
  * Additional CSS classes to apply to the calendar wrapper
69
69
  */
@@ -72,6 +72,13 @@ export interface CalendarProps extends Omit<DayPickerProps, 'className' | 'class
72
72
  * Custom classNames for DayPicker sub-components
73
73
  */
74
74
  classNames?: DayPickerProps['classNames'];
75
+ /**
76
+ * Date selection handler. Signature depends on mode:
77
+ * - mode="single": (date: Date | undefined) => void
78
+ * - mode="range": (range: { from: Date; to?: Date } | undefined) => void
79
+ * - mode="multiple": (dates: Date[]) => void
80
+ */
81
+ onSelect?: ((date: Date | undefined) => void) | ((range: { from: Date; to?: Date } | undefined) => void) | ((dates: Date[]) => void);
75
82
  }
76
83
 
77
84
  /**
@@ -97,9 +97,10 @@ function getCardClasses(variant: CardProps['variant'] = 'default', size: CardPro
97
97
  return `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`;
98
98
  }
99
99
 
100
- const Card = React.forwardRef<
100
+ // Internal component for cards with navigation (requires Router context)
101
+ const CardWithNavigation = React.forwardRef<
101
102
  HTMLElement,
102
- CardProps
103
+ CardProps & { link: string }
103
104
  >(({ className, variant, size, isLink, link, onClick, ...props }, ref) => {
104
105
  const navigate = useNavigate();
105
106
 
@@ -131,19 +132,57 @@ const Card = React.forwardRef<
131
132
  shouldShowLinkStyles && "cursor-pointer hover:bg-acc-200 hover:shadow-xl/30",
132
133
  className
133
134
  )}
134
- onClick={link ? handleClick : onClick}
135
- role={link ? "link" : undefined}
136
- tabIndex={link ? 0 : undefined}
137
- onKeyDown={link ? (e) => {
135
+ onClick={handleClick}
136
+ role="link"
137
+ tabIndex={0}
138
+ onKeyDown={(e) => {
138
139
  if (e.key === 'Enter' || e.key === ' ') {
139
140
  e.preventDefault();
140
141
  handleClick(e as unknown as React.MouseEvent<HTMLElement>);
141
142
  }
142
- } : undefined}
143
+ }}
143
144
  {...props}
144
145
  />
145
146
  );
146
- })
147
+ });
148
+ CardWithNavigation.displayName = "CardWithNavigation";
149
+
150
+ // Internal component for cards without navigation (no Router context required)
151
+ const CardWithoutNavigation = React.forwardRef<
152
+ HTMLElement,
153
+ Omit<CardProps, 'link'>
154
+ >(({ className, variant, size, isLink, onClick, ...props }, ref) => {
155
+ // Automatically enable link styles if isLink is true
156
+ const shouldShowLinkStyles = isLink;
157
+
158
+ return (
159
+ <article
160
+ ref={ref}
161
+ className={cn(
162
+ "grid grid-rows-[auto_1fr_auto] min-w-0 overflow-visible",
163
+ getCardClasses(variant, size),
164
+ shouldShowLinkStyles && "cursor-pointer hover:bg-acc-200 hover:shadow-xl/30",
165
+ className
166
+ )}
167
+ onClick={onClick}
168
+ {...props}
169
+ />
170
+ );
171
+ });
172
+ CardWithoutNavigation.displayName = "CardWithoutNavigation";
173
+
174
+ // Main Card component that conditionally renders the appropriate variant
175
+ const Card = React.forwardRef<
176
+ HTMLElement,
177
+ CardProps
178
+ >(({ link, ...props }, ref) => {
179
+ // Only use navigation component if link is provided
180
+ // This prevents useNavigate() from being called when Router context is not available
181
+ if (link) {
182
+ return <CardWithNavigation ref={ref} link={link} {...props} />;
183
+ }
184
+ return <CardWithoutNavigation ref={ref} {...props} />;
185
+ });
147
186
  Card.displayName = "Card"
148
187
 
149
188
  const CardHeader = React.forwardRef<