@cossistant/core 0.0.7
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/dist/_virtual/rolldown_runtime.js +33 -0
- package/dist/client.d.ts +82 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +275 -0
- package/dist/client.js.map +1 -0
- package/dist/contact.d.ts +28 -0
- package/dist/contact.d.ts.map +1 -0
- package/dist/conversation.d.ts +85 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +16 -0
- package/dist/locale-utils.d.ts +17 -0
- package/dist/locale-utils.d.ts.map +1 -0
- package/dist/locale-utils.js +22 -0
- package/dist/locale-utils.js.map +1 -0
- package/dist/logger.d.ts +11 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +22 -0
- package/dist/logger.js.map +1 -0
- package/dist/realtime-events.d.ts +120 -0
- package/dist/realtime-events.d.ts.map +1 -0
- package/dist/rest-client.d.ts +65 -0
- package/dist/rest-client.d.ts.map +1 -0
- package/dist/rest-client.js +367 -0
- package/dist/rest-client.js.map +1 -0
- package/dist/schemas.d.ts +33 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/store/conversations-store.d.ts +22 -0
- package/dist/store/conversations-store.d.ts.map +1 -0
- package/dist/store/conversations-store.js +108 -0
- package/dist/store/conversations-store.js.map +1 -0
- package/dist/store/create-store.d.ts +14 -0
- package/dist/store/create-store.d.ts.map +1 -0
- package/dist/store/create-store.js +47 -0
- package/dist/store/create-store.js.map +1 -0
- package/dist/store/seen-store.d.ts +37 -0
- package/dist/store/seen-store.d.ts.map +1 -0
- package/dist/store/seen-store.js +131 -0
- package/dist/store/seen-store.js.map +1 -0
- package/dist/store/support-store.d.ts +63 -0
- package/dist/store/support-store.d.ts.map +1 -0
- package/dist/store/support-store.js +170 -0
- package/dist/store/support-store.js.map +1 -0
- package/dist/store/timeline-items-store.d.ts +27 -0
- package/dist/store/timeline-items-store.d.ts.map +1 -0
- package/dist/store/timeline-items-store.js +142 -0
- package/dist/store/timeline-items-store.js.map +1 -0
- package/dist/store/typing-store.d.ts +50 -0
- package/dist/store/typing-store.d.ts.map +1 -0
- package/dist/store/typing-store.js +149 -0
- package/dist/store/typing-store.js.map +1 -0
- package/dist/store/website-store.d.ts +24 -0
- package/dist/store/website-store.d.ts.map +1 -0
- package/dist/store/website-store.js +60 -0
- package/dist/store/website-store.js.map +1 -0
- package/dist/timeline-item.d.ts +207 -0
- package/dist/timeline-item.d.ts.map +1 -0
- package/dist/types/src/enums.js +24 -0
- package/dist/types/src/enums.js.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +20 -0
- package/dist/utils.js.map +1 -0
- package/dist/visitor-data.d.ts +33 -0
- package/dist/visitor-data.d.ts.map +1 -0
- package/dist/visitor-data.js +212 -0
- package/dist/visitor-data.js.map +1 -0
- package/dist/visitor-tracker.d.ts +31 -0
- package/dist/visitor-tracker.d.ts.map +1 -0
- package/dist/visitor-tracker.js +109 -0
- package/dist/visitor-tracker.js.map +1 -0
- package/package.json +48 -0
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/logger.d.ts
|
|
2
|
+
type LogMethod = (message: string, ...details: unknown[]) => void;
|
|
3
|
+
declare const logger: {
|
|
4
|
+
debug: LogMethod;
|
|
5
|
+
info: LogMethod;
|
|
6
|
+
warn: LogMethod;
|
|
7
|
+
error: LogMethod;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { logger };
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","names":[],"sources":["../src/logger.ts"],"sourcesContent":[],"mappings":";KAIK,SAAA;AAAA,cAsBQ,MAtBC,EAAA;EAsBD,KAAA,WAKZ"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/logger.ts
|
|
2
|
+
const LOG_PREFIX = "[cossistant]";
|
|
3
|
+
const resolveConsole = () => {
|
|
4
|
+
if (typeof globalThis === "undefined") return null;
|
|
5
|
+
return globalThis.console ?? null;
|
|
6
|
+
};
|
|
7
|
+
const createLoggerMethod = (level) => (message, ...details) => {
|
|
8
|
+
const target = resolveConsole();
|
|
9
|
+
if (!target) return;
|
|
10
|
+
const consoleMethod = (target[level] ?? target.log)?.bind(target);
|
|
11
|
+
consoleMethod?.(LOG_PREFIX, message, ...details);
|
|
12
|
+
};
|
|
13
|
+
const logger = {
|
|
14
|
+
debug: createLoggerMethod("debug"),
|
|
15
|
+
info: createLoggerMethod("info"),
|
|
16
|
+
warn: createLoggerMethod("warn"),
|
|
17
|
+
error: createLoggerMethod("error")
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { logger };
|
|
22
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","names":[],"sources":["../src/logger.ts"],"sourcesContent":["const LOG_PREFIX = \"[cossistant]\";\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\ntype LogMethod = (message: string, ...details: unknown[]) => void;\n\nconst resolveConsole = (): Console | null => {\n\tif (typeof globalThis === \"undefined\") {\n\t\treturn null;\n\t}\n\n\treturn globalThis.console ?? null;\n};\n\nconst createLoggerMethod =\n\t(level: LogLevel): LogMethod =>\n\t(message, ...details) => {\n\t\tconst target = resolveConsole();\n\t\tif (!target) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst consoleMethod = (target[level] ?? target.log)?.bind(target);\n\t\tconsoleMethod?.(LOG_PREFIX, message, ...details);\n\t};\n\nexport const logger = {\n\tdebug: createLoggerMethod(\"debug\"),\n\tinfo: createLoggerMethod(\"info\"),\n\twarn: createLoggerMethod(\"warn\"),\n\terror: createLoggerMethod(\"error\"),\n};\n"],"mappings":";AAAA,MAAM,aAAa;AAMnB,MAAM,uBAAuC;AAC5C,KAAI,OAAO,eAAe,YACzB,QAAO;AAGR,QAAO,WAAW,WAAW;;AAG9B,MAAM,sBACJ,WACA,SAAS,GAAG,YAAY;CACxB,MAAM,SAAS,gBAAgB;AAC/B,KAAI,CAAC,OACJ;CAGD,MAAM,iBAAiB,OAAO,UAAU,OAAO,MAAM,KAAK,OAAO;AACjE,iBAAgB,YAAY,SAAS,GAAG,QAAQ;;AAGlD,MAAa,SAAS;CACrB,OAAO,mBAAmB,QAAQ;CAClC,MAAM,mBAAmB,OAAO;CAChC,MAAM,mBAAmB,OAAO;CAChC,OAAO,mBAAmB,QAAQ;CAClC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region ../types/src/realtime-events.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Central event system for real-time communication
|
|
7
|
+
* All WebSocket and Redis Pub/Sub events are defined here
|
|
8
|
+
*/
|
|
9
|
+
declare const realtimeSchema: {
|
|
10
|
+
readonly userConnected: z.ZodObject<{
|
|
11
|
+
websiteId: z.ZodString;
|
|
12
|
+
organizationId: z.ZodString;
|
|
13
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
14
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
15
|
+
connectionId: z.ZodString;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
readonly userDisconnected: z.ZodObject<{
|
|
18
|
+
websiteId: z.ZodString;
|
|
19
|
+
organizationId: z.ZodString;
|
|
20
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
21
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
22
|
+
connectionId: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
readonly visitorConnected: z.ZodObject<{
|
|
25
|
+
websiteId: z.ZodString;
|
|
26
|
+
organizationId: z.ZodString;
|
|
27
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
28
|
+
visitorId: z.ZodString;
|
|
29
|
+
connectionId: z.ZodString;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
readonly visitorDisconnected: z.ZodObject<{
|
|
32
|
+
websiteId: z.ZodString;
|
|
33
|
+
organizationId: z.ZodString;
|
|
34
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
35
|
+
visitorId: z.ZodString;
|
|
36
|
+
connectionId: z.ZodString;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
readonly userPresenceUpdate: z.ZodObject<{
|
|
39
|
+
websiteId: z.ZodString;
|
|
40
|
+
organizationId: z.ZodString;
|
|
41
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
42
|
+
userId: z.ZodString;
|
|
43
|
+
status: z.ZodEnum<{
|
|
44
|
+
online: "online";
|
|
45
|
+
away: "away";
|
|
46
|
+
offline: "offline";
|
|
47
|
+
}>;
|
|
48
|
+
lastSeen: z.ZodString;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
readonly conversationSeen: z.ZodObject<{
|
|
51
|
+
websiteId: z.ZodString;
|
|
52
|
+
organizationId: z.ZodString;
|
|
53
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
54
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
55
|
+
conversationId: z.ZodString;
|
|
56
|
+
aiAgentId: z.ZodNullable<z.ZodString>;
|
|
57
|
+
lastSeenAt: z.ZodString;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
readonly conversationTyping: z.ZodObject<{
|
|
60
|
+
websiteId: z.ZodString;
|
|
61
|
+
organizationId: z.ZodString;
|
|
62
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
63
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
64
|
+
conversationId: z.ZodString;
|
|
65
|
+
aiAgentId: z.ZodNullable<z.ZodString>;
|
|
66
|
+
isTyping: z.ZodBoolean;
|
|
67
|
+
visitorPreview: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
readonly timelineItemCreated: z.ZodObject<{
|
|
70
|
+
websiteId: z.ZodString;
|
|
71
|
+
organizationId: z.ZodString;
|
|
72
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
73
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
74
|
+
conversationId: z.ZodString;
|
|
75
|
+
item: z.ZodObject<{
|
|
76
|
+
id: z.ZodString;
|
|
77
|
+
conversationId: z.ZodString;
|
|
78
|
+
organizationId: z.ZodString;
|
|
79
|
+
visibility: z.ZodEnum<{
|
|
80
|
+
[x: string]: any;
|
|
81
|
+
}>;
|
|
82
|
+
type: z.ZodEnum<{
|
|
83
|
+
[x: string]: any;
|
|
84
|
+
}>;
|
|
85
|
+
text: z.ZodNullable<z.ZodString>;
|
|
86
|
+
parts: z.ZodArray<z.ZodUnknown>;
|
|
87
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
88
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
89
|
+
aiAgentId: z.ZodNullable<z.ZodString>;
|
|
90
|
+
createdAt: z.ZodString;
|
|
91
|
+
deletedAt: z.ZodNullable<z.ZodString>;
|
|
92
|
+
tool: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
93
|
+
}, z.core.$strip>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
readonly conversationCreated: z.ZodObject<{
|
|
96
|
+
websiteId: z.ZodString;
|
|
97
|
+
organizationId: z.ZodString;
|
|
98
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
99
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
100
|
+
conversationId: z.ZodString;
|
|
101
|
+
conversation: any;
|
|
102
|
+
header: any;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
readonly visitorIdentified: z.ZodObject<{
|
|
105
|
+
websiteId: z.ZodString;
|
|
106
|
+
organizationId: z.ZodString;
|
|
107
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
108
|
+
visitorId: z.ZodString;
|
|
109
|
+
visitor: any;
|
|
110
|
+
}, z.core.$strip>;
|
|
111
|
+
};
|
|
112
|
+
type RealtimeEventType = keyof typeof realtimeSchema;
|
|
113
|
+
type RealtimeEventPayload<T extends RealtimeEventType> = z.infer<(typeof realtimeSchema)[T]>;
|
|
114
|
+
type RealtimeEvent<T extends RealtimeEventType> = {
|
|
115
|
+
type: T;
|
|
116
|
+
payload: RealtimeEventPayload<T>;
|
|
117
|
+
};
|
|
118
|
+
//#endregion
|
|
119
|
+
export { RealtimeEvent };
|
|
120
|
+
//# sourceMappingURL=realtime-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmED,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,CAAA,CAAE,cACzD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, GetConversationSeenDataResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody } from "./conversation.js";
|
|
2
|
+
import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse } from "./timeline-item.js";
|
|
3
|
+
import { types_d_exports } from "./types.js";
|
|
4
|
+
import { IdentifyContactResponse } from "./contact.js";
|
|
5
|
+
|
|
6
|
+
//#region src/rest-client.d.ts
|
|
7
|
+
declare class CossistantRestClient {
|
|
8
|
+
private config;
|
|
9
|
+
private baseHeaders;
|
|
10
|
+
private publicKey;
|
|
11
|
+
private websiteId;
|
|
12
|
+
private visitorId;
|
|
13
|
+
private visitorBlocked;
|
|
14
|
+
constructor(config: types_d_exports.CossistantConfig);
|
|
15
|
+
private normalizeVisitorResponse;
|
|
16
|
+
private resolveVisitorId;
|
|
17
|
+
private syncVisitorSnapshot;
|
|
18
|
+
private request;
|
|
19
|
+
getWebsite(): Promise<types_d_exports.PublicWebsiteResponse>;
|
|
20
|
+
setWebsiteContext(websiteId: string, visitorId?: string): void;
|
|
21
|
+
setVisitorBlocked(isBlocked: boolean): void;
|
|
22
|
+
getCurrentWebsiteId(): string | null;
|
|
23
|
+
getCurrentVisitorId(): string | null;
|
|
24
|
+
updateVisitorMetadata(metadata: types_d_exports.VisitorMetadata): Promise<types_d_exports.VisitorResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* Identify a visitor by creating or updating their contact information
|
|
27
|
+
* This will link the visitor to a contact record that can be tracked across devices
|
|
28
|
+
*/
|
|
29
|
+
identify(params: {
|
|
30
|
+
externalId?: string;
|
|
31
|
+
email?: string;
|
|
32
|
+
name?: string;
|
|
33
|
+
image?: string;
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
contactOrganizationId?: string;
|
|
36
|
+
}): Promise<IdentifyContactResponse>;
|
|
37
|
+
/**
|
|
38
|
+
* Update metadata for the contact associated with the current visitor
|
|
39
|
+
* Note: The visitor must be identified first via the identify() method
|
|
40
|
+
*/
|
|
41
|
+
updateContactMetadata(metadata: Record<string, unknown>): Promise<types_d_exports.VisitorResponse>;
|
|
42
|
+
createConversation(params?: Partial<CreateConversationRequestBody>): Promise<CreateConversationResponseBody>;
|
|
43
|
+
updateConfiguration(config: Partial<types_d_exports.CossistantConfig>): Promise<void>;
|
|
44
|
+
listConversations(params?: Partial<ListConversationsRequest>): Promise<ListConversationsResponse>;
|
|
45
|
+
getConversation(params: GetConversationRequest): Promise<GetConversationResponse>;
|
|
46
|
+
markConversationSeen(params: {
|
|
47
|
+
conversationId: string;
|
|
48
|
+
} & Partial<MarkConversationSeenRequestBody>): Promise<MarkConversationSeenResponseBody>;
|
|
49
|
+
getConversationSeenData(params: {
|
|
50
|
+
conversationId: string;
|
|
51
|
+
}): Promise<GetConversationSeenDataResponse>;
|
|
52
|
+
setConversationTyping(params: {
|
|
53
|
+
conversationId: string;
|
|
54
|
+
isTyping: boolean;
|
|
55
|
+
visitorPreview?: string | null;
|
|
56
|
+
visitorId?: string;
|
|
57
|
+
}): Promise<SetConversationTypingResponseBody>;
|
|
58
|
+
sendMessage(params: SendTimelineItemRequest): Promise<SendTimelineItemResponse>;
|
|
59
|
+
getConversationTimelineItems(params: GetConversationTimelineItemsRequest & {
|
|
60
|
+
conversationId: string;
|
|
61
|
+
}): Promise<GetConversationTimelineItemsResponse>;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { CossistantRestClient };
|
|
65
|
+
//# sourceMappingURL=rest-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-client.d.ts","names":[],"sources":["../src/rest-client.ts"],"sourcesContent":[],"mappings":";;;;;;cAqCa,oBAAA;;EAAA,QAAA,WAAA;EAQQ,QAAA,SAAA;EA2LQ,QAAA,SAAA;EAAR,QAAA,SAAA;EA6ET,QAAA,cAAA;EACA,WAAA,CAAA,MAAA,EAzQS,eAAA,CAAA,gBAyQT;EAAR,QAAA,wBAAA;EAyBS,QAAA,gBAAA;EAEA,QAAA,mBAAA;EAAR,QAAA,OAAA;EAqCO,UAAA,CAAA,CAAA,EA9IS,OA8IT,CA9IiB,eAAA,CAAA,qBA8IjB,CAAA;EACA,iBAAA,CAAA,SAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAR,iBAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAOc,mBAAA,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,mBAAA,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EACE,qBAAA,CAAA,QAAA,EA1EA,eAAA,CAAA,eA0EA,CAAA,EAzER,OAyEQ,CAzEA,eAAA,CAAA,eAyEA,CAAA;EAAR;;;;EAwEc,QAAA,CAAA,MAAA,EAAA;IAAR,UAAA,CAAA,EAAA,MAAA;IACE,KAAA,CAAA,EAAA,MAAA;IAAR,IAAA,CAAA,EAAA,MAAA;IAiEM,KAAA,CAAA,EAAA,MAAA;IACE,QAAA,CAAA,EA3LC,MA2LD,CAAA,MAAA,EAAA,OAAA,CAAA;IAAR,qBAAA,CAAA,EAAA,MAAA;EAgCU,CAAA,CAAA,EAzNT,OAyNS,CAzND,uBAyNC,CAAA;EAAR;;;;EAsCD,qBAAA,CAAA,QAAA,EA1NO,MA0NP,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EAzND,OAyNC,CAzNO,eAAA,CAAA,eAyNP,CAAA;EAwBQ,kBAAA,CAAA,MAAA,CAAA,EA1OH,OA0OG,CA1OK,6BA0OL,CAAA,CAAA,EAzOT,OAyOS,CAzOD,8BAyOC,CAAA;EAAR,mBAAA,CAAA,MAAA,EAzL8B,OAyL9B,CAzLsC,eAAA,CAAA,gBAyLtC,CAAA,CAAA,EAzL0D,OAyL1D,CAAA,IAAA,CAAA;EA6CK,iBAAA,CAAA,MAAA,CAAA,EA9MA,OA8MA,CA9MQ,wBA8MR,CAAA,CAAA,EA7MN,OA6MM,CA7ME,yBA6MF,CAAA;EACE,eAAA,CAAA,MAAA,EA7IF,sBA6IE,CAAA,EA5IR,OA4IQ,CA5IA,uBA4IA,CAAA;EAAR,oBAAA,CAAA,MAAA,EAAA;IAsBM,cAAA,EAAA,MAAA;EACE,CAAA,GAnIN,OAmIM,CAnIE,+BAmIF,CAAA,CAAA,EAlIR,OAkIQ,CAlIA,gCAkIA,CAAA;EAAR,uBAAA,CAAA,MAAA,EAAA;IAAO,cAAA,EAAA,MAAA;MA7FN,QAAQ;;;;;;MAwBR,QAAQ;sBA6CH,0BACN,QAAQ;uCAsBF;;MACN,QAAQ"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { logger } from "./logger.js";
|
|
2
|
+
import { CossistantAPIError } from "./types.js";
|
|
3
|
+
import { generateConversationId } from "./utils.js";
|
|
4
|
+
import { collectVisitorData } from "./visitor-data.js";
|
|
5
|
+
import { getExistingVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
6
|
+
|
|
7
|
+
//#region src/rest-client.ts
|
|
8
|
+
var CossistantRestClient = class {
|
|
9
|
+
config;
|
|
10
|
+
baseHeaders;
|
|
11
|
+
publicKey;
|
|
12
|
+
websiteId = null;
|
|
13
|
+
visitorId = null;
|
|
14
|
+
visitorBlocked = false;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.publicKey = config.publicKey || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_COSSISTANT_KEY : void 0) || (typeof process !== "undefined" ? process.env.COSSISTANT_PUBLIC_KEY : void 0) || "";
|
|
18
|
+
if (!this.publicKey) throw new Error("Public key is required. Please provide it in the config or set NEXT_PUBLIC_COSSISTANT_KEY or COSSISTANT_PUBLIC_KEY environment variable.");
|
|
19
|
+
this.baseHeaders = {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
"X-Public-Key": this.publicKey
|
|
22
|
+
};
|
|
23
|
+
if (config.userId) this.baseHeaders["X-User-ID"] = config.userId;
|
|
24
|
+
if (config.organizationId) this.baseHeaders["X-Organization-ID"] = config.organizationId;
|
|
25
|
+
}
|
|
26
|
+
normalizeVisitorResponse(payload) {
|
|
27
|
+
payload.contact && payload.contact;
|
|
28
|
+
return {
|
|
29
|
+
...payload,
|
|
30
|
+
latitude: typeof payload.latitude === "string" ? Number.parseFloat(payload.latitude) : payload.latitude,
|
|
31
|
+
longitude: typeof payload.longitude === "string" ? Number.parseFloat(payload.longitude) : payload.longitude,
|
|
32
|
+
createdAt: payload.createdAt,
|
|
33
|
+
updatedAt: payload.updatedAt,
|
|
34
|
+
lastSeenAt: payload.lastSeenAt ? payload.lastSeenAt : null,
|
|
35
|
+
blockedAt: payload.blockedAt ? payload.blockedAt : null,
|
|
36
|
+
contact: payload.contact ? payload.contact : null
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
resolveVisitorId() {
|
|
40
|
+
if (this.visitorId) return this.visitorId;
|
|
41
|
+
if (this.websiteId) {
|
|
42
|
+
const storedVisitorId = getVisitorId(this.websiteId);
|
|
43
|
+
if (storedVisitorId) {
|
|
44
|
+
this.visitorId = storedVisitorId;
|
|
45
|
+
return storedVisitorId;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw new Error("Visitor ID is required");
|
|
49
|
+
}
|
|
50
|
+
async syncVisitorSnapshot(visitorId) {
|
|
51
|
+
try {
|
|
52
|
+
const visitorData = await collectVisitorData();
|
|
53
|
+
if (!visitorData) return;
|
|
54
|
+
const payload = Object.entries(visitorData).reduce((acc, [key, value]) => {
|
|
55
|
+
if (value === null || value === void 0) return acc;
|
|
56
|
+
acc[key] = value;
|
|
57
|
+
return acc;
|
|
58
|
+
}, {});
|
|
59
|
+
if (Object.keys(payload).length === 0) return;
|
|
60
|
+
await this.request(`/visitors/${visitorId}`, {
|
|
61
|
+
method: "PATCH",
|
|
62
|
+
body: JSON.stringify(payload),
|
|
63
|
+
headers: { "X-Visitor-Id": visitorId }
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
logger.warn("Failed to sync visitor data", error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async request(path, options = {}) {
|
|
70
|
+
if (this.visitorBlocked) {
|
|
71
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
72
|
+
const [rawPath] = path.split("?");
|
|
73
|
+
if (!((rawPath.endsWith("/") ? rawPath.slice(0, -1) : rawPath) === "/websites" && (method === "GET" || method === "HEAD"))) throw new CossistantAPIError({
|
|
74
|
+
code: "VISITOR_BLOCKED",
|
|
75
|
+
message: "Visitor is blocked and cannot perform this action.",
|
|
76
|
+
details: {
|
|
77
|
+
path,
|
|
78
|
+
method
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const url = `${this.config.apiUrl}${path}`;
|
|
83
|
+
const response = await fetch(url, {
|
|
84
|
+
...options,
|
|
85
|
+
headers: {
|
|
86
|
+
...this.baseHeaders,
|
|
87
|
+
...options.headers
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const errorData = await response.json().catch(() => ({}));
|
|
92
|
+
const statusCode = response.status;
|
|
93
|
+
const errorCode = errorData.code || `HTTP_${statusCode}`;
|
|
94
|
+
const serverMessage = errorData.message;
|
|
95
|
+
const isAuthError = statusCode === 401 || statusCode === 403 || errorCode === "UNAUTHORIZED" || errorCode === "FORBIDDEN" || errorCode === "INVALID_API_KEY" || errorCode === "API_KEY_EXPIRED" || errorCode === "API_KEY_MISSING" || errorCode?.toUpperCase().includes("AUTH") || errorCode?.toUpperCase().includes("API_KEY");
|
|
96
|
+
const errorMessage = isAuthError ? "Your Cossistant public API key is invalid, expired, missing or not authorized to access this resource." : serverMessage || `Request failed with status ${statusCode}`;
|
|
97
|
+
if (isAuthError) logger.error(errorMessage, {
|
|
98
|
+
details: errorData.details,
|
|
99
|
+
path,
|
|
100
|
+
status: statusCode,
|
|
101
|
+
code: errorCode
|
|
102
|
+
});
|
|
103
|
+
else logger.error("API request failed", {
|
|
104
|
+
message: errorMessage,
|
|
105
|
+
details: errorData.details,
|
|
106
|
+
path,
|
|
107
|
+
status: statusCode,
|
|
108
|
+
code: errorCode
|
|
109
|
+
});
|
|
110
|
+
throw new CossistantAPIError({
|
|
111
|
+
code: errorCode,
|
|
112
|
+
message: errorMessage,
|
|
113
|
+
details: errorData.details
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return response.json();
|
|
117
|
+
}
|
|
118
|
+
async getWebsite() {
|
|
119
|
+
const headers = {};
|
|
120
|
+
if (this.websiteId) {
|
|
121
|
+
const storedVisitorId = getVisitorId(this.websiteId);
|
|
122
|
+
if (storedVisitorId) headers["X-Visitor-Id"] = storedVisitorId;
|
|
123
|
+
} else {
|
|
124
|
+
const existingVisitor = getExistingVisitorId(this.publicKey);
|
|
125
|
+
if (existingVisitor) {
|
|
126
|
+
headers["X-Visitor-Id"] = existingVisitor.visitorId;
|
|
127
|
+
this.websiteId = existingVisitor.websiteId;
|
|
128
|
+
this.visitorId = existingVisitor.visitorId;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const response = await this.request("/websites", { headers });
|
|
132
|
+
this.websiteId = response.id;
|
|
133
|
+
this.visitorBlocked = response.visitor?.isBlocked ?? false;
|
|
134
|
+
if (response.visitor?.id) {
|
|
135
|
+
if (this.visitorBlocked) {
|
|
136
|
+
this.visitorId = response.visitor.id;
|
|
137
|
+
setVisitorId(response.id, response.visitor.id);
|
|
138
|
+
return response;
|
|
139
|
+
}
|
|
140
|
+
this.visitorId = response.visitor.id;
|
|
141
|
+
setVisitorId(response.id, response.visitor.id);
|
|
142
|
+
this.syncVisitorSnapshot(response.visitor.id);
|
|
143
|
+
}
|
|
144
|
+
return response;
|
|
145
|
+
}
|
|
146
|
+
setWebsiteContext(websiteId, visitorId) {
|
|
147
|
+
this.websiteId = websiteId;
|
|
148
|
+
if (visitorId) {
|
|
149
|
+
this.visitorId = visitorId;
|
|
150
|
+
setVisitorId(websiteId, visitorId);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
setVisitorBlocked(isBlocked) {
|
|
154
|
+
this.visitorBlocked = isBlocked;
|
|
155
|
+
}
|
|
156
|
+
getCurrentWebsiteId() {
|
|
157
|
+
return this.websiteId;
|
|
158
|
+
}
|
|
159
|
+
getCurrentVisitorId() {
|
|
160
|
+
if (this.visitorId) return this.visitorId;
|
|
161
|
+
if (!this.websiteId) return null;
|
|
162
|
+
return getVisitorId(this.websiteId) ?? null;
|
|
163
|
+
}
|
|
164
|
+
async updateVisitorMetadata(metadata) {
|
|
165
|
+
const visitorId = this.resolveVisitorId();
|
|
166
|
+
const response = await this.request(`/visitors/${visitorId}/metadata`, {
|
|
167
|
+
method: "PATCH",
|
|
168
|
+
body: JSON.stringify({ metadata }),
|
|
169
|
+
headers: { "X-Visitor-Id": visitorId }
|
|
170
|
+
});
|
|
171
|
+
return this.normalizeVisitorResponse(response);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Identify a visitor by creating or updating their contact information
|
|
175
|
+
* This will link the visitor to a contact record that can be tracked across devices
|
|
176
|
+
*/
|
|
177
|
+
async identify(params) {
|
|
178
|
+
const visitorId = this.resolveVisitorId();
|
|
179
|
+
const response = await this.request("/contacts/identify", {
|
|
180
|
+
method: "POST",
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
visitorId,
|
|
183
|
+
...params
|
|
184
|
+
}),
|
|
185
|
+
headers: { "X-Visitor-Id": visitorId }
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
contact: {
|
|
189
|
+
...response.contact,
|
|
190
|
+
metadata: typeof response.contact.metadata === "string" ? JSON.parse(response.contact.metadata) : response.contact.metadata,
|
|
191
|
+
createdAt: response.contact.createdAt,
|
|
192
|
+
updatedAt: response.contact.updatedAt
|
|
193
|
+
},
|
|
194
|
+
visitorId: response.visitorId
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Update metadata for the contact associated with the current visitor
|
|
199
|
+
* Note: The visitor must be identified first via the identify() method
|
|
200
|
+
*/
|
|
201
|
+
async updateContactMetadata(metadata) {
|
|
202
|
+
return this.updateVisitorMetadata(metadata);
|
|
203
|
+
}
|
|
204
|
+
async createConversation(params = {}) {
|
|
205
|
+
const conversationId = params.conversationId || generateConversationId();
|
|
206
|
+
const storedVisitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
207
|
+
const visitorId = params.visitorId || storedVisitorId;
|
|
208
|
+
if (!visitorId) throw new Error("Visitor ID is required");
|
|
209
|
+
const body = {
|
|
210
|
+
conversationId,
|
|
211
|
+
visitorId,
|
|
212
|
+
defaultTimelineItems: params.defaultTimelineItems || [],
|
|
213
|
+
channel: params.channel || "widget"
|
|
214
|
+
};
|
|
215
|
+
const headers = {};
|
|
216
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
217
|
+
const response = await this.request("/conversations", {
|
|
218
|
+
method: "POST",
|
|
219
|
+
body: JSON.stringify(body),
|
|
220
|
+
headers
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
conversation: {
|
|
224
|
+
...response.conversation,
|
|
225
|
+
createdAt: response.conversation.createdAt,
|
|
226
|
+
updatedAt: response.conversation.updatedAt,
|
|
227
|
+
deletedAt: response.conversation.deletedAt ?? null,
|
|
228
|
+
lastTimelineItem: response.conversation.lastTimelineItem
|
|
229
|
+
},
|
|
230
|
+
initialTimelineItems: response.initialTimelineItems
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async updateConfiguration(config) {
|
|
234
|
+
if (config.publicKey) {
|
|
235
|
+
this.publicKey = config.publicKey;
|
|
236
|
+
this.baseHeaders["X-Public-Key"] = config.publicKey;
|
|
237
|
+
}
|
|
238
|
+
if (config.userId) this.baseHeaders["X-User-ID"] = config.userId;
|
|
239
|
+
else if (config.userId === null) {
|
|
240
|
+
const { "X-User-ID": _,...rest } = this.baseHeaders;
|
|
241
|
+
this.baseHeaders = rest;
|
|
242
|
+
}
|
|
243
|
+
if (config.organizationId) this.baseHeaders["X-Organization-ID"] = config.organizationId;
|
|
244
|
+
else if (config.organizationId === null) {
|
|
245
|
+
const { "X-Organization-ID": _,...rest } = this.baseHeaders;
|
|
246
|
+
this.baseHeaders = rest;
|
|
247
|
+
}
|
|
248
|
+
this.config = {
|
|
249
|
+
...this.config,
|
|
250
|
+
...config
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
async listConversations(params = {}) {
|
|
254
|
+
const storedVisitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
255
|
+
const visitorId = params.visitorId || storedVisitorId;
|
|
256
|
+
if (!visitorId) throw new Error("Visitor ID is required");
|
|
257
|
+
const queryParams = new URLSearchParams();
|
|
258
|
+
if (visitorId) queryParams.set("visitorId", visitorId);
|
|
259
|
+
if (params.page) queryParams.set("page", params.page.toString());
|
|
260
|
+
if (params.limit) queryParams.set("limit", params.limit.toString());
|
|
261
|
+
if (params.status) queryParams.set("status", params.status);
|
|
262
|
+
if (params.orderBy) queryParams.set("orderBy", params.orderBy);
|
|
263
|
+
if (params.order) queryParams.set("order", params.order);
|
|
264
|
+
const headers = {};
|
|
265
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
266
|
+
const response = await this.request(`/conversations?${queryParams.toString()}`, { headers });
|
|
267
|
+
return {
|
|
268
|
+
conversations: response.conversations.map((conv) => ({
|
|
269
|
+
...conv,
|
|
270
|
+
createdAt: conv.createdAt,
|
|
271
|
+
updatedAt: conv.updatedAt,
|
|
272
|
+
deletedAt: conv.deletedAt ?? null,
|
|
273
|
+
lastTimelineItem: conv.lastTimelineItem
|
|
274
|
+
})),
|
|
275
|
+
pagination: response.pagination
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
async getConversation(params) {
|
|
279
|
+
const visitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
280
|
+
const headers = {};
|
|
281
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
282
|
+
const response = await this.request(`/conversations/${params.conversationId}`, { headers });
|
|
283
|
+
return { conversation: {
|
|
284
|
+
...response.conversation,
|
|
285
|
+
createdAt: response.conversation.createdAt,
|
|
286
|
+
updatedAt: response.conversation.updatedAt,
|
|
287
|
+
deletedAt: response.conversation.deletedAt ?? null,
|
|
288
|
+
lastTimelineItem: response.conversation.lastTimelineItem
|
|
289
|
+
} };
|
|
290
|
+
}
|
|
291
|
+
async markConversationSeen(params) {
|
|
292
|
+
const storedVisitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
293
|
+
const visitorId = params.visitorId || storedVisitorId;
|
|
294
|
+
if (!visitorId) throw new Error("Visitor ID is required to mark a conversation as seen");
|
|
295
|
+
const headers = {};
|
|
296
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
297
|
+
const body = {};
|
|
298
|
+
if (params.visitorId) body.visitorId = params.visitorId;
|
|
299
|
+
const response = await this.request(`/conversations/${params.conversationId}/seen`, {
|
|
300
|
+
method: "POST",
|
|
301
|
+
body: JSON.stringify(body),
|
|
302
|
+
headers
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
conversationId: response.conversationId,
|
|
306
|
+
lastSeenAt: response.lastSeenAt
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
async getConversationSeenData(params) {
|
|
310
|
+
return { seenData: (await this.request(`/conversations/${params.conversationId}/seen`, { method: "GET" })).seenData.map((item) => ({
|
|
311
|
+
...item,
|
|
312
|
+
lastSeenAt: item.lastSeenAt,
|
|
313
|
+
createdAt: item.createdAt,
|
|
314
|
+
updatedAt: item.updatedAt,
|
|
315
|
+
deletedAt: item.deletedAt ? item.deletedAt : null
|
|
316
|
+
})) };
|
|
317
|
+
}
|
|
318
|
+
async setConversationTyping(params) {
|
|
319
|
+
const storedVisitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
320
|
+
const visitorId = params.visitorId || storedVisitorId;
|
|
321
|
+
if (!visitorId) throw new Error("Visitor ID is required to report typing state");
|
|
322
|
+
const headers = {};
|
|
323
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
324
|
+
const body = { isTyping: params.isTyping };
|
|
325
|
+
if (params.visitorId) body.visitorId = params.visitorId;
|
|
326
|
+
if (params.visitorPreview && params.isTyping) body.visitorPreview = params.visitorPreview.slice(0, 2e3);
|
|
327
|
+
const response = await this.request(`/conversations/${params.conversationId}/typing`, {
|
|
328
|
+
method: "POST",
|
|
329
|
+
body: JSON.stringify(body),
|
|
330
|
+
headers
|
|
331
|
+
});
|
|
332
|
+
return {
|
|
333
|
+
conversationId: response.conversationId,
|
|
334
|
+
isTyping: response.isTyping,
|
|
335
|
+
visitorPreview: response.visitorPreview,
|
|
336
|
+
sentAt: response.sentAt
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async sendMessage(params) {
|
|
340
|
+
const visitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
341
|
+
const headers = {};
|
|
342
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
343
|
+
return { item: (await this.request("/messages", {
|
|
344
|
+
method: "POST",
|
|
345
|
+
body: JSON.stringify(params),
|
|
346
|
+
headers
|
|
347
|
+
})).item };
|
|
348
|
+
}
|
|
349
|
+
async getConversationTimelineItems(params) {
|
|
350
|
+
const visitorId = this.websiteId ? getVisitorId(this.websiteId) : void 0;
|
|
351
|
+
const queryParams = new URLSearchParams();
|
|
352
|
+
if (params.limit) queryParams.set("limit", params.limit.toString());
|
|
353
|
+
if (params.cursor) queryParams.set("cursor", params.cursor);
|
|
354
|
+
const headers = {};
|
|
355
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
356
|
+
const response = await this.request(`/conversations/${params.conversationId}/timeline?${queryParams.toString()}`, { headers });
|
|
357
|
+
return {
|
|
358
|
+
items: response.items,
|
|
359
|
+
nextCursor: response.nextCursor,
|
|
360
|
+
hasNextPage: response.hasNextPage
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
//#endregion
|
|
366
|
+
export { CossistantRestClient };
|
|
367
|
+
//# sourceMappingURL=rest-client.js.map
|