@cstar.help/js 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/index.cjs +73 -11
- package/dist/auth/index.d.cts +121 -1
- package/dist/auth/index.d.ts +121 -1
- package/dist/auth/index.js +59 -10
- package/dist/chat/index.cjs +64 -7
- package/dist/chat/index.d.cts +48 -4
- package/dist/chat/index.d.ts +48 -4
- package/dist/chat/index.js +64 -7
- package/dist/community/index.cjs +73 -11
- package/dist/community/index.d.cts +121 -1
- package/dist/community/index.d.ts +121 -1
- package/dist/community/index.js +59 -10
- package/dist/index.cjs +75 -11
- package/dist/index.d.cts +86 -26
- package/dist/index.d.ts +86 -26
- package/dist/index.js +75 -11
- package/dist/library/index.cjs +73 -11
- package/dist/library/index.d.cts +121 -1
- package/dist/library/index.d.ts +121 -1
- package/dist/library/index.js +59 -10
- package/dist/quickhelp/index.cjs +179 -17
- package/dist/quickhelp/index.d.cts +147 -5
- package/dist/quickhelp/index.d.ts +147 -5
- package/dist/quickhelp/index.js +165 -16
- package/dist/webhook/index.cjs +64 -8
- package/dist/webhook/index.d.cts +27 -3
- package/dist/webhook/index.d.ts +27 -3
- package/dist/webhook/index.js +62 -8
- package/dist/webhook/node.cjs +53 -5
- package/dist/webhook/node.d.cts +27 -4
- package/dist/webhook/node.d.ts +27 -4
- package/dist/webhook/node.js +51 -5
- package/package.json +1 -1
package/dist/chat/index.cjs
CHANGED
|
@@ -343,6 +343,7 @@ var ChatClient = class {
|
|
|
343
343
|
this.customerId = null;
|
|
344
344
|
this.authMode = null;
|
|
345
345
|
this.pollingTimers = /* @__PURE__ */ new Map();
|
|
346
|
+
this.stateListeners = /* @__PURE__ */ new Set();
|
|
346
347
|
this.realtimeManager = null;
|
|
347
348
|
this.presenceManager = null;
|
|
348
349
|
this.realtimeReady = false;
|
|
@@ -383,6 +384,7 @@ var ChatClient = class {
|
|
|
383
384
|
this.teamId = response.data.teamId;
|
|
384
385
|
this.customerId = response.data.customer.id;
|
|
385
386
|
this.authMode = "hmac";
|
|
387
|
+
this.notifyStateChanged();
|
|
386
388
|
if (this.realtimeEnabled) {
|
|
387
389
|
this.realtimeInitPromise = this.initRealtime(
|
|
388
390
|
response.data.customer.id,
|
|
@@ -442,11 +444,35 @@ var ChatClient = class {
|
|
|
442
444
|
this.teamId = params.teamId;
|
|
443
445
|
}
|
|
444
446
|
this.authMode = "session";
|
|
447
|
+
this.notifyStateChanged();
|
|
445
448
|
if (this.realtimeEnabled) {
|
|
446
449
|
const customerName = params.customerName ?? "";
|
|
447
450
|
this.realtimeInitPromise = this.initRealtimeFromSession(customerName);
|
|
448
451
|
}
|
|
449
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Subscribe to client state changes (auth mode flips, identify, disconnect).
|
|
455
|
+
* Fires after the mutation, so listeners reading `getAuthMode()` /
|
|
456
|
+
* `getCustomerId()` see the new value.
|
|
457
|
+
*
|
|
458
|
+
* Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
|
|
459
|
+
* and `ChatState` (Svelte) to re-render when consumers mutate the client
|
|
460
|
+
* outside of the framework wrappers.
|
|
461
|
+
*/
|
|
462
|
+
subscribe(listener) {
|
|
463
|
+
this.stateListeners.add(listener);
|
|
464
|
+
return () => {
|
|
465
|
+
this.stateListeners.delete(listener);
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
notifyStateChanged() {
|
|
469
|
+
for (const listener of this.stateListeners) {
|
|
470
|
+
try {
|
|
471
|
+
listener();
|
|
472
|
+
} catch {
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
450
476
|
/**
|
|
451
477
|
* Returns the auth mode the client is currently using, or `null` before
|
|
452
478
|
* any authenticated call has resolved one. Useful for branching UI
|
|
@@ -509,6 +535,7 @@ var ChatClient = class {
|
|
|
509
535
|
this.teamId = null;
|
|
510
536
|
this.customerId = null;
|
|
511
537
|
this.authMode = null;
|
|
538
|
+
this.notifyStateChanged();
|
|
512
539
|
}
|
|
513
540
|
/**
|
|
514
541
|
* @internal Make an authenticated request to the widget API.
|
|
@@ -546,7 +573,9 @@ var ChatClient = class {
|
|
|
546
573
|
const responseHeaders = response.headers && typeof response.headers.get === "function" ? response.headers : null;
|
|
547
574
|
const headerMode = responseHeaders?.get("X-Cstar-Auth-Mode") ?? null;
|
|
548
575
|
if (headerMode === "hmac" || headerMode === "session") {
|
|
576
|
+
const previous = this.authMode;
|
|
549
577
|
this.authMode = headerMode;
|
|
578
|
+
if (previous !== headerMode) this.notifyStateChanged();
|
|
550
579
|
}
|
|
551
580
|
const requestId = responseHeaders?.get("X-Request-Id") ?? null;
|
|
552
581
|
if (!response.ok) {
|
|
@@ -633,6 +662,27 @@ var ChatClient = class {
|
|
|
633
662
|
getTeamId() {
|
|
634
663
|
return this.teamId;
|
|
635
664
|
}
|
|
665
|
+
/**
|
|
666
|
+
* Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
|
|
667
|
+
* has been cached yet. Used by `tickets.list` and friends so that a
|
|
668
|
+
* caller who constructed `new ChatClient({ teamSlug, publishableKey })`
|
|
669
|
+
* doesn't have to manually call `loginWithCredentials` before reading
|
|
670
|
+
* public data.
|
|
671
|
+
*
|
|
672
|
+
* Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
|
|
673
|
+
* `"Missing teamId"` when the chat client was teamSlug-only because the
|
|
674
|
+
* tickets sub-resource read `getTeamId()` synchronously and bailed.
|
|
675
|
+
*/
|
|
676
|
+
async ensureTeamId() {
|
|
677
|
+
if (this.teamId) return this.teamId;
|
|
678
|
+
if (!this.teamSlug) {
|
|
679
|
+
throw new ChatClientAuthError(
|
|
680
|
+
"Missing teamId. Construct ChatClient with `teamSlug` or call `setTeamId()` / `identify()` / `loginWithCredentials()` first."
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
this.teamId = await this.resolveTeamIdFromSlug();
|
|
684
|
+
return this.teamId;
|
|
685
|
+
}
|
|
636
686
|
/** @internal Set team ID from identify response or other source. */
|
|
637
687
|
setTeamId(teamId) {
|
|
638
688
|
this.teamId = teamId;
|
|
@@ -718,8 +768,10 @@ var TicketsApi = class {
|
|
|
718
768
|
}
|
|
719
769
|
/** List tickets for the identified customer. */
|
|
720
770
|
async list(params) {
|
|
721
|
-
|
|
722
|
-
|
|
771
|
+
if (this.chat.getAuthMode() === null) {
|
|
772
|
+
throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
|
|
773
|
+
}
|
|
774
|
+
const teamId = await this.chat.ensureTeamId();
|
|
723
775
|
const response = await this.chat.fetch("/api/widget/conversations", {
|
|
724
776
|
method: "GET",
|
|
725
777
|
query: {
|
|
@@ -728,16 +780,21 @@ var TicketsApi = class {
|
|
|
728
780
|
cursor: params?.cursor
|
|
729
781
|
}
|
|
730
782
|
});
|
|
783
|
+
const data = response.data.tickets ?? response.data.conversations ?? [];
|
|
784
|
+
const cursor = response.data.cursor;
|
|
785
|
+
const hasMore = response.data.hasMore;
|
|
731
786
|
return {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
hasMore
|
|
787
|
+
data,
|
|
788
|
+
pagination: { cursor, hasMore },
|
|
789
|
+
hasMore
|
|
735
790
|
};
|
|
736
791
|
}
|
|
737
792
|
/** Create a new ticket. */
|
|
738
793
|
async create(params) {
|
|
739
|
-
|
|
740
|
-
|
|
794
|
+
if (this.chat.getAuthMode() === null) {
|
|
795
|
+
throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
|
|
796
|
+
}
|
|
797
|
+
const teamId = await this.chat.ensureTeamId();
|
|
741
798
|
const response = await this.chat.fetch("/api/widget/tickets", {
|
|
742
799
|
method: "POST",
|
|
743
800
|
body: {
|
package/dist/chat/index.d.cts
CHANGED
|
@@ -107,10 +107,24 @@ interface Ticket {
|
|
|
107
107
|
*/
|
|
108
108
|
messages?: Message[];
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Paginated ticket list response.
|
|
112
|
+
*
|
|
113
|
+
* As of `@cstar.help/js@0.14.0` the canonical fields match the admin SDK and
|
|
114
|
+
* library SDK envelopes (`{ data, pagination, hasMore }`). Closes F-037.
|
|
115
|
+
*
|
|
116
|
+
* Breaking change in 0.15.0 (B-11): the deprecated `tickets` and `cursor`
|
|
117
|
+
* top-level aliases are removed. Read `data` and `pagination.cursor`.
|
|
118
|
+
*/
|
|
111
119
|
interface TicketListResponse {
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
/** Tickets on this page. */
|
|
121
|
+
data: Ticket[];
|
|
122
|
+
/** Pagination cursor + a flag for whether more pages exist. */
|
|
123
|
+
pagination: {
|
|
124
|
+
cursor: string | null;
|
|
125
|
+
hasMore: boolean;
|
|
126
|
+
};
|
|
127
|
+
/** Convenience copy of `pagination.hasMore`. */
|
|
114
128
|
hasMore: boolean;
|
|
115
129
|
}
|
|
116
130
|
/** A message on a ticket. */
|
|
@@ -345,6 +359,12 @@ declare class ChatClientNetworkError extends ChatClientError {
|
|
|
345
359
|
* `ChatClientServerError`, `ChatClientNetworkError`. Each carries
|
|
346
360
|
* `requestId` for correlating with server-side logs.
|
|
347
361
|
*/
|
|
362
|
+
/**
|
|
363
|
+
* Listener for client-state changes (auth-mode flips, identity assignment,
|
|
364
|
+
* disconnects). Fires once after the underlying state mutates so a UI layer
|
|
365
|
+
* can re-read `getAuthMode()` / `getCustomerId()` and re-render. Closes F-041.
|
|
366
|
+
*/
|
|
367
|
+
type ChatStateListener = () => void;
|
|
348
368
|
declare class ChatClient {
|
|
349
369
|
private readonly baseUrl;
|
|
350
370
|
private readonly teamSlug;
|
|
@@ -355,6 +375,7 @@ declare class ChatClient {
|
|
|
355
375
|
private customerId;
|
|
356
376
|
private authMode;
|
|
357
377
|
private pollingTimers;
|
|
378
|
+
private stateListeners;
|
|
358
379
|
private realtimeManager;
|
|
359
380
|
private presenceManager;
|
|
360
381
|
private realtimeReady;
|
|
@@ -397,6 +418,17 @@ declare class ChatClient {
|
|
|
397
418
|
* every request — there is no client-side validation here.
|
|
398
419
|
*/
|
|
399
420
|
loginWithSession(params: LoginWithSessionParams): Promise<void>;
|
|
421
|
+
/**
|
|
422
|
+
* Subscribe to client state changes (auth mode flips, identify, disconnect).
|
|
423
|
+
* Fires after the mutation, so listeners reading `getAuthMode()` /
|
|
424
|
+
* `getCustomerId()` see the new value.
|
|
425
|
+
*
|
|
426
|
+
* Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
|
|
427
|
+
* and `ChatState` (Svelte) to re-render when consumers mutate the client
|
|
428
|
+
* outside of the framework wrappers.
|
|
429
|
+
*/
|
|
430
|
+
subscribe(listener: ChatStateListener): () => void;
|
|
431
|
+
private notifyStateChanged;
|
|
400
432
|
/**
|
|
401
433
|
* Returns the auth mode the client is currently using, or `null` before
|
|
402
434
|
* any authenticated call has resolved one. Useful for branching UI
|
|
@@ -453,6 +485,18 @@ declare class ChatClient {
|
|
|
453
485
|
private initRealtimeFromSession;
|
|
454
486
|
/** @internal Get the stored team ID for requests that need it. */
|
|
455
487
|
getTeamId(): string | null;
|
|
488
|
+
/**
|
|
489
|
+
* Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
|
|
490
|
+
* has been cached yet. Used by `tickets.list` and friends so that a
|
|
491
|
+
* caller who constructed `new ChatClient({ teamSlug, publishableKey })`
|
|
492
|
+
* doesn't have to manually call `loginWithCredentials` before reading
|
|
493
|
+
* public data.
|
|
494
|
+
*
|
|
495
|
+
* Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
|
|
496
|
+
* `"Missing teamId"` when the chat client was teamSlug-only because the
|
|
497
|
+
* tickets sub-resource read `getTeamId()` synchronously and bailed.
|
|
498
|
+
*/
|
|
499
|
+
ensureTeamId(): Promise<string>;
|
|
456
500
|
/** @internal Set team ID from identify response or other source. */
|
|
457
501
|
setTeamId(teamId: string): void;
|
|
458
502
|
/** @internal Wait for realtime to be initialized (for testing). */
|
|
@@ -509,4 +553,4 @@ declare class MessagesApi {
|
|
|
509
553
|
send(ticketId: string, content: string): Promise<Message>;
|
|
510
554
|
}
|
|
511
555
|
|
|
512
|
-
export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
|
|
556
|
+
export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type ChatStateListener, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -107,10 +107,24 @@ interface Ticket {
|
|
|
107
107
|
*/
|
|
108
108
|
messages?: Message[];
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Paginated ticket list response.
|
|
112
|
+
*
|
|
113
|
+
* As of `@cstar.help/js@0.14.0` the canonical fields match the admin SDK and
|
|
114
|
+
* library SDK envelopes (`{ data, pagination, hasMore }`). Closes F-037.
|
|
115
|
+
*
|
|
116
|
+
* Breaking change in 0.15.0 (B-11): the deprecated `tickets` and `cursor`
|
|
117
|
+
* top-level aliases are removed. Read `data` and `pagination.cursor`.
|
|
118
|
+
*/
|
|
111
119
|
interface TicketListResponse {
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
/** Tickets on this page. */
|
|
121
|
+
data: Ticket[];
|
|
122
|
+
/** Pagination cursor + a flag for whether more pages exist. */
|
|
123
|
+
pagination: {
|
|
124
|
+
cursor: string | null;
|
|
125
|
+
hasMore: boolean;
|
|
126
|
+
};
|
|
127
|
+
/** Convenience copy of `pagination.hasMore`. */
|
|
114
128
|
hasMore: boolean;
|
|
115
129
|
}
|
|
116
130
|
/** A message on a ticket. */
|
|
@@ -345,6 +359,12 @@ declare class ChatClientNetworkError extends ChatClientError {
|
|
|
345
359
|
* `ChatClientServerError`, `ChatClientNetworkError`. Each carries
|
|
346
360
|
* `requestId` for correlating with server-side logs.
|
|
347
361
|
*/
|
|
362
|
+
/**
|
|
363
|
+
* Listener for client-state changes (auth-mode flips, identity assignment,
|
|
364
|
+
* disconnects). Fires once after the underlying state mutates so a UI layer
|
|
365
|
+
* can re-read `getAuthMode()` / `getCustomerId()` and re-render. Closes F-041.
|
|
366
|
+
*/
|
|
367
|
+
type ChatStateListener = () => void;
|
|
348
368
|
declare class ChatClient {
|
|
349
369
|
private readonly baseUrl;
|
|
350
370
|
private readonly teamSlug;
|
|
@@ -355,6 +375,7 @@ declare class ChatClient {
|
|
|
355
375
|
private customerId;
|
|
356
376
|
private authMode;
|
|
357
377
|
private pollingTimers;
|
|
378
|
+
private stateListeners;
|
|
358
379
|
private realtimeManager;
|
|
359
380
|
private presenceManager;
|
|
360
381
|
private realtimeReady;
|
|
@@ -397,6 +418,17 @@ declare class ChatClient {
|
|
|
397
418
|
* every request — there is no client-side validation here.
|
|
398
419
|
*/
|
|
399
420
|
loginWithSession(params: LoginWithSessionParams): Promise<void>;
|
|
421
|
+
/**
|
|
422
|
+
* Subscribe to client state changes (auth mode flips, identify, disconnect).
|
|
423
|
+
* Fires after the mutation, so listeners reading `getAuthMode()` /
|
|
424
|
+
* `getCustomerId()` see the new value.
|
|
425
|
+
*
|
|
426
|
+
* Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
|
|
427
|
+
* and `ChatState` (Svelte) to re-render when consumers mutate the client
|
|
428
|
+
* outside of the framework wrappers.
|
|
429
|
+
*/
|
|
430
|
+
subscribe(listener: ChatStateListener): () => void;
|
|
431
|
+
private notifyStateChanged;
|
|
400
432
|
/**
|
|
401
433
|
* Returns the auth mode the client is currently using, or `null` before
|
|
402
434
|
* any authenticated call has resolved one. Useful for branching UI
|
|
@@ -453,6 +485,18 @@ declare class ChatClient {
|
|
|
453
485
|
private initRealtimeFromSession;
|
|
454
486
|
/** @internal Get the stored team ID for requests that need it. */
|
|
455
487
|
getTeamId(): string | null;
|
|
488
|
+
/**
|
|
489
|
+
* Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
|
|
490
|
+
* has been cached yet. Used by `tickets.list` and friends so that a
|
|
491
|
+
* caller who constructed `new ChatClient({ teamSlug, publishableKey })`
|
|
492
|
+
* doesn't have to manually call `loginWithCredentials` before reading
|
|
493
|
+
* public data.
|
|
494
|
+
*
|
|
495
|
+
* Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
|
|
496
|
+
* `"Missing teamId"` when the chat client was teamSlug-only because the
|
|
497
|
+
* tickets sub-resource read `getTeamId()` synchronously and bailed.
|
|
498
|
+
*/
|
|
499
|
+
ensureTeamId(): Promise<string>;
|
|
456
500
|
/** @internal Set team ID from identify response or other source. */
|
|
457
501
|
setTeamId(teamId: string): void;
|
|
458
502
|
/** @internal Wait for realtime to be initialized (for testing). */
|
|
@@ -509,4 +553,4 @@ declare class MessagesApi {
|
|
|
509
553
|
send(ticketId: string, content: string): Promise<Message>;
|
|
510
554
|
}
|
|
511
555
|
|
|
512
|
-
export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
|
|
556
|
+
export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type ChatStateListener, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
|
package/dist/chat/index.js
CHANGED
|
@@ -302,6 +302,7 @@ var ChatClient = class {
|
|
|
302
302
|
this.customerId = null;
|
|
303
303
|
this.authMode = null;
|
|
304
304
|
this.pollingTimers = /* @__PURE__ */ new Map();
|
|
305
|
+
this.stateListeners = /* @__PURE__ */ new Set();
|
|
305
306
|
this.realtimeManager = null;
|
|
306
307
|
this.presenceManager = null;
|
|
307
308
|
this.realtimeReady = false;
|
|
@@ -342,6 +343,7 @@ var ChatClient = class {
|
|
|
342
343
|
this.teamId = response.data.teamId;
|
|
343
344
|
this.customerId = response.data.customer.id;
|
|
344
345
|
this.authMode = "hmac";
|
|
346
|
+
this.notifyStateChanged();
|
|
345
347
|
if (this.realtimeEnabled) {
|
|
346
348
|
this.realtimeInitPromise = this.initRealtime(
|
|
347
349
|
response.data.customer.id,
|
|
@@ -401,11 +403,35 @@ var ChatClient = class {
|
|
|
401
403
|
this.teamId = params.teamId;
|
|
402
404
|
}
|
|
403
405
|
this.authMode = "session";
|
|
406
|
+
this.notifyStateChanged();
|
|
404
407
|
if (this.realtimeEnabled) {
|
|
405
408
|
const customerName = params.customerName ?? "";
|
|
406
409
|
this.realtimeInitPromise = this.initRealtimeFromSession(customerName);
|
|
407
410
|
}
|
|
408
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Subscribe to client state changes (auth mode flips, identify, disconnect).
|
|
414
|
+
* Fires after the mutation, so listeners reading `getAuthMode()` /
|
|
415
|
+
* `getCustomerId()` see the new value.
|
|
416
|
+
*
|
|
417
|
+
* Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
|
|
418
|
+
* and `ChatState` (Svelte) to re-render when consumers mutate the client
|
|
419
|
+
* outside of the framework wrappers.
|
|
420
|
+
*/
|
|
421
|
+
subscribe(listener) {
|
|
422
|
+
this.stateListeners.add(listener);
|
|
423
|
+
return () => {
|
|
424
|
+
this.stateListeners.delete(listener);
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
notifyStateChanged() {
|
|
428
|
+
for (const listener of this.stateListeners) {
|
|
429
|
+
try {
|
|
430
|
+
listener();
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
409
435
|
/**
|
|
410
436
|
* Returns the auth mode the client is currently using, or `null` before
|
|
411
437
|
* any authenticated call has resolved one. Useful for branching UI
|
|
@@ -468,6 +494,7 @@ var ChatClient = class {
|
|
|
468
494
|
this.teamId = null;
|
|
469
495
|
this.customerId = null;
|
|
470
496
|
this.authMode = null;
|
|
497
|
+
this.notifyStateChanged();
|
|
471
498
|
}
|
|
472
499
|
/**
|
|
473
500
|
* @internal Make an authenticated request to the widget API.
|
|
@@ -505,7 +532,9 @@ var ChatClient = class {
|
|
|
505
532
|
const responseHeaders = response.headers && typeof response.headers.get === "function" ? response.headers : null;
|
|
506
533
|
const headerMode = responseHeaders?.get("X-Cstar-Auth-Mode") ?? null;
|
|
507
534
|
if (headerMode === "hmac" || headerMode === "session") {
|
|
535
|
+
const previous = this.authMode;
|
|
508
536
|
this.authMode = headerMode;
|
|
537
|
+
if (previous !== headerMode) this.notifyStateChanged();
|
|
509
538
|
}
|
|
510
539
|
const requestId = responseHeaders?.get("X-Request-Id") ?? null;
|
|
511
540
|
if (!response.ok) {
|
|
@@ -592,6 +621,27 @@ var ChatClient = class {
|
|
|
592
621
|
getTeamId() {
|
|
593
622
|
return this.teamId;
|
|
594
623
|
}
|
|
624
|
+
/**
|
|
625
|
+
* Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
|
|
626
|
+
* has been cached yet. Used by `tickets.list` and friends so that a
|
|
627
|
+
* caller who constructed `new ChatClient({ teamSlug, publishableKey })`
|
|
628
|
+
* doesn't have to manually call `loginWithCredentials` before reading
|
|
629
|
+
* public data.
|
|
630
|
+
*
|
|
631
|
+
* Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
|
|
632
|
+
* `"Missing teamId"` when the chat client was teamSlug-only because the
|
|
633
|
+
* tickets sub-resource read `getTeamId()` synchronously and bailed.
|
|
634
|
+
*/
|
|
635
|
+
async ensureTeamId() {
|
|
636
|
+
if (this.teamId) return this.teamId;
|
|
637
|
+
if (!this.teamSlug) {
|
|
638
|
+
throw new ChatClientAuthError(
|
|
639
|
+
"Missing teamId. Construct ChatClient with `teamSlug` or call `setTeamId()` / `identify()` / `loginWithCredentials()` first."
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
this.teamId = await this.resolveTeamIdFromSlug();
|
|
643
|
+
return this.teamId;
|
|
644
|
+
}
|
|
595
645
|
/** @internal Set team ID from identify response or other source. */
|
|
596
646
|
setTeamId(teamId) {
|
|
597
647
|
this.teamId = teamId;
|
|
@@ -677,8 +727,10 @@ var TicketsApi = class {
|
|
|
677
727
|
}
|
|
678
728
|
/** List tickets for the identified customer. */
|
|
679
729
|
async list(params) {
|
|
680
|
-
|
|
681
|
-
|
|
730
|
+
if (this.chat.getAuthMode() === null) {
|
|
731
|
+
throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
|
|
732
|
+
}
|
|
733
|
+
const teamId = await this.chat.ensureTeamId();
|
|
682
734
|
const response = await this.chat.fetch("/api/widget/conversations", {
|
|
683
735
|
method: "GET",
|
|
684
736
|
query: {
|
|
@@ -687,16 +739,21 @@ var TicketsApi = class {
|
|
|
687
739
|
cursor: params?.cursor
|
|
688
740
|
}
|
|
689
741
|
});
|
|
742
|
+
const data = response.data.tickets ?? response.data.conversations ?? [];
|
|
743
|
+
const cursor = response.data.cursor;
|
|
744
|
+
const hasMore = response.data.hasMore;
|
|
690
745
|
return {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
hasMore
|
|
746
|
+
data,
|
|
747
|
+
pagination: { cursor, hasMore },
|
|
748
|
+
hasMore
|
|
694
749
|
};
|
|
695
750
|
}
|
|
696
751
|
/** Create a new ticket. */
|
|
697
752
|
async create(params) {
|
|
698
|
-
|
|
699
|
-
|
|
753
|
+
if (this.chat.getAuthMode() === null) {
|
|
754
|
+
throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
|
|
755
|
+
}
|
|
756
|
+
const teamId = await this.chat.ensureTeamId();
|
|
700
757
|
const response = await this.chat.fetch("/api/widget/tickets", {
|
|
701
758
|
method: "POST",
|
|
702
759
|
body: {
|
package/dist/community/index.cjs
CHANGED
|
@@ -20,7 +20,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/community/index.ts
|
|
21
21
|
var community_exports = {};
|
|
22
22
|
__export(community_exports, {
|
|
23
|
-
|
|
23
|
+
CStarAuthenticationError: () => CStarAuthenticationError,
|
|
24
|
+
CStarConflictError: () => CStarConflictError,
|
|
25
|
+
CStarError: () => CStarError,
|
|
26
|
+
CStarFeatureDisabledError: () => CStarFeatureDisabledError,
|
|
27
|
+
CStarNotFoundError: () => CStarNotFoundError,
|
|
28
|
+
CStarPermissionError: () => CStarPermissionError,
|
|
29
|
+
CStarRateLimitError: () => CStarRateLimitError,
|
|
30
|
+
CStarRealtimeUnavailableError: () => CStarRealtimeUnavailableError,
|
|
31
|
+
CStarServerError: () => CStarServerError,
|
|
32
|
+
CStarValidationError: () => CStarValidationError,
|
|
33
|
+
CommunityClient: () => CommunityClient,
|
|
34
|
+
ErrorType: () => ErrorType,
|
|
35
|
+
parseError: () => parseError,
|
|
36
|
+
parsePublicError: () => parsePublicError
|
|
24
37
|
});
|
|
25
38
|
module.exports = __toCommonJS(community_exports);
|
|
26
39
|
|
|
@@ -61,7 +74,7 @@ function normalizeArgs(messageOrStatus, maybeBody, defaults) {
|
|
|
61
74
|
}
|
|
62
75
|
};
|
|
63
76
|
}
|
|
64
|
-
var
|
|
77
|
+
var CStarErrorImpl = class extends Error {
|
|
65
78
|
constructor(messageOrStatus, body) {
|
|
66
79
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body);
|
|
67
80
|
super(resolved.message);
|
|
@@ -74,7 +87,7 @@ var CStarError = class extends Error {
|
|
|
74
87
|
this.statusCode = statusCode;
|
|
75
88
|
}
|
|
76
89
|
};
|
|
77
|
-
var
|
|
90
|
+
var CStarAuthenticationErrorImpl = class extends CStarErrorImpl {
|
|
78
91
|
constructor(messageOrStatus, body) {
|
|
79
92
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
80
93
|
type: ErrorType.AUTHENTICATION_ERROR,
|
|
@@ -85,7 +98,7 @@ var CStarAuthenticationError = class extends CStarError {
|
|
|
85
98
|
this.name = "CStarAuthenticationError";
|
|
86
99
|
}
|
|
87
100
|
};
|
|
88
|
-
var
|
|
101
|
+
var CStarRateLimitErrorImpl = class extends CStarErrorImpl {
|
|
89
102
|
constructor(messageOrStatus, body, retryAfter) {
|
|
90
103
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
91
104
|
type: ErrorType.RATE_LIMIT_ERROR,
|
|
@@ -97,7 +110,7 @@ var CStarRateLimitError = class extends CStarError {
|
|
|
97
110
|
this.retryAfter = retryAfter ?? 60;
|
|
98
111
|
}
|
|
99
112
|
};
|
|
100
|
-
var
|
|
113
|
+
var CStarNotFoundErrorImpl = class extends CStarErrorImpl {
|
|
101
114
|
constructor(messageOrStatus, body) {
|
|
102
115
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
103
116
|
type: ErrorType.NOT_FOUND_ERROR,
|
|
@@ -108,7 +121,7 @@ var CStarNotFoundError = class extends CStarError {
|
|
|
108
121
|
this.name = "CStarNotFoundError";
|
|
109
122
|
}
|
|
110
123
|
};
|
|
111
|
-
var
|
|
124
|
+
var CStarValidationErrorImpl = class extends CStarErrorImpl {
|
|
112
125
|
constructor(messageOrStatus, body) {
|
|
113
126
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
114
127
|
type: ErrorType.INVALID_REQUEST_ERROR,
|
|
@@ -119,7 +132,7 @@ var CStarValidationError = class extends CStarError {
|
|
|
119
132
|
this.name = "CStarValidationError";
|
|
120
133
|
}
|
|
121
134
|
};
|
|
122
|
-
var
|
|
135
|
+
var CStarPermissionErrorImpl = class extends CStarErrorImpl {
|
|
123
136
|
constructor(messageOrStatus, body) {
|
|
124
137
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
125
138
|
type: ErrorType.PERMISSION_ERROR,
|
|
@@ -130,7 +143,7 @@ var CStarPermissionError = class extends CStarError {
|
|
|
130
143
|
this.name = "CStarPermissionError";
|
|
131
144
|
}
|
|
132
145
|
};
|
|
133
|
-
var
|
|
146
|
+
var CStarConflictErrorImpl = class extends CStarErrorImpl {
|
|
134
147
|
constructor(messageOrStatus, body) {
|
|
135
148
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
136
149
|
type: ErrorType.CONFLICT_ERROR,
|
|
@@ -141,7 +154,7 @@ var CStarConflictError = class extends CStarError {
|
|
|
141
154
|
this.name = "CStarConflictError";
|
|
142
155
|
}
|
|
143
156
|
};
|
|
144
|
-
var
|
|
157
|
+
var CStarServerErrorImpl = class extends CStarErrorImpl {
|
|
145
158
|
constructor(messageOrStatus, body) {
|
|
146
159
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
147
160
|
type: ErrorType.SERVER_ERROR,
|
|
@@ -152,7 +165,7 @@ var CStarServerError = class extends CStarError {
|
|
|
152
165
|
this.name = "CStarServerError";
|
|
153
166
|
}
|
|
154
167
|
};
|
|
155
|
-
var
|
|
168
|
+
var CStarFeatureDisabledErrorImpl = class extends CStarErrorImpl {
|
|
156
169
|
constructor(messageOrStatus, body) {
|
|
157
170
|
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
158
171
|
type: ErrorType.FEATURE_NOT_CONFIGURED,
|
|
@@ -165,6 +178,42 @@ var CStarFeatureDisabledError = class extends CStarError {
|
|
|
165
178
|
this.enableUrl = resolved.enable_url ?? "";
|
|
166
179
|
}
|
|
167
180
|
};
|
|
181
|
+
var CStarRealtimeUnavailableErrorImpl = class extends CStarErrorImpl {
|
|
182
|
+
constructor(message) {
|
|
183
|
+
const resolved = message ?? "EventSource is not available in this environment. Real-time subscriptions only work in the browser. Move the call to a client-only path (`useEffect` / `onMount`), or pass an `eventSource` polyfill via the realtime options. See https://cstar.help/developers/sdk/realtime#ssr";
|
|
184
|
+
super(0, {
|
|
185
|
+
type: ErrorType.API_ERROR,
|
|
186
|
+
code: "realtime_unavailable",
|
|
187
|
+
message: resolved,
|
|
188
|
+
doc_url: "https://cstar.help/developers/sdk/realtime#ssr"
|
|
189
|
+
});
|
|
190
|
+
this.name = "CStarRealtimeUnavailableError";
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("@cstar.help/js/errors/v1");
|
|
194
|
+
var globalSlot = globalThis;
|
|
195
|
+
var registry = globalSlot[REGISTRY_KEY] ?? (globalSlot[REGISTRY_KEY] = {
|
|
196
|
+
CStarError: CStarErrorImpl,
|
|
197
|
+
CStarAuthenticationError: CStarAuthenticationErrorImpl,
|
|
198
|
+
CStarRateLimitError: CStarRateLimitErrorImpl,
|
|
199
|
+
CStarNotFoundError: CStarNotFoundErrorImpl,
|
|
200
|
+
CStarValidationError: CStarValidationErrorImpl,
|
|
201
|
+
CStarPermissionError: CStarPermissionErrorImpl,
|
|
202
|
+
CStarConflictError: CStarConflictErrorImpl,
|
|
203
|
+
CStarServerError: CStarServerErrorImpl,
|
|
204
|
+
CStarFeatureDisabledError: CStarFeatureDisabledErrorImpl,
|
|
205
|
+
CStarRealtimeUnavailableError: CStarRealtimeUnavailableErrorImpl
|
|
206
|
+
});
|
|
207
|
+
var CStarError = registry.CStarError;
|
|
208
|
+
var CStarAuthenticationError = registry.CStarAuthenticationError;
|
|
209
|
+
var CStarRateLimitError = registry.CStarRateLimitError;
|
|
210
|
+
var CStarNotFoundError = registry.CStarNotFoundError;
|
|
211
|
+
var CStarValidationError = registry.CStarValidationError;
|
|
212
|
+
var CStarPermissionError = registry.CStarPermissionError;
|
|
213
|
+
var CStarConflictError = registry.CStarConflictError;
|
|
214
|
+
var CStarServerError = registry.CStarServerError;
|
|
215
|
+
var CStarFeatureDisabledError = registry.CStarFeatureDisabledError;
|
|
216
|
+
var CStarRealtimeUnavailableError = registry.CStarRealtimeUnavailableError;
|
|
168
217
|
function parsePublicError(status, body, fallbackMessage) {
|
|
169
218
|
const obj = body && typeof body === "object" ? body : null;
|
|
170
219
|
const errVal = obj?.error;
|
|
@@ -529,5 +578,18 @@ var CommunityClient = class {
|
|
|
529
578
|
};
|
|
530
579
|
// Annotate the CommonJS export names for ESM import in node:
|
|
531
580
|
0 && (module.exports = {
|
|
532
|
-
|
|
581
|
+
CStarAuthenticationError,
|
|
582
|
+
CStarConflictError,
|
|
583
|
+
CStarError,
|
|
584
|
+
CStarFeatureDisabledError,
|
|
585
|
+
CStarNotFoundError,
|
|
586
|
+
CStarPermissionError,
|
|
587
|
+
CStarRateLimitError,
|
|
588
|
+
CStarRealtimeUnavailableError,
|
|
589
|
+
CStarServerError,
|
|
590
|
+
CStarValidationError,
|
|
591
|
+
CommunityClient,
|
|
592
|
+
ErrorType,
|
|
593
|
+
parseError,
|
|
594
|
+
parsePublicError
|
|
533
595
|
});
|