@wishknish/knishio-client-js 0.6.4 → 0.7.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 (121) hide show
  1. package/dist/client.cjs.js +567 -0
  2. package/dist/client.cjs.js.map +1 -0
  3. package/dist/client.es.mjs +8665 -0
  4. package/dist/client.es.mjs.map +1 -0
  5. package/dist/client.iife.js +84 -45
  6. package/dist/client.iife.js.map +1 -0
  7. package/package.json +48 -28
  8. package/src/Atom.js +132 -5
  9. package/src/AtomMeta.js +7 -8
  10. package/src/AuthToken.js +1 -1
  11. package/src/KnishIOClient.js +180 -78
  12. package/src/Meta.js +6 -2
  13. package/src/Molecule.js +383 -44
  14. package/src/PolicyMeta.js +1 -1
  15. package/src/Wallet.js +67 -12
  16. package/src/exception/AtomIndexException.js +1 -1
  17. package/src/exception/AtomsMissingException.js +1 -1
  18. package/src/exception/AuthorizationRejectedException.js +1 -1
  19. package/src/exception/BalanceInsufficientException.js +1 -1
  20. package/src/exception/BatchIdException.js +1 -1
  21. package/src/exception/CodeException.js +1 -1
  22. package/src/exception/DecryptionKeyException.js +1 -1
  23. package/src/exception/InvalidResponseException.js +1 -1
  24. package/src/exception/MetaMissingException.js +1 -1
  25. package/src/exception/MolecularHashMismatchException.js +1 -1
  26. package/src/exception/MolecularHashMissingException.js +1 -1
  27. package/src/exception/NegativeAmountException.js +1 -1
  28. package/src/exception/PolicyInvalidException.js +1 -1
  29. package/src/exception/SignatureMalformedException.js +1 -1
  30. package/src/exception/SignatureMismatchException.js +1 -1
  31. package/src/exception/StackableUnitAmountException.js +1 -1
  32. package/src/exception/StackableUnitDecimalsException.js +1 -1
  33. package/src/exception/TransferBalanceException.js +1 -1
  34. package/src/exception/TransferMalformedException.js +1 -1
  35. package/src/exception/TransferMismatchedException.js +1 -1
  36. package/src/exception/TransferRemainderException.js +1 -1
  37. package/src/exception/TransferToSelfException.js +1 -1
  38. package/src/exception/TransferUnbalancedException.js +1 -1
  39. package/src/exception/UnauthenticatedException.js +1 -1
  40. package/src/exception/WalletCredentialException.js +1 -1
  41. package/src/exception/WalletShadowException.js +1 -1
  42. package/src/exception/WrongTokenTypeException.js +1 -1
  43. package/src/exception/index.js +25 -25
  44. package/src/index.js +29 -9
  45. package/src/instance/Rules/Callback.js +5 -5
  46. package/src/instance/Rules/Condition.js +1 -1
  47. package/src/instance/Rules/Rule.js +4 -4
  48. package/src/instance/Rules/exception/RuleArgumentException.js +1 -1
  49. package/src/libraries/CheckMolecule.js +285 -27
  50. package/src/libraries/crypto.js +16 -2
  51. package/src/libraries/strings.js +1 -1
  52. package/src/libraries/urql/UrqlClientWrapper.js +3 -1
  53. package/src/mutation/Mutation.js +2 -2
  54. package/src/mutation/MutationActiveSession.js +2 -2
  55. package/src/mutation/MutationAppendRequest.js +91 -0
  56. package/src/mutation/MutationClaimShadowWallet.js +3 -3
  57. package/src/mutation/MutationCreateIdentifier.js +2 -2
  58. package/src/mutation/MutationCreateMeta.js +2 -2
  59. package/src/mutation/MutationCreateRule.js +2 -2
  60. package/src/mutation/MutationCreateToken.js +2 -2
  61. package/src/mutation/MutationCreateWallet.js +2 -2
  62. package/src/mutation/MutationDepositBufferToken.js +1 -1
  63. package/src/mutation/MutationLinkIdentifier.js +2 -2
  64. package/src/mutation/MutationPeering.js +82 -0
  65. package/src/mutation/MutationProposeMolecule.js +2 -2
  66. package/src/mutation/MutationRequestAuthorization.js +2 -2
  67. package/src/mutation/MutationRequestAuthorizationGuest.js +2 -2
  68. package/src/mutation/MutationRequestTokens.js +2 -2
  69. package/src/mutation/MutationTransferTokens.js +2 -2
  70. package/src/mutation/MutationWithdrawBufferToken.js +1 -1
  71. package/src/query/Query.js +2 -2
  72. package/src/query/QueryActiveSession.js +2 -2
  73. package/src/query/QueryAtom.js +2 -2
  74. package/src/query/QueryBalance.js +2 -2
  75. package/src/query/QueryBatch.js +2 -2
  76. package/src/query/QueryBatchHistory.js +3 -3
  77. package/src/query/QueryContinuId.js +2 -2
  78. package/src/query/QueryMetaType.js +11 -5
  79. package/src/query/QueryMetaTypeViaAtom.js +11 -4
  80. package/src/query/QueryMetaTypeViaMolecule.js +223 -0
  81. package/src/query/QueryPolicy.js +2 -2
  82. package/src/query/QueryToken.js +2 -2
  83. package/src/query/QueryUserActivity.js +2 -2
  84. package/src/query/QueryWalletBundle.js +2 -2
  85. package/src/query/QueryWalletList.js +2 -2
  86. package/src/response/Response.js +168 -4
  87. package/src/response/ResponseActiveSession.js +2 -2
  88. package/src/response/{ResponseMetaBatch.js → ResponseAppendRequest.js} +4 -21
  89. package/src/response/ResponseAtom.js +2 -2
  90. package/src/response/ResponseAuthorizationGuest.js +4 -4
  91. package/src/response/ResponseBalance.js +9 -4
  92. package/src/response/ResponseClaimShadowWallet.js +1 -1
  93. package/src/response/ResponseContinuId.js +4 -4
  94. package/src/response/ResponseCreateIdentifier.js +1 -1
  95. package/src/response/ResponseCreateMeta.js +1 -1
  96. package/src/response/ResponseCreateRule.js +1 -1
  97. package/src/response/ResponseCreateToken.js +1 -1
  98. package/src/response/ResponseCreateWallet.js +1 -1
  99. package/src/response/ResponseLinkIdentifier.js +3 -3
  100. package/src/response/ResponseMetaType.js +2 -2
  101. package/src/response/ResponseMetaTypeViaAtom.js +2 -2
  102. package/src/response/ResponseMetaTypeViaMolecule.js +210 -0
  103. package/src/response/ResponsePeering.js +55 -0
  104. package/src/response/ResponsePolicy.js +2 -2
  105. package/src/response/ResponseProposeMolecule.js +3 -3
  106. package/src/response/ResponseQueryActiveSession.js +2 -2
  107. package/src/response/ResponseQueryUserActivity.js +2 -2
  108. package/src/response/ResponseRequestAuthorization.js +3 -3
  109. package/src/response/ResponseRequestAuthorizationGuest.js +3 -3
  110. package/src/response/ResponseRequestTokens.js +1 -1
  111. package/src/response/ResponseTransferTokens.js +1 -1
  112. package/src/response/ResponseWalletBundle.js +3 -3
  113. package/src/response/ResponseWalletList.js +5 -5
  114. package/src/subscribe/ActiveSessionSubscribe.js +1 -1
  115. package/src/subscribe/ActiveWalletSubscribe.js +1 -1
  116. package/src/subscribe/CreateMoleculeSubscribe.js +1 -1
  117. package/src/subscribe/Subscribe.js +1 -1
  118. package/src/subscribe/WalletStatusSubscribe.js +1 -1
  119. package/src/types/index.js +2 -2
  120. package/src/versions/Version4.js +1 -1
  121. package/src/versions/index.js +1 -1
