@jmruthers/pace-core 0.5.62 → 0.5.63

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 (109) hide show
  1. package/dist/chunk-4BWGRQBG.js +74 -0
  2. package/dist/chunk-4BWGRQBG.js.map +1 -0
  3. package/dist/{appConfig-DjpeG6P-.d.ts → formatting-BfDeV-ja.d.ts} +29 -1
  4. package/dist/index.d.ts +2 -6
  5. package/dist/index.js +14 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/utils.d.ts +2 -30
  8. package/dist/utils.js +7 -40
  9. package/dist/utils.js.map +1 -1
  10. package/docs/api/classes/ErrorBoundary.md +1 -1
  11. package/docs/api/classes/InvalidScopeError.md +1 -1
  12. package/docs/api/classes/MissingUserContextError.md +1 -1
  13. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  14. package/docs/api/classes/PermissionDeniedError.md +1 -1
  15. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  16. package/docs/api/classes/RBACAuditManager.md +1 -1
  17. package/docs/api/classes/RBACCache.md +1 -1
  18. package/docs/api/classes/RBACEngine.md +1 -1
  19. package/docs/api/classes/RBACError.md +1 -1
  20. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  21. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  22. package/docs/api/classes/StorageUtils.md +1 -1
  23. package/docs/api/interfaces/AggregateConfig.md +1 -1
  24. package/docs/api/interfaces/ButtonProps.md +1 -1
  25. package/docs/api/interfaces/CardProps.md +1 -1
  26. package/docs/api/interfaces/ColorPalette.md +1 -1
  27. package/docs/api/interfaces/ColorShade.md +1 -1
  28. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  29. package/docs/api/interfaces/DataTableAction.md +1 -1
  30. package/docs/api/interfaces/DataTableColumn.md +1 -1
  31. package/docs/api/interfaces/DataTableProps.md +1 -1
  32. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  33. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  34. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  35. package/docs/api/interfaces/EventContextType.md +1 -1
  36. package/docs/api/interfaces/EventLogoProps.md +1 -1
  37. package/docs/api/interfaces/EventProviderProps.md +1 -1
  38. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  39. package/docs/api/interfaces/FileUploadProps.md +1 -1
  40. package/docs/api/interfaces/FooterProps.md +1 -1
  41. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  42. package/docs/api/interfaces/InputProps.md +1 -1
  43. package/docs/api/interfaces/LabelProps.md +1 -1
  44. package/docs/api/interfaces/LoginFormProps.md +1 -1
  45. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  46. package/docs/api/interfaces/NavigationContextType.md +1 -1
  47. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  48. package/docs/api/interfaces/NavigationItem.md +1 -1
  49. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  50. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  51. package/docs/api/interfaces/Organisation.md +1 -1
  52. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  53. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  54. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  55. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  56. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  57. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  58. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  59. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  60. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  61. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  62. package/docs/api/interfaces/PaletteData.md +1 -1
  63. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  64. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  65. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  66. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  67. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  68. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  69. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  70. package/docs/api/interfaces/RBACConfig.md +1 -1
  71. package/docs/api/interfaces/RBACContextType.md +1 -1
  72. package/docs/api/interfaces/RBACLogger.md +1 -1
  73. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  74. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  75. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  76. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  77. package/docs/api/interfaces/RouteConfig.md +1 -1
  78. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  79. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  80. package/docs/api/interfaces/StorageConfig.md +1 -1
  81. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  82. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  83. package/docs/api/interfaces/StorageListOptions.md +1 -1
  84. package/docs/api/interfaces/StorageListResult.md +1 -1
  85. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  86. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  87. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  88. package/docs/api/interfaces/StyleImport.md +1 -1
  89. package/docs/api/interfaces/ToastActionElement.md +1 -1
  90. package/docs/api/interfaces/ToastProps.md +1 -1
  91. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  92. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  93. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  94. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  95. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  96. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  97. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  98. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  99. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  100. package/docs/api/interfaces/UserEventAccess.md +1 -1
  101. package/docs/api/interfaces/UserMenuProps.md +1 -1
  102. package/docs/api/interfaces/UserProfile.md +1 -1
  103. package/docs/api/modules.md +147 -25
  104. package/package.json +1 -1
  105. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -1
  106. package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
  107. package/src/index.ts +10 -0
  108. package/dist/chunk-W66AZIOH.js +0 -29
  109. package/dist/chunk-W66AZIOH.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ // src/utils/appConfig.ts
2
+ var currentAppConfig = null;
3
+ function setAppConfig(config) {
4
+ currentAppConfig = config;
5
+ }
6
+ function getAppConfig() {
7
+ if (!currentAppConfig) {
8
+ const appName = import.meta.env.REACT_APP_NAME || "PACE";
9
+ return {
10
+ appName,
11
+ appId: appName
12
+ };
13
+ }
14
+ return currentAppConfig;
15
+ }
16
+ function getCurrentAppName() {
17
+ return getAppConfig().appName;
18
+ }
19
+ function getCurrentAppId() {
20
+ return getAppConfig().appId;
21
+ }
22
+
23
+ // src/utils/formatting.ts
24
+ function formatDate(date) {
25
+ const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
26
+ return dateObj.toLocaleDateString(void 0, {
27
+ year: "numeric",
28
+ month: "short",
29
+ day: "numeric"
30
+ });
31
+ }
32
+ function formatCurrency(value, currencyCode = "USD", locale = "en-US") {
33
+ return new Intl.NumberFormat(locale, {
34
+ style: "currency",
35
+ currency: currencyCode
36
+ }).format(value);
37
+ }
38
+ function formatNumber(value, options = {}, locale = "en-US") {
39
+ return new Intl.NumberFormat(locale, options).format(value);
40
+ }
41
+ function formatPercent(value, locale = "en-US", decimals = 1) {
42
+ return new Intl.NumberFormat(locale, {
43
+ style: "percent",
44
+ minimumFractionDigits: decimals,
45
+ maximumFractionDigits: decimals
46
+ }).format(value / 100);
47
+ }
48
+ function formatCompactNumber(value, locale = "en-US") {
49
+ return new Intl.NumberFormat(locale, {
50
+ notation: "compact",
51
+ compactDisplay: "short"
52
+ }).format(value);
53
+ }
54
+ function formatFileSize(bytes) {
55
+ if (bytes === 0) return "0 Bytes";
56
+ const k = 1024;
57
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
58
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
59
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
60
+ }
61
+
62
+ export {
63
+ setAppConfig,
64
+ getAppConfig,
65
+ getCurrentAppName,
66
+ getCurrentAppId,
67
+ formatDate,
68
+ formatCurrency,
69
+ formatNumber,
70
+ formatPercent,
71
+ formatCompactNumber,
72
+ formatFileSize
73
+ };
74
+ //# sourceMappingURL=chunk-4BWGRQBG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/appConfig.ts","../src/utils/formatting.ts"],"sourcesContent":["\n/**\n * Application configuration utilities\n */\n\nexport interface AppConfig {\n appName: string;\n appId: string;\n}\n\nlet currentAppConfig: AppConfig | null = null;\n\n/**\n * Set the current application configuration\n */\nexport function setAppConfig(config: AppConfig) {\n currentAppConfig = config;\n}\n\n/**\n * Get the current application configuration\n */\nexport function getAppConfig(): AppConfig {\n if (!currentAppConfig) {\n // Fallback to environment or default\n const appName = import.meta.env.REACT_APP_NAME || 'PACE';\n return {\n appName,\n appId: appName\n };\n }\n return currentAppConfig;\n}\n\n/**\n * Get the current app name\n */\nexport function getCurrentAppName(): string {\n return getAppConfig().appName;\n}\n\n/**\n * Get the current app ID\n */\nexport function getCurrentAppId(): string {\n return getAppConfig().appId;\n}\n","/**\n * Utility functions for formatting data in the application\n */\n\n/**\n * Format a date as a readable string\n */\nexport function formatDate(date: Date | string | number): string {\n const dateObj = typeof date === 'string' || typeof date === 'number' \n ? new Date(date) \n : date;\n \n return dateObj.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n}\n\n/**\n * Format a number as a currency\n */\nexport function formatCurrency(value: number, currencyCode = 'USD', locale = 'en-US'): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n }).format(value);\n}\n\n/**\n * Format a number with custom options\n */\nexport function formatNumber(\n value: number,\n options: Intl.NumberFormatOptions = {},\n locale = 'en-US'\n): string {\n return new Intl.NumberFormat(locale, options).format(value);\n}\n\n/**\n * Format a number as a percentage\n */\nexport function formatPercent(\n value: number,\n locale: string = 'en-US',\n decimals: number = 1\n): string {\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(value / 100);\n}\n\n/**\n * Format a large number with abbreviations (K, M, B)\n */\nexport function formatCompactNumber(value: number, locale = 'en-US'): string {\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short'\n }).format(value);\n}\n\n/**\n * Format a file size in bytes to a human-readable string\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n \n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n"],"mappings":";AAUA,IAAI,mBAAqC;AAKlC,SAAS,aAAa,QAAmB;AAC9C,qBAAmB;AACrB;AAKO,SAAS,eAA0B;AACxC,MAAI,CAAC,kBAAkB;AAErB,UAAM,UAAU,YAAY,IAAI,kBAAkB;AAClD,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO,aAAa,EAAE;AACxB;AAKO,SAAS,kBAA0B;AACxC,SAAO,aAAa,EAAE;AACxB;;;ACvCO,SAAS,WAAW,MAAsC;AAC/D,QAAM,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,WACxD,IAAI,KAAK,IAAI,IACb;AAEJ,SAAO,QAAQ,mBAAmB,QAAW;AAAA,IAC3C,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,EACP,CAAC;AACH;AAKO,SAAS,eAAe,OAAe,eAAe,OAAO,SAAS,SAAiB;AAC5F,SAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,IACnC,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC,EAAE,OAAO,KAAK;AACjB;AAKO,SAAS,aACd,OACA,UAAoC,CAAC,GACrC,SAAS,SACD;AACR,SAAO,IAAI,KAAK,aAAa,QAAQ,OAAO,EAAE,OAAO,KAAK;AAC5D;AAKO,SAAS,cACd,OACA,SAAiB,SACjB,WAAmB,GACX;AACR,SAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,IACnC,OAAO;AAAA,IACP,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC,EAAE,OAAO,QAAQ,GAAG;AACvB;AAKO,SAAS,oBAAoB,OAAe,SAAS,SAAiB;AAC3E,SAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,IACnC,UAAU;AAAA,IACV,gBAAgB;AAAA,EAClB,CAAC,EAAE,OAAO,KAAK;AACjB;AAKO,SAAS,eAAe,OAAuB;AACpD,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,SAAS,MAAM,MAAM,MAAM,MAAM,IAAI;AACpD,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAElD,SAAO,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC;AACxE;","names":[]}
@@ -76,4 +76,32 @@ declare function getCurrentAppName(): string;
76
76
  */
