@cstar.help/js 0.16.0 → 0.16.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/dist/index.cjs CHANGED
@@ -303,7 +303,7 @@ var HttpClient = class {
303
303
  }
304
304
  if (typeof config.teamId !== "string" || config.teamId.length === 0) {
305
305
  throw new Error(
306
- "[cStar] CStarClient: teamId is required. Find your team ID in Settings \u2192 General or via `cstar status`."
306
+ "[cStar] CStarClient: teamId is required. Find your team ID in Settings \u2192 API Keys (Team Identifiers) or via `cstar status`."
307
307
  );
308
308
  }
309
309
  this.config = {
@@ -510,6 +510,15 @@ var CStarRealtime = class {
510
510
  this.errorHandlers = /* @__PURE__ */ new Set();
511
511
  this.connectionHandlers = /* @__PURE__ */ new Set();
512
512
  this.lastEventId = null;
513
+ /**
514
+ * Timestamp of the most recently received event, kept as an ISO-8601 string.
515
+ * Sent as `?since=<iso>` on reconnect so the server can replay events missed
516
+ * during the gap. The `id:` field on each SSE message is a prefixed entity
517
+ * ID (`evt_*`), which `new Date(...)` can't parse — passing it as `since`
518
+ * silently skips the replay branch on the server. Track the timestamp
519
+ * separately so reconnects actually catch up. R62.
520
+ */
521
+ this.lastEventTimestamp = null;
513
522
  this.retryCount = 0;
514
523
  this.retryTimer = null;
515
524
  this._connected = false;
@@ -619,8 +628,8 @@ var CStarRealtime = class {
619
628
  if (this.types && this.types.length > 0) {
620
629
  params.set("types", this.types.join(","));
621
630
  }
622
- if (this.lastEventId) {
623
- params.set("since", this.lastEventId);
631
+ if (this.lastEventTimestamp) {
632
+ params.set("since", this.lastEventTimestamp);
624
633
  }
625
634
  const qs = params.toString();
626
635
  const url = `${baseUrl}/events/stream${qs ? `?${qs}` : ""}`;
@@ -683,6 +692,9 @@ var CStarRealtime = class {
683
692
  }
684
693
  try {
685
694
  const parsed = JSON.parse(msgEvent.data);
695
+ if (typeof parsed.timestamp === "string" && parsed.timestamp) {
696
+ this.lastEventTimestamp = parsed.timestamp;
697
+ }
686
698
  const realtimeEvent = {
687
699
  type: parsed.type || type,
688
700
  id: msgEvent.lastEventId || "",
@@ -713,6 +725,8 @@ var CStarRealtime = class {
713
725
  }
714
726
  this.sseToken = null;
715
727
  this.sseTokenExpiresAt = 0;
728
+ this.lastEventId = null;
729
+ this.lastEventTimestamp = null;
716
730
  this.setConnected(false);
717
731
  this.handlers.clear();
718
732
  this.anyHandlers.clear();
@@ -736,6 +750,9 @@ var CStarRealtime = class {
736
750
  try {
737
751
  const parsed = JSON.parse(event.data);
738
752
  if (parsed.type === "connected") return;
753
+ if (typeof parsed.timestamp === "string" && parsed.timestamp) {
754
+ this.lastEventTimestamp = parsed.timestamp;
755
+ }
739
756
  const realtimeEvent = {
740
757
  type: parsed.type,
741
758
  id: event.lastEventId || "",
@@ -1956,7 +1973,7 @@ var AchievementsResource = class {
1956
1973
  constructor(client) {
1957
1974
  this.client = client;
1958
1975
  }
1959
- /** List all achievements with progress. */
1976
+ /** List all achievements with progress. `params.userId` is required. */
1960
1977
  async list(params) {
1961
1978
  return this.client.request("GET", "/game/achievements", {
1962
1979
  query: params
package/dist/index.d.cts CHANGED
@@ -189,6 +189,15 @@ declare class CStarRealtime {
189
189
  private errorHandlers;
190
190
  private connectionHandlers;
191
191
  private lastEventId;
192
+ /**
193
+ * Timestamp of the most recently received event, kept as an ISO-8601 string.
194
+ * Sent as `?since=<iso>` on reconnect so the server can replay events missed
195
+ * during the gap. The `id:` field on each SSE message is a prefixed entity
196
+ * ID (`evt_*`), which `new Date(...)` can't parse — passing it as `since`
197
+ * silently skips the replay branch on the server. Track the timestamp
198
+ * separately so reconnects actually catch up. R62.
199
+ */
200
+ private lastEventTimestamp;
192
201
  private retryCount;
193
202
  private retryTimer;
194
203
  private _connected;
@@ -2194,21 +2203,37 @@ interface ExportResult {
2194
2203
  /** Import request parameters. */
2195
2204
  interface ImportCreateParams {
2196
2205
  resource: 'tickets' | 'customers' | 'articles';
2206
+ /**
2207
+ * Records to import. Flat objects with the per-entity fields you want
2208
+ * to set — e.g. `[{ name: 'Jane', email: 'jane@example.com' }]` for
2209
+ * `resource: 'customers'`. Each record is treated as a create. Server
2210
+ * also accepts the wrapped internal shape `{ data, action, existingId? }`
2211
+ * if you need to drive updates from the SDK.
2212
+ */
2197
2213
  records: Record<string, unknown>[];
2214
+ /** How to handle duplicates. Defaults to `'overwrite'`. */
2198
2215
  mergeStrategy?: 'skip' | 'overwrite' | 'merge';
2199
2216
  }
2200
2217
  /** Import result. */
2201
2218
  interface ImportResult {
2202
2219
  object: 'import_result';
2203
- resource: string;
2220
+ /** ID of the persisted import-log row (null if the log row could not be written). */
2221
+ logId: string | null;
2222
+ /** Entity type imported — `ticket`, `customer`, or `article`. */
2223
+ entityType: string;
2224
+ /** True when every record imported without error. */
2225
+ success: boolean;
2204
2226
  total: number;
2205
2227
  created: number;
2206
2228
  updated: number;
2207
2229
  skipped: number;
2208
- errors: Array<{
2230
+ failed: number;
2231
+ errors?: Array<{
2209
2232
  index: number;
2210
2233
  error: string;
2211
2234
  }>;
2235
+ /** IDs of the rows created by this import. */
2236
+ createdIds: string[];
2212
2237
  }
2213
2238
  /** Import log entry. */
2214
2239
  interface ImportLog {
@@ -2545,6 +2570,8 @@ interface Achievement {
2545
2570
  }
2546
2571
  /** Parameters for listing achievements. */
2547
2572
  interface AchievementListParams extends PaginationParams {
2573
+ /** Whose achievement progress to load. Required — the endpoint 400s without it. */
2574
+ userId: string;
2548
2575
  category?: string;
2549
2576
  }
2550
2577
  /** A daily quest. */
@@ -2741,8 +2768,8 @@ declare class BossResource {
2741
2768
  declare class AchievementsResource {
2742
2769
  private readonly client;
2743
2770
  constructor(client: HttpClient);
2744
- /** List all achievements with progress. */
2745
- list(params?: AchievementListParams): Promise<ApiResponse<{
2771
+ /** List all achievements with progress. `params.userId` is required. */
2772
+ list(params: AchievementListParams): Promise<ApiResponse<{
2746
2773
  object: 'achievement_list';
2747
2774
  data: Achievement[];
2748
2775
  summary: {
package/dist/index.d.ts CHANGED
@@ -189,6 +189,15 @@ declare class CStarRealtime {
189
189
  private errorHandlers;
190
190
  private connectionHandlers;
191
191
  private lastEventId;
192
+ /**
193
+ * Timestamp of the most recently received event, kept as an ISO-8601 string.
194
+ * Sent as `?since=<iso>` on reconnect so the server can replay events missed
195
+ * during the gap. The `id:` field on each SSE message is a prefixed entity
196
+ * ID (`evt_*`), which `new Date(...)` can't parse — passing it as `since`
197
+ * silently skips the replay branch on the server. Track the timestamp
198
+ * separately so reconnects actually catch up. R62.
199
+ */
200
+ private lastEventTimestamp;
192
201
  private retryCount;
193
202
  private retryTimer;
194
203
  private _connected;
@@ -2194,21 +2203,37 @@ interface ExportResult {
2194
2203
  /** Import request parameters. */
2195
2204
  interface ImportCreateParams {
2196
2205
  resource: 'tickets' | 'customers' | 'articles';
2206
+ /**
2207
+ * Records to import. Flat objects with the per-entity fields you want
2208
+ * to set — e.g. `[{ name: 'Jane', email: 'jane@example.com' }]` for
2209
+ * `resource: 'customers'`. Each record is treated as a create. Server
2210
+ * also accepts the wrapped internal shape `{ data, action, existingId? }`
2211
+ * if you need to drive updates from the SDK.
2212
+ */
2197
2213
  records: Record<string, unknown>[];
2214
+ /** How to handle duplicates. Defaults to `'overwrite'`. */
2198
2215
  mergeStrategy?: 'skip' | 'overwrite' | 'merge';
2199
2216
  }
2200
2217
  /** Import result. */
2201
2218
  interface ImportResult {
2202
2219
  object: 'import_result';
2203
- resource: string;
2220
+ /** ID of the persisted import-log row (null if the log row could not be written). */
2221
+ logId: string | null;
2222
+ /** Entity type imported — `ticket`, `customer`, or `article`. */
2223
+ entityType: string;
2224
+ /** True when every record imported without error. */
2225
+ success: boolean;
2204
2226
  total: number;
2205
2227
  created: number;
2206
2228
  updated: number;
2207
2229
  skipped: number;
2208
- errors: Array<{
2230
+ failed: number;
2231
+ errors?: Array<{
2209
2232
  index: number;
2210
2233
  error: string;
2211
2234
  }>;
2235
+ /** IDs of the rows created by this import. */
2236
+ createdIds: string[];
2212
2237
  }
2213
2238
  /** Import log entry. */
2214
2239
  interface ImportLog {
@@ -2545,6 +2570,8 @@ interface Achievement {
2545
2570
  }
2546
2571
  /** Parameters for listing achievements. */
2547
2572
  interface AchievementListParams extends PaginationParams {
2573
+ /** Whose achievement progress to load. Required — the endpoint 400s without it. */
2574
+ userId: string;
2548
2575
  category?: string;
2549
2576
  }
2550
2577
  /** A daily quest. */
@@ -2741,8 +2768,8 @@ declare class BossResource {
2741
2768
  declare class AchievementsResource {
2742
2769
  private readonly client;
2743
2770
  constructor(client: HttpClient);
2744
- /** List all achievements with progress. */
2745
- list(params?: AchievementListParams): Promise<ApiResponse<{
2771
+ /** List all achievements with progress. `params.userId` is required. */
2772
+ list(params: AchievementListParams): Promise<ApiResponse<{
2746
2773
  object: 'achievement_list';
2747
2774
  data: Achievement[];
2748
2775
  summary: {
package/dist/index.js CHANGED
@@ -262,7 +262,7 @@ var HttpClient = class {
262
262
  }
263
263
  if (typeof config.teamId !== "string" || config.teamId.length === 0) {
264
264
  throw new Error(
265
- "[cStar] CStarClient: teamId is required. Find your team ID in Settings \u2192 General or via `cstar status`."
265
+ "[cStar] CStarClient: teamId is required. Find your team ID in Settings \u2192 API Keys (Team Identifiers) or via `cstar status`."
266
266
  );
267
267
  }
268
268
  this.config = {
@@ -469,6 +469,15 @@ var CStarRealtime = class {
469
469
  this.errorHandlers = /* @__PURE__ */ new Set();
470
470
  this.connectionHandlers = /* @__PURE__ */ new Set();
471
471
  this.lastEventId = null;
472
+ /**
473
+ * Timestamp of the most recently received event, kept as an ISO-8601 string.
474
+ * Sent as `?since=<iso>` on reconnect so the server can replay events missed
475
+ * during the gap. The `id:` field on each SSE message is a prefixed entity
476
+ * ID (`evt_*`), which `new Date(...)` can't parse — passing it as `since`
477
+ * silently skips the replay branch on the server. Track the timestamp
478
+ * separately so reconnects actually catch up. R62.
479
+ */
480
+ this.lastEventTimestamp = null;
472
481
  this.retryCount = 0;
473
482
  this.retryTimer = null;
474
483
  this._connected = false;
@@ -578,8 +587,8 @@ var CStarRealtime = class {
578
587
  if (this.types && this.types.length > 0) {
579
588
  params.set("types", this.types.join(","));
580
589
  }
581
- if (this.lastEventId) {
582
- params.set("since", this.lastEventId);
590
+ if (this.lastEventTimestamp) {
591
+ params.set("since", this.lastEventTimestamp);
583
592
  }
584
593
  const qs = params.toString();
585
594
  const url = `${baseUrl}/events/stream${qs ? `?${qs}` : ""}`;
@@ -642,6 +651,9 @@ var CStarRealtime = class {
642
651
  }
643
652
  try {
644
653
  const parsed = JSON.parse(msgEvent.data);
654
+ if (typeof parsed.timestamp === "string" && parsed.timestamp) {
655
+ this.lastEventTimestamp = parsed.timestamp;
656
+ }
645
657
  const realtimeEvent = {
646
658
  type: parsed.type || type,
647
659
  id: msgEvent.lastEventId || "",
@@ -672,6 +684,8 @@ var CStarRealtime = class {
672
684
  }
673
685
  this.sseToken = null;
674
686
  this.sseTokenExpiresAt = 0;
687
+ this.lastEventId = null;
688
+ this.lastEventTimestamp = null;
675
689
  this.setConnected(false);
676
690
  this.handlers.clear();
677
691
  this.anyHandlers.clear();
@@ -695,6 +709,9 @@ var CStarRealtime = class {
695
709
  try {
696
710
  const parsed = JSON.parse(event.data);
697
711
  if (parsed.type === "connected") return;
712
+ if (typeof parsed.timestamp === "string" && parsed.timestamp) {
713
+ this.lastEventTimestamp = parsed.timestamp;
714
+ }
698
715
  const realtimeEvent = {
699
716
  type: parsed.type,
700
717
  id: event.lastEventId || "",
@@ -1915,7 +1932,7 @@ var AchievementsResource = class {
1915
1932
  constructor(client) {
1916
1933
  this.client = client;
1917
1934
  }
1918
- /** List all achievements with progress. */
1935
+ /** List all achievements with progress. `params.userId` is required. */
1919
1936
  async list(params) {
1920
1937
  return this.client.request("GET", "/game/achievements", {
1921
1938
  query: params
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cstar.help/js",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "Official TypeScript SDK for the cStar customer support platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",