@sparkvault/sdk-mobile 7.1.11 → 7.1.13

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.
Files changed (52) hide show
  1. package/README.md +2 -1
  2. package/dist/account.d.ts +0 -5
  3. package/dist/account.js +0 -9
  4. package/dist/account.js.map +1 -1
  5. package/dist/account.test-d.d.ts +26 -0
  6. package/dist/account.test-d.js +17 -0
  7. package/dist/account.test-d.js.map +1 -0
  8. package/dist/errors.d.ts +0 -3
  9. package/dist/errors.js +0 -7
  10. package/dist/errors.js.map +1 -1
  11. package/dist/http.d.ts +7 -13
  12. package/dist/http.js +7 -41
  13. package/dist/http.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/ingots.d.ts +17 -8
  18. package/dist/ingots.js +48 -26
  19. package/dist/ingots.js.map +1 -1
  20. package/dist/ingots.test-d.d.ts +11 -6
  21. package/dist/ingots.test-d.js +7 -4
  22. package/dist/ingots.test-d.js.map +1 -1
  23. package/dist/products/identity.d.ts +8 -5
  24. package/dist/products/identity.js +12 -29
  25. package/dist/products/identity.js.map +1 -1
  26. package/dist/sparks.d.ts +1 -2
  27. package/dist/sparks.js +0 -1
  28. package/dist/sparks.js.map +1 -1
  29. package/dist/tus.d.ts +0 -1
  30. package/dist/tus.js +1 -5
  31. package/dist/tus.js.map +1 -1
  32. package/dist/types.d.ts +27 -52
  33. package/dist/vaults.d.ts +1 -4
  34. package/dist/vaults.js +3 -3
  35. package/dist/vaults.js.map +1 -1
  36. package/dist/vaults.test-d.d.ts +7 -4
  37. package/dist/vaults.test-d.js +4 -2
  38. package/dist/vaults.test-d.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/account.test-d.ts +39 -0
  41. package/src/account.ts +0 -14
  42. package/src/errors.ts +0 -8
  43. package/src/http.ts +8 -50
  44. package/src/index.ts +0 -1
  45. package/src/ingots.test-d.ts +28 -5
  46. package/src/ingots.ts +56 -42
  47. package/src/products/identity.ts +16 -46
  48. package/src/sparks.ts +1 -3
  49. package/src/tus.ts +1 -6
  50. package/src/types.ts +27 -56
  51. package/src/vaults.test-d.ts +6 -3
  52. package/src/vaults.ts +4 -8
package/dist/types.d.ts CHANGED
@@ -42,14 +42,8 @@ export interface ApiErrorBody {
42
42
  details?: Record<string, unknown>;
43
43
  };
44
44
  message?: string;
45
- data?: unknown;
46
45
  meta?: ApiMeta;
47
46
  }
48
- export interface RateLimitInfo {
49
- limit: number;
50
- remaining: number;
51
- reset: number;
52
- }
53
47
  /** Account-scoped role. Owners and admins manage the organization and team. */
54
48
  export type OrgRole = 'owner' | 'admin' | 'user';
