gen-typescript-from-tolk-dev 0.2.4 → 0.3.1
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/README.md +23 -3
- package/dist/abi-types.d.ts +33 -20
- package/dist/abi.d.ts +12 -11
- package/dist/codegen-ctx.d.ts +3 -12
- package/dist/codegen-ctx.js +4 -42
- package/dist/dynamic-ctx.d.ts +2 -2
- package/dist/dynamic-ctx.js +5 -5
- package/dist/dynamic-debug-print.d.ts +1 -2
- package/dist/dynamic-debug-print.js +36 -34
- package/dist/dynamic-get-methods.d.ts +1 -2
- package/dist/dynamic-get-methods.js +78 -78
- package/dist/dynamic-serialization.d.ts +8 -9
- package/dist/dynamic-serialization.js +85 -81
- package/dist/dynamic-validation.d.ts +8 -8
- package/dist/dynamic-validation.js +15 -15
- package/dist/emit-field-defs.d.ts +3 -3
- package/dist/emit-field-defs.js +11 -10
- package/dist/emit-pack-unpack.d.ts +14 -8
- package/dist/emit-pack-unpack.js +158 -82
- package/dist/emit-stack-rw.d.ts +2 -3
- package/dist/emit-stack-rw.js +64 -63
- package/dist/emit-ts-types.d.ts +6 -3
- package/dist/emit-ts-types.js +22 -14
- package/dist/generate-ts-wrappers.d.ts +3 -1
- package/dist/generate-ts-wrappers.js +101 -139
- package/dist/index.d.ts +3 -4
- package/dist/index.js +2 -9
- package/dist/types-kernel.d.ts +24 -6
- package/dist/types-kernel.js +154 -75
- package/dist/unsupported-errors.d.ts +1 -2
- package/dist/unsupported-errors.js +2 -3
- package/package.json +1 -1
|
@@ -43,6 +43,7 @@ const c = __importStar(require("@ton/core"));
|
|
|
43
43
|
const unsupported_errors_1 = require("./unsupported-errors");
|
|
44
44
|
const dynamic_validation_1 = require("./dynamic-validation");
|
|
45
45
|
const types_kernel_1 = require("./types-kernel");
|
|
46
|
+
const emit_ts_types_1 = require("./emit-ts-types");
|
|
46
47
|
/*
|
|
47
48
|
Dynamic serialization works without generating TypeScript wrappers.
|
|
48
49
|
Just given an ABI, serialize any JS input to a cell, and unpack back.
|
|
@@ -55,95 +56,97 @@ const types_kernel_1 = require("./types-kernel");
|
|
|
55
56
|
function lookupPrefix(s, expected, prefixLen) {
|
|
56
57
|
return s.remainingBits >= prefixLen && s.preloadUint(prefixLen) === expected;
|
|
57
58
|
}
|
|
58
|
-
function createTonCoreDictionaryKey(fieldPath,
|
|
59
|
+
function createTonCoreDictionaryKey(ctx, fieldPath, tyKIdx) {
|
|
60
|
+
const tyK = ctx.symbols.tyByIdx(tyKIdx);
|
|
59
61
|
if (tyK.kind === 'intN')
|
|
60
62
|
return c.Dictionary.Keys.BigInt(tyK.n);
|
|
61
63
|
if (tyK.kind === 'uintN')
|
|
62
64
|
return c.Dictionary.Keys.BigUint(tyK.n);
|
|
63
65
|
if (tyK.kind === 'address')
|
|
64
66
|
return c.Dictionary.Keys.Address();
|
|
65
|
-
throw new unsupported_errors_1.NonStandardDictKey(`'${fieldPath}' is 'map<${(0, types_kernel_1.renderTy)(
|
|
67
|
+
throw new unsupported_errors_1.NonStandardDictKey(`'${fieldPath}' is 'map<${(0, types_kernel_1.renderTy)(ctx.symbols, tyKIdx)}, ...>': such a non-standard map key can not be handled by @ton/core library`);
|
|
66
68
|
}
|
|
67
|
-
function createTonCoreDictionaryValue(ctx, fieldPath,
|
|
69
|
+
function createTonCoreDictionaryValue(ctx, fieldPath, tyVIdx) {
|
|
68
70
|
return {
|
|
69
71
|
serialize(self, b) {
|
|
70
|
-
dynamicPack(ctx, fieldPath,
|
|
72
|
+
dynamicPack(ctx, fieldPath, tyVIdx, self, b);
|
|
71
73
|
},
|
|
72
74
|
parse(s) {
|
|
73
|
-
return dynamicUnpack(ctx, fieldPath,
|
|
75
|
+
return dynamicUnpack(ctx, fieldPath, tyVIdx, s);
|
|
74
76
|
}
|
|
75
77
|
};
|
|
76
78
|
}
|
|
77
79
|
// Parameter `fieldPath` is used for error messages only, e.g. when provided invalid input.
|
|
78
|
-
function dynamicPack(ctx, fieldPath,
|
|
80
|
+
function dynamicPack(ctx, fieldPath, tyIdx, v, b, uLabelTyIdx) {
|
|
81
|
+
const ty = ctx.symbols.tyByIdx(tyIdx);
|
|
79
82
|
switch (ty.kind) {
|
|
80
83
|
case 'intN': {
|
|
81
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
84
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
82
85
|
b.storeInt(v, ty.n);
|
|
83
86
|
break;
|
|
84
87
|
}
|
|
85
88
|
case 'uintN': {
|
|
86
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
89
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
87
90
|
b.storeUint(v, ty.n);
|
|
88
91
|
break;
|
|
89
92
|
}
|
|
90
93
|
case 'varintN': {
|
|
91
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
94
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
92
95
|
b.storeVarInt(v, Math.log2(ty.n));
|
|
93
96
|
break;
|
|
94
97
|
}
|
|
95
98
|
case 'varuintN': {
|
|
96
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
99
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
97
100
|
b.storeVarUint(v, Math.log2(ty.n));
|
|
98
101
|
break;
|
|
99
102
|
}
|
|
100
103
|
case 'coins': {
|
|
101
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
104
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
102
105
|
b.storeCoins(v);
|
|
103
106
|
break;
|
|
104
107
|
}
|
|
105
108
|
case 'bool': {
|
|
106
|
-
(0, dynamic_validation_1.checkIsBoolean)(fieldPath,
|
|
109
|
+
(0, dynamic_validation_1.checkIsBoolean)(ctx, fieldPath, tyIdx, v);
|
|
107
110
|
b.storeBit(v);
|
|
108
111
|
break;
|
|
109
112
|
}
|
|
110
113
|
case 'cell': {
|
|
111
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
114
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
112
115
|
b.storeRef(v);
|
|
113
116
|
break;
|
|
114
117
|
}
|
|
115
118
|
case 'builder': {
|
|
116
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
119
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
117
120
|
b.storeBuilder(v);
|
|
118
121
|
break;
|
|
119
122
|
}
|
|
120
123
|
case 'slice': {
|
|
121
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
124
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
122
125
|
b.storeSlice(v);
|
|
123
126
|
break;
|
|
124
127
|
}
|
|
125
128
|
case 'string': {
|
|
126
|
-
(0, dynamic_validation_1.checkIsString)(fieldPath,
|
|
129
|
+
(0, dynamic_validation_1.checkIsString)(ctx, fieldPath, tyIdx, v);
|
|
127
130
|
b.storeStringRefTail(v);
|
|
128
131
|
break;
|
|
129
132
|
}
|
|
130
133
|
case 'remaining': {
|
|
131
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
134
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
132
135
|
b.storeSlice(v);
|
|
133
136
|
break;
|
|
134
137
|
}
|
|
135
138
|
case 'address': {
|
|
136
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
139
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
137
140
|
b.storeAddress(v);
|
|
138
141
|
break;
|
|
139
142
|
}
|
|
140
143
|
case 'addressOpt': {
|
|
141
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
144
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v, true);
|
|
142
145
|
b.storeAddress(v);
|
|
143
146
|
break;
|
|
144
147
|
}
|
|
145
148
|
case 'addressExt': {
|
|
146
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
149
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
147
150
|
b.storeAddress(v);
|
|
148
151
|
break;
|
|
149
152
|
}
|
|
@@ -152,15 +155,15 @@ function dynamicPack(ctx, fieldPath, ty, v, b) {
|
|
|
152
155
|
b.storeAddress(null);
|
|
153
156
|
}
|
|
154
157
|
else {
|
|
155
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
158
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
156
159
|
b.storeAddress(v);
|
|
157
160
|
}
|
|
158
161
|
break;
|
|
159
162
|
}
|
|
160
163
|
case 'bitsN': {
|
|
161
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
164
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
162
165
|
if (v.remainingBits !== ty.n || v.remainingRefs !== 0) {
|
|
163
|
-
(0, dynamic_validation_1.throwInvalidInput)(fieldPath,
|
|
166
|
+
(0, dynamic_validation_1.throwInvalidInput)(ctx, fieldPath, tyIdx, `expected ${ty.n} bits and 0 refs, got ${v.remainingBits} bits and ${v.remainingRefs} refs`);
|
|
164
167
|
}
|
|
165
168
|
b.storeSlice(v);
|
|
166
169
|
break;
|
|
@@ -171,24 +174,24 @@ function dynamicPack(ctx, fieldPath, ty, v, b) {
|
|
|
171
174
|
}
|
|
172
175
|
else {
|
|
173
176
|
b.storeUint(1, 1);
|
|
174
|
-
dynamicPack(ctx, fieldPath, ty.
|
|
177
|
+
dynamicPack(ctx, fieldPath, ty.inner_ty_idx, v, b);
|
|
175
178
|
}
|
|
176
179
|
break;
|
|
177
180
|
}
|
|
178
181
|
case 'cellOf': {
|
|
179
|
-
(0, dynamic_validation_1.checkIsObjectWithProperty)(fieldPath,
|
|
182
|
+
(0, dynamic_validation_1.checkIsObjectWithProperty)(ctx, fieldPath, tyIdx, v, 'ref');
|
|
180
183
|
let b_ref = c.beginCell();
|
|
181
|
-
dynamicPack(ctx, fieldPath, ty.
|
|
184
|
+
dynamicPack(ctx, fieldPath, ty.inner_ty_idx, v.ref, b_ref);
|
|
182
185
|
b.storeRef(b_ref.endCell());
|
|
183
186
|
break;
|
|
184
187
|
}
|
|
185
188
|
case 'arrayOf': {
|
|
186
|
-
(0, dynamic_validation_1.checkIsArray)(fieldPath,
|
|
189
|
+
(0, dynamic_validation_1.checkIsArray)(ctx, fieldPath, tyIdx, v);
|
|
187
190
|
// the compiler stores array<T> in chunks; in TypeScript, for simplicity, store "1 elem = 1 ref"
|
|
188
191
|
let tail = null;
|
|
189
192
|
for (let i = 0; i < v.length; ++i) {
|
|
190
193
|
let chunkB = c.beginCell().storeMaybeRef(tail);
|
|
191
|
-
dynamicPack(ctx, fieldPath + '[ith]', ty.
|
|
194
|
+
dynamicPack(ctx, fieldPath + '[ith]', ty.inner_ty_idx, v[v.length - 1 - i], chunkB);
|
|
192
195
|
tail = chunkB.endCell();
|
|
193
196
|
}
|
|
194
197
|
b.storeUint(v.length, 8);
|
|
@@ -196,11 +199,11 @@ function dynamicPack(ctx, fieldPath, ty, v, b) {
|
|
|
196
199
|
break;
|
|
197
200
|
}
|
|
198
201
|
case 'lispListOf': {
|
|
199
|
-
(0, dynamic_validation_1.checkIsArray)(fieldPath,
|
|
202
|
+
(0, dynamic_validation_1.checkIsArray)(ctx, fieldPath, tyIdx, v);
|
|
200
203
|
let tail = c.Cell.EMPTY;
|
|
201
204
|
for (let i = 0; i < v.length; ++i) {
|
|
202
205
|
let itemB = c.beginCell();
|
|
203
|
-
dynamicPack(ctx, `${fieldPath}[${i}]`, ty.
|
|
206
|
+
dynamicPack(ctx, `${fieldPath}[${i}]`, ty.inner_ty_idx, v[i], itemB);
|
|
204
207
|
tail = itemB.storeRef(tail).endCell();
|
|
205
208
|
}
|
|
206
209
|
b.storeRef(tail);
|
|
@@ -208,50 +211,49 @@ function dynamicPack(ctx, fieldPath, ty, v, b) {
|
|
|
208
211
|
}
|
|
209
212
|
case 'tensor': // `(T1, T2)` and `[T1, T2]` are both TypeScript arrays
|
|
210
213
|
case 'shapedTuple': { // (but in Tolk, they are different: a tensor and a TVM shaped tuple)
|
|
211
|
-
(0, dynamic_validation_1.checkIsArray)(fieldPath,
|
|
214
|
+
(0, dynamic_validation_1.checkIsArray)(ctx, fieldPath, tyIdx, v, ty.items_ty_idx.length);
|
|
212
215
|
for (let i = 0; i < v.length; ++i) {
|
|
213
|
-
dynamicPack(ctx, `${fieldPath}[${i}]`, ty.
|
|
216
|
+
dynamicPack(ctx, `${fieldPath}[${i}]`, ty.items_ty_idx[i], v[i], b);
|
|
214
217
|
}
|
|
215
218
|
break;
|
|
216
219
|
}
|
|
217
220
|
case 'mapKV': {
|
|
218
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
219
|
-
let dictKey = createTonCoreDictionaryKey(fieldPath, ty.
|
|
220
|
-
let dictValue = createTonCoreDictionaryValue(ctx, fieldPath, ty.
|
|
221
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
222
|
+
let dictKey = createTonCoreDictionaryKey(ctx, fieldPath, ty.key_ty_idx);
|
|
223
|
+
let dictValue = createTonCoreDictionaryValue(ctx, fieldPath, ty.value_ty_idx);
|
|
221
224
|
b.storeDict(v, dictKey, dictValue);
|
|
222
225
|
break;
|
|
223
226
|
}
|
|
224
227
|
case 'EnumRef': {
|
|
225
|
-
(0, dynamic_validation_1.checkIsNumber)(fieldPath,
|
|
228
|
+
(0, dynamic_validation_1.checkIsNumber)(ctx, fieldPath, tyIdx, v);
|
|
226
229
|
let enumRef = ctx.symbols.getEnum(ty.enum_name);
|
|
227
230
|
if (enumRef.custom_pack_unpack?.pack_to_builder) {
|
|
228
231
|
ctx.getCustomPackFnOrThrow(ty.enum_name, fieldPath)(v, b);
|
|
229
232
|
break;
|
|
230
233
|
}
|
|
231
|
-
dynamicPack(ctx, fieldPath, enumRef.
|
|
234
|
+
dynamicPack(ctx, fieldPath, enumRef.encoded_as_ty_idx, v, b);
|
|
232
235
|
break;
|
|
233
236
|
}
|
|
234
237
|
case 'StructRef': {
|
|
235
|
-
(0, dynamic_validation_1.checkIsObject)(fieldPath,
|
|
238
|
+
(0, dynamic_validation_1.checkIsObject)(ctx, fieldPath, tyIdx, v);
|
|
236
239
|
let structRef = ctx.symbols.getStruct(ty.struct_name);
|
|
237
240
|
if (structRef.custom_pack_unpack?.pack_to_builder) {
|
|
238
241
|
ctx.getCustomPackFnOrThrow(ty.struct_name, fieldPath)(v, b);
|
|
239
242
|
break;
|
|
240
243
|
}
|
|
241
244
|
if (structRef.prefix) {
|
|
242
|
-
b.storeUint(
|
|
245
|
+
b.storeUint(structRef.prefix.prefix_num, structRef.prefix.prefix_len);
|
|
243
246
|
}
|
|
244
|
-
for (let f of
|
|
245
|
-
const fTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(f.ty, structRef.type_params, ty.type_args) : f.ty;
|
|
247
|
+
for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
|
|
246
248
|
try {
|
|
247
|
-
dynamicPack(ctx, `${fieldPath}.${f.name}`,
|
|
249
|
+
dynamicPack(ctx, `${fieldPath}.${f.name}`, f.ty_idx, v[f.name], b, f.uLabelTyIdx);
|
|
248
250
|
}
|
|
249
251
|
catch (ex) {
|
|
250
252
|
if (ex instanceof unsupported_errors_1.InvalidDynamicInput) {
|
|
251
253
|
throw ex;
|
|
252
254
|
}
|
|
253
255
|
// serialization errors from @ton/core, like "value is out of range"
|
|
254
|
-
(0, dynamic_validation_1.throwInvalidInput)(`${fieldPath}.${f.name}`,
|
|
256
|
+
(0, dynamic_validation_1.throwInvalidInput)(ctx, `${fieldPath}.${f.name}`, f.ty_idx, ex.message ?? ex.toString());
|
|
255
257
|
}
|
|
256
258
|
}
|
|
257
259
|
break;
|
|
@@ -262,41 +264,42 @@ function dynamicPack(ctx, fieldPath, ty, v, b) {
|
|
|
262
264
|
ctx.getCustomPackFnOrThrow(ty.alias_name, fieldPath)(v, b);
|
|
263
265
|
break;
|
|
264
266
|
}
|
|
265
|
-
const
|
|
266
|
-
dynamicPack(ctx, fieldPath,
|
|
267
|
+
const target = ctx.symbols.aliasTargetOf(tyIdx);
|
|
268
|
+
dynamicPack(ctx, fieldPath, target.ty_idx, v, b, target.uLabelTyIdx);
|
|
267
269
|
break;
|
|
268
270
|
}
|
|
269
271
|
case 'union': {
|
|
270
|
-
const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants);
|
|
271
|
-
const hasNull = variants.find(v => v.
|
|
272
|
+
const variants = (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx);
|
|
273
|
+
const hasNull = variants.find(v => ctx.symbols.tyByIdx(v.variant_ty_idx).kind === 'nullLiteral');
|
|
272
274
|
if (hasNull && v === null) {
|
|
273
|
-
b.storeUint(
|
|
275
|
+
b.storeUint(hasNull.prefix_num, hasNull.prefix_len);
|
|
274
276
|
}
|
|
275
277
|
else {
|
|
276
|
-
(0, dynamic_validation_1.checkIsObjectWithProperty)(fieldPath,
|
|
278
|
+
(0, dynamic_validation_1.checkIsObjectWithProperty)(ctx, fieldPath, tyIdx, v, '$');
|
|
277
279
|
const activeVariant = variants.find(variant => v.$ === variant.labelStr);
|
|
278
280
|
if (!activeVariant) {
|
|
279
|
-
(0, dynamic_validation_1.throwInvalidInput)(fieldPath,
|
|
281
|
+
(0, dynamic_validation_1.throwInvalidInput)(ctx, fieldPath, tyIdx, `non-existing union variant for $ = '${v.$}'`);
|
|
280
282
|
}
|
|
281
283
|
if (activeVariant.hasValueField && !v.hasOwnProperty('value')) {
|
|
282
|
-
(0, dynamic_validation_1.throwInvalidInput)(fieldPath,
|
|
284
|
+
(0, dynamic_validation_1.throwInvalidInput)(ctx, fieldPath, tyIdx, `expected {$,value} but field 'value' not provided`);
|
|
283
285
|
}
|
|
284
286
|
if (activeVariant.is_prefix_implicit) {
|
|
285
|
-
b.storeUint(
|
|
287
|
+
b.storeUint(activeVariant.prefix_num, activeVariant.prefix_len);
|
|
286
288
|
}
|
|
287
289
|
let actualValue = activeVariant.hasValueField ? v.value : v;
|
|
288
|
-
dynamicPack(ctx, `${fieldPath}#${activeVariant.labelStr}`, activeVariant.
|
|
290
|
+
dynamicPack(ctx, `${fieldPath}#${activeVariant.labelStr}`, activeVariant.variant_ty_idx, actualValue, b);
|
|
289
291
|
}
|
|
290
292
|
break;
|
|
291
293
|
}
|
|
292
294
|
case 'void':
|
|
293
295
|
break;
|
|
294
296
|
default:
|
|
295
|
-
throw new unsupported_errors_1.CantPackDynamic(fieldPath, `type '${(0, types_kernel_1.renderTy)(
|
|
297
|
+
throw new unsupported_errors_1.CantPackDynamic(fieldPath, `type '${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}' is not serializable`);
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
// Parameter `fieldPath` is used for error messages only, e.g. when can't deserialize exact field (bad slice).
|
|
299
|
-
function dynamicUnpack(ctx, fieldPath,
|
|
301
|
+
function dynamicUnpack(ctx, fieldPath, tyIdx, s, uLabelTyIdx) {
|
|
302
|
+
const ty = ctx.symbols.tyByIdx(tyIdx);
|
|
300
303
|
switch (ty.kind) {
|
|
301
304
|
case 'intN': return s.loadIntBig(ty.n);
|
|
302
305
|
case 'uintN': return s.loadUintBig(ty.n);
|
|
@@ -323,10 +326,10 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
323
326
|
}
|
|
324
327
|
case 'bitsN': return new c.Slice(new c.BitReader(s.loadBits(ty.n)), []);
|
|
325
328
|
case 'nullLiteral': return null;
|
|
326
|
-
case 'nullable': return s.loadBoolean() ? dynamicUnpack(ctx, fieldPath, ty.
|
|
329
|
+
case 'nullable': return s.loadBoolean() ? dynamicUnpack(ctx, fieldPath, ty.inner_ty_idx, s) : null;
|
|
327
330
|
case 'cellOf': {
|
|
328
331
|
let s_ref = s.loadRef().beginParse();
|
|
329
|
-
return { ref: dynamicUnpack(ctx, fieldPath, ty.
|
|
332
|
+
return { ref: dynamicUnpack(ctx, fieldPath, ty.inner_ty_idx, s_ref) };
|
|
330
333
|
}
|
|
331
334
|
case 'arrayOf': {
|
|
332
335
|
let len = s.loadUint(8);
|
|
@@ -336,7 +339,7 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
336
339
|
let s = head.beginParse();
|
|
337
340
|
head = s.loadMaybeRef();
|
|
338
341
|
while (s.remainingBits || s.remainingRefs) {
|
|
339
|
-
outArr.push(dynamicUnpack(ctx, fieldPath + '[ith]', ty.
|
|
342
|
+
outArr.push(dynamicUnpack(ctx, fieldPath + '[ith]', ty.inner_ty_idx, s));
|
|
340
343
|
}
|
|
341
344
|
}
|
|
342
345
|
if (len !== outArr.length) {
|
|
@@ -349,7 +352,7 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
349
352
|
let head = s.loadRef().beginParse();
|
|
350
353
|
while (head.remainingRefs) {
|
|
351
354
|
let tailSnaked = head.loadRef();
|
|
352
|
-
let headValue = dynamicUnpack(ctx, fieldPath + '[ith]', ty.
|
|
355
|
+
let headValue = dynamicUnpack(ctx, fieldPath + '[ith]', ty.inner_ty_idx, head);
|
|
353
356
|
head.endParse(); // ensure no data is present besides T
|
|
354
357
|
outArr.unshift(headValue);
|
|
355
358
|
head = tailSnaked.beginParse();
|
|
@@ -358,11 +361,11 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
358
361
|
}
|
|
359
362
|
case 'tensor':
|
|
360
363
|
case 'shapedTuple': {
|
|
361
|
-
return ty.
|
|
364
|
+
return ty.items_ty_idx.map((ty_idx, idx) => dynamicUnpack(ctx, `${fieldPath}[${idx}]`, ty_idx, s));
|
|
362
365
|
}
|
|
363
366
|
case 'mapKV': {
|
|
364
|
-
let dictKey = createTonCoreDictionaryKey(fieldPath, ty.
|
|
365
|
-
let dictValue = createTonCoreDictionaryValue(ctx, fieldPath, ty.
|
|
367
|
+
let dictKey = createTonCoreDictionaryKey(ctx, fieldPath, ty.key_ty_idx);
|
|
368
|
+
let dictValue = createTonCoreDictionaryValue(ctx, fieldPath, ty.value_ty_idx);
|
|
366
369
|
return s.loadDict(dictKey, dictValue);
|
|
367
370
|
}
|
|
368
371
|
case 'EnumRef': {
|
|
@@ -370,7 +373,7 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
370
373
|
if (enumRef.custom_pack_unpack?.unpack_from_slice) {
|
|
371
374
|
return ctx.getCustomUnpackFnOrThrow(ty.enum_name, fieldPath)(s);
|
|
372
375
|
}
|
|
373
|
-
return dynamicUnpack(ctx, fieldPath, enumRef.
|
|
376
|
+
return dynamicUnpack(ctx, fieldPath, enumRef.encoded_as_ty_idx, s);
|
|
374
377
|
}
|
|
375
378
|
case 'StructRef': {
|
|
376
379
|
let structRef = ctx.symbols.getStruct(ty.struct_name);
|
|
@@ -380,14 +383,13 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
380
383
|
let result = { $: ty.struct_name };
|
|
381
384
|
if (structRef.prefix) {
|
|
382
385
|
let prefix = s.loadUint(structRef.prefix.prefix_len);
|
|
383
|
-
if (prefix !==
|
|
384
|
-
throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `incorrect prefix for '${ty.struct_name}', expected ${structRef.prefix
|
|
386
|
+
if (prefix !== structRef.prefix.prefix_num) {
|
|
387
|
+
throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `incorrect prefix for '${ty.struct_name}', expected ${(0, emit_ts_types_1.emitPrefixHex)(structRef.prefix)}`);
|
|
385
388
|
}
|
|
386
389
|
}
|
|
387
|
-
for (let f of
|
|
388
|
-
const fTy = ty.type_args ? (0, types_kernel_1.instantiateGenerics)(f.ty, structRef.type_params, ty.type_args) : f.ty;
|
|
390
|
+
for (let f of ctx.symbols.structFieldsOf(tyIdx)) {
|
|
389
391
|
try {
|
|
390
|
-
result[f.name] = dynamicUnpack(ctx, `${fieldPath}.${f.name}`,
|
|
392
|
+
result[f.name] = dynamicUnpack(ctx, `${fieldPath}.${f.name}`, f.ty_idx, s, f.uLabelTyIdx);
|
|
391
393
|
}
|
|
392
394
|
catch (ex) {
|
|
393
395
|
if (ex instanceof unsupported_errors_1.CantUnpackDynamic) {
|
|
@@ -404,19 +406,19 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
404
406
|
if (aliasRef.custom_pack_unpack?.unpack_from_slice) {
|
|
405
407
|
return ctx.getCustomUnpackFnOrThrow(ty.alias_name, fieldPath)(s);
|
|
406
408
|
}
|
|
407
|
-
const
|
|
408
|
-
return dynamicUnpack(ctx, fieldPath,
|
|
409
|
+
const target = ctx.symbols.aliasTargetOf(tyIdx);
|
|
410
|
+
return dynamicUnpack(ctx, fieldPath, target.ty_idx, s, target.uLabelTyIdx);
|
|
409
411
|
}
|
|
410
|
-
case 'genericT': throw new unsupported_errors_1.CantUnpackDynamic(fieldPath,
|
|
412
|
+
case 'genericT': throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `unexpected genericT at ${fieldPath}`);
|
|
411
413
|
case 'union': {
|
|
412
|
-
for (const variant of (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants)) {
|
|
413
|
-
if (!lookupPrefix(s,
|
|
414
|
+
for (const variant of (0, types_kernel_1.createLabelsForUnion)(ctx.symbols, ty.variants, uLabelTyIdx)) {
|
|
415
|
+
if (!lookupPrefix(s, variant.prefix_num, variant.prefix_len)) {
|
|
414
416
|
continue;
|
|
415
417
|
}
|
|
416
418
|
if (variant.is_prefix_implicit) {
|
|
417
419
|
s.skip(variant.prefix_len);
|
|
418
420
|
}
|
|
419
|
-
let actualValue = dynamicUnpack(ctx, `${fieldPath}#${variant.labelStr}`, variant.
|
|
421
|
+
let actualValue = dynamicUnpack(ctx, `${fieldPath}#${variant.labelStr}`, variant.variant_ty_idx, s);
|
|
420
422
|
if (!variant.hasValueField) {
|
|
421
423
|
return actualValue;
|
|
422
424
|
}
|
|
@@ -427,27 +429,29 @@ function dynamicUnpack(ctx, fieldPath, ty, s) {
|
|
|
427
429
|
case 'void':
|
|
428
430
|
return void 0;
|
|
429
431
|
default:
|
|
430
|
-
throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `type '${(0, types_kernel_1.renderTy)(
|
|
432
|
+
throw new unsupported_errors_1.CantUnpackDynamic(fieldPath, `type '${(0, types_kernel_1.renderTy)(ctx.symbols, tyIdx)}' is not serializable`);
|
|
431
433
|
}
|
|
432
434
|
}
|
|
433
435
|
/**
|
|
434
436
|
* Pack any input to a builder according to an ABI schema.
|
|
435
437
|
* Example: `struct Point { x: int8, y: int8 }`.
|
|
436
438
|
* After being converted, it's stored as ABI.
|
|
437
|
-
* Call: `packToBuilderDynamic(ctx,
|
|
439
|
+
* Call: `packToBuilderDynamic(ctx, pointTyIdx, { x: 10, y: 20 }, b)` appends 0x0A14.
|
|
438
440
|
* When input is incorrect (e.g. missing property in a JS object), throws InvalidDynamicInput.
|
|
439
441
|
*/
|
|
440
|
-
function packToBuilderDynamic(ctx,
|
|
442
|
+
function packToBuilderDynamic(ctx, tyIdx, value, b) {
|
|
443
|
+
let ty = ctx.symbols.tyByIdx(tyIdx);
|
|
441
444
|
let fieldPath = ty.kind === 'StructRef' ? ty.struct_name : 'self';
|
|
442
|
-
dynamicPack(ctx, fieldPath,
|
|
445
|
+
dynamicPack(ctx, fieldPath, tyIdx, value, b);
|
|
443
446
|
}
|
|
444
447
|
/**
|
|
445
448
|
* Unpack any slice to a JS variable according to an ABI schema.
|
|
446
449
|
* Example: `struct Point { x: int8, y: int8 }`.
|
|
447
|
-
* Call: `unpackFromSliceDynamic(ctx,
|
|
450
|
+
* Call: `unpackFromSliceDynamic(ctx, pointTyIdx, hex"0A14")` returns `{ x: 10, y: 20 }`.
|
|
448
451
|
* When ty can't be deserialized, throws CantUnpackDynamic.
|
|
449
452
|
*/
|
|
450
|
-
function unpackFromSliceDynamic(ctx,
|
|
453
|
+
function unpackFromSliceDynamic(ctx, tyIdx, s) {
|
|
454
|
+
let ty = ctx.symbols.tyByIdx(tyIdx);
|
|
451
455
|
let fieldPath = ty.kind === 'StructRef' ? ty.struct_name : 'self';
|
|
452
|
-
return dynamicUnpack(ctx, fieldPath,
|
|
456
|
+
return dynamicUnpack(ctx, fieldPath, tyIdx, s);
|
|
453
457
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare function throwInvalidInput(fieldPath: string,
|
|
3
|
-
export declare function checkIsNumber(fieldPath: string,
|
|
4
|
-
export declare function checkIsBoolean(fieldPath: string,
|
|
5
|
-
export declare function checkIsString(fieldPath: string,
|
|
6
|
-
export declare function checkIsArray(fieldPath: string,
|
|
7
|
-
export declare function checkIsObject(fieldPath: string,
|
|
8
|
-
export declare function checkIsObjectWithProperty(fieldPath: string,
|
|
1
|
+
import { DynamicCtx } from './dynamic-ctx';
|
|
2
|
+
export declare function throwInvalidInput(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, msgWhyInvalid: string): never;
|
|
3
|
+
export declare function checkIsNumber(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any): void;
|
|
4
|
+
export declare function checkIsBoolean(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any): void;
|
|
5
|
+
export declare function checkIsString(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any): void;
|
|
6
|
+
export declare function checkIsArray(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any, expectedLen?: number): void;
|
|
7
|
+
export declare function checkIsObject(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any, allowNull?: boolean): void;
|
|
8
|
+
export declare function checkIsObjectWithProperty(ctx: DynamicCtx, fieldPath: string, expectedTyIdx: number, passedV: any, propertyName: string): void;
|
|
@@ -9,48 +9,48 @@ exports.checkIsObject = checkIsObject;
|
|
|
9
9
|
exports.checkIsObjectWithProperty = checkIsObjectWithProperty;
|
|
10
10
|
const unsupported_errors_1 = require("./unsupported-errors");
|
|
11
11
|
const types_kernel_1 = require("./types-kernel");
|
|
12
|
-
function throwInvalidInput(fieldPath,
|
|
13
|
-
throw new unsupported_errors_1.InvalidDynamicInput(`invalid value passed for '${fieldPath}' of type '${(0, types_kernel_1.renderTy)(
|
|
12
|
+
function throwInvalidInput(ctx, fieldPath, expectedTyIdx, msgWhyInvalid) {
|
|
13
|
+
throw new unsupported_errors_1.InvalidDynamicInput(`invalid value passed for '${fieldPath}' of type '${(0, types_kernel_1.renderTy)(ctx.symbols, expectedTyIdx)}': ${msgWhyInvalid}`);
|
|
14
14
|
}
|
|
15
|
-
function checkIsNumber(fieldPath,
|
|
15
|
+
function checkIsNumber(ctx, fieldPath, expectedTyIdx, passedV) {
|
|
16
16
|
let isNumber = typeof passedV === 'bigint' || typeof passedV === 'number';
|
|
17
17
|
if (!isNumber) {
|
|
18
|
-
throwInvalidInput(fieldPath,
|
|
18
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, 'not a number');
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
function checkIsBoolean(fieldPath,
|
|
21
|
+
function checkIsBoolean(ctx, fieldPath, expectedTyIdx, passedV) {
|
|
22
22
|
let isBoolean = typeof passedV === 'boolean';
|
|
23
23
|
if (!isBoolean) {
|
|
24
|
-
throwInvalidInput(fieldPath,
|
|
24
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, 'not a boolean');
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
function checkIsString(fieldPath,
|
|
27
|
+
function checkIsString(ctx, fieldPath, expectedTyIdx, passedV) {
|
|
28
28
|
let isString = typeof passedV === 'string';
|
|
29
29
|
if (!isString) {
|
|
30
|
-
throwInvalidInput(fieldPath,
|
|
30
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, 'not a string');
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
function checkIsArray(fieldPath,
|
|
33
|
+
function checkIsArray(ctx, fieldPath, expectedTyIdx, passedV, expectedLen) {
|
|
34
34
|
let isArray = Array.isArray(passedV);
|
|
35
35
|
if (!isArray) {
|
|
36
|
-
throwInvalidInput(fieldPath,
|
|
36
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, 'not an array');
|
|
37
37
|
}
|
|
38
38
|
if (expectedLen !== undefined && passedV.length !== expectedLen) {
|
|
39
|
-
throwInvalidInput(fieldPath,
|
|
39
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, `expected ${expectedLen} elements, got ${passedV.length}`);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
function checkIsObject(fieldPath,
|
|
42
|
+
function checkIsObject(ctx, fieldPath, expectedTyIdx, passedV, allowNull = false) {
|
|
43
43
|
let isObject = typeof passedV === 'object' && !Array.isArray(passedV);
|
|
44
44
|
if (passedV === null && !allowNull) {
|
|
45
45
|
isObject = false;
|
|
46
46
|
}
|
|
47
47
|
if (!isObject) {
|
|
48
|
-
throwInvalidInput(fieldPath,
|
|
48
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, 'not an object');
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
function checkIsObjectWithProperty(fieldPath,
|
|
51
|
+
function checkIsObjectWithProperty(ctx, fieldPath, expectedTyIdx, passedV, propertyName) {
|
|
52
52
|
let isObject = typeof passedV === 'object' && !Array.isArray(passedV) && passedV !== null;
|
|
53
53
|
if (!isObject || !passedV.hasOwnProperty(propertyName)) {
|
|
54
|
-
throwInvalidInput(fieldPath,
|
|
54
|
+
throwInvalidInput(ctx, fieldPath, expectedTyIdx, `not an object with property ${propertyName}`);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ABIConstExpression
|
|
1
|
+
import { ABIConstExpression } from './abi-types';
|
|
2
2
|
import { CodegenCtx } from './codegen-ctx';
|
|
3
|
-
export declare function isDefaultValueSupported(
|
|
3
|
+
export declare function isDefaultValueSupported(ctx: CodegenCtx, fieldTyIdx: number): boolean;
|
|
4
4
|
export declare function emitFieldDefault(ctx: CodegenCtx, expr: ABIConstExpression): string;
|
|
5
|
-
export declare function emitFieldDefaultInComment(expr: ABIConstExpression): string;
|
|
5
|
+
export declare function emitFieldDefaultInComment(ctx: CodegenCtx, expr: ABIConstExpression): string;
|
package/dist/emit-field-defs.js
CHANGED
|
@@ -10,15 +10,16 @@ const types_kernel_1 = require("./types-kernel");
|
|
|
10
10
|
// But in theory, a field can be a union, for example. It will require a large amount of work to support
|
|
11
11
|
// cases like `f: int8 | slice = 5` or `f: int32 | int64 = 5 as int64` (to generate correct `$` labels).
|
|
12
12
|
// So, if such a field exists, then we just assume it has no default.
|
|
13
|
-
function isDefaultValueSupported(
|
|
13
|
+
function isDefaultValueSupported(ctx, fieldTyIdx) {
|
|
14
|
+
const fieldTy = ctx.symbols.tyByIdx(fieldTyIdx);
|
|
14
15
|
if (fieldTy.kind === 'arrayOf')
|
|
15
|
-
return isDefaultValueSupported(fieldTy.
|
|
16
|
+
return isDefaultValueSupported(ctx, fieldTy.inner_ty_idx);
|
|
16
17
|
if (fieldTy.kind === 'lispListOf')
|
|
17
|
-
return isDefaultValueSupported(fieldTy.
|
|
18
|
+
return isDefaultValueSupported(ctx, fieldTy.inner_ty_idx);
|
|
18
19
|
if (fieldTy.kind === 'tensor')
|
|
19
|
-
return fieldTy.
|
|
20
|
+
return fieldTy.items_ty_idx.every(ty_idx => isDefaultValueSupported(ctx, ty_idx));
|
|
20
21
|
if (fieldTy.kind === 'shapedTuple')
|
|
21
|
-
return fieldTy.
|
|
22
|
+
return fieldTy.items_ty_idx.every(ty_idx => isDefaultValueSupported(ctx, ty_idx));
|
|
22
23
|
return fieldTy.kind !== 'union' && fieldTy.kind !== 'mapKV';
|
|
23
24
|
}
|
|
24
25
|
// Default values of fields (particularly, in storage) are precalculated by the compiler
|
|
@@ -45,17 +46,17 @@ function emitFieldDefault(ctx, expr) {
|
|
|
45
46
|
// Output a default value not as a TypeScript expression, but as a human-readable one.
|
|
46
47
|
// For instance, "123" instead of bigint "123n".
|
|
47
48
|
// It's inserted inside comments next to fields having defaults.
|
|
48
|
-
function emitFieldDefaultInComment(expr) {
|
|
49
|
+
function emitFieldDefaultInComment(ctx, expr) {
|
|
49
50
|
switch (expr.kind) {
|
|
50
51
|
case 'int': return expr.v;
|
|
51
52
|
case 'bool': return expr.v ? 'true' : 'false';
|
|
52
53
|
case 'slice': return `hex('${expr.hex}')`;
|
|
53
54
|
case 'string': return JSON.stringify(expr.str);
|
|
54
55
|
case 'address': return `address('${expr.addr}')`;
|
|
55
|
-
case 'tensor': return `[${expr.items.map(emitFieldDefaultInComment).join(', ')}]`;
|
|
56
|
-
case 'shapedTuple': return `[${expr.items.map(emitFieldDefaultInComment).join(', ')}]`;
|
|
57
|
-
case 'object': return `${expr.struct_name} { ${expr.fields.map(emitFieldDefaultInComment).join(', ')} }`;
|
|
58
|
-
case 'castTo': return `${emitFieldDefaultInComment(expr.inner)} as ${(0, types_kernel_1.renderTy)(expr.
|
|
56
|
+
case 'tensor': return `[${expr.items.map(i => emitFieldDefaultInComment(ctx, i)).join(', ')}]`;
|
|
57
|
+
case 'shapedTuple': return `[${expr.items.map(i => emitFieldDefaultInComment(ctx, i)).join(', ')}]`;
|
|
58
|
+
case 'object': return `${expr.struct_name} { ${expr.fields.map(i => emitFieldDefaultInComment(ctx, i)).join(', ')} }`;
|
|
59
|
+
case 'castTo': return `${emitFieldDefaultInComment(ctx, expr.inner)} as ${(0, types_kernel_1.renderTy)(ctx.symbols, expr.cast_to_ty_idx)}`;
|
|
59
60
|
case 'null': return `null`;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import type { Ty } from './abi-types';
|
|
2
1
|
import { CodegenCtx } from './codegen-ctx';
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
2
|
+
import { ABIAlias, ABIEnum, ABIStruct } from './abi-types';
|
|
3
|
+
export declare function emitLoadOfStruct(ctx: CodegenCtx, structRef: ABIStruct, instantiationTyIdx: number): string;
|
|
4
|
+
export declare function emitLoadOfAlias(ctx: CodegenCtx, aliasRef: ABIAlias, instantiationTyIdx: number): string;
|
|
5
|
+
export declare function emitLoadOfEnum(ctx: CodegenCtx, enumRef: ABIEnum): string;
|
|
6
|
+
export declare function emitLoadExpr(ctx: CodegenCtx, fieldPath: string, tyIdx: number, uLabelTyIdx?: number): string;
|
|
7
|
+
export declare function emitLoadCallback(ctx: CodegenCtx, fieldPath: string, tyIdx: number): string;
|
|
8
|
+
export declare function emitStoreOfStruct(ctx: CodegenCtx, tsExpr: string, structRef: ABIStruct, instantiationTyIdx: number): string;
|
|
9
|
+
export declare function emitStoreOfAlias(ctx: CodegenCtx, tsExpr: string, aliasRef: ABIAlias, instantiationTyIdx: number): string;
|
|
10
|
+
export declare function emitStoreOfEnum(ctx: CodegenCtx, tsExpr: string, enumRef: ABIEnum): string;
|
|
11
|
+
export declare function emitStoreStatement(ctx: CodegenCtx, tsExpr: string, tyIdx: number, uLabelTyIdx?: number): string;
|
|
12
|
+
export declare function emitStoreCallback(ctx: CodegenCtx, tyIdx: number): string;
|
|
13
|
+
export declare function emitMakeCellFromExpr(ctx: CodegenCtx, tsExpr: string, tyIdx: number, disableShortHand?: boolean): string;
|
|
14
|
+
export declare function emitCallToCreateMethodExpr(ctx: CodegenCtx, bodyArg: string, tyIdx: number): string;
|
|
15
|
+
export declare function emitDictKVSerializers(ctx: CodegenCtx, fieldPath: string, tyKIdx: number, tyVIdx: number): string;
|