@sparkvault/sdk-mobile 6.0.2 → 7.0.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.
Files changed (156) hide show
  1. package/README.md +5 -5
  2. package/dist/account.d.ts +4 -3
  3. package/dist/account.js +16 -11
  4. package/dist/account.js.map +1 -1
  5. package/dist/app-sdk/email-address.d.ts +37 -0
  6. package/dist/app-sdk/email-address.js +91 -0
  7. package/dist/app-sdk/email-address.js.map +1 -0
  8. package/dist/app-sdk/encoding.d.ts +64 -0
  9. package/dist/app-sdk/encoding.js +245 -0
  10. package/dist/app-sdk/encoding.js.map +1 -0
  11. package/dist/app-sdk/entropy-contract.d.ts +33 -0
  12. package/dist/app-sdk/entropy-contract.js +51 -0
  13. package/dist/app-sdk/entropy-contract.js.map +1 -0
  14. package/dist/app-sdk/filename.d.ts +93 -0
  15. package/dist/app-sdk/filename.js +161 -0
  16. package/dist/app-sdk/filename.js.map +1 -0
  17. package/dist/app-sdk/forge-url.d.ts +107 -0
  18. package/dist/app-sdk/forge-url.js +222 -0
  19. package/dist/app-sdk/forge-url.js.map +1 -0
  20. package/dist/app-sdk/ids.d.ts +48 -0
  21. package/dist/app-sdk/ids.js +65 -0
  22. package/dist/app-sdk/ids.js.map +1 -0
  23. package/dist/app-sdk/ingot-access-log.d.ts +29 -0
  24. package/dist/app-sdk/ingot-access-log.js +49 -0
  25. package/dist/app-sdk/ingot-access-log.js.map +1 -0
  26. package/dist/app-sdk/phone.d.ts +37 -0
  27. package/dist/app-sdk/phone.js +134 -0
  28. package/dist/app-sdk/phone.js.map +1 -0
  29. package/dist/app-sdk/platform-domains.d.ts +41 -0
  30. package/dist/app-sdk/platform-domains.js +82 -0
  31. package/dist/app-sdk/platform-domains.js.map +1 -0
  32. package/dist/app-sdk/request-path.d.ts +49 -0
  33. package/dist/app-sdk/request-path.js +81 -0
  34. package/dist/app-sdk/request-path.js.map +1 -0
  35. package/dist/app-sdk/transfer-retry.d.ts +298 -0
  36. package/dist/app-sdk/transfer-retry.js +535 -0
  37. package/dist/app-sdk/transfer-retry.js.map +1 -0
  38. package/dist/app-sdk/transient.d.ts +23 -0
  39. package/dist/app-sdk/transient.js +29 -0
  40. package/dist/app-sdk/transient.js.map +1 -0
  41. package/dist/app-sdk/upload-publication.d.ts +81 -0
  42. package/dist/app-sdk/upload-publication.js +93 -0
  43. package/dist/app-sdk/upload-publication.js.map +1 -0
  44. package/dist/app-sdk/vat-refusal.d.ts +66 -0
  45. package/dist/app-sdk/vat-refusal.js +69 -0
  46. package/dist/app-sdk/vat-refusal.js.map +1 -0
  47. package/dist/billing.d.ts +9 -17
  48. package/dist/billing.js +14 -17
  49. package/dist/billing.js.map +1 -1
  50. package/dist/config.d.ts +33 -1
  51. package/dist/config.js +23 -17
  52. package/dist/config.js.map +1 -1
  53. package/dist/encoding.d.ts +30 -4
  54. package/dist/encoding.js +89 -83
  55. package/dist/encoding.js.map +1 -1
  56. package/dist/entropy.d.ts +25 -4
  57. package/dist/entropy.js +62 -15
  58. package/dist/entropy.js.map +1 -1
  59. package/dist/entropy.test-d.d.ts +40 -0
  60. package/dist/entropy.test-d.js +12 -0
  61. package/dist/entropy.test-d.js.map +1 -0
  62. package/dist/errors.d.ts +105 -21
  63. package/dist/errors.js +74 -28
  64. package/dist/errors.js.map +1 -1
  65. package/dist/folders.js +8 -7
  66. package/dist/folders.js.map +1 -1
  67. package/dist/http.d.ts +57 -15
  68. package/dist/http.js +125 -138
  69. package/dist/http.js.map +1 -1
  70. package/dist/identity-dialog.js +4 -30
  71. package/dist/identity-dialog.js.map +1 -1
  72. package/dist/identity-input.d.ts +39 -0
  73. package/dist/identity-input.js +59 -0
  74. package/dist/identity-input.js.map +1 -0
  75. package/dist/index.d.ts +8 -7
  76. package/dist/index.js +5 -4
  77. package/dist/index.js.map +1 -1
  78. package/dist/ingots.d.ts +77 -32
  79. package/dist/ingots.js +152 -136
  80. package/dist/ingots.js.map +1 -1
  81. package/dist/mutex.d.ts +1 -2
  82. package/dist/mutex.js +0 -6
  83. package/dist/mutex.js.map +1 -1
  84. package/dist/notify.d.ts +7 -2
  85. package/dist/notify.js +12 -15
  86. package/dist/notify.js.map +1 -1
  87. package/dist/notify.test-d.d.ts +3 -2
  88. package/dist/notify.test-d.js +1 -1
  89. package/dist/products/identity.d.ts +5 -0
  90. package/dist/products/identity.js +40 -35
  91. package/dist/products/identity.js.map +1 -1
  92. package/dist/request-path.d.ts +32 -0
  93. package/dist/request-path.js +35 -0
  94. package/dist/request-path.js.map +1 -0
  95. package/dist/sparks.js +16 -15
  96. package/dist/sparks.js.map +1 -1
  97. package/dist/tus.d.ts +198 -16
  98. package/dist/tus.js +816 -327
  99. package/dist/tus.js.map +1 -1
  100. package/dist/types.d.ts +183 -23
  101. package/dist/users.d.ts +12 -5
  102. package/dist/users.js +27 -19
  103. package/dist/users.js.map +1 -1
  104. package/dist/validation.d.ts +20 -5
  105. package/dist/validation.js +29 -27
  106. package/dist/validation.js.map +1 -1
  107. package/dist/vaults.d.ts +34 -83
  108. package/dist/vaults.js +64 -44
  109. package/dist/vaults.js.map +1 -1
  110. package/dist/vaults.test-d.d.ts +22 -0
  111. package/dist/vaults.test-d.js +14 -0
  112. package/dist/vaults.test-d.js.map +1 -0
  113. package/package.json +4 -2
  114. package/src/account.ts +16 -11
  115. package/src/app-sdk/email-address.js +94 -0
  116. package/src/app-sdk/encoding.js +250 -0
  117. package/src/app-sdk/entropy-contract.js +56 -0
  118. package/src/app-sdk/filename.js +174 -0
  119. package/src/app-sdk/forge-url.js +224 -0
  120. package/src/app-sdk/ids.js +71 -0
  121. package/src/app-sdk/ingot-access-log.js +51 -0
  122. package/src/app-sdk/phone.js +139 -0
  123. package/src/app-sdk/platform-domains.js +99 -0
  124. package/src/app-sdk/request-path.js +81 -0
  125. package/src/app-sdk/transfer-retry.js +563 -0
  126. package/src/app-sdk/transient.js +30 -0
  127. package/src/app-sdk/upload-publication.js +102 -0
  128. package/src/app-sdk/vat-refusal.js +74 -0
  129. package/src/billing.ts +16 -25
  130. package/src/config.ts +56 -23
  131. package/src/encoding.ts +91 -103
  132. package/src/entropy.test-d.ts +47 -0
  133. package/src/entropy.ts +86 -20
  134. package/src/errors.ts +135 -38
  135. package/src/folders.ts +8 -7
  136. package/src/http.ts +145 -150
  137. package/src/identity-dialog.tsx +4 -37
  138. package/src/identity-input.ts +70 -0
  139. package/src/index.ts +13 -3
  140. package/src/ingots.ts +225 -180
  141. package/src/mutex.ts +1 -8
  142. package/src/notify.test-d.ts +3 -1
  143. package/src/notify.ts +19 -17
  144. package/src/products/identity.ts +45 -39
  145. package/src/request-path.ts +45 -0
  146. package/src/sparks.ts +16 -13
  147. package/src/tus.ts +1054 -408
  148. package/src/types.ts +181 -23
  149. package/src/users.ts +27 -17
  150. package/src/validation.ts +30 -24
  151. package/src/vaults.test-d.ts +29 -0
  152. package/src/vaults.ts +87 -153
  153. package/dist/platform-domains.generated.d.ts +0 -2
  154. package/dist/platform-domains.generated.js +0 -16
  155. package/dist/platform-domains.generated.js.map +0 -1
  156. package/src/platform-domains.generated.ts +0 -17
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Identity entry rules: what a typed identity is, its normalized form, and the
3
+ * keyboard its field needs. The sign-in dialog and every public identity method
4
+ * read identities through these rules, so a number or address resolves to the
5
+ * same identity whichever path it arrives by. A rule that misreads an identity
6
+ * locks that person out.
7
+ *
8
+ * What reads as a phone number and its E.164 form, and what is an email address
9
+ * and its canonical form, are the platform's one rules, mirrored from
10
+ * `@sparkvault/app-sdk/phone` and `@sparkvault/app-sdk/email-address` into
11
+ * `./app-sdk/`: the rules the Identity Product and the web SDK's identity field
12
+ * apply, so the dialog refuses exactly what the server would.
13
+ */
14
+ import { inferIdentityType } from './app-sdk/phone.js';
15
+ import type { IdentityType } from './types.js';
16
+ export { inferIdentityType };
17
+ /**
18
+ * An identity in the form the Identity Product keys it by, read as the given
19
+ * type: the canonical email address (trimmed, lowercased), or a phone number in
20
+ * E.164. Null when the value is not a valid identity of that type.
21
+ */
22
+ export declare function normalizeIdentifier(value: string, identityType: IdentityType): string | null;
23
+ export type ParsedIdentity = {
24
+ ok: true;
25
+ identity: string;
26
+ identityType: IdentityType;
27
+ } | {
28
+ ok: false;
29
+ error: string;
30
+ };
31
+ /** Classify and normalize a submitted identity (the canonical email address, or E.164 phone via `parsePhone`). */
32
+ export declare function parseIdentity(value: string, allowedTypes: IdentityType[]): ParsedIdentity;
33
+ /**
34
+ * The identity field's keyboard. A field that takes an email keeps a keyboard
35
+ * that can type one even while the input still reads as a phone number: the
36
+ * first characters of "2024user@gmail.com" do, and the phone pad has no
37
+ * letters or '@' to finish it with.
38
+ */
39
+ export declare function identityKeyboardType(allowedTypes: IdentityType[]): 'email-address' | 'phone-pad';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Identity entry rules: what a typed identity is, its normalized form, and the
3
+ * keyboard its field needs. The sign-in dialog and every public identity method
4
+ * read identities through these rules, so a number or address resolves to the
5
+ * same identity whichever path it arrives by. A rule that misreads an identity
6
+ * locks that person out.
7
+ *
8
+ * What reads as a phone number and its E.164 form, and what is an email address
9
+ * and its canonical form, are the platform's one rules, mirrored from
10
+ * `@sparkvault/app-sdk/phone` and `@sparkvault/app-sdk/email-address` into
11
+ * `./app-sdk/`: the rules the Identity Product and the web SDK's identity field
12
+ * apply, so the dialog refuses exactly what the server would.
13
+ */
14
+ import { canonicalEmailAddress, isValidEmailAddress } from './app-sdk/email-address.js';
15
+ import { inferIdentityType, parsePhone } from './app-sdk/phone.js';
16
+ export { inferIdentityType };
17
+ /**
18
+ * An identity in the form the Identity Product keys it by, read as the given
19
+ * type: the canonical email address (trimmed, lowercased), or a phone number in
20
+ * E.164. Null when the value is not a valid identity of that type.
21
+ */
22
+ export function normalizeIdentifier(value, identityType) {
23
+ if (identityType === 'phone') {
24
+ return parsePhone(value);
25
+ }
26
+ return isValidEmailAddress(value) ? canonicalEmailAddress(value) : null;
27
+ }
28
+ /** Classify and normalize a submitted identity (the canonical email address, or E.164 phone via `parsePhone`). */
29
+ export function parseIdentity(value, allowedTypes) {
30
+ const trimmed = value.trim();
31
+ if (!trimmed) {
32
+ return { ok: false, error: 'Enter an identity to continue.' };
33
+ }
34
+ const inferredType = inferIdentityType(trimmed);
35
+ if (!allowedTypes.includes(inferredType)) {
36
+ return {
37
+ ok: false,
38
+ error: inferredType === 'phone' ? 'Phone sign-in is not enabled for this app.' : 'Email sign-in is not enabled for this app.',
39
+ };
40
+ }
41
+ const identity = normalizeIdentifier(trimmed, inferredType);
42
+ if (!identity) {
43
+ return {
44
+ ok: false,
45
+ error: inferredType === 'email' ? 'Enter a valid email address.' : 'Enter a valid phone number in international format.',
46
+ };
47
+ }
48
+ return { ok: true, identity, identityType: inferredType };
49
+ }
50
+ /**
51
+ * The identity field's keyboard. A field that takes an email keeps a keyboard
52
+ * that can type one even while the input still reads as a phone number: the
53
+ * first characters of "2024user@gmail.com" do, and the phone pad has no
54
+ * letters or '@' to finish it with.
55
+ */
56
+ export function identityKeyboardType(allowedTypes) {
57
+ return allowedTypes.includes('email') ? 'email-address' : 'phone-pad';
58
+ }
59
+ //# sourceMappingURL=identity-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-input.js","sourceRoot":"","sources":["../src/identity-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,YAA0B;IAC3E,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AAMD,kHAAkH;AAClH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,YAA4B;IACvE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACzC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,4CAA4C;SAC9H,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,qDAAqD;SACzH,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAA4B;IAC/D,OAAO,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;AACxE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  export { SparkVaultMobile, createSparkVaultMobileClient, } from './client.js';
2
- export type { SparkVaultMobileConfig, ResolvedMobileConfig, } from './config.js';
2
+ export type { MobileConnectivity, SparkVaultMobileConfig, ResolvedMobileConfig, } from './config.js';
3
3
  export type { AuthEvent, AuthEventListener, } from './http.js';
