@datacline/langos-sdk-node 0.2.0-alpha.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/CHANGELOG.md +63 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/dist/index.cjs +774 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +569 -0
- package/dist/index.d.ts +569 -0
- package/dist/index.mjs +758 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
type CandidateStatus = 'invited' | 'started' | 'completed' | 'cancelled' | 'error';
|
|
2
|
+
type SessionStatus = 'pending' | 'provisioning' | 'active' | 'submitted' | 'completed' | 'failed' | 'expired';
|
|
3
|
+
interface Assessment {
|
|
4
|
+
id: string;
|
|
5
|
+
object: 'assessment';
|
|
6
|
+
name: string;
|
|
7
|
+
description: string | null;
|
|
8
|
+
challengeCount: number;
|
|
9
|
+
createdAt: string;
|
|
10
|
+
updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
interface Candidate {
|
|
13
|
+
id: string;
|
|
14
|
+
object: 'candidate';
|
|
15
|
+
email: string;
|
|
16
|
+
name: string | null;
|
|
17
|
+
assessmentId: string;
|
|
18
|
+
externalId: string | null;
|
|
19
|
+
status: CandidateStatus;
|
|
20
|
+
invitationUrl: string | null;
|
|
21
|
+
invitedAt: string | null;
|
|
22
|
+
startedAt: string | null;
|
|
23
|
+
completedAt: string | null;
|
|
24
|
+
cancelledAt: string | null;
|
|
25
|
+
expiresAt: string | null;
|
|
26
|
+
latestSessionId: string | null;
|
|
27
|
+
score: number | null;
|
|
28
|
+
metadata: Record<string, unknown> | null;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
}
|
|
32
|
+
interface SessionSubmission {
|
|
33
|
+
language: string | null;
|
|
34
|
+
finalCode: string | null;
|
|
35
|
+
diff: string | null;
|
|
36
|
+
commitSha: string | null;
|
|
37
|
+
previewUrl: string | null;
|
|
38
|
+
}
|
|
39
|
+
interface SessionInsights {
|
|
40
|
+
aiUsagePercent: number | null;
|
|
41
|
+
testPassRate: number | null;
|
|
42
|
+
codeQuality: Record<string, unknown> | null;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
interface SessionFeedback {
|
|
46
|
+
notes: string | null;
|
|
47
|
+
problemSolvingScore: number | null;
|
|
48
|
+
codeQualityScore: number | null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Typed activity counters surfaced from `session_analytics`. All counts are
|
|
52
|
+
* non-negative integers and default to `0` when no events have been recorded
|
|
53
|
+
* yet (`null` is never returned). Lets partner UIs render "candidate spent
|
|
54
|
+
* X minutes coding, ran tests Y times" without parsing the opaque `insights`
|
|
55
|
+
* JSON blob.
|
|
56
|
+
*/
|
|
57
|
+
interface SessionAnalytics {
|
|
58
|
+
editorEventCount: number;
|
|
59
|
+
runEventCount: number;
|
|
60
|
+
testEventCount: number;
|
|
61
|
+
aiEventCount: number;
|
|
62
|
+
pasteEventCount: number;
|
|
63
|
+
activeSeconds: number;
|
|
64
|
+
idleSeconds: number;
|
|
65
|
+
codingSeconds: number;
|
|
66
|
+
}
|
|
67
|
+
interface Session {
|
|
68
|
+
id: string;
|
|
69
|
+
object: 'session';
|
|
70
|
+
candidateId: string;
|
|
71
|
+
assessmentId: string;
|
|
72
|
+
status: SessionStatus;
|
|
73
|
+
attempt: number;
|
|
74
|
+
startedAt: string | null;
|
|
75
|
+
completedAt: string | null;
|
|
76
|
+
durationSeconds: number | null;
|
|
77
|
+
score: number | null;
|
|
78
|
+
passed: boolean | null;
|
|
79
|
+
/**
|
|
80
|
+
* Partner-readable HTML report URL. Click-through opens a server-rendered
|
|
81
|
+
* report page for the recruiter (no Langos login required). `null` when the
|
|
82
|
+
* session has no calculated score yet.
|
|
83
|
+
*/
|
|
84
|
+
reportUrl: string | null;
|
|
85
|
+
submission: SessionSubmission | null;
|
|
86
|
+
/** Typed activity stats; companion to the opaque `insights` blob. */
|
|
87
|
+
analytics: SessionAnalytics;
|
|
88
|
+
insights: SessionInsights | null;
|
|
89
|
+
feedback: SessionFeedback | null;
|
|
90
|
+
createdAt: string;
|
|
91
|
+
updatedAt: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Canonical Langos plan tiers. Mirrors the public pricing page at
|
|
95
|
+
* https://www.langos.io/#pricing — the source of truth lives in the server's
|
|
96
|
+
* `plan-features.json`. No aliases, no synonyms; if a partner sees an unknown
|
|
97
|
+
* value here it's a deploy mismatch, not a plan tier we forgot to add.
|
|
98
|
+
*
|
|
99
|
+
* Note: `mid_tier` is the canonical key. There is no `mid` shorthand.
|
|
100
|
+
*/
|
|
101
|
+
type PlanTier = 'free' | 'starter' | 'mid_tier' | 'growth' | 'custom';
|
|
102
|
+
/**
|
|
103
|
+
* Account info for the Langos company that owns the calling integration.
|
|
104
|
+
* Returned by `client.account.retrieve()`.
|
|
105
|
+
*/
|
|
106
|
+
interface Account {
|
|
107
|
+
id: string;
|
|
108
|
+
object: 'account';
|
|
109
|
+
name: string;
|
|
110
|
+
/**
|
|
111
|
+
* Immutable, auto-assigned URL slug for this company. Stable across the
|
|
112
|
+
* company's lifetime; safe to embed in your UI/links. Server-generated on
|
|
113
|
+
* signup — partners cannot set it.
|
|
114
|
+
*/
|
|
115
|
+
slug: string;
|
|
116
|
+
/**
|
|
117
|
+
* The company's current plan tier. One of `free | starter | mid_tier |
|
|
118
|
+
* growth | custom`. Use this to gate UI on `planCaps` rather than hardcoding
|
|
119
|
+
* tier strings.
|
|
120
|
+
*/
|
|
121
|
+
planTier: PlanTier;
|
|
122
|
+
billingCycle: string;
|
|
123
|
+
status: string;
|
|
124
|
+
sessionsUsed: number;
|
|
125
|
+
/** `null` on unlimited plans (e.g. `custom`). */
|
|
126
|
+
sessionsLimit: number | null;
|
|
127
|
+
/** `null` on unlimited plans (e.g. `custom`). */
|
|
128
|
+
sessionsRemaining: number | null;
|
|
129
|
+
trialEndsAt: string | null;
|
|
130
|
+
/**
|
|
131
|
+
* Top-level feature flags derived from the plan-features matrix and runtime
|
|
132
|
+
* configuration. Each flag answers "can this account use feature X right now?"
|
|
133
|
+
*
|
|
134
|
+
* - `webIdeEnabled` — true when the plan includes the web IDE.
|
|
135
|
+
* - `replayEnabled` — true when the plan includes session replay.
|
|
136
|
+
* - `aiAssistanceEnabled` — true ONLY when the plan includes AI assistance
|
|
137
|
+
* AND an Anthropic API key is configured for the company. (Tier alone
|
|
138
|
+
* isn't enough; AI is gated by tier but inert without a key.)
|
|
139
|
+
*/
|
|
140
|
+
features: AccountFeatures;
|
|
141
|
+
/**
|
|
142
|
+
* What the company's plan tier *includes*, mirrored from the public pricing
|
|
143
|
+
* page. Read-only — partners use this to render upgrade prompts (e.g. "your
|
|
144
|
+
* plan caps at 30 sessions/mo, upgrade for unlimited"). `null` when the
|
|
145
|
+
* company is on a legacy or unknown tier.
|
|
146
|
+
*/
|
|
147
|
+
planCaps: PlanCaps | null;
|
|
148
|
+
integration: AccountIntegration;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Plan capability block, mirrored from `plan-features.json` on the server.
|
|
152
|
+
* The shape mirrors the public pricing page: render upgrade prompts from this
|
|
153
|
+
* rather than hardcoding plan limits in your UI.
|
|
154
|
+
*/
|
|
155
|
+
interface PlanCaps {
|
|
156
|
+
label: string;
|
|
157
|
+
priceMonthly: number | null;
|
|
158
|
+
/** Billing cadence. Currently always `'monthly'`. */
|
|
159
|
+
billing: 'monthly';
|
|
160
|
+
/** Display currency. Currently always `'USD'`. */
|
|
161
|
+
currency: 'USD';
|
|
162
|
+
/** Sessions per billing period. `null` on unlimited tiers. */
|
|
163
|
+
sessionLimit: number | null;
|
|
164
|
+
/** Library challenges available out of the box. `null` on unlimited tiers. */
|
|
165
|
+
readyMadeChallenges: number | null;
|
|
166
|
+
/** Max custom challenges the company can author. `null` on unlimited tiers. */
|
|
167
|
+
customChallengesMax: number | null;
|
|
168
|
+
/**
|
|
169
|
+
* Raw feature matrix from plan-features.json — keys like `web_ide`,
|
|
170
|
+
* `replay`, `ai_assistance`, `sso`, etc. Prefer the typed `Account.features`
|
|
171
|
+
* for the small set of flags surfaced at top level.
|
|
172
|
+
*/
|
|
173
|
+
features: Record<string, boolean>;
|
|
174
|
+
support: string;
|
|
175
|
+
popular: boolean;
|
|
176
|
+
contactSales: boolean;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Top-level feature flags, derived from `plan_caps.features` plus runtime
|
|
180
|
+
* configuration (see `aiAssistanceEnabled`).
|
|
181
|
+
*/
|
|
182
|
+
interface AccountFeatures {
|
|
183
|
+
/** True when `plan_caps.features.web_ide` is true. */
|
|
184
|
+
webIdeEnabled: boolean;
|
|
185
|
+
/** True when `plan_caps.features.replay` is true. */
|
|
186
|
+
replayEnabled: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* True only when `plan_caps.features.ai_assistance` is true AND an
|
|
189
|
+
* Anthropic API key is configured for the company. Without the key, AI is
|
|
190
|
+
* gated by tier but would be inert at runtime.
|
|
191
|
+
*/
|
|
192
|
+
aiAssistanceEnabled: boolean;
|
|
193
|
+
}
|
|
194
|
+
interface AccountIntegration {
|
|
195
|
+
/**
|
|
196
|
+
* Which integration path issued the calling API key.
|
|
197
|
+
*
|
|
198
|
+
* - `"customer"` — this key was minted from the Langos dashboard and used
|
|
199
|
+
* directly via this SDK.
|
|
200
|
+
* - `"ashby"` (or another ATS slug) — Langos was wired through your ATS
|
|
201
|
+
* partner; the customer is operating Langos inside the partner's UI.
|
|
202
|
+
*
|
|
203
|
+
* Both paths surface the same `/v1/account` data and call the same API.
|
|
204
|
+
*/
|
|
205
|
+
provider: string;
|
|
206
|
+
apiKeyPrefix: string;
|
|
207
|
+
scopes: string[];
|
|
208
|
+
rateLimitPerMinute: number | null;
|
|
209
|
+
webhookUrl: string | null;
|
|
210
|
+
}
|
|
211
|
+
interface WebhookEndpoint {
|
|
212
|
+
object: 'webhook_endpoint';
|
|
213
|
+
webhookUrl: string | null;
|
|
214
|
+
/**
|
|
215
|
+
* The `whsec_…` signing secret. Only returned once, immediately after a
|
|
216
|
+
* `rotateSigningSecret: true` call. Subsequent reads return `null`.
|
|
217
|
+
*/
|
|
218
|
+
signingSecret: string | null;
|
|
219
|
+
}
|
|
220
|
+
interface WebhookEndpointParams {
|
|
221
|
+
/** Absolute http(s) URL, or `null` to disable outbound delivery. */
|
|
222
|
+
webhookUrl?: string | null;
|
|
223
|
+
/**
|
|
224
|
+
* Generate a fresh signing secret. The previous secret is overwritten
|
|
225
|
+
* and cannot be recovered — store the response value.
|
|
226
|
+
*/
|
|
227
|
+
rotateSigningSecret?: boolean;
|
|
228
|
+
}
|
|
229
|
+
interface CandidateCreateParams {
|
|
230
|
+
email: string;
|
|
231
|
+
assessmentId: string;
|
|
232
|
+
name?: string;
|
|
233
|
+
externalId?: string;
|
|
234
|
+
expiresAt?: string | Date;
|
|
235
|
+
metadata?: Record<string, unknown>;
|
|
236
|
+
}
|
|
237
|
+
interface ListParams {
|
|
238
|
+
limit?: number;
|
|
239
|
+
cursor?: string;
|
|
240
|
+
}
|
|
241
|
+
interface CandidateListParams extends ListParams {
|
|
242
|
+
status?: CandidateStatus;
|
|
243
|
+
assessmentId?: string;
|
|
244
|
+
}
|
|
245
|
+
interface AssessmentListParams extends ListParams {
|
|
246
|
+
}
|
|
247
|
+
interface SessionListParams extends ListParams {
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Per-call request options. Override SDK defaults (timeout, retries) for a
|
|
251
|
+
* single call, supply an `AbortSignal`, or attach extra headers.
|
|
252
|
+
*/
|
|
253
|
+
interface RequestOptions {
|
|
254
|
+
timeout?: number;
|
|
255
|
+
maxRetries?: number;
|
|
256
|
+
signal?: AbortSignal;
|
|
257
|
+
headers?: Record<string, string>;
|
|
258
|
+
idempotencyKey?: string;
|
|
259
|
+
}
|
|
260
|
+
interface Logger {
|
|
261
|
+
debug(obj: object, msg?: string): void;
|
|
262
|
+
info(obj: object, msg?: string): void;
|
|
263
|
+
warn(obj: object, msg?: string): void;
|
|
264
|
+
error(obj: object, msg?: string): void;
|
|
265
|
+
}
|
|
266
|
+
interface LangosOptions {
|
|
267
|
+
apiKey: string;
|
|
268
|
+
baseUrl?: string;
|
|
269
|
+
timeout?: number;
|
|
270
|
+
maxRetries?: number;
|
|
271
|
+
fetch?: typeof fetch;
|
|
272
|
+
logger?: Logger;
|
|
273
|
+
/** Free-form identifier appended to the User-Agent (e.g. "GreenhouseConnector/2.1.0"). */
|
|
274
|
+
appName?: string;
|
|
275
|
+
/** Disables outbound client telemetry header. */
|
|
276
|
+
telemetry?: boolean;
|
|
277
|
+
}
|
|
278
|
+
interface PageMeta {
|
|
279
|
+
hasMore: boolean;
|
|
280
|
+
nextCursor: string | null;
|
|
281
|
+
}
|
|
282
|
+
interface Page<T> extends PageMeta {
|
|
283
|
+
data: T[];
|
|
284
|
+
/** Fetches the next page. Returns null when `hasMore` is false. */
|
|
285
|
+
getNextPage: () => Promise<Page<T> | null>;
|
|
286
|
+
}
|
|
287
|
+
type AsyncIterablePage<T> = AsyncIterable<T> & Page<T>;
|
|
288
|
+
type WebhookEventType = 'session.submitted' | 'session.completed' | 'candidate.cancelled';
|
|
289
|
+
/**
|
|
290
|
+
* Discriminated union of webhook event payloads. Each `type` narrows `data` to
|
|
291
|
+
* the corresponding shape so partners can `switch (event.type)` and let the
|
|
292
|
+
* compiler enforce exhaustive handling. When the server adds new event types,
|
|
293
|
+
* surface them here in lockstep.
|
|
294
|
+
*/
|
|
295
|
+
type Event = SessionSubmittedEvent | SessionCompletedEvent | CandidateCancelledEvent;
|
|
296
|
+
interface BaseEvent<TType extends WebhookEventType, TData> {
|
|
297
|
+
id: string;
|
|
298
|
+
object: 'event';
|
|
299
|
+
type: TType;
|
|
300
|
+
created: string;
|
|
301
|
+
data: TData;
|
|
302
|
+
}
|
|
303
|
+
type SessionSubmittedEvent = BaseEvent<'session.submitted', Session>;
|
|
304
|
+
type SessionCompletedEvent = BaseEvent<'session.completed', Session>;
|
|
305
|
+
type CandidateCancelledEvent = BaseEvent<'candidate.cancelled', Candidate>;
|
|
306
|
+
interface WebhookEvent<T = unknown> {
|
|
307
|
+
id: string;
|
|
308
|
+
object: 'event';
|
|
309
|
+
type: WebhookEventType;
|
|
310
|
+
created: string;
|
|
311
|
+
data: T;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
interface ResolvedClientConfig {
|
|
315
|
+
apiKey: string;
|
|
316
|
+
baseUrl: string;
|
|
317
|
+
timeout: number;
|
|
318
|
+
maxRetries: number;
|
|
319
|
+
fetchImpl: typeof fetch;
|
|
320
|
+
logger: Logger;
|
|
321
|
+
appName: string | undefined;
|
|
322
|
+
telemetry: boolean;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
declare class APIResource {
|
|
326
|
+
protected readonly cfg: ResolvedClientConfig;
|
|
327
|
+
constructor(cfg: ResolvedClientConfig);
|
|
328
|
+
protected get<T>(path: string, query?: Record<string, string | number | undefined | null>, options?: RequestOptions): Promise<T>;
|
|
329
|
+
protected post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
330
|
+
protected delete<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
331
|
+
protected patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* `client.account` — read the company info that owns this integration, and
|
|
336
|
+
* manage the outbound webhook endpoint.
|
|
337
|
+
*
|
|
338
|
+
* Typical usage:
|
|
339
|
+
*
|
|
340
|
+
* ```ts
|
|
341
|
+
* const account = await client.account.retrieve();
|
|
342
|
+
* if (account.sessionsRemaining === 0) {
|
|
343
|
+
* showUpgradePrompt();
|
|
344
|
+
* }
|
|
345
|
+
*
|
|
346
|
+
* await client.account.setWebhookEndpoint({
|
|
347
|
+
* webhookUrl: 'https://greenhouse.example.com/webhooks/langos',
|
|
348
|
+
* rotateSigningSecret: true,
|
|
349
|
+
* });
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
declare class AccountResource extends APIResource {
|
|
353
|
+
/**
|
|
354
|
+
* Read the calling integration's account.
|
|
355
|
+
*
|
|
356
|
+
* Includes plan, quota, feature flags, and integration metadata
|
|
357
|
+
* (key prefix, scopes, rate limit, webhook URL).
|
|
358
|
+
*
|
|
359
|
+
* @returns {Promise<Account>}
|
|
360
|
+
*/
|
|
361
|
+
retrieve(options?: RequestOptions): Promise<Account>;
|
|
362
|
+
/**
|
|
363
|
+
* Set or clear the outbound webhook URL, and optionally rotate the signing
|
|
364
|
+
* secret.
|
|
365
|
+
*
|
|
366
|
+
* When `rotateSigningSecret: true`, the response includes the new secret in
|
|
367
|
+
* `signingSecret`. Store it — the secret cannot be re-fetched. Subsequent
|
|
368
|
+
* reads return `signingSecret: null`.
|
|
369
|
+
*
|
|
370
|
+
* @param {WebhookEndpointParams} params
|
|
371
|
+
*/
|
|
372
|
+
setWebhookEndpoint(params: WebhookEndpointParams, options?: RequestOptions): Promise<WebhookEndpoint>;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
declare class AssessmentsResource extends APIResource {
|
|
376
|
+
list(params?: AssessmentListParams, options?: RequestOptions): Promise<AsyncIterablePage<Assessment>>;
|
|
377
|
+
retrieve(id: string, options?: RequestOptions): Promise<Assessment>;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
declare class CandidatesResource extends APIResource {
|
|
381
|
+
list(params?: CandidateListParams, options?: RequestOptions): Promise<AsyncIterablePage<Candidate>>;
|
|
382
|
+
retrieve(id: string, options?: RequestOptions): Promise<Candidate>;
|
|
383
|
+
create(params: CandidateCreateParams, options?: RequestOptions): Promise<Candidate>;
|
|
384
|
+
/** Idempotent — calling twice on a cancelled candidate returns the same record. */
|
|
385
|
+
cancel(id: string, options?: RequestOptions): Promise<Candidate>;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
declare class SessionsResource extends APIResource {
|
|
389
|
+
retrieve(id: string, options?: RequestOptions): Promise<Session>;
|
|
390
|
+
listForCandidate(candidateId: string, params?: SessionListParams, options?: RequestOptions): Promise<AsyncIterablePage<Session>>;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
declare class Langos {
|
|
394
|
+
readonly account: AccountResource;
|
|
395
|
+
readonly assessments: AssessmentsResource;
|
|
396
|
+
readonly candidates: CandidatesResource;
|
|
397
|
+
readonly sessions: SessionsResource;
|
|
398
|
+
/**
|
|
399
|
+
* Webhook signature helpers (`Langos.webhooks.constructEvent`). Static-style:
|
|
400
|
+
* does not need the client instance, since signing is independent of API
|
|
401
|
+
* calls. Exposed both as a class member and as `Langos.webhooks` for parity
|
|
402
|
+
* with Stripe's `stripe.webhooks` style.
|
|
403
|
+
*/
|
|
404
|
+
readonly webhooks: {
|
|
405
|
+
constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
|
|
406
|
+
};
|
|
407
|
+
static readonly webhooks: {
|
|
408
|
+
constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
|
|
409
|
+
};
|
|
410
|
+
private readonly cfg;
|
|
411
|
+
constructor(options: LangosOptions);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Structured details merged into the 402 `quota_exceeded` error body. The
|
|
416
|
+
* server emits these as top-level fields alongside the standard problem+json
|
|
417
|
+
* envelope; partners can render an upgrade prompt without parsing free-form
|
|
418
|
+
* text.
|
|
419
|
+
*/
|
|
420
|
+
interface QuotaExceededDetails {
|
|
421
|
+
sessions_used: number;
|
|
422
|
+
sessions_limit: number;
|
|
423
|
+
/** ISO timestamp when the quota window resets. */
|
|
424
|
+
reset_at: string;
|
|
425
|
+
/** Absolute URL to the upgrade page; `null` if the server can't build one. */
|
|
426
|
+
upgrade_url: string | null;
|
|
427
|
+
/** The plan tier that hit the cap (e.g. `mid_tier`, `growth`). */
|
|
428
|
+
plan_tier: string;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Structured details merged into the 403 `feature_not_available` error body.
|
|
432
|
+
* Returned when an integration calls a feature its plan tier does not include
|
|
433
|
+
* (e.g. asking for replay on `starter`).
|
|
434
|
+
*/
|
|
435
|
+
interface FeatureNotAvailableDetails {
|
|
436
|
+
/** The plan-features key that is gated off (e.g. `replay`, `ai_assistance`). */
|
|
437
|
+
feature: string;
|
|
438
|
+
/** Absolute URL to the upgrade page; `null` if the server can't build one. */
|
|
439
|
+
upgrade_url: string | null;
|
|
440
|
+
}
|
|
441
|
+
interface LangosErrorBody {
|
|
442
|
+
type?: string;
|
|
443
|
+
title?: string;
|
|
444
|
+
status?: number;
|
|
445
|
+
detail?: string;
|
|
446
|
+
code?: string;
|
|
447
|
+
request_id?: string;
|
|
448
|
+
errors?: Array<{
|
|
449
|
+
field: string;
|
|
450
|
+
message: string;
|
|
451
|
+
code?: string;
|
|
452
|
+
}>;
|
|
453
|
+
[extra: string]: unknown;
|
|
454
|
+
}
|
|
455
|
+
declare class LangosError extends Error {
|
|
456
|
+
constructor(message: string);
|
|
457
|
+
}
|
|
458
|
+
/** Thrown when an HTTP response is received and indicates an error (>= 400). */
|
|
459
|
+
declare class LangosAPIError extends LangosError {
|
|
460
|
+
readonly status: number;
|
|
461
|
+
readonly code: string | undefined;
|
|
462
|
+
readonly requestId: string | undefined;
|
|
463
|
+
readonly headers: Headers;
|
|
464
|
+
readonly body: LangosErrorBody | undefined;
|
|
465
|
+
readonly errors: LangosErrorBody['errors'] | undefined;
|
|
466
|
+
constructor(status: number, body: LangosErrorBody | undefined, headers: Headers, fallbackMessage: string);
|
|
467
|
+
/**
|
|
468
|
+
* Typed accessor for 402 `quota_exceeded` errors. Returns the structured
|
|
469
|
+
* details payload (sessions used/limit, reset timestamp, upgrade URL, plan
|
|
470
|
+
* tier) when the error matches; otherwise `null`.
|
|
471
|
+
*
|
|
472
|
+
* Use this instead of reaching into `err.body` to render upgrade prompts.
|
|
473
|
+
*/
|
|
474
|
+
get quotaDetails(): QuotaExceededDetails | null;
|
|
475
|
+
/**
|
|
476
|
+
* Typed accessor for 403 `feature_not_available` errors. Returns the gated
|
|
477
|
+
* feature key and an upgrade URL; otherwise `null`.
|
|
478
|
+
*/
|
|
479
|
+
get featureDetails(): FeatureNotAvailableDetails | null;
|
|
480
|
+
static from(status: number, body: unknown, headers: Headers): LangosAPIError;
|
|
481
|
+
}
|
|
482
|
+
declare const LangosAuthenticationError: {
|
|
483
|
+
new (...args: any[]): {
|
|
484
|
+
name: string;
|
|
485
|
+
message: string;
|
|
486
|
+
stack?: string;
|
|
487
|
+
cause?: unknown;
|
|
488
|
+
};
|
|
489
|
+
} & typeof LangosAPIError;
|
|
490
|
+
type LangosAuthenticationError = LangosAPIError;
|
|
491
|
+
declare const LangosForbiddenError: {
|
|
492
|
+
new (...args: any[]): {
|
|
493
|
+
name: string;
|
|
494
|
+
message: string;
|
|
495
|
+
stack?: string;
|
|
496
|
+
cause?: unknown;
|
|
497
|
+
};
|
|
498
|
+
} & typeof LangosAPIError;
|
|
499
|
+
type LangosForbiddenError = LangosAPIError;
|
|
500
|
+
declare const LangosNotFoundError: {
|
|
501
|
+
new (...args: any[]): {
|
|
502
|
+
name: string;
|
|
503
|
+
message: string;
|
|
504
|
+
stack?: string;
|
|
505
|
+
cause?: unknown;
|
|
506
|
+
};
|
|
507
|
+
} & typeof LangosAPIError;
|
|
508
|
+
type LangosNotFoundError = LangosAPIError;
|
|
509
|
+
declare const LangosBadRequestError: {
|
|
510
|
+
new (...args: any[]): {
|
|
511
|
+
name: string;
|
|
512
|
+
message: string;
|
|
513
|
+
stack?: string;
|
|
514
|
+
cause?: unknown;
|
|
515
|
+
};
|
|
516
|
+
} & typeof LangosAPIError;
|
|
517
|
+
type LangosBadRequestError = LangosAPIError;
|
|
518
|
+
declare const LangosConflictError: {
|
|
519
|
+
new (...args: any[]): {
|
|
520
|
+
name: string;
|
|
521
|
+
message: string;
|
|
522
|
+
stack?: string;
|
|
523
|
+
cause?: unknown;
|
|
524
|
+
};
|
|
525
|
+
} & typeof LangosAPIError;
|
|
526
|
+
type LangosConflictError = LangosAPIError;
|
|
527
|
+
declare const LangosServerError: {
|
|
528
|
+
new (...args: any[]): {
|
|
529
|
+
name: string;
|
|
530
|
+
message: string;
|
|
531
|
+
stack?: string;
|
|
532
|
+
cause?: unknown;
|
|
533
|
+
};
|
|
534
|
+
} & typeof LangosAPIError;
|
|
535
|
+
type LangosServerError = LangosAPIError;
|
|
536
|
+
declare class LangosRateLimitError extends LangosAPIError {
|
|
537
|
+
readonly retryAfter: number | undefined;
|
|
538
|
+
constructor(status: number, body: LangosErrorBody | undefined, headers: Headers, fallback: string, retryAfter: number | undefined);
|
|
539
|
+
}
|
|
540
|
+
/** Thrown when the underlying fetch fails (DNS, TCP, TLS). */
|
|
541
|
+
declare class LangosConnectionError extends LangosError {
|
|
542
|
+
readonly cause: unknown;
|
|
543
|
+
constructor(message: string, cause: unknown);
|
|
544
|
+
}
|
|
545
|
+
/** Thrown when a request exceeds the configured timeout. */
|
|
546
|
+
declare class LangosTimeoutError extends LangosError {
|
|
547
|
+
readonly timeoutMs: number;
|
|
548
|
+
constructor(timeoutMs: number);
|
|
549
|
+
}
|
|
550
|
+
/** Thrown by `Langos.webhooks.constructEvent` when signature verification fails. */
|
|
551
|
+
declare class LangosSignatureVerificationError extends LangosError {
|
|
552
|
+
constructor(reason: string);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Webhook helpers. v1.0 ships verification only — outbound delivery from Langos
|
|
557
|
+
* is on the roadmap. Partners can wire `constructEvent` against the planned
|
|
558
|
+
* signature header today; the SDK contract will not change when delivery lands.
|
|
559
|
+
*
|
|
560
|
+
* Pattern matches Stripe's `stripe.webhooks.constructEvent` so partners with
|
|
561
|
+
* existing handlers re-use the same shape.
|
|
562
|
+
*/
|
|
563
|
+
declare const Webhooks: {
|
|
564
|
+
constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
declare const version = "0.2.0-alpha.1";
|
|
568
|
+
|
|
569
|
+
export { type Account, type AccountFeatures, type AccountIntegration, type Assessment, type AssessmentListParams, type AsyncIterablePage, type Candidate, type CandidateCancelledEvent, type CandidateCreateParams, type CandidateListParams, type CandidateStatus, type Event, type FeatureNotAvailableDetails, Langos, LangosAPIError, LangosAuthenticationError, LangosBadRequestError, LangosConflictError, LangosConnectionError, LangosError, type LangosErrorBody, LangosForbiddenError, LangosNotFoundError, type LangosOptions, LangosRateLimitError, LangosServerError, LangosSignatureVerificationError, LangosTimeoutError, type Logger, type Page, type PageMeta, type PlanCaps, type PlanTier, type QuotaExceededDetails, type RequestOptions, type Session, type SessionAnalytics, type SessionCompletedEvent, type SessionFeedback, type SessionInsights, type SessionListParams, type SessionStatus, type SessionSubmission, type SessionSubmittedEvent, type WebhookEndpoint, type WebhookEndpointParams, type WebhookEvent, type WebhookEventType, Webhooks, version };
|