@sparkvault/sdk-mobile 1.0.2 → 1.0.4

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.d.ts CHANGED
@@ -15,10 +15,10 @@ export type { EntropyFormat, EntropyResponse, GenerateEntropyOptions, } from './
15
15
  export { MobilePushTokensClient, } from './push-tokens.js';
16
16
  export type { RegisterPushTokenResponse, } from './push-tokens.js';
17
17
  export { MobileBillingClient, } from './billing.js';
18
- export type { BillingBalance, } from './billing.js';
18
+ export type { PortalSession, } from './billing.js';
19
19
  export { MobileTusUploader, parseForgeUrl, } from './tus.js';
20
20
  export type { TusUploadFromUriOptions, ParsedForgeUrl, } from './tus.js';
21
21
  export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
22
- export { SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
22
+ export { gateErrorFromBody, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
23
23
  export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
24
24
  export type * from './types.js';
package/dist/index.js CHANGED
@@ -10,6 +10,6 @@ export { MobilePushTokensClient, } from './push-tokens.js';
10
10
  export { MobileBillingClient, } from './billing.js';
11
11
  export { MobileTusUploader, parseForgeUrl, } from './tus.js';
12
12
  export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
13
- export { SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
13
+ export { gateErrorFromBody, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
14
14
  export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
15
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAQrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAQrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
package/dist/tus.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { base64EncodeUtf8, base64ToBytes } from './encoding.js';
2
- import { SparkVaultValidationError, TusUploadError } from './errors.js';
2
+ import { gateErrorFromBody, SparkVaultMobileError, SparkVaultValidationError, TusUploadError, } from './errors.js';
3
3
  const TUS_VERSION = '1.0.0';
4
4
  export function parseForgeUrl(forgeUrl) {
5
5
  let url;
@@ -23,6 +23,22 @@ export function parseForgeUrl(forgeUrl) {
23
23
  istk,
24
24
  };
25
25
  }
26
+ /**
27
+ * Parse a Forge error response body (JSON text) into the shared ApiErrorBody
28
+ * shape so gate mapping can read its `error.code` / `error.details.resource`.
29
+ * Returns an empty body on non-JSON text, which simply matches no gate.
30
+ */
31
+ function parseErrorBody(text) {
32
+ if (!text)
33
+ return {};
34
+ try {
35
+ const parsed = JSON.parse(text);
36
+ return parsed && typeof parsed === 'object' ? parsed : {};
37
+ }
38
+ catch {
39
+ return {};
40
+ }
41
+ }
26
42
  function getErrorName(err) {
27
43
  return err instanceof Error ? err.name : 'UnknownError';
28
44
  }
@@ -87,6 +103,13 @@ async function createTusUpload(config, parsed, fileSize, filename, contentType,
87
103
  });
88
104
  if (!response.ok) {
89
105
  const errorText = await response.text().catch(() => '');
106
+ // A 402 here is a billable gate hit mid-create (e.g. storage/bandwidth pool
107
+ // exhausted). Route it through the same typed-gate mapping as the JSON HTTP
108
+ // path so callers handle subscribe / add-on UX off one set of error types.
109
+ const gateError = gateErrorFromBody(response.status, parseErrorBody(errorText));
110
+ if (gateError) {
111
+ throw gateError;
112
+ }
90
113
  throw new TusUploadError(`TUS create failed: ${response.status} - ${errorText}`, {
91
114
  httpStatus: response.status,
92
115
  filename,
@@ -143,6 +166,11 @@ function uploadChunk(uploadUrl, istk, chunk, offset, timeoutMs, signal, onChunkP
143
166
  finish(() => resolve(newOffset));
144
167
  }
145
168
  else {
169
+ const gateError = gateErrorFromBody(xhr.status, parseErrorBody(xhr.responseText));
170
+ if (gateError) {
171
+ finish(() => reject(gateError));
172
+ return;
173
+ }
146
174
  finish(() => reject(new TusUploadError(`Chunk upload failed: ${xhr.status} - ${xhr.responseText.substring(0, 200)}`, {
147
175
  httpStatus: xhr.status,
148
176
  phase: 'upload',
@@ -210,6 +238,11 @@ export class MobileTusUploader {
210
238
  }
211
239
  if (err instanceof TusUploadError)
212
240
  throw err;
241
+ // Typed gate errors (PlanRequiredError / QuotaExceededError) must reach
242
+ // the caller intact so the subscribe / add-on UX fires; never bury them
243
+ // in a generic TusUploadError.
244
+ if (err instanceof SparkVaultMobileError)
245
+ throw err;
213
246
  throw TusUploadError.fromError(error, {
214
247
  filename: options.filename,
215
248
  fileSize: options.fileSize,
package/dist/tus.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tus.js","sourceRoot":"","sources":["../src/tus.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,9 +1,27 @@
1
+ /** Utilization state shared by storage, bandwidth, and Identity pools. */
2
+ export type PoolState = 'ok' | 'notice' | 'warning' | 'exhausted';
3
+ /** Live usage for a single capacity pool. `limit_gb` is null on unlimited plans. */
4
+ export interface PoolStatus {
5
+ used_gb: number;
6
+ limit_gb: number | null;
7
+ pct: number;
8
+ state: PoolState;
9
+ }
10
+ /** Bandwidth pool additionally reports when the metered cycle resets. */
11
+ export interface BandwidthPoolStatus extends PoolStatus {
12
+ cycle_resets_at: number | null;
13
+ }
14
+ /** Storage + bandwidth pool snapshot; rides responses on `meta.pools`. */
15
+ export interface SubscriptionPools {
16
+ storage: PoolStatus;
17
+ bandwidth: BandwidthPoolStatus;
18
+ }
1
19
  export interface ApiMeta {
2
20
  request_id: string;
3
21
  response_ms: number;
4
22
  timestamp: number;
5
23
  api_version: string;
6
- balance?: string;
24
+ pools?: SubscriptionPools;
7
25
  quota?: {
8
26
  limit: number;
9
27
  used: number;
@@ -43,11 +61,45 @@ export interface SparkVaultAccount {
43
61
  organization_name: string;
44
62
  email: string;
45
63
  status: 'active' | 'suspended';
46
- balance: string;
47
64
  logo_url?: string;
48
65
  logo_dark_url?: string;
49
66
  created_at: number;
50
67
  }
68
+ /** Identity attempts usage against the purchased tier cap. */
69
+ export interface SubscriptionIdentityStatus {
70
+ attempts_cap: number | null;
71
+ attempts_used: number;
72
+ soft_cap: number | null;
73
+ state: PoolState;
74
+ }
75
+ /**
76
+ * GET /v1/billing/subscription — the account's current plan, licensed vs. used
77
+ * seats, capacity blocks, live pool usage, and Identity attempts. Drives the
78
+ * subscription / usage view. `renewal_amount_usd` is a formatted dollars string;
79
+ * `renewal_date` is an epoch (seconds) or null when there is no active plan.
80
+ */
81
+ export interface SparkVaultSubscription {
82
+ plan: 'subscription' | 'internal' | 'unsubscribed';
83
+ unlimited: boolean;
84
+ subscription_status: string | null;
85
+ past_due: boolean;
86
+ renewal_date: number | null;
87
+ renewal_amount_usd: string;
88
+ seats: {
89
+ full: number;
90
+ viewer: number;
91
+ licensed: number;
92
+ used: number;
93
+ };
94
+ blocks: {
95
+ storage: number;
96
+ bandwidth: number;
97
+ };
98
+ pools: SubscriptionPools;
99
+ identity: SubscriptionIdentityStatus;
100
+ }
101
+ /** Native in-app purchase store channel for receipt validation. */
102
+ export type IapPlatform = 'ios' | 'android';
51
103
  export type IdentityType = 'email' | 'phone';
52
104
  export type VerifiedIdentityType = IdentityType | 'social';
53
105
  export type IdentityMethodId = 'totp_email' | 'totp_sms' | 'totp_voice' | 'passkey' | 'sparklink' | 'social_google' | 'social_apple' | 'social_microsoft' | 'social_github' | 'social_facebook' | 'social_linkedin' | 'enterprise_okta' | 'enterprise_entra' | 'enterprise_onelogin' | 'enterprise_ping' | 'enterprise_jumpcloud';
@@ -89,6 +141,18 @@ export interface IdentityTokenClaims {
89
141
  verified_at: number;
90
142
  method: string;
91
143
  }
144
+ /**
145
+ * A server-decided post-login nudge. Computed once per login (default mode);
146
+ * clients act on the steps they support, in order.
147
+ */
148
+ export type Recommendation = {
149
+ type: 'passkey';
150
+ } | {
151
+ type: 'backup_identifier';
152
+ missingType: 'email' | 'phone';
153
+ };
154
+ /** Canonical dismiss key for a recommendation (suppresses it server-side 30d). */
155
+ export type RecommendationKey = 'passkey' | 'backup_email' | 'backup_phone';
92
156
  export interface IdentityVerifyResult {
93
157
  token: string;
94
158
  identity: string;
@@ -97,6 +161,25 @@ export interface IdentityVerifyResult {
97
161
  redirect?: string;
98
162
  jwksUri: string;
99
163
  jwks?: IdentityJwks;
164
+ /** Ordered post-login nudges (default-mode logins only). */
165
+ recommendations?: Recommendation[];
166
+ }
167
+ /** Response to POST /backup-verification/send. */
168
+ export interface BackupSendResponse {
169
+ /** Opaque pending-attach session id (present when a code was sent). */
170
+ session_id?: string;
171
+ /** Delivery channel actually used. */
172
+ method?: 'email' | 'sms' | 'voice';
173
+ /** Code expiry (Unix seconds). */
174
+ expires_at?: number;
175
+ /** True when the identifier is already on the identity — no code was sent. */
176
+ already_verified?: boolean;
177
+ }
178
+ /** Response to POST /backup-verification/verify. */
179
+ export interface BackupVerifyResponse {
180
+ verified: boolean;
181
+ type: 'email' | 'phone';
182
+ value: string;
100
183
  }
101
184
  export interface SendTotpRequest {
102
185
  identity: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkvault/sdk-mobile",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Mobile SDK for SparkVault Identity, vault, folder, and ingot workflows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/auth.ts CHANGED
@@ -4,6 +4,10 @@ import { SparkVaultAuthenticationError, SparkVaultMobileError, SparkVaultValidat
4
4
  import type { MobileHttpClient } from './http.js';
5
5
  import type {
6
6
  ApiErrorBody,
7
+ BackupSendResponse,
8
+ BackupVerifyResponse,
9
+ Recommendation,
10
+ RecommendationKey,
7
11
  CompleteSignupRequest,
8
12
  CompleteSignupResponse,
9
13
  IdentityConfig,
@@ -30,6 +34,12 @@ import type {
30
34
  } from './types.js';
31
35
  import nacl from 'tweetnacl';
32
36
 
37
+ /** Raw snake_case recommendation as the API returns it. */
38
+ interface RawRecommendation {
39
+ type?: string;
40
+ missing_type?: 'email' | 'phone' | null;
41
+ }
42
+
33
43
  interface IdentityVerificationResponse {
34
44
  verified: boolean;
35
45
  token?: string;
@@ -46,6 +56,8 @@ interface IdentityVerificationResponse {
46
56
  ticket?: string;
47
57
  /** Offered second-factor methods. */
48
58
  methods?: string[];
59
+ /** Ordered post-login nudges. */
60
+ recommendations?: RawRecommendation[];
49
61
  }
50
62
 
51
63
  interface IdentityPasskeyCompletionResponse {
@@ -55,6 +67,25 @@ interface IdentityPasskeyCompletionResponse {
55
67
  identity_type: VerifiedIdentityType;
56
68
  method: string;
57
69
  redirect?: string;
70
+ /** Ordered post-login nudges. */
71
+ recommendations?: RawRecommendation[];
72
+ }
73
+
74
+ /**
75
+ * Map the API's snake_case recommendation list to the SDK's typed shape,
76
+ * dropping entries the SDK does not understand. Returns undefined when absent.
77
+ */
78
+ function mapRecommendations(raw: RawRecommendation[] | undefined): Recommendation[] | undefined {
79
+ if (!Array.isArray(raw)) return undefined;
80
+ const result: Recommendation[] = [];
81
+ for (const rec of raw) {
82
+ if (rec?.type === 'passkey') {
83
+ result.push({ type: 'passkey' });
84
+ } else if (rec?.type === 'backup_identifier' && (rec.missing_type === 'email' || rec.missing_type === 'phone')) {
85
+ result.push({ type: 'backup_identifier', missingType: rec.missing_type });
86
+ }
87
+ }
88
+ return result;
58
89
  }
59
90
 
60
91
  interface JwtHeader {
@@ -269,6 +300,7 @@ export class MobileAuthClient {
269
300
  identityType: verifyResult.identity_type,
270
301
  method: verifyResult.method,
271
302
  redirect: verifyResult.redirect,
303
+ recommendations: mapRecommendations(verifyResult.recommendations),
272
304
  });
273
305
  }
274
306
 
@@ -338,6 +370,7 @@ export class MobileAuthClient {
338
370
  identityType: result.identity_type,
339
371
  method: result.method,
340
372
  redirect: result.redirect,
373
+ recommendations: mapRecommendations(result.recommendations),
341
374
  });
342
375
  }
343
376
 
@@ -427,6 +460,7 @@ export class MobileAuthClient {
427
460
  identityType: result.identity_type,
428
461
  method: result.method,
429
462
  redirect: result.redirect,
463
+ recommendations: mapRecommendations(result.recommendations),
430
464
  });
431
465
  }
432
466
 
@@ -639,6 +673,7 @@ export class MobileAuthClient {
639
673
  identityType?: VerifiedIdentityType;
640
674
  method?: string;
641
675
  redirect?: string;
676
+ recommendations?: Recommendation[];
642
677
  }
643
678
  ): IdentityVerifyResult {
644
679
  const claims = this.decodeIdentityTokenClaims(token);
@@ -649,9 +684,55 @@ export class MobileAuthClient {
649
684
  method: details.method ?? claims.method,
650
685
  redirect: details.redirect,
651
686
  jwksUri: this.getJwksUri(),
687
+ recommendations: details.recommendations,
652
688
  };
653
689
  }
654
690
 
691
+ /**
692
+ * Skip a post-login recommendation, suppressing it server-side for 30 days.
693
+ * Authorized by the login's verification token. Best-effort.
694
+ */
695
+ async dismissRecommendation(params: { verificationToken: string; key: RecommendationKey }): Promise<void> {
696
+ await this.postIdentity('/recommendations/dismiss', {
697
+ verification_token: params.verificationToken,
698
+ key: params.key
699
+ });
700
+ }
701
+
702
+ /**
703
+ * Post-login: send a one-time code to a new backup identifier (the inverse of
704
+ * the one just logged in with), authorized by the login's verification token.
705
+ * Returns a pending-attach `session_id`, or `already_verified` when the
706
+ * identifier is already on the identity.
707
+ */
708
+ async sendBackupVerification(params: {
709
+ verificationToken: string;
710
+ type: IdentityType;
711
+ value: string;
712
+ method?: 'email' | 'sms' | 'voice';
713
+ }): Promise<BackupSendResponse> {
714
+ return this.postIdentity<BackupSendResponse>('/backup-verification/send', {
715
+ verification_token: params.verificationToken,
716
+ type: params.type,
717
+ value: params.value,
718
+ ...(params.method ? { method: params.method } : {}),
719
+ });
720
+ }
721
+
722
+ /**
723
+ * Confirm the backup-identifier code and attach it to the identity. An
724
+ * identifier already owned by another identity throws (409 `backup_conflict`).
725
+ */
726
+ async verifyBackupVerification(params: {
727
+ sessionId: string;
728
+ code: string;
729
+ }): Promise<BackupVerifyResponse> {
730
+ return this.postIdentity<BackupVerifyResponse>('/backup-verification/verify', {
731
+ session_id: params.sessionId,
732
+ code: params.code,
733
+ });
734
+ }
735
+
655
736
  private decodeIdentityTokenClaims(token: string): IdentityTokenClaims {
656
737
  const parts = token.split('.');
657
738
  if (parts.length !== 3) {
package/src/billing.ts CHANGED
@@ -1,19 +1,9 @@
1
1
  import type { MobileHttpClient } from './http.js';
2
+ import type { IapPlatform, SparkVaultSubscription } from './types.js';
2
3
 
3
- export interface BillingBalance {
4
- balance: string;
5
- balance_usd?: number;
6
- currency?: string;
7
- monthly_spend?: string;
8
- monthly_spend_usd?: number;
9
- transaction_count?: number;
10
- recent_transactions?: Array<{
11
- type: string;
12
- amount: string;
13
- balance_after?: string;
14
- reference_id?: string;
15
- created_at: number;
16
- }>;
4
+ /** Short-lived Stripe Customer Portal URL for managing the subscription on web. */
5
+ export interface PortalSession {
6
+ portal_url: string;
17
7
  }
18
8
 
19
9
  export class MobileBillingClient {
@@ -23,8 +13,40 @@ export class MobileBillingClient {
23
13
  this.http = http;
24
14
  }
25
15
 
26
- async getBalance(): Promise<BillingBalance> {
27
- const response = await this.http.get<BillingBalance>('/billing/balance');
16
+ /**
17
+ * Current subscription: plan, licensed vs. used seats, capacity blocks, live
18
+ * pool usage, and Identity attempts. Drives the subscription / usage view.
19
+ */
20
+ async getSubscription(): Promise<SparkVaultSubscription> {
21
+ const response = await this.http.get<SparkVaultSubscription>('/billing/subscription');
22
+ return response.data;
23
+ }
24
+
25
+ /**
26
+ * Open the Stripe Customer Portal to manage the subscription on web (seat /
27
+ * block changes that fixed native SKUs cannot carry route here). The caller
28
+ * loads the returned URL in the WebView.
29
+ */
30
+ async createPortalSession(): Promise<PortalSession> {
31
+ const response = await this.http.post<PortalSession>('/billing/portal');
32
+ return response.data;
33
+ }
34
+
35
+ /**
36
+ * Validate a native in-app purchase receipt server-side and apply the
37
+ * resulting entitlements. Returns the refreshed subscription so the client
38
+ * can update its plan / usage view immediately after purchase.
39
+ */
40
+ async iapValidate(
41
+ platform: IapPlatform,
42
+ productId: string,
43
+ receipt: string
44
+ ): Promise<SparkVaultSubscription> {
45
+ const response = await this.http.post<SparkVaultSubscription>('/billing/iap/validate', {
46
+ platform,
47
+ product_id: productId,
48
+ receipt,
49
+ });
28
50
  return response.data;
29
51
  }
30
52
  }
package/src/errors.ts CHANGED
@@ -1,4 +1,10 @@
1
- import type { ApiMeta } from './types.js';
1
+ import type { ApiErrorBody, ApiMeta } from './types.js';
2
+
3
+ type QuotaResource = 'storage' | 'bandwidth' | 'seats' | 'identity';
4
+
5
+ function isQuotaResource(value: unknown): value is QuotaResource {
6
+ return value === 'storage' || value === 'bandwidth' || value === 'seats' || value === 'identity';
7
+ }
2
8
 
3
9
  export class SparkVaultMobileError extends Error {
4
10
  readonly code: string | number;
@@ -49,6 +55,48 @@ export class SparkVaultAuthorizationError extends SparkVaultMobileError {
49
55
  }
50
56
  }
51
57
 
58
+ /**
59
+ * Thrown on a 402 PLAN_REQUIRED gate: the account has no active subscription
60
+ * and attempted a billable action. Callers route the user into the in-app
61
+ * subscribe flow (native IAP: fixed bundle / Identity tier).
62
+ */
63
+ export class PlanRequiredError extends SparkVaultMobileError {
64
+ constructor(message = 'An active plan is required for this action', options: {
65
+ details?: Record<string, unknown>;
66
+ meta?: ApiMeta;
67
+ } = {}) {
68
+ super(message, { code: 'PLAN_REQUIRED', statusCode: 402, details: options.details, meta: options.meta });
69
+ this.name = 'PlanRequiredError';
70
+ Object.setPrototypeOf(this, PlanRequiredError.prototype);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Thrown on a 402 QUOTA_EXCEEDED gate: a pooled-capacity or seat limit was
76
+ * reached. `resource` identifies what to extend, routed through the in-app
77
+ * subscribe flow (native IAP): storage/bandwidth to a capacity add-on,
78
+ * seats/identity to a seat or tier change.
79
+ */
80
+ export class QuotaExceededError extends SparkVaultMobileError {
81
+ readonly resource: 'storage' | 'bandwidth' | 'seats' | 'identity';
82
+
83
+ constructor(
84
+ resource: QuotaExceededError['resource'],
85
+ message?: string,
86
+ options: { details?: Record<string, unknown>; meta?: ApiMeta } = {}
87
+ ) {
88
+ super(message ?? `${resource} limit reached for this account`, {
89
+ code: 'QUOTA_EXCEEDED',
90
+ statusCode: 402,
91
+ details: { resource, ...(options.details ?? {}) },
92
+ meta: options.meta,
93
+ });
94
+ this.name = 'QuotaExceededError';
95
+ this.resource = resource;
96
+ Object.setPrototypeOf(this, QuotaExceededError.prototype);
97
+ }
98
+ }
99
+
52
100
  export class SparkVaultNetworkError extends SparkVaultMobileError {
53
101
  constructor(message = 'Network request failed', details?: Record<string, unknown>) {
54
102
  super(message, { code: 'network_error', details });
@@ -108,3 +156,37 @@ export class TusUploadError extends SparkVaultMobileError {
108
156
  });
109
157
  }
110
158
  }
159
+
160
+ /**
161
+ * Single source of truth for turning a 402 response into a typed gate error.
162
+ * Both the JSON HTTP path (http.ts) and the TUS upload path (tus.ts) route 402s
163
+ * through here so the subscribe / add-on UX keys off one set of error types.
164
+ *
165
+ * Returns a typed gate error for recognized server codes (`PLAN_REQUIRED`,
166
+ * `QUOTA_EXCEEDED`) and `null` for any other 402 body, letting the caller fall
167
+ * back to its generic error so unknown gates are never silently swallowed.
168
+ */
169
+ export function gateErrorFromBody(
170
+ statusCode: number,
171
+ errorBody: ApiErrorBody
172
+ ): PlanRequiredError | QuotaExceededError | null {
173
+ if (statusCode !== 402) return null;
174
+
175
+ const code = errorBody.error?.code;
176
+ const message = errorBody.error?.message ?? errorBody.message ?? undefined;
177
+ const details = errorBody.error?.details;
178
+ const meta = errorBody.meta;
179
+
180
+ if (code === 'PLAN_REQUIRED') {
181
+ return new PlanRequiredError(message, { details, meta });
182
+ }
183
+
184
+ if (code === 'QUOTA_EXCEEDED') {
185
+ const resource = details?.resource;
186
+ if (isQuotaResource(resource)) {
187
+ return new QuotaExceededError(resource, message, { details, meta });
188
+ }
189
+ }
190
+
191
+ return null;
192
+ }
package/src/http.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ResolvedMobileConfig } from './config.js';
2
2
  import {
3
+ gateErrorFromBody,
3
4
  SparkVaultAuthenticationError,
4
5
  SparkVaultMobileError,
5
6
  SparkVaultNetworkError,
@@ -149,6 +150,33 @@ export class MobileHttpClient {
149
150
  throw new SparkVaultMobileError(err instanceof Error ? err.message : 'Unknown request error');
150
151
  }
151
152
 
153
+ /**
154
+ * Single exit for non-OK responses: 402s become typed gate errors
155
+ * (PlanRequiredError / QuotaExceededError) so the subscribe / add-on UX keys
156
+ * off one set of types; everything else becomes a SparkVaultMobileError
157
+ * carrying the server code, status, details, and meta.
158
+ */
159
+ private throwHttpError(status: number, errorBody: ApiErrorBody): never {
160
+ if (errorBody.meta) {
161
+ this.lastMeta = errorBody.meta;
162
+ }
163
+
164
+ const gateError = gateErrorFromBody(status, errorBody);
165
+ if (gateError) {
166
+ throw gateError;
167
+ }
168
+
169
+ throw new SparkVaultMobileError(
170
+ errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(status),
171
+ {
172
+ code: errorBody.error?.code ?? status,
173
+ statusCode: status,
174
+ details: errorBody.error?.details,
175
+ meta: errorBody.meta,
176
+ }
177
+ );
178
+ }
179
+
152
180
  private makeUrl(endpoint: string): string {
153
181
  if (/^https?:\/\//i.test(endpoint)) {
154
182
  return endpoint;
@@ -296,19 +324,7 @@ export class MobileHttpClient {
296
324
  this.config.logger.debug('Failed to parse error response body', { status: response.status });
297
325
  }
298
326
 
299
- if (errorBody.meta) {
300
- this.lastMeta = errorBody.meta;
301
- }
302
-
303
- throw new SparkVaultMobileError(
304
- errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(response.status),
305
- {
306
- code: errorBody.error?.code ?? response.status,
307
- statusCode: response.status,
308
- details: errorBody.error?.details,
309
- meta: errorBody.meta,
310
- }
311
- );
327
+ this.throwHttpError(response.status, errorBody);
312
328
  }
313
329
 
314
330
  const result = await response.json();
@@ -365,15 +381,7 @@ export class MobileHttpClient {
365
381
  } catch {
366
382
  this.config.logger.debug('Failed to parse raw error response body', { status: response.status });
367
383
  }
368
- throw new SparkVaultMobileError(
369
- errorBody.error?.message ?? errorBody.message ?? this.defaultErrorMessage(response.status),
370
- {
371
- code: errorBody.error?.code ?? response.status,
372
- statusCode: response.status,
373
- details: errorBody.error?.details,
374
- meta: errorBody.meta,
375
- }
376
- );
384
+ this.throwHttpError(response.status, errorBody);
377
385
  }
378
386
 
379
387
  return response;
@@ -414,7 +422,7 @@ export class MobileHttpClient {
414
422
  case 401:
415
423
  return 'Authentication required.';
416
424
  case 402:
417
- return 'Insufficient balance. Please add funds to continue.';
425
+ return 'An active plan is required to continue.';
418
426
  case 403:
419
427
  return 'You do not have permission to perform this action.';
420
428
  case 404: