@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.
- package/README.md +5 -5
- package/dist/account.d.ts +4 -3
- package/dist/account.js +16 -11
- package/dist/account.js.map +1 -1
- package/dist/app-sdk/email-address.d.ts +37 -0
- package/dist/app-sdk/email-address.js +91 -0
- package/dist/app-sdk/email-address.js.map +1 -0
- package/dist/app-sdk/encoding.d.ts +64 -0
- package/dist/app-sdk/encoding.js +245 -0
- package/dist/app-sdk/encoding.js.map +1 -0
- package/dist/app-sdk/entropy-contract.d.ts +33 -0
- package/dist/app-sdk/entropy-contract.js +51 -0
- package/dist/app-sdk/entropy-contract.js.map +1 -0
- package/dist/app-sdk/filename.d.ts +93 -0
- package/dist/app-sdk/filename.js +161 -0
- package/dist/app-sdk/filename.js.map +1 -0
- package/dist/app-sdk/forge-url.d.ts +107 -0
- package/dist/app-sdk/forge-url.js +222 -0
- package/dist/app-sdk/forge-url.js.map +1 -0
- package/dist/app-sdk/ids.d.ts +48 -0
- package/dist/app-sdk/ids.js +65 -0
- package/dist/app-sdk/ids.js.map +1 -0
- package/dist/app-sdk/ingot-access-log.d.ts +29 -0
- package/dist/app-sdk/ingot-access-log.js +49 -0
- package/dist/app-sdk/ingot-access-log.js.map +1 -0
- package/dist/app-sdk/phone.d.ts +37 -0
- package/dist/app-sdk/phone.js +134 -0
- package/dist/app-sdk/phone.js.map +1 -0
- package/dist/app-sdk/platform-domains.d.ts +41 -0
- package/dist/app-sdk/platform-domains.js +82 -0
- package/dist/app-sdk/platform-domains.js.map +1 -0
- package/dist/app-sdk/request-path.d.ts +49 -0
- package/dist/app-sdk/request-path.js +81 -0
- package/dist/app-sdk/request-path.js.map +1 -0
- package/dist/app-sdk/transfer-retry.d.ts +298 -0
- package/dist/app-sdk/transfer-retry.js +535 -0
- package/dist/app-sdk/transfer-retry.js.map +1 -0
- package/dist/app-sdk/transient.d.ts +23 -0
- package/dist/app-sdk/transient.js +29 -0
- package/dist/app-sdk/transient.js.map +1 -0
- package/dist/app-sdk/upload-publication.d.ts +81 -0
- package/dist/app-sdk/upload-publication.js +93 -0
- package/dist/app-sdk/upload-publication.js.map +1 -0
- package/dist/app-sdk/vat-refusal.d.ts +66 -0
- package/dist/app-sdk/vat-refusal.js +69 -0
- package/dist/app-sdk/vat-refusal.js.map +1 -0
- package/dist/billing.d.ts +9 -17
- package/dist/billing.js +14 -17
- package/dist/billing.js.map +1 -1
- package/dist/config.d.ts +33 -1
- package/dist/config.js +23 -17
- package/dist/config.js.map +1 -1
- package/dist/encoding.d.ts +30 -4
- package/dist/encoding.js +89 -83
- package/dist/encoding.js.map +1 -1
- package/dist/entropy.d.ts +25 -4
- package/dist/entropy.js +62 -15
- package/dist/entropy.js.map +1 -1
- package/dist/entropy.test-d.d.ts +40 -0
- package/dist/entropy.test-d.js +12 -0
- package/dist/entropy.test-d.js.map +1 -0
- package/dist/errors.d.ts +105 -21
- package/dist/errors.js +74 -28
- package/dist/errors.js.map +1 -1
- package/dist/folders.js +8 -7
- package/dist/folders.js.map +1 -1
- package/dist/http.d.ts +57 -15
- package/dist/http.js +125 -138
- package/dist/http.js.map +1 -1
- package/dist/identity-dialog.js +4 -30
- package/dist/identity-dialog.js.map +1 -1
- package/dist/identity-input.d.ts +39 -0
- package/dist/identity-input.js +59 -0
- package/dist/identity-input.js.map +1 -0
- package/dist/index.d.ts +8 -7
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/ingots.d.ts +77 -32
- package/dist/ingots.js +152 -136
- package/dist/ingots.js.map +1 -1
- package/dist/mutex.d.ts +1 -2
- package/dist/mutex.js +0 -6
- package/dist/mutex.js.map +1 -1
- package/dist/notify.d.ts +7 -2
- package/dist/notify.js +12 -15
- package/dist/notify.js.map +1 -1
- package/dist/notify.test-d.d.ts +3 -2
- package/dist/notify.test-d.js +1 -1
- package/dist/products/identity.d.ts +5 -0
- package/dist/products/identity.js +40 -35
- package/dist/products/identity.js.map +1 -1
- package/dist/request-path.d.ts +32 -0
- package/dist/request-path.js +35 -0
- package/dist/request-path.js.map +1 -0
- package/dist/sparks.js +16 -15
- package/dist/sparks.js.map +1 -1
- package/dist/tus.d.ts +198 -16
- package/dist/tus.js +816 -327
- package/dist/tus.js.map +1 -1
- package/dist/types.d.ts +183 -23
- package/dist/users.d.ts +12 -5
- package/dist/users.js +27 -19
- package/dist/users.js.map +1 -1
- package/dist/validation.d.ts +20 -5
- package/dist/validation.js +29 -27
- package/dist/validation.js.map +1 -1
- package/dist/vaults.d.ts +34 -83
- package/dist/vaults.js +64 -44
- package/dist/vaults.js.map +1 -1
- package/dist/vaults.test-d.d.ts +22 -0
- package/dist/vaults.test-d.js +14 -0
- package/dist/vaults.test-d.js.map +1 -0
- package/package.json +4 -2
- package/src/account.ts +16 -11
- package/src/app-sdk/email-address.js +94 -0
- package/src/app-sdk/encoding.js +250 -0
- package/src/app-sdk/entropy-contract.js +56 -0
- package/src/app-sdk/filename.js +174 -0
- package/src/app-sdk/forge-url.js +224 -0
- package/src/app-sdk/ids.js +71 -0
- package/src/app-sdk/ingot-access-log.js +51 -0
- package/src/app-sdk/phone.js +139 -0
- package/src/app-sdk/platform-domains.js +99 -0
- package/src/app-sdk/request-path.js +81 -0
- package/src/app-sdk/transfer-retry.js +563 -0
- package/src/app-sdk/transient.js +30 -0
- package/src/app-sdk/upload-publication.js +102 -0
- package/src/app-sdk/vat-refusal.js +74 -0
- package/src/billing.ts +16 -25
- package/src/config.ts +56 -23
- package/src/encoding.ts +91 -103
- package/src/entropy.test-d.ts +47 -0
- package/src/entropy.ts +86 -20
- package/src/errors.ts +135 -38
- package/src/folders.ts +8 -7
- package/src/http.ts +145 -150
- package/src/identity-dialog.tsx +4 -37
- package/src/identity-input.ts +70 -0
- package/src/index.ts +13 -3
- package/src/ingots.ts +225 -180
- package/src/mutex.ts +1 -8
- package/src/notify.test-d.ts +3 -1
- package/src/notify.ts +19 -17
- package/src/products/identity.ts +45 -39
- package/src/request-path.ts +45 -0
- package/src/sparks.ts +16 -13
- package/src/tus.ts +1054 -408
- package/src/types.ts +181 -23
- package/src/users.ts +27 -17
- package/src/validation.ts +30 -24
- package/src/vaults.test-d.ts +29 -0
- package/src/vaults.ts +87 -153
- package/dist/platform-domains.generated.d.ts +0 -2
- package/dist/platform-domains.generated.js +0 -16
- package/dist/platform-domains.generated.js.map +0 -1
- package/src/platform-domains.generated.ts +0 -17
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ledger reference of an upload's transfer charge,
|
|
3
|
+
* `forge_ingot_transfer_upload_<first 24 ISTK chars>`: every charge of one
|
|
4
|
+
* upload carries it — Core's activation, Core's charge of an upload that never
|
|
5
|
+
* publishes, Forge's cancel — so whichever lands first is the upload's one
|
|
6
|
+
* ledger row and the others are duplicates.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} istk - The upload's ISTK, as its session carries it
|
|
9
|
+
* @returns {string}
|
|
10
|
+
* @throws {TypeError} When the ISTK is not a string of at least
|
|
11
|
+
* TRANSFER_REFERENCE_ISTK_CHARS characters
|
|
12
|
+
*/
|
|
13
|
+
export function uploadTransferReference(istk: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* The upload publication contract between Forge and Core's activation.
|
|
16
|
+
*
|
|
17
|
+
* Forge stamps UPLOAD_PUBLICATION_PROTOCOL on every upload session it creates
|
|
18
|
+
* and on the final state it hands Core's activation (POST
|
|
19
|
+
* /v1/vaults/:vault_id/ingots/:ingot_id/activate); activation refuses any
|
|
20
|
+
* other version. The two services deploy separately, so a change to what
|
|
21
|
+
* either side sends or expects moves this number: a session or a finalize
|
|
22
|
+
* from the other side's contract then fails closed ("restart the upload")
|
|
23
|
+
* instead of publishing under a contract the other side does not hold.
|
|
24
|
+
*
|
|
25
|
+
* Version 2: an upload's own metadata (content type, original file name,
|
|
26
|
+
* uploader, content HMAC) travels on its upload token and its session, and
|
|
27
|
+
* activation publishes it from the session; the final state Forge sends
|
|
28
|
+
* carries only the storage facts Forge owns.
|
|
29
|
+
*
|
|
30
|
+
* Isomorphic: no Node imports.
|
|
31
|
+
*/
|
|
32
|
+
export const UPLOAD_PUBLICATION_PROTOCOL: 2;
|
|
33
|
+
/**
|
|
34
|
+
* An upload's id as both services spell it: `tus_` and the 32 lowercase hex
|
|
35
|
+
* digits of 16 random bytes. An encrypt token that names one (`upload_id`)
|
|
36
|
+
* was staged by Core under it, and Forge keys the upload's session, its chunk
|
|
37
|
+
* prefix and its VAK wrapping by it, so Core finds and settles the upload by
|
|
38
|
+
* the session's id.
|
|
39
|
+
*/
|
|
40
|
+
export const UPLOAD_ID_PATTERN: RegExp;
|
|
41
|
+
/**
|
|
42
|
+
* How much of an ISTK names a transfer's charge on the usage ledger: enough to
|
|
43
|
+
* be unique to the token, never the whole bearer credential.
|
|
44
|
+
*/
|
|
45
|
+
export const TRANSFER_REFERENCE_ISTK_CHARS: 24;
|
|
46
|
+
/**
|
|
47
|
+
* The codes Core's activation refuses an upload with, which Forge's refusal
|
|
48
|
+
* map reads (the status is Core's):
|
|
49
|
+
* - UPLOAD_CONTRACT_MISMATCH (409): a finalize or session from another
|
|
50
|
+
* publication contract than Core's, a mixed deployment that converges — the
|
|
51
|
+
* upload is kept and its finalize tried again.
|
|
52
|
+
* - UPLOAD_PROTOCOL_RETIRED (410): a session from a contract Core no longer
|
|
53
|
+
* publishes, which never can be.
|
|
54
|
+
* - UPLOAD_SUPERSEDED (410): a session a later staging of its ingot
|
|
55
|
+
* superseded, which never can be.
|
|
56
|
+
* - UPLOAD_POOL_FULL (402): an upload the owner's storage pool cannot take at
|
|
57
|
+
* publication, which is final.
|
|
58
|
+
*/
|
|
59
|
+
export const UPLOAD_REFUSAL_CODES: Readonly<{
|
|
60
|
+
UPLOAD_CONTRACT_MISMATCH: "UPLOAD_CONTRACT_MISMATCH";
|
|
61
|
+
UPLOAD_PROTOCOL_RETIRED: "UPLOAD_PROTOCOL_RETIRED";
|
|
62
|
+
UPLOAD_SUPERSEDED: "UPLOAD_SUPERSEDED";
|
|
63
|
+
UPLOAD_POOL_FULL: "UPLOAD_POOL_FULL";
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* The refusals of Core's that a new upload of the same file cannot remedy:
|
|
67
|
+
* the owner's storage pool cannot take it (UPLOAD_POOL_FULL), or a later
|
|
68
|
+
* upload of its ingot replaced it (UPLOAD_SUPERSEDED). Any other code Core
|
|
69
|
+
* ends an upload with ends its session alone, which a new upload starts
|
|
70
|
+
* over. Every client reads a terminal answer's code by it
|
|
71
|
+
* (transfer-retry.js): one of these is a refusal it reports in Core's words,
|
|
72
|
+
* any other a gone session.
|
|
73
|
+
*/
|
|
74
|
+
export const UPLOAD_FINAL_REFUSAL_CODES: readonly ("UPLOAD_SUPERSEDED" | "UPLOAD_POOL_FULL")[];
|
|
75
|
+
/**
|
|
76
|
+
* The response header that names the code Core refused an upload with for
|
|
77
|
+
* good: Forge sends it on every terminal answer to a tus request, a HEAD's
|
|
78
|
+
* (which has no body) included, so a client tells an upload the owner's pool
|
|
79
|
+
* cannot take from one a later upload superseded without reading a body.
|
|
80
|
+
*/
|
|
81
|
+
export const UPLOAD_REFUSAL_HEADER: "X-Upload-Refusal";
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// GENERATED FILE — do not edit by hand.
|
|
2
|
+
// Source of truth: packages/app-sdk/src/upload-publication.js
|
|
3
|
+
// Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
|
|
4
|
+
/**
|
|
5
|
+
* The upload publication contract between Forge and Core's activation.
|
|
6
|
+
*
|
|
7
|
+
* Forge stamps UPLOAD_PUBLICATION_PROTOCOL on every upload session it creates
|
|
8
|
+
* and on the final state it hands Core's activation (POST
|
|
9
|
+
* /v1/vaults/:vault_id/ingots/:ingot_id/activate); activation refuses any
|
|
10
|
+
* other version. The two services deploy separately, so a change to what
|
|
11
|
+
* either side sends or expects moves this number: a session or a finalize
|
|
12
|
+
* from the other side's contract then fails closed ("restart the upload")
|
|
13
|
+
* instead of publishing under a contract the other side does not hold.
|
|
14
|
+
*
|
|
15
|
+
* Version 2: an upload's own metadata (content type, original file name,
|
|
16
|
+
* uploader, content HMAC) travels on its upload token and its session, and
|
|
17
|
+
* activation publishes it from the session; the final state Forge sends
|
|
18
|
+
* carries only the storage facts Forge owns.
|
|
19
|
+
*
|
|
20
|
+
* Isomorphic: no Node imports.
|
|
21
|
+
*/
|
|
22
|
+
export const UPLOAD_PUBLICATION_PROTOCOL = 2;
|
|
23
|
+
/**
|
|
24
|
+
* An upload's id as both services spell it: `tus_` and the 32 lowercase hex
|
|
25
|
+
* digits of 16 random bytes. An encrypt token that names one (`upload_id`)
|
|
26
|
+
* was staged by Core under it, and Forge keys the upload's session, its chunk
|
|
27
|
+
* prefix and its VAK wrapping by it, so Core finds and settles the upload by
|
|
28
|
+
* the session's id.
|
|
29
|
+
*/
|
|
30
|
+
export const UPLOAD_ID_PATTERN = /^tus_[0-9a-f]{32}$/;
|
|
31
|
+
/**
|
|
32
|
+
* How much of an ISTK names a transfer's charge on the usage ledger: enough to
|
|
33
|
+
* be unique to the token, never the whole bearer credential.
|
|
34
|
+
*/
|
|
35
|
+
export const TRANSFER_REFERENCE_ISTK_CHARS = 24;
|
|
36
|
+
/**
|
|
37
|
+
* The ledger reference of an upload's transfer charge,
|
|
38
|
+
* `forge_ingot_transfer_upload_<first 24 ISTK chars>`: every charge of one
|
|
39
|
+
* upload carries it — Core's activation, Core's charge of an upload that never
|
|
40
|
+
* publishes, Forge's cancel — so whichever lands first is the upload's one
|
|
41
|
+
* ledger row and the others are duplicates.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} istk - The upload's ISTK, as its session carries it
|
|
44
|
+
* @returns {string}
|
|
45
|
+
* @throws {TypeError} When the ISTK is not a string of at least
|
|
46
|
+
* TRANSFER_REFERENCE_ISTK_CHARS characters
|
|
47
|
+
*/
|
|
48
|
+
export function uploadTransferReference(istk) {
|
|
49
|
+
if (typeof istk !== 'string' || istk.length < TRANSFER_REFERENCE_ISTK_CHARS) {
|
|
50
|
+
throw new TypeError(`An upload's transfer reference is named from its ISTK, a string of at least ${TRANSFER_REFERENCE_ISTK_CHARS} characters`);
|
|
51
|
+
}
|
|
52
|
+
return `forge_ingot_transfer_upload_${istk.slice(0, TRANSFER_REFERENCE_ISTK_CHARS)}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The codes Core's activation refuses an upload with, which Forge's refusal
|
|
56
|
+
* map reads (the status is Core's):
|
|
57
|
+
* - UPLOAD_CONTRACT_MISMATCH (409): a finalize or session from another
|
|
58
|
+
* publication contract than Core's, a mixed deployment that converges — the
|
|
59
|
+
* upload is kept and its finalize tried again.
|
|
60
|
+
* - UPLOAD_PROTOCOL_RETIRED (410): a session from a contract Core no longer
|
|
61
|
+
* publishes, which never can be.
|
|
62
|
+
* - UPLOAD_SUPERSEDED (410): a session a later staging of its ingot
|
|
63
|
+
* superseded, which never can be.
|
|
64
|
+
* - UPLOAD_POOL_FULL (402): an upload the owner's storage pool cannot take at
|
|
65
|
+
* publication, which is final.
|
|
66
|
+
*/
|
|
67
|
+
export const UPLOAD_REFUSAL_CODES = Object.freeze({
|
|
68
|
+
UPLOAD_CONTRACT_MISMATCH: 'UPLOAD_CONTRACT_MISMATCH',
|
|
69
|
+
UPLOAD_PROTOCOL_RETIRED: 'UPLOAD_PROTOCOL_RETIRED',
|
|
70
|
+
UPLOAD_SUPERSEDED: 'UPLOAD_SUPERSEDED',
|
|
71
|
+
UPLOAD_POOL_FULL: 'UPLOAD_POOL_FULL'
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* The refusals of Core's that a new upload of the same file cannot remedy:
|
|
75
|
+
* the owner's storage pool cannot take it (UPLOAD_POOL_FULL), or a later
|
|
76
|
+
* upload of its ingot replaced it (UPLOAD_SUPERSEDED). Any other code Core
|
|
77
|
+
* ends an upload with ends its session alone, which a new upload starts
|
|
78
|
+
* over. Every client reads a terminal answer's code by it
|
|
79
|
+
* (transfer-retry.js): one of these is a refusal it reports in Core's words,
|
|
80
|
+
* any other a gone session.
|
|
81
|
+
*/
|
|
82
|
+
export const UPLOAD_FINAL_REFUSAL_CODES = Object.freeze([
|
|
83
|
+
UPLOAD_REFUSAL_CODES.UPLOAD_POOL_FULL,
|
|
84
|
+
UPLOAD_REFUSAL_CODES.UPLOAD_SUPERSEDED
|
|
85
|
+
]);
|
|
86
|
+
/**
|
|
87
|
+
* The response header that names the code Core refused an upload with for
|
|
88
|
+
* good: Forge sends it on every terminal answer to a tus request, a HEAD's
|
|
89
|
+
* (which has no body) included, so a client tells an upload the owner's pool
|
|
90
|
+
* cannot take from one a later upload superseded without reading a body.
|
|
91
|
+
*/
|
|
92
|
+
export const UPLOAD_REFUSAL_HEADER = 'X-Upload-Refusal';
|
|
93
|
+
//# sourceMappingURL=upload-publication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-publication.js","sourceRoot":"","sources":["../../src/app-sdk/upload-publication.js"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,8DAA8D;AAC9D,8DAA8D;AAE9D;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAI;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,6BAA6B,EAAE,CAAC;QAC5E,MAAM,IAAI,SAAS,CACjB,+EAA+E,6BAA6B,aAAa,CAC1H,CAAC;IACJ,CAAC;IACD,OAAO,+BAA+B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,EAAE,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,wBAAwB,EAAE,0BAA0B;IACpD,uBAAuB,EAAE,yBAAyB;IAClD,iBAAiB,EAAE,mBAAmB;IACtC,gBAAgB,EAAE,kBAAkB;CACrC,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,oBAAoB,CAAC,gBAAgB;IACrC,oBAAoB,CAAC,iBAAiB;CACvC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The VAT refusal a Core error answer names, or null when it is not one.
|
|
3
|
+
*
|
|
4
|
+
* @param {{ statusCode?: number, details?: { reason?: string } }} error - An
|
|
5
|
+
* error as parsed from a Core response (status plus the body's `details`)
|
|
6
|
+
* @returns {string|null} One of VAT_REFUSAL_REASONS, or null
|
|
7
|
+
*/
|
|
8
|
+
export function vatRefusalReason(error: {
|
|
9
|
+
statusCode?: number;
|
|
10
|
+
details?: {
|
|
11
|
+
reason?: string;
|
|
12
|
+
};
|
|
13
|
+
}): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Whether a refusal says the token's vault session is over: an invalid or an
|
|
16
|
+
* expired token, which only a new unseal replaces, so a client forgets it. A
|
|
17
|
+
* read-only refusal leaves the session standing (the token still reads), and
|
|
18
|
+
* so does a refusal that names no VAT reason.
|
|
19
|
+
*
|
|
20
|
+
* @param {string|null} reason - What vatRefusalReason returned
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
export function endsVatSession(reason: string | null): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* True when Core refused the request's login, not a Vault Access Token it
|
|
26
|
+
* carried: a 401 bearing Core's session code (AUTHENTICATION_ERROR, the
|
|
27
|
+
* mapped error's `upstreamCode`) that names no VAT refusal. Its token was
|
|
28
|
+
* refused, or its account is unavailable (details.reason ACCOUNT_UNAVAILABLE,
|
|
29
|
+
* ./refusal-reasons.js). A 401 for a credential in the request body (an
|
|
30
|
+
* unseal key) carries Core's credential code (UNAUTHORIZED) and is not one.
|
|
31
|
+
*
|
|
32
|
+
* @param {{ statusCode?: number, upstreamCode?: string|null, details?: { reason?: string } }} error -
|
|
33
|
+
* An error as parsed from a Core response (parseApiError)
|
|
34
|
+
* @returns {boolean}
|
|
35
|
+
*/
|
|
36
|
+
export function isRefusedLogin(error: {
|
|
37
|
+
statusCode?: number;
|
|
38
|
+
upstreamCode?: string | null;
|
|
39
|
+
details?: {
|
|
40
|
+
reason?: string;
|
|
41
|
+
};
|
|
42
|
+
}): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Why Core refused a Vault Access Token (VAT): the `details.reason` every VAT
|
|
45
|
+
* refusal carries, and the one reading of it clients share.
|
|
46
|
+
*
|
|
47
|
+
* 401 VAT_INVALID no token, or a malformed, unknown or swept one, or one a
|
|
48
|
+
* since-revoked DVAK minted — unseal again
|
|
49
|
+
* 403 VAT_EXPIRED the token outlived its TTL — unseal again, retry as-is
|
|
50
|
+
* 403 VAT_READ_ONLY a View Only token on a write — no unseal fixes it
|
|
51
|
+
*
|
|
52
|
+
* A 403 with no reason is a token for another vault or account, which no
|
|
53
|
+
* unseal of this vault fixes; a 401 with no reason is the login itself, never
|
|
54
|
+
* the VAT. Browser-safe: no imports.
|
|
55
|
+
*/
|
|
56
|
+
export const VAT_REFUSAL_REASONS: Readonly<{
|
|
57
|
+
INVALID: "VAT_INVALID";
|
|
58
|
+
EXPIRED: "VAT_EXPIRED";
|
|
59
|
+
READ_ONLY: "VAT_READ_ONLY";
|
|
60
|
+
}>;
|
|
61
|
+
/** The status each refusal is answered with. */
|
|
62
|
+
export const VAT_REFUSAL_STATUS: Readonly<{
|
|
63
|
+
VAT_INVALID: 401;
|
|
64
|
+
VAT_EXPIRED: 403;
|
|
65
|
+
VAT_READ_ONLY: 403;
|
|
66
|
+
}>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// GENERATED FILE — do not edit by hand.
|
|
2
|
+
// Source of truth: packages/app-sdk/src/vat-refusal.js
|
|
3
|
+
// Regenerate with: pnpm --filter @sparkvault/sdk-mobile build
|
|
4
|
+
/**
|
|
5
|
+
* Why Core refused a Vault Access Token (VAT): the `details.reason` every VAT
|
|
6
|
+
* refusal carries, and the one reading of it clients share.
|
|
7
|
+
*
|
|
8
|
+
* 401 VAT_INVALID no token, or a malformed, unknown or swept one, or one a
|
|
9
|
+
* since-revoked DVAK minted — unseal again
|
|
10
|
+
* 403 VAT_EXPIRED the token outlived its TTL — unseal again, retry as-is
|
|
11
|
+
* 403 VAT_READ_ONLY a View Only token on a write — no unseal fixes it
|
|
12
|
+
*
|
|
13
|
+
* A 403 with no reason is a token for another vault or account, which no
|
|
14
|
+
* unseal of this vault fixes; a 401 with no reason is the login itself, never
|
|
15
|
+
* the VAT. Browser-safe: no imports.
|
|
16
|
+
*/
|
|
17
|
+
export const VAT_REFUSAL_REASONS = Object.freeze({
|
|
18
|
+
INVALID: 'VAT_INVALID',
|
|
19
|
+
EXPIRED: 'VAT_EXPIRED',
|
|
20
|
+
READ_ONLY: 'VAT_READ_ONLY'
|
|
21
|
+
});
|
|
22
|
+
/** The status each refusal is answered with. */
|
|
23
|
+
export const VAT_REFUSAL_STATUS = Object.freeze({
|
|
24
|
+
[VAT_REFUSAL_REASONS.INVALID]: 401,
|
|
25
|
+
[VAT_REFUSAL_REASONS.EXPIRED]: 403,
|
|
26
|
+
[VAT_REFUSAL_REASONS.READ_ONLY]: 403
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* The VAT refusal a Core error answer names, or null when it is not one.
|
|
30
|
+
*
|
|
31
|
+
* @param {{ statusCode?: number, details?: { reason?: string } }} error - An
|
|
32
|
+
* error as parsed from a Core response (status plus the body's `details`)
|
|
33
|
+
* @returns {string|null} One of VAT_REFUSAL_REASONS, or null
|
|
34
|
+
*/
|
|
35
|
+
export function vatRefusalReason(error) {
|
|
36
|
+
const reason = error?.details?.reason;
|
|
37
|
+
return typeof reason === 'string' && Object.hasOwn(VAT_REFUSAL_STATUS, reason) &&
|
|
38
|
+
VAT_REFUSAL_STATUS[reason] === error?.statusCode
|
|
39
|
+
? reason
|
|
40
|
+
: null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Whether a refusal says the token's vault session is over: an invalid or an
|
|
44
|
+
* expired token, which only a new unseal replaces, so a client forgets it. A
|
|
45
|
+
* read-only refusal leaves the session standing (the token still reads), and
|
|
46
|
+
* so does a refusal that names no VAT reason.
|
|
47
|
+
*
|
|
48
|
+
* @param {string|null} reason - What vatRefusalReason returned
|
|
49
|
+
* @returns {boolean}
|
|
50
|
+
*/
|
|
51
|
+
export function endsVatSession(reason) {
|
|
52
|
+
return reason === VAT_REFUSAL_REASONS.INVALID || reason === VAT_REFUSAL_REASONS.EXPIRED;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* True when Core refused the request's login, not a Vault Access Token it
|
|
56
|
+
* carried: a 401 bearing Core's session code (AUTHENTICATION_ERROR, the
|
|
57
|
+
* mapped error's `upstreamCode`) that names no VAT refusal. Its token was
|
|
58
|
+
* refused, or its account is unavailable (details.reason ACCOUNT_UNAVAILABLE,
|
|
59
|
+
* ./refusal-reasons.js). A 401 for a credential in the request body (an
|
|
60
|
+
* unseal key) carries Core's credential code (UNAUTHORIZED) and is not one.
|
|
61
|
+
*
|
|
62
|
+
* @param {{ statusCode?: number, upstreamCode?: string|null, details?: { reason?: string } }} error -
|
|
63
|
+
* An error as parsed from a Core response (parseApiError)
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
export function isRefusedLogin(error) {
|
|
67
|
+
return error?.statusCode === 401 && error?.upstreamCode === 'AUTHENTICATION_ERROR' && vatRefusalReason(error) === null;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=vat-refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vat-refusal.js","sourceRoot":"","sources":["../../src/app-sdk/vat-refusal.js"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,uDAAuD;AACvD,8DAA8D;AAE9D;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/C,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,eAAe;CAC3B,CAAC,CAAC;AAEH,gDAAgD;AAChD,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,GAAG;IAClC,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,GAAG;IAClC,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,GAAG;CACrC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAK;IACpC,MAAM,MAAM,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC;IACtC,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC;QAC5E,kBAAkB,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,UAAU;QAChD,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAM;IACnC,OAAO,MAAM,KAAK,mBAAmB,CAAC,OAAO,IAAI,MAAM,KAAK,mBAAmB,CAAC,OAAO,CAAC;AAC1F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,KAAK;IAClC,OAAO,KAAK,EAAE,UAAU,KAAK,GAAG,IAAI,KAAK,EAAE,YAAY,KAAK,sBAAsB,IAAI,gBAAgB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACzH,CAAC"}
|
package/dist/billing.d.ts
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
import type { MobileHttpClient } from './http.js';
|
|
2
|
-
import type { IapPlatform, SparkVaultSubscription } from './types.js';
|
|
3
|
-
/** Short-lived Stripe Customer Portal URL for managing the subscription on web. */
|
|
4
|
-
export interface PortalSession {
|
|
5
|
-
portal_url: string;
|
|
6
|
-
}
|
|
2
|
+
import type { IapPlatform, IapValidation, SparkVaultSubscription } from './types.js';
|
|
7
3
|
export declare class MobileBillingClient {
|
|
8
4
|
private readonly http;
|
|
9
5
|
constructor(http: MobileHttpClient);
|
|
10
6
|
/**
|
|
11
|
-
* Current subscription:
|
|
12
|
-
* pool usage, and Identity attempts. Drives the subscription /
|
|
7
|
+
* Current subscription: billing lifecycle, licensed vs. used seats, capacity
|
|
8
|
+
* blocks, live pool usage, and Identity attempts. Drives the subscription /
|
|
9
|
+
* usage view.
|
|
13
10
|
*/
|
|
14
11
|
getSubscription(): Promise<SparkVaultSubscription>;
|
|
15
12
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
createPortalSession(): Promise<PortalSession>;
|
|
21
|
-
/**
|
|
22
|
-
* Validate a native in-app purchase receipt server-side and apply the
|
|
23
|
-
* resulting entitlements. Returns the refreshed subscription so the client
|
|
24
|
-
* can update its plan / usage view immediately after purchase.
|
|
13
|
+
* Validate a native in-app purchase server-side and apply the entitlements
|
|
14
|
+
* it buys. `receipt` is the App Store signed transaction (JWS) or the Play
|
|
15
|
+
* purchase token. Answers whether Core provisioned the purchase; read the
|
|
16
|
+
* subscription again with getSubscription() to show the change.
|
|
25
17
|
*/
|
|
26
|
-
iapValidate(platform: IapPlatform, productId: string, receipt: string): Promise<
|
|
18
|
+
iapValidate(platform: IapPlatform, productId: string, receipt: string): Promise<IapValidation>;
|
|
27
19
|
}
|
package/dist/billing.js
CHANGED
|
@@ -1,34 +1,31 @@
|
|
|
1
|
+
import { apiPath } from './request-path.js';
|
|
1
2
|
export class MobileBillingClient {
|
|
2
3
|
constructor(http) {
|
|
3
4
|
this.http = http;
|
|
4
5
|
}
|
|
5
6
|
/**
|
|
6
|
-
* Current subscription:
|
|
7
|
-
* pool usage, and Identity attempts. Drives the subscription /
|
|
7
|
+
* Current subscription: billing lifecycle, licensed vs. used seats, capacity
|
|
8
|
+
* blocks, live pool usage, and Identity attempts. Drives the subscription /
|
|
9
|
+
* usage view.
|
|
8
10
|
*/
|
|
9
11
|
async getSubscription() {
|
|
10
|
-
const response = await this.http.get(
|
|
12
|
+
const response = await this.http.get(apiPath `/billing/subscription`);
|
|
11
13
|
return response.data;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
async createPortalSession() {
|
|
19
|
-
const response = await this.http.post('/billing/portal');
|
|
20
|
-
return response.data;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Validate a native in-app purchase receipt server-side and apply the
|
|
24
|
-
* resulting entitlements. Returns the refreshed subscription so the client
|
|
25
|
-
* can update its plan / usage view immediately after purchase.
|
|
16
|
+
* Validate a native in-app purchase server-side and apply the entitlements
|
|
17
|
+
* it buys. `receipt` is the App Store signed transaction (JWS) or the Play
|
|
18
|
+
* purchase token. Answers whether Core provisioned the purchase; read the
|
|
19
|
+
* subscription again with getSubscription() to show the change.
|
|
26
20
|
*/
|
|
27
21
|
async iapValidate(platform, productId, receipt) {
|
|
28
|
-
|
|
22
|
+
// Core reads an App Store purchase's signed transaction as `receipt` and a
|
|
23
|
+
// Play purchase's token as `purchase_token`.
|
|
24
|
+
const credential = platform === 'android' ? { purchase_token: receipt } : { receipt };
|
|
25
|
+
const response = await this.http.post(apiPath `/billing/iap/validate`, {
|
|
29
26
|
platform,
|
|
30
27
|
product_id: productId,
|
|
31
|
-
|
|
28
|
+
...credential,
|
|
32
29
|
});
|
|
33
30
|
return response.data;
|
|
34
31
|
}
|
package/dist/billing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,OAAO,mBAAmB;IAG9B,YAAY,IAAsB;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAyB,OAAO,CAAA,uBAAuB,CAAC,CAAC;QAC7F,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CACf,QAAqB,EACrB,SAAiB,EACjB,OAAe;QAEf,2EAA2E;QAC3E,6CAA6C;QAC7C,MAAM,UAAU,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QACtF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAgB,OAAO,CAAA,uBAAuB,EAAE;YACnF,QAAQ;YACR,UAAU,EAAE,SAAS;YACrB,GAAG,UAAU;SACd,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FetchLike, MobileBackgroundTransfer, MobileBackgroundUploader, MobileFileDownloader, MobileFileReader, SparkVaultLogger, TokenStorageAdapter } from './types.js';
|
|
2
|
+
import { type ApiPath } from './request-path.js';
|
|
2
3
|
export interface SparkVaultMobileConfig {
|
|
3
4
|
tokenStorage: TokenStorageAdapter;
|
|
4
5
|
apiBaseUrl?: string;
|
|
@@ -8,6 +9,11 @@ export interface SparkVaultMobileConfig {
|
|
|
8
9
|
userAgent?: string;
|
|
9
10
|
timeoutMs?: number;
|
|
10
11
|
fileTransferTimeoutMs?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Timeout of a tus create POST and DELETE. A HEAD and the receipt (the
|
|
14
|
+
* PATCH at the final offset) wait HEAD_AND_RECEIPT_TIMEOUT_MS instead:
|
|
15
|
+
* Forge answers either only after its own call to Core.
|
|
16
|
+
*/
|
|
11
17
|
tusPostTimeoutMs?: number;
|
|
12
18
|
/** Stall watchdog per tus chunk PATCH: aborts after this long with NO upload progress (not an absolute deadline). */
|
|
13
19
|
tusChunkTimeoutMs?: number;
|
|
@@ -30,9 +36,34 @@ export interface SparkVaultMobileConfig {
|
|
|
30
36
|
* upload, and every upload when this is unset, streams over XHR.
|
|
31
37
|
*/
|
|
32
38
|
backgroundUploader?: MobileBackgroundUploader;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the device has a network path right now (an app wires it to its
|
|
41
|
+
* OS network signal). Read when an upload request got no answer: while it
|
|
42
|
+
* answers false the upload waits for `onOnline` instead of spending its
|
|
43
|
+
* retries, then asks Forge where the session stands. Only a definite
|
|
44
|
+
* "offline" should answer false; a path that may come up is online. Given
|
|
45
|
+
* together with `onOnline`, or not at all.
|
|
46
|
+
*/
|
|
47
|
+
isOnline?: () => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Subscribe to the network coming back; returns the unsubscribe. The pair
|
|
50
|
+
* of `isOnline`. A wait it ends is otherwise ended only by the upload's
|
|
51
|
+
* `abortSignal`.
|
|
52
|
+
*/
|
|
53
|
+
onOnline?: (listener: () => void) => () => void;
|
|
33
54
|
logger?: Partial<SparkVaultLogger>;
|
|
55
|
+
/**
|
|
56
|
+
* Host allowlist for the backend-issued Forge transfer URLs the SDK sends an
|
|
57
|
+
* ingot's ISTK to (downloads and uploads alike). Defaults to the SparkVault
|
|
58
|
+
* platform's own hosts; override only when pointing at another deployment.
|
|
59
|
+
*/
|
|
34
60
|
allowedDownloadHostPatterns?: RegExp[];
|
|
35
61
|
}
|
|
62
|
+
/** The device's network signal, as the upload's offline wait reads it (`isOnline` with `onOnline`). */
|
|
63
|
+
export interface MobileConnectivity {
|
|
64
|
+
isOnline(): boolean;
|
|
65
|
+
onOnline(listener: () => void): () => void;
|
|
66
|
+
}
|
|
36
67
|
export interface ResolvedMobileConfig {
|
|
37
68
|
tokenStorage: TokenStorageAdapter;
|
|
38
69
|
apiBaseUrl: string;
|
|
@@ -49,8 +80,9 @@ export interface ResolvedMobileConfig {
|
|
|
49
80
|
fileDownloader?: MobileFileDownloader;
|
|
50
81
|
backgroundTransfer?: MobileBackgroundTransfer;
|
|
51
82
|
backgroundUploader?: MobileBackgroundUploader;
|
|
83
|
+
connectivity?: MobileConnectivity;
|
|
52
84
|
logger: SparkVaultLogger;
|
|
53
85
|
allowedDownloadHostPatterns: RegExp[];
|
|
54
86
|
}
|
|
55
87
|
export declare function resolveMobileConfig(config: SparkVaultMobileConfig): ResolvedMobileConfig;
|
|
56
|
-
export declare function identityUrl(config: ResolvedMobileConfig, path:
|
|
88
|
+
export declare function identityUrl(config: ResolvedMobileConfig, path: ApiPath): string;
|
package/dist/config.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { SparkVaultValidationError } from './errors.js';
|
|
2
|
-
import {
|
|
2
|
+
import { isResourceIdOf } from './app-sdk/ids.js';
|
|
3
|
+
import { SPARKVAULT_IDENTITY_HOST, SPARKVAULT_OWNED_HOST_PATTERNS } from './app-sdk/platform-domains.js';
|
|
4
|
+
import { apiPath } from './request-path.js';
|
|
3
5
|
const DEFAULT_API_BASE_URL = 'https://api.sparkvault.com/v1';
|
|
4
|
-
const DEFAULT_IDENTITY_BASE_URL =
|
|
5
|
-
function escapeRegExp(value) {
|
|
6
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
7
|
-
}
|
|
8
|
-
// Hosts that are allowed to serve backend-issued ingot download URLs, derived
|
|
9
|
-
// from the canonical platform domain registry baked in at build time.
|
|
10
|
-
const DEFAULT_ALLOWED_DOWNLOAD_HOST_PATTERNS = [
|
|
11
|
-
new RegExp(`(^|\\.)${escapeRegExp(SPARKVAULT_ROOT_DOMAIN)}$`, 'i'),
|
|
12
|
-
new RegExp(`(^|\\.)(${SPARKVAULT_PLATFORM_SV_HOSTS.map(escapeRegExp).join('|')})$`, 'i'),
|
|
13
|
-
/\.amazonaws\.com$/i,
|
|
14
|
-
/\.cloudfront\.net$/i,
|
|
15
|
-
];
|
|
6
|
+
const DEFAULT_IDENTITY_BASE_URL = `https://${SPARKVAULT_IDENTITY_HOST}`;
|
|
16
7
|
const noopLogger = {
|
|
17
8
|
debug: () => undefined,
|
|
18
9
|
info: () => undefined,
|
|
19
10
|
warn: () => undefined,
|
|
20
11
|
error: () => undefined,
|
|
21
12
|
};
|
|
13
|
+
/** The `isOnline` / `onOnline` pair as one signal, or none: one without the other cannot wait for the network. */
|
|
14
|
+
function resolveConnectivity(config) {
|
|
15
|
+
const { isOnline, onOnline } = config;
|
|
16
|
+
if (isOnline === undefined && onOnline === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (typeof isOnline !== 'function' || typeof onOnline !== 'function') {
|
|
19
|
+
throw new SparkVaultValidationError('isOnline and onOnline are given together, as functions', {
|
|
20
|
+
field: typeof isOnline === 'function' ? 'onOnline' : 'isOnline',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return { isOnline, onOnline };
|
|
24
|
+
}
|
|
22
25
|
function normalizeBaseUrl(url, field) {
|
|
23
26
|
if (!url || typeof url !== 'string') {
|
|
24
27
|
throw new SparkVaultValidationError(`${field} must be a non-empty string`, { field });
|
|
@@ -60,8 +63,10 @@ export function resolveMobileConfig(config) {
|
|
|
60
63
|
received: identityAccountId,
|
|
61
64
|
});
|
|
62
65
|
}
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
// The account id names Identity request paths: the platform's one id
|
|
67
|
+
// grammar keeps it a single path segment.
|
|
68
|
+
if (!isResourceIdOf('account', identityAccountId)) {
|
|
69
|
+
throw new SparkVaultValidationError('identityAccountId must be a SparkVault account id (acc_...)', {
|
|
65
70
|
field: 'identityAccountId',
|
|
66
71
|
received: identityAccountId,
|
|
67
72
|
});
|
|
@@ -82,11 +87,12 @@ export function resolveMobileConfig(config) {
|
|
|
82
87
|
fileDownloader: config.fileDownloader,
|
|
83
88
|
backgroundTransfer: config.backgroundTransfer,
|
|
84
89
|
backgroundUploader: config.backgroundUploader,
|
|
90
|
+
connectivity: resolveConnectivity(config),
|
|
85
91
|
logger: { ...noopLogger, ...config.logger },
|
|
86
|
-
allowedDownloadHostPatterns: config.allowedDownloadHostPatterns ??
|
|
92
|
+
allowedDownloadHostPatterns: config.allowedDownloadHostPatterns ?? [...SPARKVAULT_OWNED_HOST_PATTERNS],
|
|
87
93
|
};
|
|
88
94
|
}
|
|
89
95
|
export function identityUrl(config, path) {
|
|
90
|
-
return `${config.identityBaseUrl}
|
|
96
|
+
return `${config.identityBaseUrl}${apiPath `/${config.identityAccountId}`}${path}`;
|
|
91
97
|
}
|
|
92
98
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/encoding.d.ts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64 and UTF-8 for the mobile SDK.
|
|
3
|
+
*
|
|
4
|
+
* The base64 codec is the platform's one copy, mirrored from
|
|
5
|
+
* `@sparkvault/app-sdk/encoding` into `./app-sdk/encoding.js`; the decoders here
|
|
6
|
+
* raise this SDK's validation error where that codec refuses a text. UTF-8 is
|
|
7
|
+
* converted here rather than with TextEncoder/TextDecoder, which the JavaScript
|
|
8
|
+
* engines of the React Native versions this SDK supports need not provide.
|
|
9
|
+
* Decoding UTF-8 is fatal: bytes that are not UTF-8 are refused, never read as
|
|
10
|
+
* invented characters.
|
|
11
|
+
*/
|
|
12
|
+
import { bytesToBase64, bytesToBase64url } from './app-sdk/encoding.js';
|
|
13
|
+
export { bytesToBase64, bytesToBase64url };
|
|
14
|
+
/**
|
|
15
|
+
* Decode standard base64.
|
|
16
|
+
* @throws SparkVaultValidationError when the text is not base64
|
|
17
|
+
*/
|
|
18
|
+
export declare function base64ToBytes(value: string): Uint8Array;
|
|
19
|
+
/**
|
|
20
|
+
* Decode base64url.
|
|
21
|
+
* @throws SparkVaultValidationError when the text is not base64url
|
|
22
|
+
*/
|
|
23
|
+
export declare function base64UrlToBytes(value: string): Uint8Array;
|
|
1
24
|
export declare function utf8ToBytes(value: string): Uint8Array;
|
|
2
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Decode UTF-8 by the WHATWG decoder's rules in fatal mode: a byte that cannot
|
|
27
|
+
* start a sequence, a sequence cut short, an overlong form, a surrogate or a
|
|
28
|
+
* code point past U+10FFFF refuses the whole input.
|
|
29
|
+
* @throws SparkVaultValidationError when the bytes are not UTF-8
|
|
30
|
+
*/
|
|
3
31
|
export declare function bytesToUtf8(bytes: Uint8Array): string;
|
|
4
|
-
export declare function
|
|
32
|
+
export declare function base64EncodeUtf8(value: string): string;
|
|
5
33
|
export declare function base64UrlToUtf8(value: string): string;
|
|
6
|
-
export declare function bytesToBase64(bytes: Uint8Array): string;
|
|
7
|
-
export declare function base64ToBytes(value: string): Uint8Array;
|