@mdbase-dev/connect-protocol 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/dist/application-authorization.d.ts +4 -1
- package/dist/application-authorization.js +23 -5
- package/dist/capabilities.d.ts +1 -0
- package/dist/capabilities.js +1 -0
- package/dist/collection-setup.d.ts +83 -0
- package/dist/collection-setup.js +1 -0
- package/dist/compatibility.d.ts +26 -0
- package/dist/compatibility.js +35 -0
- package/dist/connect-problems.generated.d.ts +151 -2
- package/dist/connect-problems.generated.js +161 -0
- package/dist/files.d.ts +2 -0
- package/dist/index.d.ts +33 -14
- package/dist/index.js +16 -4
- package/dist/manifest.js +118 -5
- package/dist/mutation-fingerprint.d.ts +6 -0
- package/dist/mutation-fingerprint.js +116 -0
- package/dist/operations.d.ts +11 -6
- package/dist/operations.js +147 -5
- package/package.json +2 -2
- package/schemas/catalog.json +2 -1
- package/schemas/connect-problem.v1.schema.json +634 -32
- package/schemas/connect-problems.v1.catalog.json +78 -1
- package/schemas/connect-protocol.v1.schema.json +104 -14
- package/schemas/encrypted-relay.v1.schema.json +1 -1
- package/schemas/encrypted-relay.v2.schema.json +63 -0
- package/schemas/files.v1.schema.json +7 -2
- package/schemas/mdbase-app.schema.json +51 -0
- package/schemas/mdbase-query.v0.3.schema.json +171 -0
- package/schemas/operation-catalog.v1.json +42 -0
|
@@ -6,11 +6,13 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
6
6
|
"application_identity_unavailable": { category: "compatibility", recovery: "upgrade_application" },
|
|
7
7
|
"approval_window_blocked": { category: "authorization", recovery: "reauthorize" },
|
|
8
8
|
"authority_authorization_changed": { category: "authorization", recovery: "reauthorize" },
|
|
9
|
+
"authorization_binding_incompatible": { category: "compatibility", recovery: "upgrade_application" },
|
|
9
10
|
"authorization_cancelled": { category: "cancellation", recovery: "none" },
|
|
10
11
|
"authorization_expired": { category: "authorization", recovery: "reauthorize" },
|
|
11
12
|
"authorization_replayed": { category: "integrity", recovery: "reauthorize" },
|
|
12
13
|
"browser_required": { category: "compatibility", recovery: "none" },
|
|
13
14
|
"callback_url_required": { category: "validation", recovery: "fix_request" },
|
|
15
|
+
"capability_contract_incompatible": { category: "compatibility", recovery: "upgrade_application" },
|
|
14
16
|
"change_cursor_reset": { category: "conflict", recovery: "refresh" },
|
|
15
17
|
"collection_access_denied": { category: "authorization", recovery: "reauthorize" },
|
|
16
18
|
"collection_configuration_invalid": { category: "validation", recovery: "repair_collection" },
|
|
@@ -31,6 +33,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
31
33
|
"device_authorization_failed": { category: "authorization", recovery: "reauthorize" },
|
|
32
34
|
"direct_operation_rejected": { category: "authorization", recovery: "reauthorize" },
|
|
33
35
|
"discovery_failed": { category: "availability", recovery: "retry" },
|
|
36
|
+
"durable_mutation_unsupported": { category: "compatibility", recovery: "upgrade_connector" },
|
|
34
37
|
"encrypted_relay_rejected": { category: "authorization", recovery: "reauthorize" },
|
|
35
38
|
"encryption_required": { category: "authorization", recovery: "reauthorize" },
|
|
36
39
|
"expired_token": { category: "authorization", recovery: "reauthorize" },
|
|
@@ -61,6 +64,8 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
61
64
|
"manifest_load_failed": { category: "availability", recovery: "retry" },
|
|
62
65
|
"manifest_required": { category: "validation", recovery: "fix_request" },
|
|
63
66
|
"missing_grant_key": { category: "authorization", recovery: "reauthorize" },
|
|
67
|
+
"mutation_recovery_expired": { category: "compatibility", recovery: "none" },
|
|
68
|
+
"mutation_request_conflict": { category: "conflict", recovery: "resolve_conflict" },
|
|
64
69
|
"no_pending_mutation": { category: "conflict", recovery: "refresh" },
|
|
65
70
|
"not_authorized": { category: "authorization", recovery: "reauthorize" },
|
|
66
71
|
"not_remote_authority": { category: "compatibility", recovery: "choose_collection" },
|
|
@@ -81,6 +86,11 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
81
86
|
"reconnect_required": { category: "authorization", recovery: "reauthorize" },
|
|
82
87
|
"redirect_uri_required": { category: "validation", recovery: "fix_request" },
|
|
83
88
|
"reference_updates_unsupported": { category: "compatibility", recovery: "fix_request" },
|
|
89
|
+
"registry_backup_invalid": { category: "integrity", recovery: "contact_support" },
|
|
90
|
+
"registry_busy": { category: "availability", recovery: "retry" },
|
|
91
|
+
"registry_corrupt": { category: "integrity", recovery: "repair_collection" },
|
|
92
|
+
"registry_migration_failed": { category: "internal", recovery: "contact_support" },
|
|
93
|
+
"registry_schema_incompatible": { category: "compatibility", recovery: "upgrade_connector" },
|
|
84
94
|
"relay_authorization_expired": { category: "authorization", recovery: "reauthorize" },
|
|
85
95
|
"relay_unavailable": { category: "availability", recovery: "retry" },
|
|
86
96
|
"sandbox_unsupported": { category: "compatibility", recovery: "fix_request" },
|
|
@@ -91,6 +101,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
91
101
|
"temporarily_unavailable": { category: "availability", recovery: "retry" },
|
|
92
102
|
"timeout": { category: "availability", recovery: "retry" },
|
|
93
103
|
"token_exchange_failed": { category: "availability", recovery: "retry" },
|
|
104
|
+
"transport_protocol_incompatible": { category: "compatibility", recovery: "upgrade_connector" },
|
|
94
105
|
"type_pack_provision_failed": { category: "validation", recovery: "repair_collection" },
|
|
95
106
|
"unknown_collection": { category: "selection", recovery: "choose_collection" },
|
|
96
107
|
"unsafe_file_path": { category: "validation", recovery: "fix_request" },
|
|
@@ -134,6 +145,70 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
134
145
|
}
|
|
135
146
|
}
|
|
136
147
|
},
|
|
148
|
+
"authorization_binding_incompatible": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"required": [
|
|
151
|
+
"contract",
|
|
152
|
+
"required",
|
|
153
|
+
"supported",
|
|
154
|
+
"peer"
|
|
155
|
+
],
|
|
156
|
+
"properties": {
|
|
157
|
+
"contract": {
|
|
158
|
+
"type": "string"
|
|
159
|
+
},
|
|
160
|
+
"required": {
|
|
161
|
+
"type": "array",
|
|
162
|
+
"items": {
|
|
163
|
+
"type": "integer"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"supported": {
|
|
167
|
+
"type": "array",
|
|
168
|
+
"items": {
|
|
169
|
+
"type": "integer"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"peer": {
|
|
173
|
+
"type": "string"
|
|
174
|
+
},
|
|
175
|
+
"operation": {
|
|
176
|
+
"type": "string"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
"capability_contract_incompatible": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"required": [
|
|
183
|
+
"contract",
|
|
184
|
+
"required",
|
|
185
|
+
"supported",
|
|
186
|
+
"peer"
|
|
187
|
+
],
|
|
188
|
+
"properties": {
|
|
189
|
+
"contract": {
|
|
190
|
+
"type": "string"
|
|
191
|
+
},
|
|
192
|
+
"required": {
|
|
193
|
+
"type": "array",
|
|
194
|
+
"items": {
|
|
195
|
+
"type": "integer"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"supported": {
|
|
199
|
+
"type": "array",
|
|
200
|
+
"items": {
|
|
201
|
+
"type": "integer"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"peer": {
|
|
205
|
+
"type": "string"
|
|
206
|
+
},
|
|
207
|
+
"operation": {
|
|
208
|
+
"type": "string"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
},
|
|
137
212
|
"collection_configuration_invalid": {
|
|
138
213
|
"type": "object",
|
|
139
214
|
"required": [
|
|
@@ -226,6 +301,38 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
226
301
|
}
|
|
227
302
|
}
|
|
228
303
|
},
|
|
304
|
+
"durable_mutation_unsupported": {
|
|
305
|
+
"type": "object",
|
|
306
|
+
"required": [
|
|
307
|
+
"contract",
|
|
308
|
+
"required",
|
|
309
|
+
"supported",
|
|
310
|
+
"peer"
|
|
311
|
+
],
|
|
312
|
+
"properties": {
|
|
313
|
+
"contract": {
|
|
314
|
+
"type": "string"
|
|
315
|
+
},
|
|
316
|
+
"required": {
|
|
317
|
+
"type": "array",
|
|
318
|
+
"items": {
|
|
319
|
+
"type": "integer"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"supported": {
|
|
323
|
+
"type": "array",
|
|
324
|
+
"items": {
|
|
325
|
+
"type": "integer"
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"peer": {
|
|
329
|
+
"type": "string"
|
|
330
|
+
},
|
|
331
|
+
"operation": {
|
|
332
|
+
"type": "string"
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
},
|
|
229
336
|
"insufficient_access": {
|
|
230
337
|
"type": "object",
|
|
231
338
|
"required": [
|
|
@@ -288,6 +395,17 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
288
395
|
}
|
|
289
396
|
}
|
|
290
397
|
},
|
|
398
|
+
"mutation_request_conflict": {
|
|
399
|
+
"type": "object",
|
|
400
|
+
"required": [
|
|
401
|
+
"request_id"
|
|
402
|
+
],
|
|
403
|
+
"properties": {
|
|
404
|
+
"request_id": {
|
|
405
|
+
"type": "string"
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
},
|
|
291
409
|
"operation_invalid": {
|
|
292
410
|
"type": "object",
|
|
293
411
|
"required": [
|
|
@@ -303,6 +421,17 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
303
421
|
"partial_result": {}
|
|
304
422
|
}
|
|
305
423
|
},
|
|
424
|
+
"operation_outcome_unknown": {
|
|
425
|
+
"type": "object",
|
|
426
|
+
"required": [
|
|
427
|
+
"request_id"
|
|
428
|
+
],
|
|
429
|
+
"properties": {
|
|
430
|
+
"request_id": {
|
|
431
|
+
"type": "string"
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
},
|
|
306
435
|
"rate_limited": {
|
|
307
436
|
"type": "object",
|
|
308
437
|
"required": [],
|
|
@@ -311,6 +440,38 @@ const CONNECT_PROBLEM_DETAIL_SCHEMAS = {
|
|
|
311
440
|
"type": "integer"
|
|
312
441
|
}
|
|
313
442
|
}
|
|
443
|
+
},
|
|
444
|
+
"transport_protocol_incompatible": {
|
|
445
|
+
"type": "object",
|
|
446
|
+
"required": [
|
|
447
|
+
"contract",
|
|
448
|
+
"required",
|
|
449
|
+
"supported",
|
|
450
|
+
"peer"
|
|
451
|
+
],
|
|
452
|
+
"properties": {
|
|
453
|
+
"contract": {
|
|
454
|
+
"type": "string"
|
|
455
|
+
},
|
|
456
|
+
"required": {
|
|
457
|
+
"type": "array",
|
|
458
|
+
"items": {
|
|
459
|
+
"type": "integer"
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
"supported": {
|
|
463
|
+
"type": "array",
|
|
464
|
+
"items": {
|
|
465
|
+
"type": "integer"
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
"peer": {
|
|
469
|
+
"type": "string"
|
|
470
|
+
},
|
|
471
|
+
"operation": {
|
|
472
|
+
"type": "string"
|
|
473
|
+
}
|
|
474
|
+
}
|
|
314
475
|
}
|
|
315
476
|
};
|
|
316
477
|
export function isConnectProblemCode(code) {
|
package/dist/files.d.ts
CHANGED
|
@@ -152,6 +152,8 @@ export interface FileTransferStatus {
|
|
|
152
152
|
state: FileTransferState;
|
|
153
153
|
received: number[];
|
|
154
154
|
received_bytes: number;
|
|
155
|
+
/** Object-store receipts for the currently durable multipart parts. */
|
|
156
|
+
uploaded_parts: UploadedFilePart[];
|
|
155
157
|
}
|
|
156
158
|
export interface PrepareFileUploadPartRequest {
|
|
157
159
|
protocol_version: 1;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,24 +3,31 @@ import type { ApplicationFileRequirement, CollectionFileDescriptor, FileCapabili
|
|
|
3
3
|
import type { CollectionOperation } from "./operations.js";
|
|
4
4
|
import type { ApplicationCapabilityRequirements } from "./capabilities.js";
|
|
5
5
|
import type { ContractRequirement, ContractSetupChoice, TypePackProvision } from "./type-packs.js";
|
|
6
|
+
import type { ConfigurationProvision, ConfigurationRequirement } from "./collection-setup.js";
|
|
6
7
|
import type { ApplicationAuthorizationProof } from "./application-authorization.js";
|
|
7
8
|
export * from "./connect-problems.generated.js";
|
|
8
9
|
export * from "./files.js";
|
|
9
10
|
export * from "./operations.js";
|
|
11
|
+
export * from "./mutation-fingerprint.js";
|
|
12
|
+
export * from "./compatibility.js";
|
|
10
13
|
export * from "./capabilities.js";
|
|
11
14
|
export * from "./application-authorization.js";
|
|
12
15
|
export * from "./type-packs.js";
|
|
16
|
+
export * from "./collection-setup.js";
|
|
13
17
|
export declare const CONTROL_PROTOCOL_VERSION: 1;
|
|
14
|
-
export
|
|
15
|
-
export declare const APPLICATION_AUTHORIZATION_PROTOCOL_VERSION: 2;
|
|
18
|
+
export { AUTHORIZATION_BINDING_PROTOCOL_VERSION as APPLICATION_AUTHORIZATION_PROTOCOL_VERSION } from "./compatibility.js";
|
|
16
19
|
export declare const LOOPBACK_PROTOCOL_VERSION: 1;
|
|
17
20
|
export declare const DEFAULT_LOOPBACK_PORT: 28485;
|
|
18
21
|
export declare const RELAY_ENCRYPTION_SUITE: "P256-HKDF-SHA256-AES256GCM";
|
|
22
|
+
export declare const GRANT_ENCRYPTION_PROTOCOL_VERSION: 1;
|
|
19
23
|
export declare const SYNC_PROTOCOL_VERSION: 1;
|
|
20
24
|
export declare const CONTRACT_SETUP_CAPABILITY: "contract-setup-v1";
|
|
21
25
|
export declare const FILE_RELAY_CAPABILITY: "file-relay-v1";
|
|
22
|
-
export declare const RELAY_REQUIRED_CAPABILITIES: readonly ["application-authorization-
|
|
23
|
-
export declare const
|
|
26
|
+
export declare const RELAY_REQUIRED_CAPABILITIES: readonly ["application-authorization-v4", "authorization-activation", "encrypted-relay", "policy-ack"];
|
|
27
|
+
export declare const MINIMUM_CONNECTOR_VERSION: "0.1.0-beta.33";
|
|
28
|
+
export declare const HOSTED_PROVIDER_REQUIRED_CAPABILITIES: readonly ["durable-mutation-journal-v1", "durable-file-lifecycle-v1"];
|
|
29
|
+
export declare const HOSTED_PROVIDER_CAPABILITIES: readonly ["durable-mutation-journal-v1", "durable-file-lifecycle-v1", "mutation-replay-after-credential-retirement-v1"];
|
|
30
|
+
export declare const RELAY_CAPABILITIES: readonly ["application-authorization-v4", "authorization-activation", "encrypted-relay", "policy-ack", "contract-setup-v1", "file-relay-v1"];
|
|
24
31
|
export declare const AUTHORITY_PROOF_VERSION: 1;
|
|
25
32
|
export declare const AUTHORITY_PROOF_ALGORITHM: "P256-SHA256";
|
|
26
33
|
export declare const AUTHORITY_PROOF_DOMAIN: "mdbase-authority-request-proof-v1";
|
|
@@ -42,7 +49,7 @@ export declare const CONNECT_SCHEMA_IDS: {
|
|
|
42
49
|
readonly dataContract: "https://mdbase.dev/schemas/v0.3/data-contract.schema.json";
|
|
43
50
|
readonly eventActionInterop: "https://mdbase.dev/schemas/interop/v0.1/profile.schema.json";
|
|
44
51
|
readonly protocol: "https://mdbase.dev/connect/schemas/connect-protocol.v1.json";
|
|
45
|
-
readonly encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.
|
|
52
|
+
readonly encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.v2.json";
|
|
46
53
|
readonly files: "https://mdbase.dev/connect/schemas/files.v1.json";
|
|
47
54
|
readonly sync: "https://mdbase.dev/connect/schemas/sync.v1.json";
|
|
48
55
|
};
|
|
@@ -148,6 +155,8 @@ export interface NotificationWebhook {
|
|
|
148
155
|
}
|
|
149
156
|
export interface ApplicationRequirements {
|
|
150
157
|
contracts: ContractRequirement[];
|
|
158
|
+
/** Collection extension values required before the application is ready. */
|
|
159
|
+
configuration?: ConfigurationRequirement[];
|
|
151
160
|
/** Versioned semantic intent compiled by Connect into exact operations. */
|
|
152
161
|
capabilities?: ApplicationCapabilityRequirements;
|
|
153
162
|
/** Access boundary requested after compatibility and provisioning checks. */
|
|
@@ -159,6 +168,8 @@ export interface ApplicationRequirements {
|
|
|
159
168
|
}
|
|
160
169
|
export interface ApplicationProvisions {
|
|
161
170
|
type_packs: TypePackProvision[];
|
|
171
|
+
/** Narrow semantic changes that may satisfy configuration requirements. */
|
|
172
|
+
configuration?: ConfigurationProvision[];
|
|
162
173
|
}
|
|
163
174
|
export interface GrantScope {
|
|
164
175
|
/**
|
|
@@ -171,7 +182,7 @@ export interface GrantScope {
|
|
|
171
182
|
}
|
|
172
183
|
export interface RelayOperationRequest {
|
|
173
184
|
type: "operation_request";
|
|
174
|
-
protocol_version:
|
|
185
|
+
protocol_version: 2;
|
|
175
186
|
request_id: string;
|
|
176
187
|
grant_id: string;
|
|
177
188
|
collection_id: string;
|
|
@@ -181,29 +192,29 @@ export interface RelayOperationRequest {
|
|
|
181
192
|
}
|
|
182
193
|
export type RelayOperationResponse = {
|
|
183
194
|
type: "operation_response";
|
|
184
|
-
protocol_version:
|
|
195
|
+
protocol_version: 2;
|
|
185
196
|
request_id: string;
|
|
186
197
|
ok: true;
|
|
187
198
|
result: unknown;
|
|
188
199
|
} | {
|
|
189
200
|
type: "operation_response";
|
|
190
|
-
protocol_version:
|
|
201
|
+
protocol_version: 2;
|
|
191
202
|
request_id: string;
|
|
192
203
|
ok: false;
|
|
193
204
|
problem: ConnectProblem;
|
|
194
205
|
};
|
|
195
206
|
export interface MdbaseOperationRequest<Input = unknown> {
|
|
196
|
-
protocol_version:
|
|
207
|
+
protocol_version: 2;
|
|
197
208
|
request_id: string;
|
|
198
209
|
input: Input;
|
|
199
210
|
}
|
|
200
211
|
export type MdbaseOperationResponse<Result = unknown> = {
|
|
201
|
-
protocol_version:
|
|
212
|
+
protocol_version: 2;
|
|
202
213
|
request_id: string;
|
|
203
214
|
ok: true;
|
|
204
215
|
result: Result;
|
|
205
216
|
} | {
|
|
206
|
-
protocol_version:
|
|
217
|
+
protocol_version: 2;
|
|
207
218
|
request_id: string;
|
|
208
219
|
ok: false;
|
|
209
220
|
problem: ConnectProblem;
|
|
@@ -232,7 +243,9 @@ export interface GrantPolicy {
|
|
|
232
243
|
application_authorization: ApplicationAuthorizationProof;
|
|
233
244
|
}
|
|
234
245
|
/** Presentation-only grant shape used outside a local authorization boundary. */
|
|
235
|
-
export type GrantSummary = Omit<GrantPolicy, "application_authorization"
|
|
246
|
+
export type GrantSummary = Omit<GrantPolicy, "application_authorization"> & {
|
|
247
|
+
contracts: import("./compatibility.js").ConnectContractRequirements;
|
|
248
|
+
};
|
|
236
249
|
export interface GrantEncryption {
|
|
237
250
|
protocol_version: 1;
|
|
238
251
|
suite: typeof RELAY_ENCRYPTION_SUITE;
|
|
@@ -244,7 +257,7 @@ export interface GrantEncryption {
|
|
|
244
257
|
connector_agreement_public_key: string;
|
|
245
258
|
}
|
|
246
259
|
export interface EncryptedRelayEnvelope {
|
|
247
|
-
protocol_version:
|
|
260
|
+
protocol_version: 2;
|
|
248
261
|
suite: typeof RELAY_ENCRYPTION_SUITE;
|
|
249
262
|
request_id: string;
|
|
250
263
|
grant_id: string;
|
|
@@ -490,18 +503,22 @@ export interface RelayHello {
|
|
|
490
503
|
protocol_version: 1;
|
|
491
504
|
connector_version: string;
|
|
492
505
|
capabilities: string[];
|
|
506
|
+
contract_support: import("./compatibility.js").ConnectContractSupport;
|
|
493
507
|
}
|
|
494
508
|
export interface RelayWelcome {
|
|
495
509
|
type: "relay_welcome";
|
|
496
510
|
protocol_version: 1;
|
|
497
511
|
session_id: string;
|
|
498
512
|
capabilities: string[];
|
|
513
|
+
contract_support: import("./compatibility.js").ConnectContractSupport;
|
|
499
514
|
}
|
|
500
515
|
export interface RelayIncompatible {
|
|
501
516
|
type: "relay_incompatible";
|
|
502
517
|
protocol_version: 1;
|
|
503
|
-
code: "connector_upgrade_required";
|
|
518
|
+
code: "connector_upgrade_required" | "transport_protocol_incompatible" | "authorization_binding_incompatible" | "capability_contract_incompatible" | "durable_mutation_unsupported";
|
|
504
519
|
message: string;
|
|
520
|
+
details?: import("./connect-problems.generated.js").ConnectProblemDetailsByCode["transport_protocol_incompatible" | "authorization_binding_incompatible" | "capability_contract_incompatible" | "durable_mutation_unsupported"];
|
|
521
|
+
minimum_connector_version: string;
|
|
505
522
|
update_url: string;
|
|
506
523
|
}
|
|
507
524
|
export interface RelayPolicyApplied {
|
|
@@ -539,6 +556,8 @@ export interface AuthorizationActivationResponse {
|
|
|
539
556
|
contracts: CollectionContractDescriptor[];
|
|
540
557
|
/** Exact setup plan applied by the authority. */
|
|
541
558
|
contract_setups: ContractSetupChoice[];
|
|
559
|
+
setup_assessment?: unknown;
|
|
560
|
+
provision_receipt?: unknown;
|
|
542
561
|
error?: {
|
|
543
562
|
code: string;
|
|
544
563
|
message: string;
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
export * from "./connect-problems.generated.js";
|
|
2
2
|
export * from "./files.js";
|
|
3
3
|
export * from "./operations.js";
|
|
4
|
+
export * from "./mutation-fingerprint.js";
|
|
5
|
+
export * from "./compatibility.js";
|
|
4
6
|
export * from "./capabilities.js";
|
|
5
7
|
export * from "./application-authorization.js";
|
|
6
8
|
export * from "./type-packs.js";
|
|
9
|
+
export * from "./collection-setup.js";
|
|
7
10
|
export const CONTROL_PROTOCOL_VERSION = 1;
|
|
8
|
-
export
|
|
9
|
-
export const APPLICATION_AUTHORIZATION_PROTOCOL_VERSION = 2;
|
|
11
|
+
export { AUTHORIZATION_BINDING_PROTOCOL_VERSION as APPLICATION_AUTHORIZATION_PROTOCOL_VERSION } from "./compatibility.js";
|
|
10
12
|
export const LOOPBACK_PROTOCOL_VERSION = 1;
|
|
11
13
|
export const DEFAULT_LOOPBACK_PORT = 28_485;
|
|
12
14
|
export const RELAY_ENCRYPTION_SUITE = "P256-HKDF-SHA256-AES256GCM";
|
|
15
|
+
export const GRANT_ENCRYPTION_PROTOCOL_VERSION = 1;
|
|
13
16
|
export const SYNC_PROTOCOL_VERSION = 1;
|
|
14
17
|
export const CONTRACT_SETUP_CAPABILITY = "contract-setup-v1";
|
|
15
18
|
export const FILE_RELAY_CAPABILITY = "file-relay-v1";
|
|
16
19
|
export const RELAY_REQUIRED_CAPABILITIES = [
|
|
17
|
-
"application-authorization-
|
|
20
|
+
"application-authorization-v4",
|
|
18
21
|
"authorization-activation",
|
|
19
22
|
"encrypted-relay",
|
|
20
23
|
"policy-ack"
|
|
21
24
|
];
|
|
25
|
+
export const MINIMUM_CONNECTOR_VERSION = "0.1.0-beta.33";
|
|
26
|
+
export const HOSTED_PROVIDER_REQUIRED_CAPABILITIES = [
|
|
27
|
+
"durable-mutation-journal-v1",
|
|
28
|
+
"durable-file-lifecycle-v1"
|
|
29
|
+
];
|
|
30
|
+
export const HOSTED_PROVIDER_CAPABILITIES = [
|
|
31
|
+
...HOSTED_PROVIDER_REQUIRED_CAPABILITIES,
|
|
32
|
+
"mutation-replay-after-credential-retirement-v1"
|
|
33
|
+
];
|
|
22
34
|
export const RELAY_CAPABILITIES = [
|
|
23
35
|
...RELAY_REQUIRED_CAPABILITIES,
|
|
24
36
|
CONTRACT_SETUP_CAPABILITY,
|
|
@@ -62,7 +74,7 @@ export const CONNECT_SCHEMA_IDS = {
|
|
|
62
74
|
dataContract: "https://mdbase.dev/schemas/v0.3/data-contract.schema.json",
|
|
63
75
|
eventActionInterop: "https://mdbase.dev/schemas/interop/v0.1/profile.schema.json",
|
|
64
76
|
protocol: "https://mdbase.dev/connect/schemas/connect-protocol.v1.json",
|
|
65
|
-
encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.
|
|
77
|
+
encryptedRelay: "https://mdbase.dev/connect/schemas/encrypted-relay.v2.json",
|
|
66
78
|
files: "https://mdbase.dev/connect/schemas/files.v1.json",
|
|
67
79
|
sync: "https://mdbase.dev/connect/schemas/sync.v1.json"
|
|
68
80
|
};
|
package/dist/manifest.js
CHANGED
|
@@ -40,7 +40,8 @@ export function validateAppManifest(value, options = {}) {
|
|
|
40
40
|
const issues = [
|
|
41
41
|
...validateManifestOrigins(value, options.allowLocal === true),
|
|
42
42
|
...validateCapabilityRequirements(value),
|
|
43
|
-
...validateProvisionRequirements(value)
|
|
43
|
+
...validateProvisionRequirements(value),
|
|
44
|
+
...validateConfigurationSetup(value)
|
|
44
45
|
];
|
|
45
46
|
return issues.length === 0 ? { valid: true, issues: [] } : invalid(issues);
|
|
46
47
|
}
|
|
@@ -52,8 +53,16 @@ export function parseAppManifest(value, options = {}) {
|
|
|
52
53
|
const manifest = structuredClone(value);
|
|
53
54
|
return {
|
|
54
55
|
...manifest,
|
|
55
|
-
requirements:
|
|
56
|
-
|
|
56
|
+
requirements: {
|
|
57
|
+
contracts: [],
|
|
58
|
+
configuration: [],
|
|
59
|
+
...manifest.requirements
|
|
60
|
+
},
|
|
61
|
+
provisions: {
|
|
62
|
+
type_packs: [],
|
|
63
|
+
configuration: [],
|
|
64
|
+
...manifest.provisions
|
|
65
|
+
},
|
|
57
66
|
notifications: manifest.notifications ?? { criteria: [] }
|
|
58
67
|
};
|
|
59
68
|
}
|
|
@@ -253,6 +262,95 @@ function validateProvisionRequirements(value) {
|
|
|
253
262
|
}
|
|
254
263
|
return issues;
|
|
255
264
|
}
|
|
265
|
+
function validateConfigurationSetup(value) {
|
|
266
|
+
const manifest = asObject(value);
|
|
267
|
+
const requirements = asObject(manifest.requirements);
|
|
268
|
+
const provisions = asObject(manifest.provisions);
|
|
269
|
+
const requiredValues = Array.isArray(requirements.configuration)
|
|
270
|
+
? requirements.configuration
|
|
271
|
+
: [];
|
|
272
|
+
const provisionValues = Array.isArray(provisions.configuration)
|
|
273
|
+
? provisions.configuration
|
|
274
|
+
: [];
|
|
275
|
+
const issues = [];
|
|
276
|
+
const required = new Map();
|
|
277
|
+
for (const [index, candidate] of requiredValues.entries()) {
|
|
278
|
+
const requirement = asObject(candidate);
|
|
279
|
+
const id = String(requirement.id);
|
|
280
|
+
const path = String(requirement.path);
|
|
281
|
+
const pathError = configurationPointerError(path);
|
|
282
|
+
if (pathError) {
|
|
283
|
+
issues.push(issue(`/requirements/configuration/${index}/path`, "configurationPointer", pathError));
|
|
284
|
+
}
|
|
285
|
+
if (required.has(id)) {
|
|
286
|
+
issues.push(issue(`/requirements/configuration/${index}/id`, "uniqueRequirement", `duplicates configuration requirement ${id}`));
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
required.set(id, { path, value: requirement.value, index });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const linked = new Set();
|
|
293
|
+
const contributionKeys = new Set();
|
|
294
|
+
for (const [index, candidate] of provisionValues.entries()) {
|
|
295
|
+
const provision = asObject(candidate);
|
|
296
|
+
const requirementId = String(provision.requirement);
|
|
297
|
+
const path = String(provision.path);
|
|
298
|
+
const pathError = configurationPointerError(path);
|
|
299
|
+
if (pathError) {
|
|
300
|
+
issues.push(issue(`/provisions/configuration/${index}/path`, "configurationPointer", pathError));
|
|
301
|
+
}
|
|
302
|
+
const requirement = required.get(requirementId);
|
|
303
|
+
if (!requirement) {
|
|
304
|
+
issues.push(issue(`/provisions/configuration/${index}/requirement`, "configurationRequirement", `references unknown configuration requirement ${requirementId}`));
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (linked.has(requirementId)) {
|
|
308
|
+
issues.push(issue(`/provisions/configuration/${index}/requirement`, "uniqueProvision", `configuration requirement ${requirementId} may have exactly one provision`));
|
|
309
|
+
}
|
|
310
|
+
linked.add(requirementId);
|
|
311
|
+
if (path !== requirement.path) {
|
|
312
|
+
issues.push(issue(`/provisions/configuration/${index}/path`, "configurationRequirement", `must equal /requirements/configuration/${requirement.index}/path`));
|
|
313
|
+
}
|
|
314
|
+
if (JSON.stringify(provision.value) !== JSON.stringify(requirement.value)) {
|
|
315
|
+
issues.push(issue(`/provisions/configuration/${index}/value`, "configurationRequirement", `must equal /requirements/configuration/${requirement.index}/value`));
|
|
316
|
+
}
|
|
317
|
+
const contributionKey = `${path}\0${JSON.stringify(provision.value)}`;
|
|
318
|
+
if (contributionKeys.has(contributionKey)) {
|
|
319
|
+
issues.push(issue(`/provisions/configuration/${index}`, "uniqueContribution", "duplicates another configuration path and value contribution"));
|
|
320
|
+
}
|
|
321
|
+
contributionKeys.add(contributionKey);
|
|
322
|
+
}
|
|
323
|
+
for (const [id, requirement] of required) {
|
|
324
|
+
if (!linked.has(id)) {
|
|
325
|
+
issues.push(issue(`/requirements/configuration/${requirement.index}`, "configurationProvision", `requires one provision linked by id ${id}`));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return issues;
|
|
329
|
+
}
|
|
330
|
+
function configurationPointerError(path) {
|
|
331
|
+
if (!path.startsWith("/") || new TextEncoder().encode(path).byteLength > 1024) {
|
|
332
|
+
return "must be a bounded RFC 6901 JSON pointer";
|
|
333
|
+
}
|
|
334
|
+
const encoded = path.slice(1).split("/");
|
|
335
|
+
if (encoded.length < 2 || encoded.length > 16) {
|
|
336
|
+
return "must address a value below an x-* extension namespace";
|
|
337
|
+
}
|
|
338
|
+
const segments = [];
|
|
339
|
+
for (const value of encoded) {
|
|
340
|
+
if (/~(?:[^01]|$)/u.test(value))
|
|
341
|
+
return "contains an invalid RFC 6901 escape";
|
|
342
|
+
const segment = value.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
343
|
+
if (segment.length === 0
|
|
344
|
+
|| segment === "-"
|
|
345
|
+
|| /^\d+$/u.test(segment)
|
|
346
|
+
|| [...segment].some((character) => /\p{Cc}/u.test(character)))
|
|
347
|
+
return "contains a disallowed object-key segment";
|
|
348
|
+
segments.push(segment);
|
|
349
|
+
}
|
|
350
|
+
return /^x-[a-z0-9][a-z0-9-]*$/u.test(segments[0])
|
|
351
|
+
? undefined
|
|
352
|
+
: "must be inside a top-level x-* extension namespace";
|
|
353
|
+
}
|
|
256
354
|
function validateCapabilityRequirements(value) {
|
|
257
355
|
const manifest = asObject(value);
|
|
258
356
|
const requirements = asObject(manifest.requirements);
|
|
@@ -285,8 +383,23 @@ function validateCapabilityRequirements(value) {
|
|
|
285
383
|
}
|
|
286
384
|
if (Array.isArray(provisions.type_packs)
|
|
287
385
|
&& provisions.type_packs.length > 0
|
|
288
|
-
&& !required.includes("
|
|
289
|
-
issues.push(issue("/requirements/capabilities/required", "
|
|
386
|
+
&& !required.includes("collection.setup.apply")) {
|
|
387
|
+
issues.push(issue("/requirements/capabilities/required", "collectionSetupCapability", "must require collection.setup.apply when bundled type packs are declared"));
|
|
388
|
+
}
|
|
389
|
+
const hasConfigurationProvisions = Array.isArray(provisions.configuration)
|
|
390
|
+
&& provisions.configuration.length > 0;
|
|
391
|
+
const hasSetupProvisions = hasConfigurationProvisions
|
|
392
|
+
|| (Array.isArray(provisions.type_packs) && provisions.type_packs.length > 0);
|
|
393
|
+
if (hasConfigurationProvisions && !required.includes("collection.setup.apply")) {
|
|
394
|
+
issues.push(issue("/requirements/capabilities/required", "collectionSetupCapability", "must require collection.setup.apply when configuration provisions are declared"));
|
|
395
|
+
}
|
|
396
|
+
if (declared.has("collection.setup.apply")) {
|
|
397
|
+
if (requirements.access !== "full_collection") {
|
|
398
|
+
issues.push(issue("/requirements/access", "collectionSetupAccess", "must be full_collection for collection.setup.apply"));
|
|
399
|
+
}
|
|
400
|
+
if (!hasSetupProvisions) {
|
|
401
|
+
issues.push(issue("/provisions", "collectionSetupProvision", "must declare a configuration provision or type pack for collection.setup.apply"));
|
|
402
|
+
}
|
|
290
403
|
}
|
|
291
404
|
if (declared.has("notifications.background-delivery")
|
|
292
405
|
&& !Array.isArray(asObject(manifest.notifications).criteria)) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type EncryptedOperation } from "./operations.js";
|
|
2
|
+
export declare const MUTATION_FINGERPRINT_SCHEMA_VERSION: 1;
|
|
3
|
+
export declare const MUTATION_FINGERPRINT_DOMAIN: "mdbase-connect mutation fingerprint v1\0";
|
|
4
|
+
export declare function canonicalMutationInput(input: unknown): string;
|
|
5
|
+
export declare function mutationFingerprintTranscript(operation: EncryptedOperation, input: unknown): Uint8Array<ArrayBuffer>;
|
|
6
|
+
export declare function mutationFingerprint(operation: EncryptedOperation, input: unknown): Promise<string>;
|