ripple-binary-codec 2.7.0-smartescrow.0 → 2.8.0-smartcontract.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/dist/enums/definitions.json +173 -270
- package/dist/enums/src/enums/definitions.json +173 -270
- package/dist/quality.js +15 -3
- package/dist/quality.js.map +1 -1
- package/dist/serdes/binary-parser.js +8 -2
- package/dist/serdes/binary-parser.js.map +1 -1
- package/dist/serdes/binary-serializer.d.ts +1 -1
- package/dist/serdes/binary-serializer.js +2 -2
- package/dist/serdes/binary-serializer.js.map +1 -1
- package/dist/src/enums/definitions.json +173 -270
- package/dist/src/quality.js +15 -3
- package/dist/src/quality.js.map +1 -1
- package/dist/src/serdes/binary-parser.js +8 -2
- package/dist/src/serdes/binary-parser.js.map +1 -1
- package/dist/src/serdes/binary-serializer.d.ts +1 -1
- package/dist/src/serdes/binary-serializer.js +2 -2
- package/dist/src/serdes/binary-serializer.js.map +1 -1
- package/dist/src/types/account-id.d.ts +2 -0
- package/dist/src/types/account-id.js +4 -0
- package/dist/src/types/account-id.js.map +1 -1
- package/dist/src/types/amount.d.ts +2 -1
- package/dist/src/types/amount.js +25 -4
- package/dist/src/types/amount.js.map +1 -1
- package/dist/src/types/blob.d.ts +2 -1
- package/dist/src/types/blob.js +3 -0
- package/dist/src/types/blob.js.map +1 -1
- package/dist/src/types/currency.d.ts +2 -0
- package/dist/src/types/currency.js +4 -0
- package/dist/src/types/currency.js.map +1 -1
- package/dist/src/types/data.d.ts +86 -0
- package/dist/src/types/data.js +252 -0
- package/dist/src/types/data.js.map +1 -0
- package/dist/src/types/dataType.d.ts +94 -0
- package/dist/src/types/dataType.js +145 -0
- package/dist/src/types/dataType.js.map +1 -0
- package/dist/src/types/hash-128.d.ts +2 -0
- package/dist/src/types/hash-128.js +4 -0
- package/dist/src/types/hash-128.js.map +1 -1
- package/dist/src/types/hash-160.d.ts +2 -0
- package/dist/src/types/hash-160.js +4 -0
- package/dist/src/types/hash-160.js.map +1 -1
- package/dist/src/types/hash-192.d.ts +2 -0
- package/dist/src/types/hash-192.js +4 -0
- package/dist/src/types/hash-192.js.map +1 -1
- package/dist/src/types/hash-256.d.ts +2 -0
- package/dist/src/types/hash-256.js +4 -0
- package/dist/src/types/hash-256.js.map +1 -1
- package/dist/src/types/index.d.ts +3 -1
- package/dist/src/types/index.js +7 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/int-32.d.ts +17 -8
- package/dist/src/types/int-32.js +25 -11
- package/dist/src/types/int-32.js.map +1 -1
- package/dist/src/types/int.d.ts +38 -0
- package/dist/src/types/int.js +57 -0
- package/dist/src/types/int.js.map +1 -0
- package/dist/src/types/issue.d.ts +2 -1
- package/dist/src/types/issue.js +3 -0
- package/dist/src/types/issue.js.map +1 -1
- package/dist/src/types/json.d.ts +173 -0
- package/dist/src/types/json.js +531 -0
- package/dist/src/types/json.js.map +1 -0
- package/dist/src/types/path-set.d.ts +2 -1
- package/dist/src/types/path-set.js +3 -0
- package/dist/src/types/path-set.js.map +1 -1
- package/dist/src/types/serialized-type.d.ts +43 -0
- package/dist/src/types/serialized-type.js +63 -1
- package/dist/src/types/serialized-type.js.map +1 -1
- package/dist/src/types/st-array.d.ts +2 -1
- package/dist/src/types/st-array.js +3 -0
- package/dist/src/types/st-array.js.map +1 -1
- package/dist/src/types/st-number.d.ts +2 -1
- package/dist/src/types/st-number.js +3 -0
- package/dist/src/types/st-number.js.map +1 -1
- package/dist/src/types/st-object.d.ts +2 -1
- package/dist/src/types/st-object.js +9 -1
- package/dist/src/types/st-object.js.map +1 -1
- package/dist/src/types/uint-16.d.ts +2 -0
- package/dist/src/types/uint-16.js +4 -0
- package/dist/src/types/uint-16.js.map +1 -1
- package/dist/src/types/uint-32.d.ts +2 -0
- package/dist/src/types/uint-32.js +4 -0
- package/dist/src/types/uint-32.js.map +1 -1
- package/dist/src/types/uint-64.d.ts +2 -0
- package/dist/src/types/uint-64.js +4 -0
- package/dist/src/types/uint-64.js.map +1 -1
- package/dist/src/types/uint-8.d.ts +2 -0
- package/dist/src/types/uint-8.js +4 -0
- package/dist/src/types/uint-8.js.map +1 -1
- package/dist/src/types/vector-256.d.ts +2 -1
- package/dist/src/types/vector-256.js +3 -0
- package/dist/src/types/vector-256.js.map +1 -1
- package/dist/src/types/xchain-bridge.d.ts +2 -1
- package/dist/src/types/xchain-bridge.js +3 -0
- package/dist/src/types/xchain-bridge.js.map +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/account-id.d.ts +2 -0
- package/dist/types/account-id.js +4 -0
- package/dist/types/account-id.js.map +1 -1
- package/dist/types/amount.d.ts +2 -1
- package/dist/types/amount.js +25 -4
- package/dist/types/amount.js.map +1 -1
- package/dist/types/blob.d.ts +2 -1
- package/dist/types/blob.js +3 -0
- package/dist/types/blob.js.map +1 -1
- package/dist/types/currency.d.ts +2 -0
- package/dist/types/currency.js +4 -0
- package/dist/types/currency.js.map +1 -1
- package/dist/types/data.d.ts +86 -0
- package/dist/types/data.js +252 -0
- package/dist/types/data.js.map +1 -0
- package/dist/types/dataType.d.ts +94 -0
- package/dist/types/dataType.js +145 -0
- package/dist/types/dataType.js.map +1 -0
- package/dist/types/hash-128.d.ts +2 -0
- package/dist/types/hash-128.js +4 -0
- package/dist/types/hash-128.js.map +1 -1
- package/dist/types/hash-160.d.ts +2 -0
- package/dist/types/hash-160.js +4 -0
- package/dist/types/hash-160.js.map +1 -1
- package/dist/types/hash-192.d.ts +2 -0
- package/dist/types/hash-192.js +4 -0
- package/dist/types/hash-192.js.map +1 -1
- package/dist/types/hash-256.d.ts +2 -0
- package/dist/types/hash-256.js +4 -0
- package/dist/types/hash-256.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js +7 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/int-32.d.ts +17 -8
- package/dist/types/int-32.js +25 -11
- package/dist/types/int-32.js.map +1 -1
- package/dist/types/int.d.ts +38 -0
- package/dist/types/int.js +57 -0
- package/dist/types/int.js.map +1 -0
- package/dist/types/issue.d.ts +2 -1
- package/dist/types/issue.js +3 -0
- package/dist/types/issue.js.map +1 -1
- package/dist/types/json.d.ts +173 -0
- package/dist/types/json.js +531 -0
- package/dist/types/json.js.map +1 -0
- package/dist/types/path-set.d.ts +2 -1
- package/dist/types/path-set.js +3 -0
- package/dist/types/path-set.js.map +1 -1
- package/dist/types/serialized-type.d.ts +43 -0
- package/dist/types/serialized-type.js +63 -1
- package/dist/types/serialized-type.js.map +1 -1
- package/dist/types/st-array.d.ts +2 -1
- package/dist/types/st-array.js +3 -0
- package/dist/types/st-array.js.map +1 -1
- package/dist/types/st-number.d.ts +2 -1
- package/dist/types/st-number.js +3 -0
- package/dist/types/st-number.js.map +1 -1
- package/dist/types/st-object.d.ts +2 -1
- package/dist/types/st-object.js +9 -1
- package/dist/types/st-object.js.map +1 -1
- package/dist/types/uint-16.d.ts +2 -0
- package/dist/types/uint-16.js +4 -0
- package/dist/types/uint-16.js.map +1 -1
- package/dist/types/uint-32.d.ts +2 -0
- package/dist/types/uint-32.js +4 -0
- package/dist/types/uint-32.js.map +1 -1
- package/dist/types/uint-64.d.ts +2 -0
- package/dist/types/uint-64.js +4 -0
- package/dist/types/uint-64.js.map +1 -1
- package/dist/types/uint-8.d.ts +2 -0
- package/dist/types/uint-8.js +4 -0
- package/dist/types/uint-8.js.map +1 -1
- package/dist/types/vector-256.d.ts +2 -1
- package/dist/types/vector-256.js +3 -0
- package/dist/types/vector-256.js.map +1 -1
- package/dist/types/xchain-bridge.d.ts +2 -1
- package/dist/types/xchain-bridge.js +3 -0
- package/dist/types/xchain-bridge.js.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/enums/definitions.json +173 -270
- package/src/quality.ts +13 -3
- package/src/serdes/binary-parser.ts +12 -2
- package/src/serdes/binary-serializer.ts +2 -2
- package/src/types/account-id.ts +5 -0
- package/src/types/amount.ts +25 -6
- package/src/types/blob.ts +5 -1
- package/src/types/currency.ts +5 -0
- package/src/types/data.ts +294 -0
- package/src/types/dataType.ts +178 -0
- package/src/types/hash-128.ts +5 -0
- package/src/types/hash-160.ts +5 -0
- package/src/types/hash-192.ts +5 -0
- package/src/types/hash-256.ts +5 -0
- package/src/types/index.ts +6 -0
- package/src/types/int-32.ts +27 -12
- package/src/types/int.ts +75 -0
- package/src/types/issue.ts +5 -1
- package/src/types/json.ts +650 -0
- package/src/types/path-set.ts +5 -1
- package/src/types/serialized-type.ts +67 -0
- package/src/types/st-array.ts +5 -1
- package/src/types/st-number.ts +5 -1
- package/src/types/st-object.ts +12 -2
- package/src/types/uint-16.ts +5 -0
- package/src/types/uint-32.ts +5 -0
- package/src/types/uint-64.ts +6 -1
- package/src/types/uint-8.ts +5 -0
- package/src/types/vector-256.ts +5 -1
- package/src/types/xchain-bridge.ts +5 -1
- package/src/utils.ts +1 -1
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
3
|
+
import { JsonObject, SerializedType, SerializedTypeID } from './serialized-type'
|
|
4
|
+
import { bytesToHex } from '@xrplf/isomorphic/utils'
|
|
5
|
+
import { BinarySerializer, BytesList } from '../serdes/binary-serializer'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* STJson: Serialized Type for JSON-like structures (objects or arrays).
|
|
9
|
+
*
|
|
10
|
+
* Supports two modes:
|
|
11
|
+
* - Object: Key-value pairs where keys are VL-encoded strings
|
|
12
|
+
* - Array: Ordered list of values
|
|
13
|
+
*
|
|
14
|
+
* Values are [SType marker][VL-encoded SType serialization].
|
|
15
|
+
* Values can be any SType, including nested STJson.
|
|
16
|
+
*
|
|
17
|
+
* Serialization format: [type_byte][VL_length][data...]
|
|
18
|
+
* - type_byte: 0x00 = Object, 0x01 = Array
|
|
19
|
+
*
|
|
20
|
+
* Depth constraint: Maximum nesting depth of 1 level
|
|
21
|
+
*/
|
|
22
|
+
class STJson extends SerializedType {
|
|
23
|
+
private static readonly JsonType = {
|
|
24
|
+
Object: 0x00,
|
|
25
|
+
Array: 0x01,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private data: Map<string, SerializedType | null> | (SerializedType | null)[]
|
|
29
|
+
private jsonType: number
|
|
30
|
+
private default_ = false
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Construct STJson from bytes
|
|
34
|
+
* @param bytes - Uint8Array containing serialized JSON
|
|
35
|
+
*/
|
|
36
|
+
constructor(bytes: Uint8Array) {
|
|
37
|
+
super(bytes)
|
|
38
|
+
this.data = new Map()
|
|
39
|
+
this.jsonType = STJson.JsonType.Object
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Create an empty STJson with the given type
|
|
44
|
+
*/
|
|
45
|
+
private static createEmpty(
|
|
46
|
+
type: number,
|
|
47
|
+
initialData?:
|
|
48
|
+
| Map<string, SerializedType | null>
|
|
49
|
+
| (SerializedType | null)[],
|
|
50
|
+
): STJson {
|
|
51
|
+
const json = new STJson(new Uint8Array())
|
|
52
|
+
json.data = initialData ?? (type === STJson.JsonType.Array ? [] : new Map())
|
|
53
|
+
json.jsonType = type
|
|
54
|
+
return json
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parse STJson from BinaryParser
|
|
59
|
+
*
|
|
60
|
+
* @param parser - BinaryParser positioned at the start of STJson
|
|
61
|
+
* @returns STJson instance
|
|
62
|
+
*/
|
|
63
|
+
static fromParser(parser: BinaryParser): STJson {
|
|
64
|
+
const dataLength = parser.readVariableLengthLength()
|
|
65
|
+
|
|
66
|
+
if (dataLength < 0) {
|
|
67
|
+
throw new Error('Invalid STJson length')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (dataLength === 0) {
|
|
71
|
+
const json = new STJson(new Uint8Array())
|
|
72
|
+
json.data = new Map()
|
|
73
|
+
return json
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Read type byte
|
|
77
|
+
const typeByte = parser.read(1)[0]
|
|
78
|
+
const type = typeByte
|
|
79
|
+
const initialBytesLeft = parser.size()
|
|
80
|
+
|
|
81
|
+
if (type === STJson.JsonType.Array) {
|
|
82
|
+
const array: (SerializedType | null)[] = []
|
|
83
|
+
while (
|
|
84
|
+
parser.size() > 0 &&
|
|
85
|
+
initialBytesLeft - parser.size() < dataLength
|
|
86
|
+
) {
|
|
87
|
+
const valueVL = parser.readVariableLength()
|
|
88
|
+
if (valueVL.length > 0) {
|
|
89
|
+
const valueSit = new BinaryParser(bytesToHex(valueVL))
|
|
90
|
+
const value = STJson.makeValueFromVLWithType(valueSit)
|
|
91
|
+
array.push(value)
|
|
92
|
+
} else {
|
|
93
|
+
array.push(null)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const json = new STJson(new Uint8Array())
|
|
98
|
+
json.data = array
|
|
99
|
+
json.jsonType = STJson.JsonType.Array
|
|
100
|
+
return json
|
|
101
|
+
} else {
|
|
102
|
+
// JsonType.Object
|
|
103
|
+
const map = new Map<string, SerializedType | null>()
|
|
104
|
+
while (
|
|
105
|
+
parser.size() > 0 &&
|
|
106
|
+
initialBytesLeft - parser.size() < dataLength
|
|
107
|
+
) {
|
|
108
|
+
const [key, value] = STJson.parsePair(parser)
|
|
109
|
+
map.set(key, value)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const json = new STJson(new Uint8Array())
|
|
113
|
+
json.data = map
|
|
114
|
+
json.jsonType = STJson.JsonType.Object
|
|
115
|
+
return json
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Parse a single key-value pair from the parser
|
|
121
|
+
*/
|
|
122
|
+
private static parsePair(
|
|
123
|
+
parser: BinaryParser,
|
|
124
|
+
): [string, SerializedType | null] {
|
|
125
|
+
const keyVL = parser.readVariableLength()
|
|
126
|
+
const key = new TextDecoder().decode(keyVL)
|
|
127
|
+
|
|
128
|
+
const valueVL = parser.readVariableLength()
|
|
129
|
+
let value: SerializedType | null = null
|
|
130
|
+
|
|
131
|
+
if (valueVL.length > 0) {
|
|
132
|
+
const valueSit = new BinaryParser(bytesToHex(valueVL))
|
|
133
|
+
value = STJson.makeValueFromVLWithType(valueSit)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return [key, value]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Factory for SType value from VL blob (with SType marker)
|
|
141
|
+
*/
|
|
142
|
+
private static makeValueFromVLWithType(parser: BinaryParser): SerializedType {
|
|
143
|
+
if (parser.size() === 0) {
|
|
144
|
+
throw new Error('Empty data when parsing STJson value')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const typeId = parser.read(1)[0]
|
|
148
|
+
|
|
149
|
+
// Delegate to appropriate type's fromParser
|
|
150
|
+
// This is a placeholder - actual implementation would dispatch to concrete types
|
|
151
|
+
// For now, we create an STJson if type is Object or Array
|
|
152
|
+
if (typeId === STJson.JsonType.Object || typeId === STJson.JsonType.Array) {
|
|
153
|
+
return STJson.fromParser(parser)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
throw new Error(`Unsupported type ID in STJson: ${typeId}`)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Check if this is an array type
|
|
161
|
+
*/
|
|
162
|
+
isArray(): boolean {
|
|
163
|
+
return this.jsonType === STJson.JsonType.Array
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Check if this is an object type
|
|
168
|
+
*/
|
|
169
|
+
isObject(): boolean {
|
|
170
|
+
return this.jsonType === STJson.JsonType.Object
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Get the JSON type
|
|
175
|
+
*/
|
|
176
|
+
getType(): number {
|
|
177
|
+
return this.jsonType
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get nesting depth (0 = no nesting, 1 = one level of nesting)
|
|
182
|
+
*/
|
|
183
|
+
getDepth(): number {
|
|
184
|
+
if (this.isArray()) {
|
|
185
|
+
const array = this.data as (SerializedType | null)[]
|
|
186
|
+
for (const value of array) {
|
|
187
|
+
if (value && value instanceof STJson) {
|
|
188
|
+
return 1 + value.getDepth()
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return 0
|
|
192
|
+
} else {
|
|
193
|
+
// isObject()
|
|
194
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
195
|
+
for (const value of map.values()) {
|
|
196
|
+
if (value && value instanceof STJson) {
|
|
197
|
+
return 1 + value.getDepth()
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return 0
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validate nesting depth (max 1 level)
|
|
206
|
+
*/
|
|
207
|
+
private validateDepth(
|
|
208
|
+
value: SerializedType | null,
|
|
209
|
+
currentDepth: number,
|
|
210
|
+
): void {
|
|
211
|
+
if (!value) {
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!(value instanceof STJson)) {
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const valueDepth = value.getDepth()
|
|
220
|
+
if (currentDepth + valueDepth > 1) {
|
|
221
|
+
throw new Error('STJson nesting depth exceeds maximum of 1')
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Set a field in an object
|
|
227
|
+
*/
|
|
228
|
+
setObjectField(key: string, value: SerializedType | null): void {
|
|
229
|
+
if (!this.isObject()) {
|
|
230
|
+
throw new Error('STJson::setObjectField called on non-object')
|
|
231
|
+
}
|
|
232
|
+
this.validateDepth(value, 0)
|
|
233
|
+
;(this.data as Map<string, SerializedType | null>).set(key, value)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Get a field from an object
|
|
238
|
+
*/
|
|
239
|
+
getObjectField(key: string): SerializedType | null | undefined {
|
|
240
|
+
if (!this.isObject()) {
|
|
241
|
+
return undefined
|
|
242
|
+
}
|
|
243
|
+
return (this.data as Map<string, SerializedType | null>).get(key)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Set a nested object field (one level deep)
|
|
248
|
+
*/
|
|
249
|
+
setNestedObjectField(
|
|
250
|
+
key: string,
|
|
251
|
+
nestedKey: string,
|
|
252
|
+
value: SerializedType | null,
|
|
253
|
+
): void {
|
|
254
|
+
if (!this.isObject()) {
|
|
255
|
+
throw new Error('STJson::setNestedObjectField called on non-object')
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
259
|
+
let nestedObj = map.get(key)
|
|
260
|
+
|
|
261
|
+
if (!nestedObj || !(nestedObj instanceof STJson) || !nestedObj.isObject()) {
|
|
262
|
+
const newNested = STJson.createEmpty(STJson.JsonType.Object)
|
|
263
|
+
map.set(key, newNested as SerializedType)
|
|
264
|
+
nestedObj = newNested
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (nestedObj instanceof STJson) {
|
|
268
|
+
nestedObj.setObjectField(nestedKey, value)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Get a nested object field
|
|
274
|
+
*/
|
|
275
|
+
getNestedObjectField(
|
|
276
|
+
key: string,
|
|
277
|
+
nestedKey: string,
|
|
278
|
+
): SerializedType | null | undefined {
|
|
279
|
+
if (!this.isObject()) {
|
|
280
|
+
return undefined
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const nestedObj = (this.data as Map<string, SerializedType | null>).get(key)
|
|
284
|
+
if (nestedObj instanceof STJson && nestedObj.isObject()) {
|
|
285
|
+
return nestedObj.getObjectField(nestedKey)
|
|
286
|
+
}
|
|
287
|
+
return undefined
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Get the inner data as a Map (for objects)
|
|
292
|
+
*/
|
|
293
|
+
getMap(): Map<string, SerializedType | null> {
|
|
294
|
+
if (!this.isObject()) {
|
|
295
|
+
throw new Error('STJson is not an object type')
|
|
296
|
+
}
|
|
297
|
+
return this.data as Map<string, SerializedType | null>
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Get the inner data as an array
|
|
302
|
+
*/
|
|
303
|
+
getArray(): (SerializedType | null)[] {
|
|
304
|
+
if (!this.isArray()) {
|
|
305
|
+
throw new Error('STJson is not an array type')
|
|
306
|
+
}
|
|
307
|
+
return this.data as (SerializedType | null)[]
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Push an element to an array
|
|
312
|
+
*/
|
|
313
|
+
pushArrayElement(value: SerializedType | null): void {
|
|
314
|
+
if (!this.isArray()) {
|
|
315
|
+
throw new Error('STJson::pushArrayElement called on non-array')
|
|
316
|
+
}
|
|
317
|
+
this.validateDepth(value, 0)
|
|
318
|
+
;(this.data as (SerializedType | null)[]).push(value)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Get an array element by index
|
|
323
|
+
*/
|
|
324
|
+
getArrayElement(index: number): SerializedType | null | undefined {
|
|
325
|
+
if (!this.isArray()) {
|
|
326
|
+
return undefined
|
|
327
|
+
}
|
|
328
|
+
const array = this.data as (SerializedType | null)[]
|
|
329
|
+
return array[index]
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Set an array element by index
|
|
334
|
+
*/
|
|
335
|
+
setArrayElement(index: number, value: SerializedType | null): void {
|
|
336
|
+
if (!this.isArray()) {
|
|
337
|
+
throw new Error('STJson::setArrayElement called on non-array')
|
|
338
|
+
}
|
|
339
|
+
this.validateDepth(value, 0)
|
|
340
|
+
|
|
341
|
+
const array = this.data as (SerializedType | null)[]
|
|
342
|
+
// Auto-resize with nulls if needed
|
|
343
|
+
if (index >= array.length) {
|
|
344
|
+
array.length = index + 1
|
|
345
|
+
array.fill(null)
|
|
346
|
+
}
|
|
347
|
+
array[index] = value
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Set a field within an array element (element must be an object)
|
|
352
|
+
*/
|
|
353
|
+
setArrayElementField(
|
|
354
|
+
index: number,
|
|
355
|
+
key: string,
|
|
356
|
+
value: SerializedType | null,
|
|
357
|
+
): void {
|
|
358
|
+
if (!this.isArray()) {
|
|
359
|
+
throw new Error('STJson::setArrayElementField called on non-array')
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
this.validateDepth(value, 1)
|
|
363
|
+
|
|
364
|
+
const array = this.data as (SerializedType | null)[]
|
|
365
|
+
// Auto-resize with nulls if needed
|
|
366
|
+
if (index >= array.length) {
|
|
367
|
+
array.length = index + 1
|
|
368
|
+
array.fill(null)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
let element = array[index]
|
|
372
|
+
if (!element || !(element instanceof STJson) || !element.isObject()) {
|
|
373
|
+
const newElement = STJson.createEmpty(STJson.JsonType.Object)
|
|
374
|
+
array[index] = newElement as SerializedType
|
|
375
|
+
element = newElement
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (element instanceof STJson) {
|
|
379
|
+
element.setObjectField(key, value)
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Get a field within an array element
|
|
385
|
+
*/
|
|
386
|
+
getArrayElementField(
|
|
387
|
+
index: number,
|
|
388
|
+
key: string,
|
|
389
|
+
): SerializedType | null | undefined {
|
|
390
|
+
if (!this.isArray()) {
|
|
391
|
+
return undefined
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const array = this.data as (SerializedType | null)[]
|
|
395
|
+
if (index >= array.length) {
|
|
396
|
+
return undefined
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const element = array[index]
|
|
400
|
+
if (element instanceof STJson && element.isObject()) {
|
|
401
|
+
return element.getObjectField(key)
|
|
402
|
+
}
|
|
403
|
+
return undefined
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Get the size of the array
|
|
408
|
+
*/
|
|
409
|
+
arraySize(): number {
|
|
410
|
+
if (!this.isArray()) {
|
|
411
|
+
return 0
|
|
412
|
+
}
|
|
413
|
+
return (this.data as (SerializedType | null)[]).length
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Set a nested array element (array stored in object field)
|
|
418
|
+
*/
|
|
419
|
+
setNestedArrayElement(
|
|
420
|
+
key: string,
|
|
421
|
+
index: number,
|
|
422
|
+
value: SerializedType | null,
|
|
423
|
+
): void {
|
|
424
|
+
if (!this.isObject()) {
|
|
425
|
+
throw new Error('STJson::setNestedArrayElement called on non-object')
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
this.validateDepth(value, 1)
|
|
429
|
+
|
|
430
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
431
|
+
let arrayJson = map.get(key)
|
|
432
|
+
|
|
433
|
+
if (!arrayJson || !(arrayJson instanceof STJson) || !arrayJson.isArray()) {
|
|
434
|
+
const newArray = STJson.createEmpty(STJson.JsonType.Array)
|
|
435
|
+
map.set(key, newArray as SerializedType)
|
|
436
|
+
arrayJson = newArray
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (arrayJson instanceof STJson) {
|
|
440
|
+
arrayJson.setArrayElement(index, value)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Set a field within a nested array element
|
|
446
|
+
*/
|
|
447
|
+
// eslint-disable-next-line max-params -- all 4 params are needed to address a nested array element field
|
|
448
|
+
setNestedArrayElementField(
|
|
449
|
+
key: string,
|
|
450
|
+
index: number,
|
|
451
|
+
nestedKey: string,
|
|
452
|
+
value: SerializedType | null,
|
|
453
|
+
): void {
|
|
454
|
+
if (!this.isObject()) {
|
|
455
|
+
throw new Error('STJson::setNestedArrayElementField called on non-object')
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
this.validateDepth(value, 1)
|
|
459
|
+
|
|
460
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
461
|
+
let arrayJson = map.get(key)
|
|
462
|
+
|
|
463
|
+
if (!arrayJson || !(arrayJson instanceof STJson) || !arrayJson.isArray()) {
|
|
464
|
+
const newArray = STJson.createEmpty(STJson.JsonType.Array)
|
|
465
|
+
map.set(key, newArray as SerializedType)
|
|
466
|
+
arrayJson = newArray
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (arrayJson instanceof STJson) {
|
|
470
|
+
arrayJson.setArrayElementField(index, nestedKey, value)
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Get a nested array element
|
|
476
|
+
*/
|
|
477
|
+
getNestedArrayElement(
|
|
478
|
+
key: string,
|
|
479
|
+
index: number,
|
|
480
|
+
): SerializedType | null | undefined {
|
|
481
|
+
if (!this.isObject()) {
|
|
482
|
+
return undefined
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const arrayJson = (this.data as Map<string, SerializedType | null>).get(key)
|
|
486
|
+
if (arrayJson instanceof STJson && arrayJson.isArray()) {
|
|
487
|
+
return arrayJson.getArrayElement(index)
|
|
488
|
+
}
|
|
489
|
+
return undefined
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Get a field within a nested array element
|
|
494
|
+
*/
|
|
495
|
+
getNestedArrayElementField(
|
|
496
|
+
key: string,
|
|
497
|
+
index: number,
|
|
498
|
+
nestedKey: string,
|
|
499
|
+
): SerializedType | null | undefined {
|
|
500
|
+
if (!this.isObject()) {
|
|
501
|
+
return undefined
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const arrayJson = (this.data as Map<string, SerializedType | null>).get(key)
|
|
505
|
+
if (arrayJson instanceof STJson && arrayJson.isArray()) {
|
|
506
|
+
return arrayJson.getArrayElementField(index, nestedKey)
|
|
507
|
+
}
|
|
508
|
+
return undefined
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Serialize to binary
|
|
513
|
+
*/
|
|
514
|
+
add(s: BinarySerializer): void {
|
|
515
|
+
const bytesList = new BytesList()
|
|
516
|
+
const tmp = new BinarySerializer(bytesList)
|
|
517
|
+
|
|
518
|
+
// Add type byte
|
|
519
|
+
tmp.put(new Uint8Array([this.jsonType]))
|
|
520
|
+
|
|
521
|
+
if (this.isArray()) {
|
|
522
|
+
const array = this.data as (SerializedType | null)[]
|
|
523
|
+
for (const value of array) {
|
|
524
|
+
STJson.addVLValue(tmp, value)
|
|
525
|
+
}
|
|
526
|
+
} else {
|
|
527
|
+
// isObject()
|
|
528
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
529
|
+
for (const [key, value] of map.entries()) {
|
|
530
|
+
STJson.addVLKey(tmp, key)
|
|
531
|
+
STJson.addVLValue(tmp, value)
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const innerBytes = bytesList.toBytes()
|
|
536
|
+
const lengthBytes = BinarySerializer.encodeVariableLength(innerBytes.length)
|
|
537
|
+
s.put(lengthBytes)
|
|
538
|
+
s.put(innerBytes)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Encode a key as VL
|
|
543
|
+
*/
|
|
544
|
+
private static addVLKey(s: BinarySerializer, str: string): void {
|
|
545
|
+
const keyBytes = new TextEncoder().encode(str)
|
|
546
|
+
const lengthBytes = BinarySerializer.encodeVariableLength(keyBytes.length)
|
|
547
|
+
s.put(lengthBytes)
|
|
548
|
+
s.put(keyBytes)
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Encode a value as [SType marker][VL]
|
|
553
|
+
*/
|
|
554
|
+
private static addVLValue(
|
|
555
|
+
s: BinarySerializer,
|
|
556
|
+
value: SerializedType | null,
|
|
557
|
+
): void {
|
|
558
|
+
if (!value) {
|
|
559
|
+
s.put(BinarySerializer.encodeVariableLength(0))
|
|
560
|
+
return
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const bytesList = new BytesList()
|
|
564
|
+
const tmp = new BinarySerializer(bytesList)
|
|
565
|
+
tmp.put(new Uint8Array([value.getSType()]))
|
|
566
|
+
value.toBytesSink(bytesList)
|
|
567
|
+
|
|
568
|
+
const innerBytes = bytesList.toBytes()
|
|
569
|
+
const lengthBytes = BinarySerializer.encodeVariableLength(innerBytes.length)
|
|
570
|
+
s.put(lengthBytes)
|
|
571
|
+
s.put(innerBytes)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Convert to JSON representation
|
|
576
|
+
*/
|
|
577
|
+
toJSON(): JsonObject | JsonObject[] {
|
|
578
|
+
if (this.isArray()) {
|
|
579
|
+
const array = this.data as (SerializedType | null)[]
|
|
580
|
+
return array.map((item) => {
|
|
581
|
+
return item ? item.toJSON() : null
|
|
582
|
+
}) as JsonObject[]
|
|
583
|
+
} else {
|
|
584
|
+
// isObject()
|
|
585
|
+
const map = this.data as Map<string, SerializedType | null>
|
|
586
|
+
const result: JsonObject = {}
|
|
587
|
+
for (const [key, value] of map.entries()) {
|
|
588
|
+
result[key] = value ? value.toJSON() : null
|
|
589
|
+
}
|
|
590
|
+
return result
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Compare with another STJson for equivalence
|
|
596
|
+
*/
|
|
597
|
+
isEquivalent(t: SerializedType): boolean {
|
|
598
|
+
if (!(t instanceof STJson)) {
|
|
599
|
+
return false
|
|
600
|
+
}
|
|
601
|
+
return bytesToHex(this.bytes) === bytesToHex(t.bytes)
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Check if this is the default value
|
|
606
|
+
*/
|
|
607
|
+
isDefault(): boolean {
|
|
608
|
+
return this.default_
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Get blob representation
|
|
613
|
+
*/
|
|
614
|
+
toBlob(): Uint8Array {
|
|
615
|
+
const bytesList = new BytesList()
|
|
616
|
+
const s = new BinarySerializer(bytesList)
|
|
617
|
+
this.add(s)
|
|
618
|
+
return bytesList.toBytes()
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Get the size (number of bytes in serialized form)
|
|
623
|
+
*/
|
|
624
|
+
size(): number {
|
|
625
|
+
const bytesList = new BytesList()
|
|
626
|
+
const s = new BinarySerializer(bytesList)
|
|
627
|
+
this.add(s)
|
|
628
|
+
return bytesList.getLength()
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Set the value from another STJson
|
|
633
|
+
*/
|
|
634
|
+
setValue(v: STJson): void {
|
|
635
|
+
if (!(v instanceof STJson)) {
|
|
636
|
+
throw new Error('setValue: value must be STJson')
|
|
637
|
+
}
|
|
638
|
+
this.data = v.data
|
|
639
|
+
this.jsonType = v.jsonType
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Get serialized type ID
|
|
644
|
+
*/
|
|
645
|
+
getSType(): SerializedTypeID {
|
|
646
|
+
return SerializedTypeID.STI_JSON
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
export { STJson }
|
package/src/types/path-set.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AccountID } from './account-id'
|
|
2
2
|
import { Currency } from './currency'
|
|
3
3
|
import { BinaryParser } from '../serdes/binary-parser'
|
|
4
|
-
import { SerializedType, JsonObject } from './serialized-type'
|
|
4
|
+
import { SerializedType, JsonObject, SerializedTypeID } from './serialized-type'
|
|
5
5
|
import { bytesToHex, concat } from '@xrplf/isomorphic/utils'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -285,6 +285,10 @@ class PathSet extends SerializedType {
|
|
|
285
285
|
|
|
286
286
|
return json
|
|
287
287
|
}
|
|
288
|
+
|
|
289
|
+
getSType(): SerializedTypeID {
|
|
290
|
+
return SerializedTypeID.STI_PATHSET
|
|
291
|
+
}
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
export { PathSet }
|