@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.
Files changed (68) hide show
  1. package/README.md +112 -34
  2. package/dist/advanced.d.ts +9 -0
  3. package/dist/advanced.js +6 -0
  4. package/dist/application-session.d.ts +39 -14
  5. package/dist/application-session.js +201 -70
  6. package/dist/async.js +11 -5
  7. package/dist/authority-proof.d.ts +3 -0
  8. package/dist/authority-proof.js +24 -0
  9. package/dist/browser/integrity.json +1 -1
  10. package/dist/browser/mdbase-connect.min.js +3 -3
  11. package/dist/browser/mdbase-connect.min.js.sha384 +1 -1
  12. package/dist/browser.d.ts +3 -0
  13. package/dist/browser.js +5 -0
  14. package/dist/capabilities.js +2 -1
  15. package/dist/collection-client.d.ts +36 -33
  16. package/dist/collection-client.js +549 -104
  17. package/dist/connect-authorization-helpers.d.ts +3 -0
  18. package/dist/connect-authorization-helpers.js +13 -0
  19. package/dist/connect-options.d.ts +12 -4
  20. package/dist/connect.d.ts +12 -4
  21. package/dist/connect.js +102 -103
  22. package/dist/connection-file-transport.d.ts +2 -2
  23. package/dist/connection-file-transport.js +4 -4
  24. package/dist/connection-notifications.d.ts +10 -4
  25. package/dist/connection-notifications.js +41 -23
  26. package/dist/connection-transport.d.ts +19 -15
  27. package/dist/connection-transport.js +202 -202
  28. package/dist/connection-types.d.ts +5 -4
  29. package/dist/connection.d.ts +47 -46
  30. package/dist/connection.js +320 -162
  31. package/dist/crypto-entry.d.ts +7 -0
  32. package/dist/crypto-entry.js +4 -0
  33. package/dist/crypto.js +4 -4
  34. package/dist/external-store.d.ts +10 -0
  35. package/dist/external-store.js +10 -0
  36. package/dist/file-transfer-internals.d.ts +23 -0
  37. package/dist/file-transfer-internals.js +224 -0
  38. package/dist/files.d.ts +36 -14
  39. package/dist/files.js +92 -222
  40. package/dist/hosted-file-request.js +3 -3
  41. package/dist/index.d.ts +24 -19
  42. package/dist/index.js +10 -18
  43. package/dist/internal-types.d.ts +9 -1
  44. package/dist/local-file-transport.d.ts +2 -2
  45. package/dist/local-file-transport.js +13 -13
  46. package/dist/mdbase-connect.d.ts +6 -4
  47. package/dist/mdbase-connect.js +9 -8
  48. package/dist/notifications.d.ts +3 -2
  49. package/dist/operation-helpers.d.ts +3 -3
  50. package/dist/operation-helpers.js +17 -34
  51. package/dist/operation-types.d.ts +435 -45
  52. package/dist/outcomes.d.ts +15 -15
  53. package/dist/outcomes.js +13 -1
  54. package/dist/pending-mutation-store.d.ts +13 -0
  55. package/dist/pending-mutation-store.js +64 -0
  56. package/dist/request-budget.d.ts +27 -0
  57. package/dist/request-budget.js +95 -0
  58. package/dist/runtime-utils.d.ts +2 -0
  59. package/dist/runtime-utils.js +19 -0
  60. package/dist/session.d.ts +5 -4
  61. package/dist/session.js +6 -5
  62. package/dist/stored-token.d.ts +10 -0
  63. package/dist/stored-token.js +60 -0
  64. package/dist/token-response.d.ts +11 -0
  65. package/dist/token-response.js +77 -0
  66. package/dist/watch-policy.d.ts +8 -0
  67. package/dist/watch-policy.js +12 -0
  68. package/package.json +12 -2
