@ezychat/web 0.0.0-stage → 0.1.38

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 (186) hide show
  1. package/dist-lib/assets/font-1be3448e292f.woff2 +0 -0
  2. package/dist-lib/assets/font-3100e775e861.woff2 +0 -0
  3. package/dist-lib/assets/font-34b9c504cab7.woff2 +0 -0
  4. package/dist-lib/assets/font-5c66f9e07e90.woff2 +0 -0
  5. package/dist-lib/assets/font-6e9e020a25f9.woff2 +0 -0
  6. package/dist-lib/assets/font-71d5ee93cc1e.woff2 +0 -0
  7. package/dist-lib/assets/font-ca157063339a.woff2 +0 -0
  8. package/dist-lib/chunks/admin-BPgvUcQO.js +602 -0
  9. package/dist-lib/chunks/admin-B_hIZ1Sp.js +603 -0
  10. package/dist-lib/chunks/app-C2A7ZZsu.js +97 -0
  11. package/dist-lib/chunks/app-RX8Fy2Oz.js +97 -0
  12. package/dist-lib/chunks/auth-Cif_yktU.js +127 -0
  13. package/dist-lib/chunks/auth-DJBQd10l.js +127 -0
  14. package/dist-lib/chunks/common-BwLWsyiW.js +80 -0
  15. package/dist-lib/chunks/common-CDytP7HK.js +80 -0
  16. package/dist-lib/chunks/errors-BIyy5VTn.js +39 -0
  17. package/dist-lib/chunks/errors-CEweqDjm.js +39 -0
  18. package/dist-lib/chunks/inbox-IiNeuwOm.js +487 -0
  19. package/dist-lib/chunks/inbox-VvClcCZP.js +487 -0
  20. package/dist-lib/chunks/registerSW-Gn8zt2XY.js +16 -0
  21. package/dist-lib/ezychat-web.css +2 -0
  22. package/dist-lib/index.js +16732 -0
  23. package/dist-lib/public/apple-touch-icon.png +0 -0
  24. package/dist-lib/public/brand/ezychat-logo.png +0 -0
  25. package/dist-lib/public/favicon.ico +0 -0
  26. package/dist-lib/public/icon-192.png +0 -0
  27. package/dist-lib/public/icon-512.png +0 -0
  28. package/dist-lib/public/icon-maskable-512.png +0 -0
  29. package/dist-lib/public/illustrations/empty-inbox.png +0 -0
  30. package/dist-lib/public/illustrations/link-whatsapp.png +0 -0
  31. package/dist-lib/public/illustrations/no-results.png +0 -0
  32. package/dist-lib/public/illustrations/tunnel.png +0 -0
  33. package/dist-lib/public/illustrations/welcome.png +0 -0
  34. package/dist-lib/public/share-app.svg +16 -0
  35. package/dist-lib/sw.ts +71 -0
  36. package/dist-lib/types/App.d.ts +2 -0
  37. package/dist-lib/types/access/AccessGate.d.ts +24 -0
  38. package/dist-lib/types/access/BannerSlot.d.ts +35 -0
  39. package/dist-lib/types/access/events.d.ts +16 -0
  40. package/dist-lib/types/admin/AdminLayout.d.ts +36 -0
  41. package/dist-lib/types/admin/AiConnectionBanner.d.ts +7 -0
  42. package/dist-lib/types/admin/AiConnectionSection.d.ts +3 -0
  43. package/dist-lib/types/admin/AiContextPanel.d.ts +11 -0
  44. package/dist-lib/types/admin/AiEditDialog.d.ts +13 -0
  45. package/dist-lib/types/admin/AiMemberPage.d.ts +1 -0
  46. package/dist-lib/types/admin/AiQuickConnect.d.ts +22 -0
  47. package/dist-lib/types/admin/AiTryIt.d.ts +8 -0
  48. package/dist-lib/types/admin/AiVoiceSection.d.ts +2 -0
  49. package/dist-lib/types/admin/AuditPage.d.ts +1 -0
  50. package/dist-lib/types/admin/CloudflareSetup.d.ts +5 -0
  51. package/dist-lib/types/admin/CreateTokenDialog.d.ts +13 -0
  52. package/dist-lib/types/admin/CustomerEnrichmentSection.d.ts +1 -0
  53. package/dist-lib/types/admin/EnrichmentAuditScore.d.ts +4 -0
  54. package/dist-lib/types/admin/IntegrationsSection.d.ts +7 -0
  55. package/dist-lib/types/admin/MembersPage.d.ts +2 -0
  56. package/dist-lib/types/admin/QuickRepliesPage.d.ts +2 -0
  57. package/dist-lib/types/admin/ResolveAllChatsCard.d.ts +1 -0
  58. package/dist-lib/types/admin/SettingsPage.d.ts +2 -0
  59. package/dist-lib/types/admin/TokenConnectSteps.d.ts +12 -0
  60. package/dist-lib/types/admin/TunnelPage.d.ts +1 -0
  61. package/dist-lib/types/admin/WhatsAppPage.d.ts +11 -0
  62. package/dist-lib/types/admin/adminUi.d.ts +62 -0
  63. package/dist-lib/types/admin/ai-status.d.ts +12 -0
  64. package/dist-lib/types/admin/audit-actions.d.ts +10 -0
  65. package/dist-lib/types/admin/line-diff.d.ts +26 -0
  66. package/dist-lib/types/admin/use-chatgpt-sign-in.d.ts +14 -0
  67. package/dist-lib/types/api/ai.d.ts +174 -0
  68. package/dist-lib/types/api/client.d.ts +22 -0
  69. package/dist-lib/types/api/enrichment.d.ts +8 -0
  70. package/dist-lib/types/api/queries.d.ts +664 -0
  71. package/dist-lib/types/api/resume-reconnect.d.ts +15 -0
  72. package/dist-lib/types/api/socket.d.ts +19 -0
  73. package/dist-lib/types/api/voice.d.ts +33 -0
  74. package/dist-lib/types/auth/AuthProvider.d.ts +15 -0
  75. package/dist-lib/types/auth/AuthShell.d.ts +28 -0
  76. package/dist-lib/types/auth/ChangePasswordPage.d.ts +2 -0
  77. package/dist-lib/types/auth/LoginPage.d.ts +2 -0
  78. package/dist-lib/types/auth/RequireAuth.d.ts +12 -0
  79. package/dist-lib/types/auth/UserMenu.d.ts +5 -0
  80. package/dist-lib/types/components/app/AboutDialog.d.ts +7 -0
  81. package/dist-lib/types/components/app/AppCredits.d.ts +8 -0
  82. package/dist-lib/types/components/app/DesktopUpdates.d.ts +3 -0
  83. package/dist-lib/types/components/app/DevBuildBadge.d.ts +5 -0
  84. package/dist-lib/types/components/app/ErrorBoundary.d.ts +23 -0
  85. package/dist-lib/types/components/app/FeatureRequestAction.d.ts +7 -0
  86. package/dist-lib/types/components/app/SearchField.d.ts +7 -0
  87. package/dist-lib/types/components/app/SegmentedControl.d.ts +19 -0
  88. package/dist-lib/types/components/app/ShareAppAction.d.ts +5 -0
  89. package/dist-lib/types/components/app/index.d.ts +81 -0
  90. package/dist-lib/types/components/ui/alert-dialog.d.ts +18 -0
  91. package/dist-lib/types/components/ui/avatar.d.ts +11 -0
  92. package/dist-lib/types/components/ui/badge.d.ts +9 -0
  93. package/dist-lib/types/components/ui/button.d.ts +10 -0
  94. package/dist-lib/types/components/ui/card.d.ts +9 -0
  95. package/dist-lib/types/components/ui/checkbox.d.ts +4 -0
  96. package/dist-lib/types/components/ui/command.d.ts +18 -0
  97. package/dist-lib/types/components/ui/dialog.d.ts +17 -0
  98. package/dist-lib/types/components/ui/drawer.d.ts +13 -0
  99. package/dist-lib/types/components/ui/dropdown-menu.d.ts +25 -0
  100. package/dist-lib/types/components/ui/input.d.ts +3 -0
  101. package/dist-lib/types/components/ui/label.d.ts +4 -0
  102. package/dist-lib/types/components/ui/popover.d.ts +10 -0
  103. package/dist-lib/types/components/ui/progress.d.ts +4 -0
  104. package/dist-lib/types/components/ui/radio-group.d.ts +5 -0
  105. package/dist-lib/types/components/ui/scroll-area.d.ts +5 -0
  106. package/dist-lib/types/components/ui/select.d.ts +15 -0
  107. package/dist-lib/types/components/ui/separator.d.ts +4 -0
  108. package/dist-lib/types/components/ui/sheet.d.ts +14 -0
  109. package/dist-lib/types/components/ui/skeleton.d.ts +2 -0
  110. package/dist-lib/types/components/ui/sonner.d.ts +4 -0
  111. package/dist-lib/types/components/ui/switch.d.ts +6 -0
  112. package/dist-lib/types/components/ui/table.d.ts +10 -0
  113. package/dist-lib/types/components/ui/tabs.d.ts +11 -0
  114. package/dist-lib/types/components/ui/textarea.d.ts +3 -0
  115. package/dist-lib/types/components/ui/tooltip.d.ts +7 -0
  116. package/dist-lib/types/create-app.d.ts +20 -0
  117. package/dist-lib/types/extensions/context.d.ts +8 -0
  118. package/dist-lib/types/extensions/i18n.d.ts +15 -0
  119. package/dist-lib/types/extensions/index.d.ts +4 -0
  120. package/dist-lib/types/extensions/routes.d.ts +12 -0
  121. package/dist-lib/types/extensions/types.d.ts +116 -0
  122. package/dist-lib/types/i18n/LanguageSelect.d.ts +4 -0
  123. package/dist-lib/types/i18n/LocaleSync.d.ts +2 -0
  124. package/dist-lib/types/i18n/date-locale.d.ts +5 -0
  125. package/dist-lib/types/i18n/index.d.ts +17 -0
  126. package/dist-lib/types/i18n/locale-store.d.ts +26 -0
  127. package/dist-lib/types/i18n/resources.d.ts +1711 -0
  128. package/dist-lib/types/i18n/use-change-locale.d.ts +9 -0
  129. package/dist-lib/types/inbox/ChatAvatar.d.ts +13 -0
  130. package/dist-lib/types/inbox/ChatFilters.d.ts +6 -0
  131. package/dist-lib/types/inbox/ChatList.d.ts +9 -0
  132. package/dist-lib/types/inbox/ChatListItem.d.ts +13 -0
  133. package/dist-lib/types/inbox/Composer.d.ts +30 -0
  134. package/dist-lib/types/inbox/Conversation.d.ts +7 -0
  135. package/dist-lib/types/inbox/ConversationHeader.d.ts +25 -0
  136. package/dist-lib/types/inbox/CustomerPanel.d.ts +32 -0
  137. package/dist-lib/types/inbox/EmojiPicker.d.ts +6 -0
  138. package/dist-lib/types/inbox/EventItem.d.ts +14 -0
  139. package/dist-lib/types/inbox/GettingStartedCard.d.ts +10 -0
  140. package/dist-lib/types/inbox/GroupPanel.d.ts +19 -0
  141. package/dist-lib/types/inbox/InboxPage.d.ts +2 -0
  142. package/dist-lib/types/inbox/MediaView.d.ts +8 -0
  143. package/dist-lib/types/inbox/MessageBubble.d.ts +31 -0
  144. package/dist-lib/types/inbox/MessageList.d.ts +21 -0
  145. package/dist-lib/types/inbox/NotesPanel.d.ts +15 -0
  146. package/dist-lib/types/inbox/PanelHeader.d.ts +13 -0
  147. package/dist-lib/types/inbox/ProfileImageContext.d.ts +5 -0
  148. package/dist-lib/types/inbox/QuickReplyPicker.d.ts +18 -0
  149. package/dist-lib/types/inbox/ReconnectBanner.d.ts +8 -0
  150. package/dist-lib/types/inbox/TagInput.d.ts +14 -0
  151. package/dist-lib/types/inbox/TypingIndicator.d.ts +6 -0
  152. package/dist-lib/types/inbox/VoiceNote.d.ts +36 -0
  153. package/dist-lib/types/inbox/WaBanner.d.ts +9 -0
  154. package/dist-lib/types/inbox/chat-title.d.ts +4 -0
  155. package/dist-lib/types/inbox/navigation-guard.d.ts +17 -0
  156. package/dist-lib/types/inbox/timeline.d.ts +26 -0
  157. package/dist-lib/types/inbox/useCanonicalChatRedirect.d.ts +2 -0
  158. package/dist-lib/types/inbox/useDirectory.d.ts +21 -0
  159. package/dist-lib/types/inbox/useSwipeReply.d.ts +11 -0
  160. package/dist-lib/types/index.d.ts +43 -0
  161. package/dist-lib/types/lib/ai-handoff.d.ts +4 -0
  162. package/dist-lib/types/lib/app-links.d.ts +9 -0
  163. package/dist-lib/types/lib/desktop-updates.d.ts +15 -0
  164. package/dist-lib/types/lib/error-reporter.d.ts +6 -0
  165. package/dist-lib/types/lib/format.d.ts +20 -0
  166. package/dist-lib/types/lib/jid.d.ts +15 -0
  167. package/dist-lib/types/lib/links.d.ts +40 -0
  168. package/dist-lib/types/lib/share-app.d.ts +18 -0
  169. package/dist-lib/types/lib/theme.d.ts +29 -0
  170. package/dist-lib/types/lib/use-media-query.d.ts +2 -0
  171. package/dist-lib/types/lib/utils.d.ts +2 -0
  172. package/dist-lib/types/lib/version.d.ts +12 -0
  173. package/dist-lib/types/lib/voice-recorder.d.ts +26 -0
  174. package/dist-lib/types/pwa/InstallHint.d.ts +9 -0
  175. package/dist-lib/types/pwa/PushToggle.d.ts +20 -0
  176. package/dist-lib/types/pwa/desktop-notifications.d.ts +18 -0
  177. package/dist-lib/types/pwa/push.d.ts +13 -0
  178. package/dist-lib/types/setup/AiAssistantStep.d.ts +9 -0
  179. package/dist-lib/types/setup/SetupWizard.d.ts +3 -0
  180. package/dist-lib/types/setup/WaLinkStep.d.ts +8 -0
  181. package/dist-lib/types/setup/agent-name.d.ts +8 -0
  182. package/dist-lib/types/setup/connected-label.d.ts +7 -0
  183. package/dist-lib/types/setup/username.d.ts +9 -0
  184. package/dist-lib/types/wa/PhoneLink.d.ts +4 -0
  185. package/package.json +81 -4
  186. package/README.md +0 -3
