@enbox/dwn-sdk-js 0.3.4 → 0.3.5

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 (199) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +3 -3
  3. package/dist/esm/generated/precompiled-validators.js +766 -1224
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/abstract-message.js +3 -3
  6. package/dist/esm/src/core/abstract-message.js.map +1 -1
  7. package/dist/esm/src/core/grant-authorization.js +6 -2
  8. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  9. package/dist/esm/src/core/message.js +3 -3
  10. package/dist/esm/src/core/message.js.map +1 -1
  11. package/dist/esm/src/core/protocol-authorization-action.js +3 -3
  12. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  13. package/dist/esm/src/core/protocol-authorization-validation.js +1 -1
  14. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization.js +11 -11
  16. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  17. package/dist/esm/src/core/records-grant-authorization.js +1 -1
  18. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  19. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  20. package/dist/esm/src/dwn.js.map +1 -1
  21. package/dist/esm/src/event-stream/event-emitter-event-log.js +12 -12
  22. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -1
  23. package/dist/esm/src/handlers/messages-read.js +7 -7
  24. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  25. package/dist/esm/src/handlers/messages-subscribe.js +1 -1
  26. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  27. package/dist/esm/src/handlers/messages-sync.js +18 -18
  28. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  29. package/dist/esm/src/handlers/protocols-configure.js +1 -1
  30. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  31. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  32. package/dist/esm/src/handlers/records-count.js.map +1 -1
  33. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  34. package/dist/esm/src/handlers/records-query.js.map +1 -1
  35. package/dist/esm/src/handlers/records-read.js +6 -6
  36. package/dist/esm/src/handlers/records-read.js.map +1 -1
  37. package/dist/esm/src/handlers/records-subscribe.js +1 -1
  38. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  39. package/dist/esm/src/handlers/records-write.js +16 -16
  40. package/dist/esm/src/handlers/records-write.js.map +1 -1
  41. package/dist/esm/src/index.js +2 -2
  42. package/dist/esm/src/index.js.map +1 -1
  43. package/dist/esm/src/interfaces/protocols-configure.js +9 -9
  44. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  45. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  46. package/dist/esm/src/interfaces/records-write.js +8 -8
  47. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  48. package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
  49. package/dist/esm/src/jose/jws/general/verifier.js +30 -2
  50. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  51. package/dist/esm/src/protocols/permissions.js +1 -1
  52. package/dist/esm/src/protocols/permissions.js.map +1 -1
  53. package/dist/esm/src/smt/smt-store-level.js.map +1 -1
  54. package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
  55. package/dist/esm/src/smt/sparse-merkle-tree.js +2 -2
  56. package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
  57. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  58. package/dist/esm/src/store/index-level-compound.js +10 -10
  59. package/dist/esm/src/store/index-level-compound.js.map +1 -1
  60. package/dist/esm/src/store/index-level.js +2 -2
  61. package/dist/esm/src/store/index-level.js.map +1 -1
  62. package/dist/esm/src/store/level-wrapper.js +1 -1
  63. package/dist/esm/src/store/level-wrapper.js.map +1 -1
  64. package/dist/esm/src/store/storage-controller.js +23 -10
  65. package/dist/esm/src/store/storage-controller.js.map +1 -1
  66. package/dist/esm/src/types/permission-types.js.map +1 -1
  67. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  68. package/dist/esm/src/utils/messages.js +1 -1
  69. package/dist/esm/src/utils/messages.js.map +1 -1
  70. package/dist/esm/src/utils/object.js +1 -4
  71. package/dist/esm/src/utils/object.js.map +1 -1
  72. package/dist/esm/src/utils/private-key-signer.js.map +1 -1
  73. package/dist/esm/src/utils/records.js.map +1 -1
  74. package/dist/esm/tests/core/grant-authorization.spec.js +38 -0
  75. package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -0
  76. package/dist/esm/tests/features/permissions.spec.js +1 -1
  77. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  78. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +422 -0
  79. package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -0
  80. package/dist/esm/tests/handlers/messages-subscribe.spec.js +3 -26
  81. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  82. package/dist/esm/tests/handlers/messages-sync.spec.js +3 -26
  83. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  84. package/dist/esm/tests/handlers/protocols-query.spec.js +4 -3
  85. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  86. package/dist/esm/tests/jose/jws/general.spec.js +115 -0
  87. package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
  88. package/dist/esm/tests/test-suite.js +2 -0
  89. package/dist/esm/tests/test-suite.js.map +1 -1
  90. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  91. package/dist/types/src/core/abstract-message.d.ts +4 -4
  92. package/dist/types/src/core/abstract-message.d.ts.map +1 -1
  93. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  94. package/dist/types/src/core/resumable-task-manager.d.ts +2 -2
  95. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  96. package/dist/types/src/dwn.d.ts +12 -12
  97. package/dist/types/src/dwn.d.ts.map +1 -1
  98. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +5 -5
  99. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -1
  100. package/dist/types/src/handlers/messages-read.d.ts +1 -1
  101. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  102. package/dist/types/src/handlers/messages-subscribe.d.ts +1 -1
  103. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  104. package/dist/types/src/handlers/messages-sync.d.ts +1 -1
  105. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  106. package/dist/types/src/handlers/protocols-configure.d.ts +1 -1
  107. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  108. package/dist/types/src/handlers/protocols-query.d.ts +1 -1
  109. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  110. package/dist/types/src/handlers/records-count.d.ts +1 -1
  111. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  112. package/dist/types/src/handlers/records-delete.d.ts +1 -1
  113. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  114. package/dist/types/src/handlers/records-query.d.ts +1 -1
  115. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  116. package/dist/types/src/handlers/records-read.d.ts +1 -1
  117. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  118. package/dist/types/src/handlers/records-subscribe.d.ts +1 -1
  119. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  120. package/dist/types/src/handlers/records-write.d.ts +1 -1
  121. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  122. package/dist/types/src/index.d.ts +5 -5
  123. package/dist/types/src/index.d.ts.map +1 -1
  124. package/dist/types/src/interfaces/records-write.d.ts +2 -2
  125. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  126. package/dist/types/src/jose/jws/general/builder.d.ts +1 -1
  127. package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -1
  128. package/dist/types/src/jose/jws/general/verifier.d.ts +13 -0
  129. package/dist/types/src/jose/jws/general/verifier.d.ts.map +1 -1
  130. package/dist/types/src/smt/smt-store-level.d.ts +1 -1
  131. package/dist/types/src/smt/smt-store-level.d.ts.map +1 -1
  132. package/dist/types/src/smt/smt-store-memory.d.ts +1 -1
  133. package/dist/types/src/smt/smt-store-memory.d.ts.map +1 -1
  134. package/dist/types/src/smt/sparse-merkle-tree.d.ts +1 -1
  135. package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +1 -1
  136. package/dist/types/src/state-index/state-index-level.d.ts +3 -3
  137. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  138. package/dist/types/src/store/index-level.d.ts +2 -2
  139. package/dist/types/src/store/index-level.d.ts.map +1 -1
  140. package/dist/types/src/store/storage-controller.d.ts +19 -5
  141. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  142. package/dist/types/src/types/permission-types.d.ts +3 -4
  143. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  144. package/dist/types/src/utils/memory-cache.d.ts +2 -2
  145. package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
  146. package/dist/types/src/utils/object.d.ts.map +1 -1
  147. package/dist/types/src/utils/private-key-signer.d.ts +2 -2
  148. package/dist/types/src/utils/private-key-signer.d.ts.map +1 -1
  149. package/dist/types/tests/core/grant-authorization.spec.d.ts +2 -0
  150. package/dist/types/tests/core/grant-authorization.spec.d.ts.map +1 -0
  151. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts +29 -0
  152. package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts.map +1 -0
  153. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  154. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  155. package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
  156. package/dist/types/tests/test-suite.d.ts.map +1 -1
  157. package/package.json +1 -1
  158. package/src/core/abstract-message.ts +8 -8
  159. package/src/core/grant-authorization.ts +9 -2
  160. package/src/core/message.ts +3 -3
  161. package/src/core/protocol-authorization-action.ts +3 -3
  162. package/src/core/protocol-authorization-validation.ts +9 -9
  163. package/src/core/protocol-authorization.ts +24 -24
  164. package/src/core/records-grant-authorization.ts +1 -1
  165. package/src/core/resumable-task-manager.ts +2 -2
  166. package/src/dwn.ts +13 -13
  167. package/src/event-stream/event-emitter-event-log.ts +15 -15
  168. package/src/handlers/messages-read.ts +7 -7
  169. package/src/handlers/messages-subscribe.ts +2 -2
  170. package/src/handlers/messages-sync.ts +19 -19
  171. package/src/handlers/protocols-configure.ts +2 -2
  172. package/src/handlers/protocols-query.ts +1 -1
  173. package/src/handlers/records-count.ts +1 -1
  174. package/src/handlers/records-delete.ts +1 -1
  175. package/src/handlers/records-query.ts +1 -1
  176. package/src/handlers/records-read.ts +6 -6
  177. package/src/handlers/records-subscribe.ts +2 -2
  178. package/src/handlers/records-write.ts +18 -18
  179. package/src/index.ts +5 -5
  180. package/src/interfaces/protocols-configure.ts +12 -12
  181. package/src/interfaces/records-delete.ts +1 -1
  182. package/src/interfaces/records-write.ts +11 -11
  183. package/src/jose/jws/general/builder.ts +1 -1
  184. package/src/jose/jws/general/verifier.ts +44 -3
  185. package/src/protocols/permissions.ts +1 -1
  186. package/src/smt/smt-store-level.ts +1 -1
  187. package/src/smt/smt-store-memory.ts +1 -1
  188. package/src/smt/sparse-merkle-tree.ts +10 -10
  189. package/src/state-index/state-index-level.ts +3 -3
  190. package/src/store/index-level-compound.ts +11 -11
  191. package/src/store/index-level.ts +4 -4
  192. package/src/store/level-wrapper.ts +1 -1
  193. package/src/store/storage-controller.ts +31 -16
  194. package/src/types/permission-types.ts +3 -4
  195. package/src/utils/memory-cache.ts +2 -2
  196. package/src/utils/messages.ts +2 -2
  197. package/src/utils/object.ts +1 -5
  198. package/src/utils/private-key-signer.ts +2 -2
  199. package/src/utils/records.ts +1 -1
@@ -20,7 +20,7 @@ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.j
20
20
 
21
21
  export class RecordsSubscribeHandler implements MethodHandler {
22
22
 
23
- constructor(private deps: HandlerDependencies) { }
23
+ constructor(private readonly deps: HandlerDependencies) { }
24
24
 
25
25
  public async handle({
26
26
  tenant,
@@ -97,7 +97,7 @@ export class RecordsSubscribeHandler implements MethodHandler {
97
97
  const gapInfo = (error as any).gapInfo as ProgressGapInfo | undefined;
98
98
  return {
99
99
  status : { code: 410, detail: 'Progress token gap' },
100
- error : gapInfo !== undefined ? { code: 'ProgressGap' as const, ...gapInfo } : undefined,
100
+ error : gapInfo === undefined ? undefined : { code: 'ProgressGap' as const, ...gapInfo },
101
101
  };
102
102
  }
103
103
  return messageReplyFromError(error, 500);
@@ -27,7 +27,7 @@ type HandlerArgs = { tenant: string, message: RecordsWriteMessage, dataStream?:
27
27
 
28
28
  export class RecordsWriteHandler implements MethodHandler {
29
29
 
30
- constructor(private deps: HandlerDependencies) { }
30
+ constructor(private readonly deps: HandlerDependencies) { }
31
31
 
32
32
  public async handle({
33
33
  tenant,
@@ -106,7 +106,7 @@ export class RecordsWriteHandler implements MethodHandler {
106
106
  if (isInitial) {
107
107
  const hasInlineData = !!(newestExistingMessage as any).encodedData;
108
108
  const hasStoredData = this.deps.dataStore
109
- ? !!(await this.deps.dataStore.get(tenant, recordsWrite.message.recordId, message.descriptor.dataCid!))
109
+ ? !!(await this.deps.dataStore.get(tenant, recordsWrite.message.recordId, message.descriptor.dataCid))
110
110
  : false;
111
111
  existingLacksData = !hasInlineData && !hasStoredData;
112
112
  }
@@ -121,9 +121,9 @@ export class RecordsWriteHandler implements MethodHandler {
121
121
 
122
122
  // Look up the core protocol (if any) for the incoming message so that lifecycle hooks
123
123
  // can be dispatched generically rather than checking for specific protocol URIs.
124
- const coreProtocol = message.descriptor.protocol !== undefined
125
- ? this.deps.coreProtocols?.get(message.descriptor.protocol)
126
- : undefined;
124
+ const coreProtocol = message.descriptor.protocol === undefined
125
+ ? undefined
126
+ : this.deps.coreProtocols?.get(message.descriptor.protocol);
127
127
 
128
128
  try {
129
129
  if (newestExistingMessage?.descriptor.method === DwnMethodName.Delete) {
@@ -148,11 +148,8 @@ export class RecordsWriteHandler implements MethodHandler {
148
148
  let isLatestBaseState = false;
149
149
  let messageWithOptionalEncodedData = message as RecordsQueryReplyEntry;
150
150
 
151
- if (dataStream !== undefined) {
152
- messageWithOptionalEncodedData = await this.processMessageWithDataStream(tenant, message, dataStream);
153
- isLatestBaseState = true;
154
- } else {
155
- // else data stream is NOT provided
151
+ if (dataStream === undefined) {
152
+ // data stream is NOT provided
156
153
 
157
154
  // if the incoming message is not an initial write, and no dataStream is provided, we would allow it provided it passes validation
158
155
  // processMessageWithoutDataStream() abstracts that logic
@@ -161,6 +158,9 @@ export class RecordsWriteHandler implements MethodHandler {
161
158
  messageWithOptionalEncodedData = await this.processMessageWithoutDataStream(tenant, message, newestExistingWrite );
162
159
  isLatestBaseState = true;
163
160
  }
161
+ } else {
162
+ messageWithOptionalEncodedData = await this.processMessageWithDataStream(tenant, message, dataStream);
163
+ isLatestBaseState = true;
164
164
  }
165
165
 
166
166
  const indexes = await recordsWrite.constructIndexes(isLatestBaseState);
@@ -252,14 +252,14 @@ export class RecordsWriteHandler implements MethodHandler {
252
252
  // if data is below the threshold, we store it within MessageStore
253
253
  if (message.descriptor.dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
254
254
  // validate data integrity before setting.
255
- const dataBytes = await DataStream.toBytes(dataStream!);
255
+ const dataBytes = await DataStream.toBytes(dataStream);
256
256
  const dataCid = await Cid.computeDagPbCidFromBytes(dataBytes);
257
257
  RecordsWriteHandler.validateDataIntegrity(message.descriptor.dataCid, message.descriptor.dataSize, dataCid, dataBytes.length);
258
258
 
259
259
  // Dispatch schema validation to the core protocol, if applicable.
260
- const coreProtocol = message.descriptor.protocol !== undefined
261
- ? this.deps.coreProtocols?.get(message.descriptor.protocol)
262
- : undefined;
260
+ const coreProtocol = message.descriptor.protocol === undefined
261
+ ? undefined
262
+ : this.deps.coreProtocols?.get(message.descriptor.protocol);
263
263
  if (coreProtocol?.validateRecord !== undefined) {
264
264
  coreProtocol.validateRecord(message, dataBytes);
265
265
  }
@@ -304,13 +304,13 @@ export class RecordsWriteHandler implements MethodHandler {
304
304
 
305
305
  if (dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
306
306
  // we encode the data from the original write if it is smaller than the data-store threshold
307
- if (newestExistingWrite.encodedData !== undefined) {
308
- messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
309
- } else {
307
+ if (newestExistingWrite.encodedData === undefined) {
310
308
  throw new DwnError(
311
309
  DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious,
312
310
  `No dataStream was provided and unable to get data from previous message`
313
311
  );
312
+ } else {
313
+ messageWithOptionalEncodedData.encodedData = newestExistingWrite.encodedData;
314
314
  }
315
315
  } else {
316
316
  // else just make sure the data is in the data store
@@ -396,7 +396,7 @@ export class RecordsWriteHandler implements MethodHandler {
396
396
  ruleSet = ruleSet[pathSegments[i]] as typeof ruleSet;
397
397
  }
398
398
 
399
- if (ruleSet === undefined || ruleSet.$squash !== true) {
399
+ if (ruleSet?.$squash !== true) {
400
400
  return;
401
401
  }
402
402
 
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  export type { DwnConfig } from './dwn.js';
3
3
  export type { EventListener, EventLog, EventLogEntry, EventLogReadOptions, EventLogReadResult, EventLogSubscribeOptions, EventSubscription, MessageEvent, ProgressGapInfo, ProgressGapReason, ProgressToken, SubscriptionEose, SubscriptionEvent, SubscriptionListener, SubscriptionMessage, SubscriptionReply } from './types/subscriptions.js';
4
4
  export type { AuthorizationModel, Descriptor, DelegatedGrantRecordsWriteMessage, GenericMessage, GenericMessageReply, GenericSignaturePayload, MessageSort, MessageSubscription, Pagination, QueryResultEntry, Status } from './types/message-types.js';
5
- export type { MessagesFilter, MessagesReadMessage as MessagesReadMessage, MessagesReadReply as MessagesReadReply, MessagesReadReplyEntry as MessagesReadReplyEntry, MessagesReadDescriptor, MessagesSubscribeDescriptor, MessagesSubscribeMessage, MessagesSubscribeReply, MessagesSubscribeMessageOptions, MessagesSyncAction, MessagesSyncDescriptor, MessagesSyncDiffEntry, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
5
+ export type { MessagesFilter, MessagesReadMessage, MessagesReadReply, MessagesReadReplyEntry, MessagesReadDescriptor, MessagesSubscribeDescriptor, MessagesSubscribeMessage, MessagesSubscribeReply, MessagesSubscribeMessageOptions, MessagesSyncAction, MessagesSyncDescriptor, MessagesSyncDiffEntry, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
6
6
  export type { GT, LT, Filter, FilterValue, KeyValues, EqualFilter, OneOfFilter, RangeFilter, RangeCriterion, PaginationCursor, QueryOptions, RangeValue, StartsWithFilter } from './types/query-types.js';
7
7
  export type { ProtocolsConfigureDescriptor, ProtocolDefinition, ProtocolTypes, ProtocolRuleSet, ProtocolsQueryFilter, ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply, ProtocolActionRule, ProtocolDeliveryStrategy, ProtocolPathEncryption, ProtocolsQueryDescriptor, ProtocolRecordLimitDefinition, ProtocolSizeDefinition, ProtocolTagsDefinition, ProtocolTagSchema, ProtocolType, ProtocolUses } from './types/protocols-types.js';
8
8
  export { ProtocolRecordLimitStrategy } from './types/protocols-types.js';
@@ -30,8 +30,8 @@ export { DwnConstant } from './core/dwn-constant.js';
30
30
  export { DwnError, DwnErrorCode } from './core/dwn-error.js';
31
31
  export { DwnInterfaceName, DwnMethodName } from './enums/dwn-interface-method.js';
32
32
  export { Encoder } from './utils/encoder.js';
33
- export { MessagesSubscribe as MessagesSubscribe } from './interfaces/messages-subscribe.js';
34
- export type { MessagesSubscribeOptions as MessagesSubscribeOptions } from './interfaces/messages-subscribe.js';
33
+ export { MessagesSubscribe } from './interfaces/messages-subscribe.js';
34
+ export type { MessagesSubscribeOptions } from './interfaces/messages-subscribe.js';
35
35
  export { Encryption, ContentEncryptionAlgorithm, KeyAgreementAlgorithm } from './utils/encryption.js';
36
36
  export type { JweEncryption, JweRecipient, JweRecipientHeader, JweProtectedHeader, JweKeyUnwrapPayload } from './utils/encryption.js';
37
37
  export { RecordsWrite } from './interfaces/records-write.js';
@@ -40,8 +40,8 @@ export { executeUnlessAborted } from './utils/abort.js';
40
40
  export { Jws } from './utils/jws.js';
41
41
  export type { KeyMaterial, PrivateKeyJwk, PublicKeyJwk, Jwk } from './types/jose-types.js';
42
42
  export { Message } from './core/message.js';
43
- export { MessagesRead as MessagesRead } from './interfaces/messages-read.js';
44
- export type { MessagesReadOptions as MessagesReadOptions } from './interfaces/messages-read.js';
43
+ export { MessagesRead } from './interfaces/messages-read.js';
44
+ export type { MessagesReadOptions } from './interfaces/messages-read.js';
45
45
  export { MessagesSync } from './interfaces/messages-sync.js';
46
46
  export type { MessagesSyncOptions } from './interfaces/messages-sync.js';
47
47
  export type { UnionMessageReply } from './core/message-reply.js';
@@ -377,16 +377,8 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
377
377
  for (let j = i + 1; j < actionRules.length; j++) {
378
378
  const otherActionRule = actionRules[j];
379
379
 
380
- if (actionRule.who !== undefined) {
381
- if (actionRule.who === otherActionRule.who && actionRule.of === otherActionRule.of) {
382
- throw new DwnError(
383
- DwnErrorCode.ProtocolsConfigureDuplicateActorInRuleSet,
384
- `More than one action rule per actor ${actionRule.who} of ${actionRule.of} ` +
385
- `not allowed within a rule set: ${JSON.stringify(actionRule)}`
386
- );
387
- }
388
- } else {
389
- // else implicitly a role-based action rule
380
+ if (actionRule.who === undefined) {
381
+ // implicitly a role-based action rule
390
382
 
391
383
  if (actionRule.role === otherActionRule.role) {
392
384
  throw new DwnError(
@@ -394,6 +386,14 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
394
386
  `More than one action rule per role ${actionRule.role} not allowed within a rule set: ${JSON.stringify(actionRule)}`
395
387
  );
396
388
  }
389
+ } else {
390
+ if (actionRule.who === otherActionRule.who && actionRule.of === otherActionRule.of) {
391
+ throw new DwnError(
392
+ DwnErrorCode.ProtocolsConfigureDuplicateActorInRuleSet,
393
+ `More than one action rule per actor ${actionRule.who} of ${actionRule.of} ` +
394
+ `not allowed within a rule set: ${JSON.stringify(actionRule)}`
395
+ );
396
+ }
397
397
  }
398
398
  }
399
399
  }
@@ -497,7 +497,7 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
497
497
  }
498
498
 
499
499
  // validate alias exists in `uses`
500
- if (uses === undefined || uses[parsed.alias] === undefined) {
500
+ if (uses?.[parsed.alias] === undefined) {
501
501
  throw new DwnError(
502
502
  DwnErrorCode.ProtocolsConfigureInvalidRefAlias,
503
503
  `'$ref' alias '${parsed.alias}' at protocol path '${ruleSetProtocolPath}' does not exist in the 'uses' map.`
@@ -543,7 +543,7 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
543
543
  );
544
544
  }
545
545
 
546
- if (uses === undefined || uses[parsed.alias] === undefined) {
546
+ if (uses?.[parsed.alias] === undefined) {
547
547
  const errorCode = fieldName === 'role'
548
548
  ? DwnErrorCode.ProtocolsConfigureInvalidCrossProtocolRole
549
549
  : DwnErrorCode.ProtocolsConfigureInvalidCrossProtocolOf;
@@ -110,7 +110,7 @@ export class RecordsDelete extends AbstractMessage<RecordsDeleteMessage> {
110
110
  * @param messageStore Used to check if the grant has been revoked.
111
111
  */
112
112
  public async authorizeDelegate(recordsWriteToDelete: RecordsWriteMessage, messageStore: MessageStore): Promise<void> {
113
- const delegatedGrant = PermissionGrant.parse(this.message.authorization!.authorDelegatedGrant!);
113
+ const delegatedGrant = PermissionGrant.parse(this.message.authorization.authorDelegatedGrant!);
114
114
  await RecordsGrantAuthorization.authorizeDelete({
115
115
  recordsDeleteMessage : this.message,
116
116
  recordsWriteToDelete,
@@ -135,9 +135,9 @@ export type CreateFromOptions = {
135
135
  * NOTE: Unable to extend `AbstractMessage` directly because the incompatible `_message` type, which is not just a generic `<M>` type.
136
136
  */
137
137
  export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
138
- private parentContextId: string | undefined;
138
+ private readonly parentContextId: string | undefined;
139
139
 
140
- private _message: InternalRecordsWriteMessage;
140
+ private readonly _message: InternalRecordsWriteMessage;
141
141
  /**
142
142
  * Valid JSON message representing this RecordsWrite.
143
143
  * @throws `DwnErrorCode.RecordsWriteMissingSigner` if the message is not signed yet.
@@ -232,10 +232,10 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
232
232
  if (message.authorization.ownerSignature !== undefined) {
233
233
  // if the message authorization contains owner delegated grant, the owner would be the grantor of the grant
234
234
  // else the owner would be the signer of the owner signature
235
- if (message.authorization.ownerDelegatedGrant !== undefined) {
236
- this._owner = Message.getSigner(message.authorization.ownerDelegatedGrant);
237
- } else {
235
+ if (message.authorization.ownerDelegatedGrant === undefined) {
238
236
  this._owner = Jws.getSignerDid(message.authorization.ownerSignature.signatures[0]);
237
+ } else {
238
+ this._owner = Message.getSigner(message.authorization.ownerDelegatedGrant);
239
239
  }
240
240
 
241
241
  this._ownerSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.ownerSignature);
@@ -321,7 +321,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
321
321
  protocol : normalizeProtocolUrl(options.protocol),
322
322
  protocolPath : options.protocolPath,
323
323
  recipient : options.recipient,
324
- schema : options.schema !== undefined ? normalizeSchemaUrl(options.schema) : undefined,
324
+ schema : options.schema === undefined ? undefined : normalizeSchemaUrl(options.schema),
325
325
  tags : options.tags,
326
326
  parentId : RecordsWrite.getRecordIdFromContextId(options.parentContextId),
327
327
  dataCid,
@@ -524,11 +524,11 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
524
524
  // compute delegated grant ID and author if delegated grant is given
525
525
  let delegatedGrantId;
526
526
  let authorDid;
527
- if (delegatedGrant !== undefined) {
527
+ if (delegatedGrant === undefined) {
528
+ authorDid = Jws.extractDid(signer.keyId);
529
+ } else {
528
530
  delegatedGrantId = await Message.getCid(delegatedGrant);
529
531
  authorDid = Jws.getSignerDid(delegatedGrant.authorization.signature.signatures[0]);
530
- } else {
531
- authorDid = Jws.extractDid(signer.keyId);
532
532
  }
533
533
 
534
534
  const descriptor = this._message.descriptor;
@@ -549,7 +549,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
549
549
  // `signature` generation
550
550
  const signature = await createSignerSignature({
551
551
  recordId : this._message.recordId,
552
- contextId : this._message.contextId!, // contextId is computed just above, always defined here
552
+ contextId : this._message.contextId, // contextId is computed just above, always defined here
553
553
  descriptorCid,
554
554
  attestation : this._message.attestation,
555
555
  encryption : this._message.encryption,
@@ -872,7 +872,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
872
872
  public static async fetchInitialRecordsWrite(
873
873
  messageStore: MessageStore, tenant: string, recordId: string
874
874
  ): Promise<RecordsWrite | undefined> {
875
- return fetchInitialRecordsWrite(messageStore, tenant, recordId) as Promise<RecordsWrite | undefined>;
875
+ return fetchInitialRecordsWrite(messageStore, tenant, recordId);
876
876
  }
877
877
 
878
878
  /** Delegate to `fetchInitialRecordsWriteMessage` in `records-write-query.ts`. */
@@ -4,7 +4,7 @@ import type { MessageSigner } from '../../../types/signer.js';
4
4
  import { Encoder } from '../../../utils/encoder.js';
5
5
 
6
6
  export class GeneralJwsBuilder {
7
- private jws: GeneralJws;
7
+ private readonly jws: GeneralJws;
8
8
 
9
9
  private constructor(jws: GeneralJws) {
10
10
  this.jws = jws;
@@ -1,7 +1,7 @@
1
1
  import type { Cache } from '../../../types/cache.js';
2
2
  import type { GeneralJws } from '../../../types/jws-types.js';
3
3
  import type { PublicKeyJwk } from '../../../types/jose-types.js';
4
- import type { DidResolver, DidVerificationMethod } from '@enbox/dids';
4
+ import type { DidResolutionResult, DidResolver, DidVerificationMethod } from '@enbox/dids';
5
5
 
6
6
  import { Encoder } from '../../../utils/encoder.js';
7
7
  import { Jws } from '../../../utils/jws.js';
@@ -89,12 +89,19 @@ export class GeneralJwsVerifier {
89
89
 
90
90
  /**
91
91
  * Gets the public key given a fully qualified key ID (`kid`) by resolving the DID to its DID Document.
92
+ *
93
+ * Throws `GeneralJwsVerifierGetPublicKeyNotFound` when the public key cannot be located.
94
+ * The error message distinguishes between two failure modes so callers can tell them apart:
95
+ * 1. DID resolution failed (network error, DID not published, method not supported, etc.).
96
+ * The resolution metadata error code and message are included.
97
+ * 2. DID resolved successfully but the requested `kid` does not match any verification
98
+ * method in the DID Document. The list of available verification method IDs is included.
92
99
  */
93
100
  private static async getPublicKey(kid: string, didResolver: DidResolver): Promise<PublicKeyJwk> {
94
101
  // `resolve` throws exception if DID is invalid, DID method is not supported,
95
102
  // or resolving DID fails
96
103
  const did = Jws.extractDid(kid);
97
- const { didDocument } = await didResolver.resolve(did);
104
+ const { didDocument, didResolutionMetadata } = await didResolver.resolve(did);
98
105
  const { verificationMethod: verificationMethods = [] } = didDocument || {};
99
106
 
100
107
  let verificationMethod: DidVerificationMethod | undefined;
@@ -110,7 +117,10 @@ export class GeneralJwsVerifier {
110
117
  }
111
118
 
112
119
  if (!verificationMethod) {
113
- throw new DwnError(DwnErrorCode.GeneralJwsVerifierGetPublicKeyNotFound, 'public key needed to verify signature not found in DID Document');
120
+ throw new DwnError(
121
+ DwnErrorCode.GeneralJwsVerifierGetPublicKeyNotFound,
122
+ GeneralJwsVerifier.buildPublicKeyNotFoundMessage(kid, did, didDocument, didResolutionMetadata, verificationMethods),
123
+ );
114
124
  }
115
125
 
116
126
  validateJsonSchema('JwkVerificationMethod', verificationMethod);
@@ -119,4 +129,35 @@ export class GeneralJwsVerifier {
119
129
 
120
130
  return publicJwk as PublicKeyJwk;
121
131
  }
132
+
133
+ /**
134
+ * Builds a diagnostic error message for `GeneralJwsVerifierGetPublicKeyNotFound`.
135
+ * Surfaces resolution metadata or available verification methods so operators can
136
+ * distinguish between an unreachable DID and a `kid` mismatch.
137
+ */
138
+ private static buildPublicKeyNotFoundMessage(
139
+ kid: string,
140
+ did: string,
141
+ didDocument: DidResolutionResult['didDocument'],
142
+ didResolutionMetadata: DidResolutionResult['didResolutionMetadata'] | undefined,
143
+ verificationMethods: DidVerificationMethod[],
144
+ ): string {
145
+ const resolutionError = didResolutionMetadata?.error;
146
+ if (resolutionError !== undefined) {
147
+ const resolutionErrorMessage = didResolutionMetadata?.errorMessage;
148
+ const detail = resolutionErrorMessage ? `${resolutionError} — ${resolutionErrorMessage}` : resolutionError;
149
+ return `unable to resolve DID '${did}' to verify signature with kid '${kid}': ${detail}`;
150
+ }
151
+
152
+ if (didDocument === undefined || didDocument === null) {
153
+ return `DID Document not found for '${did}' when verifying signature with kid '${kid}'`;
154
+ }
155
+
156
+ if (verificationMethods.length === 0) {
157
+ return `DID Document for '${did}' has no verification methods to verify signature with kid '${kid}'`;
158
+ }
159
+
160
+ const availableIds = verificationMethods.map((method) => method.id).join(', ');
161
+ return `public key for kid '${kid}' not found in DID Document for '${did}' (available verification methods: [${availableIds}])`;
162
+ }
122
163
  }
@@ -605,7 +605,7 @@ export class PermissionsProtocol implements CoreProtocol {
605
605
  */
606
606
  private static validateTags(requestOrGrant: RecordsWriteMessage, scopedProtocol: string): void {
607
607
  // the protocol tag must be included with the record.
608
- if (requestOrGrant.descriptor.tags === undefined || requestOrGrant.descriptor.tags.protocol === undefined) {
608
+ if (requestOrGrant.descriptor.tags?.protocol === undefined) {
609
609
  throw new DwnError(
610
610
  DwnErrorCode.PermissionsProtocolValidateScopeMissingProtocolTag,
611
611
  'Permission grants must have a `tags` property that contains a protocol tag'
@@ -31,7 +31,7 @@ type SerializedLeafNode = {
31
31
  type SerializedNode = SerializedInternalNode | SerializedLeafNode;
32
32
 
33
33
  export class SMTStoreLevel implements SMTNodeStore {
34
- private db: LevelWrapper<string>;
34
+ private readonly db: LevelWrapper<string>;
35
35
  private nodesPartition!: LevelWrapper<string>;
36
36
  private metaPartition!: LevelWrapper<string>;
37
37
  private initialized = false;
@@ -8,7 +8,7 @@ import type { Hash, SMTNode, SMTNodeStore } from '../types/smt-types.js';
8
8
  import { hashToHex } from './smt-utils.js';
9
9
 
10
10
  export class SMTStoreMemory implements SMTNodeStore {
11
- private nodes: Map<string, SMTNode> = new Map();
11
+ private readonly nodes: Map<string, SMTNode> = new Map();
12
12
  private root: Hash | undefined;
13
13
 
14
14
  async open(): Promise<void> {
@@ -19,7 +19,7 @@ import type { Hash, SMTDiffResult, SMTInternalNode, SMTLeafNode, SMTNodeStore, S
19
19
  import { getBit, hashChildren, hashEquals, hashKey, hashLeaf, initDefaultHashes, SMT_DEPTH } from './smt-utils.js';
20
20
 
21
21
  export class SparseMerkleTree {
22
- private store: SMTNodeStore;
22
+ private readonly store: SMTNodeStore;
23
23
  private defaultHashes!: Hash[];
24
24
 
25
25
  constructor(store: SMTNodeStore) {
@@ -142,13 +142,13 @@ export class SparseMerkleTree {
142
142
  // subtree hash would be if this leaf were pushed down to the prefix depth.
143
143
  // For simplicity, if we've hit a leaf, the subtree at this prefix
144
144
  // either contains this leaf or is empty.
145
- if (node !== undefined && node.type === 'leaf') {
145
+ if (node?.type === 'leaf') {
146
146
  return this.computeSubtreeHashForLeaf(node, i, prefix);
147
147
  }
148
148
  return this.defaultHashes[prefix.length];
149
149
  }
150
150
 
151
- const internalNode = node as SMTInternalNode;
151
+ const internalNode = node;
152
152
  if (prefix[i]) {
153
153
  currentHash = internalNode.rightHash;
154
154
  } else {
@@ -186,7 +186,7 @@ export class SparseMerkleTree {
186
186
  return [];
187
187
  }
188
188
 
189
- const internalNode = node as SMTInternalNode;
189
+ const internalNode = node;
190
190
  if (prefix[i]) {
191
191
  currentHash = internalNode.rightHash;
192
192
  } else {
@@ -266,7 +266,7 @@ export class SparseMerkleTree {
266
266
  }
267
267
 
268
268
  // Internal node — recurse into the appropriate child
269
- const internalNode = node as SMTInternalNode;
269
+ const internalNode = node;
270
270
  const goRight = getBit(keyHash, depth);
271
271
 
272
272
  let newLeftHash: Hash;
@@ -405,7 +405,7 @@ export class SparseMerkleTree {
405
405
  }
406
406
 
407
407
  // Internal node — recurse into the appropriate child
408
- const internalNode = node as SMTInternalNode;
408
+ const internalNode = node;
409
409
  const goRight = getBit(keyHash, depth);
410
410
 
411
411
  let newLeftHash: Hash;
@@ -433,7 +433,7 @@ export class SparseMerkleTree {
433
433
  if (leftIsDefault || rightIsDefault) {
434
434
  const survivingHash = leftIsDefault ? newRightHash : newLeftHash;
435
435
  const survivingNode = await this.store.getNode(survivingHash);
436
- if (survivingNode !== undefined && survivingNode.type === 'leaf') {
436
+ if (survivingNode?.type === 'leaf') {
437
437
  // Collapse: remove the internal node, return the leaf hash directly
438
438
  await this.store.deleteNode(currentHash);
439
439
  return survivingHash;
@@ -477,7 +477,7 @@ export class SparseMerkleTree {
477
477
  return hashEquals(node.keyHash, keyHash);
478
478
  }
479
479
 
480
- const internalNode = node as SMTInternalNode;
480
+ const internalNode = node;
481
481
  const goRight = getBit(keyHash, depth);
482
482
 
483
483
  if (goRight) {
@@ -508,7 +508,7 @@ export class SparseMerkleTree {
508
508
  return { siblings: [], leafNode: node, depth };
509
509
  }
510
510
 
511
- const internalNode = node as SMTInternalNode;
511
+ const internalNode = node;
512
512
  const goRight = getBit(keyHash, depth);
513
513
 
514
514
  let childHash: Hash;
@@ -578,7 +578,7 @@ export class SparseMerkleTree {
578
578
  return [node.valueCid];
579
579
  }
580
580
 
581
- const internalNode = node as SMTInternalNode;
581
+ const internalNode = node;
582
582
  const leftLeaves = await this.collectLeaves(internalNode.leftHash, depth + 1);
583
583
  const rightLeaves = await this.collectLeaves(internalNode.rightHash, depth + 1);
584
584
 
@@ -28,7 +28,7 @@ export type StateIndexLevelConfig = {
28
28
  };
29
29
 
30
30
  export class StateIndexLevel implements StateIndex {
31
- private config: StateIndexLevelConfig;
31
+ private readonly config: StateIndexLevelConfig;
32
32
  private db!: LevelWrapper<string>;
33
33
 
34
34
  /**
@@ -36,13 +36,13 @@ export class StateIndexLevel implements StateIndex {
36
36
  * Stores promises to avoid race conditions when multiple concurrent operations
37
37
  * trigger lazy initialization of the same tenant's SMT.
38
38
  */
39
- private globalTrees: Map<string, Promise<SparseMerkleTree>> = new Map();
39
+ private readonly globalTrees: Map<string, Promise<SparseMerkleTree>> = new Map();
40
40
 
41
41
  /**
42
42
  * Cache of per-tenant, per-protocol SMTs. Key format: `{tenant}\x00{protocol}`
43
43
  * Stores promises to avoid race conditions (same reason as globalTrees).
44
44
  */
45
- private protocolTrees: Map<string, Promise<SparseMerkleTree>> = new Map();
45
+ private readonly protocolTrees: Map<string, Promise<SparseMerkleTree>> = new Map();
46
46
 
47
47
  constructor(config?: StateIndexLevelConfig) {
48
48
  this.config = {
@@ -203,28 +203,28 @@ export async function queryWithCompoundIndex(
203
203
  // determine the iterator bounds from the prefix
204
204
  const iteratorOptions: LevelWrapperIteratorOptions<string> = {};
205
205
 
206
- if (cursor !== undefined) {
207
- // build the full compound key for the cursor position
208
- const cursorSortEncoded = encodeValue(cursor.value);
209
- const cursorKey = prefix + cursorSortEncoded + delimiter + cursor.messageCid;
210
-
206
+ if (cursor === undefined) {
211
207
  if (sortDirection === SortDirection.Ascending) {
212
- iteratorOptions.gt = cursorKey;
213
- // upper bound: everything with this prefix (prefix + \xff is past all valid compound keys with this prefix)
208
+ iteratorOptions.gt = prefix;
214
209
  iteratorOptions.lt = prefix + '\xff';
215
210
  } else {
216
- iteratorOptions.lt = cursorKey;
211
+ // for descending without cursor, start from the end of the prefix range
217
212
  iteratorOptions.gt = prefix;
213
+ iteratorOptions.lt = prefix + '\xff';
218
214
  iteratorOptions.reverse = true;
219
215
  }
220
216
  } else {
217
+ // build the full compound key for the cursor position
218
+ const cursorSortEncoded = encodeValue(cursor.value);
219
+ const cursorKey = prefix + cursorSortEncoded + delimiter + cursor.messageCid;
220
+
221
221
  if (sortDirection === SortDirection.Ascending) {
222
- iteratorOptions.gt = prefix;
222
+ iteratorOptions.gt = cursorKey;
223
+ // upper bound: everything with this prefix (prefix + \xff is past all valid compound keys with this prefix)
223
224
  iteratorOptions.lt = prefix + '\xff';
224
225
  } else {
225
- // for descending without cursor, start from the end of the prefix range
226
+ iteratorOptions.lt = cursorKey;
226
227
  iteratorOptions.gt = prefix;
227
- iteratorOptions.lt = prefix + '\xff';
228
228
  iteratorOptions.reverse = true;
229
229
  }
230
230
  }
@@ -53,7 +53,7 @@ export interface IndexLevelOptions {
53
53
  export class IndexLevel {
54
54
  db: LevelWrapper<string>;
55
55
  config: IndexLevelConfig;
56
- private _compoundIndexes: CompoundIndexDefinition[];
56
+ private readonly _compoundIndexes: CompoundIndexDefinition[];
57
57
 
58
58
  constructor(config: IndexLevelConfig) {
59
59
  this.config = {
@@ -498,13 +498,13 @@ export class IndexLevel {
498
498
 
499
499
  const sortedValues = [...matches.values()].sort((a,b) => this.sortItems(a,b, sortProperty, sortDirection));
500
500
 
501
- const start = cursorStartingKey !== undefined ? this.findCursorStartingIndex(sortedValues, sortDirection, sortProperty, cursorStartingKey) : 0;
501
+ const start = cursorStartingKey === undefined ? 0 : this.findCursorStartingIndex(sortedValues, sortDirection, sortProperty, cursorStartingKey);
502
502
  if (start < 0) {
503
503
  // if the provided cursor does not come before any of the results, we return no results
504
504
  return [];
505
505
  }
506
506
 
507
- const end = limit !== undefined ? start + limit: undefined;
507
+ const end = limit === undefined ? undefined : start + limit;
508
508
  return sortedValues.slice(start, end);
509
509
  }
510
510
 
@@ -735,7 +735,7 @@ export class IndexLevel {
735
735
  /**
736
736
  * Joins the given values using the `\x00` (\u0000) character.
737
737
  */
738
- private static delimiter = `\x00`;
738
+ private static readonly delimiter = `\x00`;
739
739
  private static keySegmentJoin(...values: string[]): string {
740
740
  return values.join(IndexLevel.delimiter);
741
741
  }
@@ -183,7 +183,7 @@ export class LevelWrapper<V> {
183
183
  }
184
184
 
185
185
  async isEmpty(options?: LevelWrapperOptions): Promise<boolean> {
186
- for await (const _key of this.keys(options)) {
186
+ for await (const _key of this.keys(options)) { // NOSONAR — intentional single-iteration check
187
187
  return false;
188
188
  }
189
189
  return true;