@cstar.help/js 0.4.0 → 0.5.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/README.md CHANGED
@@ -4,7 +4,7 @@ Official TypeScript SDK for the [cStar](https://cstar.help) customer support pla
4
4
 
5
5
  - **Zero dependencies** — works with Node.js 18+ native `fetch`
6
6
  - **TypeScript-first** — full type definitions included
7
- - **Five entry points** — tree-shake what you don't need
7
+ - **Six entry points** — tree-shake what you don't need
8
8
  - **ESM + CJS** — works everywhere
9
9
 
10
10
  ## Install
@@ -13,18 +13,56 @@ Official TypeScript SDK for the [cStar](https://cstar.help) customer support pla
13
13
  npm install @cstar.help/js
14
14
  ```
15
15
 
16
- ## Quick Start
16
+ ---
17
17
 
18
- ### Server-side API Client
18
+ ## Which SDK Do I Need?
19
19
 
20
- Manage tickets, customers, articles, and webhooks with your secret API key.
20
+ cStar has one package with **six entry points**, each designed for a different context:
21
+
22
+ | Import | Use Case | Runs On | Auth Required | Key Type |
23
+ | -------------------------- | ----------------------------------------- | ----------------- | ------------- | -------------------- |
24
+ | `@cstar.help/js` | **Admin dashboard / backend integration** | Server only | Yes | Secret (`sk_*`) |
25
+ | `@cstar.help/js/chat` | Customer chat widget | Browser | Yes | Publishable (`pk_*`) |
26
+ | `@cstar.help/js/library` | Public knowledge base | Browser or server | No | None |
27
+ | `@cstar.help/js/community` | Public community forum | Browser or server | No | None |
28
+ | `@cstar.help/js/webhook` | Webhook signature verification | Server only | No | Signing secret |
29
+ | `@cstar.help/js/auth` | Authentication utilities | Server only | Yes | Secret (`sk_*`) |
30
+
31
+ ### The Security Model
32
+
33
+ cStar uses **two key types** to control access — the same pattern as Stripe and Supabase:
34
+
35
+ ```
36
+ Secret keys (sk_live_*, sk_test_*)
37
+ ├── Full CRUD on all resources
38
+ ├── Settings, billing, analytics, game system
39
+ ├── Team member management, audit log
40
+ ├── AI actions, automations, SLA rules
41
+ └── NEVER expose in client-side code
42
+
43
+ Publishable keys (pk_live_*, pk_test_*)
44
+ ├── Read-only on public data (tickets, customers, articles)
45
+ ├── Used by the chat widget for customer-facing features
46
+ ├── Safe to include in browser bundles
47
+ └── Cannot write, delete, or access sensitive endpoints
48
+ ```
49
+
50
+ > **Rule of thumb**: If you're building a custom support dashboard for your team, use `CStarClient` with a secret key on your backend. If you're adding chat to your website, use `ChatClient` with a publishable key in the browser.
51
+
52
+ ---
53
+
54
+ ## Server-Side: Admin API Client
55
+
56
+ > **⚠️ Server-side only.** `CStarClient` requires a secret key (`sk_*`) and must never be used in browser code. The SDK will warn you if it detects a browser environment.
57
+
58
+ Manage tickets, customers, articles, team members, settings, game system, and everything else.
21
59
 
22
60
  ```typescript
23
61
  import { CStarClient } from '@cstar.help/js';
24
62
 
25
63
  const cstar = new CStarClient({
26
- apiKey: 'sk_live_abc123...',
27
- teamId: 'tm_your_team_id'
64
+ apiKey: process.env.CSTAR_SECRET_KEY, // sk_live_... or sk_test_...
65
+ teamId: process.env.CSTAR_TEAM_ID
28
66
  });
29
67
 
30
68
  // List open tickets
@@ -36,18 +74,131 @@ const { data: ticket } = await cstar.tickets.create({
36
74
  customerId: 'cus_abc123'
37
75
  });
38
76
 
39
- // Get a customer with expanded fields
40
- const { data: customer } = await cstar.customers.get('cus_abc123');
41
-
42
77
  // Auto-paginate through all tickets
43
78
  for await (const ticket of cstar.tickets.listAutoPaginating({ status: 'open' })) {
44
79
  console.log(ticket.title);
45
80
  }
46
81
  ```
47
82
 
48
- ### Customer Chat (Widget SDK)
83
+ ### Full Resource Reference
84
+
85
+ **Core Resources** — Tickets, customers, and knowledge base.
86
+
87
+ | Resource | Methods |
88
+ | ------------------------ | ----------------------------------------------------------------------------------------------- |
89
+ | `cstar.tickets` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
90
+ | `cstar.tickets.messages` | `.list(ticketId)` `.create(ticketId, params)` |
91
+ | `cstar.customers` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
92
+ | `cstar.articles` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
93
+ | `cstar.categories` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` |
94
+
95
+ **Team & Configuration** — Members, settings, and customization.
96
+
97
+ | Resource | Methods |
98
+ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
99
+ | `cstar.members` | `.list()` `.get(id)` `.update(id, params)` `.del(id)` |
100
+ | `cstar.members.invites` | `.list()` `.create(params)` `.del(id)` |
101
+ | `cstar.settings` | `.get()` `.update(params)` `.getBusinessHours()` `.updateBusinessHours(params)` `.getWidget()` `.updateWidget(params)` |
102
+ | `cstar.settings.statuses` | `.list()` `.create(params)` `.update(key, params)` `.del(key)` `.reorder(keys)` |
103
+ | `cstar.settings.quickReplies` | `.list()` `.create(params)` `.update(id, params)` `.del(id)` `.reorder(ids)` |
104
+ | `cstar.customFields` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.reorder(ids)` |
105
+ | `cstar.notifications` | `.list()` `.unreadCount()` `.markRead(id)` `.markAllRead()` |
106
+
107
+ **Operations** — Analytics, bulk actions, and data management.
108
+
109
+ | Resource | Methods |
110
+ | ---------------------- | --------------------------------------------------------------------------------------- |
111
+ | `cstar.analytics` | `.overview(params?)` `.agents(params?)` `.csatStats(params?)` `.csatResponses(params?)` |
112
+ | `cstar.sla` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` |
113
+ | `cstar.bulk` | `.update(params)` `.del(params)` |
114
+ | `cstar.export` | `.create(params)` |
115
+ | `cstar.import` | `.create(params)` `.logs(params?)` `.getLog(id)` |
116
+ | `cstar.search` | `.query(params)` |
117
+ | `cstar.tags` | `.list()` `.create(name)` `.del(name)` |
118
+ | `cstar.activity` | `.list(params?)` |
119
+ | `cstar.auditLog` | `.list(params?)` |
120
+ | `cstar.customerGroups` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` |
121
+
122
+ **Gamification** — The full game system.
123
+
124
+ | Resource | Methods |
125
+ | ------------------------- | --------------------------------------------------------------------------------------------------- |
126
+ | `cstar.game` | `.player(params?)` `.getPlayer(memberId)` `.leaderboard(params?)` `.myRank(params?)` |
127
+ | `cstar.game.boss` | `.current()` `.isActive()` `.spawn(params?)` `.damage(params)` `.defeats(params?)` `.getDefeat(id)` |
128
+ | `cstar.game.achievements` | `.list(params?)` `.unlocked(params)` `.get(id, params?)` |
129
+ | `cstar.game.quests` | `.today(params?)` `.history(params?)` |
130
+ | `cstar.game.puzzles` | `.today(params?)` `.complete(params)` `.streak(params)` `.leaderboard(params?)` |
131
+ | `cstar.game.oneUps` | `.list(params?)` `.send(params)` `.remaining(params)` |
132
+ | `cstar.game.highFives` | `.list(params?)` `.send(params)` `.canSend(teamId, params)` |
133
+ | `cstar.game.cosmetics` | `.list(params?)` `.getPreferences(params)` `.updatePreferences(params)` |
134
+ | `cstar.game.seasons` | `.list()` `.current()` `.stats(seasonId, params)` |
135
+ | `cstar.game.skills` | `.get(params)` `.allocate(params)` `.reset(params)` |
136
+
137
+ **Advanced** — AI, automations, views, billing, webhooks.
138
+
139
+ | Resource | Methods |
140
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
141
+ | `cstar.ai` | `.run(params)` `.autoTag(ticketId)` `.suggestReply(ticketId)` `.summarize(ticketId)` `.improve(text)` |
142
+ | `cstar.automations` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.toggle(id)` `.reorder(ids)` `.test(id, params)` `.executions(id)` `.allExecutions()` `.evaluate(params)` |
143
+ | `cstar.views` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.execute(id, params?)` |
144
+ | `cstar.billing` | `.subscription()` `.portal(params?)` |
145
+ | `cstar.webhooks` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.test(id)` |
146
+ | `cstar.community.posts` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` |
147
+ | `cstar.community.topics` | `.list()` `.get(id)` |
148
+ | `cstar.attachments` | `.list(params?)` `.get(id)` `.del(id)` |
149
+
150
+ ### Usage Examples
151
+
152
+ ```typescript
153
+ // Team analytics
154
+ const { data: overview } = await cstar.analytics.overview({ period: 'week' });
155
+ console.log(`${overview.tickets.open} open tickets this week`);
156
+
157
+ // SLA rules
158
+ const { data: rules } = await cstar.sla.list();
159
+
160
+ // Boss battle
161
+ const { data: boss } = await cstar.game.boss.current();
162
+ if (boss.active) {
163
+ console.log(`${boss.name} — ${boss.health}/${boss.maxHealth} HP`);
164
+ }
165
+
166
+ // AI-powered reply suggestion
167
+ const { data: suggestion } = await cstar.ai.suggestReply('tkt_abc123');
168
+
169
+ // Bulk close resolved tickets
170
+ await cstar.bulk.update({
171
+ resource: 'tickets',
172
+ ids: ['tkt_1', 'tkt_2', 'tkt_3'],
173
+ data: { status: 'closed' }
174
+ });
175
+
176
+ // Export data
177
+ const { data: exportResult } = await cstar.export.create({
178
+ resources: [{ type: 'tickets', filters: { status: 'closed' } }],
179
+ format: 'csv'
180
+ });
181
+
182
+ // Saved views
183
+ const { data: view } = await cstar.views.create({
184
+ name: 'Urgent Unresolved',
185
+ entityType: 'tickets',
186
+ filters: { priority: 'urgent', status: 'open' }
187
+ });
188
+ const { data: results } = await cstar.views.execute(view.id);
189
+
190
+ // Search across everything
191
+ const { data: searchResults } = await cstar.search.query({
192
+ query: 'billing issue',
193
+ types: ['tickets', 'customers']
194
+ });
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Client-Side: Chat Widget SDK
49
200
 
50
- Build custom chat experiences with identity verification.
201
+ Build custom chat experiences in the browser. Uses a publishable key — safe for frontend code.
51
202
 
52
203
  ```typescript
53
204
  import { ChatClient } from '@cstar.help/js/chat';
@@ -66,7 +217,7 @@ const { conversations } = await chat.conversations.list();
66
217
  // Send a message
67
218
  await chat.messages.send('tkt_abc123', 'Thanks for the help!');
68
219
 
69
- // Subscribe to new messages (polling)
220
+ // Subscribe to new messages
70
221
  const unsubscribe = chat.onMessage('tkt_abc123', (message) => {
71
222
  console.log(`${message.sender_name}: ${message.content}`);
72
223
  });
@@ -75,88 +226,48 @@ const unsubscribe = chat.onMessage('tkt_abc123', (message) => {
75
226
  chat.disconnect();
76
227
  ```
77
228
 
78
- ### Public Knowledge Base
229
+ ---
79
230
 
80
- Search and browse your public help center — no authentication required.
231
+ ## Client-Side: Public Knowledge Base
232
+
233
+ Search and browse your public help center — **no authentication required**.
81
234
 
82
235
  ```typescript
83
236
  import { LibraryClient } from '@cstar.help/js/library';
84
237
 
85
238
  const library = new LibraryClient({ teamSlug: 'acme' });
86
239
 
87
- // List categories
88
240
  const categories = await library.categories();
89
-
90
- // Search articles
91
241
  const results = await library.search('reset password');
92
-
93
- // Get a specific article
94
242
  const article = await library.article('how-to-reset-password');
95
243
  ```
96
244
 
97
- ### Public Community
245
+ ---
98
246
 
99
- Browse and search your public community forum — no authentication required.
247
+ ## Client-Side: Public Community
248
+
249
+ Browse your public community forum — **no authentication required**.
100
250
 
101
251
  ```typescript
102
252
  import { CommunityClient } from '@cstar.help/js/community';
103
253
 
104
254
  const community = new CommunityClient({ teamSlug: 'acme' });
105
255
 
106
- // List discussion topics
107
256
  const topics = await community.topics();
108
-
109
- // List posts (with filters)
110
- const { posts, count } = await community.posts({
111
- topicSlug: 'feature-requests',
112
- sort: 'votes'
113
- });
114
-
115
- // Get a single post with all comments
257
+ const { posts } = await community.posts({ topicSlug: 'feature-requests', sort: 'votes' });
116
258
  const { post, comments } = await community.post('dark-mode-support');
117
-
118
- // Search posts
119
- const results = await community.search('billing');
120
259
  ```
121
260
 
122
- ### Server-side Community (Admin)
123
-
124
- Manage community posts with your secret API key via `CStarClient`:
261
+ ---
125
262
 
126
- ```typescript
127
- const cstar = new CStarClient({ apiKey: 'sk_live_...', teamId: 'tm_...' });
128
-
129
- // List all posts (including hidden/unapproved)
130
- const { data: posts } = await cstar.community.posts.list({ status: 'open' });
131
-
132
- // Create a post
133
- const { data: post } = await cstar.community.posts.create({
134
- title: 'New Feature: Dark Mode',
135
- body: 'We just shipped dark mode!',
136
- topicId: 'topic_abc123'
137
- });
138
-
139
- // Toggle vote on a post
140
- const { voted, voteCount } = await cstar.community.posts.vote('post_id');
141
-
142
- // Add a comment
143
- const comment = await cstar.community.posts.createComment('post_id', {
144
- body: 'Great idea!',
145
- isOfficial: true
146
- });
147
-
148
- // List topics
149
- const { data: topics } = await cstar.community.topics.list();
150
- ```
151
-
152
- ### Webhook Verification
263
+ ## Server-Side: Webhook Verification
153
264
 
154
265
  Verify incoming webhook signatures on your server.
155
266
 
156
267
  ```typescript
157
268
  import { constructEvent } from '@cstar.help/js/webhook';
158
269
 
159
- // In your webhook handler (Express, Hono, etc.)
270
+ // In your webhook handler
160
271
  const event = constructEvent(rawBody, signature, 'whsec_your_secret');
161
272
 
162
273
  switch (event.type) {
@@ -169,33 +280,20 @@ switch (event.type) {
169
280
  }
170
281
  ```
171
282
 
172
- For edge environments (Cloudflare Workers, Deno), use the async variant:
283
+ For edge runtimes (Cloudflare Workers, Deno), use the async variant:
173
284
 
174
285
  ```typescript
175
286
  import { constructEventAsync } from '@cstar.help/js/webhook';
176
-
177
287
  const event = await constructEventAsync(rawBody, signature, secret);
178
288
  ```
179
289
 
180
- ## API Reference
181
-
182
- ### CStarClient
183
-
184
- | Resource | Methods |
185
- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
186
- | `cstar.tickets` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
187
- | `cstar.tickets.messages` | `.list(ticketId)` `.create(ticketId, params)` |
188
- | `cstar.customers` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
189
- | `cstar.articles` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.listAutoPaginating()` |
190
- | `cstar.webhooks` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.test(id)` |
191
- | `cstar.community.posts` | `.list()` `.get(id)` `.create(params)` `.update(id, params)` `.del(id)` `.vote(id)` `.follow(id)` `.listComments(id)` `.createComment(id, params)` |
192
- | `cstar.community.topics` | `.list()` `.get(id)` |
290
+ ---
193
291
 
194
- ### Configuration
292
+ ## Configuration
195
293
 
196
294
  ```typescript
197
295
  const cstar = new CStarClient({
198
- apiKey: 'sk_live_...', // Required — secret or publishable key
296
+ apiKey: 'sk_live_...', // Required — must be a secret key (sk_*)
199
297
  teamId: 'tm_...', // Required — your team ID
200
298
  baseUrl: 'https://...', // Optional — defaults to https://www.cstar.help
201
299
  version: '2026-03-01', // Optional — API version header
@@ -204,26 +302,32 @@ const cstar = new CStarClient({
204
302
  });
205
303
  ```
206
304
 
207
- ### Test Mode
305
+ ## Test Mode
208
306
 
209
307
  Test mode is auto-detected from your API key prefix:
210
308
 
211
309
  ```typescript
212
- // Uses test data — no real customers affected
213
310
  const cstar = new CStarClient({
214
311
  apiKey: 'sk_test_abc123...',
215
312
  teamId: 'tm_your_team_id'
216
313
  });
217
314
 
218
315
  console.log(cstar.isTestMode); // true
316
+ // All operations use test data — no real customers affected
219
317
  ```
220
318
 
221
- ### Error Handling
319
+ ## Error Handling
222
320
 
223
321
  All API errors throw typed exceptions:
224
322
 
225
323
  ```typescript
226
- import { CStarError, CStarNotFoundError, CStarValidationError } from '@cstar.help/js';
324
+ import {
325
+ CStarError,
326
+ CStarAuthenticationError,
327
+ CStarRateLimitError,
328
+ CStarNotFoundError,
329
+ CStarValidationError
330
+ } from '@cstar.help/js';
227
331
 
228
332
  try {
229
333
  await cstar.tickets.get('tkt_nonexistent');
@@ -232,15 +336,19 @@ try {
232
336
  console.log('Ticket not found:', err.message);
233
337
  } else if (err instanceof CStarValidationError) {
234
338
  console.log('Invalid param:', err.param);
339
+ } else if (err instanceof CStarRateLimitError) {
340
+ console.log('Rate limited, retry after:', err.retryAfter, 'seconds');
341
+ } else if (err instanceof CStarAuthenticationError) {
342
+ console.log('Bad API key');
235
343
  } else if (err instanceof CStarError) {
236
344
  console.log('API error:', err.code, err.statusCode);
237
345
  }
238
346
  }
239
347
  ```
240
348
 
241
- ### Idempotency
349
+ ## Idempotency
242
350
 
243
- Safely retry create operations:
351
+ Safely retry create/update operations:
244
352
 
245
353
  ```typescript
246
354
  const { data: ticket } = await cstar.tickets.create(