codama-renderers-dart 0.5.3 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.browser.cjs +195 -126
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +196 -127
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.cjs +195 -126
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +196 -127
- package/dist/index.node.js.map +1 -1
- package/dist/index.react-native.js +196 -127
- package/dist/index.react-native.js.map +1 -1
- package/dist/types/fragments/accountPage.d.ts.map +1 -1
- package/dist/types/fragments/errorPage.d.ts.map +1 -1
- package/dist/types/fragments/instructionPage.d.ts.map +1 -1
- package/dist/types/fragments/pdaPage.d.ts.map +1 -1
- package/dist/types/fragments/programPage.d.ts.map +1 -1
- package/dist/types/utils/nameTransformers.d.ts.map +1 -1
- package/dist/types/utils/valueNodes.d.ts +4 -0
- package/dist/types/utils/valueNodes.d.ts.map +1 -1
- package/dist/types/visitors/getRenderMapVisitor.d.ts.map +1 -1
- package/dist/types/visitors/getTypeManifestVisitor.d.ts.map +1 -1
- package/dist/types/visitors/renderVisitor.d.ts.map +1 -1
- package/package.json +11 -11
- package/src/fragments/accountPage.ts +2 -1
- package/src/fragments/errorPage.ts +8 -5
- package/src/fragments/instructionPage.ts +51 -21
- package/src/fragments/pdaPage.ts +7 -14
- package/src/fragments/programPage.ts +3 -2
- package/src/utils/formatCode.ts +2 -2
- package/src/utils/nameTransformers.ts +11 -0
- package/src/utils/valueNodes.ts +24 -1
- package/src/visitors/getRenderMapVisitor.ts +30 -5
- package/src/visitors/getTypeManifestVisitor.ts +127 -87
- package/src/visitors/renderVisitor.ts +11 -13
- package/LICENSE +0 -21
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type BooleanTypeNode,
|
|
6
6
|
type BytesTypeNode,
|
|
7
7
|
type CamelCaseString,
|
|
8
|
+
type ConstantValueNode,
|
|
8
9
|
type DateTimeTypeNode,
|
|
9
10
|
type DefinedTypeLinkNode,
|
|
10
11
|
type DefinedTypeNode,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
type StructFieldTypeNode,
|
|
32
33
|
type StructTypeNode,
|
|
33
34
|
type TupleTypeNode,
|
|
35
|
+
type TypeNode,
|
|
34
36
|
type ZeroableOptionTypeNode,
|
|
35
37
|
isNode,
|
|
36
38
|
resolveNestedTypeNode,
|
|
@@ -55,6 +57,7 @@ import {
|
|
|
55
57
|
use,
|
|
56
58
|
} from "../utils/index.js";
|
|
57
59
|
import { type DartNameApi, snakeCase } from "../utils/nameTransformers.js";
|
|
60
|
+
import { getDartValueFragment, getNonNegativeInteger, toDartStringLiteral } from "../utils/valueNodes.js";
|
|
58
61
|
|
|
59
62
|
/**
|
|
60
63
|
* Type alias for the type manifest visitor.
|
|
@@ -121,32 +124,12 @@ export function getTypeManifestVisitor(input: {
|
|
|
121
124
|
);
|
|
122
125
|
|
|
123
126
|
return extendVisitor(baseVisitor, {
|
|
124
|
-
visitNumberType(node: NumberTypeNode
|
|
125
|
-
const { format, endian } = node;
|
|
126
|
-
const endianSuffix =
|
|
127
|
-
endian === "be"
|
|
128
|
-
? ", NumberCodecConfig(endian: Endian.big)"
|
|
129
|
-
: "";
|
|
130
|
-
const endianDecoderSuffix =
|
|
131
|
-
endian === "be"
|
|
132
|
-
? ", NumberCodecConfig(endian: Endian.big)"
|
|
133
|
-
: "";
|
|
134
|
-
|
|
135
|
-
// Map format to Dart type and codec
|
|
136
|
-
const dartType = getNumberDartType(format);
|
|
137
|
-
const codecName = getNumberCodecName(format);
|
|
138
|
-
|
|
127
|
+
visitNumberType(node: NumberTypeNode) {
|
|
139
128
|
return {
|
|
140
129
|
// `BigInt` and other number types live in `dart:core` and need no import.
|
|
141
|
-
type: fragmentFromString(
|
|
142
|
-
encoder:
|
|
143
|
-
|
|
144
|
-
"solanaCodecsNumbers",
|
|
145
|
-
)}(${endianSuffix ? fragmentFromString(endianSuffix.slice(2)) : fragmentFromString("")})`,
|
|
146
|
-
decoder: fragment`${use(
|
|
147
|
-
`get${codecName}Decoder`,
|
|
148
|
-
"solanaCodecsNumbers",
|
|
149
|
-
)}(${endianDecoderSuffix ? fragmentFromString(endianDecoderSuffix.slice(2)) : fragmentFromString("")})`,
|
|
130
|
+
type: fragmentFromString(getNumberDartType(node.format)),
|
|
131
|
+
encoder: getNumberCodecExpression(node, "Encoder"),
|
|
132
|
+
decoder: getNumberCodecExpression(node, "Decoder"),
|
|
150
133
|
value: emptyTypeManifest().value,
|
|
151
134
|
isEnum: false,
|
|
152
135
|
};
|
|
@@ -226,8 +209,8 @@ export function getTypeManifestVisitor(input: {
|
|
|
226
209
|
|
|
227
210
|
visitArrayType(node: ArrayTypeNode, { self }) {
|
|
228
211
|
const itemManifest = visit(node.item, self);
|
|
229
|
-
const encoderSizeExpr = getArraySizeExpression(node, "Encoder");
|
|
230
|
-
const decoderSizeExpr = getArraySizeExpression(node, "Decoder");
|
|
212
|
+
const encoderSizeExpr = getArraySizeExpression(node, "Encoder", self);
|
|
213
|
+
const decoderSizeExpr = getArraySizeExpression(node, "Decoder", self);
|
|
231
214
|
const itemType = fragmentFromString(itemManifest.type.content);
|
|
232
215
|
const itemEncoder = fragment`${use(
|
|
233
216
|
"transformEncoder",
|
|
@@ -252,8 +235,8 @@ export function getTypeManifestVisitor(input: {
|
|
|
252
235
|
visitMapType(node: MapTypeNode, { self }) {
|
|
253
236
|
const keyManifest = visit(node.key, self);
|
|
254
237
|
const valueManifest = visit(node.value, self);
|
|
255
|
-
const encoderSizeExpr = getMapSizeExpression(node, "Encoder");
|
|
256
|
-
const decoderSizeExpr = getMapSizeExpression(node, "Decoder");
|
|
238
|
+
const encoderSizeExpr = getMapSizeExpression(node, "Encoder", self);
|
|
239
|
+
const decoderSizeExpr = getMapSizeExpression(node, "Decoder", self);
|
|
257
240
|
|
|
258
241
|
return {
|
|
259
242
|
type: fragment`Map<${keyManifest.type}, ${valueManifest.type}>`,
|
|
@@ -272,8 +255,8 @@ export function getTypeManifestVisitor(input: {
|
|
|
272
255
|
|
|
273
256
|
visitSetType(node: SetTypeNode, { self }) {
|
|
274
257
|
const itemManifest = visit(node.item, self);
|
|
275
|
-
const encoderSizeExpr = getSetSizeExpression(node, "Encoder");
|
|
276
|
-
const decoderSizeExpr = getSetSizeExpression(node, "Decoder");
|
|
258
|
+
const encoderSizeExpr = getSetSizeExpression(node, "Encoder", self);
|
|
259
|
+
const decoderSizeExpr = getSetSizeExpression(node, "Decoder", self);
|
|
277
260
|
|
|
278
261
|
return {
|
|
279
262
|
type: fragment`Set<${itemManifest.type}>`,
|
|
@@ -355,7 +338,7 @@ export function getTypeManifestVisitor(input: {
|
|
|
355
338
|
|
|
356
339
|
// Build encoder fields list
|
|
357
340
|
const encoderFields = fields
|
|
358
|
-
.map((f, i) => `(
|
|
341
|
+
.map((f, i) => `(${toDartStringLiteral(fieldNames[i])}, ${f.encoder.content})`)
|
|
359
342
|
.join(", ");
|
|
360
343
|
const encoderFrag = fragment`${use(
|
|
361
344
|
"getStructEncoder",
|
|
@@ -366,7 +349,7 @@ export function getTypeManifestVisitor(input: {
|
|
|
366
349
|
}
|
|
367
350
|
|
|
368
351
|
const decoderFields = fields
|
|
369
|
-
.map((f, i) => `(
|
|
352
|
+
.map((f, i) => `(${toDartStringLiteral(fieldNames[i])}, ${f.decoder.content})`)
|
|
370
353
|
.join(", ");
|
|
371
354
|
const decoderFrag = fragment`${use(
|
|
372
355
|
"getStructDecoder",
|
|
@@ -442,10 +425,10 @@ export function getTypeManifestVisitor(input: {
|
|
|
442
425
|
const itemTypeStr = itemManifest.type.content;
|
|
443
426
|
const resolvedPrefix = resolveNestedTypeNode(node.prefix);
|
|
444
427
|
const prefixExpr = resolvedPrefix.format !== "u8"
|
|
445
|
-
? `, prefix: ${getNumberCodecExpression(resolvedPrefix
|
|
428
|
+
? fragment`, prefix: ${getNumberCodecExpression(resolvedPrefix, "Encoder")}`
|
|
446
429
|
: "";
|
|
447
430
|
const prefixDecoderExpr = resolvedPrefix.format !== "u8"
|
|
448
|
-
? `, prefix: ${getNumberCodecExpression(resolvedPrefix
|
|
431
|
+
? fragment`, prefix: ${getNumberCodecExpression(resolvedPrefix, "Decoder")}`
|
|
449
432
|
: "";
|
|
450
433
|
const noneValueExpr = node.fixed
|
|
451
434
|
? ", noneValue: const ZeroesNoneValue()"
|
|
@@ -459,11 +442,11 @@ export function getTypeManifestVisitor(input: {
|
|
|
459
442
|
)}<${fragmentFromString(itemTypeStr)}>(${use(
|
|
460
443
|
"transformEncoder",
|
|
461
444
|
"solanaCodecsCore",
|
|
462
|
-
)}(${itemManifest.encoder}, (${fragmentFromString(itemTypeStr)} value) => value)${
|
|
445
|
+
)}(${itemManifest.encoder}, (${fragmentFromString(itemTypeStr)} value) => value)${prefixExpr}${fragmentFromString(noneValueExpr)})`,
|
|
463
446
|
decoder: fragment`${use(
|
|
464
447
|
"getNullableDecoder",
|
|
465
448
|
"solanaCodecsDataStructures",
|
|
466
|
-
)}<${fragmentFromString(itemTypeStr)}>(${itemManifest.decoder}${
|
|
449
|
+
)}<${fragmentFromString(itemTypeStr)}>(${itemManifest.decoder}${prefixDecoderExpr}${fragmentFromString(noneValueExpr)})`,
|
|
467
450
|
value: emptyTypeManifest().value,
|
|
468
451
|
isEnum: false,
|
|
469
452
|
};
|
|
@@ -521,11 +504,11 @@ export function getTypeManifestVisitor(input: {
|
|
|
521
504
|
encoder: fragment`${use(
|
|
522
505
|
"fixEncoderSize",
|
|
523
506
|
"solanaCodecsCore",
|
|
524
|
-
)}(${innerManifest.encoder}, ${fragmentFromString(
|
|
507
|
+
)}(${innerManifest.encoder}, ${fragmentFromString(getNonNegativeInteger(node.size))}, allowTruncation: false)`,
|
|
525
508
|
decoder: fragment`${use(
|
|
526
509
|
"fixDecoderSize",
|
|
527
510
|
"solanaCodecsCore",
|
|
528
|
-
)}(${innerManifest.decoder}, ${fragmentFromString(
|
|
511
|
+
)}(${innerManifest.decoder}, ${fragmentFromString(getNonNegativeInteger(node.size))})`,
|
|
529
512
|
value: innerManifest.value,
|
|
530
513
|
isEnum: innerManifest.isEnum,
|
|
531
514
|
};
|
|
@@ -544,12 +527,12 @@ export function getTypeManifestVisitor(input: {
|
|
|
544
527
|
let prefixManifest;
|
|
545
528
|
if (
|
|
546
529
|
node.prefix.kind === "numberTypeNode" &&
|
|
547
|
-
bigIntFormats.has(
|
|
530
|
+
bigIntFormats.has(node.prefix.format)
|
|
548
531
|
) {
|
|
549
|
-
const
|
|
532
|
+
const numberManifest = visit(node.prefix, self);
|
|
550
533
|
prefixManifest = {
|
|
551
|
-
encoder: fragment
|
|
552
|
-
decoder: fragment
|
|
534
|
+
encoder: fragment`${use("transformEncoder", "solanaCodecsCore")}(${numberManifest.encoder}, (size) => BigInt.from(size))`,
|
|
535
|
+
decoder: fragment`${use("transformDecoder", "solanaCodecsCore")}(${numberManifest.decoder}, (size, _, __) => size.toInt())`,
|
|
553
536
|
};
|
|
554
537
|
} else {
|
|
555
538
|
prefixManifest = visit(node.prefix, self);
|
|
@@ -660,13 +643,11 @@ export function getTypeManifestVisitor(input: {
|
|
|
660
643
|
},
|
|
661
644
|
|
|
662
645
|
visitPreOffsetType(node: PreOffsetTypeNode, { self }) {
|
|
663
|
-
|
|
664
|
-
return visit(node.type, self);
|
|
646
|
+
return getOffsetManifest(node, self);
|
|
665
647
|
},
|
|
666
648
|
|
|
667
649
|
visitPostOffsetType(node: PostOffsetTypeNode, { self }) {
|
|
668
|
-
|
|
669
|
-
return visit(node.type, self);
|
|
650
|
+
return getOffsetManifest(node, self);
|
|
670
651
|
},
|
|
671
652
|
|
|
672
653
|
visitSolAmountType(node: SolAmountTypeNode, { self }) {
|
|
@@ -777,30 +758,39 @@ function getNumberCodecName(format: string): string {
|
|
|
777
758
|
}
|
|
778
759
|
|
|
779
760
|
function getNumberCodecExpression(
|
|
780
|
-
|
|
761
|
+
node: NumberTypeNode,
|
|
781
762
|
codecType: "Encoder" | "Decoder",
|
|
782
|
-
):
|
|
783
|
-
const name = getNumberCodecName(format);
|
|
784
|
-
|
|
763
|
+
): Fragment {
|
|
764
|
+
const name = getNumberCodecName(node.format);
|
|
765
|
+
const config = node.endian === "be"
|
|
766
|
+
? fragment`${use("NumberCodecConfig", "solanaCodecsNumbers")}(endian: ${use("Endian", "dartTypedData")}.big)`
|
|
767
|
+
: "";
|
|
768
|
+
|
|
769
|
+
return fragment`${use(`get${name}${codecType}`, "solanaCodecsNumbers")}(${config})`;
|
|
785
770
|
}
|
|
786
771
|
|
|
787
772
|
function getArraySizeExpression(
|
|
788
773
|
node: ArrayTypeNode,
|
|
789
774
|
codecType: "Encoder" | "Decoder",
|
|
790
|
-
|
|
775
|
+
self: Visitor<TypeManifest>,
|
|
776
|
+
): string | Fragment {
|
|
791
777
|
if (!("count" in node) || !node.count) return "";
|
|
792
778
|
const count = node.count;
|
|
793
779
|
switch (count.kind) {
|
|
794
780
|
case "fixedCountNode":
|
|
795
|
-
return `, size: FixedArraySize(${count.value})`;
|
|
781
|
+
return `, size: FixedArraySize(${getNonNegativeInteger(count.value)})`;
|
|
796
782
|
case "remainderCountNode":
|
|
797
783
|
return ", size: RemainderArraySize()";
|
|
798
784
|
case "prefixedCountNode": {
|
|
799
|
-
|
|
800
|
-
|
|
785
|
+
if (
|
|
786
|
+
count.prefix.kind === "numberTypeNode" &&
|
|
787
|
+
count.prefix.format === "u32" &&
|
|
788
|
+
(!count.prefix.endian || count.prefix.endian === "le")
|
|
789
|
+
) {
|
|
801
790
|
return ""; // Default
|
|
802
791
|
}
|
|
803
|
-
|
|
792
|
+
const prefix = visit(count.prefix, self);
|
|
793
|
+
return fragment`, size: PrefixedArraySize(${codecType === "Encoder" ? prefix.encoder : prefix.decoder})`;
|
|
804
794
|
}
|
|
805
795
|
default:
|
|
806
796
|
return "";
|
|
@@ -810,20 +800,25 @@ function getArraySizeExpression(
|
|
|
810
800
|
function getMapSizeExpression(
|
|
811
801
|
node: MapTypeNode,
|
|
812
802
|
codecType: "Encoder" | "Decoder",
|
|
813
|
-
|
|
803
|
+
self: Visitor<TypeManifest>,
|
|
804
|
+
): string | Fragment {
|
|
814
805
|
if (!("count" in node) || !node.count) return "";
|
|
815
806
|
const count = node.count;
|
|
816
807
|
switch (count.kind) {
|
|
817
808
|
case "fixedCountNode":
|
|
818
|
-
return `, size: FixedArraySize(${count.value})`;
|
|
809
|
+
return `, size: FixedArraySize(${getNonNegativeInteger(count.value)})`;
|
|
819
810
|
case "remainderCountNode":
|
|
820
811
|
return ", size: RemainderArraySize()";
|
|
821
812
|
case "prefixedCountNode": {
|
|
822
|
-
|
|
823
|
-
|
|
813
|
+
if (
|
|
814
|
+
count.prefix.kind === "numberTypeNode" &&
|
|
815
|
+
count.prefix.format === "u32" &&
|
|
816
|
+
(!count.prefix.endian || count.prefix.endian === "le")
|
|
817
|
+
) {
|
|
824
818
|
return "";
|
|
825
819
|
}
|
|
826
|
-
|
|
820
|
+
const prefix = visit(count.prefix, self);
|
|
821
|
+
return fragment`, size: PrefixedArraySize(${codecType === "Encoder" ? prefix.encoder : prefix.decoder})`;
|
|
827
822
|
}
|
|
828
823
|
default:
|
|
829
824
|
return "";
|
|
@@ -833,20 +828,25 @@ function getMapSizeExpression(
|
|
|
833
828
|
function getSetSizeExpression(
|
|
834
829
|
node: SetTypeNode,
|
|
835
830
|
codecType: "Encoder" | "Decoder",
|
|
836
|
-
|
|
831
|
+
self: Visitor<TypeManifest>,
|
|
832
|
+
): string | Fragment {
|
|
837
833
|
if (!("count" in node) || !node.count) return "";
|
|
838
834
|
const count = node.count;
|
|
839
835
|
switch (count.kind) {
|
|
840
836
|
case "fixedCountNode":
|
|
841
|
-
return `, size: FixedArraySize(${count.value})`;
|
|
837
|
+
return `, size: FixedArraySize(${getNonNegativeInteger(count.value)})`;
|
|
842
838
|
case "remainderCountNode":
|
|
843
839
|
return ", size: RemainderArraySize()";
|
|
844
840
|
case "prefixedCountNode": {
|
|
845
|
-
|
|
846
|
-
|
|
841
|
+
if (
|
|
842
|
+
count.prefix.kind === "numberTypeNode" &&
|
|
843
|
+
count.prefix.format === "u32" &&
|
|
844
|
+
(!count.prefix.endian || count.prefix.endian === "le")
|
|
845
|
+
) {
|
|
847
846
|
return "";
|
|
848
847
|
}
|
|
849
|
-
|
|
848
|
+
const prefix = visit(count.prefix, self);
|
|
849
|
+
return fragment`, size: PrefixedArraySize(${codecType === "Encoder" ? prefix.encoder : prefix.decoder})`;
|
|
850
850
|
}
|
|
851
851
|
default:
|
|
852
852
|
return "";
|
|
@@ -859,7 +859,7 @@ type HiddenAffixManifest = {
|
|
|
859
859
|
};
|
|
860
860
|
|
|
861
861
|
function getHiddenAffixManifest(
|
|
862
|
-
node:
|
|
862
|
+
node: ConstantValueNode | TypeNode,
|
|
863
863
|
self: Visitor<TypeManifest>,
|
|
864
864
|
): HiddenAffixManifest {
|
|
865
865
|
if (node?.kind !== "constantValueNode") {
|
|
@@ -867,40 +867,80 @@ function getHiddenAffixManifest(
|
|
|
867
867
|
return { encoder: manifest.encoder, decoder: manifest.decoder };
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
-
const constantBytes = getConstantBytesExpression(node);
|
|
870
|
+
const constantBytes = getConstantBytesExpression(node, self);
|
|
871
871
|
return {
|
|
872
872
|
encoder: fragment`${use("getConstantEncoder", "solanaCodecsDataStructures")}(${constantBytes})`,
|
|
873
873
|
decoder: fragment`${use("getConstantDecoder", "solanaCodecsDataStructures")}(${constantBytes})`,
|
|
874
874
|
};
|
|
875
875
|
}
|
|
876
876
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
877
|
+
/** Serialize affix constants using the same validated codec as ordinary fields. */
|
|
878
|
+
function getConstantBytesExpression(
|
|
879
|
+
node: ConstantValueNode,
|
|
880
|
+
self: Visitor<TypeManifest>,
|
|
881
|
+
): Fragment {
|
|
882
|
+
if (node.value.kind !== "numberValueNode") {
|
|
882
883
|
throw new Error(
|
|
883
|
-
`Unsupported hidden affix constant value kind: ${
|
|
884
|
+
`Unsupported hidden affix constant value kind: ${node.value.kind}`,
|
|
884
885
|
);
|
|
885
886
|
}
|
|
886
887
|
|
|
887
|
-
const
|
|
888
|
+
const manifest = visit(node.type, self);
|
|
888
889
|
|
|
889
|
-
if (
|
|
890
|
-
|
|
890
|
+
if (!["int", "BigInt", "double"].includes(manifest.type.content)) {
|
|
891
|
+
throw new Error(`Unsupported hidden affix constant type kind: ${node.type.kind}`);
|
|
891
892
|
}
|
|
892
893
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
894
|
+
const value = getDartValueFragment(node.value, manifest.type.content);
|
|
895
|
+
|
|
896
|
+
return fragment`${manifest.encoder}.encode(${value})`;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/** Preserve the IDL's cursor strategy instead of silently discarding offsets. */
|
|
900
|
+
function getOffsetManifest(
|
|
901
|
+
node: PreOffsetTypeNode | PostOffsetTypeNode,
|
|
902
|
+
self: Visitor<TypeManifest>,
|
|
903
|
+
): TypeManifest {
|
|
904
|
+
if (!Number.isSafeInteger(node.offset)) {
|
|
905
|
+
throw new Error("Expected a safe integer for a codec offset");
|
|
901
906
|
}
|
|
902
907
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
908
|
+
const manifest = visit(node.type, self);
|
|
909
|
+
const pre = node.kind === "preOffsetTypeNode";
|
|
910
|
+
const key = pre ? "preOffset" : "postOffset";
|
|
911
|
+
|
|
912
|
+
if (node.strategy === "padded") {
|
|
913
|
+
const side = pre ? "Left" : "Right";
|
|
914
|
+
const offset = getNonNegativeInteger(node.offset);
|
|
915
|
+
|
|
916
|
+
return {
|
|
917
|
+
...manifest,
|
|
918
|
+
encoder: fragment`${use(`pad${side}Encoder`, "solanaCodecsCore")}(${manifest.encoder}, ${offset})`,
|
|
919
|
+
decoder: fragment`${use(`pad${side}Decoder`, "solanaCodecsCore")}(${manifest.decoder}, ${offset})`,
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
let expression: string;
|
|
924
|
+
|
|
925
|
+
switch (node.strategy) {
|
|
926
|
+
case "absolute":
|
|
927
|
+
expression = node.offset < 0 ? `scope.wrapBytes(${node.offset})` : String(node.offset);
|
|
928
|
+
break;
|
|
929
|
+
case "relative":
|
|
930
|
+
expression = `scope.${key} + ${node.offset}`;
|
|
931
|
+
break;
|
|
932
|
+
case "preOffset":
|
|
933
|
+
expression = `scope.preOffset + ${node.offset}`;
|
|
934
|
+
break;
|
|
935
|
+
default:
|
|
936
|
+
throw new Error(`Unsupported offset strategy: ${node.strategy}`);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
const config = fragment`${use("OffsetConfig", "solanaCodecsCore")}(${key}: (scope) => ${expression})`;
|
|
940
|
+
|
|
941
|
+
return {
|
|
942
|
+
...manifest,
|
|
943
|
+
encoder: fragment`${use("offsetEncoder", "solanaCodecsCore")}(${manifest.encoder}, ${config})`,
|
|
944
|
+
decoder: fragment`${use("offsetDecoder", "solanaCodecsCore")}(${manifest.decoder}, ${config})`,
|
|
945
|
+
};
|
|
906
946
|
}
|
|
@@ -32,11 +32,6 @@ export function renderVisitor(
|
|
|
32
32
|
return rootNodeVisitor((root: RootNode) => {
|
|
33
33
|
const normalizedRoot = normalizeRootNode(root);
|
|
34
34
|
|
|
35
|
-
// 1. Optionally delete the output directory
|
|
36
|
-
if (deleteFolderBeforeRendering && existsSync(outputDir)) {
|
|
37
|
-
deleteDirectory(outputDir);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
35
|
// 2. Build the render map
|
|
41
36
|
const renderMap = visit(
|
|
42
37
|
normalizedRoot,
|
|
@@ -52,16 +47,10 @@ export function renderVisitor(
|
|
|
52
47
|
}
|
|
53
48
|
}
|
|
54
49
|
|
|
55
|
-
//
|
|
50
|
+
// Resolve every file before deleting previous output, so invalid IDLs fail safely.
|
|
51
|
+
const files: [string, string][] = [];
|
|
56
52
|
for (const [filePath, frag] of renderMap.entries()) {
|
|
57
53
|
const fullPath = join(outputDir, filePath);
|
|
58
|
-
const dir = dirname(fullPath);
|
|
59
|
-
|
|
60
|
-
// Ensure directory exists
|
|
61
|
-
if (!existsSync(dir)) {
|
|
62
|
-
mkdirSync(dir, { recursive: true });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
54
|
// Compute per-file internal import map (relative paths to defined types)
|
|
66
55
|
const fileDir = dirname(filePath);
|
|
67
56
|
const internalMap: Record<string, string> = {};
|
|
@@ -81,6 +70,15 @@ export function renderVisitor(
|
|
|
81
70
|
|
|
82
71
|
// Resolve fragment content with imports
|
|
83
72
|
const content = resolveFragmentContent(frag, dependencyMap ?? {}, internalMap);
|
|
73
|
+
files.push([fullPath, content]);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (deleteFolderBeforeRendering && existsSync(outputDir)) {
|
|
77
|
+
deleteDirectory(outputDir);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (const [fullPath, content] of files) {
|
|
81
|
+
mkdirSync(dirname(fullPath), { recursive: true });
|
|
84
82
|
writeFileSync(fullPath, content, "utf-8");
|
|
85
83
|
}
|
|
86
84
|
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Ifiok Jr.
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|