@mailoo/chat 0.0.0-stage → 1.33.0

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 (58) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +152 -2
  3. package/dist/chat-message-Dw6tKBEb.d.cts +10 -0
  4. package/dist/chat-message-Dw6tKBEb.d.ts +10 -0
  5. package/dist/chunk-2Y37RYEL.js +141 -0
  6. package/dist/chunk-2Y37RYEL.js.map +1 -0
  7. package/dist/chunk-4TNHJERE.js +19 -0
  8. package/dist/chunk-4TNHJERE.js.map +1 -0
  9. package/dist/chunk-77E6HUHY.js +41 -0
  10. package/dist/chunk-77E6HUHY.js.map +1 -0
  11. package/dist/chunk-AU6EFFLV.js +431 -0
  12. package/dist/chunk-AU6EFFLV.js.map +1 -0
  13. package/dist/chunk-QZ7HWQDO.js +839 -0
  14. package/dist/chunk-QZ7HWQDO.js.map +1 -0
  15. package/dist/client/index.cjs +1658 -0
  16. package/dist/client/index.cjs.map +1 -0
  17. package/dist/client/index.d.cts +33 -0
  18. package/dist/client/index.d.ts +33 -0
  19. package/dist/client/index.js +597 -0
  20. package/dist/client/index.js.map +1 -0
  21. package/dist/hooks/index.cjs +751 -0
  22. package/dist/hooks/index.cjs.map +1 -0
  23. package/dist/hooks/index.d.cts +79 -0
  24. package/dist/hooks/index.d.ts +79 -0
  25. package/dist/hooks/index.js +32 -0
  26. package/dist/hooks/index.js.map +1 -0
  27. package/dist/index.cjs +213 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +53 -0
  30. package/dist/index.d.ts +53 -0
  31. package/dist/index.js +27 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/mailoo-site-chat-widget-C7B797Lu.d.ts +130 -0
  34. package/dist/mailoo-site-chat-widget-h_cBqsJw.d.cts +130 -0
  35. package/dist/routes/index.cjs +204 -0
  36. package/dist/routes/index.cjs.map +1 -0
  37. package/dist/routes/index.d.cts +30 -0
  38. package/dist/routes/index.d.ts +30 -0
  39. package/dist/routes/index.js +174 -0
  40. package/dist/routes/index.js.map +1 -0
  41. package/dist/shared-glVmghqk.d.cts +40 -0
  42. package/dist/shared-glVmghqk.d.ts +40 -0
  43. package/dist/styles/widget.css +122 -0
  44. package/dist/welcome-presets/index.cjs +479 -0
  45. package/dist/welcome-presets/index.cjs.map +1 -0
  46. package/dist/welcome-presets/index.d.cts +53 -0
  47. package/dist/welcome-presets/index.d.ts +53 -0
  48. package/dist/welcome-presets/index.js +38 -0
  49. package/dist/welcome-presets/index.js.map +1 -0
  50. package/dist/welcome-presets/parse.cjs +44 -0
  51. package/dist/welcome-presets/parse.cjs.map +1 -0
  52. package/dist/welcome-presets/parse.d.cts +11 -0
  53. package/dist/welcome-presets/parse.d.ts +11 -0
  54. package/dist/welcome-presets/parse.js +9 -0
  55. package/dist/welcome-presets/parse.js.map +1 -0
  56. package/dist/widget-config-B5Tf7gqn.d.cts +32 -0
  57. package/dist/widget-config-B5Tf7gqn.d.ts +32 -0
  58. package/package.json +85 -3
