@mdbase-dev/connect-protocol 0.1.0-beta.27 → 0.1.0-beta.29
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/dist/application-authorization.d.ts +2 -3
- package/dist/application-authorization.js +5 -10
- package/dist/capabilities.d.ts +51 -0
- package/dist/capabilities.js +49 -0
- package/dist/connect-problems.generated.d.ts +53 -24
- package/dist/connect-problems.generated.js +38 -2
- package/dist/index.d.ts +8 -14
- package/dist/index.js +3 -2
- package/dist/manifest.d.ts +45 -0
- package/dist/manifest.js +355 -0
- package/package.json +10 -3
- package/schemas/connect-problem.v1.schema.json +165 -48
- package/schemas/connect-problems.v1.catalog.json +26 -3
- package/schemas/connect-protocol.v1.schema.json +3 -19
- package/schemas/mdbase-app.schema.json +60 -2
|
@@ -2,12 +2,11 @@ import type { ApplicationFileRequirement } from "./files.js";
|
|
|
2
2
|
import type { CollectionOperation } from "./operations.js";
|
|
3
3
|
export type ApplicationAuthorizationFlow = "authorization_code" | "device_code";
|
|
4
4
|
export interface ApplicationAuthorizationBinding {
|
|
5
|
-
protocol_version:
|
|
5
|
+
protocol_version: 2;
|
|
6
6
|
authorization_id: string;
|
|
7
7
|
application_id: string;
|
|
8
8
|
application_manifest_digest: string;
|
|
9
9
|
application_installation_id: string;
|
|
10
|
-
installation_agreement_public_key: string;
|
|
11
10
|
installation_signing_public_key: string;
|
|
12
11
|
grant_agreement_public_key: string;
|
|
13
12
|
grant_signing_public_key: string;
|
|
@@ -26,5 +25,5 @@ export interface ApplicationAuthorizationProof {
|
|
|
26
25
|
binding: ApplicationAuthorizationBinding;
|
|
27
26
|
signature: string;
|
|
28
27
|
}
|
|
29
|
-
export declare function
|
|
28
|
+
export declare function applicationInstallationIdFromPublicKey(signingPublicKey: string): Promise<string>;
|
|
30
29
|
export declare function authorizationSigningMessage(binding: ApplicationAuthorizationBinding): Uint8Array;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
const INSTALLATION_ID_DOMAIN = new TextEncoder().encode("mdbase-connect application installation id
|
|
2
|
-
const AUTHORIZATION_PROOF_DOMAIN = new TextEncoder().encode("mdbase-connect application authorization proof\0");
|
|
3
|
-
export async function
|
|
4
|
-
const agreement = publicKey(agreementPublicKey);
|
|
1
|
+
const INSTALLATION_ID_DOMAIN = new TextEncoder().encode("mdbase-connect application installation id v2\0");
|
|
2
|
+
const AUTHORIZATION_PROOF_DOMAIN = new TextEncoder().encode("mdbase-connect application authorization proof v2\0");
|
|
3
|
+
export async function applicationInstallationIdFromPublicKey(signingPublicKey) {
|
|
5
4
|
const signing = publicKey(signingPublicKey);
|
|
6
|
-
|
|
7
|
-
throw new Error("Application installation agreement and signing keys must be distinct.");
|
|
8
|
-
}
|
|
9
|
-
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", concat([INSTALLATION_ID_DOMAIN, field(agreement), field(signing)])));
|
|
5
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", concat([INSTALLATION_ID_DOMAIN, field(signing)])));
|
|
10
6
|
const id = digest.slice(0, 16);
|
|
11
7
|
id[6] = (id[6] & 0x0f) | 0x80;
|
|
12
8
|
id[8] = (id[8] & 0x3f) | 0x80;
|
|
@@ -20,7 +16,6 @@ export async function applicationInstallationIdFromPublicKeys(agreementPublicKey
|
|
|
20
16
|
}
|
|
21
17
|
export function authorizationSigningMessage(binding) {
|
|
22
18
|
const keys = [
|
|
23
|
-
publicKey(binding.installation_agreement_public_key),
|
|
24
19
|
publicKey(binding.installation_signing_public_key),
|
|
25
20
|
publicKey(binding.grant_agreement_public_key),
|
|
26
21
|
publicKey(binding.grant_signing_public_key)
|
|
@@ -30,7 +25,7 @@ export function authorizationSigningMessage(binding) {
|
|
|
30
25
|
}
|
|
31
26
|
const nonce = canonicalBase64(binding.authorization_nonce);
|
|
32
27
|
const challenge = canonicalBase64(binding.code_challenge);
|
|
33
|
-
if (binding.protocol_version !==
|
|
28
|
+
if (binding.protocol_version !== 2
|
|
34
29
|
|| nonce.byteLength !== 32
|
|
35
30
|
|| !/^[0-9a-f]{64}$/u.test(binding.application_manifest_digest)
|
|
36
31
|
|| !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/u.test(binding.issued_at)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { CollectionOperation } from "./operations.js";
|
|
2
|
+
export declare const APPLICATION_CAPABILITY_CONTRACT_VERSION: 1;
|
|
3
|
+
/**
|
|
4
|
+
* Stable application-facing abilities. Applications declare intent in these
|
|
5
|
+
* terms; Connect alone translates them into wire-level collection operations.
|
|
6
|
+
*/
|
|
7
|
+
export declare const APPLICATION_CAPABILITY_DEFINITIONS: {
|
|
8
|
+
readonly "collection.inspect": readonly ["describe"];
|
|
9
|
+
readonly "records.watch": readonly ["changes"];
|
|
10
|
+
readonly "records.read": readonly ["read"];
|
|
11
|
+
readonly "records.query": readonly ["query"];
|
|
12
|
+
readonly "records.validate": readonly ["validate"];
|
|
13
|
+
readonly "records.create": readonly ["create"];
|
|
14
|
+
readonly "records.update": readonly ["update"];
|
|
15
|
+
readonly "records.delete": readonly ["delete"];
|
|
16
|
+
readonly "records.rename": readonly ["rename"];
|
|
17
|
+
readonly "views.list": readonly ["list_views"];
|
|
18
|
+
readonly "views.execute": readonly ["execute_view"];
|
|
19
|
+
readonly "views.source.read": readonly ["read_view_source"];
|
|
20
|
+
readonly "views.source.create": readonly ["create_view_source"];
|
|
21
|
+
readonly "views.source.update": readonly ["update_view_source"];
|
|
22
|
+
readonly "views.source.delete": readonly ["delete_view_source"];
|
|
23
|
+
readonly "definitions.contracts.current": readonly [];
|
|
24
|
+
readonly "definitions.read": readonly ["read_type"];
|
|
25
|
+
readonly "definitions.create": readonly ["create_type"];
|
|
26
|
+
readonly "definitions.update": readonly ["update_type"];
|
|
27
|
+
readonly "definitions.type-pack.inspect": readonly ["assess_type_pack"];
|
|
28
|
+
readonly "definitions.type-pack.apply": readonly ["assess_type_pack", "apply_type_pack"];
|
|
29
|
+
readonly "timers.list": readonly ["list_timers"];
|
|
30
|
+
readonly "timers.put": readonly ["put_timer"];
|
|
31
|
+
readonly "timers.cancel": readonly ["cancel_timer"];
|
|
32
|
+
readonly "timers.reconcile": readonly ["reconcile_timers"];
|
|
33
|
+
readonly "sync.offline-replica": readonly ["sync"];
|
|
34
|
+
readonly "notifications.background-delivery": readonly [];
|
|
35
|
+
readonly "files.list": readonly [];
|
|
36
|
+
readonly "files.read": readonly [];
|
|
37
|
+
readonly "files.add": readonly [];
|
|
38
|
+
readonly "files.replace": readonly [];
|
|
39
|
+
readonly "files.move": readonly [];
|
|
40
|
+
readonly "files.delete": readonly [];
|
|
41
|
+
};
|
|
42
|
+
export type ApplicationCapabilityId = keyof typeof APPLICATION_CAPABILITY_DEFINITIONS;
|
|
43
|
+
export interface ApplicationCapabilityRequirements {
|
|
44
|
+
contract_version: typeof APPLICATION_CAPABILITY_CONTRACT_VERSION;
|
|
45
|
+
required: ApplicationCapabilityId[];
|
|
46
|
+
optional?: ApplicationCapabilityId[];
|
|
47
|
+
}
|
|
48
|
+
export declare function operationsForApplicationCapabilities(requirements: ApplicationCapabilityRequirements, options?: {
|
|
49
|
+
includeOptional?: boolean;
|
|
50
|
+
}): CollectionOperation[];
|
|
51
|
+
export declare function capabilityOperations(capability: ApplicationCapabilityId): CollectionOperation[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export const APPLICATION_CAPABILITY_CONTRACT_VERSION = 1;
|
|
2
|
+
/**
|
|
3
|
+
* Stable application-facing abilities. Applications declare intent in these
|
|
4
|
+
* terms; Connect alone translates them into wire-level collection operations.
|
|
5
|
+
*/
|
|
6
|
+
export const APPLICATION_CAPABILITY_DEFINITIONS = {
|
|
7
|
+
"collection.inspect": ["describe"],
|
|
8
|
+
"records.watch": ["changes"],
|
|
9
|
+
"records.read": ["read"],
|
|
10
|
+
"records.query": ["query"],
|
|
11
|
+
"records.validate": ["validate"],
|
|
12
|
+
"records.create": ["create"],
|
|
13
|
+
"records.update": ["update"],
|
|
14
|
+
"records.delete": ["delete"],
|
|
15
|
+
"records.rename": ["rename"],
|
|
16
|
+
"views.list": ["list_views"],
|
|
17
|
+
"views.execute": ["execute_view"],
|
|
18
|
+
"views.source.read": ["read_view_source"],
|
|
19
|
+
"views.source.create": ["create_view_source"],
|
|
20
|
+
"views.source.update": ["update_view_source"],
|
|
21
|
+
"views.source.delete": ["delete_view_source"],
|
|
22
|
+
"definitions.contracts.current": [],
|
|
23
|
+
"definitions.read": ["read_type"],
|
|
24
|
+
"definitions.create": ["create_type"],
|
|
25
|
+
"definitions.update": ["update_type"],
|
|
26
|
+
"definitions.type-pack.inspect": ["assess_type_pack"],
|
|
27
|
+
"definitions.type-pack.apply": ["assess_type_pack", "apply_type_pack"],
|
|
28
|
+
"timers.list": ["list_timers"],
|
|
29
|
+
"timers.put": ["put_timer"],
|
|
30
|
+
"timers.cancel": ["cancel_timer"],
|
|
31
|
+
"timers.reconcile": ["reconcile_timers"],
|
|
32
|
+
"sync.offline-replica": ["sync"],
|
|
33
|
+
"notifications.background-delivery": [],
|
|
34
|
+
"files.list": [],
|
|
35
|
+
"files.read": [],
|
|
36
|
+
"files.add": [],
|
|
37
|
+
"files.replace": [],
|
|
38
|
+
"files.move": [],
|
|
39
|
+
"files.delete": []
|
|
40
|
+
};
|
|
41
|
+
export function operationsForApplicationCapabilities(requirements, options = {}) {
|
|
42
|
+
const capabilities = options.includeOptional === false
|
|
43
|
+
? requirements.required
|
|
44
|
+
: [...requirements.required, ...(requirements.optional ?? [])];
|
|
45
|
+
return [...new Set(capabilities.flatMap((capability) => APPLICATION_CAPABILITY_DEFINITIONS[capability]))];
|
|
46
|
+
}
|
|
47
|
+
export function capabilityOperations(capability) {
|
|
48
|
+
return [...APPLICATION_CAPABILITY_DEFINITIONS[capability]];
|
|
49
|
+
}
|
|
@@ -8,6 +8,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
8
8
|
readonly category: "availability";
|
|
9
9
|
readonly recovery: "resume_connector_access";
|
|
10
10
|
};
|
|
11
|
+
readonly application_identity_unavailable: {
|
|
12
|
+
readonly category: "compatibility";
|
|
13
|
+
readonly recovery: "upgrade_application";
|
|
14
|
+
};
|
|
11
15
|
readonly approval_window_blocked: {
|
|
12
16
|
readonly category: "authorization";
|
|
13
17
|
readonly recovery: "reauthorize";
|
|
@@ -24,6 +28,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
24
28
|
readonly category: "authorization";
|
|
25
29
|
readonly recovery: "reauthorize";
|
|
26
30
|
};
|
|
31
|
+
readonly authorization_replayed: {
|
|
32
|
+
readonly category: "integrity";
|
|
33
|
+
readonly recovery: "reauthorize";
|
|
34
|
+
};
|
|
27
35
|
readonly browser_required: {
|
|
28
36
|
readonly category: "compatibility";
|
|
29
37
|
readonly recovery: "none";
|
|
@@ -152,10 +160,6 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
152
160
|
readonly category: "conflict";
|
|
153
161
|
readonly recovery: "retry";
|
|
154
162
|
};
|
|
155
|
-
readonly first_contact_handler_required: {
|
|
156
|
-
readonly category: "compatibility";
|
|
157
|
-
readonly recovery: "upgrade_application";
|
|
158
|
-
};
|
|
159
163
|
readonly hosted_provider_unavailable: {
|
|
160
164
|
readonly category: "availability";
|
|
161
165
|
readonly recovery: "retry";
|
|
@@ -164,6 +168,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
164
168
|
readonly category: "authorization";
|
|
165
169
|
readonly recovery: "reauthorize";
|
|
166
170
|
};
|
|
171
|
+
readonly invalid_application_authorization: {
|
|
172
|
+
readonly category: "validation";
|
|
173
|
+
readonly recovery: "fix_request";
|
|
174
|
+
};
|
|
167
175
|
readonly invalid_application_manifest: {
|
|
168
176
|
readonly category: "validation";
|
|
169
177
|
readonly recovery: "fix_request";
|
|
@@ -180,10 +188,6 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
180
188
|
readonly category: "integrity";
|
|
181
189
|
readonly recovery: "contact_support";
|
|
182
190
|
};
|
|
183
|
-
readonly invalid_first_contact: {
|
|
184
|
-
readonly category: "integrity";
|
|
185
|
-
readonly recovery: "contact_support";
|
|
186
|
-
};
|
|
187
191
|
readonly invalid_loopback_url: {
|
|
188
192
|
readonly category: "validation";
|
|
189
193
|
readonly recovery: "fix_request";
|
|
@@ -304,6 +308,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
304
308
|
readonly category: "availability";
|
|
305
309
|
readonly recovery: "retry";
|
|
306
310
|
};
|
|
311
|
+
readonly reconnect_required: {
|
|
312
|
+
readonly category: "authorization";
|
|
313
|
+
readonly recovery: "reauthorize";
|
|
314
|
+
};
|
|
307
315
|
readonly redirect_uri_required: {
|
|
308
316
|
readonly category: "validation";
|
|
309
317
|
readonly recovery: "fix_request";
|
|
@@ -388,6 +396,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
388
396
|
"return_to"?: string;
|
|
389
397
|
};
|
|
390
398
|
"access_paused": undefined;
|
|
399
|
+
"application_identity_unavailable": undefined;
|
|
391
400
|
"approval_window_blocked": {
|
|
392
401
|
"user_code": string;
|
|
393
402
|
"verification_uri": string;
|
|
@@ -398,6 +407,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
398
407
|
"authority_authorization_changed": undefined;
|
|
399
408
|
"authorization_cancelled": undefined;
|
|
400
409
|
"authorization_expired": undefined;
|
|
410
|
+
"authorization_replayed": undefined;
|
|
401
411
|
"browser_required": undefined;
|
|
402
412
|
"callback_url_required": undefined;
|
|
403
413
|
"change_cursor_reset": undefined;
|
|
@@ -446,18 +456,24 @@ export interface ConnectProblemDetailsByCode {
|
|
|
446
456
|
"file_not_found": undefined;
|
|
447
457
|
"file_source_mismatch": undefined;
|
|
448
458
|
"file_upload_incomplete": undefined;
|
|
449
|
-
"first_contact_handler_required": undefined;
|
|
450
459
|
"hosted_provider_unavailable": undefined;
|
|
451
460
|
"insufficient_access": {
|
|
452
461
|
"required_operations": Array<string>;
|
|
453
462
|
"granted_operations": Array<string>;
|
|
454
463
|
"missing_operations": Array<string>;
|
|
455
464
|
};
|
|
456
|
-
"
|
|
465
|
+
"invalid_application_authorization": undefined;
|
|
466
|
+
"invalid_application_manifest": {
|
|
467
|
+
"issues": Array<{
|
|
468
|
+
"path": string;
|
|
469
|
+
"keyword": string;
|
|
470
|
+
"message": string;
|
|
471
|
+
"params": Record<string, unknown>;
|
|
472
|
+
}>;
|
|
473
|
+
};
|
|
457
474
|
"invalid_callback": undefined;
|
|
458
475
|
"invalid_device_authorization_response": undefined;
|
|
459
476
|
"invalid_encrypted_response": undefined;
|
|
460
|
-
"invalid_first_contact": undefined;
|
|
461
477
|
"invalid_loopback_url": undefined;
|
|
462
478
|
"invalid_mutation_id": undefined;
|
|
463
479
|
"invalid_operation_response": undefined;
|
|
@@ -493,6 +509,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
493
509
|
"rate_limited": {
|
|
494
510
|
"retry_after_ms"?: number;
|
|
495
511
|
};
|
|
512
|
+
"reconnect_required": undefined;
|
|
496
513
|
"redirect_uri_required": undefined;
|
|
497
514
|
"reference_updates_unsupported": undefined;
|
|
498
515
|
"relay_authorization_expired": undefined;
|
|
@@ -524,6 +541,12 @@ export interface ConnectProblemByCode {
|
|
|
524
541
|
recovery: "resume_connector_access";
|
|
525
542
|
details?: never;
|
|
526
543
|
};
|
|
544
|
+
"application_identity_unavailable": ConnectProblemBase & {
|
|
545
|
+
code: "application_identity_unavailable";
|
|
546
|
+
category: "compatibility";
|
|
547
|
+
recovery: "upgrade_application";
|
|
548
|
+
details?: never;
|
|
549
|
+
};
|
|
527
550
|
"approval_window_blocked": ConnectProblemBase & {
|
|
528
551
|
code: "approval_window_blocked";
|
|
529
552
|
category: "authorization";
|
|
@@ -548,6 +571,12 @@ export interface ConnectProblemByCode {
|
|
|
548
571
|
recovery: "reauthorize";
|
|
549
572
|
details?: never;
|
|
550
573
|
};
|
|
574
|
+
"authorization_replayed": ConnectProblemBase & {
|
|
575
|
+
code: "authorization_replayed";
|
|
576
|
+
category: "integrity";
|
|
577
|
+
recovery: "reauthorize";
|
|
578
|
+
details?: never;
|
|
579
|
+
};
|
|
551
580
|
"browser_required": ConnectProblemBase & {
|
|
552
581
|
code: "browser_required";
|
|
553
582
|
category: "compatibility";
|
|
@@ -740,12 +769,6 @@ export interface ConnectProblemByCode {
|
|
|
740
769
|
recovery: "retry";
|
|
741
770
|
details?: never;
|
|
742
771
|
};
|
|
743
|
-
"first_contact_handler_required": ConnectProblemBase & {
|
|
744
|
-
code: "first_contact_handler_required";
|
|
745
|
-
category: "compatibility";
|
|
746
|
-
recovery: "upgrade_application";
|
|
747
|
-
details?: never;
|
|
748
|
-
};
|
|
749
772
|
"hosted_provider_unavailable": ConnectProblemBase & {
|
|
750
773
|
code: "hosted_provider_unavailable";
|
|
751
774
|
category: "availability";
|
|
@@ -758,11 +781,17 @@ export interface ConnectProblemByCode {
|
|
|
758
781
|
recovery: "reauthorize";
|
|
759
782
|
details: ConnectProblemDetailsByCode["insufficient_access"];
|
|
760
783
|
};
|
|
784
|
+
"invalid_application_authorization": ConnectProblemBase & {
|
|
785
|
+
code: "invalid_application_authorization";
|
|
786
|
+
category: "validation";
|
|
787
|
+
recovery: "fix_request";
|
|
788
|
+
details?: never;
|
|
789
|
+
};
|
|
761
790
|
"invalid_application_manifest": ConnectProblemBase & {
|
|
762
791
|
code: "invalid_application_manifest";
|
|
763
792
|
category: "validation";
|
|
764
793
|
recovery: "fix_request";
|
|
765
|
-
details
|
|
794
|
+
details: ConnectProblemDetailsByCode["invalid_application_manifest"];
|
|
766
795
|
};
|
|
767
796
|
"invalid_callback": ConnectProblemBase & {
|
|
768
797
|
code: "invalid_callback";
|
|
@@ -782,12 +811,6 @@ export interface ConnectProblemByCode {
|
|
|
782
811
|
recovery: "contact_support";
|
|
783
812
|
details?: never;
|
|
784
813
|
};
|
|
785
|
-
"invalid_first_contact": ConnectProblemBase & {
|
|
786
|
-
code: "invalid_first_contact";
|
|
787
|
-
category: "integrity";
|
|
788
|
-
recovery: "contact_support";
|
|
789
|
-
details?: never;
|
|
790
|
-
};
|
|
791
814
|
"invalid_loopback_url": ConnectProblemBase & {
|
|
792
815
|
code: "invalid_loopback_url";
|
|
793
816
|
category: "validation";
|
|
@@ -968,6 +991,12 @@ export interface ConnectProblemByCode {
|
|
|
968
991
|
recovery: "retry";
|
|
969
992
|
details?: ConnectProblemDetailsByCode["rate_limited"];
|
|
970
993
|
};
|
|
994
|
+
"reconnect_required": ConnectProblemBase & {
|
|
995
|
+
code: "reconnect_required";
|
|
996
|
+
category: "authorization";
|
|
997
|
+
recovery: "reauthorize";
|
|
998
|
+
details?: never;
|
|
999
|
+
};
|
|
971
1000
|
"redirect_uri_required": ConnectProblemBase & {
|
|
972
1001
|
code: "redirect_uri_required";
|
|
973
1002
|
category: "validation";
|
|
@@ -3,10 +3,12 @@ export const CONNECT_PROBLEM_VERSION = 1;
|
|
|
3
3
|
export const CONNECT_PROBLEM_CATALOG = {
|
|
4
4
|
"access_denied": { category: "authorization", recovery: "reauthorize" },
|
|
5
5
|
"access_paused": { category: "availability", recovery: "resume_connector_access" },
|
|
6
|
+
"application_identity_unavailable": { category: "compatibility", recovery: "upgrade_application" },
|
|
6
7
|
"approval_window_blocked": { category: "authorization", recovery: "reauthorize" },
|
|
7
8
|
"authority_authorization_changed": { category: "authorization", recovery: "reauthorize" },
|
|
8
9
|
"authorization_cancelled": { category: "cancellation", recovery: "none" },
|
|
9
10
|
"authorization_expired": { category: "authorization", recovery: "reauthorize" },
|
|
11
|
+
"authorization_replayed": { category: "integrity", recovery: "reauthorize" },
|
|
10
12
|
"browser_required": { category: "compatibility", recovery: "none" },
|
|
11
13
|
"callback_url_required": { category: "validation", recovery: "fix_request" },
|
|
12
14
|
"change_cursor_reset": { category: "conflict", recovery: "refresh" },
|
|
@@ -39,14 +41,13 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
39
41
|
"file_not_found": { category: "conflict", recovery: "refresh" },
|
|
40
42
|
"file_source_mismatch": { category: "conflict", recovery: "refresh" },
|
|
41
43
|
"file_upload_incomplete": { category: "conflict", recovery: "retry" },
|
|
42
|
-
"first_contact_handler_required": { category: "compatibility", recovery: "upgrade_application" },
|
|
43
44
|
"hosted_provider_unavailable": { category: "availability", recovery: "retry" },
|
|
44
45
|
"insufficient_access": { category: "authorization", recovery: "reauthorize" },
|
|
46
|
+
"invalid_application_authorization": { category: "validation", recovery: "fix_request" },
|
|
45
47
|
"invalid_application_manifest": { category: "validation", recovery: "fix_request" },
|
|
46
48
|
"invalid_callback": { category: "validation", recovery: "fix_request" },
|
|
47
49
|
"invalid_device_authorization_response": { category: "integrity", recovery: "contact_support" },
|
|
48
50
|
"invalid_encrypted_response": { category: "integrity", recovery: "contact_support" },
|
|
49
|
-
"invalid_first_contact": { category: "integrity", recovery: "contact_support" },
|
|
50
51
|
"invalid_loopback_url": { category: "validation", recovery: "fix_request" },
|
|
51
52
|
"invalid_mutation_id": { category: "validation", recovery: "fix_request" },
|
|
52
53
|
"invalid_operation_response": { category: "integrity", recovery: "contact_support" },
|
|
@@ -77,6 +78,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
77
78
|
"pending_mutation_unresolved": { category: "conflict", recovery: "resolve_outcome" },
|
|
78
79
|
"query_snapshot_changed": { category: "conflict", recovery: "refresh" },
|
|
79
80
|
"rate_limited": { category: "availability", recovery: "retry" },
|
|
81
|
+
"reconnect_required": { category: "authorization", recovery: "reauthorize" },
|
|
80
82
|
"redirect_uri_required": { category: "validation", recovery: "fix_request" },
|
|
81
83
|
"reference_updates_unsupported": { category: "compatibility", recovery: "fix_request" },
|
|
82
84
|
"relay_authorization_expired": { category: "authorization", recovery: "reauthorize" },
|
|
@@ -252,6 +254,40 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
256
|
},
|
|
257
|
+
"invalid_application_manifest": {
|
|
258
|
+
"type": "object",
|
|
259
|
+
"required": [
|
|
260
|
+
"issues"
|
|
261
|
+
],
|
|
262
|
+
"properties": {
|
|
263
|
+
"issues": {
|
|
264
|
+
"type": "array",
|
|
265
|
+
"items": {
|
|
266
|
+
"type": "object",
|
|
267
|
+
"required": [
|
|
268
|
+
"path",
|
|
269
|
+
"keyword",
|
|
270
|
+
"message",
|
|
271
|
+
"params"
|
|
272
|
+
],
|
|
273
|
+
"properties": {
|
|
274
|
+
"path": {
|
|
275
|
+
"type": "string"
|
|
276
|
+
},
|
|
277
|
+
"keyword": {
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
280
|
+
"message": {
|
|
281
|
+
"type": "string"
|
|
282
|
+
},
|
|
283
|
+
"params": {
|
|
284
|
+
"type": "object"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
},
|
|
255
291
|
"operation_invalid": {
|
|
256
292
|
"type": "object",
|
|
257
293
|
"required": [
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import type { ConnectProblem } from "./connect-problems.generated.js";
|
|
2
2
|
import type { ApplicationFileRequirement, CollectionFileDescriptor, FileCapability } from "./files.js";
|
|
3
3
|
import type { CollectionOperation } from "./operations.js";
|
|
4
|
+
import type { ApplicationCapabilityRequirements } from "./capabilities.js";
|
|
4
5
|
import type { ContractRequirement, ContractSetupChoice, TypePackProvision } from "./type-packs.js";
|
|
5
6
|
import type { ApplicationAuthorizationProof } from "./application-authorization.js";
|
|
6
7
|
export * from "./connect-problems.generated.js";
|
|
7
8
|
export * from "./files.js";
|
|
8
9
|
export * from "./operations.js";
|
|
10
|
+
export * from "./capabilities.js";
|
|
9
11
|
export * from "./application-authorization.js";
|
|
10
12
|
export * from "./type-packs.js";
|
|
11
13
|
export declare const CONTROL_PROTOCOL_VERSION: 1;
|
|
12
14
|
export declare const ENCRYPTED_RELAY_PROTOCOL_VERSION: 1;
|
|
13
|
-
export declare const
|
|
15
|
+
export declare const APPLICATION_AUTHORIZATION_PROTOCOL_VERSION: 2;
|
|
14
16
|
export declare const LOOPBACK_PROTOCOL_VERSION: 1;
|
|
15
17
|
export declare const DEFAULT_LOOPBACK_PORT: 28485;
|
|
16
18
|
export declare const RELAY_ENCRYPTION_SUITE: "P256-HKDF-SHA256-AES256GCM";
|
|
17
19
|
export declare const SYNC_PROTOCOL_VERSION: 1;
|
|
18
20
|
export declare const CONTRACT_SETUP_CAPABILITY: "contract-setup-v1";
|
|
19
21
|
export declare const FILE_RELAY_CAPABILITY: "file-relay-v1";
|
|
20
|
-
export declare const RELAY_REQUIRED_CAPABILITIES: readonly ["application-
|
|
21
|
-
export declare const RELAY_CAPABILITIES: readonly ["application-
|
|
22
|
+
export declare const RELAY_REQUIRED_CAPABILITIES: readonly ["application-authorization-v2", "authorization-activation", "encrypted-relay", "policy-ack"];
|
|
23
|
+
export declare const RELAY_CAPABILITIES: readonly ["application-authorization-v2", "authorization-activation", "encrypted-relay", "policy-ack", "contract-setup-v1", "file-relay-v1"];
|
|
22
24
|
export declare const AUTHORITY_PROOF_VERSION: 1;
|
|
23
25
|
export declare const AUTHORITY_PROOF_ALGORITHM: "P256-SHA256";
|
|
24
26
|
export declare const AUTHORITY_PROOF_DOMAIN: "mdbase-authority-request-proof-v1";
|
|
@@ -146,6 +148,8 @@ export interface NotificationWebhook {
|
|
|
146
148
|
}
|
|
147
149
|
export interface ApplicationRequirements {
|
|
148
150
|
contracts: ContractRequirement[];
|
|
151
|
+
/** Versioned semantic intent compiled by Connect into exact operations. */
|
|
152
|
+
capabilities?: ApplicationCapabilityRequirements;
|
|
149
153
|
/** Access boundary requested after compatibility and provisioning checks. */
|
|
150
154
|
access?: "contract" | "full_collection";
|
|
151
155
|
/** Restrict authorization to durable provider-backed collections. */
|
|
@@ -225,11 +229,10 @@ export interface GrantPolicy {
|
|
|
225
229
|
created_at: string;
|
|
226
230
|
encryption?: GrantEncryption;
|
|
227
231
|
file_capability?: FileCapability;
|
|
228
|
-
first_contact: FirstContactBinding;
|
|
229
232
|
application_authorization: ApplicationAuthorizationProof;
|
|
230
233
|
}
|
|
231
234
|
/** Presentation-only grant shape used outside a local authorization boundary. */
|
|
232
|
-
export type GrantSummary = Omit<GrantPolicy, "
|
|
235
|
+
export type GrantSummary = Omit<GrantPolicy, "application_authorization">;
|
|
233
236
|
export interface GrantEncryption {
|
|
234
237
|
protocol_version: 1;
|
|
235
238
|
suite: typeof RELAY_ENCRYPTION_SUITE;
|
|
@@ -240,15 +243,6 @@ export interface GrantEncryption {
|
|
|
240
243
|
application_agreement_public_key: string;
|
|
241
244
|
connector_agreement_public_key: string;
|
|
242
245
|
}
|
|
243
|
-
export interface FirstContactBinding {
|
|
244
|
-
protocol_version: typeof FIRST_CONTACT_PROTOCOL_VERSION;
|
|
245
|
-
application_id: string;
|
|
246
|
-
application_installation_id: string;
|
|
247
|
-
application_agreement_public_key: string;
|
|
248
|
-
application_signing_public_key: string;
|
|
249
|
-
connector_id: string;
|
|
250
|
-
connector_agreement_public_key: string;
|
|
251
|
-
}
|
|
252
246
|
export interface EncryptedRelayEnvelope {
|
|
253
247
|
protocol_version: 1;
|
|
254
248
|
suite: typeof RELAY_ENCRYPTION_SUITE;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export * from "./connect-problems.generated.js";
|
|
2
2
|
export * from "./files.js";
|
|
3
3
|
export * from "./operations.js";
|
|
4
|
+
export * from "./capabilities.js";
|
|
4
5
|
export * from "./application-authorization.js";
|
|
5
6
|
export * from "./type-packs.js";
|
|
6
7
|
export const CONTROL_PROTOCOL_VERSION = 1;
|
|
7
8
|
export const ENCRYPTED_RELAY_PROTOCOL_VERSION = 1;
|
|
8
|
-
export const
|
|
9
|
+
export const APPLICATION_AUTHORIZATION_PROTOCOL_VERSION = 2;
|
|
9
10
|
export const LOOPBACK_PROTOCOL_VERSION = 1;
|
|
10
11
|
export const DEFAULT_LOOPBACK_PORT = 28_485;
|
|
11
12
|
export const RELAY_ENCRYPTION_SUITE = "P256-HKDF-SHA256-AES256GCM";
|
|
@@ -13,7 +14,7 @@ export const SYNC_PROTOCOL_VERSION = 1;
|
|
|
13
14
|
export const CONTRACT_SETUP_CAPABILITY = "contract-setup-v1";
|
|
14
15
|
export const FILE_RELAY_CAPABILITY = "file-relay-v1";
|
|
15
16
|
export const RELAY_REQUIRED_CAPABILITIES = [
|
|
16
|
-
"application-
|
|
17
|
+
"application-authorization-v2",
|
|
17
18
|
"authorization-activation",
|
|
18
19
|
"encrypted-relay",
|
|
19
20
|
"policy-ack"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ApplicationNotifications, type ApplicationProvisions, type ApplicationRequirements, type MdbasePortableAppManifest, type MdbaseWebAppManifest } from "./index.js";
|
|
2
|
+
export declare const APPLICATION_MANIFEST_MAX_BYTES = 524288;
|
|
3
|
+
export interface ManifestValidationIssue {
|
|
4
|
+
path: string;
|
|
5
|
+
keyword: string;
|
|
6
|
+
message: string;
|
|
7
|
+
params: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export type ManifestValidationResult = {
|
|
10
|
+
valid: true;
|
|
11
|
+
issues: [];
|
|
12
|
+
} | {
|
|
13
|
+
valid: false;
|
|
14
|
+
issues: ManifestValidationIssue[];
|
|
15
|
+
};
|
|
16
|
+
export interface ManifestValidationOptions {
|
|
17
|
+
/** Allow HTTP only for localhost/loopback developer web manifests. */
|
|
18
|
+
allowLocal?: boolean;
|
|
19
|
+
/** Maximum UTF-8 size of the complete declaration. */
|
|
20
|
+
maxBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
interface ValidatedManifestFields {
|
|
23
|
+
requirements: ApplicationRequirements;
|
|
24
|
+
provisions: ApplicationProvisions;
|
|
25
|
+
notifications: ApplicationNotifications;
|
|
26
|
+
}
|
|
27
|
+
export type ValidatedWebAppManifest = Omit<MdbaseWebAppManifest, keyof ValidatedManifestFields> & ValidatedManifestFields;
|
|
28
|
+
export type ValidatedPortableAppManifest = Omit<MdbasePortableAppManifest, keyof ValidatedManifestFields> & ValidatedManifestFields;
|
|
29
|
+
export type ValidatedAppManifest = ValidatedWebAppManifest | ValidatedPortableAppManifest;
|
|
30
|
+
export declare class AppManifestValidationError extends Error {
|
|
31
|
+
readonly issues: ManifestValidationIssue[];
|
|
32
|
+
constructor(issues: ManifestValidationIssue[]);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate the complete bundled application declaration accepted by Connect.
|
|
36
|
+
*
|
|
37
|
+
* This is the canonical runtime validator used by the server and developer
|
|
38
|
+
* tooling. Keep structural rules in the published JSON Schema and cross-field
|
|
39
|
+
* rules here; consumers must not maintain parallel manifest validators.
|
|
40
|
+
*/
|
|
41
|
+
export declare function validateAppManifest(value: unknown, options?: ManifestValidationOptions): ManifestValidationResult;
|
|
42
|
+
/** Validate, normalize optional sections, and return an isolated declaration. */
|
|
43
|
+
export declare function parseAppManifest(value: unknown, options?: ManifestValidationOptions): ValidatedAppManifest;
|
|
44
|
+
export declare function formatManifestValidationIssues(issues: readonly ManifestValidationIssue[]): string;
|
|
45
|
+
export {};
|