@wishknish/knishio-client-ts 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +425 -0
- package/dist/index.cjs +9961 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.iife.js +32241 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.js +9853 -0
- package/dist/index.js.map +1 -0
- package/package.json +113 -0
- package/src/AuthToken.ts +214 -0
- package/src/KnishIOClient.ts +2020 -0
- package/src/constants.ts +398 -0
- package/src/core/Atom.ts +646 -0
- package/src/core/AtomMeta.ts +278 -0
- package/src/core/Meta.ts +428 -0
- package/src/core/Molecule.ts +825 -0
- package/src/core/PolicyMeta.ts +130 -0
- package/src/core/TokenUnit.ts +148 -0
- package/src/core/Wallet.ts +467 -0
- package/src/exception/AtomIndexException.ts +97 -0
- package/src/exception/AtomsMissingException.ts +109 -0
- package/src/exception/AuthorizationRejectedException.ts +63 -0
- package/src/exception/BalanceInsufficientException.ts +58 -0
- package/src/exception/BaseException.ts +275 -0
- package/src/exception/BatchIdException.ts +58 -0
- package/src/exception/CodeException.ts +119 -0
- package/src/exception/DecryptionKeyException.ts +65 -0
- package/src/exception/InvalidResponseException.ts +112 -0
- package/src/exception/MetaMissingException.ts +58 -0
- package/src/exception/MolecularHashMismatchException.ts +115 -0
- package/src/exception/MolecularHashMissingException.ts +58 -0
- package/src/exception/NegativeAmountException.ts +58 -0
- package/src/exception/PolicyInvalidException.ts +58 -0
- package/src/exception/SignatureMalformedException.ts +58 -0
- package/src/exception/SignatureMismatchException.ts +98 -0
- package/src/exception/StackableUnitAmountException.ts +65 -0
- package/src/exception/StackableUnitDecimalsException.ts +65 -0
- package/src/exception/TransferBalanceException.ts +98 -0
- package/src/exception/TransferMalformedException.ts +58 -0
- package/src/exception/TransferMismatchedException.ts +58 -0
- package/src/exception/TransferRemainderException.ts +58 -0
- package/src/exception/TransferToSelfException.ts +58 -0
- package/src/exception/TransferUnbalancedException.ts +58 -0
- package/src/exception/UnauthenticatedException.ts +147 -0
- package/src/exception/WalletCredentialException.ts +108 -0
- package/src/exception/WalletShadowException.ts +65 -0
- package/src/exception/WrongTokenTypeException.ts +58 -0
- package/src/exception/index.ts +272 -0
- package/src/index.ts +512 -0
- package/src/instance/rules/Callback.ts +257 -0
- package/src/instance/rules/Condition.ts +96 -0
- package/src/instance/rules/Meta.ts +163 -0
- package/src/instance/rules/Rule.ts +29 -0
- package/src/instance/rules/exception/RuleArgumentException.ts +65 -0
- package/src/libraries/CheckMolecule.ts +581 -0
- package/src/libraries/Decimal.ts +94 -0
- package/src/libraries/Dot.ts +202 -0
- package/src/libraries/GraphQLClient.ts +276 -0
- package/src/libraries/Hex.ts +155 -0
- package/src/libraries/UrqlClientWrapper.ts +336 -0
- package/src/libraries/array.ts +91 -0
- package/src/libraries/crypto.ts +816 -0
- package/src/libraries/strings.ts +458 -0
- package/src/mutation/Mutation.ts +103 -0
- package/src/mutation/MutationActiveSession.ts +108 -0
- package/src/mutation/MutationClaimShadowWallet.ts +91 -0
- package/src/mutation/MutationCreateIdentifier.ts +86 -0
- package/src/mutation/MutationCreateMeta.ts +92 -0
- package/src/mutation/MutationCreateRule.ts +90 -0
- package/src/mutation/MutationCreateToken.ts +92 -0
- package/src/mutation/MutationCreateWallet.ts +78 -0
- package/src/mutation/MutationDepositBufferToken.ts +72 -0
- package/src/mutation/MutationLinkIdentifier.ts +87 -0
- package/src/mutation/MutationProposeMolecule.ts +147 -0
- package/src/mutation/MutationRequestAuthorization.ts +77 -0
- package/src/mutation/MutationRequestAuthorizationGuest.ts +85 -0
- package/src/mutation/MutationRequestTokens.ts +98 -0
- package/src/mutation/MutationTransferTokens.ts +87 -0
- package/src/mutation/MutationWithdrawBufferToken.ts +73 -0
- package/src/query/Query.ts +187 -0
- package/src/query/QueryActiveSession.ts +89 -0
- package/src/query/QueryAtom.ts +275 -0
- package/src/query/QueryBalance.ts +102 -0
- package/src/query/QueryBatch.ts +145 -0
- package/src/query/QueryBatchHistory.ts +86 -0
- package/src/query/QueryContinuId.ts +91 -0
- package/src/query/QueryMetaType.ts +177 -0
- package/src/query/QueryMetaTypeViaAtom.ts +199 -0
- package/src/query/QueryPolicy.ts +91 -0
- package/src/query/QueryToken.ts +90 -0
- package/src/query/QueryUserActivity.ts +153 -0
- package/src/query/QueryWalletBundle.ts +92 -0
- package/src/query/QueryWalletList.ts +106 -0
- package/src/response/EnhancedResponse.ts +345 -0
- package/src/response/Response.ts +254 -0
- package/src/response/ResponseActiveSession.ts +72 -0
- package/src/response/ResponseAtom.ts +132 -0
- package/src/response/ResponseAuthorizationGuest.ts +119 -0
- package/src/response/ResponseBalance.ts +153 -0
- package/src/response/ResponseClaimShadowWallet.ts +56 -0
- package/src/response/ResponseContinuId.ts +101 -0
- package/src/response/ResponseCreateIdentifier.ts +56 -0
- package/src/response/ResponseCreateMeta.ts +58 -0
- package/src/response/ResponseCreateRule.ts +56 -0
- package/src/response/ResponseCreateToken.ts +58 -0
- package/src/response/ResponseCreateWallet.ts +58 -0
- package/src/response/ResponseLinkIdentifier.ts +87 -0
- package/src/response/ResponseMetaBatch.ts +72 -0
- package/src/response/ResponseMetaType.ts +108 -0
- package/src/response/ResponseMetaTypeViaAtom.ts +108 -0
- package/src/response/ResponsePolicy.ts +90 -0
- package/src/response/ResponseProposeMolecule.ts +155 -0
- package/src/response/ResponseQueryActiveSession.ts +105 -0
- package/src/response/ResponseQueryUserActivity.ts +89 -0
- package/src/response/ResponseRequestAuthorization.ts +100 -0
- package/src/response/ResponseRequestAuthorizationGuest.ts +133 -0
- package/src/response/ResponseRequestTokens.ts +58 -0
- package/src/response/ResponseTransferTokens.ts +72 -0
- package/src/response/ResponseWalletBundle.ts +95 -0
- package/src/response/ResponseWalletList.ts +165 -0
- package/src/schemas/index.ts +457 -0
- package/src/subscribe/ActiveSessionSubscribe.ts +72 -0
- package/src/subscribe/ActiveWalletSubscribe.ts +99 -0
- package/src/subscribe/CreateMoleculeSubscribe.ts +106 -0
- package/src/subscribe/Subscribe.ts +182 -0
- package/src/subscribe/WalletStatusSubscribe.ts +70 -0
- package/src/subscribe/index.ts +59 -0
- package/src/types/assertions.ts +722 -0
- package/src/types/client.ts +567 -0
- package/src/types/crypto.ts +541 -0
- package/src/types/graphql.ts +630 -0
- package/src/types/guards.ts +659 -0
- package/src/types/index.ts +614 -0
- package/src/types/response.ts +133 -0
- package/src/types/template-literals.ts +382 -0
- package/src/validation/UNIVERSAL_CONFIGURATION_INTERFACES.ts +580 -0
- package/src/validation/ValidationService.ts +607 -0
- package/src/validation/schemas.ts +447 -0
- package/src/versions/HashAtom.ts +170 -0
- package/src/versions/Version4.ts +120 -0
- package/src/versions/index.ts +80 -0
|
@@ -0,0 +1,278 @@
|
|
|
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-TS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import Meta, { type NormalizedMeta } from './Meta'
|
|
50
|
+
|
|
51
|
+
// Configuration constants matching JS SDK
|
|
52
|
+
const USE_META_CONTEXT = false
|
|
53
|
+
const DEFAULT_META_CONTEXT = 'https://www.schema.org'
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* AtomMeta class - Manages metadata for atoms
|
|
57
|
+
* Provides methods for metadata manipulation and wallet metadata
|
|
58
|
+
*/
|
|
59
|
+
export default class AtomMeta {
|
|
60
|
+
private meta: NormalizedMeta[]
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create new AtomMeta instance
|
|
64
|
+
* @param meta - Initial metadata (object or array)
|
|
65
|
+
*/
|
|
66
|
+
constructor(meta: Record<string, any> | NormalizedMeta[] | null = null) {
|
|
67
|
+
this.meta = Meta.normalizeMeta(meta)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Merge additional metadata
|
|
72
|
+
* @param meta - Metadata to merge
|
|
73
|
+
* @return This instance for chaining
|
|
74
|
+
*/
|
|
75
|
+
merge(meta: Record<string, any> | NormalizedMeta[]): AtomMeta {
|
|
76
|
+
const normalized = Meta.normalizeMeta(meta)
|
|
77
|
+
|
|
78
|
+
// Use Set to avoid duplicates based on key
|
|
79
|
+
const existingKeys = new Set(this.meta.map(m => m.key))
|
|
80
|
+
|
|
81
|
+
for (const item of normalized) {
|
|
82
|
+
if (existingKeys.has(item.key)) {
|
|
83
|
+
// Update existing key
|
|
84
|
+
const index = this.meta.findIndex(m => m.key === item.key)
|
|
85
|
+
if (index !== -1) {
|
|
86
|
+
this.meta[index] = item
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
// Add new key
|
|
90
|
+
this.meta.push(item)
|
|
91
|
+
existingKeys.add(item.key)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Add context metadata if enabled
|
|
100
|
+
* @param context - Context URL or null for default
|
|
101
|
+
* @return This instance for chaining
|
|
102
|
+
*/
|
|
103
|
+
addContext(context: string | null = null): AtomMeta {
|
|
104
|
+
// Add context key if it is enabled
|
|
105
|
+
if (USE_META_CONTEXT) {
|
|
106
|
+
this.merge({ context: context || DEFAULT_META_CONTEXT })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return this
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Set atom wallet metadata
|
|
114
|
+
* @param wallet - Wallet to extract metadata from
|
|
115
|
+
* @return This instance for chaining
|
|
116
|
+
*/
|
|
117
|
+
setAtomWallet(wallet: any): AtomMeta {
|
|
118
|
+
const walletMeta: Record<string, any> = {
|
|
119
|
+
pubkey: wallet.pubkey,
|
|
120
|
+
characters: wallet.characters
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Add token units meta key if present
|
|
124
|
+
if (wallet.tokenUnits && wallet.tokenUnits.length) {
|
|
125
|
+
walletMeta.tokenUnits = JSON.stringify(wallet.getTokenUnitsData ? wallet.getTokenUnitsData() : wallet.tokenUnits)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Add trade rates meta key if present
|
|
129
|
+
if (wallet.tradeRates && Object.keys(wallet.tradeRates).length) {
|
|
130
|
+
walletMeta.tradeRates = JSON.stringify(wallet.tradeRates)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Merge all wallet's metas
|
|
134
|
+
this.merge(walletMeta)
|
|
135
|
+
return this
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Set full NEW wallet metadata
|
|
140
|
+
* Used for shadow wallet claim & wallet creation & token creation
|
|
141
|
+
* @param wallet - Wallet with full metadata
|
|
142
|
+
* @return This instance for chaining
|
|
143
|
+
*/
|
|
144
|
+
setMetaWallet(wallet: any): AtomMeta {
|
|
145
|
+
this.merge({
|
|
146
|
+
walletTokenSlug: wallet.token,
|
|
147
|
+
walletBundleHash: wallet.bundle,
|
|
148
|
+
walletAddress: wallet.address,
|
|
149
|
+
walletPosition: wallet.position,
|
|
150
|
+
walletBatchId: wallet.batchId,
|
|
151
|
+
walletPubkey: wallet.pubkey,
|
|
152
|
+
walletCharacters: wallet.characters
|
|
153
|
+
})
|
|
154
|
+
return this
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Set shadow wallet claim flag
|
|
159
|
+
* @param shadowWalletClaim - Claim flag (converted to number)
|
|
160
|
+
* @return This instance for chaining
|
|
161
|
+
*/
|
|
162
|
+
setShadowWalletClaim(shadowWalletClaim: boolean | number): AtomMeta {
|
|
163
|
+
this.merge({ shadowWalletClaim: Number(shadowWalletClaim) })
|
|
164
|
+
return this
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Set signing wallet metadata
|
|
169
|
+
* @param signingWallet - Wallet used for signing
|
|
170
|
+
* @return This instance for chaining
|
|
171
|
+
*/
|
|
172
|
+
setSigningWallet(signingWallet: any): AtomMeta {
|
|
173
|
+
this.merge({
|
|
174
|
+
signingWallet: JSON.stringify({
|
|
175
|
+
tokenSlug: signingWallet.token,
|
|
176
|
+
bundleHash: signingWallet.bundle,
|
|
177
|
+
address: signingWallet.address,
|
|
178
|
+
position: signingWallet.position,
|
|
179
|
+
pubkey: signingWallet.pubkey,
|
|
180
|
+
characters: signingWallet.characters
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
return this
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Add policy metadata
|
|
188
|
+
* @param policy - Policy object to add
|
|
189
|
+
* @return This instance for chaining
|
|
190
|
+
*/
|
|
191
|
+
addPolicy(policy: Record<string, any>): AtomMeta {
|
|
192
|
+
// For now, just stringify the policy
|
|
193
|
+
// TODO: Implement PolicyMeta class if needed
|
|
194
|
+
this.merge({
|
|
195
|
+
policy: JSON.stringify(policy)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
return this
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get the normalized metadata array
|
|
203
|
+
* @return Array of normalized metadata items
|
|
204
|
+
*/
|
|
205
|
+
get(): NormalizedMeta[] {
|
|
206
|
+
return this.meta
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Convert metadata to plain object
|
|
211
|
+
* @return Aggregated metadata object
|
|
212
|
+
*/
|
|
213
|
+
toObject(): Record<string, any> {
|
|
214
|
+
return Meta.aggregateMeta(this.meta)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Convert metadata to JSON string
|
|
219
|
+
* @return JSON string representation
|
|
220
|
+
*/
|
|
221
|
+
toJSON(): string {
|
|
222
|
+
return JSON.stringify(this.toObject())
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Get metadata value by key
|
|
227
|
+
* @param key - Key to lookup
|
|
228
|
+
* @param defaultValue - Default if not found
|
|
229
|
+
* @return Value or default
|
|
230
|
+
*/
|
|
231
|
+
getValue(key: string, defaultValue: any = null): any {
|
|
232
|
+
return Meta.getMetaValue(this.meta, key, defaultValue)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Check if metadata has a key
|
|
237
|
+
* @param key - Key to check
|
|
238
|
+
* @return True if key exists
|
|
239
|
+
*/
|
|
240
|
+
hasKey(key: string): boolean {
|
|
241
|
+
return Meta.hasKey(this.meta, key)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Remove metadata by key
|
|
246
|
+
* @param key - Key to remove
|
|
247
|
+
* @return This instance for chaining
|
|
248
|
+
*/
|
|
249
|
+
remove(key: string): AtomMeta {
|
|
250
|
+
this.meta = Meta.removeMeta(this.meta, key)
|
|
251
|
+
return this
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Clear all metadata
|
|
256
|
+
* @return This instance for chaining
|
|
257
|
+
*/
|
|
258
|
+
clear(): AtomMeta {
|
|
259
|
+
this.meta = []
|
|
260
|
+
return this
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Get count of metadata items
|
|
265
|
+
* @return Number of items
|
|
266
|
+
*/
|
|
267
|
+
count(): number {
|
|
268
|
+
return this.meta.length
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Clone this AtomMeta instance
|
|
273
|
+
* @return New AtomMeta with same data
|
|
274
|
+
*/
|
|
275
|
+
clone(): AtomMeta {
|
|
276
|
+
return new AtomMeta(Meta.clone(this.meta))
|
|
277
|
+
}
|
|
278
|
+
}
|
package/src/core/Meta.ts
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
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-TS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-TS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Meta class - Handles metadata normalization and aggregation
|
|
51
|
+
*
|
|
52
|
+
* Provides static methods for processing metadata across atoms and molecules
|
|
53
|
+
* Ensures consistent metadata handling across the SDK
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
import type { MetaData } from '@/types'
|
|
57
|
+
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// META TYPES AND INTERFACES
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
export interface NormalizedMeta {
|
|
63
|
+
key: string
|
|
64
|
+
value: string | number | boolean | null
|
|
65
|
+
[additionalProps: string]: unknown
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface MetaItem {
|
|
69
|
+
key: string
|
|
70
|
+
value: unknown
|
|
71
|
+
[props: string]: unknown
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface AggregatedMetaResult {
|
|
75
|
+
[key: string]: unknown
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// =============================================================================
|
|
79
|
+
// META CLASS IMPLEMENTATION
|
|
80
|
+
// =============================================================================
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Meta class - Static methods for metadata processing
|
|
84
|
+
* Matches JavaScript SDK Meta class functionality exactly
|
|
85
|
+
*/
|
|
86
|
+
export default class Meta {
|
|
87
|
+
// No instance properties - this class only provides static methods
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Normalize metadata to consistent format
|
|
91
|
+
* Matches JavaScript SDK Meta.normalizeMeta exactly
|
|
92
|
+
*/
|
|
93
|
+
static normalizeMeta(meta: MetaData | MetaItem[] | null): NormalizedMeta[] {
|
|
94
|
+
if (!meta) {
|
|
95
|
+
return []
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Handle array of meta items
|
|
99
|
+
if (Array.isArray(meta)) {
|
|
100
|
+
return meta.map(item => {
|
|
101
|
+
if (typeof item === 'object' && item !== null && 'key' in item) {
|
|
102
|
+
return {
|
|
103
|
+
...item,
|
|
104
|
+
key: String(item.key),
|
|
105
|
+
value: item.value as string | number | boolean | null
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fallback for invalid items
|
|
110
|
+
return {
|
|
111
|
+
key: 'unknown',
|
|
112
|
+
value: String(item) as string | number | boolean | null
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Handle object metadata - convert to array format
|
|
118
|
+
if (typeof meta === 'object' && meta !== null) {
|
|
119
|
+
return Object.entries(meta).map(([key, value]) => ({
|
|
120
|
+
key,
|
|
121
|
+
value: value as string | number | boolean | null
|
|
122
|
+
}))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Handle primitive values
|
|
126
|
+
return [{
|
|
127
|
+
key: 'value',
|
|
128
|
+
value: meta as string | number | boolean | null
|
|
129
|
+
}]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Aggregate metadata into single object
|
|
134
|
+
* Matches JavaScript SDK Meta.aggregateMeta exactly
|
|
135
|
+
*/
|
|
136
|
+
static aggregateMeta(metaItems: NormalizedMeta[] | MetaItem[] | null): AggregatedMetaResult {
|
|
137
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
138
|
+
return {}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const aggregated: AggregatedMetaResult = {}
|
|
142
|
+
|
|
143
|
+
for (const item of metaItems) {
|
|
144
|
+
if (item && typeof item === 'object' && 'key' in item) {
|
|
145
|
+
const key = String(item.key)
|
|
146
|
+
|
|
147
|
+
// Handle different value types appropriately
|
|
148
|
+
if ('value' in item) {
|
|
149
|
+
aggregated[key] = item.value
|
|
150
|
+
} else {
|
|
151
|
+
// If no explicit value property, use the entire item minus the key
|
|
152
|
+
const { key: itemKey, ...restOfItem } = item as any
|
|
153
|
+
aggregated[key] = Object.keys(restOfItem).length === 1 && 'value' in restOfItem
|
|
154
|
+
? restOfItem.value
|
|
155
|
+
: restOfItem
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return aggregated
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Merge multiple metadata arrays
|
|
165
|
+
* Combines arrays while preserving order and handling duplicates
|
|
166
|
+
*/
|
|
167
|
+
static mergeMeta(...metaArrays: (NormalizedMeta[] | MetaItem[] | null)[]): NormalizedMeta[] {
|
|
168
|
+
const merged: NormalizedMeta[] = []
|
|
169
|
+
const keysSeen = new Set<string>()
|
|
170
|
+
|
|
171
|
+
for (const metaArray of metaArrays) {
|
|
172
|
+
if (!metaArray || !Array.isArray(metaArray)) {
|
|
173
|
+
continue
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const normalized = this.normalizeMeta(metaArray)
|
|
177
|
+
|
|
178
|
+
for (const item of normalized) {
|
|
179
|
+
// Handle duplicate keys by appending index
|
|
180
|
+
let finalKey = item.key
|
|
181
|
+
let counter = 1
|
|
182
|
+
|
|
183
|
+
while (keysSeen.has(finalKey)) {
|
|
184
|
+
finalKey = `${item.key}_${counter}`
|
|
185
|
+
counter++
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
keysSeen.add(finalKey)
|
|
189
|
+
merged.push({
|
|
190
|
+
...item,
|
|
191
|
+
key: finalKey
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return merged
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Filter metadata by key pattern or predicate
|
|
201
|
+
*/
|
|
202
|
+
static filterMeta(
|
|
203
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
204
|
+
filter: string | RegExp | ((item: NormalizedMeta) => boolean)
|
|
205
|
+
): NormalizedMeta[] {
|
|
206
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
207
|
+
return []
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
211
|
+
|
|
212
|
+
if (typeof filter === 'string') {
|
|
213
|
+
return normalized.filter(item => item.key.includes(filter))
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (filter instanceof RegExp) {
|
|
217
|
+
return normalized.filter(item => filter.test(item.key))
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (typeof filter === 'function') {
|
|
221
|
+
return normalized.filter(filter)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return normalized
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Find metadata item by key
|
|
229
|
+
*/
|
|
230
|
+
static findMeta(
|
|
231
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
232
|
+
key: string
|
|
233
|
+
): NormalizedMeta | null {
|
|
234
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
235
|
+
return null
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
239
|
+
return normalized.find(item => item.key === key) || null
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get metadata value by key
|
|
244
|
+
*/
|
|
245
|
+
static getMetaValue(
|
|
246
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
247
|
+
key: string,
|
|
248
|
+
defaultValue: unknown = null
|
|
249
|
+
): unknown {
|
|
250
|
+
const item = this.findMeta(metaItems, key)
|
|
251
|
+
return item ? item.value : defaultValue
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Set or update metadata item by key
|
|
256
|
+
*/
|
|
257
|
+
static setMeta(
|
|
258
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
259
|
+
key: string,
|
|
260
|
+
value: unknown
|
|
261
|
+
): NormalizedMeta[] {
|
|
262
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
263
|
+
const existingIndex = normalized.findIndex(item => item.key === key)
|
|
264
|
+
|
|
265
|
+
const newItem: NormalizedMeta = {
|
|
266
|
+
key,
|
|
267
|
+
value: value as string | number | boolean | null
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (existingIndex >= 0) {
|
|
271
|
+
// Update existing item
|
|
272
|
+
normalized[existingIndex] = newItem
|
|
273
|
+
} else {
|
|
274
|
+
// Add new item
|
|
275
|
+
normalized.push(newItem)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return normalized
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Remove metadata item by key
|
|
283
|
+
*/
|
|
284
|
+
static removeMeta(
|
|
285
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
286
|
+
key: string
|
|
287
|
+
): NormalizedMeta[] {
|
|
288
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
289
|
+
return []
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
293
|
+
return normalized.filter(item => item.key !== key)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Convert metadata to JSON-serializable format
|
|
298
|
+
*/
|
|
299
|
+
static toJSON(metaItems: NormalizedMeta[] | MetaItem[] | null): Record<string, unknown> {
|
|
300
|
+
return this.aggregateMeta(this.normalizeMeta(metaItems))
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Create metadata from JSON object
|
|
305
|
+
*/
|
|
306
|
+
static fromJSON(jsonData: Record<string, unknown>): NormalizedMeta[] {
|
|
307
|
+
if (!jsonData || typeof jsonData !== 'object') {
|
|
308
|
+
return []
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return Object.entries(jsonData).map(([key, value]) => ({
|
|
312
|
+
key,
|
|
313
|
+
value: value as string | number | boolean | null
|
|
314
|
+
}))
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Validate metadata structure
|
|
319
|
+
*/
|
|
320
|
+
static validateMeta(metaItems: unknown): metaItems is NormalizedMeta[] {
|
|
321
|
+
if (!Array.isArray(metaItems)) {
|
|
322
|
+
return false
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return metaItems.every(item =>
|
|
326
|
+
item &&
|
|
327
|
+
typeof item === 'object' &&
|
|
328
|
+
'key' in item &&
|
|
329
|
+
typeof item.key === 'string'
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Get all unique keys from metadata
|
|
335
|
+
*/
|
|
336
|
+
static getKeys(metaItems: NormalizedMeta[] | MetaItem[] | null): string[] {
|
|
337
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
338
|
+
return []
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
342
|
+
const keys = new Set<string>()
|
|
343
|
+
|
|
344
|
+
for (const item of normalized) {
|
|
345
|
+
keys.add(item.key)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return Array.from(keys)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Check if metadata contains specific key
|
|
353
|
+
*/
|
|
354
|
+
static hasKey(metaItems: NormalizedMeta[] | MetaItem[] | null, key: string): boolean {
|
|
355
|
+
return this.getKeys(metaItems).includes(key)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Get metadata statistics
|
|
360
|
+
*/
|
|
361
|
+
static getStats(metaItems: NormalizedMeta[] | MetaItem[] | null): {
|
|
362
|
+
totalItems: number
|
|
363
|
+
uniqueKeys: number
|
|
364
|
+
keys: string[]
|
|
365
|
+
valueTypes: Record<string, number>
|
|
366
|
+
} {
|
|
367
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
368
|
+
return {
|
|
369
|
+
totalItems: 0,
|
|
370
|
+
uniqueKeys: 0,
|
|
371
|
+
keys: [],
|
|
372
|
+
valueTypes: {}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
377
|
+
const keys = this.getKeys(normalized)
|
|
378
|
+
const valueTypes: Record<string, number> = {}
|
|
379
|
+
|
|
380
|
+
for (const item of normalized) {
|
|
381
|
+
const type = item.value === null ? 'null' : typeof item.value
|
|
382
|
+
valueTypes[type] = (valueTypes[type] || 0) + 1
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
totalItems: normalized.length,
|
|
387
|
+
uniqueKeys: keys.length,
|
|
388
|
+
keys,
|
|
389
|
+
valueTypes
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Deep clone metadata array
|
|
395
|
+
*/
|
|
396
|
+
static clone(metaItems: NormalizedMeta[] | MetaItem[] | null): NormalizedMeta[] {
|
|
397
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
398
|
+
return []
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
402
|
+
return normalized.map(item => ({ ...item }))
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Sort metadata by key
|
|
407
|
+
*/
|
|
408
|
+
static sort(
|
|
409
|
+
metaItems: NormalizedMeta[] | MetaItem[] | null,
|
|
410
|
+
descending = false
|
|
411
|
+
): NormalizedMeta[] {
|
|
412
|
+
if (!metaItems || !Array.isArray(metaItems)) {
|
|
413
|
+
return []
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const normalized = this.normalizeMeta(metaItems)
|
|
417
|
+
return normalized.sort((a, b) => {
|
|
418
|
+
const comparison = a.key.localeCompare(b.key)
|
|
419
|
+
return descending ? -comparison : comparison
|
|
420
|
+
})
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// =============================================================================
|
|
425
|
+
// TYPE EXPORTS
|
|
426
|
+
// =============================================================================
|
|
427
|
+
|
|
428
|
+
// Types are already exported at the interface declarations
|