@cossistant/core 0.0.26 → 0.0.28
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/client.d.ts +37 -5
- package/client.d.ts.map +1 -1
- package/client.js +18 -0
- package/client.js.map +1 -1
- package/conversation.d.ts +3 -0
- package/conversation.d.ts.map +1 -1
- package/index.d.ts +6 -4
- package/index.js +3 -1
- package/package.json +1 -1
- package/realtime-events.d.ts +39 -0
- package/realtime-events.d.ts.map +1 -1
- package/rest-client.d.ts +32 -1
- package/rest-client.d.ts.map +1 -1
- package/rest-client.js +75 -0
- package/rest-client.js.map +1 -1
- package/schemas.d.ts +1 -0
- package/schemas.d.ts.map +1 -1
- package/store/conversations-store.d.ts +6 -6
- package/store/conversations-store.d.ts.map +1 -1
- package/store/conversations-store.js +2 -1
- package/store/conversations-store.js.map +1 -1
- package/store/typing-store.d.ts.map +1 -1
- package/store/typing-store.js +6 -6
- package/store/typing-store.js.map +1 -1
- package/typing-reporter.d.ts +71 -0
- package/typing-reporter.d.ts.map +1 -0
- package/typing-reporter.js +145 -0
- package/typing-reporter.js.map +1 -0
- package/upload-constants.d.ts +40 -0
- package/upload-constants.d.ts.map +1 -0
- package/upload-constants.js +70 -0
- package/upload-constants.js.map +1 -0
- package/upload.d.ts +47 -0
- package/upload.d.ts.map +1 -0
package/client.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody } from "./conversation.js";
|
|
2
2
|
import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse, TimelineItem } from "./timeline-item.js";
|
|
3
|
-
import { Conversation
|
|
3
|
+
import { Conversation } from "./schemas.js";
|
|
4
|
+
import { types_d_exports } from "./types.js";
|
|
5
|
+
import { CossistantRestClient } from "./rest-client.js";
|
|
4
6
|
import { ConversationsStore } from "./store/conversations-store.js";
|
|
5
7
|
import { TimelineItemsStore } from "./store/timeline-items-store.js";
|
|
6
8
|
import { WebsiteStore } from "./store/website-store.js";
|
|
7
|
-
import { types_d_exports } from "./types.js";
|
|
8
9
|
import { AnyRealtimeEvent, DefaultMessage, IdentifyContactResponse } from "@cossistant/types";
|
|
9
10
|
|
|
10
11
|
//#region src/client.d.ts
|
|
@@ -13,12 +14,12 @@ type InitiateConversationParams = {
|
|
|
13
14
|
visitorId?: string | null;
|
|
14
15
|
websiteId?: string | null;
|
|
15
16
|
title?: string;
|
|
16
|
-
status?: Conversation
|
|
17
|
+
status?: Conversation["status"];
|
|
17
18
|
defaultTimelineItems?: Array<DefaultMessage | TimelineItem>;
|
|
18
19
|
};
|
|
19
20
|
type InitiateConversationResult = {
|
|
20
21
|
conversationId: string;
|
|
21
|
-
conversation: Conversation
|
|
22
|
+
conversation: Conversation;
|
|
22
23
|
defaultTimelineItems: TimelineItem[];
|
|
23
24
|
};
|
|
24
25
|
declare class CossistantClient {
|
|
@@ -82,11 +83,42 @@ declare class CossistantClient {
|
|
|
82
83
|
sendMessage(params: SendTimelineItemRequest & {
|
|
83
84
|
createIfPending?: boolean;
|
|
84
85
|
}): Promise<SendTimelineItemResponse & {
|
|
85
|
-
conversation?: Conversation
|
|
86
|
+
conversation?: Conversation;
|
|
86
87
|
initialTimelineItems?: TimelineItem[];
|
|
87
88
|
wasConversationCreated?: boolean;
|
|
88
89
|
}>;
|
|
89
90
|
handleRealtimeEvent(event: AnyRealtimeEvent): void;
|
|
91
|
+
/**
|
|
92
|
+
* Generate a presigned URL for uploading a file to S3.
|
|
93
|
+
*/
|
|
94
|
+
generateUploadUrl(params: Omit<Parameters<CossistantRestClient["generateUploadUrl"]>[0], "websiteId">): Promise<{
|
|
95
|
+
uploadUrl: string;
|
|
96
|
+
key: string;
|
|
97
|
+
bucket: string;
|
|
98
|
+
expiresAt: string;
|
|
99
|
+
contentType: string;
|
|
100
|
+
publicUrl: string;
|
|
101
|
+
}>;
|
|
102
|
+
/**
|
|
103
|
+
* Upload a file to S3 using a presigned URL.
|
|
104
|
+
*/
|
|
105
|
+
uploadFile(file: File, uploadUrl: string, contentType: string): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Upload multiple files for a conversation message.
|
|
108
|
+
*/
|
|
109
|
+
uploadFilesForMessage(files: File[], conversationId: string): Promise<({
|
|
110
|
+
type: "image";
|
|
111
|
+
url: string;
|
|
112
|
+
mediaType: string;
|
|
113
|
+
fileName?: string;
|
|
114
|
+
size?: number;
|
|
115
|
+
} | {
|
|
116
|
+
type: "file";
|
|
117
|
+
url: string;
|
|
118
|
+
mediaType: string;
|
|
119
|
+
fileName?: string;
|
|
120
|
+
size?: number;
|
|
121
|
+
})[]>;
|
|
90
122
|
destroy(): void;
|
|
91
123
|
}
|
|
92
124
|
//#endregion
|
package/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"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"}
|
package/client.js
CHANGED
|
@@ -227,6 +227,24 @@ var CossistantClient = class {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Generate a presigned URL for uploading a file to S3.
|
|
232
|
+
*/
|
|
233
|
+
async generateUploadUrl(params) {
|
|
234
|
+
return this.restClient.generateUploadUrl(params);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Upload a file to S3 using a presigned URL.
|
|
238
|
+
*/
|
|
239
|
+
async uploadFile(file, uploadUrl, contentType) {
|
|
240
|
+
return this.restClient.uploadFile(file, uploadUrl, contentType);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Upload multiple files for a conversation message.
|
|
244
|
+
*/
|
|
245
|
+
async uploadFilesForMessage(files, conversationId) {
|
|
246
|
+
return this.restClient.uploadFilesForMessage(files, conversationId);
|
|
247
|
+
}
|
|
230
248
|
destroy() {}
|
|
231
249
|
};
|
|
232
250
|
function normalizeBootstrapTimelineItem(conversationId, item) {
|
package/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["current: WebsiteState","conversation: Conversation","optimisticTimelineItem: TimelineItem","payload: SendTimelineItemRequest","createdAt"],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype AnyRealtimeEvent,\n\ttype DefaultMessage,\n\tgetEventPayload,\n\ttype IdentifyContactResponse,\n\ttype RealtimeEvent,\n} from \"@cossistant/types\";\nimport type {\n\tCreateConversationRequestBody,\n\tCreateConversationResponseBody,\n\tGetConversationRequest,\n\tGetConversationResponse,\n\tListConversationsRequest,\n\tListConversationsResponse,\n\tMarkConversationSeenRequestBody,\n\tMarkConversationSeenResponseBody,\n\tSetConversationTypingResponseBody,\n} from \"@cossistant/types/api/conversation\";\nimport type {\n\tGetConversationTimelineItemsRequest,\n\tGetConversationTimelineItemsResponse,\n\tSendTimelineItemRequest,\n\tSendTimelineItemResponse,\n\tTimelineItem,\n} from \"@cossistant/types/api/timeline-item\";\nimport {\n\tConversationStatus,\n\tConversationTimelineType,\n\tSenderType,\n\tTimelineItemVisibility,\n} from \"@cossistant/types/enums\";\nimport type { Conversation } from \"@cossistant/types/schemas\";\nimport { CossistantRestClient } from \"./rest-client\";\nimport {\n\ttype ConversationsStore,\n\tcreateConversationsStore,\n} from \"./store/conversations-store\";\nimport {\n\tcreateTimelineItemsStore,\n\ttype TimelineItemsStore,\n} from \"./store/timeline-items-store\";\nimport {\n\tcreateWebsiteStore,\n\ttype WebsiteState,\n\ttype WebsiteStore,\n} from \"./store/website-store\";\nimport type {\n\tCossistantConfig,\n\tPublicWebsiteResponse,\n\tVisitorMetadata,\n\tVisitorResponse,\n} from \"./types\";\nimport { generateConversationId, generateMessageId } from \"./utils\";\n\ntype PendingConversation = {\n\tconversation: Conversation;\n\tinitialTimelineItems: TimelineItem[];\n};\n\ntype InitiateConversationParams = {\n\tconversationId?: string;\n\tvisitorId?: string | null;\n\twebsiteId?: string | null;\n\ttitle?: string;\n\tstatus?: Conversation[\"status\"];\n\tdefaultTimelineItems?: Array<DefaultMessage | TimelineItem>;\n};\n\ntype InitiateConversationResult = {\n\tconversationId: string;\n\tconversation: Conversation;\n\tdefaultTimelineItems: TimelineItem[];\n};\n\nexport class CossistantClient {\n\tprivate restClient: CossistantRestClient;\n\tprivate config: CossistantConfig;\n\tprivate pendingConversations = new Map<string, PendingConversation>();\n\tprivate websiteRequest: Promise<PublicWebsiteResponse> | null = null;\n\treadonly conversationsStore: ConversationsStore;\n\treadonly timelineItemsStore: TimelineItemsStore;\n\treadonly websiteStore: WebsiteStore;\n\n\tconstructor(config: CossistantConfig) {\n\t\tthis.config = config;\n\t\tthis.restClient = new CossistantRestClient(config);\n\t\tthis.conversationsStore = createConversationsStore();\n\t\tthis.timelineItemsStore = createTimelineItemsStore();\n\t\tthis.websiteStore = createWebsiteStore();\n\t}\n\n\t// Configuration updates\n\tupdateConfiguration(config: Partial<CossistantConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t\tthis.restClient.updateConfiguration(config);\n\t}\n\n\t// Utility methods\n\tgetConfiguration(): CossistantConfig {\n\t\treturn { ...this.config };\n\t}\n\n\t// Website information\n\tasync fetchWebsite(\n\t\tparams: { force?: boolean } = {}\n\t): Promise<PublicWebsiteResponse> {\n\t\tconst { force = false } = params;\n\t\tconst current: WebsiteState = this.websiteStore.getState();\n\n\t\tif (!force) {\n\t\t\tif (current.status === \"success\" && current.website) {\n\t\t\t\treturn current.website;\n\t\t\t}\n\t\t\tif (this.websiteRequest) {\n\t\t\t\treturn this.websiteRequest;\n\t\t\t}\n\t\t}\n\n\t\tthis.websiteStore.setLoading();\n\n\t\tconst request = this.restClient\n\t\t\t.getWebsite()\n\t\t\t.then((website) => {\n\t\t\t\tthis.websiteStore.setWebsite(website);\n\t\t\t\treturn website;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.websiteStore.setError(error);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.websiteRequest === request) {\n\t\t\t\t\tthis.websiteRequest = null;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.websiteRequest = request;\n\n\t\treturn request;\n\t}\n\n\tasync getWebsite(): Promise<PublicWebsiteResponse> {\n\t\treturn this.fetchWebsite({ force: true });\n\t}\n\n\tsetWebsiteContext(websiteId: string, visitorId?: string): void {\n\t\tthis.restClient.setWebsiteContext(websiteId, visitorId);\n\t}\n\n\tsetVisitorBlocked(isBlocked: boolean): void {\n\t\tthis.restClient.setVisitorBlocked(isBlocked);\n\t}\n\n\tasync updateVisitorMetadata(\n\t\tmetadata: VisitorMetadata\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateVisitorMetadata(metadata);\n\t}\n\n\tasync identify(params: {\n\t\texternalId?: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t\tcontactOrganizationId?: string;\n\t}): Promise<IdentifyContactResponse> {\n\t\treturn this.restClient.identify(params);\n\t}\n\n\tasync updateContactMetadata(\n\t\tmetadata: Record<string, unknown>\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateContactMetadata(metadata);\n\t}\n\n\t// Conversation management\n\tinitiateConversation(\n\t\tparams: InitiateConversationParams = {}\n\t): InitiateConversationResult {\n\t\tconst conversationId = params.conversationId ?? generateConversationId();\n\t\tconst now = typeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\t\tconst timelineItems = (params.defaultTimelineItems ?? []).map((item) =>\n\t\t\tnormalizeBootstrapTimelineItem(conversationId, item)\n\t\t);\n\t\tconst existing = this.conversationsStore.getState().byId[conversationId];\n\t\tconst baseVisitorId =\n\t\t\tparams.visitorId ?? this.restClient.getCurrentVisitorId() ?? \"\";\n\t\tconst baseWebsiteId =\n\t\t\tparams.websiteId ?? this.restClient.getCurrentWebsiteId() ?? \"\";\n\n\t\tconst conversation: Conversation = existing\n\t\t\t? {\n\t\t\t\t\t...existing,\n\t\t\t\t\ttitle: params.title ?? existing.title,\n\t\t\t\t\tstatus: params.status ?? existing.status,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1) ?? existing.lastTimelineItem,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tid: conversationId,\n\t\t\t\t\ttitle: params.title,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tvisitorId: baseVisitorId,\n\t\t\t\t\twebsiteId: baseWebsiteId,\n\t\t\t\t\tstatus: params.status ?? ConversationStatus.OPEN,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1),\n\t\t\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(conversation);\n\n\t\tif (timelineItems.length > 0) {\n\t\t\tthis.timelineItemsStore.ingestPage(conversationId, {\n\t\t\t\titems: timelineItems,\n\t\t\t\thasNextPage: false,\n\t\t\t\tnextCursor: undefined,\n\t\t\t});\n\t\t}\n\n\t\tif (!existing || this.pendingConversations.has(conversationId)) {\n\t\t\tthis.pendingConversations.set(conversationId, {\n\t\t\t\tconversation,\n\t\t\t\tinitialTimelineItems: timelineItems,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tconversationId,\n\t\t\tconversation,\n\t\t\tdefaultTimelineItems: timelineItems,\n\t\t};\n\t}\n\n\tasync createConversation(\n\t\tparams?: Partial<CreateConversationRequestBody>\n\t): Promise<CreateConversationResponseBody> {\n\t\tconst response = await this.restClient.createConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync listConversations(\n\t\tparams?: Partial<ListConversationsRequest>\n\t): Promise<ListConversationsResponse> {\n\t\tconst response = await this.restClient.listConversations(params);\n\t\tthis.conversationsStore.ingestList(response);\n\t\treturn response;\n\t}\n\n\tasync getConversation(\n\t\tparams: GetConversationRequest\n\t): Promise<GetConversationResponse> {\n\t\tconst response = await this.restClient.getConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync markConversationSeen(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & Partial<MarkConversationSeenRequestBody>\n\t): Promise<MarkConversationSeenResponseBody> {\n\t\treturn this.restClient.markConversationSeen(params);\n\t}\n\n\tasync getConversationSeenData(params: { conversationId: string }) {\n\t\treturn this.restClient.getConversationSeenData(params);\n\t}\n\n\tasync setVisitorTyping(params: {\n\t\tconversationId: string;\n\t\tisTyping: boolean;\n\t\tvisitorPreview?: string | null;\n\t\tvisitorId?: string;\n\t}): Promise<SetConversationTypingResponseBody> {\n\t\treturn this.restClient.setConversationTyping(params);\n\t}\n\n\t// Timeline items management\n\n\tasync getConversationTimelineItems(\n\t\tparams: GetConversationTimelineItemsRequest & { conversationId: string }\n\t): Promise<GetConversationTimelineItemsResponse> {\n\t\tconst response = await this.restClient.getConversationTimelineItems(params);\n\t\tthis.timelineItemsStore.ingestPage(params.conversationId, {\n\t\t\titems: response.items,\n\t\t\thasNextPage: response.hasNextPage,\n\t\t\tnextCursor: response.nextCursor ?? undefined,\n\t\t});\n\t\treturn response;\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendTimelineItemRequest & { createIfPending?: boolean }\n\t): Promise<\n\t\tSendTimelineItemResponse & {\n\t\t\tconversation?: Conversation;\n\t\t\tinitialTimelineItems?: TimelineItem[];\n\t\t\twasConversationCreated?: boolean;\n\t\t}\n\t> {\n\t\tconst { createIfPending, ...rest } = params;\n\t\tconst optimisticId = rest.item.id ?? generateMessageId();\n\t\tconst createdAt = rest.item.createdAt\n\t\t\t? rest.item.createdAt\n\t\t\t: typeof window !== \"undefined\"\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: \"\";\n\n\t\t// Add optimistic timeline item\n\t\tconst optimisticTimelineItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId: rest.conversationId,\n\t\t\torganizationId: \"\", // Not available yet\n\t\t\tvisibility: rest.item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t\t\ttype: rest.item.type ?? ConversationTimelineType.MESSAGE,\n\t\t\ttext: rest.item.text,\n\t\t\ttool: rest.item.tool ?? null,\n\t\t\tparts:\n\t\t\t\trest.item.parts && rest.item.parts.length > 0\n\t\t\t\t\t? rest.item.parts\n\t\t\t\t\t: rest.item.text\n\t\t\t\t\t\t? [{ type: \"text\" as const, text: rest.item.text }]\n\t\t\t\t\t\t: [],\n\t\t\tuserId: rest.item.userId ?? null,\n\t\t\tvisitorId: rest.item.visitorId ?? null,\n\t\t\taiAgentId: rest.item.aiAgentId ?? null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\tthis.timelineItemsStore.ingestTimelineItem(optimisticTimelineItem);\n\n\t\tconst pending = this.pendingConversations.get(rest.conversationId);\n\n\t\tif (pending && createIfPending !== false) {\n\t\t\ttry {\n\t\t\t\tconst response = await this.restClient.createConversation({\n\t\t\t\t\tconversationId: rest.conversationId,\n\t\t\t\t\tdefaultTimelineItems: [\n\t\t\t\t\t\t...pending.initialTimelineItems,\n\t\t\t\t\t\toptimisticTimelineItem,\n\t\t\t\t\t],\n\t\t\t\t});\n\n\t\t\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthis.timelineItemsStore.clearConversation(rest.conversationId);\n\n\t\t\t\tthis.timelineItemsStore.ingestPage(rest.conversationId, {\n\t\t\t\t\titems: response.initialTimelineItems,\n\t\t\t\t\thasNextPage: false,\n\t\t\t\t\tnextCursor: undefined,\n\t\t\t\t});\n\n\t\t\t\tthis.pendingConversations.delete(rest.conversationId);\n\n\t\t\t\tconst item =\n\t\t\t\t\tresponse.initialTimelineItems.at(-1) ??\n\t\t\t\t\tresponse.initialTimelineItems[0];\n\n\t\t\t\treturn {\n\t\t\t\t\titem: item as TimelineItem,\n\t\t\t\t\tconversation: response.conversation,\n\t\t\t\t\tinitialTimelineItems: response.initialTimelineItems,\n\t\t\t\t\twasConversationCreated: true,\n\t\t\t\t} satisfies SendTimelineItemResponse & {\n\t\t\t\t\tconversation: Conversation;\n\t\t\t\t\tinitialTimelineItems: TimelineItem[];\n\t\t\t\t\twasConversationCreated: true;\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst { createdAt: _createdAt, ...restItem } = rest.item;\n\n\t\tconst payload: SendTimelineItemRequest = {\n\t\t\t...rest,\n\t\t\titem: {\n\t\t\t\t...restItem,\n\t\t\t\tid: optimisticId,\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this.restClient.sendMessage(payload);\n\n\t\t\t// Finalize the timeline item\n\t\t\tthis.timelineItemsStore.finalizeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId,\n\t\t\t\tresponse.item\n\t\t\t);\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\thandleRealtimeEvent(event: AnyRealtimeEvent): void {\n\t\tif (event.type === \"conversationCreated\") {\n\t\t\tconst { conversation, header } = event.payload;\n\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...conversation,\n\t\t\t\tlastTimelineItem: conversation.lastTimelineItem ?? undefined,\n\t\t\t});\n\t\t} else if (event.type === \"timelineItemCreated\") {\n\t\t\t// Ingest timeline item into store\n\t\t\tconst timelineItem =\n\t\t\t\tthis.timelineItemsStore.ingestRealtimeTimelineItem(event);\n\n\t\t\t// Update conversation with last timeline item\n\t\t\tconst existingConversation =\n\t\t\t\tthis.conversationsStore.getState().byId[timelineItem.conversationId];\n\n\t\t\tif (existingConversation) {\n\t\t\t\tconst nextConversation = {\n\t\t\t\t\t...existingConversation,\n\t\t\t\t\tupdatedAt: timelineItem.createdAt,\n\t\t\t\t\tlastTimelineItem: timelineItem,\n\t\t\t\t};\n\n\t\t\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cleanup method\n\tdestroy(): void {\n\t\t// No cleanup needed for REST client\n\t}\n}\n\nfunction normalizeBootstrapTimelineItem(\n\tconversationId: string,\n\titem: DefaultMessage | TimelineItem\n): TimelineItem {\n\tif (isDefaultMessage(item)) {\n\t\tconst createdAt =\n\t\t\ttypeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\n\t\treturn {\n\t\t\tid: generateMessageId(),\n\t\t\tconversationId,\n\t\t\torganizationId: \"\", // Not available at this point\n\t\t\ttype: ConversationTimelineType.MESSAGE,\n\t\t\ttext: item.content,\n\t\t\tparts: [{ type: \"text\" as const, text: item.content }],\n\t\t\tvisibility: TimelineItemVisibility.PUBLIC,\n\t\t\tuserId:\n\t\t\t\titem.senderType === SenderType.TEAM_MEMBER\n\t\t\t\t\t? (item.senderId ?? null)\n\t\t\t\t\t: null,\n\t\t\taiAgentId:\n\t\t\t\titem.senderType === SenderType.AI ? (item.senderId ?? null) : null,\n\t\t\tvisitorId:\n\t\t\t\titem.senderType === SenderType.VISITOR ? (item.senderId ?? null) : null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t} satisfies TimelineItem;\n\t}\n\n\tconst createdAt = item.createdAt\n\t\t? item.createdAt\n\t\t: typeof window !== \"undefined\"\n\t\t\t? new Date().toISOString()\n\t\t\t: \"\";\n\n\treturn {\n\t\t...item,\n\t\tid: item.id ?? generateMessageId(),\n\t\tconversationId,\n\t\torganizationId: item.organizationId || \"\",\n\t\ttype: item.type ?? ConversationTimelineType.MESSAGE,\n\t\ttool: item.tool ?? null,\n\t\tcreatedAt,\n\t\tdeletedAt: item.deletedAt ?? null,\n\t\tuserId: item.userId ?? null,\n\t\taiAgentId: item.aiAgentId ?? null,\n\t\tvisitorId: item.visitorId ?? null,\n\t\tvisibility: item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t} satisfies TimelineItem;\n}\n\nfunction isDefaultMessage(\n\titem: DefaultMessage | TimelineItem\n): item is DefaultMessage {\n\treturn (item as DefaultMessage).content !== undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["current: WebsiteState","conversation: Conversation","optimisticTimelineItem: TimelineItem","payload: SendTimelineItemRequest","createdAt"],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype AnyRealtimeEvent,\n\ttype DefaultMessage,\n\tgetEventPayload,\n\ttype IdentifyContactResponse,\n\ttype RealtimeEvent,\n} from \"@cossistant/types\";\nimport type {\n\tCreateConversationRequestBody,\n\tCreateConversationResponseBody,\n\tGetConversationRequest,\n\tGetConversationResponse,\n\tListConversationsRequest,\n\tListConversationsResponse,\n\tMarkConversationSeenRequestBody,\n\tMarkConversationSeenResponseBody,\n\tSetConversationTypingResponseBody,\n} from \"@cossistant/types/api/conversation\";\nimport type {\n\tGetConversationTimelineItemsRequest,\n\tGetConversationTimelineItemsResponse,\n\tSendTimelineItemRequest,\n\tSendTimelineItemResponse,\n\tTimelineItem,\n} from \"@cossistant/types/api/timeline-item\";\nimport {\n\tConversationStatus,\n\tConversationTimelineType,\n\tSenderType,\n\tTimelineItemVisibility,\n} from \"@cossistant/types/enums\";\nimport type { Conversation } from \"@cossistant/types/schemas\";\nimport { CossistantRestClient } from \"./rest-client\";\nimport {\n\ttype ConversationsStore,\n\tcreateConversationsStore,\n} from \"./store/conversations-store\";\nimport {\n\tcreateTimelineItemsStore,\n\ttype TimelineItemsStore,\n} from \"./store/timeline-items-store\";\nimport {\n\tcreateWebsiteStore,\n\ttype WebsiteState,\n\ttype WebsiteStore,\n} from \"./store/website-store\";\nimport type {\n\tCossistantConfig,\n\tPublicWebsiteResponse,\n\tVisitorMetadata,\n\tVisitorResponse,\n} from \"./types\";\nimport { generateConversationId, generateMessageId } from \"./utils\";\n\ntype PendingConversation = {\n\tconversation: Conversation;\n\tinitialTimelineItems: TimelineItem[];\n};\n\ntype InitiateConversationParams = {\n\tconversationId?: string;\n\tvisitorId?: string | null;\n\twebsiteId?: string | null;\n\ttitle?: string;\n\tstatus?: Conversation[\"status\"];\n\tdefaultTimelineItems?: Array<DefaultMessage | TimelineItem>;\n};\n\ntype InitiateConversationResult = {\n\tconversationId: string;\n\tconversation: Conversation;\n\tdefaultTimelineItems: TimelineItem[];\n};\n\nexport class CossistantClient {\n\tprivate restClient: CossistantRestClient;\n\tprivate config: CossistantConfig;\n\tprivate pendingConversations = new Map<string, PendingConversation>();\n\tprivate websiteRequest: Promise<PublicWebsiteResponse> | null = null;\n\treadonly conversationsStore: ConversationsStore;\n\treadonly timelineItemsStore: TimelineItemsStore;\n\treadonly websiteStore: WebsiteStore;\n\n\tconstructor(config: CossistantConfig) {\n\t\tthis.config = config;\n\t\tthis.restClient = new CossistantRestClient(config);\n\t\tthis.conversationsStore = createConversationsStore();\n\t\tthis.timelineItemsStore = createTimelineItemsStore();\n\t\tthis.websiteStore = createWebsiteStore();\n\t}\n\n\t// Configuration updates\n\tupdateConfiguration(config: Partial<CossistantConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t\tthis.restClient.updateConfiguration(config);\n\t}\n\n\t// Utility methods\n\tgetConfiguration(): CossistantConfig {\n\t\treturn { ...this.config };\n\t}\n\n\t// Website information\n\tasync fetchWebsite(\n\t\tparams: { force?: boolean } = {}\n\t): Promise<PublicWebsiteResponse> {\n\t\tconst { force = false } = params;\n\t\tconst current: WebsiteState = this.websiteStore.getState();\n\n\t\tif (!force) {\n\t\t\tif (current.status === \"success\" && current.website) {\n\t\t\t\treturn current.website;\n\t\t\t}\n\t\t\tif (this.websiteRequest) {\n\t\t\t\treturn this.websiteRequest;\n\t\t\t}\n\t\t}\n\n\t\tthis.websiteStore.setLoading();\n\n\t\tconst request = this.restClient\n\t\t\t.getWebsite()\n\t\t\t.then((website) => {\n\t\t\t\tthis.websiteStore.setWebsite(website);\n\t\t\t\treturn website;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.websiteStore.setError(error);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.websiteRequest === request) {\n\t\t\t\t\tthis.websiteRequest = null;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.websiteRequest = request;\n\n\t\treturn request;\n\t}\n\n\tasync getWebsite(): Promise<PublicWebsiteResponse> {\n\t\treturn this.fetchWebsite({ force: true });\n\t}\n\n\tsetWebsiteContext(websiteId: string, visitorId?: string): void {\n\t\tthis.restClient.setWebsiteContext(websiteId, visitorId);\n\t}\n\n\tsetVisitorBlocked(isBlocked: boolean): void {\n\t\tthis.restClient.setVisitorBlocked(isBlocked);\n\t}\n\n\tasync updateVisitorMetadata(\n\t\tmetadata: VisitorMetadata\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateVisitorMetadata(metadata);\n\t}\n\n\tasync identify(params: {\n\t\texternalId?: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t\tcontactOrganizationId?: string;\n\t}): Promise<IdentifyContactResponse> {\n\t\treturn this.restClient.identify(params);\n\t}\n\n\tasync updateContactMetadata(\n\t\tmetadata: Record<string, unknown>\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateContactMetadata(metadata);\n\t}\n\n\t// Conversation management\n\tinitiateConversation(\n\t\tparams: InitiateConversationParams = {}\n\t): InitiateConversationResult {\n\t\tconst conversationId = params.conversationId ?? generateConversationId();\n\t\tconst now = typeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\t\tconst timelineItems = (params.defaultTimelineItems ?? []).map((item) =>\n\t\t\tnormalizeBootstrapTimelineItem(conversationId, item)\n\t\t);\n\t\tconst existing = this.conversationsStore.getState().byId[conversationId];\n\t\tconst baseVisitorId =\n\t\t\tparams.visitorId ?? this.restClient.getCurrentVisitorId() ?? \"\";\n\t\tconst baseWebsiteId =\n\t\t\tparams.websiteId ?? this.restClient.getCurrentWebsiteId() ?? \"\";\n\n\t\tconst conversation: Conversation = existing\n\t\t\t? {\n\t\t\t\t\t...existing,\n\t\t\t\t\ttitle: params.title ?? existing.title,\n\t\t\t\t\tstatus: params.status ?? existing.status,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1) ?? existing.lastTimelineItem,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tid: conversationId,\n\t\t\t\t\ttitle: params.title,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tvisitorId: baseVisitorId,\n\t\t\t\t\twebsiteId: baseWebsiteId,\n\t\t\t\t\tstatus: params.status ?? ConversationStatus.OPEN,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1),\n\t\t\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(conversation);\n\n\t\tif (timelineItems.length > 0) {\n\t\t\tthis.timelineItemsStore.ingestPage(conversationId, {\n\t\t\t\titems: timelineItems,\n\t\t\t\thasNextPage: false,\n\t\t\t\tnextCursor: undefined,\n\t\t\t});\n\t\t}\n\n\t\tif (!existing || this.pendingConversations.has(conversationId)) {\n\t\t\tthis.pendingConversations.set(conversationId, {\n\t\t\t\tconversation,\n\t\t\t\tinitialTimelineItems: timelineItems,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tconversationId,\n\t\t\tconversation,\n\t\t\tdefaultTimelineItems: timelineItems,\n\t\t};\n\t}\n\n\tasync createConversation(\n\t\tparams?: Partial<CreateConversationRequestBody>\n\t): Promise<CreateConversationResponseBody> {\n\t\tconst response = await this.restClient.createConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync listConversations(\n\t\tparams?: Partial<ListConversationsRequest>\n\t): Promise<ListConversationsResponse> {\n\t\tconst response = await this.restClient.listConversations(params);\n\t\tthis.conversationsStore.ingestList(response);\n\t\treturn response;\n\t}\n\n\tasync getConversation(\n\t\tparams: GetConversationRequest\n\t): Promise<GetConversationResponse> {\n\t\tconst response = await this.restClient.getConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync markConversationSeen(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & Partial<MarkConversationSeenRequestBody>\n\t): Promise<MarkConversationSeenResponseBody> {\n\t\treturn this.restClient.markConversationSeen(params);\n\t}\n\n\tasync getConversationSeenData(params: { conversationId: string }) {\n\t\treturn this.restClient.getConversationSeenData(params);\n\t}\n\n\tasync setVisitorTyping(params: {\n\t\tconversationId: string;\n\t\tisTyping: boolean;\n\t\tvisitorPreview?: string | null;\n\t\tvisitorId?: string;\n\t}): Promise<SetConversationTypingResponseBody> {\n\t\treturn this.restClient.setConversationTyping(params);\n\t}\n\n\t// Timeline items management\n\n\tasync getConversationTimelineItems(\n\t\tparams: GetConversationTimelineItemsRequest & { conversationId: string }\n\t): Promise<GetConversationTimelineItemsResponse> {\n\t\tconst response = await this.restClient.getConversationTimelineItems(params);\n\t\tthis.timelineItemsStore.ingestPage(params.conversationId, {\n\t\t\titems: response.items,\n\t\t\thasNextPage: response.hasNextPage,\n\t\t\tnextCursor: response.nextCursor ?? undefined,\n\t\t});\n\t\treturn response;\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendTimelineItemRequest & { createIfPending?: boolean }\n\t): Promise<\n\t\tSendTimelineItemResponse & {\n\t\t\tconversation?: Conversation;\n\t\t\tinitialTimelineItems?: TimelineItem[];\n\t\t\twasConversationCreated?: boolean;\n\t\t}\n\t> {\n\t\tconst { createIfPending, ...rest } = params;\n\t\tconst optimisticId = rest.item.id ?? generateMessageId();\n\t\tconst createdAt = rest.item.createdAt\n\t\t\t? rest.item.createdAt\n\t\t\t: typeof window !== \"undefined\"\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: \"\";\n\n\t\t// Add optimistic timeline item\n\t\tconst optimisticTimelineItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId: rest.conversationId,\n\t\t\torganizationId: \"\", // Not available yet\n\t\t\tvisibility: rest.item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t\t\ttype: rest.item.type ?? ConversationTimelineType.MESSAGE,\n\t\t\ttext: rest.item.text,\n\t\t\ttool: rest.item.tool ?? null,\n\t\t\tparts:\n\t\t\t\trest.item.parts && rest.item.parts.length > 0\n\t\t\t\t\t? rest.item.parts\n\t\t\t\t\t: rest.item.text\n\t\t\t\t\t\t? [{ type: \"text\" as const, text: rest.item.text }]\n\t\t\t\t\t\t: [],\n\t\t\tuserId: rest.item.userId ?? null,\n\t\t\tvisitorId: rest.item.visitorId ?? null,\n\t\t\taiAgentId: rest.item.aiAgentId ?? null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\tthis.timelineItemsStore.ingestTimelineItem(optimisticTimelineItem);\n\n\t\tconst pending = this.pendingConversations.get(rest.conversationId);\n\n\t\tif (pending && createIfPending !== false) {\n\t\t\ttry {\n\t\t\t\tconst response = await this.restClient.createConversation({\n\t\t\t\t\tconversationId: rest.conversationId,\n\t\t\t\t\tdefaultTimelineItems: [\n\t\t\t\t\t\t...pending.initialTimelineItems,\n\t\t\t\t\t\toptimisticTimelineItem,\n\t\t\t\t\t],\n\t\t\t\t});\n\n\t\t\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthis.timelineItemsStore.clearConversation(rest.conversationId);\n\n\t\t\t\tthis.timelineItemsStore.ingestPage(rest.conversationId, {\n\t\t\t\t\titems: response.initialTimelineItems,\n\t\t\t\t\thasNextPage: false,\n\t\t\t\t\tnextCursor: undefined,\n\t\t\t\t});\n\n\t\t\t\tthis.pendingConversations.delete(rest.conversationId);\n\n\t\t\t\tconst item =\n\t\t\t\t\tresponse.initialTimelineItems.at(-1) ??\n\t\t\t\t\tresponse.initialTimelineItems[0];\n\n\t\t\t\treturn {\n\t\t\t\t\titem: item as TimelineItem,\n\t\t\t\t\tconversation: response.conversation,\n\t\t\t\t\tinitialTimelineItems: response.initialTimelineItems,\n\t\t\t\t\twasConversationCreated: true,\n\t\t\t\t} satisfies SendTimelineItemResponse & {\n\t\t\t\t\tconversation: Conversation;\n\t\t\t\t\tinitialTimelineItems: TimelineItem[];\n\t\t\t\t\twasConversationCreated: true;\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst { createdAt: _createdAt, ...restItem } = rest.item;\n\n\t\tconst payload: SendTimelineItemRequest = {\n\t\t\t...rest,\n\t\t\titem: {\n\t\t\t\t...restItem,\n\t\t\t\tid: optimisticId,\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this.restClient.sendMessage(payload);\n\n\t\t\t// Finalize the timeline item\n\t\t\tthis.timelineItemsStore.finalizeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId,\n\t\t\t\tresponse.item\n\t\t\t);\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\thandleRealtimeEvent(event: AnyRealtimeEvent): void {\n\t\tif (event.type === \"conversationCreated\") {\n\t\t\tconst { conversation, header } = event.payload;\n\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...conversation,\n\t\t\t\tlastTimelineItem: conversation.lastTimelineItem ?? undefined,\n\t\t\t});\n\t\t} else if (event.type === \"timelineItemCreated\") {\n\t\t\t// Ingest timeline item into store\n\t\t\tconst timelineItem =\n\t\t\t\tthis.timelineItemsStore.ingestRealtimeTimelineItem(event);\n\n\t\t\t// Update conversation with last timeline item\n\t\t\tconst existingConversation =\n\t\t\t\tthis.conversationsStore.getState().byId[timelineItem.conversationId];\n\n\t\t\tif (existingConversation) {\n\t\t\t\tconst nextConversation = {\n\t\t\t\t\t...existingConversation,\n\t\t\t\t\tupdatedAt: timelineItem.createdAt,\n\t\t\t\t\tlastTimelineItem: timelineItem,\n\t\t\t\t};\n\n\t\t\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t\t\t}\n\t\t}\n\t}\n\n\t// File upload methods\n\t/**\n\t * Generate a presigned URL for uploading a file to S3.\n\t */\n\tasync generateUploadUrl(\n\t\tparams: Omit<\n\t\t\tParameters<CossistantRestClient[\"generateUploadUrl\"]>[0],\n\t\t\t\"websiteId\"\n\t\t>\n\t) {\n\t\treturn this.restClient.generateUploadUrl(params);\n\t}\n\n\t/**\n\t * Upload a file to S3 using a presigned URL.\n\t */\n\tasync uploadFile(file: File, uploadUrl: string, contentType: string) {\n\t\treturn this.restClient.uploadFile(file, uploadUrl, contentType);\n\t}\n\n\t/**\n\t * Upload multiple files for a conversation message.\n\t */\n\tasync uploadFilesForMessage(files: File[], conversationId: string) {\n\t\treturn this.restClient.uploadFilesForMessage(files, conversationId);\n\t}\n\n\t// Cleanup method\n\tdestroy(): void {\n\t\t// No cleanup needed for REST client\n\t}\n}\n\nfunction normalizeBootstrapTimelineItem(\n\tconversationId: string,\n\titem: DefaultMessage | TimelineItem\n): TimelineItem {\n\tif (isDefaultMessage(item)) {\n\t\tconst createdAt =\n\t\t\ttypeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\n\t\treturn {\n\t\t\tid: generateMessageId(),\n\t\t\tconversationId,\n\t\t\torganizationId: \"\", // Not available at this point\n\t\t\ttype: ConversationTimelineType.MESSAGE,\n\t\t\ttext: item.content,\n\t\t\tparts: [{ type: \"text\" as const, text: item.content }],\n\t\t\tvisibility: TimelineItemVisibility.PUBLIC,\n\t\t\tuserId:\n\t\t\t\titem.senderType === SenderType.TEAM_MEMBER\n\t\t\t\t\t? (item.senderId ?? null)\n\t\t\t\t\t: null,\n\t\t\taiAgentId:\n\t\t\t\titem.senderType === SenderType.AI ? (item.senderId ?? null) : null,\n\t\t\tvisitorId:\n\t\t\t\titem.senderType === SenderType.VISITOR ? (item.senderId ?? null) : null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t} satisfies TimelineItem;\n\t}\n\n\tconst createdAt = item.createdAt\n\t\t? item.createdAt\n\t\t: typeof window !== \"undefined\"\n\t\t\t? new Date().toISOString()\n\t\t\t: \"\";\n\n\treturn {\n\t\t...item,\n\t\tid: item.id ?? generateMessageId(),\n\t\tconversationId,\n\t\torganizationId: item.organizationId || \"\",\n\t\ttype: item.type ?? ConversationTimelineType.MESSAGE,\n\t\ttool: item.tool ?? null,\n\t\tcreatedAt,\n\t\tdeletedAt: item.deletedAt ?? null,\n\t\tuserId: item.userId ?? null,\n\t\taiAgentId: item.aiAgentId ?? null,\n\t\tvisitorId: item.visitorId ?? null,\n\t\tvisibility: item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t} satisfies TimelineItem;\n}\n\nfunction isDefaultMessage(\n\titem: DefaultMessage | TimelineItem\n): item is DefaultMessage {\n\treturn (item as DefaultMessage).content !== undefined;\n}\n"],"mappings":"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"}
|
package/conversation.d.ts
CHANGED
|
@@ -159,6 +159,7 @@ declare const createConversationResponseSchema: z.ZodObject<{
|
|
|
159
159
|
spam: "spam";
|
|
160
160
|
}>>;
|
|
161
161
|
deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
162
|
+
visitorLastSeenAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
162
163
|
lastTimelineItem: z.ZodOptional<z.ZodObject<{
|
|
163
164
|
id: z.ZodOptional<z.ZodString>;
|
|
164
165
|
conversationId: z.ZodString;
|
|
@@ -263,6 +264,7 @@ declare const listConversationsResponseSchema: z.ZodObject<{
|
|
|
263
264
|
spam: "spam";
|
|
264
265
|
}>>;
|
|
265
266
|
deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
267
|
+
visitorLastSeenAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
266
268
|
lastTimelineItem: z.ZodOptional<z.ZodObject<{
|
|
267
269
|
id: z.ZodOptional<z.ZodString>;
|
|
268
270
|
conversationId: z.ZodString;
|
|
@@ -360,6 +362,7 @@ declare const getConversationResponseSchema: z.ZodObject<{
|
|
|
360
362
|
spam: "spam";
|
|
361
363
|
}>>;
|
|
362
364
|
deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
365
|
+
visitorLastSeenAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
363
366
|
lastTimelineItem: z.ZodOptional<z.ZodObject<{
|
|
364
367
|
id: z.ZodOptional<z.ZodString>;
|
|
365
368
|
conversationId: z.ZodString;
|
package/conversation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","names":[],"sources":["../../types/src/api/conversation.ts"],"sourcesContent":[],"mappings":";;;cAIa,iCAA+B,CAAA,CAAA;;EAA/B,cAAA,eAAA,YAoBV,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAES,6BAAA,GAAgC,CAAA,CAAE,aACtC;cAGK,kCAAgC,CAAA,CAAA;;;;;;MA1BD,MAAA,EAAA,QAAA;MAAA,OAAA,EAAA,SAAA;IAsBhC,CAAA,CAAA;IAIC,IAAA,WAAA,CAAA
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","names":[],"sources":["../../types/src/api/conversation.ts"],"sourcesContent":[],"mappings":";;;cAIa,iCAA+B,CAAA,CAAA;;EAA/B,cAAA,eAAA,YAoBV,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAES,6BAAA,GAAgC,CAAA,CAAE,aACtC;cAGK,kCAAgC,CAAA,CAAA;;;;;;MA1BD,MAAA,EAAA,QAAA;MAAA,OAAA,EAAA,SAAA;IAsBhC,CAAA,CAAA;IAIC,IAAA,WAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASD,8BAAA,GAAiC,CAAA,CAAE,aACvC;cAGK,gCAA8B,CAAA,CAAA;;;;;;;;;;;;;;IAbE,IAAA,EAAA,MAAA;EAAA,CAAA,CAAA,CAAA;AAS7C,CAAA,eAAY,CAAA;AAIC,KA6BD,wBAAA,GAA2B,CAAA,CAAE,KAFtC,CAAA,OAGK,8BAHL,CAAA;cAMU,iCAA+B,CAAA,CAAA;;;;;;;;;;;;;IAjCD,SAAA,cAAA,cAAA,YAAA,CAAA,CAAA;IAAA,iBAAA,eAAA,cAAA,YAAA,CAAA,CAAA;IA6B/B,gBAAA,eAAwB,YAC5B,CAAA;MAGK,EAAA,eAAA,YAaV,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAES,yBAAA,GAA4B,CAAA,CAAE,aAClC;cAGK,8BAA4B,CAAA,CAAA;;;KAU7B,sBAAA,GAAyB,CAAA,CAAE,aAC/B;cAGK,+BAA6B,CAAA,CAAA;;;;;;;;;;;;;;;;MAjCE,EAAA,eAAA,YAAA,CAAA;MAAA,cAAA,aAAA;MAehC,cAAA,aAAyB;MAIxB,UAAA,WAAA,CAAA;;;MAA4B,CAAA,CAAA;MAAA,IAAA,WAAA,CAAA;QAU7B,OAAA,EAAA,SAAsB;QAIrB,KAAA,EAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAQD,uBAAA,GAA0B,CAAA,CAAE,aAChC;cAGK,mCAAiC,CAAA,CAAA;;;KAYlC,+BAAA,GAAkC,CAAA,CAAE,aACxC;cAGK,oCAAkC,CAAA,CAAA;;;;KAcnC,gCAAA,GAAmC,CAAA,CAAE,aACzC;cA0BK,qCAAmC,CAAA,CAAA;;;;;;KAoBpC,iCAAA,GAAoC,CAAA,CAAE,aAC1C;cAGK,uCAAqC,CAAA,CAAA;;;;;;IA7FR,SAAA,eAAA,YAAA,CAAA;IAAA,UAAA,aAAA;IAQ9B,SAAA,aAAuB;IAItB,SAAA,aAAA;;;;AAAiC,KAwHlC,+BAAA,GAAkC,CAAA,CAAE,KAxHF,CAAA,OAyHtC,qCAzHsC,CAAA"}
|
package/index.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CossistantAPIError } from "./types.js";
|
|
2
|
+
import { CossistantRestClient } from "./rest-client.js";
|
|
3
|
+
import { ConversationPagination, ConversationWithSeen, ConversationsState, ConversationsStore, createConversationsStore, getConversationById, getConversationPagination, getConversations } from "./store/conversations-store.js";
|
|
2
4
|
import { ConversationTimelineItemsState, TimelineItemsState, TimelineItemsStore, createTimelineItemsStore, getConversationTimelineItems } from "./store/timeline-items-store.js";
|
|
3
5
|
import { WebsiteError, WebsiteState, WebsiteStatus, WebsiteStore, createWebsiteStore, getWebsiteState } from "./store/website-store.js";
|
|
4
|
-
import { CossistantAPIError } from "./types.js";
|
|
5
6
|
import { CossistantClient } from "./client.js";
|
|
6
7
|
import { normalizeLocale } from "./locale-utils.js";
|
|
7
|
-
import { CossistantRestClient } from "./rest-client.js";
|
|
8
8
|
import { ConversationSeenState, SeenActorType, SeenEntry, SeenState, SeenStore, applyConversationSeenEvent, createSeenStore, hydrateConversationSeen, upsertConversationSeen } from "./store/seen-store.js";
|
|
9
9
|
import { DefaultRoutes, NavigationState, RouteRegistry, SUPPORT_PAGES, SupportConfig, SupportNavigation, SupportPage, SupportStore, SupportStoreActions, SupportStoreOptions, SupportStoreState, SupportStoreStorage, createSupportStore } from "./store/support-store.js";
|
|
10
10
|
import { ConversationTypingState, TypingActorType, TypingEntry, TypingState, TypingStore, TypingStoreDependencies, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
11
|
+
import { TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, TypingReporter, TypingReporterConfig, createTypingReporter } from "./typing-reporter.js";
|
|
12
|
+
import { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, formatFileSize, isAllowedMimeType, isImageMimeType, validateFile, validateFiles } from "./upload-constants.js";
|
|
11
13
|
import { generateConversationId, generateMessageId } from "./utils.js";
|
|
12
14
|
import { VisitorData, collectVisitorData } from "./visitor-data.js";
|
|
13
15
|
import { generateVisitorName, getVisitorNameWithFallback } from "./visitor-name.js";
|
|
14
16
|
import { clearAllVisitorIds, clearVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
15
17
|
import { CossistantConfig, CossistantError } from "@cossistant/types";
|
|
16
|
-
export { type ConversationPagination, type ConversationSeenState, type ConversationTimelineItemsState, type ConversationTypingState, type ConversationsState, type ConversationsStore, CossistantAPIError, CossistantClient, type CossistantConfig, type CossistantError, CossistantRestClient, type DefaultRoutes, type NavigationState, type RouteRegistry, type SUPPORT_PAGES, type SeenActorType, type SeenEntry, type SeenState, type SeenStore, type SupportConfig, type SupportNavigation, type SupportPage, type SupportStore, type SupportStoreActions, type SupportStoreOptions, type SupportStoreState, type SupportStoreStorage, type TimelineItemsState, type TimelineItemsStore, type TypingActorType, type TypingEntry, type TypingState, type TypingStore, type TypingStoreDependencies, type VisitorData, type WebsiteError, type WebsiteState, type WebsiteStatus, type WebsiteStore, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingStore, createWebsiteStore, CossistantClient as default, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hydrateConversationSeen, normalizeLocale, setTypingState, setVisitorId, upsertConversationSeen };
|
|
18
|
+
export { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, type ConversationPagination, type ConversationSeenState, type ConversationTimelineItemsState, type ConversationTypingState, type ConversationWithSeen, type ConversationsState, type ConversationsStore, CossistantAPIError, CossistantClient, type CossistantConfig, type CossistantError, CossistantRestClient, type DefaultRoutes, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, type NavigationState, type RouteRegistry, type SUPPORT_PAGES, type SeenActorType, type SeenEntry, type SeenState, type SeenStore, type SupportConfig, type SupportNavigation, type SupportPage, type SupportStore, type SupportStoreActions, type SupportStoreOptions, type SupportStoreState, type SupportStoreStorage, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, type TimelineItemsState, type TimelineItemsStore, type TypingActorType, type TypingEntry, type TypingReporter, type TypingReporterConfig, type TypingState, type TypingStore, type TypingStoreDependencies, type VisitorData, type WebsiteError, type WebsiteState, type WebsiteStatus, type WebsiteStore, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, formatFileSize, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hydrateConversationSeen, isAllowedMimeType, isImageMimeType, normalizeLocale, setTypingState, setVisitorId, upsertConversationSeen, validateFile, validateFiles };
|
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CossistantAPIError } from "./types.js";
|
|
2
|
+
import { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, formatFileSize, isAllowedMimeType, isImageMimeType, validateFile, validateFiles } from "./upload-constants.js";
|
|
2
3
|
import { generateConversationId, generateMessageId } from "./utils.js";
|
|
3
4
|
import { collectVisitorData } from "./visitor-data.js";
|
|
4
5
|
import { clearAllVisitorIds, clearVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
@@ -11,6 +12,7 @@ import { normalizeLocale } from "./locale-utils.js";
|
|
|
11
12
|
import { applyConversationSeenEvent, createSeenStore, hydrateConversationSeen, upsertConversationSeen } from "./store/seen-store.js";
|
|
12
13
|
import { createSupportStore } from "./store/support-store.js";
|
|
13
14
|
import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
15
|
+
import { TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, createTypingReporter } from "./typing-reporter.js";
|
|
14
16
|
import { generateVisitorName, getVisitorNameWithFallback } from "./visitor-name.js";
|
|
15
17
|
|
|
16
|
-
export { CossistantAPIError, CossistantClient, CossistantRestClient, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingStore, createWebsiteStore, CossistantClient as default, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hydrateConversationSeen, normalizeLocale, setTypingState, setVisitorId, upsertConversationSeen };
|
|
18
|
+
export { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, CossistantAPIError, CossistantClient, CossistantRestClient, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, formatFileSize, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hydrateConversationSeen, isAllowedMimeType, isImageMimeType, normalizeLocale, setTypingState, setVisitorId, upsertConversationSeen, validateFile, validateFiles };
|
package/package.json
CHANGED
package/realtime-events.d.ts
CHANGED
|
@@ -114,6 +114,7 @@ declare const realtimeSchema: {
|
|
|
114
114
|
spam: "spam";
|
|
115
115
|
}>>;
|
|
116
116
|
deletedAt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
117
|
+
visitorLastSeenAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
118
|
lastTimelineItem: z.ZodOptional<z.ZodObject<{
|
|
118
119
|
id: z.ZodOptional<z.ZodString>;
|
|
119
120
|
conversationId: z.ZodString;
|
|
@@ -427,6 +428,44 @@ declare const realtimeSchema: {
|
|
|
427
428
|
}, z.core.$strip>>;
|
|
428
429
|
}, z.core.$strip>;
|
|
429
430
|
}, z.core.$strip>;
|
|
431
|
+
readonly conversationEventCreated: z.ZodObject<{
|
|
432
|
+
websiteId: z.ZodString;
|
|
433
|
+
organizationId: z.ZodString;
|
|
434
|
+
visitorId: z.ZodNullable<z.ZodString>;
|
|
435
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
436
|
+
conversationId: z.ZodString;
|
|
437
|
+
aiAgentId: z.ZodNullable<z.ZodString>;
|
|
438
|
+
event: z.ZodObject<{
|
|
439
|
+
id: z.ZodString;
|
|
440
|
+
conversationId: z.ZodString;
|
|
441
|
+
organizationId: z.ZodString;
|
|
442
|
+
type: z.ZodEnum<{
|
|
443
|
+
assigned: "assigned";
|
|
444
|
+
unassigned: "unassigned";
|
|
445
|
+
participant_requested: "participant_requested";
|
|
446
|
+
participant_joined: "participant_joined";
|
|
447
|
+
participant_left: "participant_left";
|
|
448
|
+
status_changed: "status_changed";
|
|
449
|
+
priority_changed: "priority_changed";
|
|
450
|
+
tag_added: "tag_added";
|
|
451
|
+
tag_removed: "tag_removed";
|
|
452
|
+
resolved: "resolved";
|
|
453
|
+
reopened: "reopened";
|
|
454
|
+
visitor_blocked: "visitor_blocked";
|
|
455
|
+
visitor_unblocked: "visitor_unblocked";
|
|
456
|
+
visitor_identified: "visitor_identified";
|
|
457
|
+
}>;
|
|
458
|
+
actorUserId: z.ZodNullable<z.ZodString>;
|
|
459
|
+
actorAiAgentId: z.ZodNullable<z.ZodString>;
|
|
460
|
+
targetUserId: z.ZodNullable<z.ZodString>;
|
|
461
|
+
targetAiAgentId: z.ZodNullable<z.ZodString>;
|
|
462
|
+
message: z.ZodNullable<z.ZodString>;
|
|
463
|
+
metadata: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
464
|
+
createdAt: z.ZodString;
|
|
465
|
+
updatedAt: z.ZodString;
|
|
466
|
+
deletedAt: z.ZodNullable<z.ZodString>;
|
|
467
|
+
}, z.core.$strip>;
|
|
468
|
+
}, z.core.$strip>;
|
|
430
469
|
};
|
|
431
470
|
type RealtimeEventType = keyof typeof realtimeSchema;
|
|
432
471
|
type RealtimeEventPayload<T extends RealtimeEventType> = z.infer<(typeof realtimeSchema)[T]>;
|
package/realtime-events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"realtime-events.d.ts","names":[],"sources":["../../types/src/realtime-events.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAqBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqGD,iBAAA,gBAAiC;KAEjC,+BAA+B,qBAAqB,CAAA,CAAE,cACzD,gBAAgB;KAGb,wBAAwB;QAC7B;WACG,qBAAqB"}
|
package/rest-client.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, GetConversationSeenDataResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody } from "./conversation.js";
|
|
2
2
|
import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse } from "./timeline-item.js";
|
|
3
|
-
import { types_d_exports } from "./types.js";
|
|
4
3
|
import { IdentifyContactResponse } from "./contact.js";
|
|
4
|
+
import { GenerateUploadUrlRequest, GenerateUploadUrlResponse } from "./upload.js";
|
|
5
|
+
import { types_d_exports } from "./types.js";
|
|
5
6
|
|
|
6
7
|
//#region src/rest-client.d.ts
|
|
7
8
|
declare class CossistantRestClient {
|
|
@@ -59,6 +60,36 @@ declare class CossistantRestClient {
|
|
|
59
60
|
getConversationTimelineItems(params: GetConversationTimelineItemsRequest & {
|
|
60
61
|
conversationId: string;
|
|
61
62
|
}): Promise<GetConversationTimelineItemsResponse>;
|
|
63
|
+
/**
|
|
64
|
+
* Generate a presigned URL for uploading a file to S3.
|
|
65
|
+
* The URL can be used to PUT a file directly to S3.
|
|
66
|
+
*/
|
|
67
|
+
generateUploadUrl(params: Omit<GenerateUploadUrlRequest, "websiteId" | "scope"> & {
|
|
68
|
+
conversationId: string;
|
|
69
|
+
}): Promise<GenerateUploadUrlResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Upload a file to S3 using a presigned URL.
|
|
72
|
+
* @returns The public URL of the uploaded file
|
|
73
|
+
*/
|
|
74
|
+
uploadFile(file: File, uploadUrl: string, contentType: string): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Upload multiple files for a conversation message.
|
|
77
|
+
* Files are uploaded in parallel and the function returns timeline parts
|
|
78
|
+
* that can be included in a message.
|
|
79
|
+
*/
|
|
80
|
+
uploadFilesForMessage(files: File[], conversationId: string): Promise<Array<{
|
|
81
|
+
type: "image";
|
|
82
|
+
url: string;
|
|
83
|
+
mediaType: string;
|
|
84
|
+
fileName?: string;
|
|
85
|
+
size?: number;
|
|
86
|
+
} | {
|
|
87
|
+
type: "file";
|
|
88
|
+
url: string;
|
|
89
|
+
mediaType: string;
|
|
90
|
+
fileName?: string;
|
|
91
|
+
size?: number;
|
|
92
|
+
}>>;
|
|
62
93
|
}
|
|
63
94
|
//#endregion
|
|
64
95
|
export { CossistantRestClient };
|
package/rest-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-client.d.ts","names":[],"sources":["../src/rest-client.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rest-client.d.ts","names":[],"sources":["../src/rest-client.ts"],"sourcesContent":[],"mappings":";;;;;;;cA8Ca,oBAAA;;EAAA,QAAA,WAAA;EAQQ,QAAA,SAAA;EA8LQ,QAAA,SAAA;EAAR,QAAA,SAAA;EA6ET,QAAA,cAAA;EACA,WAAA,CAAA,MAAA,EA5QS,eAAA,CAAA,gBA4QT;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;IAwCW,cAAA,EAAA,MAAA;EAAL,CAAA,CAAA,EArIL,OAqIK,CArIG,+BAqIH,CAAA;EAGE,qBAAA,CAAA,MAAA,EAAA;IAAR,cAAA,EAAA,MAAA;IA2DI,QAAA,EAAA,OAAA;IAGJ,cAAA,CAAA,EAAA,MAAA,GAAA,IAAA;IA4BK,SAAA,CAAA,EAAA,MAAA;EAGP,CAAA,CAAA,EA7MG,OA6MH,CA7MW,iCA6MX,CAAA;EADE,WAAA,CAAA,MAAA,EA/JM,uBA+JN,CAAA,EA9JA,OA8JA,CA9JQ,wBA8JR,CAAA;EAAO,4BAAA,CAAA,MAAA,EAxID,mCAwIC,GAAA;;MAvIP,QAAQ;;;;;4BAwCF,KAAK;;MAGX,QAAQ;;;;;mBA2DJ,+CAGJ;;;;;;+BA4BK,iCAEL,QACF"}
|
package/rest-client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { logger } from "./logger.js";
|
|
2
2
|
import { CossistantAPIError } from "./types.js";
|
|
3
|
+
import { isAllowedMimeType, validateFile } from "./upload-constants.js";
|
|
3
4
|
import { generateConversationId } from "./utils.js";
|
|
4
5
|
import { collectVisitorData } from "./visitor-data.js";
|
|
5
6
|
import { getExistingVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
@@ -360,6 +361,80 @@ var CossistantRestClient = class {
|
|
|
360
361
|
hasNextPage: response.hasNextPage
|
|
361
362
|
};
|
|
362
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* Generate a presigned URL for uploading a file to S3.
|
|
366
|
+
* The URL can be used to PUT a file directly to S3.
|
|
367
|
+
*/
|
|
368
|
+
async generateUploadUrl(params) {
|
|
369
|
+
if (!this.websiteId) throw new Error("Website ID is required. Call getWebsite() first to initialize the client.");
|
|
370
|
+
const visitorId = this.resolveVisitorId();
|
|
371
|
+
if (!isAllowedMimeType(params.contentType)) throw new Error(`File type "${params.contentType}" is not allowed`);
|
|
372
|
+
const headers = {};
|
|
373
|
+
if (visitorId) headers["X-Visitor-Id"] = visitorId;
|
|
374
|
+
const websiteResponse = await this.request("/websites", { headers });
|
|
375
|
+
const body = {
|
|
376
|
+
contentType: params.contentType,
|
|
377
|
+
websiteId: this.websiteId,
|
|
378
|
+
scope: {
|
|
379
|
+
type: "conversation",
|
|
380
|
+
organizationId: websiteResponse.organizationId,
|
|
381
|
+
websiteId: this.websiteId,
|
|
382
|
+
conversationId: params.conversationId
|
|
383
|
+
},
|
|
384
|
+
fileName: params.fileName,
|
|
385
|
+
fileExtension: params.fileExtension,
|
|
386
|
+
path: params.path,
|
|
387
|
+
useCdn: false,
|
|
388
|
+
expiresInSeconds: params.expiresInSeconds
|
|
389
|
+
};
|
|
390
|
+
return await this.request("/uploads/sign-url", {
|
|
391
|
+
method: "POST",
|
|
392
|
+
body: JSON.stringify(body),
|
|
393
|
+
headers
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Upload a file to S3 using a presigned URL.
|
|
398
|
+
* @returns The public URL of the uploaded file
|
|
399
|
+
*/
|
|
400
|
+
async uploadFile(file, uploadUrl, contentType) {
|
|
401
|
+
const validationError = validateFile(file);
|
|
402
|
+
if (validationError) throw new Error(validationError);
|
|
403
|
+
const response = await fetch(uploadUrl, {
|
|
404
|
+
method: "PUT",
|
|
405
|
+
body: file,
|
|
406
|
+
headers: { "Content-Type": contentType }
|
|
407
|
+
});
|
|
408
|
+
if (!response.ok) throw new Error(`Failed to upload file: ${response.status} ${response.statusText}`);
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Upload multiple files for a conversation message.
|
|
412
|
+
* Files are uploaded in parallel and the function returns timeline parts
|
|
413
|
+
* that can be included in a message.
|
|
414
|
+
*/
|
|
415
|
+
async uploadFilesForMessage(files, conversationId) {
|
|
416
|
+
if (files.length === 0) return [];
|
|
417
|
+
for (const file of files) {
|
|
418
|
+
const error = validateFile(file);
|
|
419
|
+
if (error) throw new Error(error);
|
|
420
|
+
}
|
|
421
|
+
const uploadPromises = files.map(async (file) => {
|
|
422
|
+
const uploadInfo = await this.generateUploadUrl({
|
|
423
|
+
conversationId,
|
|
424
|
+
contentType: file.type,
|
|
425
|
+
fileName: file.name
|
|
426
|
+
});
|
|
427
|
+
await this.uploadFile(file, uploadInfo.uploadUrl, file.type);
|
|
428
|
+
return {
|
|
429
|
+
type: file.type.startsWith("image/") ? "image" : "file",
|
|
430
|
+
url: uploadInfo.publicUrl,
|
|
431
|
+
mediaType: file.type,
|
|
432
|
+
fileName: file.name,
|
|
433
|
+
size: file.size
|
|
434
|
+
};
|
|
435
|
+
});
|
|
436
|
+
return Promise.all(uploadPromises);
|
|
437
|
+
}
|
|
363
438
|
};
|
|
364
439
|
|
|
365
440
|
//#endregion
|