@jmruthers/pace-core 0.5.136 → 0.5.137

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 (289) hide show
  1. package/dist/{DataTable-CYOHOX3O.js → DataTable-6M4L6BI2.js} +10 -9
  2. package/dist/{EventLogo-801uofbR.d.ts → EventLogo-rFL_kRjk.d.ts} +73 -1
  3. package/dist/{UnifiedAuthProvider-5E5TUNMS.js → UnifiedAuthProvider-XIQQ7LVU.js} +4 -5
  4. package/dist/{chunk-YLKIDTUK.js → chunk-22WKWKRX.js} +4 -4
  5. package/dist/{chunk-TVYPTYOY.js → chunk-4C7EXCAR.js} +60 -24
  6. package/dist/chunk-4C7EXCAR.js.map +1 -0
  7. package/dist/{chunk-2TWNJ46Y.js → chunk-6LAAY47Q.js} +2 -2
  8. package/dist/{chunk-444EZN6N.js → chunk-7QCC6MCP.js} +88 -1
  9. package/dist/chunk-7QCC6MCP.js.map +1 -0
  10. package/dist/{chunk-FHWWBIHA.js → chunk-BCIBECNB.js} +5 -5
  11. package/dist/chunk-BJPBT3CU.js +21 -0
  12. package/dist/chunk-BJPBT3CU.js.map +1 -0
  13. package/dist/{chunk-L6PGMCMD.js → chunk-BLCXZEYF.js} +3 -3
  14. package/dist/{chunk-HJGGOMQ6.js → chunk-HAWZXGR2.js} +147 -103
  15. package/dist/chunk-HAWZXGR2.js.map +1 -0
  16. package/dist/{chunk-XARJS7CD.js → chunk-INQLMHPF.js} +2 -2
  17. package/dist/chunk-JISYG63F.js +70 -0
  18. package/dist/chunk-JISYG63F.js.map +1 -0
  19. package/dist/{chunk-NOHEVYVX.js → chunk-KYRHUBIU.js} +417 -319
  20. package/dist/chunk-KYRHUBIU.js.map +1 -0
  21. package/dist/{chunk-SL2YQDR6.js → chunk-MA6EPSGZ.js} +2 -2
  22. package/dist/{chunk-5DPZ5EAT.js → chunk-OWAG3GSU.js} +1 -3
  23. package/dist/{chunk-LTV3XIJJ.js → chunk-T6JN6LH6.js} +4 -4
  24. package/dist/{chunk-4MT5BGGL.js → chunk-YCWDTTUK.js} +4 -6
  25. package/dist/{chunk-4MT5BGGL.js.map → chunk-YCWDTTUK.js.map} +1 -1
  26. package/dist/components.d.ts +1 -1
  27. package/dist/components.js +12 -11
  28. package/dist/components.js.map +1 -1
  29. package/dist/hooks.js +8 -9
  30. package/dist/hooks.js.map +1 -1
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +15 -14
  33. package/dist/index.js.map +1 -1
  34. package/dist/providers.js +3 -4
  35. package/dist/rbac/index.js +8 -9
  36. package/dist/schema-DTDZQe2u.d.ts +28 -0
  37. package/dist/types.d.ts +152 -3
  38. package/dist/types.js +51 -16
  39. package/dist/types.js.map +1 -1
  40. package/dist/utils.d.ts +89 -4
  41. package/dist/utils.js +214 -96
  42. package/dist/utils.js.map +1 -1
  43. package/dist/validation.d.ts +1 -343
  44. package/dist/validation.js +3 -100
  45. package/docs/api/classes/ColumnFactory.md +1 -1
  46. package/docs/api/classes/ErrorBoundary.md +1 -1
  47. package/docs/api/classes/InvalidScopeError.md +1 -1
  48. package/docs/api/classes/MissingUserContextError.md +1 -1
  49. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  50. package/docs/api/classes/PermissionDeniedError.md +1 -1
  51. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  52. package/docs/api/classes/RBACAuditManager.md +1 -1
  53. package/docs/api/classes/RBACCache.md +1 -1
  54. package/docs/api/classes/RBACEngine.md +1 -1
  55. package/docs/api/classes/RBACError.md +1 -1
  56. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  57. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  58. package/docs/api/classes/StorageUtils.md +1 -1
  59. package/docs/api/enums/FileCategory.md +1 -1
  60. package/docs/api/interfaces/AggregateConfig.md +1 -1
  61. package/docs/api/interfaces/BadgeProps.md +27 -0
  62. package/docs/api/interfaces/ButtonProps.md +1 -1
  63. package/docs/api/interfaces/CardProps.md +1 -1
  64. package/docs/api/interfaces/ColorPalette.md +1 -1
  65. package/docs/api/interfaces/ColorShade.md +1 -1
  66. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  67. package/docs/api/interfaces/DataRecord.md +1 -1
  68. package/docs/api/interfaces/DataTableAction.md +1 -1
  69. package/docs/api/interfaces/DataTableColumn.md +1 -1
  70. package/docs/api/interfaces/DataTableProps.md +1 -1
  71. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  72. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  73. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  74. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  75. package/docs/api/interfaces/EventLogoProps.md +1 -1
  76. package/docs/api/interfaces/ExportColumn.md +1 -1
  77. package/docs/api/interfaces/ExportOptions.md +1 -1
  78. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  79. package/docs/api/interfaces/FileMetadata.md +1 -1
  80. package/docs/api/interfaces/FileReference.md +1 -1
  81. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  82. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  83. package/docs/api/interfaces/FileUploadProps.md +1 -1
  84. package/docs/api/interfaces/FooterProps.md +1 -1
  85. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  86. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  87. package/docs/api/interfaces/InputProps.md +1 -1
  88. package/docs/api/interfaces/LabelProps.md +1 -1
  89. package/docs/api/interfaces/LoginFormProps.md +1 -1
  90. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  91. package/docs/api/interfaces/NavigationContextType.md +1 -1
  92. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  93. package/docs/api/interfaces/NavigationItem.md +1 -1
  94. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  95. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  96. package/docs/api/interfaces/Organisation.md +1 -1
  97. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  98. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  99. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  100. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  101. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  102. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  103. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  104. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  105. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  106. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  107. package/docs/api/interfaces/PaletteData.md +1 -1
  108. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  109. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  110. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  111. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  112. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  113. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  114. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  115. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  116. package/docs/api/interfaces/RBACConfig.md +1 -1
  117. package/docs/api/interfaces/RBACLogger.md +1 -1
  118. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  119. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  120. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  121. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  122. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  123. package/docs/api/interfaces/RouteConfig.md +1 -1
  124. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  125. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  126. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  127. package/docs/api/interfaces/StorageConfig.md +1 -1
  128. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  129. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  130. package/docs/api/interfaces/StorageListOptions.md +1 -1
  131. package/docs/api/interfaces/StorageListResult.md +1 -1
  132. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  133. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  134. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  135. package/docs/api/interfaces/StyleImport.md +1 -1
  136. package/docs/api/interfaces/SwitchProps.md +1 -1
  137. package/docs/api/interfaces/ToastActionElement.md +1 -1
  138. package/docs/api/interfaces/ToastProps.md +1 -1
  139. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  140. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  141. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  142. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  143. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  144. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  145. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  146. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  147. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  148. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  149. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  150. package/docs/api/interfaces/UserEventAccess.md +1 -1
  151. package/docs/api/interfaces/UserMenuProps.md +1 -1
  152. package/docs/api/interfaces/UserProfile.md +1 -1
  153. package/docs/api/modules.md +79 -10
  154. package/docs/architecture/README.md +0 -1
  155. package/docs/styles/README.md +0 -2
  156. package/examples/RBAC/CompleteRBACExample.tsx +324 -0
  157. package/examples/RBAC/EventBasedApp.tsx +239 -0
  158. package/examples/RBAC/PermissionExample.tsx +151 -0
  159. package/examples/RBAC/index.ts +13 -0
  160. package/examples/public-pages/CorrectPublicPageImplementation.tsx +301 -0
  161. package/examples/public-pages/PublicEventPage.tsx +274 -0
  162. package/examples/public-pages/PublicPageApp.tsx +308 -0
  163. package/examples/public-pages/PublicPageUsageExample.tsx +216 -0
  164. package/examples/public-pages/index.ts +14 -0
  165. package/package.json +1 -10
  166. package/src/__tests__/TEST_STANDARD.md +92 -0
  167. package/src/components/Badge/Badge.test.tsx +314 -0
  168. package/src/components/Badge/Badge.tsx +304 -0
  169. package/src/components/Badge/index.ts +3 -0
  170. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
  171. package/src/components/DataTable/__tests__/styles.test.ts +1 -1
  172. package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
  173. package/src/components/DataTable/components/DataTableBody.tsx +461 -0
  174. package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
  175. package/src/components/DataTable/components/FilterRow.tsx +9 -3
  176. package/src/components/DataTable/components/PaginationControls.tsx +1 -0
  177. package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
  178. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
  179. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
  180. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
  181. package/src/components/DataTable/core/ActionManager.ts +235 -0
  182. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  183. package/src/components/DataTable/core/DataManager.ts +188 -0
  184. package/src/components/DataTable/core/DataTableContext.tsx +181 -0
  185. package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
  186. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  187. package/src/components/DataTable/core/StateManager.ts +311 -0
  188. package/src/components/DataTable/core/interfaces.ts +338 -0
  189. package/src/components/DataTable/styles.ts +27 -6
  190. package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
  191. package/src/components/DataTable/utils/columnUtils.ts +40 -0
  192. package/src/components/DataTable/utils/debugTools.ts +609 -0
  193. package/src/components/DataTable/utils/index.ts +1 -0
  194. package/src/components/Dialog/README.md +804 -0
  195. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +611 -0
  196. package/src/components/Dialog/utils/safeHtml.ts +185 -0
  197. package/src/components/Footer/Footer.test.tsx +1 -1
  198. package/src/components/Form/Form.test.tsx +1 -1
  199. package/src/components/Form/FormErrorSummary.tsx +113 -0
  200. package/src/components/Form/FormFieldset.tsx +127 -0
  201. package/src/components/Form/FormLiveRegion.tsx +198 -0
  202. package/src/components/LoginForm/LoginForm.test.tsx +1 -1
  203. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
  204. package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -1
  205. package/src/components/PasswordReset/PasswordResetForm.test.tsx +597 -0
  206. package/src/components/PasswordReset/PasswordResetForm.tsx +201 -0
  207. package/src/components/PublicLayout/PublicPageDebugger.tsx +104 -0
  208. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +162 -0
  209. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
  210. package/src/components/Select/Select.test.tsx +1 -1
  211. package/src/components/Select/Select.tsx +20 -8
  212. package/src/components/Table/__tests__/Table.test.tsx +1 -1
  213. package/src/components/index.ts +3 -0
  214. package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
  215. package/src/index.ts +4 -0
  216. package/src/styles/core.css +3 -0
  217. package/src/utils/appConfig.ts +47 -0
  218. package/src/utils/appIdResolver.test.ts +499 -0
  219. package/src/utils/appIdResolver.ts +130 -0
  220. package/src/utils/appNameResolver.simple.test.ts +212 -0
  221. package/src/utils/appNameResolver.test.ts +121 -0
  222. package/src/utils/appNameResolver.ts +191 -0
  223. package/src/utils/audit.ts +127 -0
  224. package/src/utils/auth-utils.ts +96 -0
  225. package/src/utils/bundleAnalysis.ts +129 -0
  226. package/src/utils/cn.ts +7 -0
  227. package/src/utils/debugLogger.ts +67 -0
  228. package/src/utils/deviceFingerprint.ts +215 -0
  229. package/src/utils/dynamicUtils.ts +105 -0
  230. package/src/utils/file-reference.test.ts +788 -0
  231. package/src/utils/file-reference.ts +519 -0
  232. package/src/utils/formatDate.test.ts +237 -0
  233. package/src/utils/formatting.ts +133 -0
  234. package/src/utils/index.ts +7 -0
  235. package/src/utils/lazyLoad.tsx +44 -0
  236. package/src/utils/logger.ts +179 -0
  237. package/src/utils/organisationContext.test.ts +322 -0
  238. package/src/utils/organisationContext.ts +153 -0
  239. package/src/utils/performanceBenchmark.ts +64 -0
  240. package/src/utils/performanceBudgets.ts +110 -0
  241. package/src/utils/permissionTypes.ts +37 -0
  242. package/src/utils/permissionUtils.test.ts +393 -0
  243. package/src/utils/permissionUtils.ts +34 -0
  244. package/src/utils/sanitization.ts +264 -0
  245. package/src/utils/schemaUtils.ts +37 -0
  246. package/src/utils/secureDataAccess.test.ts +711 -0
  247. package/src/utils/secureDataAccess.ts +377 -0
  248. package/src/utils/secureErrors.ts +79 -0
  249. package/src/utils/secureStorage.ts +244 -0
  250. package/src/utils/security.ts +156 -0
  251. package/src/utils/securityMonitor.ts +45 -0
  252. package/src/utils/sessionTracking.ts +126 -0
  253. package/src/utils/validation.ts +111 -0
  254. package/src/utils/validationUtils.ts +120 -0
  255. package/src/validation/index.ts +2 -2
  256. package/dist/chunk-444EZN6N.js.map +0 -1
  257. package/dist/chunk-APIBCTL2.js +0 -670
  258. package/dist/chunk-APIBCTL2.js.map +0 -1
  259. package/dist/chunk-HJGGOMQ6.js.map +0 -1
  260. package/dist/chunk-K2WWTH7O.js +0 -94
  261. package/dist/chunk-K2WWTH7O.js.map +0 -1
  262. package/dist/chunk-LMC26NLJ.js +0 -84
  263. package/dist/chunk-LMC26NLJ.js.map +0 -1
  264. package/dist/chunk-NOHEVYVX.js.map +0 -1
  265. package/dist/chunk-TVYPTYOY.js.map +0 -1
  266. package/dist/validation-8npbysjg.d.ts +0 -177
  267. /package/dist/{DataTable-CYOHOX3O.js.map → DataTable-6M4L6BI2.js.map} +0 -0
  268. /package/dist/{UnifiedAuthProvider-5E5TUNMS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
  269. /package/dist/{chunk-YLKIDTUK.js.map → chunk-22WKWKRX.js.map} +0 -0
  270. /package/dist/{chunk-2TWNJ46Y.js.map → chunk-6LAAY47Q.js.map} +0 -0
  271. /package/dist/{chunk-FHWWBIHA.js.map → chunk-BCIBECNB.js.map} +0 -0
  272. /package/dist/{chunk-L6PGMCMD.js.map → chunk-BLCXZEYF.js.map} +0 -0
  273. /package/dist/{chunk-XARJS7CD.js.map → chunk-INQLMHPF.js.map} +0 -0
  274. /package/dist/{chunk-SL2YQDR6.js.map → chunk-MA6EPSGZ.js.map} +0 -0
  275. /package/dist/{chunk-5DPZ5EAT.js.map → chunk-OWAG3GSU.js.map} +0 -0
  276. /package/dist/{chunk-LTV3XIJJ.js.map → chunk-T6JN6LH6.js.map} +0 -0
  277. /package/examples/{components → components 2}/DataTable/HierarchicalActionsExample.tsx +0 -0
  278. /package/examples/{components → components 2}/DataTable/HierarchicalExample.tsx +0 -0
  279. /package/examples/{components → components 2}/DataTable/InitialPageSizeExample.tsx +0 -0
  280. /package/examples/{components → components 2}/DataTable/PerformanceExample.tsx +0 -0
  281. /package/examples/{components → components 2}/DataTable/index.ts +0 -0
  282. /package/examples/{components → components 2}/Dialog/BasicHtmlTest.tsx +0 -0
  283. /package/examples/{components → components 2}/Dialog/DebugHtmlExample.tsx +0 -0
  284. /package/examples/{components → components 2}/Dialog/HtmlDialogExample.tsx +0 -0
  285. /package/examples/{components → components 2}/Dialog/ScrollableDialogExample.tsx +0 -0
  286. /package/examples/{components → components 2}/Dialog/SimpleHtmlTest.tsx +0 -0
  287. /package/examples/{components → components 2}/Dialog/SmartDialogExample.tsx +0 -0
  288. /package/examples/{components → components 2}/Dialog/index.ts +0 -0
  289. /package/examples/{components → components 2}/index.ts +0 -0
@@ -299,97 +299,95 @@ describe('useFileUrl Hook', () => {
299
299
  });
300
300
 
301
301
  it.skip('handles signed URL generation failure', async () => {
302
- // SKIPPED: This test fails when run with other test files due to mock isolation issues.
303
- // The test passes when run in isolation, but when useFileDisplay.unit.test.ts runs first,
304
- // its mock setup for getSignedUrl interferes with this test's mock override.
305
- // TODO: Refactor to use vi.spyOn or improve mock isolation between test files.
302
+ // SKIPPED: This test has issues with async promise rejection handling in the test environment.
303
+ // The mock is being called correctly, but the promise rejection isn't being caught by the hook's
304
+ // error handling. This may be due to:
305
+ // - Timing issues between beforeEach mock reset and test mock setup
306
+ // - The hook's useEffect dependencies causing callback recreation
307
+ // - How vitest handles promise rejections in this specific scenario
308
+ //
309
+ // TODO: Investigate hook's async error handling and test environment setup.
310
+ // Consider manually triggering loadUrl() instead of relying on autoLoad, or using act() to wrap async operations.
311
+
306
312
  const error = new Error('Failed to generate signed URL');
307
- // Completely reset and override the mock to reject for this test
308
- // IMPORTANT: Must clear, reset, and set new implementation before renderHook
309
- vi.mocked(getSignedUrl).mockClear();
310
- vi.mocked(getSignedUrl).mockReset();
311
- // Force a new implementation that rejects - use mockRejectedValue for clarity
312
- vi.mocked(getSignedUrl).mockRejectedValue(error);
313
+
314
+ // Override both mocks to reject - use the same pattern as success test
315
+ // The hoisted mock is what the module uses, but we also update the imported one
316
+ mockGetSignedUrl.mockImplementation(() => Promise.reject(error));
317
+ (getSignedUrl as any).mockImplementation(() => Promise.reject(error));
313
318
 
314
- await act(async () => {
315
- const { result } = renderHook(() =>
316
- useFileUrl(mockPrivateFileReference, {
317
- organisation_id: 'org-123',
318
- supabase: mockSupabase,
319
- autoLoad: true
320
- })
321
- );
322
-
323
- // Wait for the error to be set - give it enough time for the async operation
324
- await waitFor(
325
- () => {
326
- expect(result.current.error).toBeInstanceOf(Error);
327
- },
328
- { timeout: 5000 }
329
- );
330
-
331
- // Verify getSignedUrl was called with correct arguments
332
- expect(getSignedUrl).toHaveBeenCalledWith(
333
- mockSupabase,
334
- mockPrivateFileReference.file_path,
335
- expect.objectContaining({
336
- appName: 'file-reference',
337
- orgId: 'org-123',
338
- expiresIn: 3600
339
- })
340
- );
341
-
342
- // Then verify loading is false - when an Error is thrown, the hook preserves the original error message
343
- expect(result.current.isLoading).toBe(false);
344
- expect(result.current.error?.message).toBe('Failed to generate signed URL');
345
- expect(result.current.url).toBe(null);
346
- });
319
+ const { result } = renderHook(() =>
320
+ useFileUrl(mockPrivateFileReference, {
321
+ organisation_id: 'org-123',
322
+ supabase: mockSupabase,
323
+ autoLoad: true
324
+ })
325
+ );
326
+
327
+ await waitFor(
328
+ () => {
329
+ expect(result.current.error).toBeInstanceOf(Error);
330
+ expect(result.current.isLoading).toBe(false);
331
+ },
332
+ { timeout: 5000 }
333
+ );
334
+
335
+ expect(mockGetSignedUrl).toHaveBeenCalledWith(
336
+ mockSupabase,
337
+ mockPrivateFileReference.file_path,
338
+ expect.objectContaining({
339
+ appName: 'file-reference',
340
+ orgId: 'org-123',
341
+ expiresIn: 3600
342
+ })
343
+ );
344
+ expect(result.current.error?.message).toBe('Failed to generate signed URL');
345
+ expect(result.current.url).toBe(null);
347
346
  });
348
347
 
349
348
  it.skip('handles null signed URL result', async () => {
350
- // SKIPPED: This test fails when run with other test files due to mock isolation issues.
351
- // The test passes when run in isolation, but when useFileDisplay.unit.test.ts runs first,
352
- // its mock setup for getSignedUrl interferes with this test's mock override.
353
- // TODO: Refactor to use vi.spyOn or improve mock isolation between test files.
354
- // Completely reset and override the mock to return null URL for this test
355
- // IMPORTANT: Must clear, reset, and set new implementation before renderHook
356
- vi.mocked(getSignedUrl).mockClear();
357
- vi.mocked(getSignedUrl).mockReset();
358
- // Force a new implementation that resolves with null - use mockResolvedValue for clarity
359
- vi.mocked(getSignedUrl).mockResolvedValue({ url: null, expiresAt: null });
349
+ // SKIPPED: This test has issues with async promise resolution handling in the test environment.
350
+ // The mock is being called correctly, but the promise resolution isn't completing properly,
351
+ // causing isLoading to remain true. This may be due to:
352
+ // - Timing issues between beforeEach mock reset and test mock setup
353
+ // - The hook's useEffect dependencies causing callback recreation
354
+ // - How vitest handles promise resolutions when mockImplementation is overridden
355
+ //
356
+ // TODO: Investigate hook's async state management and test environment setup.
357
+ // Consider manually triggering loadUrl() instead of relying on autoLoad, or using act() to wrap async operations.
358
+
359
+ // Clear and override both mocks - beforeEach sets mockImplementation, so we need to reset first
360
+ mockGetSignedUrl.mockReset();
361
+ mockGetSignedUrl.mockResolvedValue({ url: null, expiresAt: null });
362
+ (getSignedUrl as any).mockReset();
363
+ (getSignedUrl as any).mockResolvedValue({ url: null, expiresAt: null });
360
364
 
361
- await act(async () => {
362
- const { result } = renderHook(() =>
363
- useFileUrl(mockPrivateFileReference, {
364
- organisation_id: 'org-123',
365
- supabase: mockSupabase,
366
- autoLoad: true
367
- })
368
- );
369
-
370
- // Wait for loading to complete - check loading state first
371
- await waitFor(
372
- () => {
373
- expect(result.current.isLoading).toBe(false);
374
- },
375
- { timeout: 5000 }
376
- );
377
-
378
- // Verify getSignedUrl was called with correct arguments
379
- expect(getSignedUrl).toHaveBeenCalledWith(
380
- mockSupabase,
381
- mockPrivateFileReference.file_path,
382
- expect.objectContaining({
383
- appName: 'file-reference',
384
- orgId: 'org-123',
385
- expiresIn: 3600
386
- })
387
- );
388
-
389
- // URL should be null when getSignedUrl returns null
390
- expect(result.current.url).toBe(null);
391
- expect(result.current.error).toBe(null);
392
- });
365
+ const { result } = renderHook(() =>
366
+ useFileUrl(mockPrivateFileReference, {
367
+ organisation_id: 'org-123',
368
+ supabase: mockSupabase,
369
+ autoLoad: true
370
+ })
371
+ );
372
+
373
+ await waitFor(
374
+ () => {
375
+ expect(result.current.isLoading).toBe(false);
376
+ expect(result.current.url).toBe(null);
377
+ },
378
+ { timeout: 5000 }
379
+ );
380
+
381
+ expect(getSignedUrl).toHaveBeenCalledWith(
382
+ mockSupabase,
383
+ mockPrivateFileReference.file_path,
384
+ expect.objectContaining({
385
+ appName: 'file-reference',
386
+ orgId: 'org-123',
387
+ expiresIn: 3600
388
+ })
389
+ );
390
+ expect(result.current.error).toBe(null);
393
391
  });
394
392
  });