4
4
  export { MobileProductsClient, MobileIdentityClient, } from './products/index.js';
5
5
  export { MobileAccountClient, } from './account.js';
6
6
  export { MobileVaultsClient, } from './vaults.js';
7
7
  export { MobileFoldersClient, } from './folders.js';
8
- export { MobileIngotsClient, } from './ingots.js';
9
- export type { DownloadToFileOptions, DownloadToFileResult, UploadOptions, UploadFromUriOptions, ReplaceFromUriOptions, ResumeUploadOptions, CreateUploadOptions, CreateUploadResult, CreateDownloadLinkOptions, CreateDownloadLinkResult, } from './ingots.js';
8
+ export { MobileIngotsClient, NAME_CONFLICT_POLICIES, } from './ingots.js';
9
+ export type { NameConflictPolicy, DownloadToFileOptions, DownloadToFileResult, UploadOptions, UploadFromUriOptions, ReplaceFromUriOptions, ResumeUploadOptions, CreateUploadOptions, CreateUploadResult, CreateDownloadLinkOptions, CreateDownloadLinkResult, } from './ingots.js';
10
10
  export { MobileHealthClient, } from './health.js';
11
11
  export type { HealthCheckOptions, HealthCheckResult, } from './health.js';
12
12
  export { MobileSparksClient, } from './sparks.js';
