@marinoscar/platform-web 0.1.0-next.16 → 0.1.0-next.18
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.
- package/CHANGELOG.md +20 -0
- package/README.md +3 -2
- package/dist/ai/headless/schema-presets.js +1 -1
- package/dist/ai/headless/schema-presets.js.map +1 -1
- package/dist/ai/ui/AiConfigPage.d.ts.map +1 -1
- package/dist/ai/ui/AiConfigPage.js +3 -2
- package/dist/ai/ui/AiConfigPage.js.map +1 -1
- package/dist/ai/ui/AiModelsPage.d.ts.map +1 -1
- package/dist/ai/ui/AiModelsPage.js +4 -2
- package/dist/ai/ui/AiModelsPage.js.map +1 -1
- package/dist/ai/ui/OrgAiKeysPage.d.ts.map +1 -1
- package/dist/ai/ui/OrgAiKeysPage.js +3 -2
- package/dist/ai/ui/OrgAiKeysPage.js.map +1 -1
- package/dist/ai/ui/admin/AiGenericProviderCard.d.ts.map +1 -1
- package/dist/ai/ui/admin/AiGenericProviderCard.js +2 -0
- package/dist/ai/ui/admin/AiGenericProviderCard.js.map +1 -1
- package/dist/ai/ui/admin/AiProviderCard.d.ts.map +1 -1
- package/dist/ai/ui/admin/AiProviderCard.js +2 -0
- package/dist/ai/ui/admin/AiProviderCard.js.map +1 -1
- package/dist/ai/ui/admin/AiProviderKeyActions.d.ts.map +1 -1
- package/dist/ai/ui/admin/AiProviderKeyActions.js +2 -1
- package/dist/ai/ui/admin/AiProviderKeyActions.js.map +1 -1
- package/dist/ai/ui/admin/aiModelColumns.d.ts.map +1 -1
- package/dist/ai/ui/admin/aiModelColumns.js +2 -1
- package/dist/ai/ui/admin/aiModelColumns.js.map +1 -1
- package/dist/ai/ui/user/UserAiKeyCard.d.ts.map +1 -1
- package/dist/ai/ui/user/UserAiKeyCard.js +6 -4
- package/dist/ai/ui/user/UserAiKeyCard.js.map +1 -1
- package/dist/android-app/ui/AndroidAppPage.d.ts.map +1 -1
- package/dist/android-app/ui/AndroidAppPage.js +3 -2
- package/dist/android-app/ui/AndroidAppPage.js.map +1 -1
- package/dist/core/host.d.ts +2 -2
- package/dist/core/host.js +2 -2
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/time-zone/format.d.ts +135 -0
- package/dist/core/time-zone/format.d.ts.map +1 -0
- package/dist/core/time-zone/format.js +228 -0
- package/dist/core/time-zone/format.js.map +1 -0
- package/dist/core/time-zone/store.d.ts +93 -0
- package/dist/core/time-zone/store.d.ts.map +1 -0
- package/dist/core/time-zone/store.js +170 -0
- package/dist/core/time-zone/store.js.map +1 -0
- package/dist/credentials/headless/saved-secret.d.ts +1 -1
- package/dist/credentials/headless/saved-secret.d.ts.map +1 -1
- package/dist/credentials/headless/saved-secret.js +2 -1
- package/dist/credentials/headless/saved-secret.js.map +1 -1
- package/dist/credentials/ui/secret-field.d.ts +1 -1
- package/dist/credentials/ui/secret-field.d.ts.map +1 -1
- package/dist/credentials/ui/secret-field.js +2 -0
- package/dist/credentials/ui/secret-field.js.map +1 -1
- package/dist/db-backup/internal/format.d.ts +4 -1
- package/dist/db-backup/internal/format.d.ts.map +1 -1
- package/dist/db-backup/internal/format.js +6 -2
- package/dist/db-backup/internal/format.js.map +1 -1
- package/dist/db-backup/ui/DbBackupConfigPanel.d.ts.map +1 -1
- package/dist/db-backup/ui/DbBackupConfigPanel.js +4 -1
- package/dist/db-backup/ui/DbBackupConfigPanel.js.map +1 -1
- package/dist/db-backup/ui/DbBackupPage.d.ts.map +1 -1
- package/dist/db-backup/ui/DbBackupPage.js +7 -4
- package/dist/db-backup/ui/DbBackupPage.js.map +1 -1
- package/dist/db-backup/ui/DbBackupRestoreDialog.d.ts.map +1 -1
- package/dist/db-backup/ui/DbBackupRestoreDialog.js +4 -1
- package/dist/db-backup/ui/DbBackupRestoreDialog.js.map +1 -1
- package/dist/email/ui/EmailSettingsPage.d.ts.map +1 -1
- package/dist/email/ui/EmailSettingsPage.js +3 -2
- package/dist/email/ui/EmailSettingsPage.js.map +1 -1
- package/dist/email/ui/SesTransportPanel.d.ts.map +1 -1
- package/dist/email/ui/SesTransportPanel.js +3 -1
- package/dist/email/ui/SesTransportPanel.js.map +1 -1
- package/dist/email/ui/SmtpTransportPanel.d.ts.map +1 -1
- package/dist/email/ui/SmtpTransportPanel.js +3 -1
- package/dist/email/ui/SmtpTransportPanel.js.map +1 -1
- package/dist/exports/ui/ExportsList.d.ts.map +1 -1
- package/dist/exports/ui/ExportsList.js +5 -2
- package/dist/exports/ui/ExportsList.js.map +1 -1
- package/dist/host/ui/about-page.d.ts.map +1 -1
- package/dist/host/ui/about-page.js +7 -5
- package/dist/host/ui/about-page.js.map +1 -1
- package/dist/host/ui/maintenance-page.d.ts.map +1 -1
- package/dist/host/ui/maintenance-page.js +3 -2
- package/dist/host/ui/maintenance-page.js.map +1 -1
- package/dist/identity/index.d.ts +1 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +3 -2
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/ui/org/OrgInvitesPanel.d.ts.map +1 -1
- package/dist/identity/ui/org/OrgInvitesPanel.js +2 -0
- package/dist/identity/ui/org/OrgInvitesPanel.js.map +1 -1
- package/dist/identity/ui/org/OrgMembersPanel.d.ts.map +1 -1
- package/dist/identity/ui/org/OrgMembersPanel.js +2 -0
- package/dist/identity/ui/org/OrgMembersPanel.js.map +1 -1
- package/dist/identity/ui/org/orgLabels.d.ts +1 -1
- package/dist/identity/ui/org/orgLabels.d.ts.map +1 -1
- package/dist/identity/ui/org/orgLabels.js +3 -5
- package/dist/identity/ui/org/orgLabels.js.map +1 -1
- package/dist/identity/ui/tokens/CreatePatDialog.d.ts.map +1 -1
- package/dist/identity/ui/tokens/CreatePatDialog.js +3 -1
- package/dist/identity/ui/tokens/CreatePatDialog.js.map +1 -1
- package/dist/identity/ui/tokens/PersonalAccessTokens.d.ts.map +1 -1
- package/dist/identity/ui/tokens/PersonalAccessTokens.js +4 -1
- package/dist/identity/ui/tokens/PersonalAccessTokens.js.map +1 -1
- package/dist/identity/ui/tokens/patColumns.d.ts.map +1 -1
- package/dist/identity/ui/tokens/patColumns.js +7 -5
- package/dist/identity/ui/tokens/patColumns.js.map +1 -1
- package/dist/identity/ui/users/AllowlistTable.d.ts.map +1 -1
- package/dist/identity/ui/users/AllowlistTable.js +4 -1
- package/dist/identity/ui/users/AllowlistTable.js.map +1 -1
- package/dist/identity/ui/users/UserList.d.ts.map +1 -1
- package/dist/identity/ui/users/UserList.js +4 -2
- package/dist/identity/ui/users/UserList.js.map +1 -1
- package/dist/identity/ui/users/allowlistColumns.d.ts.map +1 -1
- package/dist/identity/ui/users/allowlistColumns.js +5 -3
- package/dist/identity/ui/users/allowlistColumns.js.map +1 -1
- package/dist/identity/ui/users/userListColumns.d.ts.map +1 -1
- package/dist/identity/ui/users/userListColumns.js +5 -3
- package/dist/identity/ui/users/userListColumns.js.map +1 -1
- package/dist/jobs/headless/format.d.ts +4 -1
- package/dist/jobs/headless/format.d.ts.map +1 -1
- package/dist/jobs/headless/format.js +6 -2
- package/dist/jobs/headless/format.js.map +1 -1
- package/dist/jobs/ui/JobInsightsPage.d.ts.map +1 -1
- package/dist/jobs/ui/JobInsightsPage.js +2 -1
- package/dist/jobs/ui/JobInsightsPage.js.map +1 -1
- package/dist/jobs/ui/JobsPage.d.ts.map +1 -1
- package/dist/jobs/ui/JobsPage.js +4 -2
- package/dist/jobs/ui/JobsPage.js.map +1 -1
- package/dist/nodes/headless/format.d.ts +4 -1
- package/dist/nodes/headless/format.d.ts.map +1 -1
- package/dist/nodes/headless/format.js +6 -2
- package/dist/nodes/headless/format.js.map +1 -1
- package/dist/nodes/ui/NodeCredentialRevealDialog.d.ts.map +1 -1
- package/dist/nodes/ui/NodeCredentialRevealDialog.js +3 -1
- package/dist/nodes/ui/NodeCredentialRevealDialog.js.map +1 -1
- package/dist/nodes/ui/NodeCredentials.d.ts.map +1 -1
- package/dist/nodes/ui/NodeCredentials.js +4 -1
- package/dist/nodes/ui/NodeCredentials.js.map +1 -1
- package/dist/nodes/ui/NodeVitalsDialog.d.ts.map +1 -1
- package/dist/nodes/ui/NodeVitalsDialog.js +2 -0
- package/dist/nodes/ui/NodeVitalsDialog.js.map +1 -1
- package/dist/nodes/ui/WorkersPage.d.ts.map +1 -1
- package/dist/nodes/ui/WorkersPage.js +4 -2
- package/dist/nodes/ui/WorkersPage.js.map +1 -1
- package/dist/notifications/headless/broadcasts.d.ts +26 -17
- package/dist/notifications/headless/broadcasts.d.ts.map +1 -1
- package/dist/notifications/headless/broadcasts.js +76 -36
- package/dist/notifications/headless/broadcasts.js.map +1 -1
- package/dist/notifications/ui/BroadcastComposer.d.ts.map +1 -1
- package/dist/notifications/ui/BroadcastComposer.js +11 -6
- package/dist/notifications/ui/BroadcastComposer.js.map +1 -1
- package/dist/notifications/ui/BroadcastDetailDialog.d.ts.map +1 -1
- package/dist/notifications/ui/BroadcastDetailDialog.js +2 -0
- package/dist/notifications/ui/BroadcastDetailDialog.js.map +1 -1
- package/dist/notifications/ui/BroadcastsPage.d.ts.map +1 -1
- package/dist/notifications/ui/BroadcastsPage.js +4 -2
- package/dist/notifications/ui/BroadcastsPage.js.map +1 -1
- package/dist/notifications/ui/NotificationBell.d.ts.map +1 -1
- package/dist/notifications/ui/NotificationBell.js +3 -1
- package/dist/notifications/ui/NotificationBell.js.map +1 -1
- package/dist/notifications/ui/PushConfigPage.d.ts.map +1 -1
- package/dist/notifications/ui/PushConfigPage.js +4 -3
- package/dist/notifications/ui/PushConfigPage.js.map +1 -1
- package/dist/notifications/ui/PushTestPanel.d.ts.map +1 -1
- package/dist/notifications/ui/PushTestPanel.js +6 -3
- package/dist/notifications/ui/PushTestPanel.js.map +1 -1
- package/dist/notifications/ui/SystemSettingsSection.d.ts.map +1 -1
- package/dist/notifications/ui/SystemSettingsSection.js +3 -2
- package/dist/notifications/ui/SystemSettingsSection.js.map +1 -1
- package/dist/notifications/ui/broadcastsTable.d.ts +4 -1
- package/dist/notifications/ui/broadcastsTable.d.ts.map +1 -1
- package/dist/notifications/ui/broadcastsTable.js +6 -2
- package/dist/notifications/ui/broadcastsTable.js.map +1 -1
- package/dist/settings/headless/use-user-settings.d.ts +7 -0
- package/dist/settings/headless/use-user-settings.d.ts.map +1 -1
- package/dist/settings/headless/use-user-settings.js +12 -4
- package/dist/settings/headless/use-user-settings.js.map +1 -1
- package/dist/settings/ui/ProfileSettings.d.ts +13 -4
- package/dist/settings/ui/ProfileSettings.d.ts.map +1 -1
- package/dist/settings/ui/ProfileSettings.js +15 -2
- package/dist/settings/ui/ProfileSettings.js.map +1 -1
- package/dist/settings/ui/UserProfilePage.d.ts +2 -2
- package/dist/settings/ui/UserProfilePage.js +3 -3
- package/dist/settings/ui/UserProfilePage.js.map +1 -1
- package/dist/settings/ui/UserSettingsSection.d.ts +5 -2
- package/dist/settings/ui/UserSettingsSection.d.ts.map +1 -1
- package/dist/settings/ui/UserSettingsSection.js.map +1 -1
- package/dist/sharing/internal/format.d.ts +1 -0
- package/dist/sharing/internal/format.d.ts.map +1 -1
- package/dist/sharing/internal/format.js +3 -6
- package/dist/sharing/internal/format.js.map +1 -1
- package/dist/sharing/ui/GroupDetailPage.d.ts.map +1 -1
- package/dist/sharing/ui/GroupDetailPage.js +2 -0
- package/dist/sharing/ui/GroupDetailPage.js.map +1 -1
- package/dist/sharing/ui/PendingGroupInvites.d.ts.map +1 -1
- package/dist/sharing/ui/PendingGroupInvites.js +2 -0
- package/dist/sharing/ui/PendingGroupInvites.js.map +1 -1
- package/dist/sharing/ui/ShareDialog.d.ts.map +1 -1
- package/dist/sharing/ui/ShareDialog.js +2 -0
- package/dist/sharing/ui/ShareDialog.js.map +1 -1
- package/dist/sharing/ui/SharedWithMeList.d.ts.map +1 -1
- package/dist/sharing/ui/SharedWithMeList.js +2 -0
- package/dist/sharing/ui/SharedWithMeList.js.map +1 -1
- package/dist/storage/ui/S3FamilyDriverPanel.d.ts.map +1 -1
- package/dist/storage/ui/S3FamilyDriverPanel.js +3 -1
- package/dist/storage/ui/S3FamilyDriverPanel.js.map +1 -1
- package/dist/storage/ui/StorageConfigPage.d.ts.map +1 -1
- package/dist/storage/ui/StorageConfigPage.js +3 -2
- package/dist/storage/ui/StorageConfigPage.js.map +1 -1
- package/dist/telemetry/headless/hooks/useTelemetryDashboard.d.ts +1 -1
- package/dist/telemetry/headless/lib/format.d.ts +4 -2
- package/dist/telemetry/headless/lib/format.d.ts.map +1 -1
- package/dist/telemetry/headless/lib/format.js +8 -6
- package/dist/telemetry/headless/lib/format.js.map +1 -1
- package/dist/telemetry/ui/components/TelemetryConnectionSection.d.ts.map +1 -1
- package/dist/telemetry/ui/components/TelemetryConnectionSection.js +3 -1
- package/dist/telemetry/ui/components/TelemetryConnectionSection.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js +2 -0
- package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js +2 -0
- package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/EventsFeed.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/EventsFeed.js +3 -0
- package/dist/telemetry/ui/components/dashboard/EventsFeed.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/KpiTiles.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/KpiTiles.js +2 -0
- package/dist/telemetry/ui/components/dashboard/KpiTiles.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js +2 -0
- package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/TopProblems.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/TopProblems.js +2 -0
- package/dist/telemetry/ui/components/dashboard/TopProblems.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js +2 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js.map +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.d.ts.map +1 -1
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js +2 -0
- package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js.map +1 -1
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.d.ts.map +1 -1
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.js +3 -2
- package/dist/telemetry/ui/pages/TelemetrySettingsPage.js.map +1 -1
- package/dist/timezone/headless/catalog.d.ts +82 -0
- package/dist/timezone/headless/catalog.d.ts.map +1 -0
- package/dist/timezone/headless/catalog.js +192 -0
- package/dist/timezone/headless/catalog.js.map +1 -0
- package/dist/timezone/headless/format.d.ts +3 -0
- package/dist/timezone/headless/format.d.ts.map +1 -0
- package/dist/timezone/headless/format.js +5 -0
- package/dist/timezone/headless/format.js.map +1 -0
- package/dist/timezone/headless/index.d.ts +10 -0
- package/dist/timezone/headless/index.d.ts.map +1 -0
- package/dist/timezone/headless/index.js +10 -0
- package/dist/timezone/headless/index.js.map +1 -0
- package/dist/timezone/headless/map-data.d.ts +13 -0
- package/dist/timezone/headless/map-data.d.ts.map +1 -0
- package/dist/timezone/headless/map-data.js +530 -0
- package/dist/timezone/headless/map-data.js.map +1 -0
- package/dist/timezone/headless/map-geometry.d.ts +77 -0
- package/dist/timezone/headless/map-geometry.d.ts.map +1 -0
- package/dist/timezone/headless/map-geometry.js +104 -0
- package/dist/timezone/headless/map-geometry.js.map +1 -0
- package/dist/timezone/headless/store.d.ts +2 -0
- package/dist/timezone/headless/store.d.ts.map +1 -0
- package/dist/timezone/headless/store.js +6 -0
- package/dist/timezone/headless/store.js.map +1 -0
- package/dist/timezone/headless/sync.d.ts +39 -0
- package/dist/timezone/headless/sync.d.ts.map +1 -0
- package/dist/timezone/headless/sync.js +66 -0
- package/dist/timezone/headless/sync.js.map +1 -0
- package/dist/timezone/index.d.ts +4 -0
- package/dist/timezone/index.d.ts.map +1 -0
- package/dist/timezone/index.js +11 -0
- package/dist/timezone/index.js.map +1 -0
- package/dist/timezone/internal/use-now.d.ts +3 -0
- package/dist/timezone/internal/use-now.d.ts.map +1 -0
- package/dist/timezone/internal/use-now.js +13 -0
- package/dist/timezone/internal/use-now.js.map +1 -0
- package/dist/timezone/ui/TimeZoneField.d.ts +33 -0
- package/dist/timezone/ui/TimeZoneField.d.ts.map +1 -0
- package/dist/timezone/ui/TimeZoneField.js +50 -0
- package/dist/timezone/ui/TimeZoneField.js.map +1 -0
- package/dist/timezone/ui/TimeZoneMap.d.ts +38 -0
- package/dist/timezone/ui/TimeZoneMap.d.ts.map +1 -0
- package/dist/timezone/ui/TimeZoneMap.js +231 -0
- package/dist/timezone/ui/TimeZoneMap.js.map +1 -0
- package/dist/timezone/ui/TimeZonePickerDialog.d.ts +34 -0
- package/dist/timezone/ui/TimeZonePickerDialog.d.ts.map +1 -0
- package/dist/timezone/ui/TimeZonePickerDialog.js +85 -0
- package/dist/timezone/ui/TimeZonePickerDialog.js.map +1 -0
- package/dist/timezone/ui/index.d.ts +7 -0
- package/dist/timezone/ui/index.d.ts.map +1 -0
- package/dist/timezone/ui/index.js +7 -0
- package/dist/timezone/ui/index.js.map +1 -0
- package/package.json +10 -2
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// Date and time formatting in the display zone. Every formatter defaults
|
|
2
|
+
// `timeZone` to `getDisplayTimeZone()`; a caller passes an explicit
|
|
3
|
+
// `timeZone` (often `'UTC'`) for a server fact that is defined in one zone.
|
|
4
|
+
// In `core` with the store (see ./store.ts); re-exported by the timezone slice.
|
|
5
|
+
import { getDisplayTimeZone } from './store.js';
|
|
6
|
+
/**
|
|
7
|
+
* The fields `Date.prototype.toLocaleString()` renders (`1/15/2026, 6:30:00 PM`
|
|
8
|
+
* in `en-US`), for a page that keeps that look while rendering in the display
|
|
9
|
+
* zone: `formatDateTime(value, NUMERIC_DATE_TIME)`.
|
|
10
|
+
*
|
|
11
|
+
* @stability experimental
|
|
12
|
+
*/
|
|
13
|
+
export const NUMERIC_DATE_TIME = Object.freeze({
|
|
14
|
+
year: 'numeric',
|
|
15
|
+
month: 'numeric',
|
|
16
|
+
day: 'numeric',
|
|
17
|
+
hour: 'numeric',
|
|
18
|
+
minute: 'numeric',
|
|
19
|
+
second: 'numeric',
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* The fields `Date.prototype.toLocaleDateString()` renders (`1/15/2026`):
|
|
23
|
+
* `formatDate(value, NUMERIC_DATE)`.
|
|
24
|
+
*
|
|
25
|
+
* @stability experimental
|
|
26
|
+
*/
|
|
27
|
+
export const NUMERIC_DATE = Object.freeze({
|
|
28
|
+
year: 'numeric',
|
|
29
|
+
month: 'numeric',
|
|
30
|
+
day: 'numeric',
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* The fields `Date.prototype.toLocaleTimeString()` renders (`6:30:00 PM`):
|
|
34
|
+
* `formatTime(value, NUMERIC_TIME)`.
|
|
35
|
+
*
|
|
36
|
+
* @stability experimental
|
|
37
|
+
*/
|
|
38
|
+
export const NUMERIC_TIME = Object.freeze({
|
|
39
|
+
hour: 'numeric',
|
|
40
|
+
minute: 'numeric',
|
|
41
|
+
second: 'numeric',
|
|
42
|
+
});
|
|
43
|
+
/** What an empty or invalid date renders across the packaged pages. */
|
|
44
|
+
const DEFAULT_FALLBACK = '—';
|
|
45
|
+
const CACHE_LIMIT = 200;
|
|
46
|
+
const cache = new Map();
|
|
47
|
+
/** Options that pick date or time fields one by one (they cannot mix with `dateStyle`/`timeStyle`). */
|
|
48
|
+
const FIELD_KEYS = [
|
|
49
|
+
'dateStyle',
|
|
50
|
+
'timeStyle',
|
|
51
|
+
'weekday',
|
|
52
|
+
'era',
|
|
53
|
+
'year',
|
|
54
|
+
'month',
|
|
55
|
+
'day',
|
|
56
|
+
'dayPeriod',
|
|
57
|
+
'hour',
|
|
58
|
+
'minute',
|
|
59
|
+
'second',
|
|
60
|
+
'fractionalSecondDigits',
|
|
61
|
+
'timeZoneName',
|
|
62
|
+
];
|
|
63
|
+
/**
|
|
64
|
+
* The value as a valid `Date`, or `null`.
|
|
65
|
+
*
|
|
66
|
+
* @param value - see {@link DateInput}.
|
|
67
|
+
* @returns the date, or `null` for an empty or invalid value.
|
|
68
|
+
*
|
|
69
|
+
* @stability experimental
|
|
70
|
+
*/
|
|
71
|
+
export function toValidDate(value) {
|
|
72
|
+
if (value === null || value === undefined || value === '')
|
|
73
|
+
return null;
|
|
74
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
75
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
76
|
+
}
|
|
77
|
+
function cachedFormatter(locale, options) {
|
|
78
|
+
const key = JSON.stringify([locale ?? null, Object.entries(options).sort(([a], [b]) => a.localeCompare(b))]);
|
|
79
|
+
let formatter = cache.get(key);
|
|
80
|
+
if (!formatter) {
|
|
81
|
+
if (cache.size >= CACHE_LIMIT)
|
|
82
|
+
cache.clear();
|
|
83
|
+
formatter = new Intl.DateTimeFormat(locale, options);
|
|
84
|
+
cache.set(key, formatter);
|
|
85
|
+
}
|
|
86
|
+
return formatter;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A cached `Intl.DateTimeFormat` for the options, in the display zone unless
|
|
90
|
+
* `options.timeZone` says otherwise. An unknown zone falls back to UTC.
|
|
91
|
+
*
|
|
92
|
+
* @param options - format options; `locale` picks the locale.
|
|
93
|
+
* @returns the formatter.
|
|
94
|
+
*
|
|
95
|
+
* @stability experimental
|
|
96
|
+
*/
|
|
97
|
+
export function getDateTimeFormat(options = {}) {
|
|
98
|
+
const { locale, ...intl } = options;
|
|
99
|
+
const resolved = { ...intl, timeZone: intl.timeZone ?? getDisplayTimeZone() };
|
|
100
|
+
try {
|
|
101
|
+
return cachedFormatter(locale, resolved);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return cachedFormatter(locale, { ...resolved, timeZone: 'UTC' });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function format(value, options, defaults) {
|
|
108
|
+
const { fallback = DEFAULT_FALLBACK, ...rest } = options ?? {};
|
|
109
|
+
const date = toValidDate(value);
|
|
110
|
+
if (!date)
|
|
111
|
+
return fallback;
|
|
112
|
+
const picksFields = FIELD_KEYS.some((key) => rest[key] !== undefined);
|
|
113
|
+
return getDateTimeFormat(picksFields ? rest : { ...defaults, ...rest }).format(date);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A date and time in the display zone (`Oct 26, 2026, 10:42 AM`).
|
|
117
|
+
*
|
|
118
|
+
* @param value - see {@link DateInput}.
|
|
119
|
+
* @param options - default `{ dateStyle: 'medium', timeStyle: 'short' }`; any field option replaces the defaults.
|
|
120
|
+
* @returns the formatted text, or the fallback (`'—'`).
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* formatDateTime(job.createdAt); // in the user's zone
|
|
125
|
+
* formatDateTime(backup.scheduledAt, { timeZone: 'UTC' });
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @stability experimental
|
|
129
|
+
*/
|
|
130
|
+
export function formatDateTime(value, options) {
|
|
131
|
+
return format(value, options, { dateStyle: 'medium', timeStyle: 'short' });
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A calendar date in the display zone (`Oct 26, 2026`).
|
|
135
|
+
*
|
|
136
|
+
* @param value - see {@link DateInput}.
|
|
137
|
+
* @param options - default `{ dateStyle: 'medium' }`.
|
|
138
|
+
* @returns the formatted text, or the fallback (`'—'`).
|
|
139
|
+
*
|
|
140
|
+
* @stability experimental
|
|
141
|
+
*/
|
|
142
|
+
export function formatDate(value, options) {
|
|
143
|
+
return format(value, options, { dateStyle: 'medium' });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* A time of day in the display zone (`10:42 AM`).
|
|
147
|
+
*
|
|
148
|
+
* @param value - see {@link DateInput}.
|
|
149
|
+
* @param options - default `{ timeStyle: 'short' }`.
|
|
150
|
+
* @returns the formatted text, or the fallback (`'—'`).
|
|
151
|
+
*
|
|
152
|
+
* @stability experimental
|
|
153
|
+
*/
|
|
154
|
+
export function formatTime(value, options) {
|
|
155
|
+
return format(value, options, { timeStyle: 'short' });
|
|
156
|
+
}
|
|
157
|
+
function zonedParts(date, timeZone) {
|
|
158
|
+
const parts = getDateTimeFormat({
|
|
159
|
+
locale: 'en-US',
|
|
160
|
+
timeZone,
|
|
161
|
+
hourCycle: 'h23',
|
|
162
|
+
year: 'numeric',
|
|
163
|
+
month: '2-digit',
|
|
164
|
+
day: '2-digit',
|
|
165
|
+
hour: '2-digit',
|
|
166
|
+
minute: '2-digit',
|
|
167
|
+
second: '2-digit',
|
|
168
|
+
}).formatToParts(date);
|
|
169
|
+
const out = {};
|
|
170
|
+
for (const part of parts)
|
|
171
|
+
if (part.type !== 'literal')
|
|
172
|
+
out[part.type] = Number(part.value);
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The calendar day of a moment in a zone, as `YYYY-MM-DD`: the key to group
|
|
177
|
+
* rows by day or to tell "Today" from "Yesterday".
|
|
178
|
+
*
|
|
179
|
+
* @param value - see {@link DateInput}.
|
|
180
|
+
* @param timeZone - default: the display zone.
|
|
181
|
+
* @returns the key, or `null` for an empty or invalid value.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const isToday = zonedDateKey(row.createdAt) === zonedDateKey(new Date());
|
|
186
|
+
* ```
|
|
187
|
+
*
|
|
188
|
+
* @stability experimental
|
|
189
|
+
*/
|
|
190
|
+
export function zonedDateKey(value, timeZone) {
|
|
191
|
+
const date = toValidDate(value);
|
|
192
|
+
if (!date)
|
|
193
|
+
return null;
|
|
194
|
+
const { year = 0, month = 0, day = 0 } = zonedParts(date, timeZone ?? getDisplayTimeZone());
|
|
195
|
+
return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The zone's offset from UTC at a moment, in minutes (`-360` for Costa Rica,
|
|
199
|
+
* `330` for India); daylight saving time included.
|
|
200
|
+
*
|
|
201
|
+
* @param timeZone - an IANA zone id.
|
|
202
|
+
* @param at - the moment; default now.
|
|
203
|
+
* @returns minutes east of UTC.
|
|
204
|
+
*
|
|
205
|
+
* @stability experimental
|
|
206
|
+
*/
|
|
207
|
+
export function getTimeZoneOffsetMinutes(timeZone, at = new Date()) {
|
|
208
|
+
const p = zonedParts(at, timeZone);
|
|
209
|
+
const asUtc = Date.UTC(p.year ?? 1970, (p.month ?? 1) - 1, p.day ?? 1, (p.hour ?? 0) % 24, p.minute ?? 0, p.second ?? 0);
|
|
210
|
+
const whole = Math.floor(at.getTime() / 1000) * 1000;
|
|
211
|
+
return Math.round((asUtc - whole) / 60_000);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* An offset as `UTC−06:00`, `UTC+05:30` or `UTC` (with the minus sign U+2212).
|
|
215
|
+
*
|
|
216
|
+
* @param minutes - minutes east of UTC.
|
|
217
|
+
* @returns the label.
|
|
218
|
+
*
|
|
219
|
+
* @stability experimental
|
|
220
|
+
*/
|
|
221
|
+
export function formatUtcOffset(minutes) {
|
|
222
|
+
if (!Number.isFinite(minutes) || minutes === 0)
|
|
223
|
+
return 'UTC';
|
|
224
|
+
const sign = minutes < 0 ? '−' : '+';
|
|
225
|
+
const abs = Math.abs(Math.round(minutes));
|
|
226
|
+
return `UTC${sign}${String(Math.floor(abs / 60)).padStart(2, '0')}:${String(abs % 60).padStart(2, '0')}`;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/core/time-zone/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `localStorage` key the chosen zone is cached under, so a reload renders
|
|
3
|
+
* in the right zone before the settings fetch lands.
|
|
4
|
+
*
|
|
5
|
+
* @stability experimental
|
|
6
|
+
*/
|
|
7
|
+
export declare const TIME_ZONE_STORAGE_KEY = "platform.timezone";
|
|
8
|
+
/**
|
|
9
|
+
* The IANA zone this device reports (`Europe/Paris`), or `'UTC'` when the
|
|
10
|
+
* runtime does not say.
|
|
11
|
+
*
|
|
12
|
+
* @returns the device's zone id.
|
|
13
|
+
*
|
|
14
|
+
* @stability experimental
|
|
15
|
+
*/
|
|
16
|
+
export declare function deviceTimeZone(): string;
|
|
17
|
+
/**
|
|
18
|
+
* The zone the user chose (`profile.timezone`), or `null` when they follow the
|
|
19
|
+
* device.
|
|
20
|
+
*
|
|
21
|
+
* @returns the stored choice.
|
|
22
|
+
*
|
|
23
|
+
* @stability experimental
|
|
24
|
+
*/
|
|
25
|
+
export declare function getPreferredTimeZone(): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* The zone every packaged time is rendered in: the user's choice, else the
|
|
28
|
+
* device's zone, else `'UTC'`.
|
|
29
|
+
*
|
|
30
|
+
* @returns an IANA zone id.
|
|
31
|
+
*
|
|
32
|
+
* @stability experimental
|
|
33
|
+
*/
|
|
34
|
+
export declare function getDisplayTimeZone(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Sets the user's choice (`null` follows the device again) and notifies every
|
|
37
|
+
* subscriber. An id the runtime does not know is ignored. The value is cached
|
|
38
|
+
* in `localStorage` (`platform.timezone`) when the browser allows it.
|
|
39
|
+
*
|
|
40
|
+
* @param id - an IANA zone id, or `null`.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* setPreferredTimeZone(settings.profile.timezone ?? null);
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @stability experimental
|
|
48
|
+
*/
|
|
49
|
+
export declare function setPreferredTimeZone(id: string | null): void;
|
|
50
|
+
/**
|
|
51
|
+
* Calls `listener` whenever the display zone may have changed.
|
|
52
|
+
*
|
|
53
|
+
* @param listener - called with no argument.
|
|
54
|
+
* @returns the unsubscribe function.
|
|
55
|
+
*
|
|
56
|
+
* @stability experimental
|
|
57
|
+
*/
|
|
58
|
+
export declare function subscribeDisplayTimeZone(listener: () => void): () => void;
|
|
59
|
+
/**
|
|
60
|
+
* The display zone, re-rendering the component when it changes. Use it in a
|
|
61
|
+
* component that formats times, so a saved profile re-renders them.
|
|
62
|
+
*
|
|
63
|
+
* @returns the effective IANA zone id ({@link getDisplayTimeZone}).
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* const zone = useDisplayTimeZone();
|
|
68
|
+
* return <span>{formatDateTime(job.createdAt, { timeZone: zone })}</span>;
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @extensionPoint hook
|
|
72
|
+
* @stability experimental
|
|
73
|
+
*/
|
|
74
|
+
export declare function useDisplayTimeZone(): string;
|
|
75
|
+
/**
|
|
76
|
+
* The user's stored choice, re-rendering on change (`null`: follow the device).
|
|
77
|
+
*
|
|
78
|
+
* @returns the choice ({@link getPreferredTimeZone}).
|
|
79
|
+
*
|
|
80
|
+
* @stability experimental
|
|
81
|
+
*/
|
|
82
|
+
export declare function usePreferredTimeZone(): string | null;
|
|
83
|
+
/**
|
|
84
|
+
* `profile.timezone` out of a settings profile: the id when it is a valid zone,
|
|
85
|
+
* else `null`.
|
|
86
|
+
*
|
|
87
|
+
* @param profile - a stored profile (any shape).
|
|
88
|
+
* @returns the zone id, or `null`.
|
|
89
|
+
*
|
|
90
|
+
* @stability experimental
|
|
91
|
+
*/
|
|
92
|
+
export declare function timeZoneFromProfile(profile: unknown): string | null;
|
|
93
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/time-zone/store.ts"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AA2BzD;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAWvC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM5D;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAInE"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// The display time zone: one module-level store, so a pure formatter, a hook
|
|
2
|
+
// and code outside React all read the same answer. The user's choice comes
|
|
3
|
+
// from `profile.timezone` (pushed here by `UserTimeZoneSync` of the timezone
|
|
4
|
+
// slice and by `useUserSettings` of the settings slice); without one, the
|
|
5
|
+
// device's zone. It lives in `core`, not in the timezone slice, because every
|
|
6
|
+
// slice renders dates (identity included, which the timezone slice depends
|
|
7
|
+
// on): core is the one place all of them may import without a cycle. The
|
|
8
|
+
// timezone slice re-exports it from `/timezone/headless`.
|
|
9
|
+
import { isValidTimeZone } from '@marinoscar/platform-contract/settings';
|
|
10
|
+
import { useSyncExternalStore } from 'react';
|
|
11
|
+
/**
|
|
12
|
+
* The `localStorage` key the chosen zone is cached under, so a reload renders
|
|
13
|
+
* in the right zone before the settings fetch lands.
|
|
14
|
+
*
|
|
15
|
+
* @stability experimental
|
|
16
|
+
*/
|
|
17
|
+
export const TIME_ZONE_STORAGE_KEY = 'platform.timezone';
|
|
18
|
+
const listeners = new Set();
|
|
19
|
+
function readCache() {
|
|
20
|
+
try {
|
|
21
|
+
const cached = globalThis.localStorage?.getItem(TIME_ZONE_STORAGE_KEY) ?? null;
|
|
22
|
+
return isValidTimeZone(cached) ? cached : null;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function writeCache(id) {
|
|
29
|
+
try {
|
|
30
|
+
const storage = globalThis.localStorage;
|
|
31
|
+
if (!storage)
|
|
32
|
+
return;
|
|
33
|
+
if (id === null)
|
|
34
|
+
storage.removeItem(TIME_ZONE_STORAGE_KEY);
|
|
35
|
+
else
|
|
36
|
+
storage.setItem(TIME_ZONE_STORAGE_KEY, id);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Private mode or blocked storage: the choice still applies to this page.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let preferred = readCache();
|
|
43
|
+
let device;
|
|
44
|
+
/**
|
|
45
|
+
* The IANA zone this device reports (`Europe/Paris`), or `'UTC'` when the
|
|
46
|
+
* runtime does not say.
|
|
47
|
+
*
|
|
48
|
+
* @returns the device's zone id.
|
|
49
|
+
*
|
|
50
|
+
* @stability experimental
|
|
51
|
+
*/
|
|
52
|
+
export function deviceTimeZone() {
|
|
53
|
+
if (device !== undefined)
|
|
54
|
+
return device;
|
|
55
|
+
let zone = 'UTC';
|
|
56
|
+
try {
|
|
57
|
+
const resolved = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
58
|
+
if (isValidTimeZone(resolved))
|
|
59
|
+
zone = resolved;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// An engine without Intl time zone support: UTC.
|
|
63
|
+
}
|
|
64
|
+
device = zone;
|
|
65
|
+
return zone;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The zone the user chose (`profile.timezone`), or `null` when they follow the
|
|
69
|
+
* device.
|
|
70
|
+
*
|
|
71
|
+
* @returns the stored choice.
|
|
72
|
+
*
|
|
73
|
+
* @stability experimental
|
|
74
|
+
*/
|
|
75
|
+
export function getPreferredTimeZone() {
|
|
76
|
+
return preferred;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The zone every packaged time is rendered in: the user's choice, else the
|
|
80
|
+
* device's zone, else `'UTC'`.
|
|
81
|
+
*
|
|
82
|
+
* @returns an IANA zone id.
|
|
83
|
+
*
|
|
84
|
+
* @stability experimental
|
|
85
|
+
*/
|
|
86
|
+
export function getDisplayTimeZone() {
|
|
87
|
+
return preferred ?? deviceTimeZone();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Sets the user's choice (`null` follows the device again) and notifies every
|
|
91
|
+
* subscriber. An id the runtime does not know is ignored. The value is cached
|
|
92
|
+
* in `localStorage` (`platform.timezone`) when the browser allows it.
|
|
93
|
+
*
|
|
94
|
+
* @param id - an IANA zone id, or `null`.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* setPreferredTimeZone(settings.profile.timezone ?? null);
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @stability experimental
|
|
102
|
+
*/
|
|
103
|
+
export function setPreferredTimeZone(id) {
|
|
104
|
+
if (id !== null && !isValidTimeZone(id))
|
|
105
|
+
return;
|
|
106
|
+
if (id === preferred)
|
|
107
|
+
return;
|
|
108
|
+
preferred = id;
|
|
109
|
+
writeCache(id);
|
|
110
|
+
for (const listener of [...listeners])
|
|
111
|
+
listener();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Calls `listener` whenever the display zone may have changed.
|
|
115
|
+
*
|
|
116
|
+
* @param listener - called with no argument.
|
|
117
|
+
* @returns the unsubscribe function.
|
|
118
|
+
*
|
|
119
|
+
* @stability experimental
|
|
120
|
+
*/
|
|
121
|
+
export function subscribeDisplayTimeZone(listener) {
|
|
122
|
+
listeners.add(listener);
|
|
123
|
+
return () => {
|
|
124
|
+
listeners.delete(listener);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The display zone, re-rendering the component when it changes. Use it in a
|
|
129
|
+
* component that formats times, so a saved profile re-renders them.
|
|
130
|
+
*
|
|
131
|
+
* @returns the effective IANA zone id ({@link getDisplayTimeZone}).
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```tsx
|
|
135
|
+
* const zone = useDisplayTimeZone();
|
|
136
|
+
* return <span>{formatDateTime(job.createdAt, { timeZone: zone })}</span>;
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @extensionPoint hook
|
|
140
|
+
* @stability experimental
|
|
141
|
+
*/
|
|
142
|
+
export function useDisplayTimeZone() {
|
|
143
|
+
return useSyncExternalStore(subscribeDisplayTimeZone, getDisplayTimeZone, getDisplayTimeZone);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The user's stored choice, re-rendering on change (`null`: follow the device).
|
|
147
|
+
*
|
|
148
|
+
* @returns the choice ({@link getPreferredTimeZone}).
|
|
149
|
+
*
|
|
150
|
+
* @stability experimental
|
|
151
|
+
*/
|
|
152
|
+
export function usePreferredTimeZone() {
|
|
153
|
+
return useSyncExternalStore(subscribeDisplayTimeZone, getPreferredTimeZone, getPreferredTimeZone);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* `profile.timezone` out of a settings profile: the id when it is a valid zone,
|
|
157
|
+
* else `null`.
|
|
158
|
+
*
|
|
159
|
+
* @param profile - a stored profile (any shape).
|
|
160
|
+
* @returns the zone id, or `null`.
|
|
161
|
+
*
|
|
162
|
+
* @stability experimental
|
|
163
|
+
*/
|
|
164
|
+
export function timeZoneFromProfile(profile) {
|
|
165
|
+
if (!profile || typeof profile !== 'object')
|
|
166
|
+
return null;
|
|
167
|
+
const value = profile.timezone;
|
|
168
|
+
return isValidTimeZone(value) ? value : null;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/time-zone/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,7 +31,7 @@ export interface SavedSecretHelperTextOptions {
|
|
|
31
31
|
/**
|
|
32
32
|
* Formats the last-change date.
|
|
33
33
|
*
|
|
34
|
-
* @defaultValue `
|
|
34
|
+
* @defaultValue the numeric date (`toLocaleDateString()`'s fields) in the display time zone
|
|
35
35
|
*/
|
|
36
36
|
readonly formatDate?: (date: Date) => string;
|
|
37
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saved-secret.d.ts","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"saved-secret.d.ts","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAGnF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,GAAG;IAC1C,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEJ;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;CAC9C;AAOD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACxC,OAAO,GAAE,4BAAiC,GACzC,MAAM,CASR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// stored", which is what the sentence tells the user and what
|
|
13
13
|
// `secretForSubmit` sends.
|
|
14
14
|
// =============================================================================
|
|
15
|
+
import { NUMERIC_DATE, formatDate } from '../../core/index.js';
|
|
15
16
|
/** `a key`, `an access key`. */
|
|
16
17
|
function withArticle(noun) {
|
|
17
18
|
return /^[aeiou]/i.test(noun) ? `An ${noun}` : `A ${noun}`;
|
|
@@ -41,7 +42,7 @@ export function savedSecretHelperText(info, options = {}) {
|
|
|
41
42
|
return options.emptyHelp ?? `No ${noun} is saved yet.`;
|
|
42
43
|
const which = info.hint ? ` (${info.hint})` : '';
|
|
43
44
|
const date = info.updatedAt ? new Date(info.updatedAt) : null;
|
|
44
|
-
const format = options.formatDate ?? ((d) => d
|
|
45
|
+
const format = options.formatDate ?? ((d) => formatDate(d, NUMERIC_DATE));
|
|
45
46
|
const when = date && !Number.isNaN(date.getTime()) ? `, updated ${format(date)}` : '';
|
|
46
47
|
return `${withArticle(noun)} is saved${which}${when}. Leave this blank to keep it, or type a new one to replace it.`;
|
|
47
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saved-secret.js","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,oEAAoE;AACpE,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,8DAA8D;AAC9D,2BAA2B;AAC3B,gFAAgF;
|
|
1
|
+
{"version":3,"file":"saved-secret.js","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,oEAAoE;AACpE,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,8DAA8D;AAC9D,2BAA2B;AAC3B,gFAAgF;AAGhF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAyC/D,gCAAgC;AAChC,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAwC,EACxC,UAAwC,EAAE;IAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,SAAS,IAAI,MAAM,IAAI,gBAAgB,CAAC;IAElE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAO,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,KAAK,GAAG,IAAI,iEAAiE,CAAC;AACvH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC"}
|
|
@@ -20,7 +20,7 @@ export interface SecretFieldProps {
|
|
|
20
20
|
emptyHelp?: string;
|
|
21
21
|
/** What the secret is called in the helper text; default `'key'`. */
|
|
22
22
|
noun?: string;
|
|
23
|
-
/** Formats the last-change date; default
|
|
23
|
+
/** Formats the last-change date; default the numeric date in the display time zone. */
|
|
24
24
|
formatDate?: SavedSecretHelperTextOptions['formatDate'];
|
|
25
25
|
/** Disables the input (a viewer without the write permission). */
|
|
26
26
|
disabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-field.d.ts","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"secret-field.d.ts","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG1F;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wFAAwF;IACxF,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,UAAU,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACxD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA6BjE"}
|
|
@@ -13,6 +13,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
13
13
|
import { TextField } from '@mui/material';
|
|
14
14
|
import { useId } from 'react';
|
|
15
15
|
import { savedSecretHelperText } from '../headless/index.js';
|
|
16
|
+
import { useDisplayTimeZone } from '../../core/index.js';
|
|
16
17
|
/**
|
|
17
18
|
* A write-only secret input with the unified "saved secret" helper text.
|
|
18
19
|
*
|
|
@@ -34,6 +35,7 @@ import { savedSecretHelperText } from '../headless/index.js';
|
|
|
34
35
|
* @stability experimental
|
|
35
36
|
*/
|
|
36
37
|
export function SecretField(props) {
|
|
38
|
+
useDisplayTimeZone(); // "updated" renders in the display zone.
|
|
37
39
|
const generatedId = useId();
|
|
38
40
|
const id = props.id ?? `secret-field-${generatedId.replace(/[^A-Za-z0-9_-]/g, '')}`;
|
|
39
41
|
const helper = props.error ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-field.js","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,8DAA8D;AAC9D,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,4DAA4D;AAC5D,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"secret-field.js","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,8DAA8D;AAC9D,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,4DAA4D;AAC5D,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAkDzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,kBAAkB,EAAE,CAAC,CAAC,yCAAyC;IAC/D,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,gBAAgB,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC;IACpF,MAAM,MAAM,GACV,KAAK,CAAC,KAAK;QACX,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE;YACjC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;IAEL,OAAO,CACL,KAAC,SAAS,IACR,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAC3B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAC,cAAc,EAC3B,SAAS,QACT,EAAE,EAAE,KAAK,CAAC,EAAE,KACR,KAAK,CAAC,KAAK,EAAE,SAAS,EAC1B,IAAI,EAAC,UAAU,EACf,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GACvD,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function formatDuration(ms: number | null | undefined): string;
|
|
15
15
|
/**
|
|
16
|
-
* A timestamp in the viewer's locale
|
|
16
|
+
* A timestamp in the viewer's locale and display time zone (the user's
|
|
17
|
+
* `profile.timezone`, else the device's), or an em dash when the API sent `null`.
|
|
18
|
+
* A component that renders it calls `useDisplayTimeZone()` so a zone change
|
|
19
|
+
* re-renders it.
|
|
17
20
|
*
|
|
18
21
|
* @param value - an ISO 8601 timestamp, or `null`.
|
|
19
22
|
* @returns the localized date and time, or an em dash.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAiBpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAEvE;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1C"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// page never reads "1500ms" beside one reading "1.5 s" for the same number.
|
|
12
12
|
// Pure functions, no markup, so they live in the headless entry.
|
|
13
13
|
// =============================================================================
|
|
14
|
+
import { NUMERIC_DATE_TIME, formatDateTime as formatZonedDateTime } from '../../core/index.js';
|
|
14
15
|
/**
|
|
15
16
|
* A duration, in the largest unit that still says something: `850 ms`,
|
|
16
17
|
* `1.5 s`, `4m 05s`, `2h 03m`, `3d 4h`.
|
|
@@ -44,7 +45,10 @@ export function formatDuration(ms) {
|
|
|
44
45
|
return `${days}d ${hours % 24}h`;
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
|
-
* A timestamp in the viewer's locale
|
|
48
|
+
* A timestamp in the viewer's locale and display time zone (the user's
|
|
49
|
+
* `profile.timezone`, else the device's), or an em dash when the API sent `null`.
|
|
50
|
+
* A component that renders it calls `useDisplayTimeZone()` so a zone change
|
|
51
|
+
* re-renders it.
|
|
48
52
|
*
|
|
49
53
|
* @param value - an ISO 8601 timestamp, or `null`.
|
|
50
54
|
* @returns the localized date and time, or an em dash.
|
|
@@ -52,7 +56,7 @@ export function formatDuration(ms) {
|
|
|
52
56
|
* @stability experimental
|
|
53
57
|
*/
|
|
54
58
|
export function formatDateTime(value) {
|
|
55
|
-
return value
|
|
59
|
+
return formatZonedDateTime(value, NUMERIC_DATE_TIME);
|
|
56
60
|
}
|
|
57
61
|
/**
|
|
58
62
|
* The first 8 characters of a UUID: enough to tell two rows apart by eye.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+EAA+E;AAC/E,kDAAkD;AAClD,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,iEAAiE;AACjE,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAA6B;IAC1D,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IACxE,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IAE7C,MAAM,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,YAAY,GAAG,EAAE;QAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAE5E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,OAAO,GAAG,EAAE,CAAC;IACtC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEjF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,CAAC;AACnC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+EAA+E;AAC/E,kDAAkD;AAClD,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,iEAAiE;AACjE,gFAAgF;AAEhF,OAAO,EAAE,iBAAiB,EAAE,cAAc,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/F;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAA6B;IAC1D,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IACxE,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IAE7C,MAAM,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,YAAY,GAAG,EAAE;QAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAE5E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,OAAO,GAAG,EAAE,CAAC;IACtC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEjF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,CAAC;AACnC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC"}
|