@gamaro.io/core-types 0.6.0 → 1.0.1
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/README.md +3 -3
- package/dist/postmessage.d.ts +24 -24
- package/dist/postmessage.js +23 -23
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/widget-config.d.ts +12 -0
- package/dist/widget-config.js +17 -1
- package/dist/widget-runtime-config.js +3 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Cross-workspace TypeScript contracts and Zod schemas consumed by
|
|
|
4
4
|
[`@gamaro.io/widget`](https://www.npmjs.com/package/@gamaro.io/widget).
|
|
5
5
|
|
|
6
6
|
> **Companion package — not for standalone use.** This package exists to share
|
|
7
|
-
> type definitions between the
|
|
7
|
+
> type definitions between the Gamaro backend, the marketing site, and the
|
|
8
8
|
> public widget SDK. If you are integrating the widget into your site, you need
|
|
9
9
|
> [`@gamaro.io/widget`](https://www.npmjs.com/package/@gamaro.io/widget), not
|
|
10
10
|
> this one. The widget already re-exports the types you need.
|
|
@@ -12,8 +12,8 @@ Cross-workspace TypeScript contracts and Zod schemas consumed by
|
|
|
12
12
|
## When you might need this directly
|
|
13
13
|
|
|
14
14
|
You only need to depend on `@gamaro.io/core-types` if you are building a custom
|
|
15
|
-
integration that talks to the
|
|
16
|
-
SDK — for example, a server-to-server pipeline that posts events to the
|
|
15
|
+
integration that talks to the Gamaro backend without going through the widget
|
|
16
|
+
SDK — for example, a server-to-server pipeline that posts events to the Gamaro
|
|
17
17
|
API and wants the same Zod schemas the official widget uses.
|
|
18
18
|
|
|
19
19
|
## Installation
|
package/dist/postmessage.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* postMessage protocol between the widget iframe and its host page.
|
|
3
3
|
*
|
|
4
|
-
* Two directions share the `
|
|
4
|
+
* Two directions share the `gamaro:*` prefix:
|
|
5
5
|
* - `WidgetCommand` — parent page → iframe (commands)
|
|
6
6
|
* - `WidgetEvent` — iframe → parent page (events)
|
|
7
7
|
*
|
|
8
8
|
* The `MESSAGE_TYPES` const aggregates every message type string across both
|
|
9
9
|
* directions. Consumers that treat the protocol opaquely (e.g. origin
|
|
10
|
-
* validation helpers) can rely on it to check `type.startsWith("
|
|
10
|
+
* validation helpers) can rely on it to check `type.startsWith("gamaro:")`
|
|
11
11
|
* without enumerating every member.
|
|
12
12
|
*/
|
|
13
13
|
import { z } from "zod";
|
|
@@ -40,30 +40,30 @@ export type WidgetMessage = z.infer<typeof widgetMessageSchema>;
|
|
|
40
40
|
*/
|
|
41
41
|
export type WidgetProfile = Record<string, unknown>;
|
|
42
42
|
/**
|
|
43
|
-
* Exhaustive catalogue of every `
|
|
43
|
+
* Exhaustive catalogue of every `gamaro:*` message type used in either
|
|
44
44
|
* direction. Kept as a single const so a new event or command is declared in
|
|
45
45
|
* one place.
|
|
46
46
|
*/
|
|
47
47
|
export declare const MESSAGE_TYPES: {
|
|
48
|
-
readonly INIT: "
|
|
49
|
-
readonly OPEN: "
|
|
50
|
-
readonly CLOSE: "
|
|
51
|
-
readonly RESET: "
|
|
52
|
-
readonly SET_THEME: "
|
|
53
|
-
readonly VIEWPORT: "
|
|
54
|
-
readonly IDENTIFY: "
|
|
55
|
-
readonly READY: "
|
|
56
|
-
readonly PROFILE_UPDATE: "
|
|
57
|
-
readonly MESSAGE: "
|
|
58
|
-
readonly QUALIFIED: "
|
|
59
|
-
readonly ERROR: "
|
|
60
|
-
readonly QUOTA_WARNING: "
|
|
61
|
-
readonly QUOTA_EXCEEDED: "
|
|
62
|
-
readonly FUNNEL_STAGE_CHANGE: "
|
|
63
|
-
readonly CTA_SHOWN: "
|
|
64
|
-
readonly CTA_CLICKED: "
|
|
65
|
-
readonly LEAD_CAPTURED: "
|
|
66
|
-
readonly IDENTITY_VERIFIED: "
|
|
48
|
+
readonly INIT: "gamaro:init";
|
|
49
|
+
readonly OPEN: "gamaro:open";
|
|
50
|
+
readonly CLOSE: "gamaro:close";
|
|
51
|
+
readonly RESET: "gamaro:reset";
|
|
52
|
+
readonly SET_THEME: "gamaro:setTheme";
|
|
53
|
+
readonly VIEWPORT: "gamaro:viewport";
|
|
54
|
+
readonly IDENTIFY: "gamaro:identify";
|
|
55
|
+
readonly READY: "gamaro:ready";
|
|
56
|
+
readonly PROFILE_UPDATE: "gamaro:profile-update";
|
|
57
|
+
readonly MESSAGE: "gamaro:message";
|
|
58
|
+
readonly QUALIFIED: "gamaro:qualified";
|
|
59
|
+
readonly ERROR: "gamaro:error";
|
|
60
|
+
readonly QUOTA_WARNING: "gamaro:quota-warning";
|
|
61
|
+
readonly QUOTA_EXCEEDED: "gamaro:quota-exceeded";
|
|
62
|
+
readonly FUNNEL_STAGE_CHANGE: "gamaro:funnel-stage-change";
|
|
63
|
+
readonly CTA_SHOWN: "gamaro:cta-shown";
|
|
64
|
+
readonly CTA_CLICKED: "gamaro:cta-clicked";
|
|
65
|
+
readonly LEAD_CAPTURED: "gamaro:lead-captured";
|
|
66
|
+
readonly IDENTITY_VERIFIED: "gamaro:identity-verified";
|
|
67
67
|
};
|
|
68
68
|
export type MessageType = (typeof MESSAGE_TYPES)[keyof typeof MESSAGE_TYPES];
|
|
69
69
|
export type WidgetCommand = {
|
|
@@ -132,14 +132,14 @@ export type WidgetEvent = {
|
|
|
132
132
|
userId?: string;
|
|
133
133
|
};
|
|
134
134
|
/**
|
|
135
|
-
* Short keys (no `
|
|
135
|
+
* Short keys (no `gamaro:` prefix) used by the widget public API (on/off).
|
|
136
136
|
*/
|
|
137
137
|
export type WidgetEventType = "ready" | "profile-update" | "message" | "qualified" | "error" | "open" | "close" | "quota-warning" | "quota-exceeded" | "funnel-stage-change" | "cta-shown" | "cta-clicked" | "lead-captured" | "identity-verified" | "widget-unavailable";
|
|
138
138
|
/**
|
|
139
139
|
* Payload emitted with the `widget-unavailable` SDK event (#867).
|
|
140
140
|
*
|
|
141
141
|
* Fired by the SDK (parent side) when the iframe loader exhausted all
|
|
142
|
-
* retries — distinct from the iframe-emitted `
|
|
142
|
+
* retries — distinct from the iframe-emitted `gamaro:error` which signals
|
|
143
143
|
* a runtime failure of an already-loaded widget.
|
|
144
144
|
*
|
|
145
145
|
* Dual-emission contract: when the loader fails, the SDK emits BOTH
|
package/dist/postmessage.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* postMessage protocol between the widget iframe and its host page.
|
|
3
3
|
*
|
|
4
|
-
* Two directions share the `
|
|
4
|
+
* Two directions share the `gamaro:*` prefix:
|
|
5
5
|
* - `WidgetCommand` — parent page → iframe (commands)
|
|
6
6
|
* - `WidgetEvent` — iframe → parent page (events)
|
|
7
7
|
*
|
|
8
8
|
* The `MESSAGE_TYPES` const aggregates every message type string across both
|
|
9
9
|
* directions. Consumers that treat the protocol opaquely (e.g. origin
|
|
10
|
-
* validation helpers) can rely on it to check `type.startsWith("
|
|
10
|
+
* validation helpers) can rely on it to check `type.startsWith("gamaro:")`
|
|
11
11
|
* without enumerating every member.
|
|
12
12
|
*/
|
|
13
13
|
import { z } from "zod";
|
|
@@ -31,38 +31,38 @@ export const widgetMessageSchema = z.object({
|
|
|
31
31
|
// Message type catalogue
|
|
32
32
|
// ============================================================================
|
|
33
33
|
/**
|
|
34
|
-
* Exhaustive catalogue of every `
|
|
34
|
+
* Exhaustive catalogue of every `gamaro:*` message type used in either
|
|
35
35
|
* direction. Kept as a single const so a new event or command is declared in
|
|
36
36
|
* one place.
|
|
37
37
|
*/
|
|
38
38
|
export const MESSAGE_TYPES = {
|
|
39
39
|
// Parent → iframe (commands)
|
|
40
|
-
INIT: "
|
|
41
|
-
OPEN: "
|
|
42
|
-
CLOSE: "
|
|
43
|
-
RESET: "
|
|
44
|
-
SET_THEME: "
|
|
45
|
-
VIEWPORT: "
|
|
46
|
-
IDENTIFY: "
|
|
40
|
+
INIT: "gamaro:init",
|
|
41
|
+
OPEN: "gamaro:open",
|
|
42
|
+
CLOSE: "gamaro:close",
|
|
43
|
+
RESET: "gamaro:reset",
|
|
44
|
+
SET_THEME: "gamaro:setTheme",
|
|
45
|
+
VIEWPORT: "gamaro:viewport",
|
|
46
|
+
IDENTIFY: "gamaro:identify",
|
|
47
47
|
// iframe → parent (events)
|
|
48
|
-
READY: "
|
|
49
|
-
PROFILE_UPDATE: "
|
|
50
|
-
MESSAGE: "
|
|
51
|
-
QUALIFIED: "
|
|
52
|
-
ERROR: "
|
|
53
|
-
QUOTA_WARNING: "
|
|
54
|
-
QUOTA_EXCEEDED: "
|
|
55
|
-
FUNNEL_STAGE_CHANGE: "
|
|
56
|
-
CTA_SHOWN: "
|
|
57
|
-
CTA_CLICKED: "
|
|
58
|
-
LEAD_CAPTURED: "
|
|
59
|
-
IDENTITY_VERIFIED: "
|
|
48
|
+
READY: "gamaro:ready",
|
|
49
|
+
PROFILE_UPDATE: "gamaro:profile-update",
|
|
50
|
+
MESSAGE: "gamaro:message",
|
|
51
|
+
QUALIFIED: "gamaro:qualified",
|
|
52
|
+
ERROR: "gamaro:error",
|
|
53
|
+
QUOTA_WARNING: "gamaro:quota-warning",
|
|
54
|
+
QUOTA_EXCEEDED: "gamaro:quota-exceeded",
|
|
55
|
+
FUNNEL_STAGE_CHANGE: "gamaro:funnel-stage-change",
|
|
56
|
+
CTA_SHOWN: "gamaro:cta-shown",
|
|
57
|
+
CTA_CLICKED: "gamaro:cta-clicked",
|
|
58
|
+
LEAD_CAPTURED: "gamaro:lead-captured",
|
|
59
|
+
IDENTITY_VERIFIED: "gamaro:identity-verified",
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* Payload emitted with the `widget-unavailable` SDK event (#867).
|
|
63
63
|
*
|
|
64
64
|
* Fired by the SDK (parent side) when the iframe loader exhausted all
|
|
65
|
-
* retries — distinct from the iframe-emitted `
|
|
65
|
+
* retries — distinct from the iframe-emitted `gamaro:error` which signals
|
|
66
66
|
* a runtime failure of an already-loaded widget.
|
|
67
67
|
*
|
|
68
68
|
* Dual-emission contract: when the loader fails, the SDK emits BOTH
|
package/dist/session.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* Per-vertical session cookie name. Each vertical owns its own cookie to prevent
|
|
16
16
|
* profile-schema conflicts. Any character outside `[a-z0-9-]` (case-insensitive)
|
|
17
17
|
* is sanitized to `_` (each char maps to one `_`, no collapsing), so
|
|
18
|
-
* `real-estate` stays `
|
|
18
|
+
* `real-estate` stays `gamaro_session_real-estate`.
|
|
19
19
|
*/
|
|
20
20
|
export declare function getSessionCookieName(verticalId: string): string;
|
|
21
21
|
/**
|
package/dist/session.js
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* Per-vertical session cookie name. Each vertical owns its own cookie to prevent
|
|
16
16
|
* profile-schema conflicts. Any character outside `[a-z0-9-]` (case-insensitive)
|
|
17
17
|
* is sanitized to `_` (each char maps to one `_`, no collapsing), so
|
|
18
|
-
* `real-estate` stays `
|
|
18
|
+
* `real-estate` stays `gamaro_session_real-estate`.
|
|
19
19
|
*/
|
|
20
20
|
export function getSessionCookieName(verticalId) {
|
|
21
21
|
const sanitized = verticalId.replace(/[^a-z0-9-]/gi, "_");
|
|
22
|
-
return `
|
|
22
|
+
return `gamaro_session_${sanitized}`;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Validate the UUID shape of a session id. The length pre-check is
|
package/dist/widget-config.d.ts
CHANGED
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
* `apps/app` sandbox/preview components via `@gamaro.io/widget`'s re-export.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
+
/**
|
|
9
|
+
* Max length of an auto-sent "example question" deep-linked into a widget at
|
|
10
|
+
* mount (#3058, e.g. the funnel canvas's "Tester en conditions réelles"
|
|
11
|
+
* link). Deliberately far tighter than `widgetMessageSchema.content`'s 10000
|
|
12
|
+
* (real chat input) — this is a short canned example string, resolved from a
|
|
13
|
+
* fixed i18n key, never free-form visitor input. Not the primary guard
|
|
14
|
+
* against unbounded LLM input either (`chatMessageSchema.content.max(5000)`
|
|
15
|
+
* already bounds that server-side) — this bound is about UX consistency, and
|
|
16
|
+
* is re-enforced authoritatively at the embed's INIT handler, not solely here.
|
|
17
|
+
*/
|
|
18
|
+
export declare const WIDGET_INITIAL_MESSAGE_MAX_LENGTH = 300;
|
|
8
19
|
export declare const widgetConfigSchema: z.ZodObject<{
|
|
9
20
|
theme: z.ZodOptional<z.ZodObject<{
|
|
10
21
|
primaryColor: z.ZodOptional<z.ZodString>;
|
|
@@ -40,5 +51,6 @@ export declare const widgetConfigSchema: z.ZodObject<{
|
|
|
40
51
|
email: z.ZodOptional<z.ZodString>;
|
|
41
52
|
userId: z.ZodOptional<z.ZodString>;
|
|
42
53
|
userHash: z.ZodOptional<z.ZodString>;
|
|
54
|
+
initialMessage: z.ZodOptional<z.ZodString>;
|
|
43
55
|
}, z.core.$strip>;
|
|
44
56
|
export type WidgetConfig = z.infer<typeof widgetConfigSchema>;
|
package/dist/widget-config.js
CHANGED
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { themeConfigSchema } from "./theme";
|
|
9
9
|
import { responsiveConfigSchema, widgetPositionSchema } from "./viewport";
|
|
10
|
+
/**
|
|
11
|
+
* Max length of an auto-sent "example question" deep-linked into a widget at
|
|
12
|
+
* mount (#3058, e.g. the funnel canvas's "Tester en conditions réelles"
|
|
13
|
+
* link). Deliberately far tighter than `widgetMessageSchema.content`'s 10000
|
|
14
|
+
* (real chat input) — this is a short canned example string, resolved from a
|
|
15
|
+
* fixed i18n key, never free-form visitor input. Not the primary guard
|
|
16
|
+
* against unbounded LLM input either (`chatMessageSchema.content.max(5000)`
|
|
17
|
+
* already bounds that server-side) — this bound is about UX consistency, and
|
|
18
|
+
* is re-enforced authoritatively at the embed's INIT handler, not solely here.
|
|
19
|
+
*/
|
|
20
|
+
export const WIDGET_INITIAL_MESSAGE_MAX_LENGTH = 300;
|
|
10
21
|
export const widgetConfigSchema = z.object({
|
|
11
22
|
theme: themeConfigSchema.describe("Custom theme configuration").optional(),
|
|
12
23
|
position: widgetPositionSchema
|
|
@@ -32,7 +43,7 @@ export const widgetConfigSchema = z.object({
|
|
|
32
43
|
.optional(),
|
|
33
44
|
showProfile: z
|
|
34
45
|
.boolean()
|
|
35
|
-
.describe("
|
|
46
|
+
.describe("Force the profile panel visible in the widget header from the start of the conversation. The panel already shows on its own once the visitor's profile has data, regardless of this flag (default: false).")
|
|
36
47
|
.optional(),
|
|
37
48
|
language: z
|
|
38
49
|
.string()
|
|
@@ -59,4 +70,9 @@ export const widgetConfigSchema = z.object({
|
|
|
59
70
|
.max(128)
|
|
60
71
|
.describe("HMAC-SHA256 of email (or userId), signed with identity secret")
|
|
61
72
|
.optional(),
|
|
73
|
+
initialMessage: z
|
|
74
|
+
.string()
|
|
75
|
+
.max(WIDGET_INITIAL_MESSAGE_MAX_LENGTH)
|
|
76
|
+
.describe("Auto-sent first visitor message, injected once via postMessage when the widget is ready (e.g. a demo deep-link). Never carried on the iframe URL. The authoritative bound is enforced again at the embed's trust boundary (useEmbedChatHandlers' INIT handler), this schema is not the sole enforcement point.")
|
|
77
|
+
.optional(),
|
|
62
78
|
});
|
|
@@ -36,18 +36,18 @@ export const widgetRuntimeConfigSchema = z
|
|
|
36
36
|
.optional(),
|
|
37
37
|
showProfile: z
|
|
38
38
|
.boolean()
|
|
39
|
-
.describe("
|
|
39
|
+
.describe("Forces the profile panel visible from the start of the conversation. The panel already shows on its own once the visitor's profile has data, regardless of this flag.")
|
|
40
40
|
.optional(),
|
|
41
41
|
open: z
|
|
42
42
|
.boolean()
|
|
43
|
-
.describe("Default open state on load. Host can still call `window.
|
|
43
|
+
.describe("Default open state on load. Host can still call `window.Gamaro.open()` programmatically.")
|
|
44
44
|
.optional(),
|
|
45
45
|
brand: z
|
|
46
46
|
.object({
|
|
47
47
|
title: z
|
|
48
48
|
.string()
|
|
49
49
|
.max(60)
|
|
50
|
-
.describe("Custom widget header title. Falls back to a vertical-specific default (e.g. '
|
|
50
|
+
.describe("Custom widget header title. Falls back to a vertical-specific default (e.g. 'Gamaro Chat' for B2B) when unset.")
|
|
51
51
|
.optional(),
|
|
52
52
|
avatarUrl: z
|
|
53
53
|
.string()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaro.io/core-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Cross-workspace TypeScript contracts and Zod schemas consumed by @gamaro.io/widget. Intended as a peer of the widget SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"node": ">=18.0.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"zod": "4.
|
|
58
|
+
"zod": "4.6.5"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@microsoft/api-extractor": "^7.
|
|
61
|
+
"@microsoft/api-extractor": "^7.59.2",
|
|
62
62
|
"typescript": "^6.0.3"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|