@getuserfeedback/chat 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ API keys are bearer credentials. Keep them on your server unless you are using a
|
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
28
|
const { items } = await chat.inbox.list({
|
|
29
|
-
|
|
29
|
+
identity: user.id,
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -35,7 +35,7 @@ const { items } = await chat.inbox.list({
|
|
|
35
35
|
```ts
|
|
36
36
|
const { messages } = await chat.messages.list({
|
|
37
37
|
conversationId: "conv_123",
|
|
38
|
-
|
|
38
|
+
identity: user.id,
|
|
39
39
|
});
|
|
40
40
|
```
|
|
41
41
|
|
|
@@ -46,11 +46,11 @@ const { message } = await chat.messages.send({
|
|
|
46
46
|
clientMessageId: crypto.randomUUID(),
|
|
47
47
|
conversationId: "conv_123",
|
|
48
48
|
text: "Hello from my app.",
|
|
49
|
-
|
|
49
|
+
identity: user.id,
|
|
50
50
|
});
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
`clientMessageId` is optional but recommended. It makes retries idempotent within the authenticated
|
|
53
|
+
`clientMessageId` is optional but recommended. It makes retries idempotent within the authenticated Chat API integration.
|
|
54
54
|
|
|
55
55
|
## Submit delivery events
|
|
56
56
|
|
|
@@ -78,7 +78,7 @@ Failed API responses throw `ChatApiError`.
|
|
|
78
78
|
import { ChatApiError } from "@getuserfeedback/chat";
|
|
79
79
|
|
|
80
80
|
try {
|
|
81
|
-
await chat.inbox.list({
|
|
81
|
+
await chat.inbox.list({ identity: user.id });
|
|
82
82
|
} catch (error) {
|
|
83
83
|
if (error instanceof ChatApiError) {
|
|
84
84
|
console.error(error.status, error.code, error.message);
|
package/dist/index.d.ts
CHANGED
|
@@ -72,18 +72,18 @@ interface ChatRequestOptions {
|
|
|
72
72
|
}
|
|
73
73
|
interface ChatInboxListInput extends ChatRequestOptions {
|
|
74
74
|
limit?: number;
|
|
75
|
-
|
|
75
|
+
identity: string;
|
|
76
76
|
}
|
|
77
77
|
interface ChatMessageListInput extends ChatRequestOptions {
|
|
78
78
|
conversationId: string;
|
|
79
79
|
limit?: number;
|
|
80
|
-
|
|
80
|
+
identity: string;
|
|
81
81
|
}
|
|
82
82
|
interface ChatMessageSendInput extends ChatRequestOptions {
|
|
83
83
|
clientMessageId?: string;
|
|
84
84
|
conversationId: string;
|
|
85
85
|
text: string;
|
|
86
|
-
|
|
86
|
+
identity: string;
|
|
87
87
|
}
|
|
88
88
|
interface ChatReceiptSubmitInput extends ChatRequestOptions {
|
|
89
89
|
receipts: ChatReceipt[];
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var b="conversation-api@1",v="https://api.getuserfeedback.com";class g extends Error{code;responseBody;status;url;constructor(e,t){super(e);this.name="ChatApiError",this.code=t.code,this.responseBody=t.responseBody,this.status=t.status,this.url=t.url}}function w(e){let t=o(e.token,"token"),a=
|
|
1
|
+
var b="conversation-api@1",v="https://api.getuserfeedback.com";class g extends Error{code;responseBody;status;url;constructor(e,t){super(e);this.name="ChatApiError",this.code=t.code,this.responseBody=t.responseBody,this.status=t.status,this.url=t.url}}function w(e){let t=o(e.token,"token"),a=R(e.fetch),c=C(e.baseUrl??"https://api.getuserfeedback.com"),d=async(n,i={})=>{let r=new URL(`${c.pathname}${n}`,c.origin),s=new Headers(i.headers);if(s.set("Authorization",`Bearer ${t}`),i.body!==void 0&&!s.has("Content-Type"))s.set("Content-Type","application/json");let p=await a(r,{...i,headers:s});return await m(p,r)};return{inbox:{list:async(n)=>{let i=o(n.identity,"identity"),r=u({limit:n.limit,identity:i}),s=await d(`/conversations?${r.toString()}`,{method:"GET",signal:n.signal});return{items:s.conversations,limit:s.limit}}},messages:{list:async(n)=>{let i=o(n.identity,"identity"),r=o(n.conversationId,"conversationId"),s=u({limit:n.limit,identity:i});return await d(`/conversations/${encodeURIComponent(r)}/messages?${s.toString()}`,{method:"GET",signal:n.signal})},send:async(n)=>{let i=o(n.identity,"identity"),r=o(n.conversationId,"conversationId"),s=o(n.text,"text"),p=u({identity:i}),h={text:s};if(n.clientMessageId!==void 0)h.clientMessageId=o(n.clientMessageId,"clientMessageId");return await d(`/conversations/${encodeURIComponent(r)}/messages?${p.toString()}`,{body:JSON.stringify(h),method:"POST",signal:n.signal})}},receipts:{submit:async(n)=>{if(n.receipts.length===0)throw TypeError("receipts must include at least one receipt.");return await d("/conversations/events",{body:JSON.stringify({events:n.receipts,version:"conversation-api@1"}),method:"POST",signal:n.signal})}}}}async function m(e,t){let a=await y(e);if(e.ok)return a;let c=x(a);throw new g(I(a,c),{code:c,responseBody:a,status:e.status,url:t.toString()})}async function y(e){let t=await e.text();if(t.trim().length===0)return null;try{return JSON.parse(t)}catch{throw new g("Chat API returned invalid JSON.",{code:"invalid_response",responseBody:t,status:e.status,url:e.url})}}function C(e){let t=new URL(e);return t.search="",t.hash="",t.pathname=f(t.pathname),t}function f(e){let t=e.replace(/\/+$/,"");if(t==="")return"/v1";if(t.endsWith("/v1"))return t;return`${t}/v1`}function R(e){if(e!==void 0)return e;if(typeof globalThis.fetch==="function")return globalThis.fetch.bind(globalThis);throw TypeError("Chat API client requires a fetch implementation.")}function o(e,t){if(typeof e!=="string"||e.trim().length===0)throw TypeError(`${t} must be a non-empty string.`);return e}function u(e){let t=new URLSearchParams({identity:e.identity});if(e.limit!==void 0){if(!Number.isInteger(e.limit)||e.limit<1)throw TypeError("limit must be a positive integer.");t.set("limit",String(e.limit))}return t}function x(e){return l(e,"code")??"request_failed"}function I(e,t){return l(e,"error")??`Chat API request failed with code ${t}.`}function l(e,t){if(typeof e==="object"&&e!==null&&t in e&&typeof e[t]==="string")return e[t];return null}export{w as createChatClient,v as DEFAULT_CHAT_API_BASE_URL,g as ChatApiError,b as CHAT_API_VERSION};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=931E6021B52F91C864756E2164756E21
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"export const CHAT_API_VERSION = \"conversation-api@1\";\nexport const DEFAULT_CHAT_API_BASE_URL = \"https://api.getuserfeedback.com\";\n\ntype FetchLike = (\n\tinput: string | URL | Request,\n\tinit?: RequestInit,\n) => Promise<Response>;\n\nexport type ChatMessageAuthor = \"system\" | \"team\" | \"unknown\" | \"user\";\n\nexport type ChatMessageContent =\n\t| {\n\t\t\ttext: string;\n\t\t\ttype: \"text\";\n\t }\n\t| {\n\t\t\tresponseId: string;\n\t\t\ttype: \"flow_response\";\n\t }\n\t| {\n\t\t\ttype: \"unsupported\";\n\t };\n\nexport interface ChatMessage {\n\tauthor: ChatMessageAuthor;\n\tcontent: ChatMessageContent;\n\tconversationId: string;\n\tid: string;\n\treceivedAt: string;\n\tsentAt: string;\n\ttimestamp: string;\n}\n\nexport interface ChatConversation {\n\tcreatedAt: string;\n\tid: string;\n\tlatestMessage: Pick<\n\t\tChatMessage,\n\t\t\"author\" | \"content\" | \"id\" | \"timestamp\"\n\t> | null;\n\tupdatedAt: string;\n}\n\nexport interface ChatInboxListResponse {\n\titems: ChatConversation[];\n\tlimit: number;\n}\n\nexport interface ChatMessageListResponse {\n\tconversationId: string;\n\tlimit: number;\n\tmessages: ChatMessage[];\n}\n\nexport interface ChatMessageSendResponse {\n\tmessage: ChatMessage;\n}\n\nexport type ChatReceiptType =\n\t| \"delivery.accepted\"\n\t| \"delivery.delivered\"\n\t| \"delivery.failed\"\n\t| \"delivery.read\"\n\t| \"delivery.rejected\";\n\nexport type ChatReceipt =\n\t| {\n\t\t\tdata: ChatReceiptData;\n\t\t\tid: string;\n\t\t\toccurredAt: string;\n\t\t\ttype: Exclude<ChatReceiptType, \"delivery.failed\">;\n\t }\n\t| {\n\t\t\tdata: ChatFailedReceiptData;\n\t\t\tid: string;\n\t\t\toccurredAt: string;\n\t\t\ttype: \"delivery.failed\";\n\t };\n\nexport interface ChatReceiptData {\n\tdeliveryId: string;\n\treason?: string;\n\tsendAttemptId: string;\n}\n\nexport interface ChatFailedReceiptData extends ChatReceiptData {\n\tretryable?: boolean;\n}\n\nexport interface ChatReceiptSubmitResponse {\n\tprocessed: number;\n\tstatus: \"accepted\";\n}\n\nexport interface ChatClientOptions {\n\tbaseUrl?: string;\n\tfetch?: FetchLike;\n\ttoken: string;\n}\n\nexport interface ChatRequestOptions {\n\tsignal?: AbortSignal;\n}\n\nexport interface ChatInboxListInput extends ChatRequestOptions {\n\tlimit?: number;\n\tuserId: string;\n}\n\nexport interface ChatMessageListInput extends ChatRequestOptions {\n\tconversationId: string;\n\tlimit?: number;\n\tuserId: string;\n}\n\nexport interface ChatMessageSendInput extends ChatRequestOptions {\n\tclientMessageId?: string;\n\tconversationId: string;\n\ttext: string;\n\tuserId: string;\n}\n\nexport interface ChatReceiptSubmitInput extends ChatRequestOptions {\n\treceipts: ChatReceipt[];\n}\n\nexport interface ChatClient {\n\tinbox: {\n\t\tlist: (input: ChatInboxListInput) => Promise<ChatInboxListResponse>;\n\t};\n\tmessages: {\n\t\tlist: (input: ChatMessageListInput) => Promise<ChatMessageListResponse>;\n\t\tsend: (input: ChatMessageSendInput) => Promise<ChatMessageSendResponse>;\n\t};\n\treceipts: {\n\t\tsubmit: (\n\t\t\tinput: ChatReceiptSubmitInput,\n\t\t) => Promise<ChatReceiptSubmitResponse>;\n\t};\n}\n\nexport interface ChatApiErrorDetails {\n\tcode: string;\n\tresponseBody: unknown;\n\tstatus: number;\n\turl: string;\n}\n\nexport class ChatApiError extends Error {\n\tcode: string;\n\tresponseBody: unknown;\n\tstatus: number;\n\turl: string;\n\n\tconstructor(message: string, details: ChatApiErrorDetails) {\n\t\tsuper(message);\n\t\tthis.name = \"ChatApiError\";\n\t\tthis.code = details.code;\n\t\tthis.responseBody = details.responseBody;\n\t\tthis.status = details.status;\n\t\tthis.url = details.url;\n\t}\n}\n\nexport function createChatClient(options: ChatClientOptions): ChatClient {\n\tconst token = requireNonEmptyString(options.token, \"token\");\n\tconst fetchFn = resolveFetch(options.fetch);\n\tconst baseUrl = resolveChatApiBaseUrl(\n\t\toptions.baseUrl ?? DEFAULT_CHAT_API_BASE_URL,\n\t);\n\n\tconst request = async <ResponseBody>(\n\t\tpath: string,\n\t\tinit: RequestInit & { signal?: AbortSignal } = {},\n\t): Promise<ResponseBody> => {\n\t\tconst url = new URL(`${baseUrl.pathname}${path}`, baseUrl.origin);\n\t\tconst headers = new Headers(init.headers);\n\t\theaders.set(\"Authorization\", `Bearer ${token}`);\n\t\tif (init.body !== undefined && !headers.has(\"Content-Type\")) {\n\t\t\theaders.set(\"Content-Type\", \"application/json\");\n\t\t}\n\n\t\tconst response = await fetchFn(url, {\n\t\t\t...init,\n\t\t\theaders,\n\t\t});\n\n\t\treturn await readChatApiResponse<ResponseBody>(response, url);\n\t};\n\n\treturn {\n\t\tinbox: {\n\t\t\tlist: async (input) => {\n\t\t\t\tconst userId = requireNonEmptyString(input.userId, \"userId\");\n\t\t\t\tconst query = toUserLimitSearchParams({\n\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\tuserId,\n\t\t\t\t});\n\t\t\t\tconst response = await request<{\n\t\t\t\t\tconversations: ChatConversation[];\n\t\t\t\t\tlimit: number;\n\t\t\t\t}>(`/conversations?${query.toString()}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tsignal: input.signal,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\titems: response.conversations,\n\t\t\t\t\tlimit: response.limit,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\tmessages: {\n\t\t\tlist: async (input) => {\n\t\t\t\tconst userId = requireNonEmptyString(input.userId, \"userId\");\n\t\t\t\tconst conversationId = requireNonEmptyString(\n\t\t\t\t\tinput.conversationId,\n\t\t\t\t\t\"conversationId\",\n\t\t\t\t);\n\t\t\t\tconst query = toUserLimitSearchParams({\n\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\tuserId,\n\t\t\t\t});\n\t\t\t\treturn await request<ChatMessageListResponse>(\n\t\t\t\t\t`/conversations/${encodeURIComponent(conversationId)}/messages?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t\tsend: async (input) => {\n\t\t\t\tconst userId = requireNonEmptyString(input.userId, \"userId\");\n\t\t\t\tconst conversationId = requireNonEmptyString(\n\t\t\t\t\tinput.conversationId,\n\t\t\t\t\t\"conversationId\",\n\t\t\t\t);\n\t\t\t\tconst text = requireNonEmptyString(input.text, \"text\");\n\t\t\t\tconst query = toUserLimitSearchParams({ userId });\n\t\t\t\tconst body: {\n\t\t\t\t\tclientMessageId?: string;\n\t\t\t\t\ttext: string;\n\t\t\t\t} = { text };\n\t\t\t\tif (input.clientMessageId !== undefined) {\n\t\t\t\t\tbody.clientMessageId = requireNonEmptyString(\n\t\t\t\t\t\tinput.clientMessageId,\n\t\t\t\t\t\t\"clientMessageId\",\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn await request<ChatMessageSendResponse>(\n\t\t\t\t\t`/conversations/${encodeURIComponent(conversationId)}/messages?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t\treceipts: {\n\t\t\tsubmit: async (input) => {\n\t\t\t\tif (input.receipts.length === 0) {\n\t\t\t\t\tthrow new TypeError(\"receipts must include at least one receipt.\");\n\t\t\t\t}\n\t\t\t\treturn await request<ChatReceiptSubmitResponse>(\n\t\t\t\t\t\"/conversations/events\",\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\tevents: input.receipts,\n\t\t\t\t\t\t\tversion: CHAT_API_VERSION,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t};\n}\n\nasync function readChatApiResponse<ResponseBody>(\n\tresponse: Response,\n\turl: URL,\n): Promise<ResponseBody> {\n\tconst responseBody = await readJsonResponse(response);\n\tif (response.ok) {\n\t\treturn responseBody as ResponseBody;\n\t}\n\n\tconst code = toErrorCode(responseBody);\n\tthrow new ChatApiError(toErrorMessage(responseBody, code), {\n\t\tcode,\n\t\tresponseBody,\n\t\tstatus: response.status,\n\t\turl: url.toString(),\n\t});\n}\n\nasync function readJsonResponse(response: Response): Promise<unknown> {\n\tconst text = await response.text();\n\tif (text.trim().length === 0) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\tthrow new ChatApiError(\"Chat API returned invalid JSON.\", {\n\t\t\tcode: \"invalid_response\",\n\t\t\tresponseBody: text,\n\t\t\tstatus: response.status,\n\t\t\turl: response.url,\n\t\t});\n\t}\n}\n\nfunction resolveChatApiBaseUrl(baseUrl: string): URL {\n\tconst url = new URL(baseUrl);\n\turl.search = \"\";\n\turl.hash = \"\";\n\turl.pathname = resolveChatApiBasePath(url.pathname);\n\treturn url;\n}\n\nfunction resolveChatApiBasePath(pathname: string): string {\n\tconst trimmedPathname = pathname.replace(/\\/+$/, \"\");\n\tif (trimmedPathname === \"\") {\n\t\treturn \"/v1\";\n\t}\n\tif (trimmedPathname.endsWith(\"/v1\")) {\n\t\treturn trimmedPathname;\n\t}\n\treturn `${trimmedPathname}/v1`;\n}\n\nfunction resolveFetch(fetchFn: FetchLike | undefined): FetchLike {\n\tif (fetchFn !== undefined) {\n\t\treturn fetchFn;\n\t}\n\tif (typeof globalThis.fetch === \"function\") {\n\t\treturn globalThis.fetch.bind(globalThis);\n\t}\n\tthrow new TypeError(\"Chat API client requires a fetch implementation.\");\n}\n\nfunction requireNonEmptyString(value: string, name: string): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new TypeError(`${name} must be a non-empty string.`);\n\t}\n\treturn value;\n}\n\nfunction toUserLimitSearchParams(input: {\n\tlimit?: number;\n\tuserId: string;\n}): URLSearchParams {\n\tconst params = new URLSearchParams({ identity: input.userId });\n\tif (input.limit !== undefined) {\n\t\tif (!Number.isInteger(input.limit) || input.limit < 1) {\n\t\t\tthrow new TypeError(\"limit must be a positive integer.\");\n\t\t}\n\t\tparams.set(\"limit\", String(input.limit));\n\t}\n\treturn params;\n}\n\nfunction toErrorCode(responseBody: unknown): string {\n\treturn toResponseStringProperty(responseBody, \"code\") ?? \"request_failed\";\n}\n\nfunction toErrorMessage(responseBody: unknown, code: string): string {\n\treturn (\n\t\ttoResponseStringProperty(responseBody, \"error\") ??\n\t\t`Chat API request failed with code ${code}.`\n\t);\n}\n\nfunction toResponseStringProperty(\n\tresponseBody: unknown,\n\tkey: string,\n): string | null {\n\tif (\n\t\ttypeof responseBody === \"object\" &&\n\t\tresponseBody !== null &&\n\t\tkey in responseBody &&\n\t\ttypeof responseBody[key as keyof typeof responseBody] === \"string\"\n\t) {\n\t\treturn responseBody[key as keyof typeof responseBody];\n\t}\n\treturn null;\n}\n"
|
|
5
|
+
"export const CHAT_API_VERSION = \"conversation-api@1\";\nexport const DEFAULT_CHAT_API_BASE_URL = \"https://api.getuserfeedback.com\";\n\ntype FetchLike = (\n\tinput: string | URL | Request,\n\tinit?: RequestInit,\n) => Promise<Response>;\n\nexport type ChatMessageAuthor = \"system\" | \"team\" | \"unknown\" | \"user\";\n\nexport type ChatMessageContent =\n\t| {\n\t\t\ttext: string;\n\t\t\ttype: \"text\";\n\t }\n\t| {\n\t\t\tresponseId: string;\n\t\t\ttype: \"flow_response\";\n\t }\n\t| {\n\t\t\ttype: \"unsupported\";\n\t };\n\nexport interface ChatMessage {\n\tauthor: ChatMessageAuthor;\n\tcontent: ChatMessageContent;\n\tconversationId: string;\n\tid: string;\n\treceivedAt: string;\n\tsentAt: string;\n\ttimestamp: string;\n}\n\nexport interface ChatConversation {\n\tcreatedAt: string;\n\tid: string;\n\tlatestMessage: Pick<\n\t\tChatMessage,\n\t\t\"author\" | \"content\" | \"id\" | \"timestamp\"\n\t> | null;\n\tupdatedAt: string;\n}\n\nexport interface ChatInboxListResponse {\n\titems: ChatConversation[];\n\tlimit: number;\n}\n\nexport interface ChatMessageListResponse {\n\tconversationId: string;\n\tlimit: number;\n\tmessages: ChatMessage[];\n}\n\nexport interface ChatMessageSendResponse {\n\tmessage: ChatMessage;\n}\n\nexport type ChatReceiptType =\n\t| \"delivery.accepted\"\n\t| \"delivery.delivered\"\n\t| \"delivery.failed\"\n\t| \"delivery.read\"\n\t| \"delivery.rejected\";\n\nexport type ChatReceipt =\n\t| {\n\t\t\tdata: ChatReceiptData;\n\t\t\tid: string;\n\t\t\toccurredAt: string;\n\t\t\ttype: Exclude<ChatReceiptType, \"delivery.failed\">;\n\t }\n\t| {\n\t\t\tdata: ChatFailedReceiptData;\n\t\t\tid: string;\n\t\t\toccurredAt: string;\n\t\t\ttype: \"delivery.failed\";\n\t };\n\nexport interface ChatReceiptData {\n\tdeliveryId: string;\n\treason?: string;\n\tsendAttemptId: string;\n}\n\nexport interface ChatFailedReceiptData extends ChatReceiptData {\n\tretryable?: boolean;\n}\n\nexport interface ChatReceiptSubmitResponse {\n\tprocessed: number;\n\tstatus: \"accepted\";\n}\n\nexport interface ChatClientOptions {\n\tbaseUrl?: string;\n\tfetch?: FetchLike;\n\ttoken: string;\n}\n\nexport interface ChatRequestOptions {\n\tsignal?: AbortSignal;\n}\n\nexport interface ChatInboxListInput extends ChatRequestOptions {\n\tlimit?: number;\n\tidentity: string;\n}\n\nexport interface ChatMessageListInput extends ChatRequestOptions {\n\tconversationId: string;\n\tlimit?: number;\n\tidentity: string;\n}\n\nexport interface ChatMessageSendInput extends ChatRequestOptions {\n\tclientMessageId?: string;\n\tconversationId: string;\n\ttext: string;\n\tidentity: string;\n}\n\nexport interface ChatReceiptSubmitInput extends ChatRequestOptions {\n\treceipts: ChatReceipt[];\n}\n\nexport interface ChatClient {\n\tinbox: {\n\t\tlist: (input: ChatInboxListInput) => Promise<ChatInboxListResponse>;\n\t};\n\tmessages: {\n\t\tlist: (input: ChatMessageListInput) => Promise<ChatMessageListResponse>;\n\t\tsend: (input: ChatMessageSendInput) => Promise<ChatMessageSendResponse>;\n\t};\n\treceipts: {\n\t\tsubmit: (\n\t\t\tinput: ChatReceiptSubmitInput,\n\t\t) => Promise<ChatReceiptSubmitResponse>;\n\t};\n}\n\nexport interface ChatApiErrorDetails {\n\tcode: string;\n\tresponseBody: unknown;\n\tstatus: number;\n\turl: string;\n}\n\nexport class ChatApiError extends Error {\n\tcode: string;\n\tresponseBody: unknown;\n\tstatus: number;\n\turl: string;\n\n\tconstructor(message: string, details: ChatApiErrorDetails) {\n\t\tsuper(message);\n\t\tthis.name = \"ChatApiError\";\n\t\tthis.code = details.code;\n\t\tthis.responseBody = details.responseBody;\n\t\tthis.status = details.status;\n\t\tthis.url = details.url;\n\t}\n}\n\nexport function createChatClient(options: ChatClientOptions): ChatClient {\n\tconst token = requireNonEmptyString(options.token, \"token\");\n\tconst fetchFn = resolveFetch(options.fetch);\n\tconst baseUrl = resolveChatApiBaseUrl(\n\t\toptions.baseUrl ?? DEFAULT_CHAT_API_BASE_URL,\n\t);\n\n\tconst request = async <ResponseBody>(\n\t\tpath: string,\n\t\tinit: RequestInit & { signal?: AbortSignal } = {},\n\t): Promise<ResponseBody> => {\n\t\tconst url = new URL(`${baseUrl.pathname}${path}`, baseUrl.origin);\n\t\tconst headers = new Headers(init.headers);\n\t\theaders.set(\"Authorization\", `Bearer ${token}`);\n\t\tif (init.body !== undefined && !headers.has(\"Content-Type\")) {\n\t\t\theaders.set(\"Content-Type\", \"application/json\");\n\t\t}\n\n\t\tconst response = await fetchFn(url, {\n\t\t\t...init,\n\t\t\theaders,\n\t\t});\n\n\t\treturn await readChatApiResponse<ResponseBody>(response, url);\n\t};\n\n\treturn {\n\t\tinbox: {\n\t\t\tlist: async (input) => {\n\t\t\t\tconst identity = requireNonEmptyString(input.identity, \"identity\");\n\t\t\t\tconst query = toIdentityLimitSearchParams({\n\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\tidentity,\n\t\t\t\t});\n\t\t\t\tconst response = await request<{\n\t\t\t\t\tconversations: ChatConversation[];\n\t\t\t\t\tlimit: number;\n\t\t\t\t}>(`/conversations?${query.toString()}`, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tsignal: input.signal,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\titems: response.conversations,\n\t\t\t\t\tlimit: response.limit,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\tmessages: {\n\t\t\tlist: async (input) => {\n\t\t\t\tconst identity = requireNonEmptyString(input.identity, \"identity\");\n\t\t\t\tconst conversationId = requireNonEmptyString(\n\t\t\t\t\tinput.conversationId,\n\t\t\t\t\t\"conversationId\",\n\t\t\t\t);\n\t\t\t\tconst query = toIdentityLimitSearchParams({\n\t\t\t\t\tlimit: input.limit,\n\t\t\t\t\tidentity,\n\t\t\t\t});\n\t\t\t\treturn await request<ChatMessageListResponse>(\n\t\t\t\t\t`/conversations/${encodeURIComponent(conversationId)}/messages?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t\tsend: async (input) => {\n\t\t\t\tconst identity = requireNonEmptyString(input.identity, \"identity\");\n\t\t\t\tconst conversationId = requireNonEmptyString(\n\t\t\t\t\tinput.conversationId,\n\t\t\t\t\t\"conversationId\",\n\t\t\t\t);\n\t\t\t\tconst text = requireNonEmptyString(input.text, \"text\");\n\t\t\t\tconst query = toIdentityLimitSearchParams({ identity });\n\t\t\t\tconst body: {\n\t\t\t\t\tclientMessageId?: string;\n\t\t\t\t\ttext: string;\n\t\t\t\t} = { text };\n\t\t\t\tif (input.clientMessageId !== undefined) {\n\t\t\t\t\tbody.clientMessageId = requireNonEmptyString(\n\t\t\t\t\t\tinput.clientMessageId,\n\t\t\t\t\t\t\"clientMessageId\",\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn await request<ChatMessageSendResponse>(\n\t\t\t\t\t`/conversations/${encodeURIComponent(conversationId)}/messages?${query.toString()}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t\treceipts: {\n\t\t\tsubmit: async (input) => {\n\t\t\t\tif (input.receipts.length === 0) {\n\t\t\t\t\tthrow new TypeError(\"receipts must include at least one receipt.\");\n\t\t\t\t}\n\t\t\t\treturn await request<ChatReceiptSubmitResponse>(\n\t\t\t\t\t\"/conversations/events\",\n\t\t\t\t\t{\n\t\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\t\tevents: input.receipts,\n\t\t\t\t\t\t\tversion: CHAT_API_VERSION,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\tsignal: input.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t};\n}\n\nasync function readChatApiResponse<ResponseBody>(\n\tresponse: Response,\n\turl: URL,\n): Promise<ResponseBody> {\n\tconst responseBody = await readJsonResponse(response);\n\tif (response.ok) {\n\t\treturn responseBody as ResponseBody;\n\t}\n\n\tconst code = toErrorCode(responseBody);\n\tthrow new ChatApiError(toErrorMessage(responseBody, code), {\n\t\tcode,\n\t\tresponseBody,\n\t\tstatus: response.status,\n\t\turl: url.toString(),\n\t});\n}\n\nasync function readJsonResponse(response: Response): Promise<unknown> {\n\tconst text = await response.text();\n\tif (text.trim().length === 0) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\tthrow new ChatApiError(\"Chat API returned invalid JSON.\", {\n\t\t\tcode: \"invalid_response\",\n\t\t\tresponseBody: text,\n\t\t\tstatus: response.status,\n\t\t\turl: response.url,\n\t\t});\n\t}\n}\n\nfunction resolveChatApiBaseUrl(baseUrl: string): URL {\n\tconst url = new URL(baseUrl);\n\turl.search = \"\";\n\turl.hash = \"\";\n\turl.pathname = resolveChatApiBasePath(url.pathname);\n\treturn url;\n}\n\nfunction resolveChatApiBasePath(pathname: string): string {\n\tconst trimmedPathname = pathname.replace(/\\/+$/, \"\");\n\tif (trimmedPathname === \"\") {\n\t\treturn \"/v1\";\n\t}\n\tif (trimmedPathname.endsWith(\"/v1\")) {\n\t\treturn trimmedPathname;\n\t}\n\treturn `${trimmedPathname}/v1`;\n}\n\nfunction resolveFetch(fetchFn: FetchLike | undefined): FetchLike {\n\tif (fetchFn !== undefined) {\n\t\treturn fetchFn;\n\t}\n\tif (typeof globalThis.fetch === \"function\") {\n\t\treturn globalThis.fetch.bind(globalThis);\n\t}\n\tthrow new TypeError(\"Chat API client requires a fetch implementation.\");\n}\n\nfunction requireNonEmptyString(value: string, name: string): string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new TypeError(`${name} must be a non-empty string.`);\n\t}\n\treturn value;\n}\n\nfunction toIdentityLimitSearchParams(input: {\n\tlimit?: number;\n\tidentity: string;\n}): URLSearchParams {\n\tconst params = new URLSearchParams({ identity: input.identity });\n\tif (input.limit !== undefined) {\n\t\tif (!Number.isInteger(input.limit) || input.limit < 1) {\n\t\t\tthrow new TypeError(\"limit must be a positive integer.\");\n\t\t}\n\t\tparams.set(\"limit\", String(input.limit));\n\t}\n\treturn params;\n}\n\nfunction toErrorCode(responseBody: unknown): string {\n\treturn toResponseStringProperty(responseBody, \"code\") ?? \"request_failed\";\n}\n\nfunction toErrorMessage(responseBody: unknown, code: string): string {\n\treturn (\n\t\ttoResponseStringProperty(responseBody, \"error\") ??\n\t\t`Chat API request failed with code ${code}.`\n\t);\n}\n\nfunction toResponseStringProperty(\n\tresponseBody: unknown,\n\tkey: string,\n): string | null {\n\tif (\n\t\ttypeof responseBody === \"object\" &&\n\t\tresponseBody !== null &&\n\t\tkey in responseBody &&\n\t\ttypeof responseBody[key as keyof typeof responseBody] === \"string\"\n\t) {\n\t\treturn responseBody[key as keyof typeof responseBody];\n\t}\n\treturn null;\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "AAAO,IAAM,EAAmB,qBACnB,EAA4B,kCAmJlC,MAAM,UAAqB,KAAM,CACvC,KACA,aACA,OACA,IAEA,WAAW,CAAC,EAAiB,EAA8B,CAC1D,MAAM,CAAO,EACb,KAAK,KAAO,eACZ,KAAK,KAAO,EAAQ,KACpB,KAAK,aAAe,EAAQ,aAC5B,KAAK,OAAS,EAAQ,OACtB,KAAK,IAAM,EAAQ,IAErB,CAEO,SAAS,CAAgB,CAAC,EAAwC,CACxE,IAAM,EAAQ,EAAsB,EAAQ,MAAO,OAAO,EACpD,EAAU,EAAa,EAAQ,KAAK,EACpC,EAAU,EACf,EAAQ,SAvK+B,iCAwKxC,EAEM,EAAU,MACf,EACA,EAA+C,CAAC,IACrB,CAC3B,IAAM,EAAM,IAAI,IAAI,GAAG,EAAQ,WAAW,IAAQ,EAAQ,MAAM,EAC1D,EAAU,IAAI,QAAQ,EAAK,OAAO,EAExC,GADA,EAAQ,IAAI,gBAAiB,UAAU,GAAO,EAC1C,EAAK,OAAS,QAAa,CAAC,EAAQ,IAAI,cAAc,EACzD,EAAQ,IAAI,eAAgB,kBAAkB,EAG/C,IAAM,EAAW,MAAM,EAAQ,EAAK,IAChC,EACH,SACD,CAAC,EAED,OAAO,MAAM,EAAkC,EAAU,CAAG,GAG7D,MAAO,CACN,MAAO,CACN,KAAM,MAAO,IAAU,CACtB,IAAM,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "931E6021B52F91C864756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|