395
393
 
package/src/index.ts CHANGED
@@ -79,6 +79,9 @@ export type { LabelProps } from './components/Label/Label';
79
79
  export { Alert, AlertTitle, AlertDescription } from './components/Alert/Alert';
80
80
  export { Avatar, AvatarImage, AvatarFallback } from './components/Avatar/Avatar';
81
81
 
82
+ export { Badge } from './components/Badge/Badge';
83
+ export type { BadgeProps, BadgeVariant } from './components/Badge/Badge';
84
+
82
85
  export { Checkbox } from './components/Checkbox/Checkbox';
83
86
  export { Switch } from './components/Switch/Switch';
84
87
  export type { SwitchProps } from './components/Switch/Switch';
@@ -141,6 +144,7 @@ export {
141
144
  type AggregateConfig,
142
145
  type EmptyStateConfig,
143
146
  type GetRowId,
147
+ type DataTableFeatureConfig,
144
148
  ColumnFactory
145
149
  } from './components/DataTable';
146
150
 
@@ -7,6 +7,8 @@
7
7
  --font-serif: "Open Sans", sans-serif;
8
8
  --font-mono: "Reddit Mono", monospace;
9
9
  --font-heading: "Georama", sans-serif;
10
+ --shadow-badge-soft: 0 0 0 0.1rem var(--color-main-600), 0 0 0 5rem var(--color-main-600) inset, 0 0 0.25rem 0.25rem var(--color-main-600);
11
+ --shadow-badge-soft-xl: 0 0 0 0.1rem var(--color-main-600), 0 0 0 5rem var(--color-main-600) inset, 0 0 0.25rem 0.75rem var(--color-main-600);
10
12
  }
11
13
 
12
14
  @layer base {
@@ -237,6 +239,7 @@
237
239
  @layer utilities {
238
240
  /* Custom utility styles go here */
239
241
 
242
+
240
243
  /* Hide spinner arrows on number inputs in DataTable */
241
244
  .datatable-number-no-spinners::-webkit-inner-spin-button,
242
245
  .datatable-number-no-spinners::-webkit-outer-spin-button {
@@ -0,0 +1,47 @@
1
+
2
+ /**
3
+ * Application configuration utilities
4
+ */
5
+
6
+ export interface AppConfig {
7
+ appName: string;
8
+ appId: string;
9
+ }
10
+
11
+ let currentAppConfig: AppConfig | null = null;
12
+
13
+ /**
14
+ * Set the current application configuration
15
+ */
16
+ export function setAppConfig(config: AppConfig) {
17
+ currentAppConfig = config;
18
+ }
19
+
20
+ /**
21
+ * Get the current application configuration
22
+ */
23
+ export function getAppConfig(): AppConfig {
24
+ if (!currentAppConfig) {
25
+ // Fallback to environment or default
26
+ const appName = import.meta.env.REACT_APP_NAME || 'PACE';
27
+ return {
28
+ appName,
29
+ appId: appName
30
+ };
31
+ }
32
+ return currentAppConfig;
33
+ }
34
+
35
+ /**
36
+ * Get the current app name
37
+ */
38
+ export function getCurrentAppName(): string {
39
+ return getAppConfig().appName;
40
+ }
41
+
42
+ /**
43
+ * Get the current app ID
44
+ */
45
+ export function getCurrentAppId(): string {
46
+ return getAppConfig().appId;
47
+ }