@curviate/sdk 0.37.1 → 0.39.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
@@ -300,7 +300,7 @@ async function errorFromResponse(res) {
300
300
  }
301
301
  const safetyHint = toSafetyHint(env?.hint);
302
302
  const safetyReason = toSafetyReason(env?.reason);
303
- return new CurviateError({
303
+ const err = new CurviateError({
304
304
  code: toErrorCode(env?.code),
305
305
  message: env?.message ?? `Request failed with status ${res.status}.`,
306
306
  httpStatus: res.status,
@@ -325,6 +325,7 @@ async function errorFromResponse(res) {
325
325
  ...safetyReason !== void 0 ? { safetyReason } : {},
326
326
  ...typeof env?.blocked === "boolean" ? { blocked: env.blocked } : {}
327
327
  });
328
+ return { err, refusesRetry: env?.retry_likely_to_succeed === false };
328
329
  }
329
330
  function retryDelay(err, attempt, jitter) {
330
331
  if (err.retryAfterMs !== void 0) return err.retryAfterMs;
@@ -405,9 +406,9 @@ async function execute(method, path, opts) {
405
406
  if (res.ok) {
406
407
  return parseSuccess(res);
407
408
  }
408
- const err = await errorFromResponse(res);
409
+ const { err, refusesRetry } = await errorFromResponse(res);
409
410
  const namesBudgetRow = err.budgetRow !== void 0;
410
- const neverRetry = err.retryHint?.kind === "never";
411
+ const neverRetry = err.retryHint?.kind === "never" || refusesRetry;
411
412
  const retryable = !isWrite && !namesBudgetRow && !neverRetry && RETRYABLE_CODES.has(err.code) && attempt < opts.maxRetries;
412
413
  if (retryable) {
413
414
  await sleep(retryDelay(err, attempt + 1, jitterFn()));
@@ -502,12 +503,19 @@ var AccountsResource = class {
502
503
  * `signatures`, `groups`) populated by an async background enrichment,
503
504
  * `null`/`[]` until the account's first enrichment pass completes.
504
505
  *
505
- * @param params - optional `limit` (1-250) and `cursor` (from a prior page).
506
+ * Each item carries `external_id` (your own id for the account's end user,
507
+ * set on `auth.intent` or `update`) and `metadata`, both `null` when unset.
508
+ *
509
+ * @param params - optional `limit` (1-250), `cursor` (from a prior page), and
510
+ * `external_id` (exact match: only that end user's accounts).
506
511
  * @returns a page of accounts and the next-page `cursor` (null when exhausted).
507
512
  *
508
513
  * @example
509
514
  * const page = await curviate.accounts.list({ limit: 50 });
510
515
  * for (const acc of page.items ?? []) console.log(acc.account_id);
516
+ *
517
+ * @example
518
+ * const { items } = await curviate.accounts.list({ external_id: "usr_42" });
511
519
  */
512
520
  list(params) {
513
521
  return this.ctx.request({
@@ -582,11 +590,18 @@ var AccountsResource = class {
582
590
  /**
583
591
  * Update an account's configuration.
584
592
  *
585
- * `metadata` is a flat string->string map that **replaces** the account's
586
- * custom-data store wholesale (keys not provided are removed). `proxy` sets a
587
- * custom egress proxy, or clears it (reverting to automatic proxy protection)
588
- * when passed as `null`. The `proxy.password`, if given, is stored securely
589
- * and never returned.
593
+ * `external_id` is your own id for the account's end user (1-255 chars, not
594
+ * unique, `null` clears it); treat it as an opaque id, not an email.
595
+ * `metadata` is a flat string->string map (at most 16 keys, key 40 chars,
596
+ * value 500) that **replaces** the stored map wholesale; `null` clears it.
597
+ * Both are stored by Curviate, read back on `get`/`list`, and a PATCH
598
+ * carrying only them makes no LinkedIn call. `proxy` sets a custom egress
599
+ * proxy, or clears it (reverting to automatic proxy protection) when passed
600
+ * as `null`. The `proxy.password`, if given, is stored securely and never
601
+ * returned.
602
+ *
603
+ * @example
604
+ * await curviate.accounts.update("acc_123", { external_id: "usr_42", metadata: { plan: "pro" } });
590
605
  */
591
606
  update(accountId, body) {
592
607
  return this.ctx.request({
@@ -604,6 +619,63 @@ var AccountsResource = class {
604
619
  path: apiPath`/v1/accounts/${accountId}`
605
620
  });
606
621
  }
622
+ /**
623
+ * Buy seats on the workspace's active subscription. Returns the new
624
+ * `seat_ids`; connect an account into one with `auth.intent({ seat_id })`.
625
+ *
626
+ * Every call buys the `qty` it asks for, so a repeated call buys again.
627
+ * The SDK never retries it for you. A
628
+ * `CurviateError(code: "SUBSCRIPTION_BUSY")` (503) means the purchase could
629
+ * not be confirmed while another change was in progress: check the seat
630
+ * count with `listSeats()` before trying again. A trialing workspace
631
+ * throws `CurviateError(code: "TRIAL_ACTIVE_SEAT_LIMIT")`: buy a seat to
632
+ * convert first.
633
+ *
634
+ * @param body - `{ qty }`, 1-50.
635
+ *
636
+ * @example
637
+ * const { seat_ids } = await curviate.accounts.addSeats({ qty: 1 });
638
+ */
639
+ addSeats(body) {
640
+ return this.ctx.request({ method: "POST", path: "/v1/billing/seats/add", body });
641
+ }
642
+ /**
643
+ * Schedule a seat's cancellation at the end of the current period.
644
+ * `effective_at` is when access ends; until then the seat keeps working
645
+ * and `revertSeatCancellation()` can undo it. Repeating the call on an
646
+ * already-scheduled seat returns the same `effective_at`; a seat whose
647
+ * cancellation already took effect throws
648
+ * `CurviateError(code: "ALREADY_CANCELLED")`.
649
+ *
650
+ * @param seatId - a `seat_...` id from `listSeats()`.
651
+ *
652
+ * @example
653
+ * const { effective_at } = await curviate.accounts.cancelSeat("seat_123");
654
+ */
655
+ cancelSeat(seatId) {
656
+ return this.ctx.request({
657
+ method: "POST",
658
+ path: apiPath`/v1/billing/seats/${seatId}/cancel`
659
+ });
660
+ }
661
+ /**
662
+ * Undo a scheduled seat cancellation before it takes effect. A seat with
663
+ * nothing scheduled (never cancelled, already reverted, or already
664
+ * effective) throws `CurviateError(code: "CANCELLATION_ALREADY_EFFECTIVE")`;
665
+ * a seat covered by a whole-subscription cancellation throws
666
+ * `CurviateError(code: "INVALID_CANCELLATION_SOURCE")`.
667
+ *
668
+ * @param seatId - the `seat_...` id passed to `cancelSeat()`.
669
+ *
670
+ * @example
671
+ * await curviate.accounts.revertSeatCancellation("seat_123");
672
+ */
673
+ revertSeatCancellation(seatId) {
674
+ return this.ctx.request({
675
+ method: "POST",
676
+ path: apiPath`/v1/billing/seats/${seatId}/cancel/revert`
677
+ });
678
+ }
607
679
  };
608
680
 
609
681
  // src/resources/auth.ts
@@ -683,20 +755,36 @@ var AuthResource = class {
683
755
  });
684
756
  }
685
757
  /**
686
- * Re-request the pending checkpoint notification (OTP / 2FA / mobile-app
687
- * push). `resent` is honest: `true` once the notification was actually
688
- * re-sent, `false` when there was nothing to re-send for that challenge
689
- * type (e.g. an authenticator-app code); this call never throws just
758
+ * Re-send the pending checkpoint code, or switch its verification method.
759
+ *
760
+ * Without `body`: re-requests the pending notification (OTP / 2FA /
761
+ * mobile-app push) and returns 200 `{ resent }`. `resent` is honest: `true`
762
+ * once the notification was actually re-sent, `false` when there was
763
+ * nothing to re-send for that challenge type (e.g. an authenticator-app
764
+ * code, or a `challenge_selection` checkpoint); this call never throws just
690
765
  * because a re-send wasn't applicable. Does not reset the checkpoint's
691
766
  * expiry.
692
767
  *
768
+ * With `{ challenge }`: answers a `challenge_selection` checkpoint. Pass one
769
+ * `id` from its `challenges` list (`email`, `sms` or `whatsapp`); the
770
+ * response is the next checkpoint (202), which you then solve as usual. An
771
+ * id the checkpoint did not offer throws `CurviateError(code:
772
+ * "INVALID_REQUEST")`.
773
+ *
693
774
  * @param accountId - the (provisional) `account_id` from the 202 response.
775
+ * @param body - optional `{ challenge }` for a `challenge_selection` checkpoint.
776
+ *
777
+ * @example
778
+ * const cp = await curviate.auth.intent({ seat_id, auth_method: "credentials", credentials });
779
+ * if (cp.object === "checkpoint" && cp.challenge_type === "challenge_selection") {
780
+ * const next = await curviate.auth.requestCheckpoint(cp.account_id!, { challenge: cp.challenges![0]!.id });
781
+ * }
694
782
  */
695
- requestCheckpoint(accountId) {
783
+ requestCheckpoint(accountId, body) {
696
784
  return this.ctx.request({
697
785
  method: "POST",
698
786
  path: "/v1/auth/checkpoint/request",
699
- body: { account_id: accountId }
787
+ body: { account_id: accountId, ...body }
700
788
  });
701
789
  }
702
790
  /**
@@ -2869,7 +2957,14 @@ var WebhooksResource = class {
2869
2957
  * Register a new webhook endpoint to receive real-time events.
2870
2958
  * `POST /v1/webhooks`
2871
2959
  * The HMAC signing secret is returned exactly once in the 201 response.
2872
- * `account_ids` is required (each webhook is scoped to specific accounts).
2960
+ * `account_ids` scopes a webhook to specific accounts (`acc_` ids you own)
2961
+ * and is required for `messaging` and `user`. For `account_status` it is
2962
+ * optional: omit it to receive status events for every current and future
2963
+ * account of the workspace (reads then return `account_ids: null`). An
2964
+ * explicit `[]` is rejected.
2965
+ *
2966
+ * @example
2967
+ * await curviate.webhooks.create({ source: "account_status", request_url: "https://example.com/hooks" });
2873
2968
  */
2874
2969
  create(body) {
2875
2970
  return this.ctx.request({
@@ -2915,6 +3010,8 @@ var WebhooksResource = class {
2915
3010
  /**
2916
3011
  * Update a webhook in place. `source` is immutable.
2917
3012
  * `PATCH /v1/webhooks/{id}`
3013
+ * `account_ids: null` switches an `account_status` webhook to every current
3014
+ * and future account.
2918
3015
  */
2919
3016
  update(id, body) {
2920
3017
  return this.ctx.request({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/sdk",
3
- "version": "0.37.1",
3
+ "version": "0.39.0",
4
4
  "private": false,
5
5
  "description": "TypeScript SDK for the Curviate API.",
6
6
  "license": "MIT",