@@ -16,11 +16,12 @@ export type { EntropyFormat, EntropyResponse, GenerateEntropyOptions, } from './
16
16
  export { MobileNotifyClient, } from './notify.js';
17
17
  export type { NotificationInboxState, NotificationMarkState, NotificationRow, ListNotificationsOptions, ListNotificationsResponse, UnreadCountResponse, MarkNotificationStateOptions, MarkNotificationStateResponse, NotificationBulkMarkState, MarkAllNotificationsStateOptions, MarkAllNotificationsStateResponse, MarkAllReadResult, RegisterDeviceResponse, } from './notify.js';
18
18
  export { MobileBillingClient, } from './billing.js';
19
- export type { PortalSession, } from './billing.js';
20
19
  export { MobileUsersClient, } from './users.js';
21
- export { isSessionGone, MobileTusUploader, parseForgeUrl, } from './tus.js';
20
+ export { isSessionExpired, isSessionGone, MobileTusUploader, parseForgeUrl, } from './tus.js';
22
21
  export type { TusUploadFromUriOptions, TusResumeSession, TusSessionProbe, ParsedForgeUrl, } from './tus.js';
23
- export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
24
- export { BackgroundTransferError, gateErrorFromBody, IngotNotReadyError, isAuthError, isIngotNotReadyError, isNetworkError, isRateLimitError, isReadOnlyVaultError, isRetryableDownloadError, isVatExpiredError, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
22
+ export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, bytesToBase64url, utf8ToBytes, } from './encoding.js';
23
+ export { BackgroundTransferError, gateErrorFromBody, IngotNameHeldError, IngotNotReadyError, isAuthError, isIngotNameHeldError, isIngotNotReadyError, isNetworkError, isNotFoundError, isRateLimitError, isReadOnlyVaultError, isRetryableDownloadError, isVatExpiredError, PlanRequiredError, vatRefusalReason, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
24
+ export { VAT_REFUSAL_REASONS, endsVatSession } from './app-sdk/vat-refusal.js';
25
+ export type { IngotNameHolder, } from './errors.js';
25
26
  export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
26
27
  export type * from './types.js';
package/dist/index.js CHANGED
@@ -3,15 +3,16 @@ export { MobileProductsClient, MobileIdentityClient, } from './products/index.js
3
3
  export { MobileAccountClient, } from './account.js';
4
4
  export { MobileVaultsClient, } from './vaults.js';
5
5
  export { MobileFoldersClient, } from './folders.js';
6
- export { MobileIngotsClient, } from './ingots.js';
6
+ export { MobileIngotsClient, NAME_CONFLICT_POLICIES, } from './ingots.js';
7
7
  export { MobileHealthClient, } from './health.js';
8
8
  export { MobileSparksClient, } from './sparks.js';
9
9
  export { MobileEntropyClient, } from './entropy.js';
10
10
  export { MobileNotifyClient, } from './notify.js';
11
11
  export { MobileBillingClient, } from './billing.js';
12
12
  export { MobileUsersClient, } from './users.js';
13
- export { isSessionGone, MobileTusUploader, parseForgeUrl, } from './tus.js';
14
- export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, utf8ToBytes, } from './encoding.js';
15
- export { BackgroundTransferError, gateErrorFromBody, IngotNotReadyError, isAuthError, isIngotNotReadyError, isNetworkError, isRateLimitError, isReadOnlyVaultError, isRetryableDownloadError, isVatExpiredError, PlanRequiredError, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
13
+ export { isSessionExpired, isSessionGone, MobileTusUploader, parseForgeUrl, } from './tus.js';
14
+ export { base64EncodeUtf8, base64UrlToBytes, base64UrlToUtf8, bytesToUtf8, base64ToBytes, bytesToBase64, bytesToBase64url, utf8ToBytes, } from './encoding.js';
15
+ export { BackgroundTransferError, gateErrorFromBody, IngotNameHeldError, IngotNotReadyError, isAuthError, isIngotNameHeldError, isIngotNotReadyError, isNetworkError, isNotFoundError, isRateLimitError, isReadOnlyVaultError, isRetryableDownloadError, isVatExpiredError, PlanRequiredError, vatRefusalReason, QuotaExceededError, SparkVaultAuthenticationError, SparkVaultAuthorizationError, SparkVaultMobileError, SparkVaultNetworkError, SparkVaultTimeoutError, SparkVaultValidationError, TusUploadError, } from './errors.js';
16
+ export { VAT_REFUSAL_REASONS, endsVatSession } from './app-sdk/vat-refusal.js';
16
17
  export { isSafeId, sanitizeFilename, validateFolderId, validateIngotId, validateVaultId, } from './validation.js';
17
18
  //# 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,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAarB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAUrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAgBrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAOlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AAUrB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAcrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAUrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAgBrB,OAAO,EACL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,MAAM,UAAU,CAAC;AAOlB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/E,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
package/dist/ingots.d.ts CHANGED
@@ -1,6 +1,23 @@
1
1
  import type { ResolvedMobileConfig } from './config.js';
2
2
  import type { MobileHttpClient } from './http.js';
3
- import type { DebugLogger, HashCheckResponse, Ingot, IngotAccessLog, IngotAccessStats, IngotInvite, IngotSharingConfig, ListIngotsResponse, IngotUploadSession, UploadAbortBehavior, UploadProgressCallback, UploadResult, UploadTransferPolicy, UploadTransport } from './types.js';
3
+ import { type TusSessionProbe } from './tus.js';
4
+ import type { DebugLogger, HashCheckResponse, Ingot, IngotAccessLog, IngotAccessStats, IngotInvite, IngotSharingConfig, ListIngotsResponse, FolderContentsResponse, IngotUploadSession, UploadAbortBehavior, UploadProgressCallback, UploadResult, UploadTransferPolicy, UploadTransport } from './types.js';
5
+ /**
6
+ * What the server does when a create's name is already held in the target
7
+ * folder (case-insensitive). The server decides on the holder it read before
8
+ * writing anything, so a caller that must not replace content says so here:
9
+ * - `upsert` (the server default): the upload replaces the holder's content.
10
+ * - `complete_pending`: a holder whose own upload never finalized is completed
11
+ * (`created: false`); a published holder is refused with
12
+ * `IngotNameHeldError`, untouched.
13
+ * - `refuse`: any holder, its upload finished or not, is refused with
14
+ * `IngotNameHeldError`, untouched; the create only ever mints.
15
+ * - `new_name`: the holder is never touched; the ingot is minted under the
16
+ * first free numbered name the server picks ("report (2).pdf"), returned
17
+ * as the result's `name`.
18
+ */
19
+ export declare const NAME_CONFLICT_POLICIES: readonly ["upsert", "complete_pending", "refuse", "new_name"];
20
+ export type NameConflictPolicy = (typeof NAME_CONFLICT_POLICIES)[number];
4
21
  export interface UploadOptions {
5
22
  vaultId: string;
6
23
  vat: string;
@@ -29,16 +46,22 @@ export interface UploadOptions {
29
46
  export interface UploadFromUriOptions extends UploadOptions {
30
47
  fileUri: string;
31
48
  fileSize: number;
49
+ /** What a name already held in the target folder does; omitted means the server's `upsert`. */
50
+ onNameConflict?: NameConflictPolicy;
32
51
  /**
33
- * Invoked once the API has minted (or, via its same-name upsert, handed
34
- * back) the ingot and before any Forge session exists. `created: false`
35
- * means the bytes about to be sent will REPLACE an existing ingot's content
36
- * once they finalize; a caller that must never overwrite throws here, and
37
- * the throw propagates as-is with nothing sent and no session to clean up.
52
+ * Invoked once the server has placed the upload and before any Forge
53
+ * session exists: `created` is true when it minted the ingot and false when
54
+ * it staged the upload onto the row holding the name (as `onNameConflict`
55
+ * allowed), and `name` is the name the ingot is stored under (the server's
56
+ * numbered name under `new_name`). The placement has already been written
57
+ * by then, so this hook observes; a caller that must not replace content
58
+ * says so through `onNameConflict`. A throw here still stops the upload
59
+ * before a byte moves and propagates as-is.
38
60
  */
39
61
  onIngotCreated?: (ingot: {
40
62
  ingotId: string;
41
63
  created: boolean;
64
+ name: string;
42
65
  }) => void;
43
66
  /**
44
67
  * Invoked once the Forge tus session exists and before the first byte is
@@ -46,6 +69,12 @@ export interface UploadFromUriOptions extends UploadOptions {
46
69
  * attempt or a relaunch instead of re-sending bytes Forge already holds.
47
70
  */
48
71
  onSessionCreated?: (session: IngotUploadSession) => void;
72
+ /**
73
+ * Invoked whenever the session's expiry changes (see
74
+ * `TusUploadFromUriOptions.onSessionExpiry`): a caller that persists the
75
+ * session keeps its `expiresAt` current with it.
76
+ */
77
+ onSessionExpiry?: (expiresAt: number | null) => void;
49
78
  /** See `UploadTransport`; default `foreground`. */
50
79
  transport?: UploadTransport;
51
80
  /** Network policy for the OS transfer engine; see `UploadTransferPolicy`. Default: both allowed. */
@@ -62,7 +91,8 @@ export interface UploadFromUriOptions extends UploadOptions {
62
91
  abortBehavior?: UploadAbortBehavior;
63
92
  debug?: DebugLogger;
64
93
  }
65
- export interface ReplaceFromUriOptions extends UploadFromUriOptions {
94
+ /** A replace addresses its ingot by id: no name is placed, so the create-only hooks do not apply. */
95
+ export interface ReplaceFromUriOptions extends Omit<UploadFromUriOptions, 'onNameConflict' | 'onIngotCreated'> {
66
96
  ingotId: string;
67
97
  }
68
98
  export interface ResumeUploadOptions {
@@ -73,12 +103,18 @@ export interface ResumeUploadOptions {
73
103
  fileUri: string;
74
104
  fileSize: number;
75
105
  name: string;
76
- contentType: string;
77
- /** The persisted tus session handed to `onSessionCreated`. */
106
+ /**
107
+ * The persisted tus session handed to `onSessionCreated`, with the expiry
108
+ * the caller keeps for it (`onSessionExpiry`): a session past it is
109
+ * refused as `sessionLost` before any request.
110
+ */
78
111
  session: {
79
112
  uploadUrl: string;
80
113
  istk: string;
114
+ expiresAt?: number | null;
81
115
  };
116
+ /** See `UploadFromUriOptions.onSessionExpiry`. */
117
+ onSessionExpiry?: (expiresAt: number | null) => void;
82
118
  /** See `UploadTransport`; default `foreground`. */
83
119
  transport?: UploadTransport;
84
120
  /** Network policy for the OS transfer engine; see `UploadTransferPolicy`. Default: both allowed. */
@@ -135,16 +171,19 @@ export interface CreateUploadOptions {
135
171
  folderId?: string;
136
172
  /** Vault-keyed plaintext HMAC (43-char base64url); see UploadOptions.contentHmac. */
137
173
  contentHmac?: string;
174
+ /** What a name already held in the target folder does; omitted means the server's `upsert`. */
175
+ onNameConflict?: NameConflictPolicy;
138
176
  }
139
177
  export interface CreateUploadResult {
140
178
  ingotId: string;
141
179
  /** Forge tus endpoint plus upload-session token (ISTK) for the resumable upload. */
142
180
  forgeUrl: string;
181
+ /** The name the ingot is stored under: the server's numbered name under `new_name`. */
143
182
  name?: string;
144
183
  sizeBytes?: number;
145
184
  /**
146
- * Whether the server minted this ingot (true) or handed back an existing
147
- * row via its same-name upsert (false). Absent when the server did not say.
185
+ * Whether the server minted this ingot (true) or staged the upload onto
186
+ * the row already holding the name (false). Absent when the server did not say.
148
187
  */
149
188
  created?: boolean;
150
189
  }
@@ -177,8 +216,10 @@ export declare class MobileIngotsClient {
177
216
  * sent, then the ingot is verified active exactly as a fresh upload is.
178
217
  *
179
218
  * A `TusUploadError` with `sessionLost` means Forge no longer has the
180
- * session (expired or terminated); the caller drops it and starts over
181
- * with `uploadFromUri`.
219
+ * session (its expiry passed, or it was terminated); the caller drops it
220
+ * and starts over with `uploadFromUri`. A session `uploadUrl` that is not
221
+ * an upload session on an allowed transfer host is refused
222
+ * (SparkVaultValidationError) before the ISTK or a byte is sent anywhere.
182
223
  */
183
224
  resumeUpload(options: ResumeUploadOptions): Promise<UploadResult>;
184
225
  /**
@@ -186,21 +227,21 @@ export declare class MobileIngotsClient {
186
227
  * longer has it. Lets a caller reconcile sessions on relaunch — a session
187
228
  * at `offset === length` only needs its ingot verified, a lost one needs a
188
229
  * fresh `uploadFromUri` — without spending an upload slot to find out.
230
+ * An `uploadUrl` that is not an upload session on an allowed transfer host
231
+ * is refused (SparkVaultValidationError) before the ISTK is sent anywhere.
189
232
  */
190
233
  probeUploadSession(session: {
191
234
  uploadUrl: string;
192
235
  istk: string;
193
- }): Promise<{
194
- offset: number;
195
- length: number;
196
- chunkSize: number;
197
- } | null>;
236
+ }): Promise<TusSessionProbe | null>;
198
237
  /**
199
238
  * Release a tus session the caller kept on Forge (`abortBehavior: 'keep'`)
200
239
  * and has since abandoned, so Forge drops the chunks it holds and settles
201
240
  * the partial transfer's billing instead of waiting for expiry. Resolves
202
241
  * once the session is gone, including when Forge no longer had it
203
242
  * (404/410); any other failure rejects so the caller can retry later.
243
+ * An `uploadUrl` that is not an upload session on an allowed transfer host
244
+ * is refused (SparkVaultValidationError) before the ISTK is sent anywhere.
204
245
  */
205
246
  terminateUploadSession(session: {
206
247
  uploadUrl: string;
@@ -224,14 +265,17 @@ export declare class MobileIngotsClient {
224
265
  limit?: number;
225
266
  cursor?: string;
226
267
  }): Promise<ListIngotsResponse>;
268
+ /**
269
+ * List a folder, or the vault root, whole: the folder, its breadcrumb, its
270
+ * direct subfolders and every ingot directly in it, in one response.
271
+ */
227
272
  listContents(vaultId: string, vat: string, options?: {
228
273
  folder_id?: string | null;
229
- cursor?: string;
230
- limit?: number;
274
+ /** Ingot sort field (name | size | content_type | created | access_count | bandwidth); `created` by default */
231
275
  sort_by?: string;
276
+ /** `desc` by default */
232
277
  sort_order?: 'asc' | 'desc';
233
- type?: string;
234
- }): Promise<ListIngotsResponse>;
278
+ }): Promise<FolderContentsResponse>;
235
279
  search(vaultId: string, vat: string, options?: {
236
280
  q?: string;
237
281
  file_type?: string;
@@ -271,19 +315,19 @@ export declare class MobileIngotsClient {
271
315
  getAccessStats(vaultId: string, ingotId: string, vat: string): Promise<IngotAccessStats>;
272
316
  purgeAccessLogs(vaultId: string, ingotId: string, vat: string): Promise<void>;
273
317
  /**
274
- * Wait for a just-uploaded ingot to finish server-side finalization.
318
+ * Read a just-uploaded ingot until the server reports it `active`.
275
319
  *
276
- * The bytes are already fully uploaded and the ingot record exists before
277
- * this runs, so this NEVER re-creates or re-uploads anything - it only polls
278
- * status. A `failed` status throws (a genuine server encryption error the
279
- * caller should surface). A still-`processing` ingot after the poll budget
280
- * is returned as success, not thrown: the transport completed and the ingot
281
- * exists, so treating it as a failure would make the caller re-run the whole
282
- * upload and mint a DUPLICATE ingot (re-streaming the entire file and
283
- * double-billing storage). Finalization completes asynchronously server-side.
320
+ * The upload resolved on Forge's receipt (a 2xx to the PATCH at the final
321
+ * offset, which Forge answers only once the ingot is published), so a read
322
+ * that is not `active` yet is a read lagging that publication, which the
323
+ * poll waits out. It never re-creates or re-uploads anything. A row still
324
+ * not `active` past the poll budget is never reported as a success: it
325
+ * throws a `TusUploadError` whose `retryLater` is set (every byte is
326
+ * received, publication is unconfirmed), so the caller resumes the session
327
+ * it persisted later, which asks Forge for the receipt again and sends no
328
+ * bytes, rather than recording a backup the vault may not hold.
284
329
  */
285
330
  private verifyIngotActive;
286
- private toAccessLog;
287
331
  private verifyDownloadedFile;
288
332
  private deleteFileIfPresent;
289
333
  private ensureNotAborted;
@@ -295,5 +339,6 @@ export declare class MobileIngotsClient {
295
339
  */
296
340
  private isAbortError;
297
341
  private delay;
342
+ /** Refuse a download link that is not a Forge decrypt URL on a trusted host (forge-url's rule). */
298
343
  private validateDownloadUrl;
299
344
  }