@@ -0,0 +1,20 @@
1
+ import { type WebExtension } from './extensions';
2
+ import { type AppLinks } from './lib/links';
3
+ export interface CreateInboxAppOptions {
4
+ /** UI added by another product build. Lite passes `[]`. */
5
+ extensions?: readonly WebExtension[];
6
+ /** Element to render into; defaults to `#root`. */
7
+ root?: HTMLElement;
8
+ /** Product name shown wherever the UI names the app; defaults to "EzyChat Lite". */
9
+ productName?: string;
10
+ /**
11
+ * Outside links (About, Report an issue, release notes, feedback, support email). Missing
12
+ * entries keep Lite's links; an explicit `null` hides that link.
13
+ */
14
+ links?: Partial<AppLinks>;
15
+ }
16
+ /**
17
+ * Renders the inbox app. Extensions are validated first (a bad extension throws before anything
18
+ * renders) and their catalogs are merged on top of the core catalogs.
19
+ */
20
+ export declare function createInboxApp({ extensions, root, productName, links, }?: CreateInboxAppOptions): Promise<void>;
@@ -0,0 +1,8 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { WebExtension } from './types';
3
+ /** Makes the (already validated) extensions available to the app shell. Lite passes none. */
4
+ export declare function WebExtensionsProvider({ extensions, children, }: {
5
+ extensions: readonly WebExtension[];
6
+ children: ReactNode;
7
+ }): import("react").JSX.Element;
8
+ export declare function useWebExtensions(): readonly WebExtension[];
@@ -0,0 +1,15 @@
1
+ import type { WebExtension } from './types';
2
+ /**
3
+ * Adds extension catalogs to the `common` namespace (the default one), on top of the core
4
+ * catalogs. Keys are `ext.<name>.…`, so they never overwrite a core key; a key missing in one
5
+ * language falls back to English the same way core keys do. Call after `validateWebExtensions`.
6
+ */
7
+ export declare function registerExtensionCatalogs(extensions: readonly WebExtension[]): Promise<void>;
8
+ /** Translates a key that is not in the typed core catalogs. */
9
+ export type ExtensionTranslate = (key: string, options?: Record<string, unknown>) => string;
10
+ /**
11
+ * `t` for extension keys (`ext.<name>.…`, `common` namespace). Core keys are type-checked against
12
+ * the bundled catalogs, which extension keys are not part of; this hook takes any string and
13
+ * re-renders on a language change like `useTranslation`.
14
+ */
15
+ export declare function useExtensionTranslation(): ExtensionTranslate;
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export { WebExtensionsProvider, useWebExtensions } from './context';
3
+ export { registerExtensionCatalogs, useExtensionTranslation, type ExtensionTranslate, } from './i18n';
4
+ export { ExtensionBoundary, extensionRoutes } from './routes';
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { WebExtension } from './types';
3
+ /** Wraps one extension element so a crash inside it never blanks the rest of the app. */
4
+ export declare function ExtensionBoundary({ children }: {
5
+ children: ReactNode;
6
+ }): import("react").JSX.Element;
7
+ /**
8
+ * `<Route>` elements for the extensions' routes of one kind. User routes are absolute
9
+ * (`/ext/<name>/<path>`); admin routes are relative to the admin shell (`ext/<name>/<path>`).
10
+ * The fixed `ext/<name>/` prefix means an extension route can never match a core path.
11
+ */
12
+ export declare function extensionRoutes(extensions: readonly WebExtension[], admin: boolean): ReactNode[];
@@ -0,0 +1,116 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import { type Locale } from '@ezychat/shared';
3
+ /**
4
+ * Web extension API: lets another product build (e.g. Enterprise) add UI without forking Lite.
5
+ *
6
+ * - `routes` mount only under `/ext/<name>/<path>` (signed-in users) or, with `admin: true`, under
7
+ * `/admin/ext/<name>/<path>` inside the admin shell. They can never replace a core route.
8
+ * - `adminNav` links point at the extension's admin routes (`/admin/ext/<name>/<path>`).
9
+ * - `settingsSections` render in Settings → Integrations, below the core sections.
10
+ * - `agentSections` render as rows on an AI agent's page (`/admin/members/ai` for the Sales
11
+ * Agent), right under Business context.
12
+ * - An admin route may declare the core admin `section` it belongs to (e.g. `members` for an
13
+ * agent sub-page): that nav item is highlighted and the phone header shows its label.
14
+ * - An admin nav item may show a small badge (a count or "needs attention") from `useBadge`.
15
+ * - `banners` render in one slim bar at the top of the signed-in shell (inbox and admin); the
16
+ * first banner that renders something wins, the others stay hidden.
17
+ * - `lockScreen` replaces the core "paused" screen while the server's access gate is closed
18
+ * (GET /api/access, or any API call answering 403 with the gate code). It is shown without
19
+ * sign-in; `recheck()` reads the gate again and the app reloads once it is open.
20
+ * - `catalogs` add translation keys to the `common` namespace; every key must start with
21
+ * `ext.<name>.`. A key missing in one language falls back to English like core keys.
22
+ *
23
+ * Every extension element is wrapped in the app's ErrorBoundary.
24
+ */
25
+ export interface WebExtensionRoute {
26
+ /** Relative path below the extension's prefix, e.g. `reports` or `reports/:id`. */
27
+ path: string;
28
+ element: ReactNode;
29
+ /** Mount in the admin shell (admins only) instead of the signed-in user area. */
30
+ admin?: boolean;
31
+ /**
32
+ * Admin routes only: the core admin section this page sits under (e.g. `members` for
33
+ * `/admin/ext/<name>/agents/ai`). Highlights that nav item and names it in the phone header.
34
+ * The page still renders its own breadcrumb.
35
+ */
36
+ section?: WebExtensionAdminSection;
37
+ }
38
+ /** Core admin sections an extension admin route may sit under (the `ADMIN_NAV` paths). */
39
+ export declare const WEB_EXTENSION_ADMIN_SECTIONS: readonly ["members", "quick-replies", "whatsapp", "tunnel", "settings", "audit"];
40
+ export type WebExtensionAdminSection = (typeof WEB_EXTENSION_ADMIN_SECTIONS)[number];
41
+ /** A small badge on an admin nav link: a count, or a dot that asks for attention. */
42
+ export interface WebExtensionNavBadge {
43
+ /** Shown when above 0 (99+ above 99). */
44
+ count?: number;
45
+ /** A dot when there is no count, e.g. a connector that needs signing in again. */
46
+ attention?: boolean;
47
+ /** Translation key (`ext.<name>.…`) read by screen readers, e.g. "2 need attention". */
48
+ labelKey?: string;
49
+ /** Values for `labelKey`'s placeholders. */
50
+ labelValues?: Record<string, string | number>;
51
+ }
52
+ export interface WebExtensionNavItem {
53
+ /** Path of one of this extension's admin routes (relative, as in `routes[].path`). */
54
+ path: string;
55
+ /** Translation key (`ext.<name>.…`) of the link label. */
56
+ labelKey: string;
57
+ icon?: ComponentType<{
58
+ className?: string;
59
+ 'aria-hidden'?: boolean;
60
+ }>;
61
+ /**
62
+ * React hook (called on every admin render, so keep it cheap: read a cached query) returning
63
+ * the badge to show, or null for none. Errors in it hide the badge, never the nav.
64
+ */
65
+ useBadge?: () => WebExtensionNavBadge | null;
66
+ }
67
+ /** The AI agents whose page can hold extension rows. Only the Sales Agent exists today. */
68
+ export type WebExtensionAgent = 'sales';
69
+ export interface WebExtensionAgentSection {
70
+ agent: WebExtensionAgent;
71
+ /** Unique within the extension; lowercase letters, digits and dashes. */
72
+ id: string;
73
+ /** One compact row (e.g. "Connectors · 2 connected · Manage ›"); details on its own page. */
74
+ element: ReactNode;
75
+ }
76
+ export interface WebExtensionSettingsSection {
77
+ /** Unique within the extension; lowercase letters, digits and dashes. */
78
+ id: string;
79
+ /** Translation key (`ext.<name>.…`) of the section heading. */
80
+ titleKey: string;
81
+ element: ReactNode;
82
+ }
83
+ /** Props of an extension's lock screen. */
84
+ export interface WebExtensionLockScreenProps {
85
+ /** The gate code from the server, e.g. `license_required`. */
86
+ code: string;
87
+ /** Read GET /api/access again now (the app reloads when access is open). */
88
+ recheck: () => void;
89
+ }
90
+ export type WebExtensionCatalogs = Partial<Record<Locale, Record<string, string>>>;
91
+ export interface WebExtension {
92
+ /** Lowercase id, 2–32 characters: `/^[a-z][a-z0-9-]{1,31}$/`; not `lite` or `core`. */
93
+ name: string;
94
+ routes?: WebExtensionRoute[];
95
+ adminNav?: WebExtensionNavItem[];
96
+ settingsSections?: WebExtensionSettingsSection[];
97
+ agentSections?: WebExtensionAgentSection[];
98
+ /** Slim one-line bars for the top of the signed-in shell; the first non-empty one is shown. */
99
+ banners?: ComponentType[];
100
+ /** Full-page screen while access is closed; the first extension that has one wins. */
101
+ lockScreen?: ComponentType<WebExtensionLockScreenProps>;
102
+ catalogs?: WebExtensionCatalogs;
103
+ }
104
+ export declare const EXTENSION_NAME_PATTERN: RegExp;
105
+ export declare class WebExtensionError extends Error {
106
+ name: string;
107
+ }
108
+ /** Prefix that every catalog, nav and section key of an extension must start with. */
109
+ export declare function extensionKeyPrefix(name: string): string;
110
+ /** URL of an extension route. */
111
+ export declare function extensionPath(name: string, path: string, admin?: boolean): string;
112
+ /**
113
+ * Checks a list of extensions and throws a `WebExtensionError` naming the first problem.
114
+ * Returns the same list so callers can write `validateWebExtensions(list)` inline.
115
+ */
116
+ export declare function validateWebExtensions(extensions: readonly WebExtension[]): readonly WebExtension[];
@@ -0,0 +1,4 @@
1
+ /** Compact language picker for screens without the account menu (sign-in, setup). */
2
+ export declare function LanguageSelect({ className }: {
3
+ className?: string;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ /** Applies the signed-in user's saved language (it follows them across browsers and devices). */
2
+ export declare function LocaleSync(): null;
@@ -0,0 +1,5 @@
1
+ import type { Locale as DateFnsLocale } from 'date-fns';
2
+ import type { Locale } from '@ezychat/shared';
3
+ export declare function loadDateLocale(locale: Locale): Promise<void>;
4
+ /** date-fns locale of the active UI language (English until another one has loaded). */
5
+ export declare function dateLocale(): DateFnsLocale;
@@ -0,0 +1,17 @@
1
+ import i18n from 'i18next';
2
+ import { type Locale } from '@ezychat/shared';
3
+ /** Product name used by catalog strings through `{{product}}`; another edition replaces it. */
4
+ export declare const DEFAULT_PRODUCT_NAME = "EzyChat Lite";
5
+ /**
6
+ * Sets the product name every `{{product}}` in the catalogs shows (e.g. "EzyChat Enterprise").
7
+ * i18next reads default variables on each translation, so this also applies after init.
8
+ */
9
+ export declare function setProductName(name: string): void;
10
+ /** Initializes i18next once with the English catalogs bundled. */
11
+ export declare function initI18n(): Promise<unknown>;
12
+ /**
13
+ * Loads a language's catalogs and date-fns locale, then switches to it. When calls overlap, only
14
+ * the most recent one is applied.
15
+ */
16
+ export declare function activateLocale(locale: Locale): Promise<void>;
17
+ export { i18n };
@@ -0,0 +1,26 @@
1
+ import { type Locale } from '@ezychat/shared';
2
+ export declare const LOCALE_STORAGE_KEY = "wati.locale";
3
+ /**
4
+ * The active UI language. Order: the signed-in user's saved choice (applied by `LocaleSync`),
5
+ * then this browser's last choice (`wati.locale`), then the browser languages, then English.
6
+ * Changes are shared with other tabs through the storage event.
7
+ */
8
+ export declare function createLocaleStore(target?: Window): {
9
+ getSnapshot: () => "en" | "ms" | "zh-CN";
10
+ subscribe(listener: () => void): () => boolean;
11
+ /** Applies the initial language; on failure the UI (and snapshot) stay English. */
12
+ ready(): Promise<void>;
13
+ /** Resolves once the language is active; rejects (keeping the current one) if it can't load. */
14
+ setLocale(next: Locale): Promise<void>;
15
+ dispose(): void;
16
+ };
17
+ export declare const localeStore: {
18
+ getSnapshot: () => "en" | "ms" | "zh-CN";
19
+ subscribe(listener: () => void): () => boolean;
20
+ /** Applies the initial language; on failure the UI (and snapshot) stay English. */
21
+ ready(): Promise<void>;
22
+ /** Resolves once the language is active; rejects (keeping the current one) if it can't load. */
23
+ setLocale(next: Locale): Promise<void>;
24
+ dispose(): void;
25
+ };
26
+ export declare function useLocale(): Locale;