@mdbase-dev/connect 0.1.0-beta.31 → 0.1.0-beta.33
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 +112 -34
- package/dist/advanced.d.ts +9 -0
- package/dist/advanced.js +6 -0
- package/dist/application-session.d.ts +39 -14
- package/dist/application-session.js +201 -70
- package/dist/async.js +11 -5
- package/dist/authority-proof.d.ts +3 -0
- package/dist/authority-proof.js +24 -0
- 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/browser.d.ts +3 -0
- package/dist/browser.js +5 -0
- package/dist/capabilities.js +2 -1
- package/dist/collection-client.d.ts +36 -33
- package/dist/collection-client.js +549 -104
- package/dist/connect-authorization-helpers.d.ts +3 -0
- package/dist/connect-authorization-helpers.js +13 -0
- package/dist/connect-options.d.ts +12 -4
- package/dist/connect.d.ts +12 -4
- package/dist/connect.js +102 -103
- package/dist/connection-file-transport.d.ts +2 -2
- package/dist/connection-file-transport.js +4 -4
- package/dist/connection-notifications.d.ts +10 -4
- package/dist/connection-notifications.js +41 -23
- package/dist/connection-transport.d.ts +19 -15
- package/dist/connection-transport.js +202 -202
- package/dist/connection-types.d.ts +5 -4
- package/dist/connection.d.ts +47 -46
- package/dist/connection.js +320 -162
- package/dist/crypto-entry.d.ts +7 -0
- package/dist/crypto-entry.js +4 -0
- package/dist/crypto.js +4 -4
- package/dist/external-store.d.ts +10 -0
- package/dist/external-store.js +10 -0
- package/dist/file-transfer-internals.d.ts +23 -0
- package/dist/file-transfer-internals.js +224 -0
- package/dist/files.d.ts +36 -14
- package/dist/files.js +92 -222
- package/dist/hosted-file-request.js +3 -3
- package/dist/index.d.ts +24 -19
- package/dist/index.js +10 -18
- package/dist/internal-types.d.ts +9 -1
- package/dist/local-file-transport.d.ts +2 -2
- package/dist/local-file-transport.js +13 -13
- package/dist/mdbase-connect.d.ts +6 -4
- package/dist/mdbase-connect.js +9 -8
- package/dist/notifications.d.ts +3 -2
- package/dist/operation-helpers.d.ts +3 -3
- package/dist/operation-helpers.js +17 -34
- package/dist/operation-types.d.ts +435 -45
- package/dist/outcomes.d.ts +15 -15
- package/dist/outcomes.js +13 -1
- package/dist/pending-mutation-store.d.ts +13 -0
- package/dist/pending-mutation-store.js +64 -0
- package/dist/request-budget.d.ts +27 -0
- package/dist/request-budget.js +95 -0
- package/dist/runtime-utils.d.ts +2 -0
- package/dist/runtime-utils.js +19 -0
- package/dist/session.d.ts +5 -4
- package/dist/session.js +6 -5
- package/dist/stored-token.d.ts +10 -0
- package/dist/stored-token.js +60 -0
- package/dist/token-response.d.ts +11 -0
- package/dist/token-response.js +77 -0
- package/dist/watch-policy.d.ts +8 -0
- package/dist/watch-policy.js +12 -0
- package/package.json +12 -2
package/dist/outcomes.d.ts
CHANGED
|
@@ -13,19 +13,19 @@ export type ConnectFailure<Code extends ConnectProblemCode = ConnectProblemCode>
|
|
|
13
13
|
* for programming errors and broken SDK invariants.
|
|
14
14
|
*/
|
|
15
15
|
export type ConnectOutcome<Value, Code extends ConnectProblemCode = ConnectProblemCode> = ConnectSuccess<Value> | ConnectFailure<Code>;
|
|
16
|
-
export type CommonOperationProblemCode = "access_denied" | "access_paused" | "authorization_expired" | "collection_access_denied" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "direct_operation_rejected" | "operation_outcome_unknown" | "encryption_required" | "encrypted_relay_rejected" | "hosted_provider_unavailable" | "insufficient_access" | "invalid_encrypted_response" | "invalid_operation_response" | "invalid_request" | "missing_grant_key" | "not_authorized" | "operation_cancelled" | "operation_failed" | "rate_limited" | "relay_authorization_expired" | "relay_unavailable" | "temporarily_unavailable" | "timeout" | "unsupported_operation";
|
|
17
|
-
export declare const COMMON_OPERATION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation"];
|
|
16
|
+
export type CommonOperationProblemCode = "access_denied" | "access_paused" | "authorization_binding_incompatible" | "authorization_expired" | "capability_contract_incompatible" | "collection_access_denied" | "connector_identity_changed" | "connector_offline" | "connector_upgrade_required" | "direct_operation_rejected" | "durable_mutation_unsupported" | "operation_outcome_unknown" | "encryption_required" | "encrypted_relay_rejected" | "hosted_provider_unavailable" | "insufficient_access" | "invalid_encrypted_response" | "invalid_operation_response" | "invalid_request" | "missing_grant_key" | "mutation_recovery_expired" | "mutation_request_conflict" | "not_authorized" | "operation_cancelled" | "operation_failed" | "rate_limited" | "relay_authorization_expired" | "relay_unavailable" | "temporarily_unavailable" | "timeout" | "transport_protocol_incompatible" | "unsupported_operation";
|
|
17
|
+
export declare const COMMON_OPERATION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation"];
|
|
18
18
|
export declare const ALL_CONNECT_PROBLEM_CODES: ConnectProblemCode[];
|
|
19
|
-
export type RegistrationProblemCode = "discovery_failed" | "invalid_application_manifest" | "invalid_request" | "manifest_load_failed" | "rate_limited" | "temporarily_unavailable" | "timeout";
|
|
20
|
-
export declare const REGISTRATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout"];
|
|
21
|
-
export type AuthorizationProblemCode = RegistrationProblemCode | "access_denied" | "application_identity_unavailable" | "approval_window_blocked" | "authorization_cancelled" | "authorization_replayed" | "browser_required" | "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" | "encryption_required" | "expired_token" | "invalid_application_authorization" | "invalid_callback" | "invalid_device_authorization_response" | "invalid_token_response" | "scope_denied" | "reconnect_required" | "token_exchange_failed";
|
|
22
|
-
export declare const AUTHORIZATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_identity_unavailable", "approval_window_blocked", "authorization_cancelled", "authorization_replayed", "browser_required", "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", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "reconnect_required", "token_exchange_failed"];
|
|
23
|
-
export type NotificationProblemCode = RegistrationProblemCode | "authorization_expired" | "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
|
-
export declare const NOTIFICATION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "authorization_expired", "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"];
|
|
19
|
+
export type RegistrationProblemCode = "discovery_failed" | "invalid_operation_response" | "invalid_application_manifest" | "invalid_request" | "manifest_load_failed" | "rate_limited" | "temporarily_unavailable" | "timeout";
|
|
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_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_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"];
|
|
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
|
+
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" | "unknown_collection";
|
|
28
|
-
export declare const SESSION_PROBLEM_CODES: readonly ["discovery_failed", "invalid_application_manifest", "invalid_request", "manifest_load_failed", "rate_limited", "temporarily_unavailable", "timeout", "access_denied", "application_identity_unavailable", "approval_window_blocked", "authorization_cancelled", "authorization_replayed", "browser_required", "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", "encryption_required", "expired_token", "invalid_application_authorization", "invalid_callback", "invalid_device_authorization_response", "invalid_token_response", "scope_denied", "reconnect_required", "token_exchange_failed", "collection_not_ready", "collection_not_selected", "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_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", "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";
|
|
@@ -34,12 +34,12 @@ export type CollectionMutationProblemCode = CollectionReadProblemCode | "concurr
|
|
|
34
34
|
export type CollectionChangesProblemCode = CollectionDescriptionProblemCode | "change_cursor_reset";
|
|
35
35
|
export type CollectionTypeProblemCode = CollectionMutationProblemCode | "type_pack_provision_failed";
|
|
36
36
|
export declare const COLLECTION_SETUP_PROBLEM_CODES: readonly ["collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported"];
|
|
37
|
-
export declare const COLLECTION_DESCRIPTION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported"];
|
|
38
|
-
export declare const COLLECTION_READ_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid"];
|
|
39
|
-
export declare const COLLECTION_QUERY_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "query_snapshot_changed", "sandbox_unsupported"];
|
|
40
|
-
export declare const COLLECTION_MUTATION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "concurrent_modification", "invalid_preflight", "pending_mutation_unresolved"];
|
|
41
|
-
export declare const COLLECTION_CHANGES_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "change_cursor_reset"];
|
|
42
|
-
export declare const COLLECTION_TYPE_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_expired", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "concurrent_modification", "invalid_preflight", "pending_mutation_unresolved", "type_pack_provision_failed"];
|
|
37
|
+
export declare const COLLECTION_DESCRIPTION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported"];
|
|
38
|
+
export declare const COLLECTION_READ_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid"];
|
|
39
|
+
export declare const COLLECTION_QUERY_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "query_snapshot_changed", "sandbox_unsupported"];
|
|
40
|
+
export declare const COLLECTION_MUTATION_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "concurrent_modification", "invalid_preflight", "pending_mutation_unresolved"];
|
|
41
|
+
export declare const COLLECTION_CHANGES_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "change_cursor_reset"];
|
|
42
|
+
export declare const COLLECTION_TYPE_PROBLEM_CODES: readonly ["access_denied", "access_paused", "authorization_binding_incompatible", "authorization_expired", "capability_contract_incompatible", "collection_access_denied", "connector_identity_changed", "connector_offline", "connector_upgrade_required", "direct_operation_rejected", "durable_mutation_unsupported", "operation_outcome_unknown", "encryption_required", "encrypted_relay_rejected", "hosted_provider_unavailable", "insufficient_access", "invalid_encrypted_response", "invalid_operation_response", "invalid_request", "missing_grant_key", "mutation_recovery_expired", "mutation_request_conflict", "not_authorized", "operation_cancelled", "operation_failed", "rate_limited", "relay_authorization_expired", "relay_unavailable", "temporarily_unavailable", "timeout", "transport_protocol_incompatible", "unsupported_operation", "collection_configuration_invalid", "collection_invalid", "collection_type_registry_invalid", "collection_version_unsupported", "invalid_path", "operation_invalid", "concurrent_modification", "invalid_preflight", "pending_mutation_unresolved", "type_pack_provision_failed"];
|
|
43
43
|
export declare function connectSuccess<Value>(value: Value, diagnostics?: MdbaseDiagnostic[]): ConnectSuccess<Value>;
|
|
44
44
|
export declare function connectFailure<Code extends ConnectProblemCode>(problem: ConnectProblem<Code>): ConnectFailure<Code>;
|
|
45
45
|
export declare function captureConnectOutcome<Value, Code extends ConnectProblemCode>(operation: () => Promise<Value>, allowedCodes: readonly Code[]): Promise<ConnectOutcome<Value, Code>>;
|
package/dist/outcomes.js
CHANGED
|
@@ -3,12 +3,15 @@ import { MdbaseConnectError, unknownConnectProblem } from "./errors.js";
|
|
|
3
3
|
export const COMMON_OPERATION_PROBLEM_CODES = [
|
|
4
4
|
"access_denied",
|
|
5
5
|
"access_paused",
|
|
6
|
+
"authorization_binding_incompatible",
|
|
6
7
|
"authorization_expired",
|
|
8
|
+
"capability_contract_incompatible",
|
|
7
9
|
"collection_access_denied",
|
|
8
10
|
"connector_identity_changed",
|
|
9
11
|
"connector_offline",
|
|
10
12
|
"connector_upgrade_required",
|
|
11
13
|
"direct_operation_rejected",
|
|
14
|
+
"durable_mutation_unsupported",
|
|
12
15
|
"operation_outcome_unknown",
|
|
13
16
|
"encryption_required",
|
|
14
17
|
"encrypted_relay_rejected",
|
|
@@ -18,6 +21,8 @@ export const COMMON_OPERATION_PROBLEM_CODES = [
|
|
|
18
21
|
"invalid_operation_response",
|
|
19
22
|
"invalid_request",
|
|
20
23
|
"missing_grant_key",
|
|
24
|
+
"mutation_recovery_expired",
|
|
25
|
+
"mutation_request_conflict",
|
|
21
26
|
"not_authorized",
|
|
22
27
|
"operation_cancelled",
|
|
23
28
|
"operation_failed",
|
|
@@ -26,11 +31,13 @@ export const COMMON_OPERATION_PROBLEM_CODES = [
|
|
|
26
31
|
"relay_unavailable",
|
|
27
32
|
"temporarily_unavailable",
|
|
28
33
|
"timeout",
|
|
34
|
+
"transport_protocol_incompatible",
|
|
29
35
|
"unsupported_operation"
|
|
30
36
|
];
|
|
31
37
|
export const ALL_CONNECT_PROBLEM_CODES = Object.keys(CONNECT_PROBLEM_CATALOG);
|
|
32
38
|
export const REGISTRATION_PROBLEM_CODES = [
|
|
33
39
|
"discovery_failed",
|
|
40
|
+
"invalid_operation_response",
|
|
34
41
|
"invalid_application_manifest",
|
|
35
42
|
"invalid_request",
|
|
36
43
|
"manifest_load_failed",
|
|
@@ -43,9 +50,11 @@ export const AUTHORIZATION_PROBLEM_CODES = [
|
|
|
43
50
|
"access_denied",
|
|
44
51
|
"application_identity_unavailable",
|
|
45
52
|
"approval_window_blocked",
|
|
53
|
+
"authorization_binding_incompatible",
|
|
46
54
|
"authorization_cancelled",
|
|
47
55
|
"authorization_replayed",
|
|
48
56
|
"browser_required",
|
|
57
|
+
"capability_contract_incompatible",
|
|
49
58
|
"collection_access_denied",
|
|
50
59
|
"collection_configuration_invalid",
|
|
51
60
|
"collection_contracts_missing",
|
|
@@ -60,6 +69,7 @@ export const AUTHORIZATION_PROBLEM_CODES = [
|
|
|
60
69
|
"connector_offline",
|
|
61
70
|
"connector_upgrade_required",
|
|
62
71
|
"device_authorization_failed",
|
|
72
|
+
"durable_mutation_unsupported",
|
|
63
73
|
"encryption_required",
|
|
64
74
|
"expired_token",
|
|
65
75
|
"invalid_application_authorization",
|
|
@@ -68,11 +78,13 @@ export const AUTHORIZATION_PROBLEM_CODES = [
|
|
|
68
78
|
"invalid_token_response",
|
|
69
79
|
"scope_denied",
|
|
70
80
|
"reconnect_required",
|
|
71
|
-
"token_exchange_failed"
|
|
81
|
+
"token_exchange_failed",
|
|
82
|
+
"transport_protocol_incompatible"
|
|
72
83
|
];
|
|
73
84
|
export const NOTIFICATION_PROBLEM_CODES = [
|
|
74
85
|
...REGISTRATION_PROBLEM_CODES,
|
|
75
86
|
"authorization_expired",
|
|
87
|
+
"invalid_operation_response",
|
|
76
88
|
"invalid_push_subscription",
|
|
77
89
|
"managed_fcm_not_declared",
|
|
78
90
|
"not_authorized",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MutationOperationIdentifier } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import type { PendingMutation } from "./internal-types.js";
|
|
3
|
+
export declare class PendingMutationStore {
|
|
4
|
+
private readonly storage;
|
|
5
|
+
private readonly baseKey;
|
|
6
|
+
constructor(storage: Storage, baseKey: string);
|
|
7
|
+
list(collectionId: string | null): PendingMutation[];
|
|
8
|
+
find(collectionId: string | null, requestId: string): PendingMutation | null;
|
|
9
|
+
identifier(pending: PendingMutation): MutationOperationIdentifier;
|
|
10
|
+
store(pending: PendingMutation): void;
|
|
11
|
+
take(requestId: string): PendingMutation | null;
|
|
12
|
+
private key;
|
|
13
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isCollectionOperation, mutationOperationIdentifier } from "@mdbase-dev/connect-protocol";
|
|
2
|
+
import { parseStored } from "./runtime-utils.js";
|
|
3
|
+
export class PendingMutationStore {
|
|
4
|
+
storage;
|
|
5
|
+
baseKey;
|
|
6
|
+
constructor(storage, baseKey) {
|
|
7
|
+
this.storage = storage;
|
|
8
|
+
this.baseKey = baseKey;
|
|
9
|
+
}
|
|
10
|
+
list(collectionId) {
|
|
11
|
+
if (!collectionId)
|
|
12
|
+
return [];
|
|
13
|
+
const legacy = parseStored(this.storage.getItem(this.baseKey));
|
|
14
|
+
if (validPendingMutation(legacy) && legacy.collectionId === collectionId) {
|
|
15
|
+
const migratedKey = this.key(legacy.requestId);
|
|
16
|
+
if (!this.storage.getItem(migratedKey)) {
|
|
17
|
+
this.storage.setItem(migratedKey, JSON.stringify(legacy));
|
|
18
|
+
}
|
|
19
|
+
this.storage.removeItem(this.baseKey);
|
|
20
|
+
}
|
|
21
|
+
const keys = [];
|
|
22
|
+
for (let index = 0; index < this.storage.length; index += 1) {
|
|
23
|
+
const key = this.storage.key(index);
|
|
24
|
+
if (key?.startsWith(`${this.baseKey}:`))
|
|
25
|
+
keys.push(key);
|
|
26
|
+
}
|
|
27
|
+
return keys
|
|
28
|
+
.map((key) => parseStored(this.storage.getItem(key)))
|
|
29
|
+
.filter((pending) => validPendingMutation(pending) && pending.collectionId === collectionId)
|
|
30
|
+
.sort((left, right) => left.createdAt - right.createdAt
|
|
31
|
+
|| left.requestId.localeCompare(right.requestId));
|
|
32
|
+
}
|
|
33
|
+
find(collectionId, requestId) {
|
|
34
|
+
return this.list(collectionId)
|
|
35
|
+
.find((pending) => pending.requestId === requestId) ?? null;
|
|
36
|
+
}
|
|
37
|
+
identifier(pending) {
|
|
38
|
+
return pending.mutation ?? mutationOperationIdentifier(pending.operation, pending.request?.input ?? (pending.operation === "sync" ? { action: "mutate" } : {})) ?? (pending.operation === "sync" ? "sync:mutate" : pending.operation);
|
|
39
|
+
}
|
|
40
|
+
store(pending) {
|
|
41
|
+
this.storage.setItem(this.key(pending.requestId), JSON.stringify(pending));
|
|
42
|
+
}
|
|
43
|
+
take(requestId) {
|
|
44
|
+
const key = this.key(requestId);
|
|
45
|
+
const pending = parseStored(this.storage.getItem(key));
|
|
46
|
+
this.storage.removeItem(key);
|
|
47
|
+
return pending;
|
|
48
|
+
}
|
|
49
|
+
key(requestId) {
|
|
50
|
+
return `${this.baseKey}:${encodeURIComponent(requestId)}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function validPendingMutation(pending) {
|
|
54
|
+
return Boolean(pending
|
|
55
|
+
&& typeof pending.collectionId === "string"
|
|
56
|
+
&& typeof pending.requestId === "string"
|
|
57
|
+
&& pending.requestId.length > 0
|
|
58
|
+
&& isCollectionOperation(pending.operation)
|
|
59
|
+
&& typeof pending.inputFingerprint === "string"
|
|
60
|
+
&& Number.isFinite(pending.createdAt)
|
|
61
|
+
&& pending.createdAt > 0
|
|
62
|
+
&& (pending.envelope || pending.request)
|
|
63
|
+
&& (pending.operation === "sync" || mutationOperationIdentifier(pending.operation, pending.request?.input ?? {}) !== null));
|
|
64
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ConnectRequestOptions } from "./operation-types.js";
|
|
2
|
+
import type { MdbaseConnectTimeouts } from "./connect-options.js";
|
|
3
|
+
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
4
|
+
export declare const DEFAULT_STARTUP_TIMEOUT_MS = 10000;
|
|
5
|
+
export declare const DEFAULT_UPLOAD_TIMEOUT_MS = 120000;
|
|
6
|
+
export declare const DEFAULT_SYNC_TIMEOUT_MS = 60000;
|
|
7
|
+
export interface ResolvedConnectTimeouts {
|
|
8
|
+
requestMs: number | null;
|
|
9
|
+
watchStartMs: number | null;
|
|
10
|
+
uploadMs: number | null;
|
|
11
|
+
syncMs: number | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolveConnectTimeouts(timeouts?: MdbaseConnectTimeouts): ResolvedConnectTimeouts;
|
|
14
|
+
export interface RequestBudget {
|
|
15
|
+
readonly signal: AbortSignal;
|
|
16
|
+
readonly deadline: number | null;
|
|
17
|
+
remainingMs(): number | null;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function createRequestBudget(options?: ConnectRequestOptions, defaultTimeoutMs?: number | null, now?: () => number): RequestBudget;
|
|
21
|
+
export declare function withRequestBudget<Result>(options: ConnectRequestOptions | undefined, defaultTimeoutMs: number | null, operation: (budget: RequestBudget) => Promise<Result>): Promise<Result>;
|
|
22
|
+
/**
|
|
23
|
+
* Budget an operation whose transport cooperates with AbortSignal and must run
|
|
24
|
+
* its own bounded cleanup/recovery before the public promise settles.
|
|
25
|
+
*/
|
|
26
|
+
export declare function withCooperativeRequestBudget<Result>(options: ConnectRequestOptions | undefined, defaultTimeoutMs: number | null, operation: (budget: RequestBudget) => Promise<Result>): Promise<Result>;
|
|
27
|
+
export declare function requestAbortReason(signal: AbortSignal): unknown;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { MdbaseConnectError, connectError } from "./errors.js";
|
|
2
|
+
export const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
3
|
+
export const DEFAULT_STARTUP_TIMEOUT_MS = 10_000;
|
|
4
|
+
export const DEFAULT_UPLOAD_TIMEOUT_MS = 120_000;
|
|
5
|
+
export const DEFAULT_SYNC_TIMEOUT_MS = 60_000;
|
|
6
|
+
export function resolveConnectTimeouts(timeouts = {}) {
|
|
7
|
+
return {
|
|
8
|
+
requestMs: configuredTimeout(timeouts.requestMs, DEFAULT_REQUEST_TIMEOUT_MS, "requestMs"),
|
|
9
|
+
watchStartMs: configuredTimeout(timeouts.watchStartMs, DEFAULT_STARTUP_TIMEOUT_MS, "watchStartMs"),
|
|
10
|
+
uploadMs: configuredTimeout(timeouts.uploadMs, DEFAULT_UPLOAD_TIMEOUT_MS, "uploadMs"),
|
|
11
|
+
syncMs: configuredTimeout(timeouts.syncMs, DEFAULT_SYNC_TIMEOUT_MS, "syncMs")
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function createRequestBudget(options = {}, defaultTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS, now = Date.now) {
|
|
15
|
+
const configured = options.timeoutMs === undefined ? defaultTimeoutMs : options.timeoutMs;
|
|
16
|
+
const timeoutMs = configured === null ? null : validTimeout(configured);
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const deadline = timeoutMs === null ? null : now() + timeoutMs;
|
|
19
|
+
const abortFromCaller = () => controller.abort(options.signal?.reason);
|
|
20
|
+
if (options.signal?.aborted)
|
|
21
|
+
abortFromCaller();
|
|
22
|
+
else
|
|
23
|
+
options.signal?.addEventListener("abort", abortFromCaller, { once: true });
|
|
24
|
+
const timer = timeoutMs === null
|
|
25
|
+
? undefined
|
|
26
|
+
: setTimeout(() => controller.abort(connectError("timeout", "The operation exceeded its request deadline.", { operationOutcome: "not_sent" })), timeoutMs);
|
|
27
|
+
let disposed = false;
|
|
28
|
+
return {
|
|
29
|
+
signal: controller.signal,
|
|
30
|
+
deadline,
|
|
31
|
+
remainingMs: () => deadline === null ? null : Math.max(0, deadline - now()),
|
|
32
|
+
dispose: () => {
|
|
33
|
+
if (disposed)
|
|
34
|
+
return;
|
|
35
|
+
disposed = true;
|
|
36
|
+
if (timer !== undefined)
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
options.signal?.removeEventListener("abort", abortFromCaller);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function withRequestBudget(options, defaultTimeoutMs, operation) {
|
|
43
|
+
const budget = createRequestBudget(options, defaultTimeoutMs);
|
|
44
|
+
let rejectOnAbort;
|
|
45
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
46
|
+
rejectOnAbort = reject;
|
|
47
|
+
});
|
|
48
|
+
const abort = () => rejectOnAbort?.(requestAbortReason(budget.signal));
|
|
49
|
+
budget.signal.addEventListener("abort", abort, { once: true });
|
|
50
|
+
try {
|
|
51
|
+
if (budget.signal.aborted)
|
|
52
|
+
throw requestAbortReason(budget.signal);
|
|
53
|
+
return await Promise.race([operation(budget), aborted]);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
budget.signal.removeEventListener("abort", abort);
|
|
57
|
+
budget.dispose();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Budget an operation whose transport cooperates with AbortSignal and must run
|
|
62
|
+
* its own bounded cleanup/recovery before the public promise settles.
|
|
63
|
+
*/
|
|
64
|
+
export async function withCooperativeRequestBudget(options, defaultTimeoutMs, operation) {
|
|
65
|
+
const budget = createRequestBudget(options, defaultTimeoutMs);
|
|
66
|
+
try {
|
|
67
|
+
if (budget.signal.aborted)
|
|
68
|
+
throw requestAbortReason(budget.signal);
|
|
69
|
+
return await operation(budget);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
budget.dispose();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function requestAbortReason(signal) {
|
|
76
|
+
if (signal.reason instanceof MdbaseConnectError)
|
|
77
|
+
return signal.reason;
|
|
78
|
+
return connectError("operation_cancelled", "The operation was cancelled before it changed the collection.", { operationOutcome: "not_sent", cause: signal.reason });
|
|
79
|
+
}
|
|
80
|
+
function validTimeout(value) {
|
|
81
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
82
|
+
throw new TypeError("timeoutMs must be a positive safe integer or null.");
|
|
83
|
+
}
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
function configuredTimeout(value, fallback, name) {
|
|
87
|
+
if (value === undefined)
|
|
88
|
+
return fallback;
|
|
89
|
+
if (value === null)
|
|
90
|
+
return null;
|
|
91
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
92
|
+
throw new TypeError(`${name} must be a positive safe integer or null.`);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
}
|
package/dist/runtime-utils.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type { MdbaseDeviceAuthorization } from "./authorization-types.js";
|
|
|
5
5
|
type NetworkProblemCode = "notification_registration_failed" | "notification_unregistration_failed" | "notifications_unavailable" | "temporarily_unavailable";
|
|
6
6
|
/** Normalize fetch rejection at the exact I/O boundary. */
|
|
7
7
|
export declare function connectFetch(input: RequestInfo | URL, init: RequestInit | undefined, code: NetworkProblemCode, message: string): Promise<Response>;
|
|
8
|
+
/** Decode JSON without allowing native syntax/body errors across the SDK boundary. */
|
|
9
|
+
export declare function decodeJsonResponse(response: Response, code: string, message: string): Promise<any>;
|
|
8
10
|
export declare function canonicalLoopbackUrl(value: string): string;
|
|
9
11
|
export declare function createPkce(): Promise<{
|
|
10
12
|
verifier: string;
|
package/dist/runtime-utils.js
CHANGED
|
@@ -11,6 +11,25 @@ export async function connectFetch(input, init, code, message) {
|
|
|
11
11
|
throw connectError(code, message, { cause });
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
/** Decode JSON without allowing native syntax/body errors across the SDK boundary. */
|
|
15
|
+
export async function decodeJsonResponse(response, code, message) {
|
|
16
|
+
let text;
|
|
17
|
+
try {
|
|
18
|
+
text = await response.text();
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
throw serverConnectError(code, message, { status: response.status, cause });
|
|
22
|
+
}
|
|
23
|
+
if (text.trim() === "") {
|
|
24
|
+
throw serverConnectError(code, message, { status: response.status });
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(text);
|
|
28
|
+
}
|
|
29
|
+
catch (cause) {
|
|
30
|
+
throw serverConnectError(code, message, { status: response.status, cause });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
14
33
|
export function canonicalLoopbackUrl(value) {
|
|
15
34
|
const url = new URL(value);
|
|
16
35
|
if (url.protocol !== "http:"
|
package/dist/session.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ import { MdbaseConnection, type MdbaseAuthorizationOutcome, type MdbaseAuthoriza
|
|
|
3
3
|
import type { MdbaseAuthorizationCapabilities, MdbaseConnectionInfo } from "./connection-types.js";
|
|
4
4
|
import { type AuthorizationProblemCode, type ConnectOutcome, type SessionProblemCode } from "./outcomes.js";
|
|
5
5
|
import type { MdbaseSelectionHistory, MdbaseApplicationSelection } from "./selection.js";
|
|
6
|
+
import type { ConnectRequestOptions } from "./operation-types.js";
|
|
6
7
|
export interface MdbaseSessionConnect<Frontmatter extends JsonObject> {
|
|
7
8
|
authorize(options?: MdbaseAuthorizeOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, AuthorizationProblemCode>>;
|
|
8
|
-
completeAuthorization(callbackUrl: string): Promise<ConnectOutcome<MdbaseAuthorizationResult<Frontmatter>, AuthorizationProblemCode>>;
|
|
9
|
+
completeAuthorization(callbackUrl: string, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseAuthorizationResult<Frontmatter>, AuthorizationProblemCode>>;
|
|
9
10
|
connections(): MdbaseConnectionInfo[];
|
|
10
11
|
connection(collectionId: string): MdbaseConnection<Frontmatter> | null;
|
|
11
12
|
unavailableReason(collectionId: string): MdbaseUnavailableReason | null;
|
|
@@ -52,7 +53,7 @@ export declare class MdbaseSession<Frontmatter extends JsonObject = JsonObject>
|
|
|
52
53
|
private transactionDepth;
|
|
53
54
|
private callbackPromise;
|
|
54
55
|
constructor(connect: MdbaseSessionConnect<Frontmatter>, options: MdbaseSessionOptions);
|
|
55
|
-
start(): Promise<ConnectOutcome<MdbaseSessionSnapshot<Frontmatter>, SessionProblemCode>>;
|
|
56
|
+
start(options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseSessionSnapshot<Frontmatter>, SessionProblemCode>>;
|
|
56
57
|
destroy(): void;
|
|
57
58
|
getSnapshot(): MdbaseSessionSnapshot<Frontmatter>;
|
|
58
59
|
subscribe(listener: () => void): () => void;
|
|
@@ -66,11 +67,11 @@ export declare class MdbaseSession<Frontmatter extends JsonObject = JsonObject>
|
|
|
66
67
|
authorize(target: "choose" | "selected" | {
|
|
67
68
|
collectionId: string;
|
|
68
69
|
}, options?: Omit<MdbaseAuthorizeOptions, "operations" | "returnTo" | "target">): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter>, SessionProblemCode>>;
|
|
69
|
-
ensureOperations(requiredOperations: CollectionOperation[]): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter> | {
|
|
70
|
+
ensureOperations(requiredOperations: CollectionOperation[], options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseAuthorizationOutcome<Frontmatter> | {
|
|
70
71
|
kind: "unchanged";
|
|
71
72
|
connection: MdbaseConnection<Frontmatter>;
|
|
72
73
|
}, SessionProblemCode>>;
|
|
73
|
-
handleAuthorizationCallback(callbackUrl: string): Promise<ConnectOutcome<MdbaseConnection<Frontmatter>, AuthorizationProblemCode>>;
|
|
74
|
+
handleAuthorizationCallback(callbackUrl: string, options?: ConnectRequestOptions): Promise<ConnectOutcome<MdbaseConnection<Frontmatter>, AuthorizationProblemCode>>;
|
|
74
75
|
private autoSelectOnlyConnection;
|
|
75
76
|
private refresh;
|
|
76
77
|
private refreshOnce;
|
package/dist/session.js
CHANGED
|
@@ -29,7 +29,7 @@ export class MdbaseSession {
|
|
|
29
29
|
this.snapshot = { status: "unselected", connections: [] };
|
|
30
30
|
this.refresh();
|
|
31
31
|
}
|
|
32
|
-
async start() {
|
|
32
|
+
async start(options) {
|
|
33
33
|
if (!this.started) {
|
|
34
34
|
this.started = true;
|
|
35
35
|
this.stopConnections = this.connect.onConnectionsChange(() => this.refresh());
|
|
@@ -40,7 +40,7 @@ export class MdbaseSession {
|
|
|
40
40
|
}
|
|
41
41
|
const callback = this.selection.authorizationCallback();
|
|
42
42
|
if (callback) {
|
|
43
|
-
const completed = await this.handleAuthorizationCallback(callback);
|
|
43
|
+
const completed = await this.handleAuthorizationCallback(callback, options);
|
|
44
44
|
if (!completed.ok)
|
|
45
45
|
return completed;
|
|
46
46
|
}
|
|
@@ -124,7 +124,7 @@ export class MdbaseSession {
|
|
|
124
124
|
this.refresh();
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
async ensureOperations(requiredOperations) {
|
|
127
|
+
async ensureOperations(requiredOperations, options) {
|
|
128
128
|
const current = this.snapshot;
|
|
129
129
|
if (current.status !== "ready") {
|
|
130
130
|
return connectFailure(connectProblem("collection_not_ready", "Choose an authorized collection first."));
|
|
@@ -137,6 +137,7 @@ export class MdbaseSession {
|
|
|
137
137
|
this.transactionDepth += 1;
|
|
138
138
|
try {
|
|
139
139
|
const outcome = await this.connect.authorize({
|
|
140
|
+
...options,
|
|
140
141
|
operations: uniqueOperations([...capabilities.grantedOperations, ...capabilities.missingOperations]),
|
|
141
142
|
target: { kind: "collection", collectionId: current.collectionId },
|
|
142
143
|
returnTo: this.selection.authorizationReturnTo()
|
|
@@ -151,14 +152,14 @@ export class MdbaseSession {
|
|
|
151
152
|
this.refresh();
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
handleAuthorizationCallback(callbackUrl) {
|
|
155
|
+
handleAuthorizationCallback(callbackUrl, options) {
|
|
155
156
|
if (!isAuthorizationCallbackUrl(callbackUrl)) {
|
|
156
157
|
return Promise.resolve(connectFailure(connectProblem("invalid_callback", "This URL is not an authorization callback.")));
|
|
157
158
|
}
|
|
158
159
|
if (this.callbackPromise)
|
|
159
160
|
return this.callbackPromise;
|
|
160
161
|
this.transactionDepth += 1;
|
|
161
|
-
const completion = this.connect.completeAuthorization(callbackUrl)
|
|
162
|
+
const completion = this.connect.completeAuthorization(callbackUrl, options)
|
|
162
163
|
.then((outcome) => {
|
|
163
164
|
if (!outcome.ok) {
|
|
164
165
|
const returnTo = authorizationReturnToFromProblem(outcome.problem);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StoredToken } from "./internal-types.js";
|
|
2
|
+
interface ReadStoredTokenOptions {
|
|
3
|
+
stored: string | null;
|
|
4
|
+
collectionId: string;
|
|
5
|
+
relayEncryption: "required" | "disabled";
|
|
6
|
+
invalidate(keyHandle?: string): void;
|
|
7
|
+
directCapable(token: StoredToken): boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function readStoredToken({ stored, collectionId, relayEncryption, invalidate, directCapable }: ReadStoredTokenOptions): StoredToken | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { parseGrantScope, parseStored, validFileCapability, validStoredAuthority, validStoredEncryption } from "./runtime-utils.js";
|
|
2
|
+
export function readStoredToken({ stored, collectionId, relayEncryption, invalidate, directCapable }) {
|
|
3
|
+
const token = parseStored(stored);
|
|
4
|
+
const reject = (keyHandle) => {
|
|
5
|
+
invalidate(typeof keyHandle === "string" ? keyHandle : undefined);
|
|
6
|
+
return null;
|
|
7
|
+
};
|
|
8
|
+
if (!token) {
|
|
9
|
+
if (stored)
|
|
10
|
+
reject();
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
if (token.version !== 1
|
|
14
|
+
|| typeof token.accessToken !== "string"
|
|
15
|
+
|| token.accessToken.length === 0
|
|
16
|
+
|| typeof token.clientId !== "string"
|
|
17
|
+
|| token.clientId.length === 0
|
|
18
|
+
|| token.collectionId !== collectionId
|
|
19
|
+
|| typeof token.collectionName !== "string"
|
|
20
|
+
|| token.collectionName.length === 0
|
|
21
|
+
|| !Array.isArray(token.operations)
|
|
22
|
+
|| token.operations.some((operation) => typeof operation !== "string")
|
|
23
|
+
|| typeof token.expiresAt !== "number"
|
|
24
|
+
|| !Number.isFinite(token.expiresAt)
|
|
25
|
+
|| (token.refreshToken !== undefined
|
|
26
|
+
&& (typeof token.refreshToken !== "string" || token.refreshToken.length === 0))
|
|
27
|
+
|| (token.refreshExpiresAt !== undefined
|
|
28
|
+
&& (typeof token.refreshExpiresAt !== "number" || !Number.isFinite(token.refreshExpiresAt))))
|
|
29
|
+
return reject(token.keyHandle);
|
|
30
|
+
if (!parseGrantScope(token.scope))
|
|
31
|
+
return reject(token.keyHandle);
|
|
32
|
+
if (token.fileCapability && !validFileCapability(token.fileCapability)) {
|
|
33
|
+
return reject(token.keyHandle);
|
|
34
|
+
}
|
|
35
|
+
if (token.authority && !validStoredAuthority(token.authority, token.collectionId)) {
|
|
36
|
+
return reject(token.keyHandle);
|
|
37
|
+
}
|
|
38
|
+
if (relayEncryption === "required") {
|
|
39
|
+
if (token.authority) {
|
|
40
|
+
if (!token.keyHandle || !token.authority.proofPublicKey) {
|
|
41
|
+
return reject(token.keyHandle);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (!token.grantId
|
|
45
|
+
|| !token.keyHandle
|
|
46
|
+
|| !validStoredEncryption(token.encryption, token.collectionId)) {
|
|
47
|
+
return reject(token.keyHandle);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (token.expiresAt <= Date.now()
|
|
51
|
+
&& (!token.refreshToken || (token.refreshExpiresAt ?? 0) <= Date.now())) {
|
|
52
|
+
// The cloud bearer and local grant proof have separate lifetimes. Keep an
|
|
53
|
+
// encrypted local grant usable while the connector still recognizes it.
|
|
54
|
+
if (directCapable(token))
|
|
55
|
+
return token;
|
|
56
|
+
invalidate(token.keyHandle);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return token;
|
|
60
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StoredToken } from "./internal-types.js";
|
|
2
|
+
interface StoredTokenResponseOptions {
|
|
3
|
+
body: any;
|
|
4
|
+
clientId: string;
|
|
5
|
+
keyHandle?: string;
|
|
6
|
+
previous: StoredToken | null;
|
|
7
|
+
defaultApplicationOrigin: string;
|
|
8
|
+
pinConnectorIdentity(connectorId: string, publicKey: string): void;
|
|
9
|
+
}
|
|
10
|
+
export declare function storedTokenFromResponse({ body, clientId, keyHandle, previous, defaultApplicationOrigin, pinConnectorIdentity }: StoredTokenResponseOptions): StoredToken;
|
|
11
|
+
export {};
|