@cstar.help/js 0.12.1 → 0.13.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 +217 -3
- package/dist/auth/index.js +215 -3
- package/dist/chat/index.cjs +46 -26
- package/dist/chat/index.d.cts +28 -24
- package/dist/chat/index.d.ts +28 -24
- package/dist/chat/index.js +46 -26
- package/dist/community/index.cjs +233 -9
- package/dist/community/index.d.cts +11 -0
- package/dist/community/index.d.ts +11 -0
- package/dist/community/index.js +231 -9
- package/dist/index.cjs +268 -73
- package/dist/index.d.cts +3259 -0
- package/dist/index.d.ts +3259 -0
- package/dist/index.js +267 -73
- package/dist/library/index.cjs +254 -9
- package/dist/library/index.d.cts +26 -3
- package/dist/library/index.d.ts +26 -3
- package/dist/library/index.js +252 -9
- package/dist/quickhelp/index.cjs +176 -2
- package/dist/quickhelp/index.d.cts +11 -0
- package/dist/quickhelp/index.d.ts +11 -0
- package/dist/quickhelp/index.js +174 -2
- package/dist/webhook/index.cjs +0 -18
- package/dist/webhook/index.d.cts +440 -0
- package/dist/webhook/index.d.ts +440 -0
- package/dist/webhook/index.js +0 -23
- package/dist/webhook/node.cjs +57 -0
- package/dist/webhook/node.d.cts +440 -0
- package/dist/webhook/node.d.ts +440 -0
- package/dist/webhook/node.js +30 -0
- package/package.json +14 -2
|
@@ -9,6 +9,14 @@ interface CommunityAttachment {
|
|
|
9
9
|
interface CommunityConfig {
|
|
10
10
|
/** Team slug (e.g., 'acme'). Identifies the community to query. */
|
|
11
11
|
teamSlug: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional publishable key (`pk_test_*` or `pk_live_*`). When provided,
|
|
14
|
+
* the client switches data scope to match the key's mode (test vs live).
|
|
15
|
+
* Without a key, defaults to live — backwards-compatible with existing
|
|
16
|
+
* widget integrations. See `LibraryConfig.publishableKey` for the full
|
|
17
|
+
* test/live story.
|
|
18
|
+
*/
|
|
19
|
+
publishableKey?: string;
|
|
12
20
|
/** Override the base URL (defaults to https://www.cstar.help). */
|
|
13
21
|
baseUrl?: string;
|
|
14
22
|
}
|
|
@@ -193,6 +201,9 @@ interface CommunityPostDetail {
|
|
|
193
201
|
declare class CommunityClient {
|
|
194
202
|
private readonly baseUrl;
|
|
195
203
|
private readonly teamSlug;
|
|
204
|
+
private readonly publishableKey;
|
|
205
|
+
/** Resolved mode based on the publishable-key prefix (`pk_test_*` => `test`). */
|
|
206
|
+
readonly mode: 'live' | 'test';
|
|
196
207
|
private sessionToken;
|
|
197
208
|
private teamId;
|
|
198
209
|
constructor(config: CommunityConfig);
|
|
@@ -9,6 +9,14 @@ interface CommunityAttachment {
|
|
|
9
9
|
interface CommunityConfig {
|
|
10
10
|
/** Team slug (e.g., 'acme'). Identifies the community to query. */
|
|
11
11
|
teamSlug: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional publishable key (`pk_test_*` or `pk_live_*`). When provided,
|
|
14
|
+
* the client switches data scope to match the key's mode (test vs live).
|
|
15
|
+
* Without a key, defaults to live — backwards-compatible with existing
|
|
16
|
+
* widget integrations. See `LibraryConfig.publishableKey` for the full
|
|
17
|
+
* test/live story.
|
|
18
|
+
*/
|
|
19
|
+
publishableKey?: string;
|
|
12
20
|
/** Override the base URL (defaults to https://www.cstar.help). */
|
|
13
21
|
baseUrl?: string;
|
|
14
22
|
}
|
|
@@ -193,6 +201,9 @@ interface CommunityPostDetail {
|
|
|
193
201
|
declare class CommunityClient {
|
|
194
202
|
private readonly baseUrl;
|
|
195
203
|
private readonly teamSlug;
|
|
204
|
+
private readonly publishableKey;
|
|
205
|
+
/** Resolved mode based on the publishable-key prefix (`pk_test_*` => `test`). */
|
|
206
|
+
readonly mode: 'live' | 'test';
|
|
196
207
|
private sessionToken;
|
|
197
208
|
private teamId;
|
|
198
209
|
constructor(config: CommunityConfig);
|
package/dist/community/index.js
CHANGED
|
@@ -1,3 +1,216 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ErrorType = {
|
|
3
|
+
AUTHENTICATION_ERROR: "authentication_error",
|
|
4
|
+
PERMISSION_ERROR: "permission_error",
|
|
5
|
+
INVALID_REQUEST_ERROR: "invalid_request_error",
|
|
6
|
+
NOT_FOUND_ERROR: "not_found_error",
|
|
7
|
+
CONFLICT_ERROR: "conflict_error",
|
|
8
|
+
RATE_LIMIT_ERROR: "rate_limit_error",
|
|
9
|
+
FEATURE_NOT_CONFIGURED: "feature_not_configured",
|
|
10
|
+
API_ERROR: "api_error",
|
|
11
|
+
SERVER_ERROR: "server_error"
|
|
12
|
+
};
|
|
13
|
+
var DEFAULT_DOC_URL = "https://cstar.help/developers/api/errors";
|
|
14
|
+
function normalizeArgs(messageOrStatus, maybeBody, defaults) {
|
|
15
|
+
if (typeof messageOrStatus === "string") {
|
|
16
|
+
return {
|
|
17
|
+
statusCode: defaults?.code === "rate_limit_error" ? 429 : 0,
|
|
18
|
+
body: {
|
|
19
|
+
type: defaults?.type ?? ErrorType.API_ERROR,
|
|
20
|
+
code: defaults?.code ?? "sdk_error",
|
|
21
|
+
message: messageOrStatus,
|
|
22
|
+
doc_url: defaults?.doc_url ?? DEFAULT_DOC_URL,
|
|
23
|
+
...defaults?.feature ? { feature: defaults.feature } : {},
|
|
24
|
+
...defaults?.enable_url ? { enable_url: defaults.enable_url } : {}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
statusCode: messageOrStatus,
|
|
30
|
+
body: maybeBody ?? {
|
|
31
|
+
type: defaults?.type ?? ErrorType.API_ERROR,
|
|
32
|
+
code: defaults?.code ?? "unknown_error",
|
|
33
|
+
message: defaults?.message ?? `Request failed with status ${messageOrStatus}`,
|
|
34
|
+
doc_url: defaults?.doc_url ?? DEFAULT_DOC_URL
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
var CStarError = class extends Error {
|
|
39
|
+
constructor(messageOrStatus, body) {
|
|
40
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body);
|
|
41
|
+
super(resolved.message);
|
|
42
|
+
this.name = "CStarError";
|
|
43
|
+
this.type = resolved.type;
|
|
44
|
+
this.code = resolved.code;
|
|
45
|
+
this.param = resolved.param;
|
|
46
|
+
this.docUrl = resolved.doc_url;
|
|
47
|
+
this.requestId = resolved.request_id;
|
|
48
|
+
this.statusCode = statusCode;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var CStarAuthenticationError = class extends CStarError {
|
|
52
|
+
constructor(messageOrStatus, body) {
|
|
53
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
54
|
+
type: ErrorType.AUTHENTICATION_ERROR,
|
|
55
|
+
code: "authentication_failed",
|
|
56
|
+
doc_url: `${DEFAULT_DOC_URL}#authentication-error`
|
|
57
|
+
});
|
|
58
|
+
super(statusCode, resolved);
|
|
59
|
+
this.name = "CStarAuthenticationError";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var CStarRateLimitError = class extends CStarError {
|
|
63
|
+
constructor(messageOrStatus, body, retryAfter) {
|
|
64
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
65
|
+
type: ErrorType.RATE_LIMIT_ERROR,
|
|
66
|
+
code: "rate_limit_exceeded",
|
|
67
|
+
doc_url: `${DEFAULT_DOC_URL}#rate-limit-error`
|
|
68
|
+
});
|
|
69
|
+
super(statusCode === 0 ? 429 : statusCode, resolved);
|
|
70
|
+
this.name = "CStarRateLimitError";
|
|
71
|
+
this.retryAfter = retryAfter ?? 60;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var CStarNotFoundError = class extends CStarError {
|
|
75
|
+
constructor(messageOrStatus, body) {
|
|
76
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
77
|
+
type: ErrorType.NOT_FOUND_ERROR,
|
|
78
|
+
code: "resource_not_found",
|
|
79
|
+
doc_url: `${DEFAULT_DOC_URL}#not-found-error`
|
|
80
|
+
});
|
|
81
|
+
super(statusCode, resolved);
|
|
82
|
+
this.name = "CStarNotFoundError";
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var CStarValidationError = class extends CStarError {
|
|
86
|
+
constructor(messageOrStatus, body) {
|
|
87
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
88
|
+
type: ErrorType.INVALID_REQUEST_ERROR,
|
|
89
|
+
code: "validation_error",
|
|
90
|
+
doc_url: `${DEFAULT_DOC_URL}#validation-error`
|
|
91
|
+
});
|
|
92
|
+
super(statusCode, resolved);
|
|
93
|
+
this.name = "CStarValidationError";
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var CStarPermissionError = class extends CStarError {
|
|
97
|
+
constructor(messageOrStatus, body) {
|
|
98
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
99
|
+
type: ErrorType.PERMISSION_ERROR,
|
|
100
|
+
code: "permission_denied",
|
|
101
|
+
doc_url: `${DEFAULT_DOC_URL}#permission-error`
|
|
102
|
+
});
|
|
103
|
+
super(statusCode, resolved);
|
|
104
|
+
this.name = "CStarPermissionError";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var CStarConflictError = class extends CStarError {
|
|
108
|
+
constructor(messageOrStatus, body) {
|
|
109
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
110
|
+
type: ErrorType.CONFLICT_ERROR,
|
|
111
|
+
code: "conflict",
|
|
112
|
+
doc_url: `${DEFAULT_DOC_URL}#conflict-error`
|
|
113
|
+
});
|
|
114
|
+
super(statusCode, resolved);
|
|
115
|
+
this.name = "CStarConflictError";
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
var CStarServerError = class extends CStarError {
|
|
119
|
+
constructor(messageOrStatus, body) {
|
|
120
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
121
|
+
type: ErrorType.SERVER_ERROR,
|
|
122
|
+
code: "server_error",
|
|
123
|
+
doc_url: `${DEFAULT_DOC_URL}#server-error`
|
|
124
|
+
});
|
|
125
|
+
super(statusCode, resolved);
|
|
126
|
+
this.name = "CStarServerError";
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var CStarFeatureDisabledError = class extends CStarError {
|
|
130
|
+
constructor(messageOrStatus, body) {
|
|
131
|
+
const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
|
|
132
|
+
type: ErrorType.FEATURE_NOT_CONFIGURED,
|
|
133
|
+
code: "feature_not_configured",
|
|
134
|
+
doc_url: `${DEFAULT_DOC_URL}#feature-not-configured`
|
|
135
|
+
});
|
|
136
|
+
super(statusCode, resolved);
|
|
137
|
+
this.name = "CStarFeatureDisabledError";
|
|
138
|
+
this.feature = resolved.feature ?? "unknown";
|
|
139
|
+
this.enableUrl = resolved.enable_url ?? "";
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
function parsePublicError(status, body, fallbackMessage) {
|
|
143
|
+
const obj = body && typeof body === "object" ? body : null;
|
|
144
|
+
const errVal = obj?.error;
|
|
145
|
+
let message = fallbackMessage;
|
|
146
|
+
let structured = null;
|
|
147
|
+
if (typeof errVal === "string") {
|
|
148
|
+
message = errVal;
|
|
149
|
+
} else if (errVal && typeof errVal === "object") {
|
|
150
|
+
const e = errVal;
|
|
151
|
+
if (typeof e.message === "string") message = e.message;
|
|
152
|
+
structured = {
|
|
153
|
+
type: typeof e.type === "string" ? e.type : ErrorType.API_ERROR,
|
|
154
|
+
code: typeof e.code === "string" ? e.code : "api_error",
|
|
155
|
+
message,
|
|
156
|
+
param: typeof e.param === "string" ? e.param : void 0,
|
|
157
|
+
doc_url: typeof e.doc_url === "string" ? e.doc_url : DEFAULT_DOC_URL,
|
|
158
|
+
request_id: typeof e.request_id === "string" ? e.request_id : void 0,
|
|
159
|
+
feature: typeof e.feature === "string" ? e.feature : void 0,
|
|
160
|
+
enable_url: typeof e.enable_url === "string" ? e.enable_url : void 0
|
|
161
|
+
};
|
|
162
|
+
} else if (typeof obj?.message === "string") {
|
|
163
|
+
message = obj.message;
|
|
164
|
+
}
|
|
165
|
+
const errorBody = structured ?? {
|
|
166
|
+
type: ErrorType.API_ERROR,
|
|
167
|
+
code: status >= 500 ? "server_error" : "request_failed",
|
|
168
|
+
message,
|
|
169
|
+
doc_url: DEFAULT_DOC_URL
|
|
170
|
+
};
|
|
171
|
+
return parseError(status, { error: errorBody });
|
|
172
|
+
}
|
|
173
|
+
var STATUS_TO_CLASS = {
|
|
174
|
+
400: CStarValidationError,
|
|
175
|
+
401: CStarAuthenticationError,
|
|
176
|
+
403: CStarPermissionError,
|
|
177
|
+
404: CStarNotFoundError,
|
|
178
|
+
409: CStarConflictError,
|
|
179
|
+
422: CStarValidationError,
|
|
180
|
+
429: CStarRateLimitError
|
|
181
|
+
};
|
|
182
|
+
var TYPE_TO_CLASS = {
|
|
183
|
+
[ErrorType.AUTHENTICATION_ERROR]: CStarAuthenticationError,
|
|
184
|
+
[ErrorType.PERMISSION_ERROR]: CStarPermissionError,
|
|
185
|
+
[ErrorType.RATE_LIMIT_ERROR]: CStarRateLimitError,
|
|
186
|
+
[ErrorType.NOT_FOUND_ERROR]: CStarNotFoundError,
|
|
187
|
+
[ErrorType.INVALID_REQUEST_ERROR]: CStarValidationError,
|
|
188
|
+
[ErrorType.CONFLICT_ERROR]: CStarConflictError,
|
|
189
|
+
[ErrorType.SERVER_ERROR]: CStarServerError,
|
|
190
|
+
[ErrorType.FEATURE_NOT_CONFIGURED]: CStarFeatureDisabledError
|
|
191
|
+
};
|
|
192
|
+
function parseError(statusCode, body, retryAfter) {
|
|
193
|
+
const errorBody = body?.error ?? {
|
|
194
|
+
type: ErrorType.API_ERROR,
|
|
195
|
+
code: "unknown_error",
|
|
196
|
+
message: `Request failed with status ${statusCode}`,
|
|
197
|
+
doc_url: DEFAULT_DOC_URL
|
|
198
|
+
};
|
|
199
|
+
if (statusCode === 429) {
|
|
200
|
+
return new CStarRateLimitError(statusCode, errorBody, retryAfter ?? 60);
|
|
201
|
+
}
|
|
202
|
+
const StatusCls = STATUS_TO_CLASS[statusCode];
|
|
203
|
+
if (StatusCls) {
|
|
204
|
+
return new StatusCls(statusCode, errorBody);
|
|
205
|
+
}
|
|
206
|
+
const TypeCls = TYPE_TO_CLASS[errorBody.type];
|
|
207
|
+
if (TypeCls) {
|
|
208
|
+
return new TypeCls(statusCode, errorBody);
|
|
209
|
+
}
|
|
210
|
+
if (statusCode >= 500) return new CStarServerError(statusCode, errorBody);
|
|
211
|
+
return new CStarError(statusCode, errorBody);
|
|
212
|
+
}
|
|
213
|
+
|
|
1
214
|
// src/community/index.ts
|
|
2
215
|
var DEFAULT_BASE_URL = "https://www.cstar.help";
|
|
3
216
|
var CommunityClient = class {
|
|
@@ -6,6 +219,13 @@ var CommunityClient = class {
|
|
|
6
219
|
this.teamId = null;
|
|
7
220
|
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
8
221
|
this.teamSlug = config.teamSlug;
|
|
222
|
+
this.publishableKey = config.publishableKey ?? null;
|
|
223
|
+
this.mode = this.publishableKey?.startsWith("pk_test_") ? "test" : "live";
|
|
224
|
+
if (this.publishableKey && !/^pk_(test|live)_/.test(this.publishableKey)) {
|
|
225
|
+
throw new Error(
|
|
226
|
+
"[cStar] CommunityClient: publishableKey must start with `pk_test_` or `pk_live_`. Secret keys (`sk_*`) cannot be used in browser/anonymous contexts."
|
|
227
|
+
);
|
|
228
|
+
}
|
|
9
229
|
}
|
|
10
230
|
/**
|
|
11
231
|
* Set a session token from identity verification.
|
|
@@ -222,13 +442,13 @@ var CommunityClient = class {
|
|
|
222
442
|
*/
|
|
223
443
|
resolveTeamId() {
|
|
224
444
|
if (this.teamId) return this.teamId;
|
|
225
|
-
throw new
|
|
445
|
+
throw new CStarValidationError(
|
|
226
446
|
"Team ID is required for authenticated operations. Pass it via setSessionToken(token, teamId) or use ChatClient.identify() which provides it automatically."
|
|
227
447
|
);
|
|
228
448
|
}
|
|
229
449
|
async authenticatedFetch(path, options) {
|
|
230
450
|
if (!this.sessionToken) {
|
|
231
|
-
throw new
|
|
451
|
+
throw new CStarValidationError(
|
|
232
452
|
"Session token required. Call setSessionToken() or use ChatClient.identify() first."
|
|
233
453
|
);
|
|
234
454
|
}
|
|
@@ -251,9 +471,8 @@ var CommunityClient = class {
|
|
|
251
471
|
body: options.body ? JSON.stringify(options.body) : void 0
|
|
252
472
|
});
|
|
253
473
|
if (!response.ok) {
|
|
254
|
-
const errorBody = await response.json().catch(() =>
|
|
255
|
-
|
|
256
|
-
throw new Error(message);
|
|
474
|
+
const errorBody = await response.json().catch(() => null);
|
|
475
|
+
throw parsePublicError(response.status, errorBody, `Community API error: ${response.status}`);
|
|
257
476
|
}
|
|
258
477
|
return response.json();
|
|
259
478
|
}
|
|
@@ -267,14 +486,17 @@ var CommunityClient = class {
|
|
|
267
486
|
const qs = params.toString();
|
|
268
487
|
if (qs) url += `?${qs}`;
|
|
269
488
|
}
|
|
489
|
+
const headers = { "Content-Type": "application/json" };
|
|
490
|
+
if (this.publishableKey) {
|
|
491
|
+
headers["Authorization"] = `Bearer ${this.publishableKey}`;
|
|
492
|
+
}
|
|
270
493
|
const response = await globalThis.fetch(url, {
|
|
271
494
|
method: "GET",
|
|
272
|
-
headers
|
|
495
|
+
headers
|
|
273
496
|
});
|
|
274
497
|
if (!response.ok) {
|
|
275
|
-
const errorBody = await response.json().catch(() =>
|
|
276
|
-
|
|
277
|
-
throw new Error(message);
|
|
498
|
+
const errorBody = await response.json().catch(() => null);
|
|
499
|
+
throw parsePublicError(response.status, errorBody, `Community API error: ${response.status}`);
|
|
278
500
|
}
|
|
279
501
|
return response.json();
|
|
280
502
|
}
|