@cstar.help/js 0.12.1 → 0.14.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 +84 -29
- package/dist/chat/index.d.cts +72 -27
- package/dist/chat/index.d.ts +72 -27
- package/dist/chat/index.js +84 -29
- 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 +309 -74
- package/dist/index.d.cts +3287 -0
- package/dist/index.d.ts +3287 -0
- package/dist/index.js +308 -74
- 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 +220 -7
- package/dist/quickhelp/index.d.cts +37 -4
- package/dist/quickhelp/index.d.ts +37 -4
- package/dist/quickhelp/index.js +218 -7
- 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
package/dist/quickhelp/index.js
CHANGED
|
@@ -1,12 +1,211 @@
|
|
|
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
|
+
var TYPE_TO_CLASS = {
|
|
143
|
+
[ErrorType.AUTHENTICATION_ERROR]: CStarAuthenticationError,
|
|
144
|
+
[ErrorType.PERMISSION_ERROR]: CStarPermissionError,
|
|
145
|
+
[ErrorType.RATE_LIMIT_ERROR]: CStarRateLimitError,
|
|
146
|
+
[ErrorType.NOT_FOUND_ERROR]: CStarNotFoundError,
|
|
147
|
+
[ErrorType.INVALID_REQUEST_ERROR]: CStarValidationError,
|
|
148
|
+
[ErrorType.CONFLICT_ERROR]: CStarConflictError,
|
|
149
|
+
[ErrorType.SERVER_ERROR]: CStarServerError,
|
|
150
|
+
[ErrorType.FEATURE_NOT_CONFIGURED]: CStarFeatureDisabledError
|
|
151
|
+
};
|
|
152
|
+
|
|
1
153
|
// src/quickhelp/index.ts
|
|
2
154
|
var DEFAULT_BASE_URL = "https://www.cstar.help";
|
|
3
155
|
var QuickHelpClient = class {
|
|
4
156
|
constructor(config) {
|
|
5
|
-
|
|
6
|
-
|
|
157
|
+
this.resolveTeamIdPromise = null;
|
|
158
|
+
if (!config?.teamId && !config?.teamSlug) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
'QuickHelpClient: either `teamId` or `teamSlug` is required. Pass `teamSlug` (e.g. "acme") for the easiest setup.'
|
|
161
|
+
);
|
|
7
162
|
}
|
|
8
163
|
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
9
|
-
this.teamId = config.teamId;
|
|
164
|
+
this.teamId = config.teamId ?? null;
|
|
165
|
+
this.teamSlug = config.teamSlug ?? null;
|
|
166
|
+
this.publishableKey = config.publishableKey ?? null;
|
|
167
|
+
this.mode = this.publishableKey?.startsWith("pk_test_") ? "test" : "live";
|
|
168
|
+
if (this.publishableKey && !/^pk_(test|live)_/.test(this.publishableKey)) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
"[cStar] QuickHelpClient: publishableKey must start with `pk_test_` or `pk_live_`. Secret keys (`sk_*`) cannot be used in browser/anonymous contexts."
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
authHeaders() {
|
|
175
|
+
return this.publishableKey ? { Authorization: `Bearer ${this.publishableKey}` } : {};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Resolve `teamSlug` → `teamId` lazily on the first call that needs it.
|
|
179
|
+
* Cached for the life of the client. NEW-v2-05.
|
|
180
|
+
*/
|
|
181
|
+
async resolveTeamId() {
|
|
182
|
+
if (this.teamId) return this.teamId;
|
|
183
|
+
if (!this.teamSlug) throw new Error("QuickHelpClient: no teamId or teamSlug set");
|
|
184
|
+
if (this.resolveTeamIdPromise) return this.resolveTeamIdPromise;
|
|
185
|
+
this.resolveTeamIdPromise = (async () => {
|
|
186
|
+
const url = `${this.baseUrl}/api/widget/team-by-slug?teamSlug=${encodeURIComponent(this.teamSlug)}`;
|
|
187
|
+
const res = await globalThis.fetch(url, { method: "GET", headers: this.authHeaders() });
|
|
188
|
+
if (!res.ok) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`QuickHelpClient: could not resolve teamSlug "${this.teamSlug}" (HTTP ${res.status}).`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const body = await res.json();
|
|
194
|
+
const id = body?.data?.teamId;
|
|
195
|
+
if (!id) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`QuickHelpClient: lookup for teamSlug "${this.teamSlug}" returned no teamId.`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
this.teamId = id;
|
|
201
|
+
return id;
|
|
202
|
+
})();
|
|
203
|
+
try {
|
|
204
|
+
return await this.resolveTeamIdPromise;
|
|
205
|
+
} catch (err) {
|
|
206
|
+
this.resolveTeamIdPromise = null;
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
10
209
|
}
|
|
11
210
|
/**
|
|
12
211
|
* Fetch the sanitized public config (title, subtitle, placeholder,
|
|
@@ -16,8 +215,9 @@ var QuickHelpClient = class {
|
|
|
16
215
|
* Returns `null` if Quick Help is disabled on the team (404).
|
|
17
216
|
*/
|
|
18
217
|
async config() {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
218
|
+
const teamId = await this.resolveTeamId();
|
|
219
|
+
const url = `${this.baseUrl}/api/quickhelp/config/${encodeURIComponent(teamId)}`;
|
|
220
|
+
const res = await globalThis.fetch(url, { method: "GET", headers: this.authHeaders() });
|
|
21
221
|
if (res.status === 404) return null;
|
|
22
222
|
if (!res.ok) {
|
|
23
223
|
const body2 = await res.json().catch(() => null);
|
|
@@ -33,18 +233,29 @@ var QuickHelpClient = class {
|
|
|
33
233
|
* property set from the response body.
|
|
34
234
|
*/
|
|
35
235
|
async ask(params) {
|
|
236
|
+
const teamId = await this.resolveTeamId();
|
|
36
237
|
const url = `${this.baseUrl}/api/quickhelp/ask`;
|
|
37
238
|
const res = await globalThis.fetch(url, {
|
|
38
239
|
method: "POST",
|
|
39
|
-
headers: { "Content-Type": "application/json" },
|
|
240
|
+
headers: { "Content-Type": "application/json", ...this.authHeaders() },
|
|
40
241
|
body: JSON.stringify({
|
|
41
|
-
team_id:
|
|
242
|
+
team_id: teamId,
|
|
42
243
|
session_id: params.sessionId ?? null,
|
|
43
244
|
question: params.question
|
|
44
245
|
})
|
|
45
246
|
});
|
|
46
247
|
const body = await res.json().catch(() => null);
|
|
47
248
|
if (!res.ok || !body?.success || !body.data) {
|
|
249
|
+
if (res.status === 503 || body?.error?.code === "feature_not_configured") {
|
|
250
|
+
throw new CStarFeatureDisabledError(res.status, {
|
|
251
|
+
type: "feature_not_configured",
|
|
252
|
+
code: "feature_not_configured",
|
|
253
|
+
message: body?.error?.message ?? "Quick Help is not available on this team. Enable an AI Agent (Settings \u2192 AI Agents) and configure Quick Help (Settings \u2192 Quick Help) before calling .ask().",
|
|
254
|
+
doc_url: "https://cstar.help/developers/api/errors#feature-not-configured",
|
|
255
|
+
feature: "quickHelp",
|
|
256
|
+
enable_url: `${this.baseUrl}/team/${encodeURIComponent(teamId)}/settings?section=quickHelp`
|
|
257
|
+
});
|
|
258
|
+
}
|
|
48
259
|
const message = body?.error?.message ?? `Quick Help ask failed: ${res.status}`;
|
|
49
260
|
const err = new QuickHelpError(message, {
|
|
50
261
|
status: res.status,
|
package/dist/webhook/index.cjs
CHANGED
|
@@ -21,9 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var webhook_exports = {};
|
|
22
22
|
__export(webhook_exports, {
|
|
23
23
|
WebhookSignatureVerificationError: () => WebhookSignatureVerificationError,
|
|
24
|
-
constructEvent: () => constructEvent,
|
|
25
24
|
constructEventAsync: () => constructEventAsync,
|
|
26
|
-
verifySignature: () => verifySignature,
|
|
27
25
|
verifySignatureAsync: () => verifySignatureAsync
|
|
28
26
|
});
|
|
29
27
|
module.exports = __toCommonJS(webhook_exports);
|
|
@@ -33,14 +31,6 @@ var WebhookSignatureVerificationError = class extends Error {
|
|
|
33
31
|
this.name = "WebhookSignatureVerificationError";
|
|
34
32
|
}
|
|
35
33
|
};
|
|
36
|
-
function constructEvent(rawBody, signature, secret) {
|
|
37
|
-
if (!verifySignature(rawBody, signature, secret)) {
|
|
38
|
-
throw new WebhookSignatureVerificationError(
|
|
39
|
-
"Webhook signature verification failed. Ensure you are using the raw request body and the correct endpoint secret."
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
return JSON.parse(rawBody);
|
|
43
|
-
}
|
|
44
34
|
async function constructEventAsync(rawBody, signature, secret) {
|
|
45
35
|
const valid = await verifySignatureAsync(rawBody, signature, secret);
|
|
46
36
|
if (!valid) {
|
|
@@ -50,12 +40,6 @@ async function constructEventAsync(rawBody, signature, secret) {
|
|
|
50
40
|
}
|
|
51
41
|
return JSON.parse(rawBody);
|
|
52
42
|
}
|
|
53
|
-
function verifySignature(rawBody, signature, secret) {
|
|
54
|
-
const crypto2 = require("crypto");
|
|
55
|
-
const expected = "sha256=" + crypto2.createHmac("sha256", secret).update(rawBody).digest("hex");
|
|
56
|
-
if (signature.length !== expected.length) return false;
|
|
57
|
-
return crypto2.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
|
|
58
|
-
}
|
|
59
43
|
async function verifySignatureAsync(rawBody, signature, secret) {
|
|
60
44
|
const encoder = new TextEncoder();
|
|
61
45
|
const key = await crypto.subtle.importKey(
|
|
@@ -77,8 +61,6 @@ async function verifySignatureAsync(rawBody, signature, secret) {
|
|
|
77
61
|
// Annotate the CommonJS export names for ESM import in node:
|
|
78
62
|
0 && (module.exports = {
|
|
79
63
|
WebhookSignatureVerificationError,
|
|
80
|
-
constructEvent,
|
|
81
64
|
constructEventAsync,
|
|
82
|
-
verifySignature,
|
|
83
65
|
verifySignatureAsync
|
|
84
66
|
});
|