@enbox/dwn-sdk-js 0.3.7 → 0.3.8

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 (230) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +2591 -1435
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/constants.js +20 -0
  6. package/dist/esm/src/core/constants.js.map +1 -1
  7. package/dist/esm/src/core/dwn-error.js +24 -1
  8. package/dist/esm/src/core/dwn-error.js.map +1 -1
  9. package/dist/esm/src/core/grant-authorization.js +4 -4
  10. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  11. package/dist/esm/src/core/message.js +89 -4
  12. package/dist/esm/src/core/message.js.map +1 -1
  13. package/dist/esm/src/core/messages-grant-authorization.js +147 -55
  14. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization.js +76 -0
  16. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  17. package/dist/esm/src/core/records-grant-authorization.js +40 -15
  18. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  19. package/dist/esm/src/handlers/messages-read.js +5 -5
  20. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  21. package/dist/esm/src/handlers/messages-subscribe.js +109 -7
  22. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  23. package/dist/esm/src/handlers/messages-sync.js +341 -96
  24. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  25. package/dist/esm/src/handlers/protocols-configure.js +81 -2
  26. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  27. package/dist/esm/src/handlers/records-count.js +30 -0
  28. package/dist/esm/src/handlers/records-count.js.map +1 -1
  29. package/dist/esm/src/handlers/records-delete.js +3 -2
  30. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  31. package/dist/esm/src/handlers/records-query.js +30 -0
  32. package/dist/esm/src/handlers/records-query.js.map +1 -1
  33. package/dist/esm/src/handlers/records-read.js +3 -2
  34. package/dist/esm/src/handlers/records-read.js.map +1 -1
  35. package/dist/esm/src/handlers/records-subscribe.js +31 -0
  36. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  37. package/dist/esm/src/handlers/records-write.js +3 -2
  38. package/dist/esm/src/handlers/records-write.js.map +1 -1
  39. package/dist/esm/src/index.js +2 -0
  40. package/dist/esm/src/index.js.map +1 -1
  41. package/dist/esm/src/interfaces/messages-read.js +6 -3
  42. package/dist/esm/src/interfaces/messages-read.js.map +1 -1
  43. package/dist/esm/src/interfaces/messages-subscribe.js +6 -3
  44. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  45. package/dist/esm/src/interfaces/messages-sync.js +17 -3
  46. package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
  47. package/dist/esm/src/interfaces/protocols-configure.js +5 -2
  48. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  49. package/dist/esm/src/interfaces/protocols-query.js +8 -4
  50. package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
  51. package/dist/esm/src/interfaces/records-count.js +5 -0
  52. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  53. package/dist/esm/src/interfaces/records-delete.js +6 -2
  54. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  55. package/dist/esm/src/interfaces/records-query.js +5 -0
  56. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  57. package/dist/esm/src/interfaces/records-read.js +6 -3
  58. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  59. package/dist/esm/src/interfaces/records-subscribe.js +5 -0
  60. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  61. package/dist/esm/src/interfaces/records-write.js +6 -3
  62. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  63. package/dist/esm/src/protocols/permissions.js +28 -7
  64. package/dist/esm/src/protocols/permissions.js.map +1 -1
  65. package/dist/esm/src/sync/records-projection.js +228 -0
  66. package/dist/esm/src/sync/records-projection.js.map +1 -0
  67. package/dist/esm/src/types/message-types.js.map +1 -1
  68. package/dist/esm/src/types/permission-types.js.map +1 -1
  69. package/dist/esm/src/utils/permission-scope.js +37 -0
  70. package/dist/esm/src/utils/permission-scope.js.map +1 -0
  71. package/dist/esm/tests/core/grant-authorization.spec.js +26 -3
  72. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -1
  73. package/dist/esm/tests/core/records-grant-authorization.spec.js +117 -0
  74. package/dist/esm/tests/core/records-grant-authorization.spec.js.map +1 -0
  75. package/dist/esm/tests/features/permissions.spec.js +126 -0
  76. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  77. package/dist/esm/tests/handlers/messages-read.spec.js +345 -12
  78. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  79. package/dist/esm/tests/handlers/messages-subscribe.spec.js +326 -9
  80. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  81. package/dist/esm/tests/handlers/messages-sync.spec.js +1053 -7
  82. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  83. package/dist/esm/tests/handlers/protocols-configure.spec.js +361 -0
  84. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  85. package/dist/esm/tests/handlers/records-count.spec.js +75 -2
  86. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  87. package/dist/esm/tests/handlers/records-query.spec.js +73 -0
  88. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  89. package/dist/esm/tests/handlers/records-subscribe.spec.js +75 -1
  90. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  91. package/dist/esm/tests/interfaces/messages-get.spec.js +107 -5
  92. package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
  93. package/dist/esm/tests/interfaces/protocols-configure.spec.js +13 -0
  94. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  95. package/dist/esm/tests/interfaces/records-delete.spec.js +12 -0
  96. package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
  97. package/dist/esm/tests/interfaces/records-query.spec.js +10 -0
  98. package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
  99. package/dist/esm/tests/interfaces/records-subscribe.spec.js +10 -0
  100. package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
  101. package/dist/esm/tests/interfaces/records-write.spec.js +33 -0
  102. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  103. package/dist/esm/tests/sync/records-projection.spec.js +245 -0
  104. package/dist/esm/tests/sync/records-projection.spec.js.map +1 -0
  105. package/dist/esm/tests/test-suite.js +2 -0
  106. package/dist/esm/tests/test-suite.js.map +1 -1
  107. package/dist/esm/tests/utils/permission-scope.spec.js +66 -0
  108. package/dist/esm/tests/utils/permission-scope.spec.js.map +1 -0
  109. package/dist/esm/tests/utils/test-data-generator.js +5 -2
  110. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  111. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  112. package/dist/types/src/core/constants.d.ts +13 -0
  113. package/dist/types/src/core/constants.d.ts.map +1 -1
  114. package/dist/types/src/core/dwn-error.d.ts +24 -1
  115. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  116. package/dist/types/src/core/grant-authorization.d.ts +1 -2
  117. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  118. package/dist/types/src/core/message.d.ts +41 -1
  119. package/dist/types/src/core/message.d.ts.map +1 -1
  120. package/dist/types/src/core/messages-grant-authorization.d.ts +36 -4
  121. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  122. package/dist/types/src/core/protocol-authorization.d.ts +12 -0
  123. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  124. package/dist/types/src/core/records-grant-authorization.d.ts +6 -0
  125. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  126. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  127. package/dist/types/src/handlers/messages-subscribe.d.ts +2 -1
  128. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  129. package/dist/types/src/handlers/messages-sync.d.ts +31 -0
  130. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  131. package/dist/types/src/handlers/protocols-configure.d.ts +3 -0
  132. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  133. package/dist/types/src/handlers/records-count.d.ts +4 -0
  134. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  135. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  136. package/dist/types/src/handlers/records-query.d.ts +4 -0
  137. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  138. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  139. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  140. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  141. package/dist/types/src/index.d.ts +6 -2
  142. package/dist/types/src/index.d.ts.map +1 -1
  143. package/dist/types/src/interfaces/messages-read.d.ts +1 -1
  144. package/dist/types/src/interfaces/messages-read.d.ts.map +1 -1
  145. package/dist/types/src/interfaces/messages-subscribe.d.ts +1 -1
  146. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  147. package/dist/types/src/interfaces/messages-sync.d.ts +4 -1
  148. package/dist/types/src/interfaces/messages-sync.d.ts.map +1 -1
  149. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  150. package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
  151. package/dist/types/src/interfaces/records-count.d.ts +1 -0
  152. package/dist/types/src/interfaces/records-count.d.ts.map +1 -1
  153. package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
  154. package/dist/types/src/interfaces/records-query.d.ts +1 -0
  155. package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
  156. package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
  157. package/dist/types/src/interfaces/records-subscribe.d.ts +1 -0
  158. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  159. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  160. package/dist/types/src/protocols/permissions.d.ts +2 -0
  161. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  162. package/dist/types/src/sync/records-projection.d.ts +98 -0
  163. package/dist/types/src/sync/records-projection.d.ts.map +1 -0
  164. package/dist/types/src/types/message-types.d.ts +1 -0
  165. package/dist/types/src/types/message-types.d.ts.map +1 -1
  166. package/dist/types/src/types/messages-types.d.ts +21 -3
  167. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  168. package/dist/types/src/types/permission-types.d.ts +4 -0
  169. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  170. package/dist/types/src/types/records-types.d.ts +4 -0
  171. package/dist/types/src/types/records-types.d.ts.map +1 -1
  172. package/dist/types/src/types/subscriptions.d.ts +18 -3
  173. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  174. package/dist/types/src/utils/permission-scope.d.ts +29 -0
  175. package/dist/types/src/utils/permission-scope.d.ts.map +1 -0
  176. package/dist/types/tests/core/records-grant-authorization.spec.d.ts +2 -0
  177. package/dist/types/tests/core/records-grant-authorization.spec.d.ts.map +1 -0
  178. package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
  179. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  180. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  181. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  182. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  183. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  184. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  185. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  186. package/dist/types/tests/sync/records-projection.spec.d.ts +2 -0
  187. package/dist/types/tests/sync/records-projection.spec.d.ts.map +1 -0
  188. package/dist/types/tests/test-suite.d.ts.map +1 -1
  189. package/dist/types/tests/utils/permission-scope.spec.d.ts +2 -0
  190. package/dist/types/tests/utils/permission-scope.spec.d.ts.map +1 -0
  191. package/dist/types/tests/utils/test-data-generator.d.ts +5 -2
  192. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  193. package/package.json +1 -1
  194. package/src/core/constants.ts +24 -0
  195. package/src/core/dwn-error.ts +24 -1
  196. package/src/core/grant-authorization.ts +7 -5
  197. package/src/core/message.ts +153 -6
  198. package/src/core/messages-grant-authorization.ts +282 -70
  199. package/src/core/protocol-authorization.ts +130 -0
  200. package/src/core/records-grant-authorization.ts +64 -21
  201. package/src/handlers/messages-read.ts +7 -5
  202. package/src/handlers/messages-subscribe.ts +149 -9
  203. package/src/handlers/messages-sync.ts +593 -102
  204. package/src/handlers/protocols-configure.ts +103 -2
  205. package/src/handlers/records-count.ts +33 -0
  206. package/src/handlers/records-delete.ts +3 -2
  207. package/src/handlers/records-query.ts +33 -0
  208. package/src/handlers/records-read.ts +3 -2
  209. package/src/handlers/records-subscribe.ts +34 -0
  210. package/src/handlers/records-write.ts +3 -2
  211. package/src/index.ts +7 -3
  212. package/src/interfaces/messages-read.ts +8 -5
  213. package/src/interfaces/messages-subscribe.ts +12 -9
  214. package/src/interfaces/messages-sync.ts +33 -12
  215. package/src/interfaces/protocols-configure.ts +8 -4
  216. package/src/interfaces/protocols-query.ts +13 -9
  217. package/src/interfaces/records-count.ts +7 -0
  218. package/src/interfaces/records-delete.ts +9 -5
  219. package/src/interfaces/records-query.ts +7 -0
  220. package/src/interfaces/records-read.ts +6 -3
  221. package/src/interfaces/records-subscribe.ts +7 -0
  222. package/src/interfaces/records-write.ts +25 -17
  223. package/src/protocols/permissions.ts +47 -9
  224. package/src/sync/records-projection.ts +328 -0
  225. package/src/types/message-types.ts +1 -0
  226. package/src/types/messages-types.ts +23 -3
  227. package/src/types/permission-types.ts +5 -1
  228. package/src/types/records-types.ts +5 -1
  229. package/src/types/subscriptions.ts +19 -3
  230. package/src/utils/permission-scope.ts +55 -0