77
77
  declare function getCurrentAppId(): string;
78
78
 
79
- export { type AppConfig as A, type SecureDataAccess as S, cn as a, getCurrentAppName as b, createSecureDataAccess as c, getCurrentAppId as d, getAppConfig as g, setAppConfig as s };
79
+ /**
80
+ * Utility functions for formatting data in the application
81
+ */
82
+ /**
83
+ * Format a date as a readable string
84
+ */
85
+ declare function formatDate(date: Date | string | number): string;
86
+ /**
87
+ * Format a number as a currency
88
+ */
89
+ declare function formatCurrency(value: number, currencyCode?: string, locale?: string): string;
90
+ /**
91
+ * Format a number with custom options
92
+ */
93
+ declare function formatNumber(value: number, options?: Intl.NumberFormatOptions, locale?: string): string;
94
+ /**
95
+ * Format a number as a percentage
96
+ */
97
+ declare function formatPercent(value: number, locale?: string, decimals?: number): string;
98
+ /**
99
+ * Format a large number with abbreviations (K, M, B)
100
+ */
101
+ declare function formatCompactNumber(value: number, locale?: string): string;
102
+ /**
103
+ * Format a file size in bytes to a human-readable string
104
+ */
105
+ declare function formatFileSize(bytes: number): string;
106
+
107
+ export { type AppConfig as A, type SecureDataAccess as S, cn as a, getCurrentAppName as b, createSecureDataAccess as c, getCurrentAppId as d, formatCurrency as e, formatDate as f, getAppConfig as g, formatNumber as h, formatPercent as i, formatCompactNumber as j, formatFileSize as k, setAppConfig as s };
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { u as useToast } from './useToast-Bm6TnSK-.js';
10
10
  export { D as DataTable, a as DataTableProps } from './DataTable-D15XipLZ.js';
11
11
  export { A as AggregateConfig, D as DataRecord, f as DataTableAction, a as DataTableColumn, g as DataTableToolbarButton, E as EmptyStateConfig, G as GetRowId } from './types-E5WSpEtz.js';
12
12
  export { o as UsePublicEventLogoOptions, n as UsePublicEventLogoReturn, m as UsePublicEventOptions, U as UsePublicEventReturn, p as UsePublicRouteParamsReturn, d as clearPublicEventCache, f as clearPublicLogoCache, l as extractEventCodeFromPath, k as generatePublicRoutePath, g as getPublicEventCacheStats, h as getPublicLogoCacheStats, b as useAppConfig, u as useOrganisationPermissions, a as useOrganisationSecurity, c as usePublicEvent, j as usePublicEventCode, e as usePublicEventLogo, i as usePublicRouteParams } from './usePublicRouteParams-CdoFxnJK.js';
13
- export { a as cn, c as createSecureDataAccess, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './appConfig-DjpeG6P-.js';
13
+ export { a as cn, c as createSecureDataAccess, j as formatCompactNumber, e as formatCurrency, f as formatDate, k as formatFileSize, h as formatNumber, i as formatPercent, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './formatting-BfDeV-ja.js';
14
14
  import React__default from 'react';
15
15
  import { SupabaseClient } from '@supabase/supabase-js';
16
16
  export { StyleImport, getAllStylePaths, getStylePath, styleConfig } from './styles/index.js';
@@ -346,10 +346,6 @@ declare function validateFileSize(file: File): {
346
346
  isValid: boolean;
347
347
  error?: string;
348
348
  };
349
- /**
350
- * Get human-readable file size
351
- */
352
- declare function formatFileSize(bytes: number): string;
353
349
 
354
350
  /**
355
351
  * Storage helper functions for pace-core
@@ -425,4 +421,4 @@ declare class StorageUtils {
425
421
  static archiveFile: typeof archiveFile;
426
422
  }
427
423
 
428
- export { APP_PATH_MAPPING, DEFAULT_FILE_SIZE_LIMIT, FILE_SIZE_LIMITS, FileSizeLimits, FileUpload, type FileUploadProps, InactivityWarningModal, type InactivityWarningModalProps, PasswordChangeForm, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, deleteFile, extractFileMetadata, formatFileSize, generateFilePath, generateUniqueFileName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, uploadFile, useInactivityTracker, validateFileSize };
424
+ export { APP_PATH_MAPPING, DEFAULT_FILE_SIZE_LIMIT, FILE_SIZE_LIMITS, FileSizeLimits, FileUpload, type FileUploadProps, InactivityWarningModal, type InactivityWarningModalProps, PasswordChangeForm, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, deleteFile, extractFileMetadata, generateFilePath, generateUniqueFileName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, uploadFile, useInactivityTracker, validateFileSize };
package/dist/index.js CHANGED
@@ -87,7 +87,7 @@ import {
87
87
  archiveFile,
88
88
  deleteFile,
89
89
  extractFileMetadata,
90
- formatFileSize,
90
+ formatFileSize as formatFileSize2,
91
91
  generateFilePath,
92
92
  generateUniqueFileName,
93
93
  getFileSizeLimit,
@@ -228,11 +228,17 @@ import {
228
228
  } from "./chunk-T2MQY57J.js";
229
229
  import "./chunk-ULBI5JGB.js";
230
230
  import {
231
+ formatCompactNumber,
232
+ formatCurrency,
233
+ formatDate,
234
+ formatFileSize,
235
+ formatNumber,
236
+ formatPercent,
231
237
  getAppConfig,
232
238
  getCurrentAppId,
233
239
  getCurrentAppName,
234
240
  setAppConfig
235
- } from "./chunk-W66AZIOH.js";
241
+ } from "./chunk-4BWGRQBG.js";
236
242
  import {
237
243
  LoadingSpinner
238
244
  } from "./chunk-CDQ3PX7L.js";
@@ -618,7 +624,7 @@ function FileUpload({
618
624
  /* @__PURE__ */ jsx("h4", { className: "file-upload__files-title", children: "Selected Files:" }),
619
625
  /* @__PURE__ */ jsx("ul", { className: "file-upload__files-list", children: selectedFiles.map((file, index) => /* @__PURE__ */ jsxs("li", { className: "file-upload__file-item", children: [
620
626
  /* @__PURE__ */ jsx("span", { className: "file-upload__file-name", children: file.name }),
621
- /* @__PURE__ */ jsx("span", { className: "file-upload__file-size", children: formatFileSize(file.size) })
627
+ /* @__PURE__ */ jsx("span", { className: "file-upload__file-size", children: formatFileSize2(file.size) })
622
628
  ] }, index)) })
623
629
  ] }),
