codama-renderers-dart 0.4.2 → 0.5.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 +21 -0
- package/dist/index.browser.cjs +184 -38
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +185 -39
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.cjs +184 -38
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +185 -39
- package/dist/index.node.js.map +1 -1
- package/dist/index.react-native.js +185 -39
- package/dist/index.react-native.js.map +1 -1
- package/dist/types/fragments/instructionPage.d.ts.map +1 -1
- package/dist/types/fragments/programPage.d.ts +1 -1
- package/dist/types/fragments/programPage.d.ts.map +1 -1
- package/dist/types/utils/importMap.d.ts.map +1 -1
- package/dist/types/utils/nameTransformers.d.ts +1 -1
- package/dist/types/utils/nameTransformers.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 -6
- package/readme.md +1 -3
- package/src/fragments/instructionPage.ts +15 -4
- package/src/fragments/programPage.ts +165 -6
- package/src/fragments/typePage.ts +4 -3
- package/src/utils/importMap.ts +16 -3
- package/src/utils/nameTransformers.ts +3 -2
- package/src/utils/wellKnownAddresses.ts +4 -4
- package/src/visitors/getTypeManifestVisitor.ts +35 -22
- package/src/visitors/renderVisitor.ts +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructionPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/instructionPage.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,QAAQ,
|
|
1
|
+
{"version":3,"file":"instructionPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/instructionPage.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAkQV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"programPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/programPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"programPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/programPage.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAiJV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importMap.d.ts","sourceRoot":"","sources":["../../../src/utils/importMap.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsB5D,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAqB;IAErC;;;OAGG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAOrC;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAEzB;IAED;;;OAGG;IACH,OAAO,CAAC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"importMap.d.ts","sourceRoot":"","sources":["../../../src/utils/importMap.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsB5D,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAqB;IAErC;;;OAGG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAOrC;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAEzB;IAED;;;OAGG;IACH,OAAO,CAAC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,EAAE;IAgC3D;;OAEG;IACH,QAAQ,CAAC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM;CAyB3D"}
|
|
@@ -44,7 +44,7 @@ export interface DartNameApi {
|
|
|
44
44
|
errorMessageFunction(name: string): string;
|
|
45
45
|
/** Enum variant: `camelCase` */
|
|
46
46
|
enumVariant(name: string): string;
|
|
47
|
-
/** Sealed class variant (data enum): `PascalCase` */
|
|
47
|
+
/** Sealed class variant (data enum): `{ParentName}{PascalCase}` */
|
|
48
48
|
sealedClassVariant(parentName: string, variantName: string): string;
|
|
49
49
|
/** File name: `snake_case.dart` */
|
|
50
50
|
fileName(name: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nameTransformers.d.ts","sourceRoot":"","sources":["../../../src/utils/nameTransformers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;GAEG;AAEH,qCAAqC;AACrC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED,oCAAoC;AACpC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,sDAAsD;IACtD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,sDAAsD;IACtD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,kDAAkD;IAClD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,kDAAkD;IAClD,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,6DAA6D;IAC7D,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAChD,oDAAoD;IACpD,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,+CAA+C;IAC/C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,iDAAiD;IACjD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,iEAAiE;IACjE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,iEAAiE;IACjE,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,4DAA4D;IAC5D,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,4DAA4D;IAC5D,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9D,4DAA4D;IAC5D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,gCAAgC;IAChC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,
|
|
1
|
+
{"version":3,"file":"nameTransformers.d.ts","sourceRoot":"","sources":["../../../src/utils/nameTransformers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;GAEG;AAEH,qCAAqC;AACrC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED,oCAAoC;AACpC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,sDAAsD;IACtD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,sDAAsD;IACtD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,kDAAkD;IAClD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,kDAAkD;IAClD,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,6DAA6D;IAC7D,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAChD,oDAAoD;IACpD,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,+CAA+C;IAC/C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,iDAAiD;IACjD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtC,iEAAiE;IACjE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,iEAAiE;IACjE,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,4DAA4D;IAC5D,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,4DAA4D;IAC5D,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9D,4DAA4D;IAC5D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,gCAAgC;IAChC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,mEAAmE;IACnE,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IACpE,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,yDAAyD;IACzD,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,oDAAoD;IACpD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACtC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAwB/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAEhE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTypeManifestVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/getTypeManifestVisitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EA8BrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,OAAO,EAIb,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAEL,KAAK,YAAY,EAKlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,8BAA8B,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;CACpC,
|
|
1
|
+
{"version":3,"file":"getTypeManifestVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/getTypeManifestVisitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EA8BrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,OAAO,EAIb,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAEL,KAAK,YAAY,EAKlB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,8BAA8B,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;CACpC,6xDA6mBA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/renderVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,
|
|
1
|
+
{"version":3,"file":"renderVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/renderVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,6DAmE5B"}
|
package/package.json
CHANGED
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@codama/nodes-from-anchor": "^1.3.9",
|
|
11
11
|
"@codama/renderers-js": "^2.0.2",
|
|
12
|
-
"@
|
|
12
|
+
"@types/node": "25.3.0",
|
|
13
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
14
|
+
"rimraf": "6.1.3",
|
|
15
|
+
"tsup": "8.5.1",
|
|
16
|
+
"typescript": "5.9.3",
|
|
17
|
+
"vitest": "4.1.0"
|
|
13
18
|
},
|
|
14
19
|
"engines": {
|
|
15
20
|
"node": ">=18"
|
|
@@ -45,6 +50,9 @@
|
|
|
45
50
|
"access": "public"
|
|
46
51
|
},
|
|
47
52
|
"repository": "https://github.com/openbudgetfun/solana_kit/tree/main/packages/codama-renderers-dart",
|
|
53
|
+
"type": "module",
|
|
54
|
+
"types": "./dist/types/index.d.ts",
|
|
55
|
+
"version": "0.5.0",
|
|
48
56
|
"scripts": {
|
|
49
57
|
"build": "pnpm exec rimraf dist && pnpm exec tsup && pnpm exec tsc -p tsconfig.declarations.json",
|
|
50
58
|
"lint": "eslint --ext .ts src",
|
|
@@ -52,8 +60,5 @@
|
|
|
52
60
|
"test:coverage": "pnpm exec vitest run --coverage.enabled --coverage.reporter=lcov",
|
|
53
61
|
"test:watch": "pnpm exec vitest",
|
|
54
62
|
"typecheck": "pnpm exec tsc --noEmit"
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
"types": "./dist/types/index.d.ts",
|
|
58
|
-
"version": "0.4.2"
|
|
59
|
-
}
|
|
63
|
+
}
|
|
64
|
+
}
|
package/readme.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# codama-renderers-dart
|
|
2
2
|
|
|
3
|
-
[](https://pub.dev/packages/codama-renderers-dart)
|
|
4
|
-
[](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml)
|
|
5
|
-
[](https://codecov.io/gh/openbudgetfun/solana_kit?flag=codama-renderers-dart)
|
|
3
|
+
[](https://pub.dev/packages/codama-renderers-dart) [](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml) [](https://codecov.io/gh/openbudgetfun/solana_kit?flag=codama-renderers-dart)
|
|
6
4
|
|
|
7
5
|
A [Codama](https://github.com/codama-idl/codama) renderer that generates Dart code targeting the [solana_kit](https://github.com/openbudgetfun/solana_kit) SDK.
|
|
8
6
|
|
|
@@ -134,7 +134,11 @@ export function getInstructionPageFragment(
|
|
|
134
134
|
const manifest = argManifestMap.get(arg)!;
|
|
135
135
|
const fieldName = camelCase(arg.name as string);
|
|
136
136
|
const typeStr = manifest.type.content;
|
|
137
|
-
|
|
137
|
+
// Account bumps require asynchronous PDA derivation, so callers must
|
|
138
|
+
// provide them instead of relying on a synchronous generated default.
|
|
139
|
+
const hasDefault =
|
|
140
|
+
arg.defaultValue != null &&
|
|
141
|
+
arg.defaultValue.kind !== "accountBumpValueNode";
|
|
138
142
|
if (hasDefault) {
|
|
139
143
|
// Don't add `?` if the type is already nullable.
|
|
140
144
|
const nullableType = typeStr.endsWith("?") ? typeStr : `${typeStr}?`;
|
|
@@ -165,7 +169,9 @@ export function getInstructionPageFragment(
|
|
|
165
169
|
return ""; // Use default
|
|
166
170
|
}
|
|
167
171
|
// Use 'arg_<name>' prefix to reference builder params without shadowing.
|
|
168
|
-
|
|
172
|
+
const typeStr2 = argManifestMap.get(arg)?.type.content;
|
|
173
|
+
const skipDefault = arg.defaultValue?.kind === "accountBumpValueNode";
|
|
174
|
+
return ` ${fieldName}: ${fieldName}${arg.defaultValue != null && !skipDefault ? ` ?? ${getDefaultValue(arg, typeStr2)}` : ""},`;
|
|
169
175
|
})
|
|
170
176
|
.filter(Boolean)
|
|
171
177
|
.join("\n");
|
|
@@ -329,12 +335,17 @@ function isConstDefaultValue(defaultValue: InstructionArgumentNode["defaultValue
|
|
|
329
335
|
}
|
|
330
336
|
}
|
|
331
337
|
|
|
332
|
-
function getDefaultValue(
|
|
338
|
+
function getDefaultValue(
|
|
339
|
+
arg: InstructionArgumentNode,
|
|
340
|
+
typeStr?: string,
|
|
341
|
+
): string {
|
|
333
342
|
if (!arg.defaultValue) return "null";
|
|
343
|
+
const isBigInt = typeStr === "BigInt";
|
|
334
344
|
const dv = arg.defaultValue;
|
|
335
345
|
switch (dv.kind) {
|
|
336
346
|
case "numberValueNode":
|
|
337
|
-
|
|
347
|
+
// Dart's `BigInt` requires a constructor; `0` is not assignable to `BigInt`.
|
|
348
|
+
return isBigInt ? `BigInt.from(${dv.number})` : String(dv.number);
|
|
338
349
|
case "booleanValueNode":
|
|
339
350
|
return String(dv.boolean);
|
|
340
351
|
case "stringValueNode":
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
getAllInstructionsWithSubs,
|
|
3
|
+
type InstructionNode,
|
|
4
|
+
type ProgramNode,
|
|
5
|
+
type ValueNode,
|
|
6
|
+
} from "@codama/nodes";
|
|
7
|
+
import { visit } from "@codama/visitors-core";
|
|
2
8
|
|
|
3
9
|
import type { Fragment } from "../utils/fragment.js";
|
|
4
10
|
import {
|
|
@@ -67,19 +73,172 @@ ${fragmentFromString(accountVariants)}
|
|
|
67
73
|
}`);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
// Instruction
|
|
71
|
-
const instructions = node
|
|
76
|
+
// Instruction identification and parsing helpers.
|
|
77
|
+
const instructions = getAllInstructionsWithSubs(node);
|
|
72
78
|
if (instructions.length > 0) {
|
|
79
|
+
const programName = pascalCase(name);
|
|
80
|
+
const instructionEnum = `${programName}Instruction`;
|
|
73
81
|
const instrVariants = instructions
|
|
74
82
|
.map((instr) => ` ${camelCase(instr.name as string)},`)
|
|
75
83
|
.join("\n");
|
|
76
84
|
|
|
77
85
|
parts.push(fragment`
|
|
78
|
-
/// Known instructions for the ${fragmentFromString(
|
|
79
|
-
enum ${fragmentFromString(
|
|
86
|
+
/// Known instructions for the ${fragmentFromString(programName)} program.
|
|
87
|
+
enum ${fragmentFromString(instructionEnum)} {
|
|
80
88
|
${fragmentFromString(instrVariants)}
|
|
81
89
|
}`);
|
|
90
|
+
|
|
91
|
+
const identifiableInstructions = instructions
|
|
92
|
+
.map((instruction) => ({
|
|
93
|
+
instruction,
|
|
94
|
+
condition: getInstructionDiscriminatorCondition(instruction, scope),
|
|
95
|
+
}))
|
|
96
|
+
.filter(({ condition }) => condition !== null) as {
|
|
97
|
+
instruction: InstructionNode;
|
|
98
|
+
condition: Fragment;
|
|
99
|
+
}[];
|
|
100
|
+
|
|
101
|
+
if (identifiableInstructions.length > 0) {
|
|
102
|
+
const identifyBranches = identifiableInstructions.map(
|
|
103
|
+
({ instruction, condition }) => fragment` if (${condition}) {
|
|
104
|
+
return ${fragmentFromString(instructionEnum)}.${fragmentFromString(camelCase(instruction.name as string))};
|
|
105
|
+
}`,
|
|
106
|
+
);
|
|
107
|
+
const parsedBase = `Parsed${programName}Instruction`;
|
|
108
|
+
const parsedClasses = instructions.map((instruction) => {
|
|
109
|
+
const instructionName = pascalCase(instruction.name as string);
|
|
110
|
+
const variant = camelCase(instruction.name as string);
|
|
111
|
+
const parsedClass = `Parsed${instructionName}`;
|
|
112
|
+
const dataClass = `${instructionName}InstructionData`;
|
|
113
|
+
return fragment`/// A parsed ${fragmentFromString(instructionName)} instruction.
|
|
114
|
+
final class ${fragmentFromString(parsedClass)} extends ${fragmentFromString(parsedBase)} {
|
|
115
|
+
const ${fragmentFromString(parsedClass)}({required this.data})
|
|
116
|
+
: super(${fragmentFromString(instructionEnum)}.${fragmentFromString(variant)});
|
|
117
|
+
|
|
118
|
+
final ${use(dataClass, "../instructions/instructions.dart")} data;
|
|
119
|
+
}`;
|
|
120
|
+
});
|
|
121
|
+
const parseBranches = instructions.map((instruction) => {
|
|
122
|
+
const instructionName = pascalCase(instruction.name as string);
|
|
123
|
+
const variant = camelCase(instruction.name as string);
|
|
124
|
+
const parsedClass = `Parsed${instructionName}`;
|
|
125
|
+
const parseFunction = scope.nameApi.instructionParseFunction(
|
|
126
|
+
instruction.name as string,
|
|
127
|
+
);
|
|
128
|
+
return fragment` ${fragmentFromString(instructionEnum)}.${fragmentFromString(variant)} => ${fragmentFromString(parsedClass)}(
|
|
129
|
+
data: ${use(parseFunction, "../instructions/instructions.dart")}(instruction),
|
|
130
|
+
),`;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
parts.push(fragment`
|
|
134
|
+
/// Identifies the type of a ${fragmentFromString(programName)} instruction.
|
|
135
|
+
${fragmentFromString(instructionEnum)} identify${fragmentFromString(programName)}Instruction(
|
|
136
|
+
${use("Uint8List", "dartTypedData")} data,
|
|
137
|
+
) {
|
|
138
|
+
${mergeFragments(identifyBranches, (cs) => cs.join("\n"))}
|
|
139
|
+
|
|
140
|
+
throw ${use("SolanaError", "solanaErrors")}(
|
|
141
|
+
${use("SolanaErrorCode", "solanaErrors")}.programClientsFailedToIdentifyInstruction,
|
|
142
|
+
{
|
|
143
|
+
'instructionData': data,
|
|
144
|
+
'programName': '${fragmentFromString(name)}',
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// A parsed instruction from the ${fragmentFromString(programName)} program.
|
|
150
|
+
sealed class ${fragmentFromString(parsedBase)} {
|
|
151
|
+
const ${fragmentFromString(parsedBase)}(this.instructionType);
|
|
152
|
+
|
|
153
|
+
final ${fragmentFromString(instructionEnum)} instructionType;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
${mergeFragments(parsedClasses, (cs) => cs.join("\n\n"))}
|
|
157
|
+
|
|
158
|
+
/// Parses a ${fragmentFromString(programName)} instruction.
|
|
159
|
+
${fragmentFromString(parsedBase)} parse${fragmentFromString(programName)}Instruction(
|
|
160
|
+
${use("Instruction", "solanaInstructions")} instruction,
|
|
161
|
+
) {
|
|
162
|
+
return switch (identify${fragmentFromString(programName)}Instruction(
|
|
163
|
+
instruction.data ?? Uint8List(0),
|
|
164
|
+
)) {
|
|
165
|
+
${mergeFragments(parseBranches, (cs) => cs.join("\n"))}
|
|
166
|
+
};
|
|
167
|
+
}`);
|
|
168
|
+
}
|
|
82
169
|
}
|
|
83
170
|
|
|
84
171
|
return mergeFragments(parts, (cs) => cs.join("\n"));
|
|
85
|
-
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function getInstructionDiscriminatorCondition(
|
|
175
|
+
instruction: InstructionNode,
|
|
176
|
+
scope: RenderScope,
|
|
177
|
+
): Fragment | null {
|
|
178
|
+
const discriminators = instruction.discriminators ?? [];
|
|
179
|
+
if (discriminators.length === 0) return null;
|
|
180
|
+
|
|
181
|
+
const conditions = discriminators.map((discriminator): Fragment | null => {
|
|
182
|
+
switch (discriminator.kind) {
|
|
183
|
+
case "sizeDiscriminatorNode":
|
|
184
|
+
return fragment`data.length == ${discriminator.size}`;
|
|
185
|
+
case "constantDiscriminatorNode": {
|
|
186
|
+
const manifest = visit(
|
|
187
|
+
discriminator.constant.type,
|
|
188
|
+
scope.typeManifestVisitor,
|
|
189
|
+
);
|
|
190
|
+
const value = getValueFragment(
|
|
191
|
+
discriminator.constant.value,
|
|
192
|
+
manifest.type.content,
|
|
193
|
+
);
|
|
194
|
+
if (value === null) return null;
|
|
195
|
+
return fragment`${use("containsBytes", "solanaCodecsCore")}(data, ${manifest.encoder}.encode(${value}), ${discriminator.offset})`;
|
|
196
|
+
}
|
|
197
|
+
case "fieldDiscriminatorNode": {
|
|
198
|
+
const argument = (instruction.arguments ?? []).find(
|
|
199
|
+
(candidate) => candidate.name === discriminator.name,
|
|
200
|
+
);
|
|
201
|
+
if (argument?.defaultValue == null) return null;
|
|
202
|
+
const manifest = visit(argument.type, scope.typeManifestVisitor);
|
|
203
|
+
const value = getValueFragment(
|
|
204
|
+
argument.defaultValue,
|
|
205
|
+
manifest.type.content,
|
|
206
|
+
);
|
|
207
|
+
if (value === null) return null;
|
|
208
|
+
return fragment`${use("containsBytes", "solanaCodecsCore")}(data, ${manifest.encoder}.encode(${value}), ${discriminator.offset})`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
if (conditions.some((condition) => condition === null)) return null;
|
|
214
|
+
return mergeFragments(conditions as Fragment[], (cs) => cs.join(" && "));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function getValueFragment(
|
|
218
|
+
value:
|
|
219
|
+
| ValueNode
|
|
220
|
+
| NonNullable<
|
|
221
|
+
NonNullable<InstructionNode["arguments"]>[number]["defaultValue"]
|
|
222
|
+
>,
|
|
223
|
+
dartType?: string,
|
|
224
|
+
): Fragment | null {
|
|
225
|
+
switch (value.kind) {
|
|
226
|
+
case "numberValueNode":
|
|
227
|
+
return fragmentFromString(
|
|
228
|
+
dartType === "BigInt"
|
|
229
|
+
? `BigInt.from(${value.number})`
|
|
230
|
+
: String(value.number),
|
|
231
|
+
);
|
|
232
|
+
case "booleanValueNode":
|
|
233
|
+
return fragmentFromString(String(value.boolean));
|
|
234
|
+
case "stringValueNode":
|
|
235
|
+
return fragmentFromString(`'${value.string.replaceAll("'", "\\'")}'`);
|
|
236
|
+
case "bytesValueNode": {
|
|
237
|
+
const clean = value.data.replace(/^0x/, "");
|
|
238
|
+
const bytes = clean.match(/.{1,2}/g)?.map((byte) => parseInt(byte, 16)) ?? [];
|
|
239
|
+
return fragment`${use("Uint8List", "dartTypedData")}.fromList([${fragmentFromString(bytes.join(", "))}])`;
|
|
240
|
+
}
|
|
241
|
+
default:
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -132,6 +132,7 @@ function getDataEnumPageFragment(
|
|
|
132
132
|
|
|
133
133
|
for (let i = 0; i < enumNode.variants.length; i++) {
|
|
134
134
|
const variant = enumNode.variants[i];
|
|
135
|
+
const variantName = pascalCase(variant.name as string);
|
|
135
136
|
const variantClassName = scope.nameApi.sealedClassVariant(
|
|
136
137
|
name,
|
|
137
138
|
variant.name as string,
|
|
@@ -149,7 +150,7 @@ function getDataEnumPageFragment(
|
|
|
149
150
|
int get hashCode => runtimeType.hashCode;
|
|
150
151
|
|
|
151
152
|
@override
|
|
152
|
-
String toString() => '${typeName}.${
|
|
153
|
+
String toString() => '${typeName}.${variantName}()';
|
|
153
154
|
}`);
|
|
154
155
|
|
|
155
156
|
encoderVariants.push(
|
|
@@ -217,7 +218,7 @@ ${fieldDecls}
|
|
|
217
218
|
int get hashCode => ${hashExpression};
|
|
218
219
|
|
|
219
220
|
@override
|
|
220
|
-
String toString() => '${typeName}.${
|
|
221
|
+
String toString() => '${typeName}.${variantName}(${toStringFields})';
|
|
221
222
|
}`);
|
|
222
223
|
|
|
223
224
|
const encFields = fieldManifests
|
|
@@ -288,7 +289,7 @@ ${fieldDecls}
|
|
|
288
289
|
int get hashCode => value.hashCode;
|
|
289
290
|
|
|
290
291
|
@override
|
|
291
|
-
String toString() => '${typeName}.${
|
|
292
|
+
String toString() => '${typeName}.${variantName}(\$value)';
|
|
292
293
|
}`);
|
|
293
294
|
encoderVariants.push(
|
|
294
295
|
`(${i}, transformEncoder<${manifest.type.content}, Map<String, Object?>>(${manifest.encoder.content}, (Map<String, Object?> map) => map['value']! as ${manifest.type.content}))`,
|
package/src/utils/importMap.ts
CHANGED
|
@@ -77,15 +77,20 @@ export class DartImportMap {
|
|
|
77
77
|
for (const module of this._imports) {
|
|
78
78
|
// Check internal map first (generated cross-references)
|
|
79
79
|
if (module in internalMap) {
|
|
80
|
-
|
|
80
|
+
const uri = internalMap[module];
|
|
81
|
+
if (uri) {
|
|
82
|
+
uris.add(uri);
|
|
83
|
+
}
|
|
81
84
|
}
|
|
82
85
|
// Then external package map
|
|
83
86
|
else if (module in DART_EXTERNAL_PACKAGE_MAP) {
|
|
84
87
|
uris.add(DART_EXTERNAL_PACKAGE_MAP[module]);
|
|
85
88
|
}
|
|
86
|
-
//
|
|
87
|
-
else {
|
|
89
|
+
// Finally, accept explicit Dart URIs and relative Dart paths.
|
|
90
|
+
else if (isRawDartImportUri(module)) {
|
|
88
91
|
uris.add(module);
|
|
92
|
+
} else {
|
|
93
|
+
throw new Error(`Unresolved Dart import module "${module}"`);
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
@@ -127,3 +132,11 @@ export class DartImportMap {
|
|
|
127
132
|
return lines.join("\n");
|
|
128
133
|
}
|
|
129
134
|
}
|
|
135
|
+
|
|
136
|
+
function isRawDartImportUri(module: string): boolean {
|
|
137
|
+
return (
|
|
138
|
+
module.startsWith("dart:") ||
|
|
139
|
+
module.startsWith("package:") ||
|
|
140
|
+
(module.endsWith(".dart") && !module.includes(":"))
|
|
141
|
+
);
|
|
142
|
+
}
|
|
@@ -66,7 +66,7 @@ export interface DartNameApi {
|
|
|
66
66
|
errorMessageFunction(name: string): string;
|
|
67
67
|
/** Enum variant: `camelCase` */
|
|
68
68
|
enumVariant(name: string): string;
|
|
69
|
-
/** Sealed class variant (data enum): `PascalCase` */
|
|
69
|
+
/** Sealed class variant (data enum): `{ParentName}{PascalCase}` */
|
|
70
70
|
sealedClassVariant(parentName: string, variantName: string): string;
|
|
71
71
|
/** File name: `snake_case.dart` */
|
|
72
72
|
fileName(name: string): string;
|
|
@@ -97,7 +97,8 @@ export function createDartNameApi(): DartNameApi {
|
|
|
97
97
|
`${camelCase(programName)}Error${pascalCase(errorName)}`,
|
|
98
98
|
errorMessageFunction: (name) => `get${pascalCase(name)}ErrorMessage`,
|
|
99
99
|
enumVariant: (name) => camelCase(name),
|
|
100
|
-
sealedClassVariant: (
|
|
100
|
+
sealedClassVariant: (parentName, variantName) =>
|
|
101
|
+
`${pascalCase(parentName)}${pascalCase(variantName)}`,
|
|
101
102
|
isTypeFunction: (name) => `is${pascalCase(name)}`,
|
|
102
103
|
fileName: (name) => snakeCase(name),
|
|
103
104
|
discriminatorConstant: (name) => `${camelCase(name)}Discriminator`,
|
|
@@ -44,10 +44,10 @@ export const WELL_KNOWN_ADDRESSES: ReadonlyMap<string, string> = new Map([
|
|
|
44
44
|
|
|
45
45
|
// SPL programs
|
|
46
46
|
['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', 'tokenProgramAddress'],
|
|
47
|
-
['
|
|
48
|
-
['
|
|
49
|
-
['
|
|
50
|
-
['
|
|
47
|
+
['TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb', 'token2022ProgramAddress'],
|
|
48
|
+
['ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL', 'associatedTokenProgramAddress'],
|
|
49
|
+
['MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr', 'memoProgramAddress'],
|
|
50
|
+
['Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo', 'memoLegacyProgramAddress'],
|
|
51
51
|
|
|
52
52
|
// Metaplex programs
|
|
53
53
|
['metaqbxxU9qX8rZXkmUJ7haCrXXz2W1PSUq1Rn3E1od', 'tokenMetadataProgramAddress'],
|
|
@@ -226,18 +226,19 @@ export function getTypeManifestVisitor(input: {
|
|
|
226
226
|
|
|
227
227
|
visitArrayType(node: ArrayTypeNode, { self }) {
|
|
228
228
|
const itemManifest = visit(node.item, self);
|
|
229
|
-
const
|
|
229
|
+
const encoderSizeExpr = getArraySizeExpression(node, "Encoder");
|
|
230
|
+
const decoderSizeExpr = getArraySizeExpression(node, "Decoder");
|
|
230
231
|
|
|
231
232
|
return {
|
|
232
233
|
type: fragment`List<${itemManifest.type}>`,
|
|
233
234
|
encoder: fragment`${use(
|
|
234
235
|
"getArrayEncoder",
|
|
235
236
|
"solanaCodecsDataStructures",
|
|
236
|
-
)}(${itemManifest.encoder}${
|
|
237
|
+
)}(${itemManifest.encoder}${encoderSizeExpr})`,
|
|
237
238
|
decoder: fragment`${use(
|
|
238
239
|
"getArrayDecoder",
|
|
239
240
|
"solanaCodecsDataStructures",
|
|
240
|
-
)}(${itemManifest.decoder}${
|
|
241
|
+
)}(${itemManifest.decoder}${decoderSizeExpr})`,
|
|
241
242
|
value: emptyTypeManifest().value,
|
|
242
243
|
isEnum: false,
|
|
243
244
|
};
|
|
@@ -246,18 +247,19 @@ export function getTypeManifestVisitor(input: {
|
|
|
246
247
|
visitMapType(node: MapTypeNode, { self }) {
|
|
247
248
|
const keyManifest = visit(node.key, self);
|
|
248
249
|
const valueManifest = visit(node.value, self);
|
|
249
|
-
const
|
|
250
|
+
const encoderSizeExpr = getMapSizeExpression(node, "Encoder");
|
|
251
|
+
const decoderSizeExpr = getMapSizeExpression(node, "Decoder");
|
|
250
252
|
|
|
251
253
|
return {
|
|
252
254
|
type: fragment`Map<${keyManifest.type}, ${valueManifest.type}>`,
|
|
253
255
|
encoder: fragment`${use(
|
|
254
256
|
"getMapEncoder",
|
|
255
257
|
"solanaCodecsDataStructures",
|
|
256
|
-
)}(${keyManifest.encoder}, ${valueManifest.encoder}${
|
|
258
|
+
)}(${keyManifest.encoder}, ${valueManifest.encoder}${encoderSizeExpr})`,
|
|
257
259
|
decoder: fragment`${use(
|
|
258
260
|
"getMapDecoder",
|
|
259
261
|
"solanaCodecsDataStructures",
|
|
260
|
-
)}(${keyManifest.decoder}, ${valueManifest.decoder}${
|
|
262
|
+
)}(${keyManifest.decoder}, ${valueManifest.decoder}${decoderSizeExpr})`,
|
|
261
263
|
value: emptyTypeManifest().value,
|
|
262
264
|
isEnum: false,
|
|
263
265
|
};
|
|
@@ -265,18 +267,19 @@ export function getTypeManifestVisitor(input: {
|
|
|
265
267
|
|
|
266
268
|
visitSetType(node: SetTypeNode, { self }) {
|
|
267
269
|
const itemManifest = visit(node.item, self);
|
|
268
|
-
const
|
|
270
|
+
const encoderSizeExpr = getSetSizeExpression(node, "Encoder");
|
|
271
|
+
const decoderSizeExpr = getSetSizeExpression(node, "Decoder");
|
|
269
272
|
|
|
270
273
|
return {
|
|
271
274
|
type: fragment`Set<${itemManifest.type}>`,
|
|
272
275
|
encoder: fragment`${use(
|
|
273
276
|
"getSetEncoder",
|
|
274
277
|
"solanaCodecsDataStructures",
|
|
275
|
-
)}(${itemManifest.encoder}${
|
|
278
|
+
)}(${itemManifest.encoder}${encoderSizeExpr})`,
|
|
276
279
|
decoder: fragment`${use(
|
|
277
280
|
"getSetDecoder",
|
|
278
281
|
"solanaCodecsDataStructures",
|
|
279
|
-
)}(${itemManifest.decoder}${
|
|
282
|
+
)}(${itemManifest.decoder}${decoderSizeExpr})`,
|
|
280
283
|
value: emptyTypeManifest().value,
|
|
281
284
|
isEnum: false,
|
|
282
285
|
};
|
|
@@ -509,20 +512,21 @@ export function getTypeManifestVisitor(input: {
|
|
|
509
512
|
const innerManifest = visit(node.type, self);
|
|
510
513
|
|
|
511
514
|
// The Dart addEncoderSizePrefix / addDecoderSizePrefix APIs require
|
|
512
|
-
// Encoder<num> / Decoder<num> for the prefix
|
|
513
|
-
// (u64, u128, i64, i128) return Encoder<BigInt> which is
|
|
514
|
-
//
|
|
515
|
-
//
|
|
515
|
+
// Encoder<num> / Decoder<num> for the prefix, but BigInt-width number
|
|
516
|
+
// types (u64, u128, i64, i128) return Encoder<BigInt> which is
|
|
517
|
+
// incompatible. Transform the BigInt codec to int so it satisfies the
|
|
518
|
+
// num constraint while preserving the on-chain byte width (e.g. the
|
|
519
|
+
// system program's bincode u64 string-length prefix).
|
|
516
520
|
const bigIntFormats = new Set(["u64", "u128", "i64", "i128"]);
|
|
517
521
|
let prefixManifest;
|
|
518
522
|
if (
|
|
519
523
|
node.prefix.kind === "numberTypeNode" &&
|
|
520
524
|
bigIntFormats.has((node.prefix as any).format)
|
|
521
525
|
) {
|
|
522
|
-
|
|
526
|
+
const codecName = getNumberCodecName((node.prefix as any).format);
|
|
523
527
|
prefixManifest = {
|
|
524
|
-
encoder: fragment
|
|
525
|
-
decoder: fragment
|
|
528
|
+
encoder: fragment`transformEncoder(${use(`get${codecName}Encoder`, "solanaCodecsNumbers")}(), (size) => BigInt.from(size))`,
|
|
529
|
+
decoder: fragment`transformDecoder(${use(`get${codecName}Decoder`, "solanaCodecsNumbers")}(), (size, _, __) => size.toInt())`,
|
|
526
530
|
};
|
|
527
531
|
} else {
|
|
528
532
|
prefixManifest = visit(node.prefix, self);
|
|
@@ -757,7 +761,10 @@ function getNumberCodecExpression(
|
|
|
757
761
|
return `get${name}${codecType}()`;
|
|
758
762
|
}
|
|
759
763
|
|
|
760
|
-
function getArraySizeExpression(
|
|
764
|
+
function getArraySizeExpression(
|
|
765
|
+
node: ArrayTypeNode,
|
|
766
|
+
codecType: "Encoder" | "Decoder",
|
|
767
|
+
): string {
|
|
761
768
|
if (!("count" in node) || !node.count) return "";
|
|
762
769
|
const count = node.count;
|
|
763
770
|
switch (count.kind) {
|
|
@@ -770,14 +777,17 @@ function getArraySizeExpression(node: ArrayTypeNode): string {
|
|
|
770
777
|
if (resolvedPrefix.format === "u32" && (!resolvedPrefix.endian || resolvedPrefix.endian === "le")) {
|
|
771
778
|
return ""; // Default
|
|
772
779
|
}
|
|
773
|
-
return `, size: PrefixedArraySize(
|
|
780
|
+
return `, size: PrefixedArraySize(${getNumberCodecExpression(resolvedPrefix.format, codecType)})`;
|
|
774
781
|
}
|
|
775
782
|
default:
|
|
776
783
|
return "";
|
|
777
784
|
}
|
|
778
785
|
}
|
|
779
786
|
|
|
780
|
-
function getMapSizeExpression(
|
|
787
|
+
function getMapSizeExpression(
|
|
788
|
+
node: MapTypeNode,
|
|
789
|
+
codecType: "Encoder" | "Decoder",
|
|
790
|
+
): string {
|
|
781
791
|
if (!("count" in node) || !node.count) return "";
|
|
782
792
|
const count = node.count;
|
|
783
793
|
switch (count.kind) {
|
|
@@ -790,14 +800,17 @@ function getMapSizeExpression(node: MapTypeNode): string {
|
|
|
790
800
|
if (resolvedPrefix.format === "u32" && (!resolvedPrefix.endian || resolvedPrefix.endian === "le")) {
|
|
791
801
|
return "";
|
|
792
802
|
}
|
|
793
|
-
return `, size: PrefixedArraySize(
|
|
803
|
+
return `, size: PrefixedArraySize(${getNumberCodecExpression(resolvedPrefix.format, codecType)})`;
|
|
794
804
|
}
|
|
795
805
|
default:
|
|
796
806
|
return "";
|
|
797
807
|
}
|
|
798
808
|
}
|
|
799
809
|
|
|
800
|
-
function getSetSizeExpression(
|
|
810
|
+
function getSetSizeExpression(
|
|
811
|
+
node: SetTypeNode,
|
|
812
|
+
codecType: "Encoder" | "Decoder",
|
|
813
|
+
): string {
|
|
801
814
|
if (!("count" in node) || !node.count) return "";
|
|
802
815
|
const count = node.count;
|
|
803
816
|
switch (count.kind) {
|
|
@@ -810,7 +823,7 @@ function getSetSizeExpression(node: SetTypeNode): string {
|
|
|
810
823
|
if (resolvedPrefix.format === "u32" && (!resolvedPrefix.endian || resolvedPrefix.endian === "le")) {
|
|
811
824
|
return "";
|
|
812
825
|
}
|
|
813
|
-
return `, size: PrefixedArraySize(
|
|
826
|
+
return `, size: PrefixedArraySize(${getNumberCodecExpression(resolvedPrefix.format, codecType)})`;
|
|
814
827
|
}
|
|
815
828
|
default:
|
|
816
829
|
return "";
|
|
@@ -43,7 +43,7 @@ export function renderVisitor(
|
|
|
43
43
|
// 3. Build a map of definedType module keys to their render map paths
|
|
44
44
|
const typePathMap: Record<string, string> = {};
|
|
45
45
|
for (const renderPath of renderMap.keys()) {
|
|
46
|
-
const match = renderPath.match(/^(?:.*\/)?types\/([a-
|
|
46
|
+
const match = renderPath.match(/^(?:.*\/)?types\/([a-z0-9_]+)\.dart$/);
|
|
47
47
|
if (match) {
|
|
48
48
|
typePathMap[`definedType:${match[1]}`] = renderPath;
|
|
49
49
|
}
|
|
@@ -63,8 +63,12 @@ export function renderVisitor(
|
|
|
63
63
|
const fileDir = dirname(filePath);
|
|
64
64
|
const internalMap: Record<string, string> = {};
|
|
65
65
|
for (const [key, typePath] of Object.entries(typePathMap)) {
|
|
66
|
-
//
|
|
67
|
-
if (typePath === filePath)
|
|
66
|
+
// Keep the key resolved without generating a self-import.
|
|
67
|
+
if (typePath === filePath) {
|
|
68
|
+
internalMap[key] = "";
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
let rel = posix.relative(fileDir, typePath);
|
|
69
73
|
if (!rel.startsWith(".")) {
|
|
70
74
|
rel = `./${rel}`;
|