@@ -0,0 +1,77 @@
1
+ import { validateGrantEncryption } from "./crypto.js";
2
+ import { connectError } from "./errors.js";
3
+ import { parseGrantScope, validAuthorityTokenResponse, validFileCapability } from "./runtime-utils.js";
4
+ export function storedTokenFromResponse({ body, clientId, keyHandle, previous, defaultApplicationOrigin, pinConnectorIdentity }) {
5
+ const collectionId = body.collection_id;
6
+ if (typeof collectionId !== "string") {
7
+ throw connectError("invalid_token_response", "Authorization returned no collection ID.");
8
+ }
9
+ const scope = parseGrantScope(body.scope);
10
+ if (!scope) {
11
+ throw connectError("invalid_token_response", "Authorization returned no valid collection scope.");
12
+ }
13
+ if (body.authority && !validAuthorityTokenResponse(body.authority, collectionId)) {
14
+ throw connectError("invalid_token_response", "Authorization returned an invalid remote authority capability.");
15
+ }
16
+ if (body.authority && body.encryption) {
17
+ throw connectError("invalid_token_response", "Authorization returned conflicting collection transports.");
18
+ }
19
+ if (body.file_capability !== null && body.file_capability !== undefined
20
+ && !validFileCapability(body.file_capability)) {
21
+ throw connectError("invalid_token_response", "Authorization returned an invalid file capability.");
22
+ }
23
+ if (body.encryption) {
24
+ try {
25
+ validateGrantEncryption(body.encryption);
26
+ }
27
+ catch {
28
+ throw connectError("invalid_token_response", "Authorization returned an invalid encrypted relay binding.");
29
+ }
30
+ pinConnectorIdentity(body.encryption.connector_id, body.encryption.connector_agreement_public_key);
31
+ if (body.encryption.collection_id !== collectionId
32
+ || typeof body.grant_id !== "string"
33
+ || body.grant_id.length === 0) {
34
+ throw connectError("invalid_token_response", "Authorization returned an encrypted relay binding for another grant.");
35
+ }
36
+ }
37
+ if (previous?.encryption
38
+ && body.encryption
39
+ && previous.keyHandle
40
+ && previous.keyHandle === keyHandle
41
+ && (previous.grantId !== body.grant_id
42
+ || previous.encryption.connector_id !== body.encryption.connector_id
43
+ || previous.encryption.connector_agreement_public_key
44
+ !== body.encryption.connector_agreement_public_key
45
+ || previous.encryption.application_agreement_public_key
46
+ !== body.encryption.application_agreement_public_key)) {
47
+ throw connectError("connector_identity_changed", "The connector identity changed during authorization renewal. Reauthorize before sending collection data.");
48
+ }
49
+ return {
50
+ version: 1,
51
+ accessToken: body.access_token,
52
+ refreshToken: body.refresh_token,
53
+ clientId,
54
+ collectionId,
55
+ collectionName: body.collection_name ?? `Collection ${collectionId.slice(0, 8)}`,
56
+ operations: body.operations,
57
+ scope,
58
+ expiresAt: Date.now() + body.expires_in * 1_000,
59
+ refreshExpiresAt: body.refresh_expires_in
60
+ ? Date.now() + body.refresh_expires_in * 1_000
61
+ : undefined,
62
+ grantId: body.grant_id,
63
+ encryption: body.encryption ?? undefined,
64
+ fileCapability: body.file_capability ?? undefined,
65
+ applicationOrigin: body.application_origin ?? defaultApplicationOrigin,
66
+ keyHandle,
67
+ savedAt: Date.now(),
68
+ authority: body.authority ? {
69
+ operationsUrl: body.authority.operations_url,
70
+ syncUrl: body.authority.sync_url,
71
+ filesUrl: body.authority.files_url,
72
+ replicaId: body.authority.replica_id,
73
+ accessToken: body.authority.access_token,
74
+ proofPublicKey: body.authority.proof_public_key
75
+ } : undefined
76
+ };
77
+ }
@@ -0,0 +1,8 @@
1
+ import type { WatchOptions } from "./operation-types.js";
2
+ export interface ResolvedWatchRetryOptions {
3
+ initialDelayMs: number;
4
+ maxDelayMs: number;
5
+ multiplier: number;
6
+ maxAttempts?: number;
7
+ }
8
+ export declare function watchRetryPolicy(options: WatchOptions["retry"]): ResolvedWatchRetryOptions | undefined;
@@ -0,0 +1,12 @@
1
+ export function watchRetryPolicy(options) {
2
+ if (options === false)
3
+ return undefined;
4
+ return {
5
+ initialDelayMs: Math.max(0, options?.initialDelayMs ?? 500),
6
+ maxDelayMs: Math.max(0, options?.maxDelayMs ?? 15_000),
7
+ multiplier: Math.max(1, options?.multiplier ?? 2),
8
+ ...(options?.maxAttempts === undefined
9
+ ? {}
10
+ : { maxAttempts: Math.max(0, options.maxAttempts) })
11
+ };
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdbase-dev/connect",
3
- "version": "0.1.0-beta.31",
3
+ "version": "0.1.0-beta.33",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,6 +18,14 @@
18
18
  ".": {
19
19
  "types": "./dist/index.d.ts",
20
20
  "import": "./dist/index.js"
21
+ },
22
+ "./advanced": {
23
+ "types": "./dist/advanced.d.ts",
24
+ "import": "./dist/advanced.js"
25
+ },
26
+ "./crypto": {
27
+ "types": "./dist/crypto-entry.d.ts",
28
+ "import": "./dist/crypto-entry.js"
21
29
  }
22
30
  },
23
31
  "files": [
@@ -25,7 +33,7 @@
25
33
  "README.md"
26
34
  ],
27
35
  "dependencies": {
28
- "@mdbase-dev/connect-protocol": "0.1.0-beta.31"
36
+ "@mdbase-dev/connect-protocol": "0.1.0-beta.33"
29
37
  },
30
38
  "devDependencies": {
31
39
  "esbuild": "^0.28.1",
@@ -36,6 +44,8 @@
36
44
  "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json && node scripts/build-browser.mjs",
37
45
  "test": "vitest run",
38
46
  "test:browser-storage": "pnpm build && node scripts/browser-storage.test.mjs",
47
+ "test:consumer-spikes": "tsc -p tsconfig.consumer-spikes.json",
48
+ "test:public-api": "pnpm build && pnpm --filter @mdbase-dev/connect-protocol build && pnpm --filter @mdbase-dev/connect-testing build && tsc -p tsconfig.public-api.json && node scripts/check-public-api.mjs && node scripts/test-packed-api.mjs",
39
49
  "typecheck": "tsc -p tsconfig.json --noEmit"
40
50
  }
41
51
  }