@@ -45,9 +45,9 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import InvalidResponseException from '../exception/InvalidResponseException'
49
- import UnauthenticatedException from '../exception/UnauthenticatedException'
50
- import Dot from '../libraries/Dot'
48
+ import InvalidResponseException from '../exception/InvalidResponseException.js'
49
+ import UnauthenticatedException from '../exception/UnauthenticatedException.js'
50
+ import Dot from '../libraries/Dot.js'
51
51
 
52
52
  /**
53
53
  * Base Response class for processing node responses
@@ -86,6 +86,17 @@ export default class Response {
86
86
  throw new InvalidResponseException()
87
87
  }
88
88
 
89
+ // Check for GraphQL errors array
90
+ if (this.$__response.errors && Array.isArray(this.$__response.errors) && this.$__response.errors.length > 0) {
91
+ const errorMessage = this.$__response.errors[0].message || 'Unknown GraphQL error'
92
+
93
+ if (errorMessage.includes('Unauthenticated')) {
94
+ throw new UnauthenticatedException()
95
+ }
96
+
97
+ throw new InvalidResponseException(`GraphQL Error: ${errorMessage}`)
98
+ }
99
+
89
100
  this.init()
90
101
  }
91
102
 
@@ -103,9 +114,14 @@ export default class Response {
103
114
  return this.response()
104
115
  }
105
116
 
117
+ // Check if response has data field
118
+ if (!this.response().data) {
119
+ throw new InvalidResponseException('Response has no data field')
120
+ }
121
+
106
122
  // Check key & return custom data from the response
107
123
  if (!Dot.has(this.response(), this.dataKey)) {
108
- throw new InvalidResponseException()
124
+ throw new InvalidResponseException(`Missing expected field: ${this.dataKey}`)
109
125
  }
110
126
 
111
127
  return Dot.get(this.response(), this.dataKey)
@@ -138,4 +154,152 @@ export default class Response {
138
154
  status () {
139
155
  return null
140
156
  }
157
+
158
+ /**
159
+ * Check if response was successful
160
+ * @return {boolean}
161
+ */
162
+ success () {
163
+ // Default implementation - can be overridden by subclasses
164
+ return !this.$__response?.errors?.length
165
+ }
166
+
167
+ /**
168
+ * Get error message if any
169
+ *
170
+ * @return {string|null}
171
+ */
172
+ error () {
173
+ return this.$__response?.errors?.length ? this.$__response.errors[0].message || 'Unknown error' : null
174
+ }
175
+
176
+ /**
177
+ * Enhanced interface methods for standardized response handling
178
+ */
179
+
180
+ /**
181
+ * Get error reason (alias for error() to match standardized interface)
182
+ * @return {string|null}
183
+ */
184
+ reason () {
185
+ return this.error()
186
+ }
187
+
188
+ /**
189
+ * Convert to ValidationResult for enhanced error handling
190
+ * @return {object}
191
+ */
192
+ toValidationResult () {
193
+ if (this.success() && this.payload() !== null) {
194
+ return {
195
+ success: true,
196
+ data: this.payload(),
197
+ warnings: []
198
+ }
199
+ } else {
200
+ return {
201
+ success: false,
202
+ error: {
203
+ message: this.reason() || 'Unknown error',
204
+ context: this.constructor.name,
205
+ details: this.$__response?.errors || []
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Enhanced error handling with callbacks
213
+ * @param {function} callback
214
+ * @return {Response}
215
+ */
216
+ onSuccess (callback) {
217
+ if (this.success() && this.payload() !== null) {
218
+ try {
219
+ callback(this.payload())
220
+ } catch (error) {
221
+ console.warn('Response.onSuccess callback failed:', error)
222
+ }
223
+ }
224
+ return this
225
+ }
226
+
227
+ /**
228
+ * Enhanced failure handling with callbacks
229
+ * @param {function} callback
230
+ * @return {Response}
231
+ */
232
+ onFailure (callback) {
233
+ if (!this.success()) {
234
+ try {
235
+ callback(this.reason() || 'Unknown error')
236
+ } catch (error) {
237
+ console.warn('Response.onFailure callback failed:', error)
238
+ }
239
+ }
240
+ return this
241
+ }
242
+
243
+ /**
244
+ * Debug logging with enhanced context
245
+ * @param {string|null} label
246
+ * @return {Response}
247
+ */
248
+ debug (label = null) {
249
+ const debugPrefix = label ? `[${label}]` : `[${this.constructor.name}]`
250
+
251
+ if (this.success()) {
252
+ console.debug(`${debugPrefix} Success:`, {
253
+ payload: this.payload(),
254
+ query: this.$__query?.constructor?.name,
255
+ dataKey: this.dataKey
256
+ })
257
+ } else {
258
+ console.debug(`${debugPrefix} Failure:`, {
259
+ error: this.reason(),
260
+ errors: this.$__response?.errors,
261
+ rawData: this.$__response
262
+ })
263
+ }
264
+
265
+ return this
266
+ }
267
+
268
+ /**
269
+ * Promise conversion for enhanced async patterns
270
+ * @return {Promise}
271
+ */
272
+ toPromise () {
273
+ if (this.success() && this.payload() !== null) {
274
+ return Promise.resolve(this.payload())
275
+ } else {
276
+ return Promise.reject(new Error(this.reason() || 'Unknown error'))
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Functional programming map operation
282
+ * @param {function} mapper
283
+ * @return {Response}
284
+ */
285
+ map (mapper) {
286
+ if (this.success() && this.payload() !== null) {
287
+ try {
288
+ const mappedPayload = mapper(this.payload())
289
+ // Create new response with mapped payload
290
+ const newResponse = Object.create(Object.getPrototypeOf(this))
291
+ Object.assign(newResponse, this)
292
+ newResponse.$__payload = mappedPayload
293
+ return newResponse
294
+ } catch (error) {
295
+ // Create error response
296
+ const errorResponse = Object.create(Object.getPrototypeOf(this))
297
+ Object.assign(errorResponse, this)
298
+ errorResponse.$__response = { errors: [{ message: `Mapping failed: ${error.message}` }] }
299
+ return errorResponse
300
+ }
301
+ } else {
302
+ return this
303
+ }
304
+ }
141
305
  }
@@ -46,8 +46,8 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
48
 
49
- import Query from '../query/Query'
50
- import Response from './Response'
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
51
 
52
52
  export default class ResponseActiveSession extends Response {
53
53
  /**
@@ -45,28 +45,11 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
-
49
- import Query from '../query/Query'
50
- import Response from './Response'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
51
49
 
52
50
  /**
53
- * Response for MetaBatch Query
51
+ * Response for append requests via A-isotope
54
52
  */
55
- export default class ResponseMetaBatch extends Response {
56
- /**
57
- * Class constructor
58
- *
59
- * @param {Query} query
60
- * @param {object} json
61
- */
62
- constructor ({
63
- query,
64
- json
65
- }) {
66
- super({
67
- query,
68
- json,
69
- dataKey: 'data.MetaBatch'
70
- })
71
- }
53
+ export default class ResponseAppendRequest extends ResponseProposeMolecule {
54
+
72
55
  }
@@ -46,8 +46,8 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
48
 
49
- import Query from '../query/Query'
50
- import Response from './Response'
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
51
 
52
52
  /**
53
53
  * Response for MetaType Query
@@ -46,10 +46,10 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
48
 
49
- import Query from '../query/Query'
50
- import Response from './Response'
51
- import Dot from '../libraries/Dot'
52
- import InvalidResponseException from '../exception/InvalidResponseException'
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
+ import Dot from '../libraries/Dot.js'
52
+ import InvalidResponseException from '../exception/InvalidResponseException.js'
53
53
 
54
54
  /**
55
55
  * Response for Guest Authorization Request
@@ -45,9 +45,9 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import Query from '../query/Query'
49
- import Response from './Response'
50
- import ResponseWalletList from './ResponseWalletList'
48
+ import Query from '../query/Query.js'
49
+ import Response from './Response.js'
50
+ import ResponseWalletList from './ResponseWalletList.js'
51
51
 
52
52
  /**
53
53
  * Response for balance query
@@ -76,7 +76,12 @@ export default class ResponseBalance extends Response {
76
76
  * @return {null|Wallet}
77
77
  */
78
78
  payload () {
79
- const walletData = this.data()
79
+ let walletData = this.data()
80
+
81
+ // Handle array response (e.g. from Rust validator which returns Vec<Wallet>)
82
+ if (Array.isArray(walletData)) {
83
+ walletData = walletData.length > 0 ? walletData[0] : null
84
+ }
80
85
 
81
86
  if (!walletData || !walletData.bundleHash || !walletData.tokenSlug) {
82
87
  return null
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for identifier creation
@@ -45,9 +45,9 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import Query from '../query/Query'
49
- import Response from './Response'
50
- import Wallet from '../Wallet'
48
+ import Query from '../query/Query.js'
49
+ import Response from './Response.js'
50
+ import Wallet from '../Wallet.js'
51
51
 
52
52
  /**
53
53
  * Response for ContinuID query
@@ -91,7 +91,7 @@ export default class ResponseContinuId extends Response {
91
91
  wallet.batchId = continuId.batchId
92
92
  wallet.characters = continuId.characters
93
93
  wallet.pubkey = continuId.pubkey
94
- wallet.balance = continuId.amount * 1.0
94
+ wallet.balance = String(continuId.amount != null ? continuId.amount : 0)
95
95
  }
96
96
 
97
97
  return wallet
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for identifier creation
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for token creation
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for rule creation
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for token creation
@@ -45,7 +45,7 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import ResponseProposeMolecule from './ResponseProposeMolecule'
48
+ import ResponseProposeMolecule from './ResponseProposeMolecule.js'
49
49
 
50
50
  /**
51
51
  * Response for Wallet creation
@@ -45,9 +45,9 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
45
 
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
- import Query from '../query/Query'
49
- import Response from './Response'
50
- import Dot from '../libraries/Dot'
48
+ import Query from '../query/Query.js'
49
+ import Response from './Response.js'
50
+ import Dot from '../libraries/Dot.js'
51
51
 
52
52
  /**
53
53
  * Response for mutation to create / link an Identifier to a Wallet Bundle
@@ -46,8 +46,8 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
48
 
49
- import Query from '../query/Query'
50
- import Response from './Response'
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
51
 
52
52
  /**
53
53
  * Response for MetaType Query
@@ -46,8 +46,8 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
46
46
  License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
47
  */
48
48
 
49
- import Query from '../query/Query'
50
- import Response from './Response'
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
51
 
52
52
  export default class ResponseMetaTypeViaAtom extends Response {
53
53
  /**
@@ -0,0 +1,210 @@
1
+ /*
2
+ (
3
+ (/(
4
+ (//(
5
+ (///(
6
+ (/////(
7
+ (//////( )
8
+ (////////( (/)
9
+ (////////( (///)
10
+ (//////////( (////)
11
+ (//////////( (//////)
12
+ (////////////( (///////)
13
+ (/////////////( (/////////)
14
+ (//////////////( (///////////)
15
+ (///////////////( (//////////////)
16
+ (////////////////( (///////////////)
17
+ ((((((((((((((((((( (((((((((((((((
18
+ ((((((((((((((((((( ((((((((((((((
19
+ ((((((((((((((((((( ((((((((((((((
20
+ (((((((((((((((((((( (((((((((((((
21
+ (((((((((((((((((((( ((((((((((((
22
+ ((((((((((((((((((( ((((((((((((
23
+ ((((((((((((((((((( ((((((((((
24
+ ((((((((((((((((((/ (((((((((
25
+ (((((((((((((((((( ((((((((
26
+ ((((((((((((((((( (((((((
27
+ (((((((((((((((((( (((((
28
+ ################# ##
29
+ ################ #
30
+ ################# ##
31
+ %################ ###
32
+ ###############( ####
33
+ ############### ####
34
+ ############### ######
35
+ %#############( (#######
36
+ %############# #########
37
+ ############( ##########
38
+ ########### #############
39
+ ######### ##############
40
+ %######
41
+
42
+ Powered by Knish.IO: Connecting a Decentralized World
43
+
44
+ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
45
+
46
+ License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
47
+ */
48
+
49
+ import Query from '../query/Query.js'
50
+ import Response from './Response.js'
51
+ import CheckMolecule from '../libraries/CheckMolecule.js'
52
+
53
+ /**
54
+ * Response for MetaType queries via Molecule data.
55
+ *
56
+ * Instead of using the redundant instance-level `metas` field,
57
+ * this response extracts metadata from molecule atoms' `metasJson`,
58
+ * producing a payload format compatible with ResponseMetaType and
59
+ * ResponseMetaTypeViaAtom for drop-in replacement usage.
60
+ */
61
+ export default class ResponseMetaTypeViaMolecule extends Response {
62
+ /**
63
+ * Class constructor
64
+ *
65
+ * @param {Query} query
66
+ * @param {object} json
67
+ */
68
+ constructor ({
69
+ query,
70
+ json
71
+ }) {
72
+ super({
73
+ query,
74
+ json,
75
+ dataKey: 'data.MetaTypeViaAtom'
76
+ })
77
+ }
78
+
79
+ /**
80
+ * Extracts metas from a molecule's atoms' metasJson for a specific instance.
81
+ * Filters atoms by matching metaType and metaId, then parses metasJson.
82
+ *
83
+ * @param {object} molecule - Molecule data with atoms array
84
+ * @param {string} metaType - Instance meta type to filter by
85
+ * @param {string} metaId - Instance meta ID to filter by
86
+ * @return {Array<{molecularHash: string, position: string, key: string, value: string, createdAt: string}>}
87
+ */
88
+ static extractMetasFromMolecule (molecule, metaType, metaId) {
89
+ if (!molecule || !molecule.atoms) {
90
+ return []
91
+ }
92
+
93
+ const metas = []
94
+
95
+ for (const atom of molecule.atoms) {
96
+ // Filter atoms to those matching this instance's metaType and metaId
97
+ if (atom.metaType !== metaType || atom.metaId !== metaId) {
98
+ continue
99
+ }
100
+
101
+ if (!atom.metasJson) {
102
+ continue
103
+ }
104
+
105
+ let parsed
106
+ try {
107
+ parsed = JSON.parse(atom.metasJson)
108
+ if (!Array.isArray(parsed)) {
109
+ continue
110
+ }
111
+ } catch (e) {
112
+ continue
113
+ }
114
+
115
+ for (const entry of parsed) {
116
+ metas.push({
117
+ molecularHash: molecule.molecularHash,
118
+ position: atom.position,
119
+ key: entry.key,
120
+ value: entry.value,
121
+ createdAt: atom.createdAt
122
+ })
123
+ }
124
+ }
125
+
126
+ return metas
127
+ }
128
+
129
+ /**
130
+ * Returns meta type instance results with metas synthesized from molecule data.
131
+ * Produces the same payload format as ResponseMetaType and ResponseMetaTypeViaAtom:
132
+ * { instances, instanceCount, paginatorInfo }
133
+ *
134
+ * @return {null|{instances: Array, instanceCount: Array, paginatorInfo: object}}
135
+ */
136
+ payload () {
137
+ const metaTypeData = this.data()
138
+
139
+ if (!metaTypeData || metaTypeData.length === 0) {
140
+ return null
141
+ }
142
+
143
+ const response = {
144
+ instances: {},
145
+ instanceCount: {},
146
+ paginatorInfo: {}
147
+ }
148
+
149
+ const metaData = metaTypeData.pop()
150
+
151
+ if (metaData.instances) {
152
+ response.instances = metaData.instances.map(instance => {
153
+ // Prefer server-filtered metas (from metas sub-field) when available
154
+ let metas = instance.metas
155
+ if (!metas || metas.length === 0) {
156
+ // Fallback: synthesize from molecule atoms' metasJson
157
+ metas = ResponseMetaTypeViaMolecule.extractMetasFromMolecule(
158
+ instance.molecule,
159
+ instance.metaType,
160
+ instance.metaId
161
+ )
162
+ }
163
+
164
+ return {
165
+ ...instance,
166
+ metas
167
+ }
168
+ })
169
+ }
170
+
171
+ if (metaData.instanceCount) {
172
+ response.instanceCount = metaData.instanceCount
173
+ }
174
+
175
+ if (metaData.paginatorInfo) {
176
+ response.paginatorInfo = metaData.paginatorInfo
177
+ }
178
+
179
+ return response
180
+ }
181
+
182
+ /**
183
+ * Verifies the cryptographic integrity of all molecules associated
184
+ * with meta instances in this response. For each instance, reconstructs
185
+ * the molecule from server data and runs CheckMolecule.verify() to validate
186
+ * the molecular hash and OTS signature.
187
+ *
188
+ * @return {{ verified: boolean, molecules: Array<{ molecularHash: string, verified: boolean, error: string|null }> }}
189
+ */
190
+ verifyIntegrity () {
191
+ const results = []
192
+ const metaTypeData = this.data()
193
+
194
+ if (!metaTypeData || metaTypeData.length === 0) {
195
+ return { verified: true, molecules: results }
196
+ }
197
+
198
+ const instances = metaTypeData[metaTypeData.length - 1]?.instances || []
199
+
200
+ for (const instance of instances) {
201
+ if (!instance.molecule) continue
202
+ results.push(CheckMolecule.verifyFromServerData(instance.molecule))
203
+ }
204
+
205
+ return {
206
+ verified: results.length === 0 || results.every(r => r.verified),
207
+ molecules: results
208
+ }
209
+ }
210
+ }