@mdbase-dev/connect 0.1.0-beta.93 → 0.1.0-beta.95
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 +59 -21
- package/dist/application-contract.d.ts +22 -0
- package/dist/application-contract.js +75 -0
- package/dist/application-session.d.ts +10 -10
- package/dist/application-session.js +90 -55
- package/dist/browser/integrity.json +1 -1
- package/dist/browser/mdbase-connect.min.js +3 -3
- package/dist/browser/mdbase-connect.min.js.sha384 +1 -1
- package/dist/capabilities.d.ts +4 -3
- package/dist/capabilities.js +25 -47
- package/dist/connect-options.d.ts +2 -1
- package/dist/connect.d.ts +2 -1
- package/dist/connect.js +41 -34
- package/dist/connection-transport-internals.d.ts +1 -1
- package/dist/connection-transport.js +1 -1
- package/dist/connection.d.ts +11 -0
- package/dist/connection.js +38 -11
- package/dist/index.d.ts +3 -1
- package/dist/internal-types.d.ts +4 -2
- package/dist/internal-types.js +1 -1
- package/dist/mdbase-connect.d.ts +1 -1
- package/dist/operation-types.d.ts +4 -3
- package/dist/outcomes.d.ts +3 -3
- package/dist/outcomes.js +1 -0
- package/dist/request-coordinator.js +1 -0
- package/dist/runtime-utils.d.ts +11 -1
- package/dist/runtime-utils.js +18 -0
- package/dist/session.d.ts +12 -5
- package/dist/session.js +41 -8
- package/dist/stored-token.d.ts +1 -1
- package/dist/stored-token.js +8 -4
- package/dist/structured-readiness.d.ts +77 -0
- package/dist/structured-readiness.js +126 -0
- package/dist/token-response.js +4 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
sha384-
|
|
1
|
+
sha384-pt5qe5l2IuGgDjsId1oPNVT/zCR+0TLeEJNt6xKdZQSxAACXxaCqoxbZd37EriJh
|
package/dist/capabilities.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ApplicationCapabilityRequirements, type LegacyApplicationCapabilityRequirements } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { MdbaseApplicationCapabilityId as ApplicationCapabilityId, MdbaseApplicationManifest as MdbaseAppManifest } from "./application-contract.js";
|
|
2
3
|
import type { MdbaseConnectionInfo } from "./connection-types.js";
|
|
3
4
|
export type MdbaseCapabilityState = "available" | "requires_authorization" | "requires_setup" | "temporarily_unavailable" | "unsupported";
|
|
4
5
|
export interface MdbaseCapabilityEvidence {
|
|
@@ -16,8 +17,8 @@ export interface MdbaseEffectiveCapability {
|
|
|
16
17
|
details?: Record<string, unknown>;
|
|
17
18
|
}
|
|
18
19
|
export interface MdbaseEffectiveCapabilities {
|
|
19
|
-
contractVersion: 1;
|
|
20
|
+
contractVersion: 1 | 2;
|
|
20
21
|
values: Partial<Record<ApplicationCapabilityId, MdbaseEffectiveCapability>>;
|
|
21
22
|
requiredAvailable: boolean;
|
|
22
23
|
}
|
|
23
|
-
export declare function effectiveCapabilities(requirements: ApplicationCapabilityRequirements, manifest: MdbaseAppManifest, connection: MdbaseConnectionInfo): MdbaseEffectiveCapabilities;
|
|
24
|
+
export declare function effectiveCapabilities(requirements: ApplicationCapabilityRequirements | LegacyApplicationCapabilityRequirements, manifest: MdbaseAppManifest, connection: MdbaseConnectionInfo): MdbaseEffectiveCapabilities;
|
package/dist/capabilities.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { capabilityOperationsForContractVersion } from "@mdbase-dev/connect-protocol";
|
|
2
2
|
export function effectiveCapabilities(requirements, manifest, connection) {
|
|
3
3
|
const required = new Set(requirements.required);
|
|
4
4
|
const declared = [...new Set([...requirements.required, ...(requirements.optional ?? [])])];
|
|
5
5
|
const values = {};
|
|
6
6
|
for (const id of declared) {
|
|
7
|
-
values[id] = effectiveCapability(id, required.has(id),
|
|
7
|
+
values[id] = effectiveCapability(id, required.has(id), connection, requirements.contract_version, manifest);
|
|
8
8
|
}
|
|
9
9
|
return {
|
|
10
|
-
contractVersion:
|
|
10
|
+
contractVersion: requirements.contract_version,
|
|
11
11
|
values,
|
|
12
12
|
requiredAvailable: requirements.required.every((id) => values[id]?.state === "available")
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
function effectiveCapability(id, required,
|
|
16
|
-
const operations =
|
|
15
|
+
function effectiveCapability(id, required, connection, version, manifest) {
|
|
16
|
+
const operations = capabilityOperationsForContractVersion(version, id) ?? [];
|
|
17
17
|
const missingOperations = operations.filter((operation) => !connection.operations.includes(operation));
|
|
18
18
|
const base = {
|
|
19
19
|
id,
|
|
@@ -22,7 +22,7 @@ function effectiveCapability(id, required, manifest, connection) {
|
|
|
22
22
|
missingOperations,
|
|
23
23
|
evidence: [{
|
|
24
24
|
source: "application",
|
|
25
|
-
fact: `${required ? "Required" : "Optional"} in capability contract
|
|
25
|
+
fact: `${required ? "Required" : "Optional"} in capability contract v${version}.`
|
|
26
26
|
}]
|
|
27
27
|
};
|
|
28
28
|
if (missingOperations.length > 0) {
|
|
@@ -36,52 +36,31 @@ function effectiveCapability(id, required, manifest, connection) {
|
|
|
36
36
|
reason: "The current grant does not include every operation for this capability."
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
source: "authorization",
|
|
50
|
-
fact: `Missing ${missingContracts.map(({ id, version }) => `${id}@${version}`).join(", ")}.`
|
|
51
|
-
}],
|
|
52
|
-
details: { missingContracts }
|
|
53
|
-
};
|
|
54
|
-
}
|
|
39
|
+
if (connection.scope.access !== "full_collection") {
|
|
40
|
+
return {
|
|
41
|
+
...base,
|
|
42
|
+
state: "requires_authorization",
|
|
43
|
+
reason: "The current grant uses legacy contract scope and must be reauthorized for the entire collection.",
|
|
44
|
+
evidence: [...base.evidence, {
|
|
45
|
+
source: "authorization",
|
|
46
|
+
fact: "Legacy contract scope is compatibility evidence, not active data authority."
|
|
47
|
+
}]
|
|
48
|
+
};
|
|
55
49
|
}
|
|
56
|
-
|
|
50
|
+
// Compatibility readiness is deliberately limited to v1 aliases. V2 needs
|
|
51
|
+
// structured file/notification/runtime evidence, not these legacy shortcuts.
|
|
52
|
+
if (version === 1 && id.startsWith("files.")) {
|
|
57
53
|
const action = id.slice("files.".length);
|
|
58
54
|
if (!connection.fileCapability?.actions.includes(action)) {
|
|
59
55
|
return {
|
|
60
56
|
...base,
|
|
61
57
|
state: connection.fileCapability ? "requires_authorization" : "unsupported",
|
|
62
|
-
reason: connection.fileCapability
|
|
63
|
-
? `The current file grant does not include ${action}.`
|
|
64
|
-
: "This connection has no file capability.",
|
|
65
|
-
evidence: [...base.evidence, {
|
|
66
|
-
source: "authorization",
|
|
67
|
-
fact: connection.fileCapability
|
|
68
|
-
? `Granted file actions: ${connection.fileCapability.actions.join(", ")}.`
|
|
69
|
-
: "No file capability was granted."
|
|
70
|
-
}]
|
|
58
|
+
reason: connection.fileCapability ? `The current file grant does not include ${action}.` : "This connection has no file capability."
|
|
71
59
|
};
|
|
72
60
|
}
|
|
73
61
|
}
|
|
74
|
-
if (id === "notifications.background-delivery"
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
...base,
|
|
78
|
-
state: "requires_setup",
|
|
79
|
-
reason: "The application manifest declares no notification criteria.",
|
|
80
|
-
evidence: [...base.evidence, {
|
|
81
|
-
source: "application",
|
|
82
|
-
fact: "No authority notification criteria are declared."
|
|
83
|
-
}]
|
|
84
|
-
};
|
|
62
|
+
if (version === 1 && id === "notifications.background-delivery" && (manifest.notifications?.criteria.length ?? 0) === 0) {
|
|
63
|
+
return { ...base, state: "requires_setup", reason: "The application manifest declares no notification criteria." };
|
|
85
64
|
}
|
|
86
65
|
return {
|
|
87
66
|
...base,
|
|
@@ -97,7 +76,7 @@ function effectiveCapability(id, required, manifest, connection) {
|
|
|
97
76
|
? "Backed by a durable hosted mdbase authority."
|
|
98
77
|
: "Backed by a user-operated mdbase connector."
|
|
99
78
|
}],
|
|
100
|
-
...(id === "sync.offline-replica"
|
|
79
|
+
...(id === "offline.replica" || (version === 1 && id === "sync.offline-replica")
|
|
101
80
|
? {
|
|
102
81
|
details: {
|
|
103
82
|
durability: "device",
|
|
@@ -106,8 +85,7 @@ function effectiveCapability(id, required, manifest, connection) {
|
|
|
106
85
|
}
|
|
107
86
|
}
|
|
108
87
|
: {}),
|
|
109
|
-
...(id === "notifications.background-delivery"
|
|
110
|
-
? { details: { delivery: "authority", payload: "opaque" } }
|
|
111
|
-
: {})
|
|
88
|
+
...(version === 1 && id === "notifications.background-delivery"
|
|
89
|
+
? { details: { delivery: "authority", payload: "opaque" } } : {})
|
|
112
90
|
};
|
|
113
91
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MdbaseApplicationManifest as MdbaseAppManifest } from "./application-contract.js";
|
|
2
|
+
import type { JsonObject } from "@mdbase-dev/connect-protocol";
|
|
2
3
|
import type { GrantKeyStore } from "./crypto.js";
|
|
3
4
|
import type { ApplicationIdentityStore } from "./application-identity.js";
|
|
4
5
|
export interface MdbaseConnectTimeouts {
|
package/dist/connect.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { JsonObject
|
|
1
|
+
import type { JsonObject } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { type MdbaseApplicationManifest as MdbaseAppManifest } from "./application-contract.js";
|
|
2
3
|
import { type ApplicationIdentityStore } from "./application-identity.js";
|
|
3
4
|
import { MdbaseConnection, type MdbaseAuthorizationOutcome, type MdbaseAuthorizationResult, type MdbaseAuthorizeOptions, type MdbaseConnectEnvironment } from "./connection.js";
|
|
4
5
|
import type { MdbaseConnectOptions } from "./connect-options.js";
|
package/dist/connect.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { APPLICATION_AUTHORIZATION_PROTOCOL_VERSION, authorizationContractRequirements, DEFAULT_LOOPBACK_PORT, GRANT_ENCRYPTION_PROTOCOL_VERSION, RELAY_ENCRYPTION_SUITE } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { authorizationOperations, authorizationFiles, semanticContractVersion, validateAuthorizationSelection } from "./application-contract.js";
|
|
2
3
|
import { abortableDelay } from "./async.js";
|
|
3
4
|
import { authorizationCallbackState } from "./authorization-url.js";
|
|
4
5
|
import { randomBase64Url } from "./base64.js";
|
|
@@ -7,14 +8,12 @@ import { MdbaseConnection } from "./connection.js";
|
|
|
7
8
|
import { addConnectionId, connectionIds, removeConnectionId } from "./connection-index.js";
|
|
8
9
|
import { authorizationAbort, declarationIdFromFamilyIdentity } from "./connect-authorization-helpers.js";
|
|
9
10
|
import { IndexedDbGrantKeyStore, MemoryGrantKeyStore } from "./crypto.js";
|
|
10
|
-
import { connectError, serverConnectError } from "./errors.js";
|
|
11
|
-
import { DEFAULT_OPERATIONS } from "./internal-types.js";
|
|
11
|
+
import { MdbaseConnectError, connectError, serverConnectError } from "./errors.js";
|
|
12
12
|
import { prepareAuthorizationWindow, publishPopupAuthorizationCompletion, waitForPopupAuthorization } from "./popup-authorization.js";
|
|
13
|
-
import { uniqueOperations } from "./operation-helpers.js";
|
|
14
13
|
import { pendingRecoveryTransports, removePendingMutations } from "./pending-recovery-transports.js";
|
|
15
14
|
import { GrantKeyLeaseRegistry } from "./grant-key-leases.js";
|
|
16
15
|
import { resolveConnectTimeouts, withRequestBudget } from "./request-budget.js";
|
|
17
|
-
import { MemoryStorage, apiError, applicationStorageOrigin, canonicalLoopbackUrl, collectionIdFromTokenKey, connectFetch, createPkce,
|
|
16
|
+
import { MemoryStorage, apiError, applicationStorageOrigin, canonicalLoopbackUrl, collectionIdFromTokenKey, connectFetch, createPkce, defaultStorage, decodeJsonResponse, isOpaquePortableManifest, resolveManifestSource, oauthErrorCode, parseDeviceAuthorization, parseStored, stripTrailingSlash, validAuthorityTokenResponse } from "./runtime-utils.js";
|
|
18
17
|
import { storedTokenFromResponse } from "./token-response.js";
|
|
19
18
|
import { deleteUnusedGrantKey, planRetiredGrantKeys, storedTokenKeyHandles } from "./retired-grant-keys.js";
|
|
20
19
|
import { SharedOperationMap } from "./shared-operation.js";
|
|
@@ -41,18 +40,11 @@ export class MdbaseConnectInternals {
|
|
|
41
40
|
invalidatedConnections = new Map();
|
|
42
41
|
constructor(options) {
|
|
43
42
|
this.serverUrl = stripTrailingSlash(String(options.serverUrl));
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.manifestSource = typeof this.manifest === "string"
|
|
48
|
-
? this.manifest
|
|
49
|
-
: this.manifest.distribution === "portable"
|
|
50
|
-
? `bundle:${this.manifest.id}:${manifestStorageFingerprint(this.manifest)}`
|
|
51
|
-
: `bundle:${this.manifest.id}`;
|
|
43
|
+
const declaration = resolveManifestSource(options.manifest, options.redirectUri);
|
|
44
|
+
this.manifest = declaration.manifest;
|
|
45
|
+
this.manifestSource = declaration.manifestSource;
|
|
52
46
|
const opaquePortable = isOpaquePortableManifest(this.manifest);
|
|
53
|
-
this.redirectUri =
|
|
54
|
-
? ""
|
|
55
|
-
: defaultRedirectUri()) : String(options.redirectUri);
|
|
47
|
+
this.redirectUri = declaration.redirectUri;
|
|
56
48
|
this.storage = options.storage ?? defaultStorage(opaquePortable);
|
|
57
49
|
this.relayEncryption = options.relayEncryption ?? "required";
|
|
58
50
|
this.keyStore = options.keyStore ?? (opaquePortable ? new MemoryGrantKeyStore() : new IndexedDbGrantKeyStore());
|
|
@@ -168,6 +160,13 @@ export class MdbaseConnectInternals {
|
|
|
168
160
|
navigate: this.navigate,
|
|
169
161
|
register: (signal) => this.registerWithinBudget(signal)
|
|
170
162
|
});
|
|
163
|
+
try {
|
|
164
|
+
validateAuthorizationSelection(application.requirements, options);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
popup?.close();
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
171
170
|
if (application.distribution === "portable") {
|
|
172
171
|
if (options.openVerification)
|
|
173
172
|
popup?.close();
|
|
@@ -192,7 +191,8 @@ export class MdbaseConnectInternals {
|
|
|
192
191
|
await this.keyStore.delete(keyHandle);
|
|
193
192
|
throw error;
|
|
194
193
|
}
|
|
195
|
-
const operations =
|
|
194
|
+
const operations = authorizationOperations(application, options);
|
|
195
|
+
const requestedFiles = authorizationFiles(application.requirements);
|
|
196
196
|
const issuedAt = new Date();
|
|
197
197
|
const proof = await signApplicationAuthorization({
|
|
198
198
|
protocol_version: APPLICATION_AUTHORIZATION_PROTOCOL_VERSION,
|
|
@@ -211,11 +211,9 @@ export class MdbaseConnectInternals {
|
|
|
211
211
|
redirect_uri: this.redirectUri,
|
|
212
212
|
state,
|
|
213
213
|
code_challenge: challenge,
|
|
214
|
-
contracts: authorizationContractRequirements(operations,
|
|
214
|
+
contracts: authorizationContractRequirements(operations, requestedFiles, pendingRecoveryTransports(this.storage, this.storagePrefix(), operations, targetCollectionId), semanticContractVersion(application.requirements)),
|
|
215
215
|
requested_operations: operations,
|
|
216
|
-
...(
|
|
217
|
-
? { requested_files: application.requirements.files }
|
|
218
|
-
: {}),
|
|
216
|
+
...(requestedFiles ? { requested_files: requestedFiles } : {}),
|
|
219
217
|
...(targetCollectionId ? { collection_id: targetCollectionId } : {})
|
|
220
218
|
}, installation);
|
|
221
219
|
const pending = {
|
|
@@ -310,7 +308,8 @@ export class MdbaseConnectInternals {
|
|
|
310
308
|
await this.keyStore.delete(keyHandle);
|
|
311
309
|
throw error;
|
|
312
310
|
}
|
|
313
|
-
const operations =
|
|
311
|
+
const operations = authorizationOperations(application, options);
|
|
312
|
+
const requestedFiles = authorizationFiles(application.requirements);
|
|
314
313
|
const authorizationId = crypto.randomUUID();
|
|
315
314
|
const issuedAt = new Date();
|
|
316
315
|
const proof = await signApplicationAuthorization({
|
|
@@ -328,11 +327,9 @@ export class MdbaseConnectInternals {
|
|
|
328
327
|
issued_at: issuedAt.toISOString(),
|
|
329
328
|
expires_at: new Date(issuedAt.getTime() + 10 * 60 * 1_000).toISOString(),
|
|
330
329
|
code_challenge: challenge,
|
|
331
|
-
contracts: authorizationContractRequirements(operations,
|
|
330
|
+
contracts: authorizationContractRequirements(operations, requestedFiles, pendingRecoveryTransports(this.storage, this.storagePrefix(), operations, options.target?.kind === "collection" ? options.target.collectionId : undefined), semanticContractVersion(application.requirements)),
|
|
332
331
|
requested_operations: operations,
|
|
333
|
-
...(
|
|
334
|
-
? { requested_files: application.requirements.files }
|
|
335
|
-
: {}),
|
|
332
|
+
...(requestedFiles ? { requested_files: requestedFiles } : {}),
|
|
336
333
|
...(options.target?.kind === "collection"
|
|
337
334
|
? { collection_id: options.target.collectionId }
|
|
338
335
|
: {})
|
|
@@ -607,15 +604,25 @@ export class MdbaseConnectInternals {
|
|
|
607
604
|
}
|
|
608
605
|
const previous = parseStored(this.storage.getItem(this.tokenKey(collectionId)));
|
|
609
606
|
const retirement = planRetiredGrantKeys(this.storage, this.pendingMutationKey(collectionId), previous, keyHandle, this.grantKeyLeases.handles(collectionId), this.grantKeyLeases.retainAutomaticallyRetiredKeys);
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
607
|
+
let token;
|
|
608
|
+
try {
|
|
609
|
+
token = storedTokenFromResponse({
|
|
610
|
+
body,
|
|
611
|
+
clientId,
|
|
612
|
+
keyHandle,
|
|
613
|
+
previous,
|
|
614
|
+
retiredKeyHandles: retirement.retained,
|
|
615
|
+
defaultApplicationOrigin: this.defaultApplicationOrigin(),
|
|
616
|
+
pinConnectorIdentity: (connectorId, publicKey) => this.pinConnectorIdentity(connectorId, publicKey)
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
catch (error) {
|
|
620
|
+
if (error instanceof MdbaseConnectError
|
|
621
|
+
&& error.code === "legacy_scope_reauthorization_required") {
|
|
622
|
+
this.removeToken(collectionId, keyHandle, error.code);
|
|
623
|
+
}
|
|
624
|
+
throw error;
|
|
625
|
+
}
|
|
619
626
|
this.storage.setItem(this.tokenKey(collectionId), JSON.stringify(token));
|
|
620
627
|
for (const handle of retirement.disposable)
|
|
621
628
|
this.deleteGrantKeyWhenUnused(collectionId, handle);
|
|
@@ -3,7 +3,7 @@ import type { StoredToken } from "./internal-types.js";
|
|
|
3
3
|
import type { ResolvedConnectTimeouts } from "./request-budget.js";
|
|
4
4
|
export interface ConnectionTransportInternals {
|
|
5
5
|
readonly relayEncryption: "required" | "disabled";
|
|
6
|
-
removeToken(collectionId: string, keyHandle?: string, reason?: "not_authorized" | "authorization_lost" | "invalid_stored_grant", discardPending?: boolean): void;
|
|
6
|
+
removeToken(collectionId: string, keyHandle?: string, reason?: "not_authorized" | "authorization_lost" | "invalid_stored_grant" | "legacy_scope_reauthorization_required", discardPending?: boolean): void;
|
|
7
7
|
storeTokenResponse(body: any, clientId: string, keyHandle?: string): StoredToken;
|
|
8
8
|
acquireGrantKeyLease(collectionId: string, keyHandle: string, signal?: AbortSignal): Promise<() => void>;
|
|
9
9
|
deleteGrantKeyWhenUnused(collectionId: string, keyHandle: string): void;
|
|
@@ -650,7 +650,7 @@ export class ConnectionTransport {
|
|
|
650
650
|
stored: this.storage.getItem(this.internals.tokenKey(this.collectionId)),
|
|
651
651
|
collectionId: this.collectionId,
|
|
652
652
|
relayEncryption: this.internals.relayEncryption,
|
|
653
|
-
invalidate: (keyHandle) => this.internals.removeToken(this.collectionId, keyHandle,
|
|
653
|
+
invalidate: (keyHandle, reason = "invalid_stored_grant") => this.internals.removeToken(this.collectionId, keyHandle, reason),
|
|
654
654
|
directCapable: (token) => this.directCapable(token)
|
|
655
655
|
});
|
|
656
656
|
}
|
package/dist/connection.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CollectionOperation, CollectionTypeDocument, FileCapability, GrantScope, JsonObject } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { type MdbaseApplicationCapabilityId as ApplicationCapabilityId } from "./application-contract.js";
|
|
2
3
|
import { type ConnectionTransportInternals } from "./connection-transport.js";
|
|
3
4
|
import type { DirectAccessStatus, MdbaseAuthorizationCapabilities, MdbaseConnectionInfo, MdbaseConnectionRoute, MdbaseSyncConnection } from "./connection-types.js";
|
|
4
5
|
import type { GrantKeyStore } from "./crypto.js";
|
|
@@ -16,7 +17,10 @@ export type MdbaseAuthorizationTarget = {
|
|
|
16
17
|
collectionId: string;
|
|
17
18
|
};
|
|
18
19
|
export interface MdbaseAuthorizeOptions extends ConnectRequestOptions {
|
|
20
|
+
/** Exact independent operations, for legacy v1 declarations only. Cannot be mixed with capabilities. */
|
|
19
21
|
operations?: CollectionOperation[];
|
|
22
|
+
/** Capability groups to request. Required groups are always included; optional groups default to all. */
|
|
23
|
+
capabilities?: ApplicationCapabilityId[];
|
|
20
24
|
/** Keep a web application loaded while Connect owns the approval ceremony. */
|
|
21
25
|
presentation?: "redirect" | "popup";
|
|
22
26
|
/** Choose any compatible collection, or require one exact collection. */
|
|
@@ -29,7 +33,10 @@ export interface MdbaseAuthorizeOptions extends ConnectRequestOptions {
|
|
|
29
33
|
openVerification?: (authorization: MdbaseDeviceAuthorization) => void | Promise<void>;
|
|
30
34
|
}
|
|
31
35
|
export interface MdbaseConnectionAuthorizeOptions extends ConnectRequestOptions {
|
|
36
|
+
/** Exact independent operations, for legacy v1 declarations only. */
|
|
32
37
|
operations?: CollectionOperation[];
|
|
38
|
+
/** Capability groups to request. Required groups are always included; optional groups default to all. */
|
|
39
|
+
capabilities?: ApplicationCapabilityId[];
|
|
33
40
|
presentation?: "redirect" | "popup";
|
|
34
41
|
returnTo?: string;
|
|
35
42
|
onDeviceCode?: (authorization: MdbaseDeviceAuthorization) => void;
|
|
@@ -80,6 +87,10 @@ export declare class MdbaseConnection<Frontmatter extends JsonObject = JsonObjec
|
|
|
80
87
|
authorizationCapabilities(requiredOperations?: CollectionOperation[]): MdbaseAuthorizationCapabilities;
|
|
81
88
|
hasOperations(requiredOperations: CollectionOperation[]): boolean;
|
|
82
89
|
authorize(options?: MdbaseConnectionAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, AuthorizationProblemCode>>;
|
|
90
|
+
requestCapabilities(capabilities: ApplicationCapabilityId[], options?: MdbaseConnectionAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter> | {
|
|
91
|
+
kind: "unchanged";
|
|
92
|
+
connection: MdbaseConnection<Frontmatter>;
|
|
93
|
+
}, AuthorizationProblemCode>>;
|
|
83
94
|
requestOperations(requiredOperations: CollectionOperation[], options?: Omit<MdbaseConnectionAuthorizeOptions, "operations">): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter> | {
|
|
84
95
|
kind: "unchanged";
|
|
85
96
|
connection: MdbaseConnection<Frontmatter>;
|
package/dist/connection.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { capabilityOperationsForContractVersion } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { retainedCapabilities, semanticContractVersion, validateAuthorizationSelection } from "./application-contract.js";
|
|
1
3
|
import { MdbaseCollectionClient } from "./collection-client.js";
|
|
2
4
|
import { ConnectionNotifications } from "./connection-notifications.js";
|
|
3
5
|
import { ConnectionTransport } from "./connection-transport.js";
|
|
@@ -106,18 +108,43 @@ export class MdbaseConnection {
|
|
|
106
108
|
target: { kind: "collection", collectionId: this.collectionId }
|
|
107
109
|
}), AUTHORIZATION_PROBLEM_CODES);
|
|
108
110
|
}
|
|
111
|
+
async requestCapabilities(capabilities, options = {}) {
|
|
112
|
+
return captureConnectOutcome(async () => {
|
|
113
|
+
const application = await this.internals.register(options);
|
|
114
|
+
validateAuthorizationSelection(application.requirements, { ...options, capabilities });
|
|
115
|
+
const sufficient = this.info() !== null && capabilities.every((capability) => (capabilityOperationsForContractVersion(semanticContractVersion(application.requirements), capability) ?? [])
|
|
116
|
+
.every((operation) => this.operations.includes(operation)));
|
|
117
|
+
if (sufficient)
|
|
118
|
+
return { kind: "unchanged", connection: this };
|
|
119
|
+
if (semanticContractVersion(application.requirements) === 1) {
|
|
120
|
+
const { capabilities: _selection, ...legacyOptions } = options;
|
|
121
|
+
return this.internals.authorize({
|
|
122
|
+
...legacyOptions,
|
|
123
|
+
target: { kind: "collection", collectionId: this.collectionId },
|
|
124
|
+
operations: [...new Set([...this.operations, ...capabilities.flatMap((id) => capabilityOperationsForContractVersion(1, id) ?? [])])]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const retained = retainedCapabilities(application.requirements, this.operations);
|
|
128
|
+
return this.internals.authorize({
|
|
129
|
+
...options,
|
|
130
|
+
target: { kind: "collection", collectionId: this.collectionId },
|
|
131
|
+
capabilities: [...new Set([...retained, ...capabilities])]
|
|
132
|
+
});
|
|
133
|
+
}, AUTHORIZATION_PROBLEM_CODES);
|
|
134
|
+
}
|
|
109
135
|
async requestOperations(requiredOperations, options = {}) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
...
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
return captureConnectOutcome(async () => {
|
|
137
|
+
const application = await this.internals.register(options);
|
|
138
|
+
validateAuthorizationSelection(application.requirements, { ...options, operations: requiredOperations });
|
|
139
|
+
const authorization = this.authorizationCapabilities(requiredOperations);
|
|
140
|
+
if (authorization.sufficient)
|
|
141
|
+
return { kind: "unchanged", connection: this };
|
|
142
|
+
return this.internals.authorize({
|
|
143
|
+
...options,
|
|
144
|
+
target: { kind: "collection", collectionId: this.collectionId },
|
|
145
|
+
operations: [...new Set([...authorization.grantedOperations, ...requiredOperations])]
|
|
146
|
+
});
|
|
147
|
+
}, AUTHORIZATION_PROBLEM_CODES);
|
|
121
148
|
}
|
|
122
149
|
onConnectionChange(listener) {
|
|
123
150
|
this.connectionListeners.add(listener);
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { MdbaseConnection } from "./connection.js";
|
|
|
7
7
|
export type { MdbaseAuthorizationTarget, MdbaseAuthorizeOptions, MdbaseConnectionAuthorizeOptions, MdbaseConnectEnvironment, MdbaseAuthorizationResult, MdbaseAuthorizationOutcome } from "./connection.js";
|
|
8
8
|
export type { MdbaseConnectionRoute, DirectAccessStatus, MdbaseConnectionInfo, MdbaseAuthorizationCapabilities, MdbaseSyncTransport, MdbaseSyncConnection } from "./connection-types.js";
|
|
9
9
|
export { effectiveCapabilities } from "./capabilities.js";
|
|
10
|
+
export type { MdbaseStructuredReadiness } from "./structured-readiness.js";
|
|
10
11
|
export type { MdbaseCapabilityState, MdbaseCapabilityEvidence, MdbaseEffectiveCapability, MdbaseEffectiveCapabilities } from "./capabilities.js";
|
|
11
12
|
export { MdbaseConnectError, isRetryableConnectError } from "./errors.js";
|
|
12
13
|
export type { ConnectErrorContext } from "./errors.js";
|
|
@@ -22,4 +23,5 @@ export { MdbaseBrowserSelection, MdbaseMemorySelection } from "./selection.js";
|
|
|
22
23
|
export type { MdbaseSelectionHistory, MdbaseApplicationSelection, MdbaseBrowserSelectionOptions } from "./selection.js";
|
|
23
24
|
export type { MdbaseUnavailableReason } from "./session.js";
|
|
24
25
|
export { MDBASE_RECORD_CREATED_CONTRACT, MDBASE_TIMER_FIRED_CONTRACT, operationsForApplicationCapabilities } from "@mdbase-dev/connect-protocol";
|
|
25
|
-
export type {
|
|
26
|
+
export type { MdbaseApplicationManifest, MdbaseApplicationManifest as MdbaseAppManifest, MdbaseApplicationRequirements, MdbaseApplicationCapabilityId as ApplicationCapabilityId, MdbaseApplicationCapabilityRequirements as ApplicationCapabilityRequirements } from "./application-contract.js";
|
|
27
|
+
export type { ApplicationProvisions, ApplicationRequirements, LegacyApplicationRequirements, LegacyApplicationCapabilityId, LegacyApplicationCapabilityRequirements, LegacyMdbaseAppManifest, ApplicationNotifications, ApplicationAuthorizationBinding, ApplicationAuthorizationProof, FileAction, FileCapability, CollectionOperation as MdbaseOperation, CollectionTypeDocument, ConnectOperationOutcome, ConnectProblem, ConnectProblemCategory, ConnectProblemCode, ConnectProblemDetailsByCode, ConnectRecoveryAction, ContractRequirement, GrantScope, JsonObject, NotificationCriterion, MdbaseDiagnostic, MdbaseOperationEnvelope, KnownConnectProblem, TypePackManifest, TypePackManifestResource, TypePackProvision, TypePackSourceResource, UnknownConnectProblem } from "@mdbase-dev/connect-protocol";
|
package/dist/internal-types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ApplicationNotifications,
|
|
1
|
+
import type { ApplicationNotifications, ApplicationProvisions, CollectionOperation, EncryptedRelayOperationRequest, GrantEncryption, FileCapability, GrantScope, MdbaseOperationRequest, MutationOperationIdentifier } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { MdbaseApplicationRequirements as ApplicationRequirements } from "./application-contract.js";
|
|
2
3
|
import { encryptRelayRequest } from "./crypto.js";
|
|
3
4
|
export interface Application {
|
|
4
5
|
id: string;
|
|
@@ -10,6 +11,7 @@ export interface Application {
|
|
|
10
11
|
project_url?: string;
|
|
11
12
|
notifications?: ApplicationNotifications;
|
|
12
13
|
requirements: ApplicationRequirements;
|
|
14
|
+
provisions?: ApplicationProvisions;
|
|
13
15
|
}
|
|
14
16
|
export interface StoredAuthorization {
|
|
15
17
|
version: 1;
|
|
@@ -95,4 +97,4 @@ export interface OperationAttempt {
|
|
|
95
97
|
pendingMutationRecord?: PendingMutation;
|
|
96
98
|
resumingMutation?: boolean;
|
|
97
99
|
}
|
|
98
|
-
export
|
|
100
|
+
export { DEFAULT_OPERATIONS } from "./application-contract.js";
|
package/dist/internal-types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { DEFAULT_OPERATIONS } from "./application-contract.js";
|
package/dist/mdbase-connect.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare class MdbaseConnect<Frontmatter extends JsonObject = JsonObject>
|
|
|
14
14
|
authorize(options?: MdbaseAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, AuthorizationProblemCode>>;
|
|
15
15
|
/** The ordinary application lifecycle entry point. */
|
|
16
16
|
application(options: MdbaseApplicationSessionOptions): MdbaseApplicationSession<Frontmatter>;
|
|
17
|
-
manifest(options?: ConnectRequestOptions): Promise<ConnectOutcome<import("
|
|
17
|
+
manifest(options?: ConnectRequestOptions): Promise<ConnectOutcome<import("./application-contract.js").MdbaseApplicationManifest, RegistrationProblemCode>>;
|
|
18
18
|
environment(): MdbaseConnectEnvironment;
|
|
19
19
|
completeAuthorization(callbackUrl?: string | URL, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseAuthorizationResult<Frontmatter>, AuthorizationProblemCode>>;
|
|
20
20
|
connections(): MdbaseConnectionInfo[];
|
|
@@ -138,8 +138,9 @@ export interface QuerySummary {
|
|
|
138
138
|
/** Application-facing form of the canonical mdbase v0.3 query schema. */
|
|
139
139
|
export interface QueryInput {
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
* `frontmatterMode`, and `contract`; filter normalized fields in
|
|
141
|
+
* Queries using a semantic contract view accept only `types`, `timezone`,
|
|
142
|
+
* pagination, `frontmatterMode`, and `contract`; filter normalized fields in
|
|
143
|
+
* the app.
|
|
143
144
|
*/
|
|
144
145
|
types?: string[];
|
|
145
146
|
/** IANA timezone used for calendar semantics in this invocation. */
|
|
@@ -166,7 +167,7 @@ export interface QueryInput {
|
|
|
166
167
|
snapshot?: string;
|
|
167
168
|
includeBody?: boolean;
|
|
168
169
|
frontmatterMode?: "effective" | "persisted" | "both";
|
|
169
|
-
/**
|
|
170
|
+
/** Select one exact semantic contract/provider view for this query. */
|
|
170
171
|
contract?: DataContractSelector;
|
|
171
172
|
}
|
|
172
173
|
export interface QueryResult<Record extends JsonObject = JsonObject> {
|
package/dist/outcomes.d.ts
CHANGED
|
@@ -18,14 +18,14 @@ export declare const COMMON_OPERATION_PROBLEM_CODES: readonly ["access_denied",
|
|
|
18
18
|
export declare const ALL_CONNECT_PROBLEM_CODES: ConnectProblemCode[];
|
|
19
19
|
export type RegistrationProblemCode = "discovery_failed" | "invalid_operation_response" | "invalid_application_manifest" | "invalid_request" | "manifest_load_failed" | "rate_limited" | "temporarily_unavailable" | "timeout";
|
|
20
20
|
export declare const REGISTRATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout"];
|
|
21
|
-
export type AuthorizationProblemCode = RegistrationProblemCode | "access_denied" | "application_declaration_mismatch" | "application_identity_unavailable" | "approval_window_blocked" | "authorization_binding_incompatible" | "authorization_cancelled" | "authorization_replayed" | "browser_required" | "capability_contract_incompatible" | "collection_access_denied" | "collection_configuration_invalid" | "collection_contracts_missing" | "collection_incompatible" | "collection_invalid" | "collection_kind_unsupported" | "collection_mismatch" | "collection_not_found" | "collection_type_registry_invalid" | "collection_version_unsupported" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "device_authorization_failed" | "durable_mutation_unsupported" | "encryption_required" | "expired_token" | "invalid_application_authorization" | "invalid_callback" | "invalid_device_authorization_response" | "invalid_token_response" | "scope_denied" | "reconnect_required" | "token_exchange_failed" | "transport_protocol_incompatible";
|
|
22
|
-
export declare const AUTHORIZATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_declaration_mismatch", "application_identity_unavailable", "approval_window_blocked", "authorization_binding_incompatible", "authorization_cancelled", "authorization_replayed", "browser_required", "capability_contract_incompatible", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "durable_mutation_unsupported", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "reconnect_required", "token_exchange_failed", "transport_protocol_incompatible"];
|
|
21
|
+
export type AuthorizationProblemCode = RegistrationProblemCode | "access_denied" | "application_declaration_mismatch" | "application_identity_unavailable" | "approval_window_blocked" | "authorization_binding_incompatible" | "authorization_cancelled" | "authorization_replayed" | "browser_required" | "capability_contract_incompatible" | "collection_access_denied" | "collection_configuration_invalid" | "collection_contracts_missing" | "collection_incompatible" | "collection_invalid" | "collection_kind_unsupported" | "collection_mismatch" | "collection_not_found" | "collection_type_registry_invalid" | "collection_version_unsupported" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "device_authorization_failed" | "durable_mutation_unsupported" | "encryption_required" | "expired_token" | "invalid_application_authorization" | "invalid_callback" | "invalid_device_authorization_response" | "invalid_token_response" | "legacy_scope_reauthorization_required" | "scope_denied" | "reconnect_required" | "token_exchange_failed" | "transport_protocol_incompatible";
|
|
22
|
+
export declare const AUTHORIZATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_declaration_mismatch", "application_identity_unavailable", "approval_window_blocked", "authorization_binding_incompatible", "authorization_cancelled", "authorization_replayed", "browser_required", "capability_contract_incompatible", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "durable_mutation_unsupported", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "legacy_scope_reauthorization_required", "scope_denied", "reconnect_required", "token_exchange_failed", "transport_protocol_incompatible"];
|
|
23
23
|
export type NotificationProblemCode = RegistrationProblemCode | "authorization_expired" | "invalid_operation_response" | "invalid_push_subscription" | "managed_fcm_not_declared" | "not_authorized" | "notification_criterion_not_declared" | "notification_reauthorization_required" | "notification_registration_failed" | "notification_unregistration_failed" | "notifications_not_declared" | "notifications_unavailable";
|
|
24
24
|
export declare const NOTIFICATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "authorization_expired", "invalid_operation_response", "invalid_push_subscription", "managed_fcm_not_declared", "not_authorized", "notification_criterion_not_declared", "notification_reauthorization_required", "notification_registration_failed", "notification_unregistration_failed", "notifications_not_declared", "notifications_unavailable"];
|
|
25
25
|
export type DirectAccessProblemCode = "connector_offline" | "connector_upgrade_required" | "invalid_operation_response" | "not_authorized" | "operation_failed" | "temporarily_unavailable" | "timeout";
|
|
26
26
|
export declare const DIRECT_ACCESS_PROBLEM_CODES: readonly ["connector_offline", "connector_upgrade_required", "invalid_operation_response", "not_authorized", "operation_failed", "temporarily_unavailable", "timeout"];
|
|
27
27
|
export type SessionProblemCode = AuthorizationProblemCode | "collection_not_ready" | "collection_not_selected" | "operation_cancelled" | "session_destroyed" | "session_not_started" | "session_starting" | "unknown_collection";
|
|
28
|
-
export declare const SESSION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_declaration_mismatch", "application_identity_unavailable", "approval_window_blocked", "authorization_binding_incompatible", "authorization_cancelled", "authorization_replayed", "browser_required", "capability_contract_incompatible", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "durable_mutation_unsupported", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "reconnect_required", "token_exchange_failed", "transport_protocol_incompatible", "collection_not_ready", "collection_not_selected", "operation_cancelled", "session_destroyed", "session_not_started", "session_starting", "unknown_collection"];
|
|
28
|
+
export declare const SESSION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_operation_response", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_declaration_mismatch", "application_identity_unavailable", "approval_window_blocked", "authorization_binding_incompatible", "authorization_cancelled", "authorization_replayed", "browser_required", "capability_contract_incompatible", "collection_access_denied", "collection_configuration_invalid", "collection_contracts_missing", "collection_incompatible", "collection_invalid", "collection_kind_unsupported", "collection_mismatch", "collection_not_found", "collection_type_registry_invalid", "collection_version_unsupported", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "device_authorization_failed", "durable_mutation_unsupported", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "legacy_scope_reauthorization_required", "scope_denied", "reconnect_required", "token_exchange_failed", "transport_protocol_incompatible", "collection_not_ready", "collection_not_selected", "operation_cancelled", "session_destroyed", "session_not_started", "session_starting", "unknown_collection"];
|
|
29
29
|
export type CollectionSetupProblemCode = "collection_configuration_invalid" | "collection_invalid" | "collection_type_registry_invalid" | "collection_version_unsupported";
|
|
30
30
|
export type CollectionDescriptionProblemCode = CommonOperationProblemCode | CollectionSetupProblemCode;
|
|
31
31
|
export type CollectionReadProblemCode = CollectionDescriptionProblemCode | "invalid_path" | "operation_invalid";
|
package/dist/outcomes.js
CHANGED
|
@@ -79,6 +79,7 @@ export class CollectionRequestCoordinator {
|
|
|
79
79
|
if (queued.started || queued.settled)
|
|
80
80
|
return;
|
|
81
81
|
queued.settled = true;
|
|
82
|
+
queue.splice(queue.indexOf(queued), 1);
|
|
82
83
|
queued.reject(requestAbortReason(combined.signal));
|
|
83
84
|
combined.dispose();
|
|
84
85
|
this.releaseLatest(coordination.family, replacement);
|
package/dist/runtime-utils.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import type { FileCapability, GrantEncryption, GrantScope
|
|
1
|
+
import type { FileCapability, GrantEncryption, GrantScope } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { MdbaseApplicationManifest as MdbaseAppManifest } from "./application-contract.js";
|
|
2
3
|
import { MdbaseConnectError } from "./errors.js";
|
|
3
4
|
import type { StoredToken } from "./internal-types.js";
|
|
4
5
|
import type { MdbaseDeviceAuthorization } from "./authorization-types.js";
|
|
6
|
+
/** Resolve bundled declarations and their stable storage identity without loading URLs. */
|
|
7
|
+
export declare function resolveManifestSource(input?: MdbaseAppManifest | string | URL, redirect?: string | URL): {
|
|
8
|
+
manifest: MdbaseAppManifest | string;
|
|
9
|
+
manifestSource: string;
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
};
|
|
5
12
|
type NetworkProblemCode = "notification_registration_failed" | "notification_unregistration_failed" | "notifications_unavailable" | "temporarily_unavailable";
|
|
6
13
|
/** Normalize fetch rejection at the exact I/O boundary. */
|
|
7
14
|
export declare function connectFetch(input: RequestInfo | URL, init: RequestInit | undefined, code: NetworkProblemCode, message: string): Promise<Response>;
|
|
@@ -20,7 +27,10 @@ export declare function validFileCapability(value: unknown): value is FileCapabi
|
|
|
20
27
|
export declare function validStoredEncryption(encryption: StoredToken["encryption"], collectionId: string): encryption is GrantEncryption;
|
|
21
28
|
export declare function parseDeviceAuthorization(body: any): MdbaseDeviceAuthorization;
|
|
22
29
|
export declare function parseStored<T>(value: string | null): T | null;
|
|
30
|
+
/** Parse both canonical and N-1 grant shapes so callers can diagnose legacy grants. */
|
|
23
31
|
export declare function parseGrantScope(value: unknown): GrantScope | null;
|
|
32
|
+
/** Only this scope authorizes application data access. */
|
|
33
|
+
export declare function isCanonicalGrantScope(scope: GrantScope): boolean;
|
|
24
34
|
export declare function stripTrailingSlash(value: string): string;
|
|
25
35
|
export declare function defaultManifestSource(): string;
|
|
26
36
|
export declare function defaultRedirectUri(): string;
|