55
49
  export interface SparkVaultUser {
@@ -248,7 +242,6 @@ export interface IdentityBranding {
248
242
  companyName: string | null;
249
243
  logoLight: string | null;
250
244
  logoDark: string | null;
251
- backdrop_blur?: boolean;
252
245
  themeMode?: 'light' | 'dark';
253
246
  }
254
247
  export interface IdentityConfig {
@@ -337,44 +330,32 @@ export interface VerifyOtpRequest {
337
330
  pin: string;
338
331
  recipient: string;
339
332
  }
340
- export interface RequestPinRequest {
341
- email: string;
342
- organization_name?: string;
343
- }
344
- export interface RequestPinResponse {
333
+ /** A code sent: the kindling its verify names, and when the code expires (Unix seconds). */
334
+ export interface SendOtpResponse {
345
335
  kindling: string;
346
336
  expires_at: number;
347
- retry_after?: number;
348
- is_signup: boolean;
349
337
  }
350
338
  export interface PinVerifyLoginResponse {
351
339
  access_token: string;
352
340
  refresh_token: string;
353
- token_type: 'Bearer';
354
- expires_in: number;
355
341
  user: SparkVaultUser;
356
342
  }
343
+ /**
344
+ * A verified identity with no SparkVault user yet: `signup_token` (an
345
+ * identity-only access token) authorizes `account.completeSignup`.
346
+ */
357
347
  export interface PinVerifySignupPendingResponse {
358
348
  verified: true;
359
349
  needs_signup_info: true;
360
350
  signup_token: string;
361
- expires_at: number;
362
351
  }
363
352
  /**
364
- * Variant of the Core exchange result indicating the account has 2FA enabled:
365
- * the caller must collect a second factor via
366
- * `products.identity.submitSecondFactor({ ticket, code })` and re-exchange the
367
- * resulting Identity token via `account.exchangeIdentityToken`.
353
+ * The Core exchange of a verified Identity token. A second factor is collected
354
+ * at the Identity Product before its token exists (`products.identity.verifyOtp`
355
+ * throws for it, and `submitSecondFactor` finishes it), so the exchange is a
356
+ * login or a pending signup, never a second-factor challenge.
368
357
  */
369
- export interface PinVerifySecondFactorPendingResponse {
370
- verified: false;
371
- second_factor_required: true;
372
- /** Opaque pending-login handle to submit the second factor against. */
373
- ticket: string;
374
- /** Methods the user may use, e.g. ['authenticator','recovery_code']. */
375
- methods: string[];
376
- }
377
- export type PinVerifyResponse = PinVerifyLoginResponse | PinVerifySignupPendingResponse | PinVerifySecondFactorPendingResponse;
358
+ export type PinVerifyResponse = PinVerifyLoginResponse | PinVerifySignupPendingResponse;
378
359
  export interface SubmitSecondFactorRequest {
379
360
  /** Pending-login ticket from a second_factor_required response. */
380
361
  ticket: string;
@@ -388,8 +369,6 @@ export interface CompleteSignupRequest {
388
369
  export interface CompleteSignupResponse {
389
370
  access_token: string;
390
371
  refresh_token: string;
391
- token_type?: 'Bearer';
392
- expires_in?: number;
393
372
  user: SparkVaultUser;
394
373
  account: SparkVaultAccount;
395
374
  }
@@ -398,10 +377,14 @@ export interface PasskeyAuthOptions {
398
377
  challenge: string;
399
378
  timeout: number;
400
379
  rpId: string;
380
+ /**
381
+ * The person's credentials when the ceremony is scoped to an identifier:
382
+ * ids only, since a transport list would hand an unauthenticated probe a
383
+ * device fingerprint.
384
+ */
401
385
  allowCredentials?: Array<{
402
386
  id: string;
403
387
  type: 'public-key';
404
- transports?: string[];
405
388
  }>;
406
389
  userVerification: 'required' | 'preferred' | 'discouraged';
407
390
  }
@@ -462,14 +445,14 @@ export interface PasskeyCredential {
462
445
  }
463
446
  export interface PasskeyStatus {
464
447
  has_passkey: boolean;
465
- registered_at?: number;
466
- last_used_at?: number;
467
448
  }
449
+ /**
450
+ * POST /auth/identity/verify: a session for the verified identity's member, or,
451
+ * with `user` and `account` null, an identity-only token for a signup.
452
+ */
468
453
  export interface IdentitySessionResponse {
469
454
  access_token: string;
470
455
  refresh_token: string;
471
- token_type?: 'Bearer';
472
- expires_in?: number;
473
456
  user: SparkVaultUser | null;
474
457
  account: SparkVaultAccount | null;
475
458
  }
@@ -485,17 +468,15 @@ export interface Vault {
485
468
  last_unsealed_at?: number;
486
469
  unseal_count?: number;
487
470
  }
471
+ /** A vault is created with its name alone; a description is set with `update`. */
488
472
  export interface CreateVaultRequest {
489
473
  name: string;
490
- description?: string;
491
474
  }
492
475
  export interface CreateVaultResponse {
493
476
  vault_id: string;
494
477
  name: string;
495
- description?: string;
496
478
  vmk: string;
497
479
  vmk_warning: string;
498
- status: 'sealed';
499
480
  created_at: number;
500
481
  }
501
482
  export interface UpdateVaultRequest {
@@ -616,7 +597,6 @@ export interface Ingot {
616
597
  name: string;
617
598
  content_type: string;
618
599
  size_bytes: number;
619
- storage_location: 'dynamodb' | 's3';
620
600
  /** `uploading` until Forge activates the upload, then `active`. */
621
601
  status?: 'uploading' | 'active';
622
602
  folder_id?: string | null;
@@ -628,10 +608,7 @@ export interface Ingot {
628
608
  */
629
609
  managed_by?: string | null;
630
610
  created_at: number;
631
- accessed_at?: number;
632
- last_accessed_at?: number;
633
611
  access_count?: number;
634
- expires_at?: number;
635
612
  /**
636
613
  * Client-computed, vault-keyed HMAC of the plaintext (43-char base64url),
637
614
  * or null when the uploader did not supply one. Used for upload dedup and
@@ -649,9 +626,14 @@ export interface HashCheckMatch {
649
626
  export interface HashCheckResponse {
650
627
  found: HashCheckMatch[];
651
628
  }
629
+ /**
630
+ * One page of GET /vaults/:id/ingots or /ingots/search. `count` is this
631
+ * page's length: the server reports no total.
632
+ */
652
633
  export interface ListIngotsResponse {
653
634
  ingots: Ingot[];
654
- total: number;
635
+ count: number;
636
+ has_more: boolean;
655
637
  next_cursor?: string;
656
638
  }
657
639
  /**
@@ -680,7 +662,6 @@ export interface UploadResult {
680
662
  */
681
663
  name: string;
682
664
  size_bytes: number;
683
- storage_location: 's3';
684
665
  /**
685
666
  * Whether this upload minted the ingot (true) or went into an existing row
686
667
  * (false): the one holding the name, as the create's name-conflict policy
@@ -756,8 +737,6 @@ export interface IngotAccessLog {
756
737
  }
757
738
  export interface IngotAccessStats {
758
739
  total_downloads: number;
759
- unique_visitors?: number;
760
- last_accessed_at?: number;
761
740
  }
762
741
  /** A folder as every folder route answers it (Core's FolderRepository.toPublicFormat). */
763
742
  export interface Folder {
@@ -794,13 +773,10 @@ export interface TokenStorageAdapter {
794
773
  clearTokens(): Promise<void>;
795
774
  getUser?<T = SparkVaultUser>(): Promise<T | null>;
796
775
  setUser?<T = SparkVaultUser>(user: T): Promise<void>;
797
- getAccount?<T = SparkVaultAccount>(): Promise<T | null>;
798
776
  setAccount?<T = SparkVaultAccount>(account: T): Promise<void>;
799
- clearAll?(): Promise<void>;
800
777
  }
801
778
  export type FetchLike = (url: string, options?: RequestInit & {
802
779
  timeoutMs?: number;
803
- responseType?: XMLHttpRequestResponseType;
804
780
  }) => Promise<Response>;
805
781
  export interface SparkVaultLogger {
806
782
  debug(message: string, context?: Record<string, unknown>): void;
@@ -998,7 +974,6 @@ export interface MobileFileDownloader {
998
974
  }
999
975
  export interface DebugLogger {
1000
976
  log(message: string): void;
1001
- warn(message: string): void;
1002
977
  error(message: string): void;
1003
978
  success(message: string): void;
1004
979
  }
package/dist/vaults.d.ts CHANGED
@@ -5,7 +5,6 @@ export declare class MobileVaultsClient {
5
5
  constructor(http: MobileHttpClient);
6
6
  create(request: CreateVaultRequest): Promise<CreateVaultResponse>;
7
7
  list(options?: {
8
- status?: 'sealed' | 'unsealed';
9
8
  limit?: number;
10
9
  cursor?: string;
11
10
  }): Promise<ListVaultsResponse>;
@@ -15,9 +14,7 @@ export declare class MobileVaultsClient {
15
14
  * filtered down to nothing still carries a cursor. A failed page fails the
16
15
  * listing: a vault picker must never show a silently partial account.
17
16
  */
18
- listAll(options?: {
19
- status?: 'sealed' | 'unsealed';
20
- }): Promise<Vault[]>;
17
+ listAll(): Promise<Vault[]>;
21
18
  get(vaultId: string): Promise<Vault>;
22
19
  update(vaultId: string, request: UpdateVaultRequest): Promise<UpdateVaultResponse>;
23
20
  /**
package/dist/vaults.js CHANGED
@@ -13,7 +13,7 @@ export class MobileVaultsClient {
13
13
  }
14
14
  async list(options) {
15
15
  const response = await this.http.get(apiPath `/vaults`, {
16
- query: { status: options?.status, limit: options?.limit || undefined, cursor: options?.cursor },
16
+ query: { limit: options?.limit || undefined, cursor: options?.cursor },
17
17
  });
18
18
  return response.data;
19
19
  }
@@ -23,11 +23,11 @@ export class MobileVaultsClient {
23
23
  * filtered down to nothing still carries a cursor. A failed page fails the
24
24
  * listing: a vault picker must never show a silently partial account.
25
25
  */
26
- async listAll(options) {
26
+ async listAll() {
27
27
  const vaults = [];
28
28
  let cursor;
29
29
  do {
30
- const page = await this.list({ ...options, limit: VAULT_LIST_PAGE_LIMIT, cursor });
30
+ const page = await this.list({ limit: VAULT_LIST_PAGE_LIMIT, cursor });
31
31
  vaults.push(...page.vaults);
32
32
  cursor = page.has_more ? page.next_cursor : undefined;
33
33
  } while (cursor);
@@ -1 +1 @@
1
- {"version":3,"file":"vaults.js","sourceRoot":"","sources":["../src/vaults.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vaults.js","sourceRoot":"","sources":["../src/vaults.ts"],"names":[],"mappings":"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"}
@@ -7,16 +7,19 @@
7
7
  * `*.test.ts`, which tsconfig excludes.
8
8
  *
9
9
  * Mirrored server sources: apps/api/src/folders/list.js (listFolders answers
10
- * `{ folders }`, the whole list and nothing else) and apps/api/src/vaults/list.js
11
- * (one page: `{ vaults, count, has_more, next_cursor? }`).
10
+ * `{ folders }`, the whole list and nothing else), apps/api/src/vaults/list.js
11
+ * (one page: `{ vaults, count, has_more, next_cursor? }`) and
12
+ * apps/api/src/vaults/create.js (createVault answers `{ vault_id, name, vmk,
13
+ * vmk_warning, created_at }`).
12
14
  */
13
- import type { ListFoldersResponse, ListVaultsResponse } from './types.js';
15
+ import type { CreateVaultResponse, ListFoldersResponse, ListVaultsResponse } from './types.js';
14
16
  /** Fails to compile unless `T` resolves to exactly `true`. */
15
17
  type Assert<T extends true> = T;
16
18
  /** Invariant type equality: the SAME type, not merely mutually assignable. */
17
19
  type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
18
20
  export type VaultsWireContract = [
19
21
  Assert<Equals<keyof ListFoldersResponse, 'folders'>>,
20
- Assert<Equals<keyof ListVaultsResponse, 'vaults' | 'count' | 'has_more' | 'next_cursor'>>
22
+ Assert<Equals<keyof ListVaultsResponse, 'vaults' | 'count' | 'has_more' | 'next_cursor'>>,
23
+ Assert<Equals<keyof CreateVaultResponse, 'vault_id' | 'name' | 'vmk' | 'vmk_warning' | 'created_at'>>
21
24
  ];
22
25
  export {};
@@ -7,8 +7,10 @@
7
7
  * `*.test.ts`, which tsconfig excludes.
8
8
  *
9
9
  * Mirrored server sources: apps/api/src/folders/list.js (listFolders answers
10
- * `{ folders }`, the whole list and nothing else) and apps/api/src/vaults/list.js
11
- * (one page: `{ vaults, count, has_more, next_cursor? }`).
10
+ * `{ folders }`, the whole list and nothing else), apps/api/src/vaults/list.js
11
+ * (one page: `{ vaults, count, has_more, next_cursor? }`) and
12
+ * apps/api/src/vaults/create.js (createVault answers `{ vault_id, name, vmk,
13
+ * vmk_warning, created_at }`).
12
14
  */
13
15
  export {};
14
16
  //# sourceMappingURL=vaults.test-d.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vaults.test-d.js","sourceRoot":"","sources":["../src/vaults.test-d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
1
+ {"version":3,"file":"vaults.test-d.js","sourceRoot":"","sources":["../src/vaults.test-d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkvault/sdk-mobile",
3
- "version": "7.1.11",
3
+ "version": "7.1.13",
4
4
  "description": "Mobile SDK for SparkVault Identity, vault, folder, and ingot workflows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Core session wire-contract assertions — COMPILE-TIME ONLY.
3
+ *
4
+ * These types have no runtime, so a unit test can never catch them drifting from
5
+ * the server: the transpiler strips them and every assertion passes. `tsc
6
+ * --noEmit` (`pnpm typecheck`) is the gate instead. It is deliberately NOT a
7
+ * `*.test.ts`, which tsconfig excludes.
8
+ *
9
+ * Mirrored server sources: apps/api/src/auth/auth-with-identity.js
10
+ * (handleIdentityVerify answers `{ access_token, refresh_token, user, account }`,
11
+ * with `user` and `account` null for an identity that has no member yet) and
12
+ * apps/api/src/auth/complete-signup.js (the same four fields). Neither names a
13
+ * token type or lifetime: a field the server never sends reads as undefined
14
+ * wherever an app trusts it.
15
+ */
16
+
17
+ import type {
18
+ CompleteSignupResponse,
19
+ IdentitySessionResponse,
20
+ PinVerifyLoginResponse,
21
+ PinVerifyResponse,
22
+ PinVerifySignupPendingResponse,
23
+ } from './types.js';
24
+
25
+ /** Fails to compile unless `T` resolves to exactly `true`. */
26
+ type Assert<T extends true> = T;
27
+
28
+ /** Invariant type equality: the SAME type, not merely mutually assignable. */
29
+ type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
30
+ ? true
31
+ : false;
32
+
33
+ export type AccountWireContract = [
34
+ Assert<Equals<keyof IdentitySessionResponse, 'access_token' | 'refresh_token' | 'user' | 'account'>>,
35
+ Assert<Equals<keyof CompleteSignupResponse, 'access_token' | 'refresh_token' | 'user' | 'account'>>,
36
+ // The exchange is a login or a pending signup: a second factor is collected
37
+ // at the Identity Product before its token exists.
38
+ Assert<Equals<PinVerifyResponse, PinVerifyLoginResponse | PinVerifySignupPendingResponse>>,
39
+ ];
package/src/account.ts CHANGED
@@ -68,8 +68,6 @@ export class MobileAccountClient {
68
68
  return {
69
69
  access_token: session.access_token,
70
70
  refresh_token: session.refresh_token,
71
- token_type: session.token_type ?? 'Bearer',
72
- expires_in: session.expires_in ?? 3600,
73
71
  user: session.user,
74
72
  };
75
73
  }
@@ -78,7 +76,6 @@ export class MobileAccountClient {
78
76
  verified: true,
79
77
  needs_signup_info: true,
80
78
  signup_token: session.access_token,
81
- expires_at: Math.floor(Date.now() / 1000) + (session.expires_in ?? 3600),
82
79
  };
83
80
  }
84
81
 
@@ -99,17 +96,6 @@ export class MobileAccountClient {
99
96
  return response.data;
100
97
  }
101
98
 
102
- async signup(params: {
103
- signup_token: string;
104
- organization_name: string;
105
- full_name?: string;
106
- }): Promise<CompleteSignupResponse> {
107
- return this.completeSignup(params.signup_token, {
108
- organization_name: params.organization_name,
109
- full_name: params.full_name,
110
- });
111
- }
112
-
113
99
  async getProfile(): Promise<SparkVaultUser> {
114
100
  const response = await this.http.get<SparkVaultUser>(apiPath`/profile`);
115
101
  if (this.config.tokenStorage.setUser) {
package/src/errors.ts CHANGED
@@ -51,14 +51,6 @@ export class SparkVaultAuthenticationError extends SparkVaultMobileError {
51
51
  }
52
52
  }
53
53
 
54
- export class SparkVaultAuthorizationError extends SparkVaultMobileError {
55
- constructor(message = 'Forbidden', details?: Record<string, unknown>) {
56
- super(message, { code: 'authorization_error', statusCode: 403, details });
57
- this.name = 'SparkVaultAuthorizationError';
58
- Object.setPrototypeOf(this, SparkVaultAuthorizationError.prototype);
59
- }
60
- }
61
-
62
54
  /**
63
55
  * Thrown on a 402 PLAN_REQUIRED gate: the account has no active subscription
64
56
  * and attempted a billable action. Callers route the user into the in-app
package/src/http.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  import { isTransientHttpStatus } from './app-sdk/transient.js';
11
11
  import { createDedupMutex } from './mutex.js';
12
12
  import { queryString, type ApiPath, type QueryParams } from './request-path.js';
13
- import type { ApiErrorBody, ApiMeta, ApiResponse, RateLimitInfo } from './types.js';
13
+ import type { ApiErrorBody, ApiMeta, ApiResponse } from './types.js';
14
14
 
15
15
  export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
16
16
 
@@ -21,7 +21,6 @@ export interface RequestOptions {
21
21
  query?: QueryParams;
22
22
  skipAuth?: boolean;
23
23
  vat?: string;
24
- timeoutMs?: number;
25
24
  }
26
25
 
27
26
  export type AuthEvent = 'logout' | 'token_refreshed';
@@ -72,24 +71,11 @@ export class MobileHttpClient {
72
71
  private readonly authListeners = new Set<AuthEventListener>();
73
72
  private readonly refreshMutex = createDedupMutex<RefreshOutcome>();
74
73
  private lastMeta: ApiMeta | null = null;
75
- private rateLimitInfo: RateLimitInfo | null = null;
76
74
 
77
75
  constructor(config: ResolvedMobileConfig) {
78
76
  this.config = config;
79
77
  }
80
78
 
81
- get baseUrl(): string {
82
- return this.config.apiBaseUrl;
83
- }
84
-
85
- get meta(): ApiMeta | null {
86
- return this.lastMeta;
87
- }
88
-
89
- get rateLimit(): RateLimitInfo | null {
90
- return this.rateLimitInfo;
91
- }
92
-
93
79
  onAuthEvent(listener: AuthEventListener): () => void {
94
80
  this.authListeners.add(listener);
95
81
  return () => this.authListeners.delete(listener);
@@ -133,32 +119,6 @@ export class MobileHttpClient {
133
119
  return headers;
134
120
  }
135
121
 
136
- private parseRateLimitHeaders(headers: Headers): void {
137
- const limit = headers.get('X-RateLimit-Limit');
138
- const remaining = headers.get('X-RateLimit-Remaining');
139
- const reset = headers.get('X-RateLimit-Reset');
140
-
141
- if (!limit || !remaining || !reset) return;
142
-
143
- const parsedLimit = parseInt(limit, 10);
144
- const parsedRemaining = parseInt(remaining, 10);
145
- const parsedReset = parseInt(reset, 10);
146
-
147
- if (
148
- Number.isFinite(parsedLimit) &&
149
- Number.isFinite(parsedRemaining) &&
150
- Number.isFinite(parsedReset)
151
- ) {
152
- this.rateLimitInfo = {
153
- limit: parsedLimit,
154
- remaining: parsedRemaining,
155
- reset: parsedReset,
156
- };
157
- } else {
158
- this.config.logger.warn('Malformed rate limit headers', { limit, remaining, reset });
159
- }
160
- }
161
-
162
122
  /** The SDK error for a request the fetch adapter rejected (no HTTP response). */
163
123
  private transportError(err: unknown): SparkVaultMobileError {
164
124
  if (err instanceof SparkVaultMobileError) {
@@ -181,12 +141,6 @@ export class MobileHttpClient {
181
141
  return new SparkVaultMobileError(err instanceof Error ? err.message : 'Unknown request error');
182
142
  }
183
143
 
184
- /**
185
- * Single mapping for non-OK responses: 402s become typed gate errors
186
- * (PlanRequiredError / QuotaExceededError) so the subscribe / add-on UX keys
187
- * off one set of types; everything else becomes a SparkVaultMobileError
188
- * carrying the server code, status, details, and meta.
189
- */
190
144
  /** An error response's JSON body, or an empty one when it has none. */
191
145
  private async readErrorBody(response: Response): Promise<ApiErrorBody> {
192
146
  try {
@@ -209,6 +163,12 @@ export class MobileHttpClient {
209
163
  }
210
164
  }
211
165
 
166
+ /**
167
+ * Single mapping for non-OK responses: 402s become typed gate errors
168
+ * (PlanRequiredError / QuotaExceededError) so the subscribe / add-on UX keys
169
+ * off one set of types; everything else becomes a SparkVaultMobileError
170
+ * carrying the server code, status, details, and meta.
171
+ */
212
172
  private httpError(status: number, errorBody: ApiErrorBody): SparkVaultMobileError {
213
173
  if (errorBody.meta) {
214
174
  this.lastMeta = errorBody.meta;
@@ -358,7 +318,7 @@ export class MobileHttpClient {
358
318
 
359
319
  async request<T>(method: HttpMethod, path: ApiPath, options: RequestOptions = {}): Promise<ApiResponse<T>> {
360
320
  const url = this.makeUrl(path, options.query);
361
- const timeoutMs = options.timeoutMs ?? this.config.timeoutMs;
321
+ const timeoutMs = this.config.timeoutMs;
362
322
  const body = method === 'GET' ? undefined : this.serializeBody(options.body);
363
323
  let headers = await this.getHeaders({ ...options, body: options.body });
364
324
 
@@ -368,7 +328,6 @@ export class MobileHttpClient {
368
328
  } catch (err) {
369
329
  throw this.transportError(err);
370
330
  }
371
- this.parseRateLimitHeaders(response.headers);
372
331
 
373
332
  if (response.status === 401 && !options.skipAuth) {
374
333
  await this.throwIfVatRefused(response);
@@ -379,7 +338,6 @@ export class MobileHttpClient {
379
338
  } catch (err) {
380
339
  throw this.transportError(err);
381
340
  }
382
- this.parseRateLimitHeaders(response.headers);
383
341
  }
384
342
 
385
343
  if (response.status === 204) {
package/src/index.ts CHANGED
@@ -133,7 +133,6 @@ export {
133
133
  vatRefusalReason,
134
134
  QuotaExceededError,
135
135
  SparkVaultAuthenticationError,
136
- SparkVaultAuthorizationError,
137
136
  SparkVaultMobileError,
138
137
  SparkVaultNetworkError,
139
138
  SparkVaultTimeoutError,
@@ -6,13 +6,16 @@
6
6
  * and every assertion would pass. `tsc --noEmit` (`pnpm typecheck`) is the gate
7
7
  * instead. It is deliberately NOT a `*.test.ts`, which tsconfig excludes.
8
8
  *
9
- * Mirrored server source: apps/api/src/ingots/sharing.js (`formatSharingConfig`,
10
- * the one shape GET and PUT /vaults/:id/ingots/:ingot_id/sharing answer). A
11
- * field the server never sends reads as undefined wherever an app trusts it:
12
- * a link section keyed on it never renders.
9
+ * Mirrored server sources: apps/api/src/ingots/sharing.js (`formatSharingConfig`,
10
+ * the one shape GET and PUT /vaults/:id/ingots/:ingot_id/sharing answer),
11
+ * apps/api/src/repositories/IngotRepository.js (`toPublicFormat`, the one
12
+ * projection every ingot answer uses) and apps/api/src/lib/pagination.js
13
+ * (`buildPaginatedResponse`: one page, `{ ingots, count, has_more,
14
+ * next_cursor? }`). A field the server never sends reads as undefined wherever
15
+ * an app trusts it: a link section keyed on it never renders.
13
16
  */
14
17
 
15
- import type { IngotSharingConfig } from './types.js';
18
+ import type { Ingot, IngotSharingConfig, ListIngotsResponse } from './types.js';
16
19
 
17
20
  /** Fails to compile unless `T` resolves to exactly `true`. */
18
21
  type Assert<T extends true> = T;
@@ -43,4 +46,24 @@ export type IngotsWireContract = [
43
46
  Assert<Equals<IngotSharingConfig['public_url'], string | null>>,
44
47
  Assert<Equals<IngotSharingConfig['link_code'], string | null>>,
45
48
  Assert<Equals<IngotSharingConfig['visibility'], 'invite_only' | 'authenticated' | 'public' | null>>,
49
+ // A page reports its own length and whether more follow; it carries no total.
50
+ Assert<Equals<keyof ListIngotsResponse, 'ingots' | 'count' | 'has_more' | 'next_cursor'>>,
51
+ // Fields toPublicFormat projects, and none it keeps to the row (storage
52
+ // location, last access, the abandoned-upload expiry).
53
+ Assert<
54
+ Equals<
55
+ keyof Ingot,
56
+ | 'ingot_id'
57
+ | 'name'
58
+ | 'content_type'
59
+ | 'size_bytes'
60
+ | 'status'
61
+ | 'folder_id'
62
+ | 'managed_by'
63
+ | 'created_at'
64
+ | 'access_count'
65
+ | 'content_hmac'
66
+ | 'content_version'
67
+ >
68
+ >,
46
69
  ];