624
630
  validationErrors.length > 0 && /* @__PURE__ */ jsx(Alert, { variant: "destructive", className: "file-upload__errors", children: /* @__PURE__ */ jsx("ul", { children: validationErrors.map((error, index) => /* @__PURE__ */ jsx("li", { children: error }, index)) }) }),
@@ -791,7 +797,12 @@ export {
791
797
  emitAuditEvent,
792
798
  extractEventCodeFromPath,
793
799
  extractFileMetadata,
800
+ formatCompactNumber,
801
+ formatCurrency,
802
+ formatDate,
794
803
  formatFileSize,
804
+ formatNumber,
805
+ formatPercent,
795
806
  fromSupabaseClient,
796
807
  generateFilePath,
797
808
  generatePublicRoutePath,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/secureDataAccess.ts","../src/components/FileUpload/FileUpload.tsx"],"sourcesContent":["/**\n * @file Complete Component Library Export\n * @package @jmruthers/pace-core\n * @module Core\n * @since 0.1.0\n * \n * This file exports the primary components, hooks, and utilities from the PACE Core library.\n * It is the main entry point for developers using the library.\n * \n * @example\n * // Import common components\n * import { Button, Card, useUnifiedAuth } from '@jmruthers/pace-core';\n * \n * // For specialized components, use the complete library import:\n * import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';\n */\n\n// AUTHENTICATION & AUTHORIZATION\nexport { UnifiedAuthProvider, useUnifiedAuth } from './providers/UnifiedAuthProvider';\nexport type { UnifiedAuthProviderProps, UnifiedAuthContextType, UserEventAccess } from './providers/UnifiedAuthProvider';\nexport { EventProvider, useEvents } from './providers/EventProvider';\nexport type { EventProviderProps, EventContextType } from './providers/EventProvider';\nexport { OrganisationProvider, useOrganisations } from './providers/OrganisationProvider';\nexport type { \n Organisation, \n OrganisationMembership, \n OrganisationContextType, \n OrganisationProviderProps,\n OrganisationSecurityError \n} from './types/organisation';\n\n// INACTIVITY TRACKING\nexport { InactivityWarningModal } from './components/InactivityWarningModal/InactivityWarningModal';\nexport type { InactivityWarningModalProps } from './components/InactivityWarningModal/InactivityWarningModal';\nexport { useInactivityTracker } from './hooks/useInactivityTracker';\nexport type { UseInactivityTrackerOptions, UseInactivityTrackerReturn } from './hooks/useInactivityTracker';\n\n// RBAC SYSTEM - Consolidated RBAC module\nexport * from './rbac';\n\n// BASIC UI COMPONENTS\nexport { Button } from './components/Button/Button';\nexport type { ButtonProps } from './components/Button/Button';\n\nexport { \n Card, \n CardHeader, \n CardFooter, \n CardTitle, \n CardDescription, \n CardContent,\n CardActions\n} from './components/Card/Card';\nexport type { CardProps } from './components/Card/Card';\n\nexport { Input } from './components/Input/Input';\nexport type { InputProps } from './components/Input/Input';\nexport { Label } from './components/Label/Label';\nexport type { LabelProps } from './components/Label/Label';\n\nexport { Alert, AlertTitle, AlertDescription } from './components/Alert/Alert';\nexport { Avatar, AvatarImage, AvatarFallback } from './components/Avatar/Avatar';\n\nexport { Checkbox } from './components/Checkbox/Checkbox';\nexport { Progress } from './components/Progress/Progress';\n\n// ADVANCED UI COMPONENTS\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogBody,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n} from './components/Dialog/Dialog';\n\n// Dropdown Menu exports\n// DropdownMenu components have been merged into Select components\n\n// Select exports\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n} from './components/Select';\n\n// Modal functionality is provided by Dialog components\n\nexport {\n Toast,\n Toaster,\n ToastAction,\n ToastProvider,\n ToastViewport,\n ToastTitle,\n ToastDescription,\n ToastClose,\n} from './components/Toast/Toast';\nexport { useToast } from './hooks/useToast';\nexport type { ToastActionElement, ToastProps } from './components/Toast/Toast';\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from './components/Tooltip/Tooltip';\n\n// DATA DISPLAY COMPONENTS\nexport {\n DataTable,\n type DataTableProps,\n type DataTableColumn,\n type DataTableAction,\n type DataTableToolbarButton,\n type AggregateConfig,\n type EmptyStateConfig,\n type GetRowId\n} from './components/DataTable';\n\n// Re-export types from DataTable types\nexport type { DataRecord } from './components/DataTable/types';\n\n// FORM COMPONENTS\nexport { Form } from './components/Form/Form';\nexport { LoginForm } from './components/LoginForm/LoginForm';\nexport type { LoginFormProps } from './components/LoginForm/LoginForm';\n\n// LAYOUT COMPONENTS\nexport { Header } from './components/Header/Header';\nexport { Footer } from './components/Footer/Footer';\nexport type { FooterProps } from './components/Footer/Footer';\n\n// NAVIGATION COMPONENTS\nexport { NavigationMenu } from './components/NavigationMenu/NavigationMenu';\nexport type { NavigationMenuProps, NavigationItem } from './components/NavigationMenu/types';\nexport { UserMenu } from './components/UserMenu/UserMenu';\nexport type { UserMenuProps } from './components/UserMenu/UserMenu';\n\n// Reusable Page/Layout Components\nexport { PaceAppLayout } from './components/PaceAppLayout/PaceAppLayout';\nexport type { PaceAppLayoutProps } from './components/PaceAppLayout/PaceAppLayout';\nexport { PaceLoginPage } from './components/PaceLoginPage/PaceLoginPage';\nexport type { PaceLoginPageProps } from './components/PaceLoginPage/PaceLoginPage';\n\n// UTILITY COMPONENTS\nexport { ErrorBoundary } from './components/ErrorBoundary/ErrorBoundary';\nexport { LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner';\n\n// EVENT MANAGEMENT\nexport { EventSelector } from './components/EventSelector/EventSelector';\n\n// ORGANISATION MANAGEMENT\nexport { OrganisationSelector } from './components/OrganisationSelector/OrganisationSelector';\nexport { useOrganisationPermissions } from './hooks/useOrganisationPermissions';\nexport { useOrganisationSecurity } from './hooks/useOrganisationSecurity';\nexport { createSecureDataAccess } from './utils/secureDataAccess';\n\n// TYPES\nexport type { UserProfile } from './types/organisation';\n\n// AUTHENTICATION FORMS\nexport { PasswordResetForm } from './components/PasswordReset/PasswordResetForm';\nexport { PasswordChangeForm } from './components/PasswordReset/PasswordChangeForm';\n\n// UTILS & HOOKS\nexport { useAppConfig } from './hooks/useAppConfig';\nexport { cn } from './utils/cn';\nexport { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/appConfig';\n\n// STORAGE UTILITIES\nexport { FileUpload } from './components/FileUpload/FileUpload';\nexport type { FileUploadProps } from './components/FileUpload/FileUpload';\nexport { useStorage, useFileUpload } from './hooks/useStorage';\nexport * from './utils/storage';\n\n// Table components\nexport {\n Table,\n TableHeader,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableRow,\n} from './components/Table/Table';\n\n// STYLES\nexport * from './styles';\n\n// PUBLIC PAGES\nexport * from './hooks/public';\nexport * from './components/PublicLayout';\n","/**\n * @file Secure Data Access Utility\n * @package @jmruthers/pace-core\n * @module Utils/SecureDataAccess\n * @since 0.4.0\n *\n * Secure data access utilities that enforce organisation context for all database operations.\n * Prevents data leakage between organisations and ensures proper access validation.\n */\n\nimport type { SupabaseClient } from '@supabase/supabase-js';\n\n// Generic database record type\nexport interface DatabaseRecord {\n id: string;\n organisation_id: string;\n [key: string]: unknown;\n}\n\n// Generic data for insert/update operations\nexport interface DatabaseData {\n [key: string]: unknown;\n}\n\n// Generic filters for queries\nexport interface DatabaseFilters {\n [key: string]: unknown;\n}\n\n// Secure query options\nexport interface SecureQueryOptions {\n table: string;\n select: string;\n organisationId: string;\n filters?: DatabaseFilters;\n orderBy?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface SecureDataAccess {\n // Secure query methods\n secureQuery: <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions) => Promise<T[]>;\n secureSingleQuery: <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions) => Promise<T | null>;\n \n // Secure mutation methods\n secureInsert: <T extends DatabaseRecord = DatabaseRecord>(table: string, data: DatabaseData, organisationId: string) => Promise<T | null>;\n secureUpdate: <T extends DatabaseRecord = DatabaseRecord>(table: string, data: DatabaseData, filters: DatabaseFilters, organisationId: string) => Promise<T | null>;\n secureDelete: (table: string, filters: DatabaseFilters, organisationId: string) => Promise<boolean>;\n \n // Organisation-scoped queries\n queryByOrganisation: <T extends DatabaseRecord = DatabaseRecord>(table: string, select: string, organisationId: string, filters?: DatabaseFilters) => Promise<T[]>;\n \n // Validation helpers\n validateOrganisationContext: (organisationId: string) => void;\n ensureOrganisationColumn: (table: string) => boolean;\n}\n\nexport interface SecureQueryBuilder {\n table: string;\n select: string;\n organisationId: string;\n filters?: DatabaseFilters;\n orderBy?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * Create a secure data access instance\n * @param supabase - Supabase client instance\n * @param organisationId - Current organisation context\n * @param isSuperAdmin - Whether user has super admin privileges\n * @returns Secure data access utilities\n */\nexport const createSecureDataAccess = (\n supabase: SupabaseClient,\n organisationId: string,\n isSuperAdmin: boolean = false\n): SecureDataAccess => {\n \n // Validate organisation context\n const validateOrganisationContext = (orgId: string): void => {\n if (!orgId) {\n throw new Error('Organisation context is required for secure data access');\n }\n \n if (!isSuperAdmin && !orgId) {\n throw new Error('Organisation context is mandatory for non-super admin users');\n }\n };\n\n // Check if table has organisation_id column\n const ensureOrganisationColumn = (table: string): boolean => {\n // This is a simplified check - in production you might want to cache this\n const tablesWithOrganisation = [\n 'event', 'organisation_settings',\n 'rbac_event_app_roles', 'rbac_organisation_roles',\n // SECURITY: Phase 2 additions - complete organisation table mapping\n 'organisation_audit_log', 'organisation_invitations', 'organisation_app_access',\n // SECURITY: Emergency additions for Phase 1 fixes\n 'cake_meal', 'cake_mealtype', 'pace_person', 'pace_member',\n // SECURITY: Phase 3A additions - medical and personal data\n 'medi_profile', 'medi_condition', 'medi_diet', 'medi_action_plan', 'medi_profile_versions',\n 'pace_consent', 'pace_contact', 'pace_id_documents', 'pace_qualifications',\n 'form_responses', 'form_response_values', 'forms',\n // SECURITY: Phase 3B additions - remaining critical tables\n 'invoice', 'line_item', 'credit_balance', 'payment_method',\n 'form_contexts', 'form_field_config', 'form_fields',\n 'cake_delivery', 'cake_diettype', 'cake_diner', 'cake_dish', 'cake_item', \n 'cake_logistics', 'cake_mealplan', 'cake_package', 'cake_recipe', 'cake_supplier', \n 'cake_supply', 'cake_unit', 'event_app_access', 'base_application', 'base_questions'\n ];\n \n return tablesWithOrganisation.includes(table);\n };\n\n // Build secure query with organisation context\n const buildSecureQuery = (options: SecureQueryBuilder) => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n validateOrganisationContext(orgId);\n \n let query = supabase\n .from(table)\n .select(select);\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', orgId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n // Handle qualified column names (e.g., 'users.role')\n const columnName = key.includes('.') ? key.split('.').pop()! : key;\n query = query.eq(columnName, value);\n }\n });\n }\n \n // Add ordering\n if (orderBy) {\n // Only use the column name, not a qualified name\n const orderByColumn = orderBy.split('.').pop();\n if (orderByColumn) {\n query = query.order(orderByColumn);\n }\n }\n \n // Add pagination\n if (limit) {\n query = query.limit(limit);\n }\n \n if (offset) {\n query = query.range(offset, offset + (limit || 10) - 1);\n }\n \n return query;\n };\n\n // Secure query for multiple results\n const secureQuery = async <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions): Promise<T[]> => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n try {\n const query = buildSecureQuery({\n table,\n select,\n organisationId: orgId,\n filters,\n orderBy,\n limit,\n offset\n });\n \n const { data, error } = await query;\n \n if (error) {\n throw error;\n }\n \n // Ensure data is an array and not an error type\n if (Array.isArray(data)) {\n return data as unknown as T[];\n }\n \n return [];\n } catch (error) {\n throw error;\n }\n };\n\n // Secure query for single result\n const secureSingleQuery = async <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions): Promise<T | null> => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n try {\n const query = buildSecureQuery({\n table,\n select,\n organisationId: orgId,\n filters,\n orderBy,\n limit,\n offset\n });\n \n const { data, error } = await query.single();\n \n if (error) {\n if (error.code === 'PGRST116') {\n // No rows returned\n return null;\n }\n throw error;\n }\n \n // Ensure data is not an error type\n if (data && typeof data === 'object' && !('code' in data)) {\n return data as unknown as T;\n }\n \n return null;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure insert with organisation context\n const secureInsert = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n data: DatabaseData, \n organisationId: string\n ): Promise<T | null> => {\n validateOrganisationContext(organisationId);\n \n try {\n const insertData = {\n ...data,\n organisation_id: organisationId\n };\n \n const { data: result, error } = await supabase\n .from(table)\n .insert(insertData)\n .select()\n .single();\n \n if (error) {\n throw error;\n }\n \n return result;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure update with organisation context\n const secureUpdate = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n data: DatabaseData, \n filters: DatabaseFilters, \n organisationId: string\n ): Promise<T | null> => {\n validateOrganisationContext(organisationId);\n \n try {\n let query = supabase\n .from(table)\n .update(data);\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', organisationId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n query = query.eq(key, value);\n }\n });\n }\n \n const { data: result, error } = await query.select().single();\n \n if (error) {\n throw error;\n }\n \n return result;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure delete with organisation context\n const secureDelete = async (\n table: string, \n filters: DatabaseFilters, \n organisationId: string\n ): Promise<boolean> => {\n validateOrganisationContext(organisationId);\n \n try {\n let query = supabase\n .from(table)\n .delete();\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', organisationId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n query = query.eq(key, value);\n }\n });\n }\n \n const { error } = await query;\n \n if (error) {\n throw error;\n }\n \n return true;\n } catch (error) {\n throw error;\n }\n };\n\n // Organisation-scoped query helper\n const queryByOrganisation = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n select: string, \n organisationId: string, \n filters?: DatabaseFilters\n ): Promise<T[]> => {\n return secureQuery<T>({\n table,\n select,\n organisationId,\n filters\n });\n };\n\n return {\n secureQuery,\n secureSingleQuery,\n secureInsert,\n secureUpdate,\n secureDelete,\n queryByOrganisation,\n validateOrganisationContext,\n ensureOrganisationColumn\n };\n};\n\n/**\n * Hook for secure data access\n * @returns Secure data access utilities\n */\nexport const useSecureDataAccess = (): SecureDataAccess => {\n // This would typically get the context from providers\n // For now, we'll create a placeholder that can be used with explicit parameters\n throw new Error('useSecureDataAccess must be used with explicit parameters. Use createSecureDataAccess instead.');\n}; ","/**\n * File upload component with app-segregated storage\n */\n\nimport React, { useCallback, useState } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { validateFileSize, formatFileSize } from '../../utils/storage';\nimport { useFileUpload } from '../../hooks/useStorage';\nimport { Button } from '../Button/Button';\nimport { Progress } from '../Progress/Progress';\nimport { Alert } from '../Alert/Alert';\n\nexport interface FileUploadProps {\n supabase: SupabaseClient;\n appName: string;\n orgId: string;\n onUploadComplete?: (result: { success: boolean; path?: string; error?: string }) => void;\n onUploadStart?: () => void;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport function FileUpload({\n supabase,\n appName,\n orgId,\n onUploadComplete,\n onUploadStart,\n accept = '*/*',\n maxSize,\n multiple = false,\n disabled = false,\n className = '',\n children\n}: FileUploadProps) {\n const [dragActive, setDragActive] = useState(false);\n const [selectedFiles, setSelectedFiles] = useState<File[]>([]);\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n\n const { uploadWithProgress, uploadProgress, isUploading, uploadError } = useFileUpload({\n supabase,\n appName,\n orgId\n });\n\n // Validate files\n const validateFiles = useCallback((files: File[]): string[] => {\n const errors: string[] = [];\n\n files.forEach((file, index) => {\n // Check file size\n const sizeValidation = validateFileSize(file);\n if (!sizeValidation.isValid) {\n errors.push(`File ${index + 1}: ${sizeValidation.error}`);\n }\n\n // Check custom max size\n if (maxSize && file.size > maxSize) {\n const fileMB = Math.round(file.size / (1024 * 1024));\n const maxMB = Math.round(maxSize / (1024 * 1024));\n errors.push(`File ${index + 1}: Size (${fileMB}MB) exceeds limit (${maxMB}MB)`);\n }\n });\n\n return errors;\n }, [maxSize]);\n\n // Handle file selection\n const handleFileSelect = useCallback((files: FileList | null) => {\n if (!files) return;\n\n const fileArray = Array.from(files);\n const errors = validateFiles(fileArray);\n\n setValidationErrors(errors);\n setSelectedFiles(fileArray);\n }, [validateFiles]);\n\n // Handle drag events\n const handleDrag = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.type === 'dragenter' || e.type === 'dragover') {\n setDragActive(true);\n } else if (e.type === 'dragleave') {\n setDragActive(false);\n }\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragActive(false);\n\n if (disabled) return;\n\n const files = e.dataTransfer.files;\n handleFileSelect(files);\n }, [disabled, handleFileSelect]);\n\n // Handle file input change\n const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n handleFileSelect(e.target.files);\n }, [handleFileSelect]);\n\n // Handle upload\n const handleUpload = useCallback(async () => {\n if (selectedFiles.length === 0 || validationErrors.length > 0) return;\n\n onUploadStart?.();\n\n for (const file of selectedFiles) {\n const result = await uploadWithProgress(file);\n onUploadComplete?.(result);\n }\n\n // Reset selection\n setSelectedFiles([]);\n setValidationErrors([]);\n }, [selectedFiles, validationErrors, uploadWithProgress, onUploadComplete, onUploadStart]);\n\n // Handle clear\n const handleClear = useCallback(() => {\n setSelectedFiles([]);\n setValidationErrors([]);\n }, []);\n\n const canUpload = selectedFiles.length > 0 && validationErrors.length === 0 && !isUploading && !disabled;\n\n return (\n <div className={`file-upload ${className}`}>\n {/* Drop zone */}\n <div\n className={`file-upload__dropzone ${\n dragActive ? 'file-upload__dropzone--active' : ''\n } ${disabled ? 'file-upload__dropzone--disabled' : ''}`}\n onDragEnter={handleDrag}\n onDragLeave={handleDrag}\n onDragOver={handleDrag}\n onDrop={handleDrop}\n >\n <input\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleFileInputChange}\n disabled={disabled}\n className=\"file-upload__input\"\n />\n \n {children || (\n <div className=\"file-upload__content\">\n <p className=\"file-upload__text\">\n {dragActive ? 'Drop files here' : 'Drag and drop files here or click to select'}\n </p>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={disabled}\n onClick={() => (document.querySelector('.file-upload__input') as HTMLInputElement)?.click()}\n >\n Select Files\n </Button>\n </div>\n )}\n </div>\n\n {/* Selected files */}\n {selectedFiles.length > 0 && (\n <div className=\"file-upload__files\">\n <h4 className=\"file-upload__files-title\">Selected Files:</h4>\n <ul className=\"file-upload__files-list\">\n {selectedFiles.map((file, index) => (\n <li key={index} className=\"file-upload__file-item\">\n <span className=\"file-upload__file-name\">{file.name}</span>\n <span className=\"file-upload__file-size\">{formatFileSize(file.size)}</span>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Validation errors */}\n {validationErrors.length > 0 && (\n <Alert variant=\"destructive\" className=\"file-upload__errors\">\n <ul>\n {validationErrors.map((error, index) => (\n <li key={index}>{error}</li>\n ))}\n </ul>\n </Alert>\n )}\n\n {/* Upload progress */}\n {isUploading && (\n <div className=\"file-upload__progress\">\n <Progress value={uploadProgress} max={100} />\n <p className=\"file-upload__progress-text\">\n Uploading... {uploadProgress}%\n </p>\n </div>\n )}\n\n {/* Upload error */}\n {uploadError && (\n <Alert variant=\"destructive\" className=\"file-upload__error\">\n {uploadError}\n </Alert>\n )}\n\n {/* Actions */}\n {selectedFiles.length > 0 && (\n <div className=\"file-upload__actions\">\n <Button\n onClick={handleUpload}\n disabled={!canUpload}\n className=\"file-upload__upload-btn\"\n >\n {isUploading ? 'Uploading...' : `Upload ${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}`}\n </Button>\n <Button\n variant=\"outline\"\n onClick={handleClear}\n disabled={isUploading}\n className=\"file-upload__clear-btn\"\n >\n Clear\n </Button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["organisationId"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/secureDataAccess.ts","../src/components/FileUpload/FileUpload.tsx"],"sourcesContent":["/**\n * @file Complete Component Library Export\n * @package @jmruthers/pace-core\n * @module Core\n * @since 0.1.0\n * \n * This file exports the primary components, hooks, and utilities from the PACE Core library.\n * It is the main entry point for developers using the library.\n * \n * @example\n * // Import common components\n * import { Button, Card, useUnifiedAuth } from '@jmruthers/pace-core';\n * \n * // For specialized components, use the complete library import:\n * import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';\n */\n\n// AUTHENTICATION & AUTHORIZATION\nexport { UnifiedAuthProvider, useUnifiedAuth } from './providers/UnifiedAuthProvider';\nexport type { UnifiedAuthProviderProps, UnifiedAuthContextType, UserEventAccess } from './providers/UnifiedAuthProvider';\nexport { EventProvider, useEvents } from './providers/EventProvider';\nexport type { EventProviderProps, EventContextType } from './providers/EventProvider';\nexport { OrganisationProvider, useOrganisations } from './providers/OrganisationProvider';\nexport type { \n Organisation, \n OrganisationMembership, \n OrganisationContextType, \n OrganisationProviderProps,\n OrganisationSecurityError \n} from './types/organisation';\n\n// INACTIVITY TRACKING\nexport { InactivityWarningModal } from './components/InactivityWarningModal/InactivityWarningModal';\nexport type { InactivityWarningModalProps } from './components/InactivityWarningModal/InactivityWarningModal';\nexport { useInactivityTracker } from './hooks/useInactivityTracker';\nexport type { UseInactivityTrackerOptions, UseInactivityTrackerReturn } from './hooks/useInactivityTracker';\n\n// RBAC SYSTEM - Consolidated RBAC module\nexport * from './rbac';\n\n// BASIC UI COMPONENTS\nexport { Button } from './components/Button/Button';\nexport type { ButtonProps } from './components/Button/Button';\n\nexport { \n Card, \n CardHeader, \n CardFooter, \n CardTitle, \n CardDescription, \n CardContent,\n CardActions\n} from './components/Card/Card';\nexport type { CardProps } from './components/Card/Card';\n\nexport { Input } from './components/Input/Input';\nexport type { InputProps } from './components/Input/Input';\nexport { Label } from './components/Label/Label';\nexport type { LabelProps } from './components/Label/Label';\n\nexport { Alert, AlertTitle, AlertDescription } from './components/Alert/Alert';\nexport { Avatar, AvatarImage, AvatarFallback } from './components/Avatar/Avatar';\n\nexport { Checkbox } from './components/Checkbox/Checkbox';\nexport { Progress } from './components/Progress/Progress';\n\n// ADVANCED UI COMPONENTS\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogBody,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n} from './components/Dialog/Dialog';\n\n// Dropdown Menu exports\n// DropdownMenu components have been merged into Select components\n\n// Select exports\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n} from './components/Select';\n\n// Modal functionality is provided by Dialog components\n\nexport {\n Toast,\n Toaster,\n ToastAction,\n ToastProvider,\n ToastViewport,\n ToastTitle,\n ToastDescription,\n ToastClose,\n} from './components/Toast/Toast';\nexport { useToast } from './hooks/useToast';\nexport type { ToastActionElement, ToastProps } from './components/Toast/Toast';\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from './components/Tooltip/Tooltip';\n\n// DATA DISPLAY COMPONENTS\nexport {\n DataTable,\n type DataTableProps,\n type DataTableColumn,\n type DataTableAction,\n type DataTableToolbarButton,\n type AggregateConfig,\n type EmptyStateConfig,\n type GetRowId\n} from './components/DataTable';\n\n// Re-export types from DataTable types\nexport type { DataRecord } from './components/DataTable/types';\n\n// FORM COMPONENTS\nexport { Form } from './components/Form/Form';\nexport { LoginForm } from './components/LoginForm/LoginForm';\nexport type { LoginFormProps } from './components/LoginForm/LoginForm';\n\n// LAYOUT COMPONENTS\nexport { Header } from './components/Header/Header';\nexport { Footer } from './components/Footer/Footer';\nexport type { FooterProps } from './components/Footer/Footer';\n\n// NAVIGATION COMPONENTS\nexport { NavigationMenu } from './components/NavigationMenu/NavigationMenu';\nexport type { NavigationMenuProps, NavigationItem } from './components/NavigationMenu/types';\nexport { UserMenu } from './components/UserMenu/UserMenu';\nexport type { UserMenuProps } from './components/UserMenu/UserMenu';\n\n// Reusable Page/Layout Components\nexport { PaceAppLayout } from './components/PaceAppLayout/PaceAppLayout';\nexport type { PaceAppLayoutProps } from './components/PaceAppLayout/PaceAppLayout';\nexport { PaceLoginPage } from './components/PaceLoginPage/PaceLoginPage';\nexport type { PaceLoginPageProps } from './components/PaceLoginPage/PaceLoginPage';\n\n// UTILITY COMPONENTS\nexport { ErrorBoundary } from './components/ErrorBoundary/ErrorBoundary';\nexport { LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner';\n\n// EVENT MANAGEMENT\nexport { EventSelector } from './components/EventSelector/EventSelector';\n\n// ORGANISATION MANAGEMENT\nexport { OrganisationSelector } from './components/OrganisationSelector/OrganisationSelector';\nexport { useOrganisationPermissions } from './hooks/useOrganisationPermissions';\nexport { useOrganisationSecurity } from './hooks/useOrganisationSecurity';\nexport { createSecureDataAccess } from './utils/secureDataAccess';\n\n// TYPES\nexport type { UserProfile } from './types/organisation';\n\n// AUTHENTICATION FORMS\nexport { PasswordResetForm } from './components/PasswordReset/PasswordResetForm';\nexport { PasswordChangeForm } from './components/PasswordReset/PasswordChangeForm';\n\n// UTILS & HOOKS\nexport { useAppConfig } from './hooks/useAppConfig';\nexport { cn } from './utils/cn';\nexport { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/appConfig';\n\n// FORMATTING UTILITIES\nexport { \n formatDate, \n formatCurrency, \n formatNumber,\n formatPercent,\n formatCompactNumber,\n formatFileSize\n} from './utils/formatting';\n\n// STORAGE UTILITIES\nexport { FileUpload } from './components/FileUpload/FileUpload';\nexport type { FileUploadProps } from './components/FileUpload/FileUpload';\nexport { useStorage, useFileUpload } from './hooks/useStorage';\nexport * from './utils/storage';\n\n// Table components\nexport {\n Table,\n TableHeader,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableRow,\n} from './components/Table/Table';\n\n// STYLES\nexport * from './styles';\n\n// PUBLIC PAGES\nexport * from './hooks/public';\nexport * from './components/PublicLayout';\n","/**\n * @file Secure Data Access Utility\n * @package @jmruthers/pace-core\n * @module Utils/SecureDataAccess\n * @since 0.4.0\n *\n * Secure data access utilities that enforce organisation context for all database operations.\n * Prevents data leakage between organisations and ensures proper access validation.\n */\n\nimport type { SupabaseClient } from '@supabase/supabase-js';\n\n// Generic database record type\nexport interface DatabaseRecord {\n id: string;\n organisation_id: string;\n [key: string]: unknown;\n}\n\n// Generic data for insert/update operations\nexport interface DatabaseData {\n [key: string]: unknown;\n}\n\n// Generic filters for queries\nexport interface DatabaseFilters {\n [key: string]: unknown;\n}\n\n// Secure query options\nexport interface SecureQueryOptions {\n table: string;\n select: string;\n organisationId: string;\n filters?: DatabaseFilters;\n orderBy?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface SecureDataAccess {\n // Secure query methods\n secureQuery: <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions) => Promise<T[]>;\n secureSingleQuery: <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions) => Promise<T | null>;\n \n // Secure mutation methods\n secureInsert: <T extends DatabaseRecord = DatabaseRecord>(table: string, data: DatabaseData, organisationId: string) => Promise<T | null>;\n secureUpdate: <T extends DatabaseRecord = DatabaseRecord>(table: string, data: DatabaseData, filters: DatabaseFilters, organisationId: string) => Promise<T | null>;\n secureDelete: (table: string, filters: DatabaseFilters, organisationId: string) => Promise<boolean>;\n \n // Organisation-scoped queries\n queryByOrganisation: <T extends DatabaseRecord = DatabaseRecord>(table: string, select: string, organisationId: string, filters?: DatabaseFilters) => Promise<T[]>;\n \n // Validation helpers\n validateOrganisationContext: (organisationId: string) => void;\n ensureOrganisationColumn: (table: string) => boolean;\n}\n\nexport interface SecureQueryBuilder {\n table: string;\n select: string;\n organisationId: string;\n filters?: DatabaseFilters;\n orderBy?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * Create a secure data access instance\n * @param supabase - Supabase client instance\n * @param organisationId - Current organisation context\n * @param isSuperAdmin - Whether user has super admin privileges\n * @returns Secure data access utilities\n */\nexport const createSecureDataAccess = (\n supabase: SupabaseClient,\n organisationId: string,\n isSuperAdmin: boolean = false\n): SecureDataAccess => {\n \n // Validate organisation context\n const validateOrganisationContext = (orgId: string): void => {\n if (!orgId) {\n throw new Error('Organisation context is required for secure data access');\n }\n \n if (!isSuperAdmin && !orgId) {\n throw new Error('Organisation context is mandatory for non-super admin users');\n }\n };\n\n // Check if table has organisation_id column\n const ensureOrganisationColumn = (table: string): boolean => {\n // This is a simplified check - in production you might want to cache this\n const tablesWithOrganisation = [\n 'event', 'organisation_settings',\n 'rbac_event_app_roles', 'rbac_organisation_roles',\n // SECURITY: Phase 2 additions - complete organisation table mapping\n 'organisation_audit_log', 'organisation_invitations', 'organisation_app_access',\n // SECURITY: Emergency additions for Phase 1 fixes\n 'cake_meal', 'cake_mealtype', 'pace_person', 'pace_member',\n // SECURITY: Phase 3A additions - medical and personal data\n 'medi_profile', 'medi_condition', 'medi_diet', 'medi_action_plan', 'medi_profile_versions',\n 'pace_consent', 'pace_contact', 'pace_id_documents', 'pace_qualifications',\n 'form_responses', 'form_response_values', 'forms',\n // SECURITY: Phase 3B additions - remaining critical tables\n 'invoice', 'line_item', 'credit_balance', 'payment_method',\n 'form_contexts', 'form_field_config', 'form_fields',\n 'cake_delivery', 'cake_diettype', 'cake_diner', 'cake_dish', 'cake_item', \n 'cake_logistics', 'cake_mealplan', 'cake_package', 'cake_recipe', 'cake_supplier', \n 'cake_supply', 'cake_unit', 'event_app_access', 'base_application', 'base_questions'\n ];\n \n return tablesWithOrganisation.includes(table);\n };\n\n // Build secure query with organisation context\n const buildSecureQuery = (options: SecureQueryBuilder) => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n validateOrganisationContext(orgId);\n \n let query = supabase\n .from(table)\n .select(select);\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', orgId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n // Handle qualified column names (e.g., 'users.role')\n const columnName = key.includes('.') ? key.split('.').pop()! : key;\n query = query.eq(columnName, value);\n }\n });\n }\n \n // Add ordering\n if (orderBy) {\n // Only use the column name, not a qualified name\n const orderByColumn = orderBy.split('.').pop();\n if (orderByColumn) {\n query = query.order(orderByColumn);\n }\n }\n \n // Add pagination\n if (limit) {\n query = query.limit(limit);\n }\n \n if (offset) {\n query = query.range(offset, offset + (limit || 10) - 1);\n }\n \n return query;\n };\n\n // Secure query for multiple results\n const secureQuery = async <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions): Promise<T[]> => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n try {\n const query = buildSecureQuery({\n table,\n select,\n organisationId: orgId,\n filters,\n orderBy,\n limit,\n offset\n });\n \n const { data, error } = await query;\n \n if (error) {\n throw error;\n }\n \n // Ensure data is an array and not an error type\n if (Array.isArray(data)) {\n return data as unknown as T[];\n }\n \n return [];\n } catch (error) {\n throw error;\n }\n };\n\n // Secure query for single result\n const secureSingleQuery = async <T extends DatabaseRecord = DatabaseRecord>(options: SecureQueryOptions): Promise<T | null> => {\n const { table, select, organisationId: orgId, filters, orderBy, limit, offset } = options;\n \n try {\n const query = buildSecureQuery({\n table,\n select,\n organisationId: orgId,\n filters,\n orderBy,\n limit,\n offset\n });\n \n const { data, error } = await query.single();\n \n if (error) {\n if (error.code === 'PGRST116') {\n // No rows returned\n return null;\n }\n throw error;\n }\n \n // Ensure data is not an error type\n if (data && typeof data === 'object' && !('code' in data)) {\n return data as unknown as T;\n }\n \n return null;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure insert with organisation context\n const secureInsert = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n data: DatabaseData, \n organisationId: string\n ): Promise<T | null> => {\n validateOrganisationContext(organisationId);\n \n try {\n const insertData = {\n ...data,\n organisation_id: organisationId\n };\n \n const { data: result, error } = await supabase\n .from(table)\n .insert(insertData)\n .select()\n .single();\n \n if (error) {\n throw error;\n }\n \n return result;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure update with organisation context\n const secureUpdate = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n data: DatabaseData, \n filters: DatabaseFilters, \n organisationId: string\n ): Promise<T | null> => {\n validateOrganisationContext(organisationId);\n \n try {\n let query = supabase\n .from(table)\n .update(data);\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', organisationId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n query = query.eq(key, value);\n }\n });\n }\n \n const { data: result, error } = await query.select().single();\n \n if (error) {\n throw error;\n }\n \n return result;\n } catch (error) {\n throw error;\n }\n };\n\n // Secure delete with organisation context\n const secureDelete = async (\n table: string, \n filters: DatabaseFilters, \n organisationId: string\n ): Promise<boolean> => {\n validateOrganisationContext(organisationId);\n \n try {\n let query = supabase\n .from(table)\n .delete();\n \n // Add organisation filter (unless super admin)\n if (!isSuperAdmin && ensureOrganisationColumn(table)) {\n query = query.eq('organisation_id', organisationId);\n }\n \n // Add additional filters\n if (filters) {\n Object.entries(filters).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n query = query.eq(key, value);\n }\n });\n }\n \n const { error } = await query;\n \n if (error) {\n throw error;\n }\n \n return true;\n } catch (error) {\n throw error;\n }\n };\n\n // Organisation-scoped query helper\n const queryByOrganisation = async <T extends DatabaseRecord = DatabaseRecord>(\n table: string, \n select: string, \n organisationId: string, \n filters?: DatabaseFilters\n ): Promise<T[]> => {\n return secureQuery<T>({\n table,\n select,\n organisationId,\n filters\n });\n };\n\n return {\n secureQuery,\n secureSingleQuery,\n secureInsert,\n secureUpdate,\n secureDelete,\n queryByOrganisation,\n validateOrganisationContext,\n ensureOrganisationColumn\n };\n};\n\n/**\n * Hook for secure data access\n * @returns Secure data access utilities\n */\nexport const useSecureDataAccess = (): SecureDataAccess => {\n // This would typically get the context from providers\n // For now, we'll create a placeholder that can be used with explicit parameters\n throw new Error('useSecureDataAccess must be used with explicit parameters. Use createSecureDataAccess instead.');\n}; ","/**\n * File upload component with app-segregated storage\n */\n\nimport React, { useCallback, useState } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { validateFileSize, formatFileSize } from '../../utils/storage';\nimport { useFileUpload } from '../../hooks/useStorage';\nimport { Button } from '../Button/Button';\nimport { Progress } from '../Progress/Progress';\nimport { Alert } from '../Alert/Alert';\n\nexport interface FileUploadProps {\n supabase: SupabaseClient;\n appName: string;\n orgId: string;\n onUploadComplete?: (result: { success: boolean; path?: string; error?: string }) => void;\n onUploadStart?: () => void;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport function FileUpload({\n supabase,\n appName,\n orgId,\n onUploadComplete,\n onUploadStart,\n accept = '*/*',\n maxSize,\n multiple = false,\n disabled = false,\n className = '',\n children\n}: FileUploadProps) {\n const [dragActive, setDragActive] = useState(false);\n const [selectedFiles, setSelectedFiles] = useState<File[]>([]);\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n\n const { uploadWithProgress, uploadProgress, isUploading, uploadError } = useFileUpload({\n supabase,\n appName,\n orgId\n });\n\n // Validate files\n const validateFiles = useCallback((files: File[]): string[] => {\n const errors: string[] = [];\n\n files.forEach((file, index) => {\n // Check file size\n const sizeValidation = validateFileSize(file);\n if (!sizeValidation.isValid) {\n errors.push(`File ${index + 1}: ${sizeValidation.error}`);\n }\n\n // Check custom max size\n if (maxSize && file.size > maxSize) {\n const fileMB = Math.round(file.size / (1024 * 1024));\n const maxMB = Math.round(maxSize / (1024 * 1024));\n errors.push(`File ${index + 1}: Size (${fileMB}MB) exceeds limit (${maxMB}MB)`);\n }\n });\n\n return errors;\n }, [maxSize]);\n\n // Handle file selection\n const handleFileSelect = useCallback((files: FileList | null) => {\n if (!files) return;\n\n const fileArray = Array.from(files);\n const errors = validateFiles(fileArray);\n\n setValidationErrors(errors);\n setSelectedFiles(fileArray);\n }, [validateFiles]);\n\n // Handle drag events\n const handleDrag = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.type === 'dragenter' || e.type === 'dragover') {\n setDragActive(true);\n } else if (e.type === 'dragleave') {\n setDragActive(false);\n }\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragActive(false);\n\n if (disabled) return;\n\n const files = e.dataTransfer.files;\n handleFileSelect(files);\n }, [disabled, handleFileSelect]);\n\n // Handle file input change\n const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n handleFileSelect(e.target.files);\n }, [handleFileSelect]);\n\n // Handle upload\n const handleUpload = useCallback(async () => {\n if (selectedFiles.length === 0 || validationErrors.length > 0) return;\n\n onUploadStart?.();\n\n for (const file of selectedFiles) {\n const result = await uploadWithProgress(file);\n onUploadComplete?.(result);\n }\n\n // Reset selection\n setSelectedFiles([]);\n setValidationErrors([]);\n }, [selectedFiles, validationErrors, uploadWithProgress, onUploadComplete, onUploadStart]);\n\n // Handle clear\n const handleClear = useCallback(() => {\n setSelectedFiles([]);\n setValidationErrors([]);\n }, []);\n\n const canUpload = selectedFiles.length > 0 && validationErrors.length === 0 && !isUploading && !disabled;\n\n return (\n <div className={`file-upload ${className}`}>\n {/* Drop zone */}\n <div\n className={`file-upload__dropzone ${\n dragActive ? 'file-upload__dropzone--active' : ''\n } ${disabled ? 'file-upload__dropzone--disabled' : ''}`}\n onDragEnter={handleDrag}\n onDragLeave={handleDrag}\n onDragOver={handleDrag}\n onDrop={handleDrop}\n >\n <input\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleFileInputChange}\n disabled={disabled}\n className=\"file-upload__input\"\n />\n \n {children || (\n <div className=\"file-upload__content\">\n <p className=\"file-upload__text\">\n {dragActive ? 'Drop files here' : 'Drag and drop files here or click to select'}\n </p>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={disabled}\n onClick={() => (document.querySelector('.file-upload__input') as HTMLInputElement)?.click()}\n >\n Select Files\n </Button>\n </div>\n )}\n </div>\n\n {/* Selected files */}\n {selectedFiles.length > 0 && (\n <div className=\"file-upload__files\">\n <h4 className=\"file-upload__files-title\">Selected Files:</h4>\n <ul className=\"file-upload__files-list\">\n {selectedFiles.map((file, index) => (\n <li key={index} className=\"file-upload__file-item\">\n <span className=\"file-upload__file-name\">{file.name}</span>\n <span className=\"file-upload__file-size\">{formatFileSize(file.size)}</span>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Validation errors */}\n {validationErrors.length > 0 && (\n <Alert variant=\"destructive\" className=\"file-upload__errors\">\n <ul>\n {validationErrors.map((error, index) => (\n <li key={index}>{error}</li>\n ))}\n </ul>\n </Alert>\n )}\n\n {/* Upload progress */}\n {isUploading && (\n <div className=\"file-upload__progress\">\n <Progress value={uploadProgress} max={100} />\n <p className=\"file-upload__progress-text\">\n Uploading... {uploadProgress}%\n </p>\n </div>\n )}\n\n {/* Upload error */}\n {uploadError && (\n <Alert variant=\"destructive\" className=\"file-upload__error\">\n {uploadError}\n </Alert>\n )}\n\n {/* Actions */}\n {selectedFiles.length > 0 && (\n <div className=\"file-upload__actions\">\n <Button\n onClick={handleUpload}\n disabled={!canUpload}\n className=\"file-upload__upload-btn\"\n >\n {isUploading ? 'Uploading...' : `Upload ${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}`}\n </Button>\n <Button\n variant=\"outline\"\n onClick={handleClear}\n disabled={isUploading}\n className=\"file-upload__clear-btn\"\n >\n Clear\n </Button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["organisationId","formatFileSize"]}
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AppConfig, S as SecureDataAccess, a as cn, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './appConfig-DjpeG6P-.js';
1
+ export { A as AppConfig, S as SecureDataAccess, a as cn, j as formatCompactNumber, e as formatCurrency, f as formatDate, k as formatFileSize, h as formatNumber, i as formatPercent, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './formatting-BfDeV-ja.js';
2
2
  import { z } from 'zod';
3
3
  export { u as useComponentPerformance } from './useComponentPerformance-DE9l5RkL.js';
4
4
  import * as date_fns from 'date-fns';
@@ -564,34 +564,6 @@ declare function validateDeviceFingerprint(storedFingerprint: DeviceFingerprint,
564
564
  reasons: string[];
565
565
  };
566
566
 
567
- /**
568
- * Utility functions for formatting data in the application
569
- */
570
- /**
571
- * Format a date as a readable string
572
- */
573
- declare function formatDate(date: Date | string | number): string;
574
- /**
575
- * Format a number as a currency
576
- */
577
- declare function formatCurrency(value: number, currencyCode?: string, locale?: string): string;
578
- /**
579
- * Format a number with custom options
580
- */
581
- declare function formatNumber(value: number, options?: Intl.NumberFormatOptions, locale?: string): string;
582
- /**
583
- * Format a number as a percentage
584
- */
585
- declare function formatPercent(value: number, locale?: string, decimals?: number): string;
586
- /**
587
- * Format a large number with abbreviations (K, M, B)
588
- */
589
- declare function formatCompactNumber(value: number, locale?: string): string;
590
- /**
591
- * Format a file size in bytes to a human-readable string
592
- */
593
- declare function formatFileSize(bytes: number): string;
594
-
595
567
  /**
596
568
  * @file Organisation Context Utility
597
569
  * @package @jmruthers/pace-core
@@ -635,4 +607,4 @@ declare function getOrganisationContext(supabase: SupabaseClient): Promise<strin
635
607
  */
636
608
  declare function isOrganisationContextAvailable(supabase: SupabaseClient): Promise<boolean>;
637
609
 
638
- export { CSP_DIRECTIVES, DebugLogger, LazyDataTable, PERFORMANCE_BUDGETS, PERFORMANCE_THRESHOLDS, type PerformanceMetrics$1 as PerformanceMetrics, PermissionType, RateLimiter, type SanitizationOptions, type SecurityEvent$1 as SecurityEvent, auditLog, auditLogger, bundleAnalyzer, clearOrganisationContext, combineSchemas, createLazyComponent, createLazyUtility, createPerformanceBenchmark, deepMerge, emailSchema, formatCompactNumber, formatCurrency, formatDate, formatFileSize, formatNumber, formatPercent, generateCSPHeader, generateDeviceFingerprint, getAppNameFromBuildTime, getAppNameFromEnvironment, getAppNameFromGlobal, getAppNameFromPackageJson, getCurrentAppNameWithFallback, getOrganisationContext, getSecurityHeaders, hasAllPermissions, hasAnyPermission, hasPermission, isEmpty, isObject, isOrganisationContextAvailable, isStrongPassword, isValidDate, isValidEmail, isValidUrl, isWithinRange, lazyCSVUtils, lazyChartUtils, lazyDateUtils, lazyFormUtils, lazyLodash, loadCSVUtils, loadChartUtils, loadDateUtils, loadFormUtils, loadLodash, logAuditEvent, logAuthEvent, logPermissionEvent, logSecurityEvent, matchesPattern, measureRenderPerformance, nameSchema, parsePermission, passwordSchema, performanceBudgetMonitor, phoneSchema, pickSchema, sanitizeEmail, sanitizeFileName, sanitizeFormData, sanitizePhoneNumber, sanitizeSqlInput, sanitizeUrl, sanitizeUserInput, sanitizeUserInput_deprecated, securityMonitor, setOrganisationContext, setRBACAppName, trackDynamicImport, transformPermissionMapToBoolean, urlSchema, useSessionTracking, usernameSchema, validateDeviceFingerprint, validateImportPattern, validateSecurityHeaders, validateUserInput };
610
+ export { CSP_DIRECTIVES, DebugLogger, LazyDataTable, PERFORMANCE_BUDGETS, PERFORMANCE_THRESHOLDS, type PerformanceMetrics$1 as PerformanceMetrics, PermissionType, RateLimiter, type SanitizationOptions, type SecurityEvent$1 as SecurityEvent, auditLog, auditLogger, bundleAnalyzer, clearOrganisationContext, combineSchemas, createLazyComponent, createLazyUtility, createPerformanceBenchmark, deepMerge, emailSchema, generateCSPHeader, generateDeviceFingerprint, getAppNameFromBuildTime, getAppNameFromEnvironment, getAppNameFromGlobal, getAppNameFromPackageJson, getCurrentAppNameWithFallback, getOrganisationContext, getSecurityHeaders, hasAllPermissions, hasAnyPermission, hasPermission, isEmpty, isObject, isOrganisationContextAvailable, isStrongPassword, isValidDate, isValidEmail, isValidUrl, isWithinRange, lazyCSVUtils, lazyChartUtils, lazyDateUtils, lazyFormUtils, lazyLodash, loadCSVUtils, loadChartUtils, loadDateUtils, loadFormUtils, loadLodash, logAuditEvent, logAuthEvent, logPermissionEvent, logSecurityEvent, matchesPattern, measureRenderPerformance, nameSchema, parsePermission, passwordSchema, performanceBudgetMonitor, phoneSchema, pickSchema, sanitizeEmail, sanitizeFileName, sanitizeFormData, sanitizePhoneNumber, sanitizeSqlInput, sanitizeUrl, sanitizeUserInput, sanitizeUserInput_deprecated, securityMonitor, setOrganisationContext, setRBACAppName, trackDynamicImport, transformPermissionMapToBoolean, urlSchema, useSessionTracking, usernameSchema, validateDeviceFingerprint, validateImportPattern, validateSecurityHeaders, validateUserInput };
package/dist/utils.js CHANGED
@@ -1,9 +1,15 @@
1
1
  import {
2
+ formatCompactNumber,
3
+ formatCurrency,
4
+ formatDate,
5
+ formatFileSize,
6
+ formatNumber,
7
+ formatPercent,
2
8
  getAppConfig,
3
9
  getCurrentAppId,
4
10
  getCurrentAppName,
5
11
  setAppConfig
6
- } from "./chunk-W66AZIOH.js";
12
+ } from "./chunk-4BWGRQBG.js";
7
13
  import {
8
14
  LoadingSpinner
9
15
  } from "./chunk-CDQ3PX7L.js";
@@ -995,45 +1001,6 @@ function generateFallbackFingerprint() {
995
1001
  };
996
1002
  }