package/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Mailoo Integrator Use License
2
+
3
+ Copyright (c) 2026 Mailoo
4
+
5
+ Permission is granted to use, install, and distribute this software in
6
+ unmodified form, including as a dependency of an application.
7
+
8
+ Modification of this software is not permitted.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,153 @@
1
- # Temporary Holding Version
1
+ # `@mailoo/chat`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ JSBOX visitor chat: BFF route factories, headless hooks, and a floating widget.
4
+
5
+ Install from npm together with `@mailoo/next-core`. Peer: `@heroicons/react`.
6
+ Inside this monorepo, `apps/web` uses `workspace:*`.
7
+
8
+ ## Requirements
9
+
10
+ - Env: `MAILOO_CHAT_INTEGRATION_{API,API_KEY,PROJECT_UID,ID}`
11
+ - Optional: `MAILOO_CHAT_WS_ORIGIN` (public API host for WSS), `MAILOO_CHAT_WELCOME_MESSAGE`
12
+ - Browser opens WebSocket **directly** to Mailoo API (`/api/v1/chat/visitor-ws`). Ingress must support Upgrade.
13
+
14
+ ## Routes (no Auth.js coupling)
15
+
16
+ ```ts
17
+ import {
18
+ createChatSubmitHandler,
19
+ createChatMessagesHandler,
20
+ createChatStatusHandler,
21
+ createChatWidgetConfigHandler,
22
+ } from '@mailoo/chat/routes'
23
+
24
+ export const POST = createChatSubmitHandler({
25
+ // optional: inject session email
26
+ resolveSender: async () => {
27
+ const session = await auth()
28
+ return session?.user?.email
29
+ ? { email: session.user.email, name: session.user.name ?? undefined }
30
+ : null
31
+ },
32
+ })
33
+
34
+ export const GET = createChatMessagesHandler()
35
+ ```
36
+
37
+ Status (optional): `createChatStatusHandler()` → `GET /api/v1/webhooks/chat/status`.
38
+ Widget-config (optional BFF): `createChatWidgetConfigHandler()`.
39
+
40
+ Config helpers from `@mailoo/chat`: `getMailooChatIntegrationConfig`,
41
+ `getMailooChatWebSocketOrigin`, `fetchMailooChatIntegrationStatus`,
42
+ `fetchMailooChatWidgetConfig` (null on failure), `resolveMailooChatHostConfig`.
43
+
44
+ ## Default floating widget (recommended)
45
+
46
+ Server Component layout:
47
+
48
+ ```tsx
49
+ import { resolveMailooChatHostConfig } from '@mailoo/chat'
50
+ import { MailooSiteChatShell } from '@mailoo/chat/client'
51
+ import { auth } from '@/auth'
52
+
53
+ const session = await auth()
54
+ const chat = await resolveMailooChatHostConfig({
55
+ locale,
56
+ isAuthenticated: Boolean(session?.user?.email),
57
+ })
58
+
59
+ {
60
+ chat ? <MailooSiteChatShell chat={chat} /> : null
61
+ }
62
+ ```
63
+
64
+ `resolveMailooChatHostConfig` returns `null` when env is incomplete or
65
+ widget-config cannot load (HTTP errors, network, invalid payload). It **never
66
+ throws** — hosts must keep the page HTTP 200 and simply omit the chat shell.
67
+ When resolve succeeds it **always** loads JSBOX `config.chatWidget` (brand,
68
+ topics, position, welcome, privacy, operators) as `widgetConfig`. Call
69
+ `openMailooSiteChat()` from any client component to open the panel.
70
+
71
+ ## Hooks
72
+
73
+ ```ts
74
+ import {
75
+ useMailooChatSession,
76
+ useMailooChatSubmit,
77
+ useMailooChatMessages,
78
+ useMailooChatStatus,
79
+ } from '@mailoo/chat/hooks'
80
+ ```
81
+
82
+ `useMailooChatSession` owns session storage, guest profile, send, poll (`since`),
83
+ and visitor WebSocket. Pass `enabled` to gate realtime (the widget uses panel open).
84
+
85
+ ## Widget (custom / headless UI)
86
+
87
+ Host CSS **must** import the widget shell (position + launcher do not rely on
88
+ host Tailwind scanning this package). Prefer a path PostCSS can resolve
89
+ (monorepo relative or package export):
90
+
91
+ ```css
92
+ /* monorepo */
93
+ @import '../../../packages/chat/src/styles/widget.css';
94
+ /* or published package */
95
+ @import '@mailoo/chat/styles';
96
+ /* Tailwind v4: also scan package sources if you style with utilities */
97
+ @source '../node_modules/@mailoo/chat/src/**/*.{ts,tsx}';
98
+ ```
99
+
100
+ ```tsx
101
+ import { MailooSiteChatWidget } from '@mailoo/chat/client'
102
+
103
+ ;<MailooSiteChatWidget
104
+ apiOrigin={wsOrigin}
105
+ projectUid={projectUid}
106
+ integrationId={integrationId}
107
+ welcomeMessage={welcome}
108
+ locale={locale}
109
+ isAuthenticated={isAuthenticated}
110
+ widgetConfig={widgetConfig}
111
+ />
112
+ ```
113
+
114
+ Prefer `resolveMailooChatHostConfig` + `MailooSiteChatShell` so brand/topics are
115
+ not omitted. For a custom UI, pass `widgetConfig` from
116
+ `fetchMailooChatWidgetConfig` (or BFF `…/widget-config`). Brand colors
117
+ (`brandPrimary` / `brandOnPrimary`), welcome title/tagline, topics, operators,
118
+ and launcher `position` come from the JSBOX dashboard **Widget** tab.
119
+
120
+ Optional: `className` / `panelClassName` / `launcherClassName`, controlled
121
+ `open` / `onOpenChange`, `labels`, endpoint overrides, host `position`
122
+ override (wins over `widgetConfig.position`), `zIndex`,
123
+ `onSessionCreated` / `onMessageSent` / `onError` / `onFault`, and small render
124
+ slots.
125
+
126
+ ### Chat unavailable / rate limit
127
+
128
+ On submit or message poll, the package classifies **429** as `rate_limited` and
129
+ network / **502** / **503** / other **5xx** as `unavailable`, stops polling, and
130
+ shows a built-in panel (not raw API text). Pass an integrator action or custom
131
+ UI via `MailooSiteChatShell` / `MailooSiteChatWidget`:
132
+
133
+ ```tsx
134
+ <MailooSiteChatShell
135
+ chat={chat}
136
+ unavailableAction={{ type: 'mailto', email: 'support@example.com' }}
137
+ // or: { type: 'link', href: '/support', label: 'Contact support' }
138
+ // or: renderUnavailable={({ fault, labels, retry }) => …}
139
+ />
140
+ ```
141
+
142
+ Headless: `useMailooChatSession` exposes `fault`, `onFault`, and
143
+ `retryAfterFault`. Widget-config load still **fail-fast** before mount — this
144
+ panel is only for post-mount send/poll failures.
145
+
146
+ ## Welcome presets
147
+
148
+ - **Client barrel** `@mailoo/chat/welcome-presets` — Provider, Switcher, renderers
149
+ (`'use client'`). Safe to import as components from Server Components; do **not**
150
+ call exported functions from the server. Optional around `MailooSiteChatShell`.
151
+ - **Server-safe parse** `@mailoo/chat/welcome-presets/parse` — `parseMailooChatWelcomePreset`
152
+ and related types only (no `'use client'`). Use this from RSC / env helpers
153
+ (e.g. `MAILOO_CHAT_WELCOME_PRESET`).
@@ -0,0 +1,10 @@
1
+ type MailooChatMessage = {
2
+ id: string;
3
+ messageType: string;
4
+ content: string;
5
+ senderEmail?: string | null;
6
+ senderName?: string | null;
7
+ createdAt: string;
8
+ };
9
+
10
+ export type { MailooChatMessage as M };
@@ -0,0 +1,10 @@
1
+ type MailooChatMessage = {
2
+ id: string;
3
+ messageType: string;
4
+ content: string;
5
+ senderEmail?: string | null;
6
+ senderName?: string | null;
7
+ createdAt: string;
8
+ };
9
+
10
+ export type { MailooChatMessage as M };
@@ -0,0 +1,141 @@
1
+ // src/config.ts
2
+ import { unstable_rethrow } from "next/navigation";
3
+ import {
4
+ defaultMailooLogger,
5
+ readMailooIntegrationConfig
6
+ } from "@mailoo/next-core";
7
+ function getMailooChatIntegrationConfig() {
8
+ return readMailooIntegrationConfig({
9
+ prefix: "MAILOO_CHAT_INTEGRATION",
10
+ allowApiBaseUrlFallback: true
11
+ });
12
+ }
13
+ function getMailooChatWebSocketOrigin() {
14
+ const explicit = process.env.MAILOO_CHAT_WS_ORIGIN?.trim();
15
+ if (explicit) {
16
+ return explicit.replace(/\/$/, "");
17
+ }
18
+ const chatCfg = getMailooChatIntegrationConfig();
19
+ if (chatCfg?.apiBaseUrl) {
20
+ return chatCfg.apiBaseUrl.replace(/\/$/, "");
21
+ }
22
+ const chatApi = process.env.MAILOO_CHAT_INTEGRATION_API?.trim();
23
+ if (chatApi) {
24
+ return chatApi.replace(/\/$/, "");
25
+ }
26
+ const api = process.env.API_BASE_URL?.trim();
27
+ if (api) {
28
+ return api.replace(/\/$/, "");
29
+ }
30
+ return null;
31
+ }
32
+ async function fetchMailooChatIntegrationStatus() {
33
+ const cfg = getMailooChatIntegrationConfig();
34
+ if (!cfg) return null;
35
+ try {
36
+ const url = `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/status`;
37
+ const response = await fetch(url, {
38
+ method: "GET",
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ "X-API-Key": cfg.apiKey
42
+ }
43
+ });
44
+ if (!response.ok) return null;
45
+ const data = await response.json();
46
+ if (typeof data.status !== "string" || typeof data.name !== "string" || typeof data.type !== "string" || typeof data.lastActivity !== "string") {
47
+ return null;
48
+ }
49
+ return {
50
+ status: data.status,
51
+ name: data.name,
52
+ type: data.type,
53
+ lastActivity: data.lastActivity
54
+ };
55
+ } catch (error) {
56
+ unstable_rethrow(error);
57
+ return null;
58
+ }
59
+ }
60
+ async function fetchMailooChatWidgetConfig(locale) {
61
+ const cfg = getMailooChatIntegrationConfig();
62
+ if (!cfg) {
63
+ return null;
64
+ }
65
+ try {
66
+ const url = new URL(
67
+ `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/widget-config`
68
+ );
69
+ url.searchParams.set("locale", locale);
70
+ const response = await fetch(url.toString(), {
71
+ method: "GET",
72
+ headers: {
73
+ "Content-Type": "application/json",
74
+ "X-API-Key": cfg.apiKey
75
+ }
76
+ });
77
+ if (!response.ok) {
78
+ defaultMailooLogger.warn?.(
79
+ `Failed to fetch chat widget config: HTTP ${response.status}`
80
+ );
81
+ return null;
82
+ }
83
+ const data = await response.json();
84
+ if (!data.widget || !Array.isArray(data.widget.topics)) {
85
+ defaultMailooLogger.warn?.(
86
+ "Failed to fetch chat widget config: invalid response (missing widget.topics)"
87
+ );
88
+ return null;
89
+ }
90
+ return {
91
+ ...data.widget,
92
+ topics: data.widget.topics,
93
+ operators: Array.isArray(data.widget.operators) ? data.widget.operators : []
94
+ };
95
+ } catch (error) {
96
+ unstable_rethrow(error);
97
+ defaultMailooLogger.logException?.(
98
+ error,
99
+ "Failed to fetch chat widget config"
100
+ );
101
+ return null;
102
+ }
103
+ }
104
+ async function resolveMailooChatHostConfig(opts) {
105
+ try {
106
+ const server = getMailooChatIntegrationConfig();
107
+ if (!server) return null;
108
+ const apiOrigin = getMailooChatWebSocketOrigin();
109
+ if (!apiOrigin) return null;
110
+ const locale = opts.locale.trim() || "en";
111
+ const widgetConfig = await fetchMailooChatWidgetConfig(locale);
112
+ if (!widgetConfig) return null;
113
+ const welcomeOverride = process.env.MAILOO_CHAT_WELCOME_MESSAGE?.trim();
114
+ const welcomeMessage = welcomeOverride || widgetConfig.welcomeTagline?.trim() || "";
115
+ return {
116
+ apiOrigin,
117
+ projectUid: server.projectUid,
118
+ integrationId: server.integrationId,
119
+ welcomeMessage,
120
+ locale,
121
+ isAuthenticated: Boolean(opts.isAuthenticated),
122
+ widgetConfig
123
+ };
124
+ } catch (error) {
125
+ unstable_rethrow(error);
126
+ defaultMailooLogger.logException?.(
127
+ error,
128
+ "resolveMailooChatHostConfig failed"
129
+ );
130
+ return null;
131
+ }
132
+ }
133
+
134
+ export {
135
+ getMailooChatIntegrationConfig,
136
+ getMailooChatWebSocketOrigin,
137
+ fetchMailooChatIntegrationStatus,
138
+ fetchMailooChatWidgetConfig,
139
+ resolveMailooChatHostConfig
140
+ };
141
+ //# sourceMappingURL=chunk-2Y37RYEL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { unstable_rethrow } from 'next/navigation'\nimport {\n defaultMailooLogger,\n readMailooIntegrationConfig,\n type MailooIntegrationConfig,\n} from '@mailoo/next-core'\nimport type { MailooChatWidgetConfig } from './lib/widget-config.js'\n\nexport type MailooChatIntegrationConfig = MailooIntegrationConfig\n\nexport function getMailooChatIntegrationConfig(): MailooChatIntegrationConfig | null {\n return readMailooIntegrationConfig({\n prefix: 'MAILOO_CHAT_INTEGRATION',\n allowApiBaseUrlFallback: true,\n })\n}\n\n/**\n * Base URL the browser uses for Mailoo chat WebSockets (ws/wss).\n * Precedence: MAILOO_CHAT_WS_ORIGIN → chat API base → API_BASE_URL.\n * The host must expose WebSocket upgrade on the public API hostname.\n */\nexport function getMailooChatWebSocketOrigin(): string | null {\n const explicit = process.env.MAILOO_CHAT_WS_ORIGIN?.trim()\n if (explicit) {\n return explicit.replace(/\\/$/, '')\n }\n const chatCfg = getMailooChatIntegrationConfig()\n if (chatCfg?.apiBaseUrl) {\n return chatCfg.apiBaseUrl.replace(/\\/$/, '')\n }\n const chatApi = process.env.MAILOO_CHAT_INTEGRATION_API?.trim()\n if (chatApi) {\n return chatApi.replace(/\\/$/, '')\n }\n const api = process.env.API_BASE_URL?.trim()\n if (api) {\n return api.replace(/\\/$/, '')\n }\n return null\n}\n\nexport type MailooChatIntegrationStatus = {\n status: string\n name: string\n type: string\n lastActivity: string\n}\n\nexport type { MailooChatWidgetConfig } from './lib/widget-config.js'\nexport {\n chatWidgetCssVariables,\n isMailooChatLauncherPosition,\n mailooChatLauncherRootClassNames,\n resolveMailooChatLauncherPosition,\n MAILOO_CHAT_LAUNCHER_POSITIONS,\n type MailooChatLauncherPosition,\n type MailooChatWidgetOperator,\n type MailooChatWidgetTopic,\n} from './lib/widget-config.js'\n\n/**\n * Server-side status check against Mailoo (API key from env).\n * Returns null when chat is not configured or the request fails.\n */\nexport async function fetchMailooChatIntegrationStatus(): Promise<MailooChatIntegrationStatus | null> {\n const cfg = getMailooChatIntegrationConfig()\n if (!cfg) return null\n try {\n const url = `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/status`\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': cfg.apiKey,\n },\n })\n if (!response.ok) return null\n const data = (await response.json()) as Partial<MailooChatIntegrationStatus>\n if (\n typeof data.status !== 'string' ||\n typeof data.name !== 'string' ||\n typeof data.type !== 'string' ||\n typeof data.lastActivity !== 'string'\n ) {\n return null\n }\n return {\n status: data.status,\n name: data.name,\n type: data.type,\n lastActivity: data.lastActivity,\n }\n } catch (error) {\n unstable_rethrow(error)\n return null\n }\n}\n\n/**\n * Server-side widget config from Mailoo API (brand, operators, topics, privacy).\n * Returns null when env is missing, the request fails, or the payload is invalid.\n * Never throws — hosts must not 500 the page when chat bootstrap fails.\n */\nexport async function fetchMailooChatWidgetConfig(\n locale: string\n): Promise<MailooChatWidgetConfig | null> {\n const cfg = getMailooChatIntegrationConfig()\n if (!cfg) {\n return null\n }\n try {\n const url = new URL(\n `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/widget-config`\n )\n url.searchParams.set('locale', locale)\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': cfg.apiKey,\n },\n })\n if (!response.ok) {\n defaultMailooLogger.warn?.(\n `Failed to fetch chat widget config: HTTP ${response.status}`\n )\n return null\n }\n const data = (await response.json()) as {\n widget?: MailooChatWidgetConfig\n }\n if (!data.widget || !Array.isArray(data.widget.topics)) {\n defaultMailooLogger.warn?.(\n 'Failed to fetch chat widget config: invalid response (missing widget.topics)'\n )\n return null\n }\n return {\n ...data.widget,\n topics: data.widget.topics,\n operators: Array.isArray(data.widget.operators)\n ? data.widget.operators\n : [],\n }\n } catch (error) {\n unstable_rethrow(error)\n defaultMailooLogger.logException?.(\n error,\n 'Failed to fetch chat widget config'\n )\n return null\n }\n}\n\n/** Props for {@link MailooSiteChatShell} / floating widget host. */\nexport type MailooChatHostConfig = {\n apiOrigin: string\n projectUid: string\n integrationId: string\n welcomeMessage: string\n locale: string\n isAuthenticated: boolean\n /** Always present when resolve succeeds — brand, topics, position, etc. */\n widgetConfig: MailooChatWidgetConfig\n}\n\n/**\n * Default host resolve: env + public JSBOX widget-config.\n * Returns null when chat env is incomplete or widget-config cannot load\n * (do not mount the widget). Never throws — page hosts must stay HTTP 200.\n */\nexport async function resolveMailooChatHostConfig(opts: {\n locale: string\n isAuthenticated?: boolean\n}): Promise<MailooChatHostConfig | null> {\n try {\n const server = getMailooChatIntegrationConfig()\n if (!server) return null\n\n const apiOrigin = getMailooChatWebSocketOrigin()\n if (!apiOrigin) return null\n\n const locale = opts.locale.trim() || 'en'\n const widgetConfig = await fetchMailooChatWidgetConfig(locale)\n if (!widgetConfig) return null\n\n const welcomeOverride = process.env.MAILOO_CHAT_WELCOME_MESSAGE?.trim()\n const welcomeMessage =\n welcomeOverride || widgetConfig.welcomeTagline?.trim() || ''\n\n return {\n apiOrigin,\n projectUid: server.projectUid,\n integrationId: server.integrationId,\n welcomeMessage,\n locale,\n isAuthenticated: Boolean(opts.isAuthenticated),\n widgetConfig,\n }\n } catch (error) {\n unstable_rethrow(error)\n defaultMailooLogger.logException?.(\n error,\n 'resolveMailooChatHostConfig failed'\n )\n return null\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,19 @@
1
+ // src/welcome-presets/types.ts
2
+ function parseMailooChatWelcomePreset(value) {
3
+ const trimmed = value?.trim();
4
+ if (trimmed === "builtin" || trimmed === "team" || trimmed === "assistant") {
5
+ return trimmed;
6
+ }
7
+ return null;
8
+ }
9
+ function normalizeLegacyWelcomePresetId(value) {
10
+ if (value === "delinea") return "team";
11
+ if (value === "mia") return "assistant";
12
+ return parseMailooChatWelcomePreset(value);
13
+ }
14
+
15
+ export {
16
+ parseMailooChatWelcomePreset,
17
+ normalizeLegacyWelcomePresetId
18
+ };
19
+ //# sourceMappingURL=chunk-4TNHJERE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/welcome-presets/types.ts"],"sourcesContent":["export type MailooChatWelcomePresetId = 'builtin' | 'team' | 'assistant'\n\nexport type MailooChatWelcomePresetOption = {\n id: MailooChatWelcomePresetId\n label: string\n description: string\n}\n\nexport function parseMailooChatWelcomePreset(\n value: string | undefined | null\n): MailooChatWelcomePresetId | null {\n const trimmed = value?.trim()\n if (trimmed === 'builtin' || trimmed === 'team' || trimmed === 'assistant') {\n return trimmed\n }\n return null\n}\n\n/** Maps legacy preset ids from earlier builds (localStorage only). */\nexport function normalizeLegacyWelcomePresetId(\n value: string\n): MailooChatWelcomePresetId | null {\n if (value === 'delinea') return 'team'\n if (value === 'mia') return 'assistant'\n return parseMailooChatWelcomePreset(value)\n}\n"],"mappings":";AAQO,SAAS,6BACd,OACkC;AAClC,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,YAAY,aAAa,YAAY,UAAU,YAAY,aAAa;AAC1E,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,+BACd,OACkC;AAClC,MAAI,UAAU,UAAW,QAAO;AAChC,MAAI,UAAU,MAAO,QAAO;AAC5B,SAAO,6BAA6B,KAAK;AAC3C;","names":[]}
@@ -0,0 +1,41 @@
1
+ // src/lib/widget-config.ts
2
+ var MAILOO_CHAT_LAUNCHER_POSITIONS = [
3
+ "bottom-right",
4
+ "bottom-left",
5
+ "top-right",
6
+ "top-left",
7
+ "middle-right",
8
+ "middle-left"
9
+ ];
10
+ function isMailooChatLauncherPosition(value) {
11
+ return typeof value === "string" && MAILOO_CHAT_LAUNCHER_POSITIONS.includes(value);
12
+ }
13
+ function resolveMailooChatLauncherPosition(prop, config) {
14
+ if (prop) return prop;
15
+ if (config?.position && isMailooChatLauncherPosition(config.position)) {
16
+ return config.position;
17
+ }
18
+ return "bottom-right";
19
+ }
20
+ function mailooChatLauncherRootClassNames(position) {
21
+ const parts = ["mailoo-chat-root"];
22
+ if (position.endsWith("-left")) parts.push("mailoo-chat-root--left");
23
+ if (position.startsWith("top-")) parts.push("mailoo-chat-root--top");
24
+ if (position.startsWith("middle-")) parts.push("mailoo-chat-root--middle");
25
+ return parts.join(" ");
26
+ }
27
+ function chatWidgetCssVariables(config) {
28
+ return {
29
+ ["--mailoo-chat-brand"]: config?.brandPrimary ?? "#2563EB",
30
+ ["--mailoo-chat-brand-on"]: config?.brandOnPrimary ?? "#FFFFFF"
31
+ };
32
+ }
33
+
34
+ export {
35
+ MAILOO_CHAT_LAUNCHER_POSITIONS,
36
+ isMailooChatLauncherPosition,
37
+ resolveMailooChatLauncherPosition,
38
+ mailooChatLauncherRootClassNames,
39
+ chatWidgetCssVariables
40
+ };
41
+ //# sourceMappingURL=chunk-77E6HUHY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/widget-config.ts"],"sourcesContent":["import type { CSSProperties } from 'react'\n\nexport type MailooChatWidgetTopic = {\n id: string\n label: string\n action: 'start_chat' | 'external_url'\n externalUrl?: string\n}\n\nexport type MailooChatWidgetOperator = {\n userId: string\n name: string | null\n image: string | null\n online: boolean\n}\n\nexport const MAILOO_CHAT_LAUNCHER_POSITIONS = [\n 'bottom-right',\n 'bottom-left',\n 'top-right',\n 'top-left',\n 'middle-right',\n 'middle-left',\n] as const\n\nexport type MailooChatLauncherPosition =\n (typeof MAILOO_CHAT_LAUNCHER_POSITIONS)[number]\n\nexport type MailooChatWidgetConfig = {\n brandPrimary?: string\n brandOnPrimary?: string\n welcomeTitle?: string\n welcomeTagline?: string\n privacyPolicyUrl?: string\n position?: MailooChatLauncherPosition\n topics: MailooChatWidgetTopic[]\n operators: MailooChatWidgetOperator[]\n}\n\nexport function isMailooChatLauncherPosition(\n value: unknown\n): value is MailooChatLauncherPosition {\n return (\n typeof value === 'string' &&\n (MAILOO_CHAT_LAUNCHER_POSITIONS as readonly string[]).includes(value)\n )\n}\n\nexport function resolveMailooChatLauncherPosition(\n prop: MailooChatLauncherPosition | undefined,\n config: Pick<MailooChatWidgetConfig, 'position'> | null | undefined\n): MailooChatLauncherPosition {\n if (prop) return prop\n if (config?.position && isMailooChatLauncherPosition(config.position)) {\n return config.position\n }\n return 'bottom-right'\n}\n\nexport function mailooChatLauncherRootClassNames(\n position: MailooChatLauncherPosition\n): string {\n const parts = ['mailoo-chat-root']\n if (position.endsWith('-left')) parts.push('mailoo-chat-root--left')\n if (position.startsWith('top-')) parts.push('mailoo-chat-root--top')\n if (position.startsWith('middle-')) parts.push('mailoo-chat-root--middle')\n return parts.join(' ')\n}\n\nexport function chatWidgetCssVariables(\n config: Pick<\n MailooChatWidgetConfig,\n 'brandPrimary' | 'brandOnPrimary'\n > | null | undefined\n): CSSProperties {\n return {\n ['--mailoo-chat-brand' as string]: config?.brandPrimary ?? '#2563EB',\n ['--mailoo-chat-brand-on' as string]: config?.brandOnPrimary ?? '#FFFFFF',\n }\n}\n"],"mappings":";AAgBO,IAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAgBO,SAAS,6BACd,OACqC;AACrC,SACE,OAAO,UAAU,YAChB,+BAAqD,SAAS,KAAK;AAExE;AAEO,SAAS,kCACd,MACA,QAC4B;AAC5B,MAAI,KAAM,QAAO;AACjB,MAAI,QAAQ,YAAY,6BAA6B,OAAO,QAAQ,GAAG;AACrE,WAAO,OAAO;AAAA,EAChB;AACA,SAAO;AACT;AAEO,SAAS,iCACd,UACQ;AACR,QAAM,QAAQ,CAAC,kBAAkB;AACjC,MAAI,SAAS,SAAS,OAAO,EAAG,OAAM,KAAK,wBAAwB;AACnE,MAAI,SAAS,WAAW,MAAM,EAAG,OAAM,KAAK,uBAAuB;AACnE,MAAI,SAAS,WAAW,SAAS,EAAG,OAAM,KAAK,0BAA0B;AACzE,SAAO,MAAM,KAAK,GAAG;AACvB;AAEO,SAAS,uBACd,QAIe;AACf,SAAO;AAAA,IACL,CAAC,qBAA+B,GAAG,QAAQ,gBAAgB;AAAA,IAC3D,CAAC,wBAAkC,GAAG,QAAQ,kBAAkB;AAAA,EAClE;AACF;","names":[]}