@curviate/sdk 0.40.0 → 0.41.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
@@ -79,6 +79,19 @@ var ERROR_CODES = [
79
79
  "CHECKPOINT_ALREADY_RESOLVED",
80
80
  "CHECKPOINT_UNSUPPORTED",
81
81
  "CONNECTION_IN_PROGRESS",
82
+ // Connection location (where LinkedIn sees the account connecting from).
83
+ // `CONNECTION_LOCATION_REQUIRED` (400): a new connect named no location, or
84
+ // a PATCH cleared your own proxy (`proxy: null`) without a `country`. Send
85
+ // exactly one of `country`, `ip` or `proxy`. user_fixable, never retryable
86
+ // as sent.
87
+ // `CONNECTION_LOCATION_UNAVAILABLE` (422): no connection is free in that
88
+ // country right now (strict), or the change landed elsewhere. When a change
89
+ // was applied, {@link CurviateError.connectionLocation} says where the
90
+ // account connects from now, which may mean your own proxy is already gone.
91
+ // Try a nearby country, or allow fallback. user_fixable, never retryable as
92
+ // sent.
93
+ "CONNECTION_LOCATION_REQUIRED",
94
+ "CONNECTION_LOCATION_UNAVAILABLE",
82
95
  // A reconnect whose seat-derived scope differs from the account's recorded
83
96
  // scope was attempted with cookie auth; a cookie replay cannot change
84
97
  // scope, so a full credentials re-authentication is required. user_fixable,
@@ -167,16 +180,6 @@ var ERROR_CODES = [
167
180
  // was charged. Stop and surface it to a human (or support) rather than
168
181
  // backing off.
169
182
  "STRIPE_DRIFT_DETECTED",
170
- // Agent-surface refusals the served Error component documents (their extras
171
- // are `toolset` and `candidates`). Both are user_fixable and never
172
- // retryable as sent.
173
- //
174
- // - `TOOLSET_DISABLED`: the toolset the call needs is switched off for this
175
- // tenant. Enable it or use another tool.
176
- // - `AMBIGUOUS_IDENTIFIER`: a name matched several entries. Pick one from
177
- // `candidates` and re-send its id.
178
- "TOOLSET_DISABLED",
179
- "AMBIGUOUS_IDENTIFIER",
180
183
  // Generic
181
184
  "INTERNAL"
182
185
  ];
@@ -197,6 +200,7 @@ var CurviateError = class _CurviateError extends Error {
197
200
  this.safetyHint = init.safetyHint;
198
201
  this.safetyReason = init.safetyReason;
199
202
  this.blocked = init.blocked;
203
+ this.connectionLocation = init.connectionLocation;
200
204
  Object.setPrototypeOf(this, _CurviateError.prototype);
201
205
  }
202
206
  /**
@@ -221,6 +225,7 @@ var CurviateError = class _CurviateError extends Error {
221
225
  if (this.safetyHint !== void 0) json.safetyHint = this.safetyHint;
222
226
  if (this.safetyReason !== void 0) json.safetyReason = this.safetyReason;
223
227
  if (this.blocked !== void 0) json.blocked = this.blocked;
228
+ if (this.connectionLocation !== void 0) json.connectionLocation = this.connectionLocation;
224
229
  return json;
225
230
  }
226
231
  };
@@ -335,7 +340,8 @@ async function errorFromResponse(res) {
335
340
  ...typeof env?.reset_at === "string" || env?.reset_at === null ? { resetAt: env.reset_at } : {},
336
341
  ...safetyHint !== void 0 ? { safetyHint } : {},
337
342
  ...safetyReason !== void 0 ? { safetyReason } : {},
338
- ...typeof env?.blocked === "boolean" ? { blocked: env.blocked } : {}
343
+ ...typeof env?.blocked === "boolean" ? { blocked: env.blocked } : {},
344
+ ...env?.connection_location !== null && typeof env?.connection_location === "object" ? { connectionLocation: env.connection_location } : {}
339
345
  });
340
346
  return { err, refusesRetry: env?.retry_likely_to_succeed === false };
341
347
  }
@@ -553,7 +559,7 @@ var AccountsResource = class {
553
559
  * const { items } = await curviate.accounts.listSeats();
554
560
  * const free = items.find((seat) => !seat.occupied);
555
561
  * if (!free) throw new Error("No seat is free to connect to right now (add a seat, or check billing).");
556
- * await curviate.auth.intent({ seat_id: free.seat_id, auth_method: "cookie", cookie: { li_at }, user_agent });
562
+ * await curviate.auth.intent({ seat_id: free.seat_id, auth_method: "cookie", cookie: { li_at }, user_agent, country: "US" });
557
563
  */
558
564
  listSeats() {
559
565
  return this.ctx.request({ method: "GET", path: "/v1/accounts/seats" });
@@ -607,13 +613,30 @@ var AccountsResource = class {
607
613
  * `metadata` is a flat string->string map (at most 16 keys, key 40 chars,
608
614
  * value 500) that **replaces** the stored map wholesale; `null` clears it.
609
615
  * Both are stored by Curviate, read back on `get`/`list`, and a PATCH
610
- * carrying only them makes no LinkedIn call. `proxy` sets a custom egress
611
- * proxy, or clears it (reverting to automatic proxy protection) when passed
612
- * as `null`. The `proxy.password`, if given, is stored securely and never
613
- * returned.
616
+ * carrying only them makes no LinkedIn call.
617
+ *
618
+ * `country` moves the account's connection location to that supported ISO
619
+ * country. LinkedIn sees a new IP there and may ask the owner to verify, so
620
+ * change it only when the current location is wrong. Strict unless
621
+ * `allow_country_fallback: true`; `allow_country_fallback` alone changes the
622
+ * strictness of the configured country. `proxy` sets your own proxy; `null`
623
+ * returns to a managed location and **requires** a `country` in the same
624
+ * call (else `CONNECTION_LOCATION_REQUIRED`), and an account on your own
625
+ * proxy can only take a `country` together with `proxy: null`. The
626
+ * `proxy.password`, if given, is never returned.
627
+ *
628
+ * Returns the account (as `get` returns it, without `quotas` and
629
+ * `event_log`). After a location change its `connection_location` is re-read,
630
+ * so it shows where the account really connects from now. A change that did
631
+ * not land where asked throws `CONNECTION_LOCATION_UNAVAILABLE`, whose
632
+ * `connectionLocation` carries the actual location.
614
633
  *
615
634
  * @example
616
635
  * await curviate.accounts.update("acc_123", { external_id: "usr_42", metadata: { plan: "pro" } });
636
+ *
637
+ * @example
638
+ * const account = await curviate.accounts.update("acc_123", { country: "DE" });
639
+ * console.log(account.connection_location?.country); // "DE"
617
640
  */
618
641
  update(accountId, body) {
619
642
  return this.ctx.request({
@@ -633,7 +656,7 @@ var AccountsResource = class {
633
656
  }
634
657
  /**
635
658
  * Buy seats on the workspace's active subscription. Returns the new
636
- * `seat_ids`; connect an account into one with `auth.intent({ seat_id })`.
659
+ * `seat_ids`; connect an account into one with `auth.intent({ seat_id, country, ... })`.
637
660
  *
638
661
  * Every call buys the `qty` it asks for, so a repeated call buys again.
639
662
  * The SDK never retries it for you. A
@@ -738,8 +761,30 @@ var AuthResource = class {
738
761
  * LinkedIn account does not hold throws
739
762
  * `CurviateError(code: "LINKEDIN_FEATURE_NOT_SUBSCRIBED")` (403); the remedy
740
763
  * is to activate the subscription on LinkedIn or to point `linkedin_premium`
741
- * at the premium the account really has. Pin a managed proxy with the
742
- * optional `country`/`ip`, or supply `proxy` to override it entirely.
764
+ * at the premium the account really has.
765
+ *
766
+ * **Connection location.** A NEW connect must say where LinkedIn sees the
767
+ * account connecting from, with exactly one of: `country` (a supported ISO
768
+ * code such as `"US"`; pick the one the owner normally signs in from), `ip`
769
+ * (a public IPv4 whose country is used) or your own `proxy`. Without one the
770
+ * API throws `CurviateError(code: "CONNECTION_LOCATION_REQUIRED")`, and the
771
+ * {@link AuthIntentBody} type refuses it at compile time. `country` and `ip`
772
+ * are strict by default: the connect fails with
773
+ * `CONNECTION_LOCATION_UNAVAILABLE` rather than use another country, unless
774
+ * you send `allow_country_fallback: true`. A reconnect may omit the location
775
+ * to keep the account's configured one. The account's `connection_location`
776
+ * says where it connects from; when a connect re-attached an account you
777
+ * already had and moved it, `connection_location.previous_country` names
778
+ * where it was.
779
+ *
780
+ * @example
781
+ * const result = await curviate.auth.intent({
782
+ * seat_id: "YOUR_SEAT_ID",
783
+ * auth_method: "credentials",
784
+ * credentials: { email: "YOUR_EMAIL", password: "YOUR_PASSWORD" },
785
+ * country: "US",
786
+ * });
787
+ * console.log(result.account_id);
743
788
  */
744
789
  intent(body) {
745
790
  return this.ctx.request({
@@ -787,7 +832,7 @@ var AuthResource = class {
787
832
  * @param body - optional `{ challenge }` for a `challenge_selection` checkpoint.
788
833
  *
789
834
  * @example
790
- * const cp = await curviate.auth.intent({ seat_id, auth_method: "credentials", credentials });
835
+ * const cp = await curviate.auth.intent({ seat_id, auth_method: "credentials", credentials, country: "US" });
791
836
  * if (cp.object === "checkpoint" && cp.challenge_type === "challenge_selection") {
792
837
  * const next = await curviate.auth.requestCheckpoint(cp.account_id!, { challenge: cp.challenges![0]!.id });
793
838
  * }
@@ -1397,15 +1442,15 @@ var PostsResource = class {
1397
1442
  * Get a single post. `GET /v1/{account_id}/posts/{post_id}`
1398
1443
  *
1399
1444
  * @param postId - the post's `id` as returned by {@link listUserPosts} or
1400
- * {@link create}. A bare numeric id (`7332661864792854528`), a URN
1401
- * (`urn:li:activity:N`, `urn:li:ugcPost:N`, `urn:li:share:N`), and a full
1402
- * share URL (`https://www.linkedin.com/posts/...` or
1445
+ * {@link create}, or a post search result's `id`. A bare numeric id
1446
+ * (`7332661864792854528`), a URN (`urn:li:activity:N`, `urn:li:ugcPost:N`,
1447
+ * `urn:li:share:N`), and a full post URL (`https://www.linkedin.com/posts/...`
1448
+ * with an `activity-`, `ugcPost-` or `share-` slug, or
1403
1449
  * `https://www.linkedin.com/feed/update/urn:li:activity:N`) all resolve to
1404
1450
  * the same post. Pass the value as-is; it is percent-encoded into the path
1405
1451
  * for you, so do not encode it yourself.
1406
1452
  *
1407
- * {@link listComments} and the reaction operations are stricter: they take
1408
- * the opaque `id` form only.
1453
+ * {@link listComments} and the reaction operations accept the same forms.
1409
1454
  */
1410
1455
  get(postId) {
1411
1456
  return this.ctx.request({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/sdk",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "private": false,
5
5
  "description": "TypeScript SDK for the Curviate API.",
6
6
  "license": "MIT",