997
1003
 
998
- // src/utils/formatting.ts
999
- function formatDate(date) {
1000
- const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
1001
- return dateObj.toLocaleDateString(void 0, {
1002
- year: "numeric",
1003
- month: "short",
1004
- day: "numeric"
1005
- });
1006
- }
1007
- function formatCurrency(value, currencyCode = "USD", locale = "en-US") {
1008
- return new Intl.NumberFormat(locale, {
1009
- style: "currency",
1010
- currency: currencyCode
1011
- }).format(value);
1012
- }
1013
- function formatNumber(value, options = {}, locale = "en-US") {
1014
- return new Intl.NumberFormat(locale, options).format(value);
1015
- }
1016
- function formatPercent(value, locale = "en-US", decimals = 1) {
1017
- return new Intl.NumberFormat(locale, {
1018
- style: "percent",
1019
- minimumFractionDigits: decimals,
1020
- maximumFractionDigits: decimals
1021
- }).format(value / 100);
1022
- }
1023
- function formatCompactNumber(value, locale = "en-US") {
1024
- return new Intl.NumberFormat(locale, {
1025
- notation: "compact",
1026
- compactDisplay: "short"
1027
- }).format(value);
1028
- }
1029
- function formatFileSize(bytes) {
1030
- if (bytes === 0) return "0 Bytes";
1031
- const k = 1024;
1032
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
1033
- const i = Math.floor(Math.log(bytes) / Math.log(k));
1034
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
1035
- }
1036
-
1037
1004
  // src/utils/index.ts
1038
1005
  init_organisationContext();
1039
1006
  export {