@cstar.help/js 0.17.5 → 0.18.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/index.js CHANGED
@@ -237,7 +237,7 @@ function parseError(statusCode, body, retryAfter) {
237
237
  }
238
238
 
239
239
  // src/client.ts
240
- var SDK_VERSION = "0.17.5";
240
+ var SDK_VERSION = "0.18.0";
241
241
  var DEFAULT_BASE_URL = "https://www.cstar.help";
242
242
  var DEFAULT_API_VERSION = "2026-03-01";
243
243
  var DEFAULT_MAX_RETRIES = 3;
@@ -257,7 +257,7 @@ var HttpClient = class {
257
257
  this.lastMeta = { requestId: null, timestamp: null, pagination: null };
258
258
  if (!config || typeof config.apiKey !== "string" || config.apiKey.length === 0) {
259
259
  throw new Error(
260
- "[cStar] CStarClient: apiKey is required. Pass a secret key (sk_live_... / sk_test_...) or a publishable key (pk_live_... / pk_test_...). See https://cstar.help/developers/quickstart"
260
+ "[cStar] CStarClient: apiKey is required. Pass a secret key (sk_live_... / sk_test_...). Publishable keys (pk_...) cannot read team endpoints; use them with LibraryClient or CommunityClient. See https://cstar.help/developers/quickstart"
261
261
  );
262
262
  }
263
263
  if (typeof config.teamId !== "string" || config.teamId.length === 0) {
@@ -489,6 +489,8 @@ var CStarRealtime = class {
489
489
  this.retryTimer = null;
490
490
  this._connected = false;
491
491
  this.destroyed = false;
492
+ /** The server closed the stream because the API key was revoked or expired. */
493
+ this.revoked = false;
492
494
  this.connecting = false;
493
495
  /** Short-lived SSE token (exchanged from secret key). */
494
496
  this.sseToken = null;
@@ -564,7 +566,7 @@ var CStarRealtime = class {
564
566
  }
565
567
  /** Start the SSE connection. Called automatically on first handler registration. */
566
568
  connect() {
567
- if (this.eventSource || this.destroyed || this.connecting) return;
569
+ if (this.eventSource || this.destroyed || this.revoked || this.connecting) return;
568
570
  if (!this.resolveEventSource()) {
569
571
  throw new CStarRealtimeUnavailableError();
570
572
  }
@@ -624,6 +626,7 @@ var CStarRealtime = class {
624
626
  this.eventSource.close();
625
627
  this.eventSource = null;
626
628
  }
629
+ if (this.revoked) return;
627
630
  if (this.autoReconnect && !this.destroyed && this.retryCount < this.maxRetries) {
628
631
  this.scheduleReconnect();
629
632
  } else if (this.retryCount >= this.maxRetries) {
@@ -633,6 +636,9 @@ var CStarRealtime = class {
633
636
  this.eventSource.onmessage = (event) => {
634
637
  this.handleMessage(event);
635
638
  };
639
+ this.eventSource.addEventListener("revoked", (event) => {
640
+ this.handleRevoked(event);
641
+ });
636
642
  const knownTypes = [
637
643
  "ticket.created",
638
644
  "ticket.updated",
@@ -761,6 +767,40 @@ var CStarRealtime = class {
761
767
  for (const handler of this.connectionHandlers) handler(value);
762
768
  }
763
769
  }
770
+ handleRevoked(event) {
771
+ if (this.revoked || this.destroyed) return;
772
+ this.revoked = true;
773
+ let body = {};
774
+ try {
775
+ body = JSON.parse(event.data).error ?? {};
776
+ } catch {
777
+ }
778
+ if (this.retryTimer) {
779
+ clearTimeout(this.retryTimer);
780
+ this.retryTimer = null;
781
+ }
782
+ if (this.tokenRefreshTimer) {
783
+ clearTimeout(this.tokenRefreshTimer);
784
+ this.tokenRefreshTimer = null;
785
+ }
786
+ if (this.eventSource) {
787
+ this.eventSource.close();
788
+ this.eventSource = null;
789
+ }
790
+ this.sseToken = null;
791
+ this.sseTokenExpiresAt = 0;
792
+ this.connecting = false;
793
+ this.setConnected(false);
794
+ this.emitError(
795
+ new CStarAuthenticationError(401, {
796
+ type: body.type ?? "authentication_error",
797
+ code: body.code ?? "invalid_api_key",
798
+ message: body.message ?? "This API key was revoked or has expired, so the stream is closed.",
799
+ doc_url: body.doc_url ?? "https://www.cstar.help/developers/errors#invalid_api_key",
800
+ ...body.request_id ? { request_id: body.request_id } : {}
801
+ })
802
+ );
803
+ }
764
804
  emitError(error) {
765
805
  for (const handler of this.errorHandlers) handler(error);
766
806
  }
@@ -1480,11 +1520,17 @@ var SettingsResource = class {
1480
1520
  async update(params) {
1481
1521
  return this.client.request("PATCH", "/settings", { body: params });
1482
1522
  }
1483
- /** Get business hours configuration. */
1523
+ /**
1524
+ * Get the chat widget's online hours (outside them the widget shows its
1525
+ * offline message). Not the SLA working hours that SLA deadlines use.
1526
+ */
1484
1527
  async getBusinessHours() {
1485
1528
  return this.client.request("GET", "/settings/business-hours");
1486
1529
  }
1487
- /** Update business hours configuration. */
1530
+ /**
1531
+ * Update the chat widget's online hours. SLA deadlines don't change:
1532
+ * they follow the SLA working hours in Settings > Business Hours.
1533
+ */
1488
1534
  async updateBusinessHours(params) {
1489
1535
  return this.client.request("PATCH", "/settings/business-hours", {
1490
1536
  body: params
@@ -1509,8 +1555,10 @@ var NotificationsResource = class {
1509
1555
  }
1510
1556
  /** List notifications for a user. */
1511
1557
  async list(params) {
1558
+ const { unreadOnly, ...query } = params;
1559
+ if (unreadOnly && query.isRead === void 0) query.isRead = false;
1512
1560
  return this.client.request("GET", "/notifications", {
1513
- query: params
1561
+ query
1514
1562
  });
1515
1563
  }
1516
1564
  /** Get unread notification count for a user. */
@@ -1584,15 +1632,22 @@ var AttachmentsResource = class {
1584
1632
  constructor(client) {
1585
1633
  this.client = client;
1586
1634
  }
1587
- /** List attachments. */
1635
+ /** List message files, each with a short-lived signed `url`. */
1588
1636
  async list(params) {
1589
1637
  return this.client.request("GET", "/attachments", {
1590
1638
  query: params
1591
1639
  });
1592
1640
  }
1593
- /** Get a single attachment. */
1594
- async get(attachmentId) {
1595
- return this.client.request("GET", `/attachments/${attachmentId}`);
1641
+ /**
1642
+ * Get a signed download URL, valid for `expiresIn` seconds, for a stored
1643
+ * file. Pass `storagePath` and `bucket` from `list()`.
1644
+ */
1645
+ async get(storagePath, params) {
1646
+ return this.client.request(
1647
+ "GET",
1648
+ `/attachments/${storagePath}`,
1649
+ params?.bucket ? { query: { bucket: params.bucket } } : void 0
1650
+ );
1596
1651
  }
1597
1652
  /** Delete an attachment. */
1598
1653
  async del(attachmentId) {
@@ -1608,16 +1663,12 @@ var CustomFieldsResource = class {
1608
1663
  constructor(client) {
1609
1664
  this.client = client;
1610
1665
  }
1611
- /** List custom fields. */
1666
+ /** List custom field definitions, optionally for one record type. There is no single-field GET. */
1612
1667
  async list(params) {
1613
1668
  return this.client.request("GET", "/custom-fields", {
1614
1669
  query: params
1615
1670
  });
1616
1671
  }
1617
- /** Get a single custom field. */
1618
- async get(fieldId) {
1619
- return this.client.request("GET", `/custom-fields/${fieldId}`);
1620
- }
1621
1672
  /** Create a custom field. */
1622
1673
  async create(params, options) {
1623
1674
  return this.client.request("POST", "/custom-fields", {
@@ -1652,11 +1703,9 @@ var SlaResource = class {
1652
1703
  constructor(client) {
1653
1704
  this.client = client;
1654
1705
  }
1655
- /** List SLA rules. */
1656
- async list(params) {
1657
- return this.client.request("GET", "/sla/rules", {
1658
- query: params
1659
- });
1706
+ /** List SLA rules in evaluation order. */
1707
+ async list() {
1708
+ return this.client.request("GET", "/sla/rules");
1660
1709
  }
1661
1710
  /** Create an SLA rule. */
1662
1711
  async create(params, options) {
@@ -1845,25 +1894,28 @@ var TagsResource = class {
1845
1894
  constructor(client) {
1846
1895
  this.client = client;
1847
1896
  }
1848
- /** List all tags with usage counts. */
1897
+ /** List tags with usage counts, one row per tag and entity type. */
1849
1898
  async list(params) {
1850
1899
  return this.client.request("GET", "/tags", {
1851
1900
  query: params
1852
1901
  });
1853
1902
  }
1854
- /** Create a tag. */
1855
- async create(name, options) {
1903
+ /** Replace `fromTag` with `toTag` on every record that carries it. */
1904
+ async merge(params, options) {
1856
1905
  return this.client.request("POST", "/tags", {
1857
- body: { name },
1906
+ body: { action: "merge", ...params },
1858
1907
  idempotencyKey: options?.idempotencyKey
1859
1908
  });
1860
1909
  }
1861
- /** Delete a tag. */
1862
- async del(name) {
1863
- return this.client.request(
1864
- "DELETE",
1865
- `/tags/${encodeURIComponent(name)}`
1866
- );
1910
+ /** Remove a tag from every record that carries it. */
1911
+ async remove(tag, params) {
1912
+ return this.client.request("DELETE", "/tags", {
1913
+ body: { tag, ...params }
1914
+ });
1915
+ }
1916
+ /** @deprecated Use `remove()`. */
1917
+ async del(tag, params) {
1918
+ return this.remove(tag, params);
1867
1919
  }
1868
1920
  };
1869
1921
 
@@ -2309,7 +2361,7 @@ var ViewsResource = class extends BaseResource {
2309
2361
  constructor(client) {
2310
2362
  super(client, "/views");
2311
2363
  }
2312
- /** Execute a view — returns the filtered results. The server uses the view's entity_type to determine which table to query. */
2364
+ /** Execute a view and return the filtered results. The server uses the view's entity_type to determine which table to query. */
2313
2365
  async execute(viewId, params) {
2314
2366
  return this.client.request("GET", `/views/${viewId}/execute`, {
2315
2367
  query: params
@@ -2545,7 +2597,7 @@ var WEBHOOK_EVENT_SAMPLES = {
2545
2597
  "comment": {
2546
2598
  "id": "cmt_01H8X9YZ7E0J3K4M5N6X",
2547
2599
  "post_id": "post_01H8X9YZ7E0J3K4M5N6W",
2548
- "content": "I would love this \u2014 bumping for visibility.",
2600
+ "content": "I would love this. Bumping for visibility.",
2549
2601
  "author_id": "cus_01H8X9YZ7E0J3K4M5N6Q",
2550
2602
  "created_at": "2026-04-27T18:55:02.000Z"
2551
2603
  }
@@ -2765,15 +2817,14 @@ var WEBHOOK_EVENT_SAMPLES = {
2765
2817
  "id": "tkt_01H8X9YZ7E0J3K4M5N6P",
2766
2818
  "prefixed_id": "CST-1024",
2767
2819
  "title": "Cannot reset password",
2768
- "status": "resolved",
2820
+ "status": "closed",
2769
2821
  "priority": "normal",
2770
- "channel": "widget",
2771
- "resolved_at": "2026-04-27T19:08:43.000Z"
2822
+ "channel": "widget"
2772
2823
  },
2773
2824
  "changes": {
2774
2825
  "status": {
2775
2826
  "from": "open",
2776
- "to": "resolved"
2827
+ "to": "closed"
2777
2828
  }
2778
2829
  }
2779
2830
  },
@@ -2806,7 +2857,7 @@ var WEBHOOK_EVENT_SAMPLES = {
2806
2857
  "id": "msg_01H8X9YZ7E0J3K4M5N6R",
2807
2858
  "sender": "agent",
2808
2859
  "sender_name": "Riley",
2809
- "content": "I just sent a reset link to your inbox \u2014 let me know if it lands.",
2860
+ "content": "I just sent a reset link to your inbox. Let me know if it lands.",
2810
2861
  "created_at": "2026-04-27T18:55:02.000Z"
2811
2862
  },
2812
2863
  "customer": {
@@ -2872,7 +2923,7 @@ var WEBHOOK_EVENT_CATALOG = {
2872
2923
  "survey.submitted": { label: "Customer Feedback Received", description: "Fired when a customer submits a CSAT survey response", category: "csat" },
2873
2924
  "team.preferences_updated": { label: "Team Preferences Updated", description: "Fired when team-wide UX preferences change (e.g., bossBattlesEnabled toggled)", category: "team" },
2874
2925
  "ticket.assigned": { label: "Ticket Assigned", description: "Fired when a ticket is assigned to an agent", category: "tickets" },
2875
- "ticket.closed": { label: "Ticket Closed/Resolved", description: "Fired when a ticket is resolved or closed", category: "tickets" },
2926
+ "ticket.closed": { label: "Ticket Closed", description: "Fired when a ticket's status changes to Closed. Moving a ticket to Resolved sends ticket.updated instead.", category: "tickets" },
2876
2927
  "ticket.created": { label: "New Ticket Created", description: "Fired when a new ticket is created via app, widget, API, or email", category: "tickets" },
2877
2928
  "ticket.deleted": { label: "Ticket Deleted", description: "Fired when a ticket is deleted via app or API", category: "tickets" },
2878
2929
  "ticket.message_added": { label: "New Message on Ticket", description: "Fired when a new message is added to a ticket", category: "tickets" },
@@ -23,51 +23,64 @@ __export(proactive_exports, {
23
23
  ProactiveClient: () => ProactiveClient
24
24
  });
25
25
  module.exports = __toCommonJS(proactive_exports);
26
- var DEFAULT_BASE_URL = "https://www.cstar.help";
27
- function createRageClickDetector(onSignal) {
26
+
27
+ // src/proactive/rageClick.ts
28
+ var INTERACTIVE_SELECTOR = 'a[href], button, input, select, textarea, label, summary, [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="tab"], [role="menuitem"], [role="option"], [contenteditable="true"], [contenteditable=""]';
29
+ var RAGE_CLICK_THRESHOLD = 3;
30
+ var RAGE_CLICK_WINDOW_MS = 1e3;
31
+ var RAGE_CLICK_RADIUS_PX = 30;
32
+ var RAGE_CLICK_DEBOUNCE_MS = 2e3;
33
+ function describe(el) {
34
+ let context = el.tagName ? "on " + el.tagName.toLowerCase() : "";
35
+ if (typeof el.className === "string") {
36
+ const cls = el.className.split(" ")[0];
37
+ if (cls) context += "." + cls;
38
+ }
39
+ return context;
40
+ }
41
+ function createRageClickDetector(onSignal, doc) {
28
42
  let clicks = [];
29
43
  let lastFired = 0;
30
44
  let handler = null;
45
+ function onClick(e) {
46
+ const now = Date.now();
47
+ const target = e.target;
48
+ if (!target || typeof target.closest !== "function" || target.closest(INTERACTIVE_SELECTOR)) {
49
+ clicks = [];
50
+ return;
51
+ }
52
+ clicks = clicks.filter((c) => now - c.t < RAGE_CLICK_WINDOW_MS && c.target === target);
53
+ clicks.push({ x: e.clientX, y: e.clientY, t: now, target });
54
+ if (clicks.length < RAGE_CLICK_THRESHOLD || now - lastFired <= RAGE_CLICK_DEBOUNCE_MS) return;
55
+ const first = clicks[0];
56
+ const allClose = clicks.every(
57
+ (c) => Math.hypot(first.x - c.x, first.y - c.y) <= RAGE_CLICK_RADIUS_PX
58
+ );
59
+ if (!allClose) return;
60
+ lastFired = now;
61
+ onSignal({
62
+ type: "rage_click",
63
+ confidence: Math.min(1, clicks.length / 5),
64
+ context: `Clicked ${clicks.length} times rapidly ${describe(target)}`,
65
+ timestamp: now
66
+ });
67
+ clicks = [];
68
+ }
31
69
  return {
32
70
  start() {
33
- handler = (e) => {
34
- const now = Date.now();
35
- clicks = clicks.filter((c) => now - c.t < 500);
36
- clicks.push({ x: e.clientX, y: e.clientY, t: now });
37
- if (clicks.length >= 3 && now - lastFired > 2e3) {
38
- const first = clicks[0];
39
- const allClose = clicks.every((c) => {
40
- const dx = first.x - c.x;
41
- const dy = first.y - c.y;
42
- return Math.sqrt(dx * dx + dy * dy) <= 50;
43
- });
44
- if (allClose) {
45
- lastFired = now;
46
- const el = e.target;
47
- let context = el?.tagName ? "on " + el.tagName.toLowerCase() : "";
48
- if (el?.className && typeof el.className === "string") {
49
- const cls = el.className.split(" ")[0];
50
- if (cls) context += "." + cls;
51
- }
52
- onSignal({
53
- type: "rage_click",
54
- confidence: Math.min(1, clicks.length / 5),
55
- context: `Clicked ${clicks.length} times rapidly ${context}`,
56
- timestamp: now
57
- });
58
- clicks = [];
59
- }
60
- }
61
- };
62
- document.addEventListener("click", handler, true);
71
+ handler = onClick;
72
+ (doc ?? document).addEventListener("click", handler, true);
63
73
  },
64
74
  stop() {
65
- if (handler) document.removeEventListener("click", handler, true);
75
+ if (handler) (doc ?? document).removeEventListener("click", handler, true);
66
76
  handler = null;
67
77
  clicks = [];
68
78
  }
69
79
  };
70
80
  }
81
+
82
+ // src/proactive/index.ts
83
+ var DEFAULT_BASE_URL = "https://www.cstar.help";
71
84
  function createExitIntentDetector(onSignal) {
72
85
  let fired = false;
73
86
  let handler = null;
@@ -1,49 +1,60 @@
1
- // src/proactive/index.ts
2
- var DEFAULT_BASE_URL = "https://www.cstar.help";
3
- function createRageClickDetector(onSignal) {
1
+ // src/proactive/rageClick.ts
2
+ var INTERACTIVE_SELECTOR = 'a[href], button, input, select, textarea, label, summary, [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="tab"], [role="menuitem"], [role="option"], [contenteditable="true"], [contenteditable=""]';
3
+ var RAGE_CLICK_THRESHOLD = 3;
4
+ var RAGE_CLICK_WINDOW_MS = 1e3;
5
+ var RAGE_CLICK_RADIUS_PX = 30;
6
+ var RAGE_CLICK_DEBOUNCE_MS = 2e3;
7
+ function describe(el) {
8
+ let context = el.tagName ? "on " + el.tagName.toLowerCase() : "";
9
+ if (typeof el.className === "string") {
10
+ const cls = el.className.split(" ")[0];
11
+ if (cls) context += "." + cls;
12
+ }
13
+ return context;
14
+ }
15
+ function createRageClickDetector(onSignal, doc) {
4
16
  let clicks = [];
5
17
  let lastFired = 0;
6
18
  let handler = null;
19
+ function onClick(e) {
20
+ const now = Date.now();
21
+ const target = e.target;
22
+ if (!target || typeof target.closest !== "function" || target.closest(INTERACTIVE_SELECTOR)) {
23
+ clicks = [];
24
+ return;
25
+ }
26
+ clicks = clicks.filter((c) => now - c.t < RAGE_CLICK_WINDOW_MS && c.target === target);
27
+ clicks.push({ x: e.clientX, y: e.clientY, t: now, target });
28
+ if (clicks.length < RAGE_CLICK_THRESHOLD || now - lastFired <= RAGE_CLICK_DEBOUNCE_MS) return;
29
+ const first = clicks[0];
30
+ const allClose = clicks.every(
31
+ (c) => Math.hypot(first.x - c.x, first.y - c.y) <= RAGE_CLICK_RADIUS_PX
32
+ );
33
+ if (!allClose) return;
34
+ lastFired = now;
35
+ onSignal({
36
+ type: "rage_click",
37
+ confidence: Math.min(1, clicks.length / 5),
38
+ context: `Clicked ${clicks.length} times rapidly ${describe(target)}`,
39
+ timestamp: now
40
+ });
41
+ clicks = [];
42
+ }
7
43
  return {
8
44
  start() {
9
- handler = (e) => {
10
- const now = Date.now();
11
- clicks = clicks.filter((c) => now - c.t < 500);
12
- clicks.push({ x: e.clientX, y: e.clientY, t: now });
13
- if (clicks.length >= 3 && now - lastFired > 2e3) {
14
- const first = clicks[0];
15
- const allClose = clicks.every((c) => {
16
- const dx = first.x - c.x;
17
- const dy = first.y - c.y;
18
- return Math.sqrt(dx * dx + dy * dy) <= 50;
19
- });
20
- if (allClose) {
21
- lastFired = now;
22
- const el = e.target;
23
- let context = el?.tagName ? "on " + el.tagName.toLowerCase() : "";
24
- if (el?.className && typeof el.className === "string") {
25
- const cls = el.className.split(" ")[0];
26
- if (cls) context += "." + cls;
27
- }
28
- onSignal({
29
- type: "rage_click",
30
- confidence: Math.min(1, clicks.length / 5),
31
- context: `Clicked ${clicks.length} times rapidly ${context}`,
32
- timestamp: now
33
- });
34
- clicks = [];
35
- }
36
- }
37
- };
38
- document.addEventListener("click", handler, true);
45
+ handler = onClick;
46
+ (doc ?? document).addEventListener("click", handler, true);
39
47
  },
40
48
  stop() {
41
- if (handler) document.removeEventListener("click", handler, true);
49
+ if (handler) (doc ?? document).removeEventListener("click", handler, true);
42
50
  handler = null;
43
51
  clicks = [];
44
52
  }
45
53
  };
46
54
  }
55
+
56
+ // src/proactive/index.ts
57
+ var DEFAULT_BASE_URL = "https://www.cstar.help";
47
58
  function createExitIntentDetector(onSignal) {
48
59
  let fired = false;
49
60
  let handler = null;
@@ -1,4 +1,4 @@
1
- import { d as WebhookEvent } from '../webhookEvents-1N2i2GcQ.cjs';
1
+ import { d as WebhookEvent } from '../webhookEvents-Lqpsj935.cjs';
2
2
 
3
3
  /** Default replay window for Stripe-style signatures: 5 minutes (300s). */
4
4
  declare const DEFAULT_TOLERANCE_SECONDS = 300;
@@ -1,4 +1,4 @@
1
- import { d as WebhookEvent } from '../webhookEvents-1N2i2GcQ.js';
1
+ import { d as WebhookEvent } from '../webhookEvents-Lqpsj935.js';
2
2
 
3
3
  /** Default replay window for Stripe-style signatures: 5 minutes (300s). */
4
4
  declare const DEFAULT_TOLERANCE_SECONDS = 300;
@@ -1,4 +1,4 @@
1
- import { d as WebhookEvent } from '../webhookEvents-1N2i2GcQ.cjs';
1
+ import { d as WebhookEvent } from '../webhookEvents-Lqpsj935.cjs';
2
2
  import { VerifyOptions } from './index.cjs';
3
3
  export { DEFAULT_TOLERANCE_SECONDS, WebhookSignatureVerificationError } from './index.cjs';
4
4
 
@@ -1,4 +1,4 @@
1
- import { d as WebhookEvent } from '../webhookEvents-1N2i2GcQ.js';
1
+ import { d as WebhookEvent } from '../webhookEvents-Lqpsj935.js';
2
2
  import { VerifyOptions } from './index.js';
3
3
  export { DEFAULT_TOLERANCE_SECONDS, WebhookSignatureVerificationError } from './index.js';
4
4
 
@@ -314,7 +314,6 @@ interface TicketClosedPayload {
314
314
  status: string;
315
315
  priority: string;
316
316
  channel: string;
317
- resolved_at: string;
318
317
  };
319
318
  changes?: Record<string, {
320
319
  from: string;
@@ -314,7 +314,6 @@ interface TicketClosedPayload {
314
314
  status: string;
315
315
  priority: string;
316
316
  channel: string;
317
- resolved_at: string;
318
317
  };
319
318
  changes?: Record<string, {
320
319
  from: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cstar.help/js",
3
- "version": "0.17.5",
3
+ "version": "0.18.0",
4
4
  "description": "Official TypeScript SDK for the cStar customer support platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",