@@ -24,7 +24,7 @@ export type MessagesReadDescriptor = {
24
24
  method: DwnMethodName.Read;
25
25
  messageCid: string;
26
26
  messageTimestamp: string;
27
- permissionGrantId?: string;
27
+ permissionGrantIds?: string[];
28
28
  };
29
29
 
30
30
  export type MessagesReadMessage = GenericMessage & {
@@ -50,8 +50,14 @@ export type MessagesSyncDescriptor = {
50
50
  messageTimestamp : string;
51
51
  action : MessagesSyncAction;
52
52
  protocol? : string; // optional protocol scope
53
+ projectionRootVersion?: string;
54
+ projectionScopes?: {
55
+ protocol: string;
56
+ protocolPath?: string;
57
+ contextId?: string;
58
+ }[];
53
59
  prefix? : string; // bit path for subtree/leaves (e.g. "0110101...")
54
- permissionGrantId? : string;
60
+ permissionGrantIds? : string[];
55
61
  /**
56
62
  * For `action: 'diff'`: a map of `{ bitPrefix: hexHash }` representing the client's
57
63
  * subtree hashes at `depth`. The server compares each hash against its own tree
@@ -85,6 +91,18 @@ export type MessagesSyncDiffEntry = {
85
91
  encodedData? : string;
86
92
  };
87
93
 
94
+ export type MessagesSyncDependencyClass = 'protocolsConfigure' | 'recordsInitialWrite';
95
+
96
+ /**
97
+ * Advisory dependency hint returned with projected diff responses. Dependency
98
+ * entries are not part of the projected root; clients must rederive that the
99
+ * dependency is required by the referenced primary before applying it.
100
+ */
101
+ export type MessagesSyncDependencyEntry = MessagesSyncDiffEntry & {
102
+ dependencyClass: MessagesSyncDependencyClass;
103
+ rootMessageCid: string;
104
+ };
105
+
88
106
  export type MessagesSyncReply = GenericMessageReply & {
89
107
  root? : string; // hex-encoded root hash (for 'root' action)
90
108
  hash? : string; // hex-encoded subtree hash (for 'subtree' action)
@@ -93,6 +111,8 @@ export type MessagesSyncReply = GenericMessageReply & {
93
111
  onlyRemote? : MessagesSyncDiffEntry[];
94
112
  /** For 'diff' action: bit prefixes where the client has entries the server doesn't. */
95
113
  onlyLocal? : string[];
114
+ /** Advisory dependency messages needed to apply projected `onlyRemote` primary entries. */
115
+ dependencies? : MessagesSyncDependencyEntry[];
96
116
  };
97
117
 
98
118
  export type MessagesSubscribeMessageOptions = {
@@ -115,7 +135,7 @@ export type MessagesSubscribeDescriptor = {
115
135
  method: DwnMethodName.Subscribe;
116
136
  messageTimestamp: string;
117
137
  filters: MessagesFilter[];
118
- permissionGrantId?: string;
138
+ permissionGrantIds?: string[];
119
139
  /**
120
140
  * Progress token to resume from. When provided, the handler replays events
121
141
  * from the EventLog starting after this position instead of returning no
@@ -96,6 +96,10 @@ export type MessagesPermissionScope = {
96
96
  interface: DwnInterfaceName.Messages;
97
97
  method: DwnMethodName.Read;
98
98
  protocol?: string;
99
+ /** May only be present when `protocol` is defined and `protocolPath` is undefined */
100
+ contextId?: string;
101
+ /** May only be present when `protocol` is defined and `contextId` is undefined */
102
+ protocolPath?: string;
99
103
  };
100
104
 
101
105
  /**
@@ -123,4 +127,4 @@ export type PermissionConditions = {
123
127
  * If `undefined`, it is optional to make the message public.
124
128
  */
125
129
  publication?: PermissionConditionPublication;
126
- };
130
+ };
@@ -105,6 +105,7 @@ export type RecordsCountDescriptor = {
105
105
  method: DwnMethodName.Count;
106
106
  messageTimestamp: string;
107
107
  filter: RecordsFilter;
108
+ permissionGrantId?: string;
108
109
  };
109
110
 
110
111
  export type RecordsCountMessage = GenericMessage & {
@@ -120,6 +121,7 @@ export type RecordsQueryDescriptor = {
120
121
  method: DwnMethodName.Query;
121
122
  messageTimestamp: string;
122
123
  filter: RecordsFilter;
124
+ permissionGrantId?: string;
123
125
  dateSort?: DateSort;
124
126
  pagination?: Pagination;
125
127
  };
@@ -129,6 +131,7 @@ export type RecordsSubscribeDescriptor = {
129
131
  method: DwnMethodName.Subscribe;
130
132
  messageTimestamp: string;
131
133
  filter: RecordsFilter;
134
+ permissionGrantId?: string;
132
135
  dateSort?: DateSort;
133
136
  pagination?: Pagination;
134
137
  /**
@@ -267,9 +270,10 @@ export type RecordsDeleteDescriptor = {
267
270
  method: DwnMethodName.Delete;
268
271
  messageTimestamp: string;
269
272
  recordId: string;
273
+ permissionGrantId?: string;
270
274
 
271
275
  /**
272
276
  * Denotes if all the descendent records should be purged.
273
277
  */
274
278
  prune: boolean
275
- };
279
+ };
@@ -110,15 +110,31 @@ export type SubscriptionEose = {
110
110
  cursor : ProgressToken;
111
111
  };
112
112
 
113
+ /**
114
+ * Subscription-level error emitted after a subscription is already open.
115
+ *
116
+ * This is used for conditions that invalidate future delivery, such as a
117
+ * delegated subscription grant being revoked after the subscription was
118
+ * authorized. The cursor identifies the event that caused delivery to stop.
119
+ */
120
+ export type SubscriptionError = {
121
+ type : 'error';
122
+ cursor : ProgressToken;
123
+ error : {
124
+ code : string;
125
+ detail : string;
126
+ };
127
+ };
128
+
113
129
  /**
114
130
  * Discriminated union of subscription event types delivered to
115
131
  * {@link SubscriptionListener} callbacks.
116
132
  */
117
- export type SubscriptionMessage = SubscriptionEvent | SubscriptionEose;
133
+ export type SubscriptionMessage = SubscriptionEvent | SubscriptionEose | SubscriptionError;
118
134
 
119
135
  /**
120
- * Callback for {@link EventLog.subscribe}. Receives either a regular event
121
- * (with cursor) or an EOSE marker indicating catch-up replay is complete.
136
+ * Callback for {@link EventLog.subscribe}. Receives events, catch-up EOSE
137
+ * markers, or subscription-level errors that stop delivery.
122
138
  */
123
139
  export type SubscriptionListener = (message: SubscriptionMessage) => void;
124
140
 
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Minimal protocol-bound scope shape used by permission grant authorization.
3
+ *
4
+ * Permission grants and candidate records/filters are projected down to these
5
+ * fields before matching so grant selection and server enforcement use the
6
+ * same rules.
7
+ */
8
+ export type ProtocolScope = {
9
+ protocol?: string;
10
+ protocolPath?: string;
11
+ contextId?: string;
12
+ };
13
+
14
+ /**
15
+ * Shared matching rules for protocol-scoped permission grants.
16
+ *
17
+ * Matching fails closed for invalid combinations: `protocolPath` and
18
+ * `contextId` are mutually exclusive, and either field requires `protocol`.
19
+ * `protocol` and `protocolPath` match by exact equality. `contextId` scopes
20
+ * match a context subtree: the target context must equal the scoped context or
21
+ * begin with the scoped context followed by `/`.
22
+ */
23
+ export class PermissionScopeMatcher {
24
+ /**
25
+ * Determines whether a candidate target is within a grant scope.
26
+ */
27
+ public static matches(scope: ProtocolScope, target: ProtocolScope): boolean {
28
+ if (scope.protocolPath !== undefined && scope.contextId !== undefined) {
29
+ return false;
30
+ }
31
+
32
+ if ((scope.protocolPath !== undefined || scope.contextId !== undefined) && scope.protocol === undefined) {
33
+ return false;
34
+ }
35
+
36
+ if (scope.protocol !== undefined && scope.protocol !== target.protocol) {
37
+ return false;
38
+ }
39
+
40
+ if (scope.protocolPath !== undefined) {
41
+ return scope.protocolPath === target.protocolPath;
42
+ }
43
+
44
+ if (scope.contextId !== undefined) {
45
+ return PermissionScopeMatcher.matchesContextId(scope.contextId, target.contextId);
46
+ }
47
+
48
+ return true;
49
+ }
50
+
51
+ private static matchesContextId(scopeContextId: string, candidateContextId: unknown): boolean {
52
+ return typeof candidateContextId === 'string' &&
53
+ (candidateContextId === scopeContextId || candidateContextId.startsWith(scopeContextId + '/'));
54
+ }
55
+ }