codama-renderers-dart 0.4.3 → 0.5.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.browser.cjs +634 -159
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +635 -161
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.node.cjs +634 -159
  7. package/dist/index.node.cjs.map +1 -1
  8. package/dist/index.node.js +635 -161
  9. package/dist/index.node.js.map +1 -1
  10. package/dist/index.react-native.js +635 -161
  11. package/dist/index.react-native.js.map +1 -1
  12. package/dist/types/fragments/accountPage.d.ts.map +1 -1
  13. package/dist/types/fragments/instructionPage.d.ts.map +1 -1
  14. package/dist/types/fragments/programPage.d.ts +1 -1
  15. package/dist/types/fragments/programPage.d.ts.map +1 -1
  16. package/dist/types/fragments/typePage.d.ts.map +1 -1
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/index.d.ts.map +1 -1
  19. package/dist/types/utils/discriminators.d.ts +10 -0
  20. package/dist/types/utils/discriminators.d.ts.map +1 -0
  21. package/dist/types/utils/exactDecoder.d.ts +17 -0
  22. package/dist/types/utils/exactDecoder.d.ts.map +1 -0
  23. package/dist/types/utils/formatCode.d.ts +1 -1
  24. package/dist/types/utils/formatCode.d.ts.map +1 -1
  25. package/dist/types/utils/importMap.d.ts.map +1 -1
  26. package/dist/types/utils/index.d.ts +4 -0
  27. package/dist/types/utils/index.d.ts.map +1 -1
  28. package/dist/types/utils/nameTransformers.d.ts +1 -1
  29. package/dist/types/utils/nameTransformers.d.ts.map +1 -1
  30. package/dist/types/utils/normalizeRootNode.d.ts +11 -0
  31. package/dist/types/utils/normalizeRootNode.d.ts.map +1 -0
  32. package/dist/types/utils/valueNodes.d.ts +16 -0
  33. package/dist/types/utils/valueNodes.d.ts.map +1 -0
  34. package/dist/types/visitors/getTypeManifestVisitor.d.ts +1 -1
  35. package/dist/types/visitors/getTypeManifestVisitor.d.ts.map +1 -1
  36. package/dist/types/visitors/renderVisitor.d.ts.map +1 -1
  37. package/package.json +31 -23
  38. package/readme.md +30 -3
  39. package/src/fragments/accountPage.ts +90 -17
  40. package/src/fragments/instructionPage.ts +109 -72
  41. package/src/fragments/programPage.ts +165 -6
  42. package/src/fragments/typePage.ts +36 -15
  43. package/src/index.ts +1 -0
  44. package/src/utils/discriminators.ts +121 -0
  45. package/src/utils/exactDecoder.ts +82 -0
  46. package/src/utils/formatCode.ts +7 -11
  47. package/src/utils/importMap.ts +16 -3
  48. package/src/utils/index.ts +4 -0
  49. package/src/utils/nameTransformers.ts +3 -2
  50. package/src/utils/normalizeRootNode.ts +76 -0
  51. package/src/utils/valueNodes.ts +87 -0
  52. package/src/utils/wellKnownAddresses.ts +4 -4
  53. package/src/visitors/getRenderMapVisitor.ts +1 -1
  54. package/src/visitors/getTypeManifestVisitor.ts +48 -29
  55. package/src/visitors/renderVisitor.ts +11 -4
@@ -1 +1 @@
1
- {"version":3,"file":"accountPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/accountPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,eAAe,CAAC;AAItE,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,CA0LV"}
1
+ {"version":3,"file":"accountPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/accountPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,eAAe,CAAC;AAItE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAUvD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,GACjB,QAAQ,CA8OV"}
@@ -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,CA4PV"}
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;AAOrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAUvD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAuUV"}
@@ -1,4 +1,4 @@
1
- import type { ProgramNode } from "@codama/nodes";
1
+ import { type ProgramNode } from "@codama/nodes";
2
2
  import type { Fragment } from "../utils/fragment.js";
3
3
  import type { RenderScope } from "../utils/options.js";
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"programPage.d.ts","sourceRoot":"","sources":["../../../src/fragments/programPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,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,CAgEV"}
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":"typePage.d.ts","sourceRoot":"","sources":["../../../src/fragments/typePage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiC,MAAM,eAAe,CAAC;AAIpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAsBV"}
1
+ {"version":3,"file":"typePage.d.ts","sourceRoot":"","sources":["../../../src/fragments/typePage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAuBV"}
@@ -3,6 +3,7 @@ export { getRenderMapVisitor } from "./visitors/getRenderMapVisitor.js";
3
3
  export { getTypeManifestVisitor } from "./visitors/getTypeManifestVisitor.js";
4
4
  export { DartImportMap, DART_EXTERNAL_PACKAGE_MAP } from "./utils/importMap.js";
5
5
  export { createDartNameApi } from "./utils/nameTransformers.js";
6
+ export { normalizeRootNode } from "./utils/normalizeRootNode.js";
6
7
  export type { DartNameApi } from "./utils/nameTransformers.js";
7
8
  export type { RenderOptions, GetRenderMapOptions, RenderScope } from "./utils/options.js";
8
9
  export type { TypeManifest } from "./utils/typeManifest.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,eAAe,aAAa,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { AccountNode, InstructionNode } from "@codama/nodes";
2
+ import type { Fragment } from "./fragment.js";
3
+ import type { RenderScope } from "./options.js";
4
+ type DiscriminatedNode = AccountNode | InstructionNode;
5
+ /**
6
+ * Generate decoder guards for every discriminator declared by a Codama node.
7
+ */
8
+ export declare function getDiscriminatorValidationFragment(node: DiscriminatedNode, scope: RenderScope): Fragment;
9
+ export {};
10
+ //# sourceMappingURL=discriminators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discriminators.d.ts","sourceRoot":"","sources":["../../../src/utils/discriminators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,eAAe,EAEhB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQ9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,KAAK,iBAAiB,GAAG,WAAW,GAAG,eAAe,CAAC;AAEvD;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,WAAW,GACjB,QAAQ,CAwDV"}
@@ -0,0 +1,17 @@
1
+ import type { Fragment } from "./fragment.js";
2
+ export interface TopLevelDecoderFragmentOptions {
3
+ readonly typeName: string;
4
+ readonly description: string;
5
+ readonly discriminatorValidation: Fragment;
6
+ readonly fromMapFields: string;
7
+ readonly requireExactConsumption: boolean;
8
+ }
9
+ /**
10
+ * Wrap a generated top-level struct decoder with discriminator and length
11
+ * validation.
12
+ *
13
+ * The wrapper preserves fixed/variable decoder metadata so it remains
14
+ * compatible with the matching generated encoder when combined into a codec.
15
+ */
16
+ export declare function getTopLevelDecoderFragment({ typeName, description, discriminatorValidation, fromMapFields, requireExactConsumption, }: TopLevelDecoderFragmentOptions): Fragment;
17
+ //# sourceMappingURL=exactDecoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exactDecoder.d.ts","sourceRoot":"","sources":["../../../src/utils/exactDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,uBAAuB,EAAE,QAAQ,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,QAAQ,EACR,WAAW,EACX,uBAAuB,EACvB,aAAa,EACb,uBAAuB,GACxB,EAAE,8BAA8B,GAAG,QAAQ,CAyD3C"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Format Dart code using `dart format`.
3
- * Falls back to returning the unformatted code if dart is not available.
3
+ * Falls back to returning the unformatted code if Dart is not available.
4
4
  */
5
5
  export declare function formatDartCode(code: string): string;
6
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"formatCode.d.ts","sourceRoot":"","sources":["../../../src/utils/formatCode.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAUrD"}
1
+ {"version":3,"file":"formatCode.d.ts","sourceRoot":"","sources":["../../../src/utils/formatCode.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMrD"}
@@ -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;IA2B3D;;OAEG;IACH,QAAQ,CAAC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM;CAyB3D"}
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"}
@@ -1,9 +1,13 @@
1
1
  export * from "./codecs.js";
2
+ export * from "./discriminators.js";
3
+ export * from "./exactDecoder.js";
2
4
  export * from "./formatCode.js";
3
5
  export * from "./fragment.js";
4
6
  export * from "./importMap.js";
5
7
  export * from "./nameTransformers.js";
8
+ export * from "./normalizeRootNode.js";
6
9
  export * from "./options.js";
7
10
  export * from "./typeManifest.js";
11
+ export * from "./valueNodes.js";
8
12
  export * from "./wellKnownAddresses.js";
9
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC"}
@@ -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,qDAAqD;IACrD,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,CAuB/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAEhE"}
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"}
@@ -0,0 +1,11 @@
1
+ import type { RootNode } from "@codama/nodes";
2
+ /**
3
+ * Normalizes a serialized Codama root before it reaches Codama's visitors.
4
+ *
5
+ * Codama constructors materialize empty child collections, while generated
6
+ * JSON commonly omits them. Pina intentionally omits those empty fields, so
7
+ * restore only the structural defaults required by Codama traversal. This is
8
+ * a copy: callers retain their original parsed IDL unchanged.
9
+ */
10
+ export declare function normalizeRootNode(root: RootNode): RootNode;
11
+ //# sourceMappingURL=normalizeRootNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeRootNode.d.ts","sourceRoot":"","sources":["../../../src/utils/normalizeRootNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAE1D"}
@@ -0,0 +1,16 @@
1
+ import type { InstructionInputValueNode, ValueNode } from "@codama/nodes";
2
+ import type { Fragment } from "./fragment.js";
3
+ type RenderableValueNode = InstructionInputValueNode | ValueNode;
4
+ /**
5
+ * Render a standalone Codama value as a Dart expression.
6
+ *
7
+ * Contextual instruction values need resolver state and are deliberately
8
+ * rejected here. Defaults and discriminators must be deterministic at code
9
+ * generation time so generated encoders cannot silently choose a different
10
+ * wire value.
11
+ */
12
+ export declare function getDartValueFragment(value: RenderableValueNode, dartType?: string): Fragment;
13
+ /** Return whether a rendered standalone value is valid in a const initializer. */
14
+ export declare function isConstDartValueNode(value: RenderableValueNode): boolean;
15
+ export {};
16
+ //# sourceMappingURL=valueNodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valueNodes.d.ts","sourceRoot":"","sources":["../../../src/utils/valueNodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,SAAS,EACV,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,KAAK,mBAAmB,GAAG,yBAAyB,GAAG,SAAS,CAAC;AAEjE;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB,QAAQ,CAsCV;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAWxE"}
@@ -15,5 +15,5 @@ export declare function getTypeManifestVisitor(input: {
15
15
  linkables: LinkableDictionary;
16
16
  stack: NodeStack;
17
17
  nonScalarEnums?: CamelCaseString[];
18
- }): Visitor<TypeManifest, "accountNode" | "constantNode" | "definedTypeNode" | "errorNode" | "eventNode" | "instructionAccountNode" | "instructionArgumentNode" | "instructionByteDeltaNode" | "instructionNode" | "instructionRemainingAccountsNode" | "instructionStatusNode" | "pdaNode" | "programNode" | "pdaSeedValueNode" | "accountBumpValueNode" | "accountValueNode" | "argumentValueNode" | "conditionalValueNode" | "identityValueNode" | "payerValueNode" | "pdaValueNode" | "programIdValueNode" | "resolverValueNode" | "fixedCountNode" | "prefixedCountNode" | "remainderCountNode" | "constantDiscriminatorNode" | "fieldDiscriminatorNode" | "sizeDiscriminatorNode" | "accountLinkNode" | "definedTypeLinkNode" | "instructionAccountLinkNode" | "instructionArgumentLinkNode" | "instructionLinkNode" | "pdaLinkNode" | "programLinkNode" | "constantPdaSeedNode" | "variablePdaSeedNode" | "enumEmptyVariantTypeNode" | "enumStructVariantTypeNode" | "enumTupleVariantTypeNode" | "amountTypeNode" | "arrayTypeNode" | "booleanTypeNode" | "bytesTypeNode" | "dateTimeTypeNode" | "enumTypeNode" | "fixedSizeTypeNode" | "hiddenPrefixTypeNode" | "hiddenSuffixTypeNode" | "mapTypeNode" | "numberTypeNode" | "optionTypeNode" | "postOffsetTypeNode" | "preOffsetTypeNode" | "publicKeyTypeNode" | "remainderOptionTypeNode" | "sentinelTypeNode" | "setTypeNode" | "sizePrefixTypeNode" | "solAmountTypeNode" | "stringTypeNode" | "structTypeNode" | "tupleTypeNode" | "zeroableOptionTypeNode" | "structFieldTypeNode" | "mapEntryValueNode" | "arrayValueNode" | "booleanValueNode" | "bytesValueNode" | "constantValueNode" | "enumValueNode" | "mapValueNode" | "noneValueNode" | "numberValueNode" | "publicKeyValueNode" | "setValueNode" | "someValueNode" | "stringValueNode" | "structValueNode" | "tupleValueNode" | "structFieldValueNode" | "rootNode">;
18
+ }): Visitor<TypeManifest, "accountBumpValueNode" | "accountValueNode" | "argumentValueNode" | "conditionalValueNode" | "identityValueNode" | "payerValueNode" | "pdaValueNode" | "programIdValueNode" | "resolverValueNode" | "programLinkNode" | "arrayValueNode" | "booleanValueNode" | "bytesValueNode" | "constantValueNode" | "enumValueNode" | "mapValueNode" | "noneValueNode" | "numberValueNode" | "publicKeyValueNode" | "setValueNode" | "someValueNode" | "stringValueNode" | "structValueNode" | "tupleValueNode" | "amountTypeNode" | "arrayTypeNode" | "booleanTypeNode" | "bytesTypeNode" | "dateTimeTypeNode" | "enumTypeNode" | "fixedSizeTypeNode" | "hiddenPrefixTypeNode" | "hiddenSuffixTypeNode" | "mapTypeNode" | "numberTypeNode" | "optionTypeNode" | "postOffsetTypeNode" | "preOffsetTypeNode" | "publicKeyTypeNode" | "remainderOptionTypeNode" | "sentinelTypeNode" | "setTypeNode" | "sizePrefixTypeNode" | "solAmountTypeNode" | "stringTypeNode" | "structTypeNode" | "tupleTypeNode" | "zeroableOptionTypeNode" | "constantDiscriminatorNode" | "fieldDiscriminatorNode" | "sizeDiscriminatorNode" | "accountNode" | "constantNode" | "definedTypeNode" | "errorNode" | "eventNode" | "instructionAccountNode" | "instructionArgumentNode" | "instructionByteDeltaNode" | "instructionNode" | "instructionRemainingAccountsNode" | "instructionStatusNode" | "pdaNode" | "programNode" | "pdaSeedValueNode" | "fixedCountNode" | "prefixedCountNode" | "remainderCountNode" | "accountLinkNode" | "definedTypeLinkNode" | "instructionAccountLinkNode" | "instructionArgumentLinkNode" | "instructionLinkNode" | "pdaLinkNode" | "constantPdaSeedNode" | "variablePdaSeedNode" | "enumEmptyVariantTypeNode" | "enumStructVariantTypeNode" | "enumTupleVariantTypeNode" | "structFieldTypeNode" | "mapEntryValueNode" | "structFieldValueNode" | "rootNode">;
19
19
  //# sourceMappingURL=getTypeManifestVisitor.d.ts.map
@@ -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,6xDAymBA"}
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,6xDAmnBA"}
@@ -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,6DA+D5B"}
1
+ {"version":3,"file":"renderVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/renderVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,6DAqE5B"}
package/package.json CHANGED
@@ -1,30 +1,38 @@
1
1
  {
2
2
  "dependencies": {
3
- "@codama/errors": "^1.4.4",
4
- "@codama/nodes": "^1.4.4",
5
- "@codama/renderers-core": "^1.3.3",
6
- "@codama/visitors-core": "^1.4.4"
3
+ "@codama/errors": "^1.10.0",
4
+ "@codama/nodes": "^1.10.0",
5
+ "@codama/renderers-core": "^1.3.12",
6
+ "@codama/visitors-core": "^1.10.0"
7
7
  },
8
8
  "description": "Codama renderer for generating Dart code targeting the solana_kit SDK",
9
9
  "devDependencies": {
10
- "@codama/nodes-from-anchor": "^1.3.9",
11
- "@codama/renderers-js": "^2.0.2",
12
- "@vitest/coverage-v8": "4.1.0"
10
+ "@codama/nodes-from-anchor": "^1.5.4",
11
+ "@codama/renderers-js": "^2.3.1",
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"
16
21
  },
17
22
  "exports": {
18
- "browser": {
19
- "import": "./dist/index.browser.mjs",
20
- "require": "./dist/index.browser.cjs"
21
- },
22
- "node": {
23
- "import": "./dist/index.node.mjs",
24
- "require": "./dist/index.node.cjs"
25
- },
26
- "react-native": "./dist/index.react-native.mjs",
27
- "types": "./dist/types/index.d.ts"
23
+ ".": {
24
+ "types": "./dist/types/index.d.ts",
25
+ "react-native": "./dist/index.react-native.js",
26
+ "browser": {
27
+ "import": "./dist/index.browser.js",
28
+ "require": "./dist/index.browser.cjs"
29
+ },
30
+ "node": {
31
+ "import": "./dist/index.node.js",
32
+ "require": "./dist/index.node.cjs"
33
+ },
34
+ "default": "./dist/index.node.js"
35
+ }
28
36
  },
29
37
  "files": [
30
38
  "dist",
@@ -39,12 +47,15 @@
39
47
  ],
40
48
  "license": "MIT",
41
49
  "main": "./dist/index.node.cjs",
42
- "module": "./dist/index.node.mjs",
50
+ "module": "./dist/index.node.js",
43
51
  "name": "codama-renderers-dart",
44
52
  "publishConfig": {
45
53
  "access": "public"
46
54
  },
47
55
  "repository": "https://github.com/openbudgetfun/solana_kit/tree/main/packages/codama-renderers-dart",
56
+ "type": "module",
57
+ "types": "./dist/types/index.d.ts",
58
+ "version": "0.5.1",
48
59
  "scripts": {
49
60
  "build": "pnpm exec rimraf dist && pnpm exec tsup && pnpm exec tsc -p tsconfig.declarations.json",
50
61
  "lint": "eslint --ext .ts src",
@@ -52,8 +63,5 @@
52
63
  "test:coverage": "pnpm exec vitest run --coverage.enabled --coverage.reporter=lcov",
53
64
  "test:watch": "pnpm exec vitest",
54
65
  "typecheck": "pnpm exec tsc --noEmit"
55
- },
56
- "type": "module",
57
- "types": "./dist/types/index.d.ts",
58
- "version": "0.4.3"
59
- }
66
+ }
67
+ }
package/readme.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # codama-renderers-dart
2
2
 
3
- [![pub package](https://img.shields.io/pub/v/codama-renderers-dart.svg)](https://pub.dev/packages/codama-renderers-dart)
4
- [![CI](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml)
5
- [![Coverage](https://codecov.io/gh/openbudgetfun/solana_kit/branch/main/graph/badge.svg?flag=codama-renderers-dart)](https://codecov.io/gh/openbudgetfun/solana_kit?flag=codama-renderers-dart)
3
+ [![pub package](https://img.shields.io/pub/v/codama-renderers-dart.svg)](https://pub.dev/packages/codama-renderers-dart) [![CI](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/openbudgetfun/solana_kit/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/openbudgetfun/solana_kit/branch/main/graph/badge.svg?flag=codama-renderers-dart)](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
 
9
7
  Given a Codama IDL (Interface Description Language) describing a Solana program, this renderer produces a complete Dart package with typed account classes, instruction builders, codec functions, error definitions, PDA helpers, and barrel exports.
10
8
 
9
+ Fixed-size Codama types generate non-truncating encoders. Values within the declared byte capacity are zero-padded, while over-capacity values throw before any malformed bytes can be emitted. For UTF-8 strings, capacity is measured in encoded bytes rather than Dart code units.
10
+
11
11
  ## Installation
12
12
 
13
13
  ```bash
@@ -39,6 +39,21 @@ visit(root, renderVisitor("lib/src/generated", {
39
39
  }));
40
40
  ```
41
41
 
42
+ ### Serialized Pina IDLs
43
+
44
+ `renderVisitor` accepts parsed Codama JSON as well as roots made with Codama constructors. Pina omits empty collections from its serialized IDLs; the renderer restores those structural defaults on an internal copy before traversal, leaving the parsed object unchanged.
45
+
46
+ ```typescript
47
+ import { readFile } from "node:fs/promises";
48
+ import { visit } from "@codama/visitors-core";
49
+ import { renderVisitor } from "codama-renderers-dart";
50
+
51
+ const idl = JSON.parse(await readFile("target/codama/my_program.json", "utf8"));
52
+ visit(idl, renderVisitor("lib/src/generated"));
53
+ ```
54
+
55
+ Use `normalizeRootNode(idl)` when calling lower-level visitors such as `getRenderMapVisitor` directly.
56
+
42
57
  ### Codama CLI
43
58
 
44
59
  Create a `codama.json` configuration file:
@@ -141,6 +156,16 @@ Instruction getTransferInstruction({
141
156
  TransferInstructionData parseTransferInstruction(Instruction instruction) { ... }
142
157
  ```
143
158
 
159
+ ### Discriminators and omitted defaults
160
+
161
+ Generated codecs treat Codama discriminators as wire invariants rather than caller input. A struct field or instruction argument with a default value strategy of `omitted` is not accepted by the generated constructor or instruction builder. Its declared default is always written by the encoder.
162
+
163
+ Account and instruction decoders validate every declared constant, field, and size discriminator before returning typed data. Invalid discriminator bytes and unexpected discriminator sizes throw a `SolanaError` instead of decoding as the wrong account or instruction type. Generation fails when a field discriminator has no deterministic default or uses a value form the renderer cannot encode safely.
164
+
165
+ Top-level instruction decoders require exact input consumption. Account decoders always reject truncated data, but accept unread trailing capacity unless the account declares a `sizeDiscriminatorNode`; size-discriminated accounts reject both truncation and suffix bytes.
166
+
167
+ Optional instruction accounts use Codama's `programId` strategy by default. When an optional account is absent, the builder emits a readonly program-address placeholder so every later account keeps its declared index. The account slot is removed only when the instruction explicitly selects the legacy `omitted` strategy.
168
+
144
169
  ### Scalar Enums
145
170
 
146
171
  Scalar enums (all-empty variants) generate a Dart `enum` with index-based encoder/decoder:
@@ -156,6 +181,8 @@ Encoder<AccountStatus> getAccountStatusEncoder() { ... }
156
181
  Decoder<AccountStatus> getAccountStatusDecoder() { ... }
157
182
  ```
158
183
 
184
+ The generated enum API is the same for `u8`, `u16`, `u32`, and `u64` discriminators. The renderer converts `u64` indices to and from `BigInt` at the codec boundary and rejects out-of-range discriminators before converting them to Dart enum indices.
185
+
159
186
  ### Data Enums (Discriminated Unions)
160
187
 
161
188
  Data enums generate Dart 3 `sealed class` hierarchies:
@@ -12,6 +12,12 @@ import {
12
12
  } from "../utils/fragment.js";
13
13
  import type { RenderScope } from "../utils/options.js";
14
14
  import { camelCase } from "../utils/nameTransformers.js";
15
+ import { getDiscriminatorValidationFragment } from "../utils/discriminators.js";
16
+ import { getTopLevelDecoderFragment } from "../utils/exactDecoder.js";
17
+ import {
18
+ getDartValueFragment,
19
+ isConstDartValueNode,
20
+ } from "../utils/valueNodes.js";
15
21
  import { getDiscriminatorConstantsFragment } from "./discriminatorConstants.js";
16
22
 
17
23
  /**
@@ -23,10 +29,8 @@ export function getAccountPageFragment(
23
29
  ): Fragment {
24
30
  const name = node.name as string;
25
31
  const typeName = scope.nameApi.dataType(name);
26
- const dataNode = resolveNestedTypeNode(node.data);
27
-
28
32
  // Fields from the struct data
29
- const fields = dataNode.fields;
33
+ const fields = resolveNestedTypeNode(node.data).fields ?? [];
30
34
 
31
35
  // Visit each field type once and collect manifests for reuse
32
36
  const fieldManifests = fields.map((f: StructFieldTypeNode) => ({
@@ -34,20 +38,60 @@ export function getAccountPageFragment(
34
38
  manifest: visit(f.type, scope.typeManifestVisitor),
35
39
  }));
36
40
 
41
+ const omittedFields = fields.filter(isOmittedDefaultField);
42
+ const constructorFields = fields.filter(
43
+ (field) => !isOmittedDefaultField(field),
44
+ );
45
+ const forcedFields = new Set([
46
+ ...omittedFields,
47
+ ...fields.filter((field) => isFieldDiscriminator(field, node)),
48
+ ]);
49
+ const fieldDefaults = new Map(
50
+ fieldManifests.flatMap(({ field, manifest }) => {
51
+ if (!forcedFields.has(field) || field.defaultValue == null) return [];
52
+ return [
53
+ [
54
+ field,
55
+ getDartValueFragment(field.defaultValue, manifest.type.content),
56
+ ] as const,
57
+ ];
58
+ }),
59
+ );
60
+
61
+ for (const field of forcedFields) {
62
+ if (!fieldDefaults.has(field)) {
63
+ throw new Error(
64
+ `Forced field "${field.name}" on account "${node.name}" must have a deterministic default value.`,
65
+ );
66
+ }
67
+ }
68
+
37
69
  const fieldDecls = fieldManifests
38
70
  .map(({ field: f, manifest }) => {
39
71
  return ` final ${manifest.type.content} ${camelCase(f.name as string)};`;
40
72
  })
41
73
  .join("\n");
42
74
 
43
- const ctorParams = fields
75
+ const ctorParams = constructorFields
44
76
  .map((f: StructFieldTypeNode) => ` required this.${camelCase(f.name as string)},`)
45
77
  .join("\n");
46
78
 
79
+ const ctorInitializers = omittedFields
80
+ .map((field) => {
81
+ const fieldName = camelCase(field.name as string);
82
+ return `${fieldName} = ${fieldDefaults.get(field)!.content}`;
83
+ })
84
+ .join(",\n ");
85
+
47
86
  // Empty structs use a no-arg constructor; `const Foo({})` is invalid Dart.
48
- const ctorSignature = fields.length === 0
49
- ? `const ${typeName}();`
50
- : `const ${typeName}({\n${ctorParams}\n });`;
87
+ const ctorKeyword = omittedFields.every((field) =>
88
+ isConstDartValueNode(field.defaultValue!),
89
+ )
90
+ ? "const "
91
+ : "";
92
+ const ctorSignature = constructorFields.length === 0
93
+ ? `${ctorKeyword}${typeName}()${ctorInitializers ? ` : ${ctorInitializers}` : ""};`
94
+ : `${ctorKeyword}${typeName}({\n${ctorParams}\n })${ctorInitializers ? ` :\n ${ctorInitializers}` : ""};`;
51
95
 
52
96
  const eqChecks =
53
97
  fields.length === 0
@@ -89,13 +133,16 @@ export function getAccountPageFragment(
89
133
  .join("\n");
90
134
 
91
135
  const toMapFields = fields
92
- .map(
93
- (f: StructFieldTypeNode) =>
94
- ` '${f.name as string}': value.${camelCase(f.name as string)},`,
95
- )
136
+ .map((f: StructFieldTypeNode) => {
137
+ const value = forcedFields.has(f)
138
+ ? fieldDefaults.get(f)!.content
139
+ : `value.${camelCase(f.name as string)}`;
140
+ return ` '${f.name as string}': ${value},`;
141
+ })
96
142
  .join("\n");
97
143
 
98
144
  const fromMapFields = fieldManifests
145
+ .filter(({ field }) => !isOmittedDefaultField(field))
99
146
  .map(({ field: f, manifest }) => {
100
147
  const typeStr = manifest.type.content;
101
148
  const isNullable = typeStr.endsWith("?");
@@ -118,6 +165,19 @@ const int ${fragmentFromString(scope.nameApi.accountSizeConstant(name))} = ${fra
118
165
 
119
166
  // Discriminator
120
167
  const discFragment = getDiscriminatorConstantsFragment(node, scope);
168
+ const discriminatorValidation = getDiscriminatorValidationFragment(
169
+ node,
170
+ scope,
171
+ );
172
+ const topLevelDecoder = getTopLevelDecoderFragment({
173
+ typeName,
174
+ description: `${name} account decoder`,
175
+ discriminatorValidation,
176
+ fromMapFields,
177
+ requireExactConsumption: (node.discriminators ?? []).some(
178
+ (discriminator) => discriminator.kind === "sizeDiscriminatorNode",
179
+ ),
180
+ });
121
181
 
122
182
  const parts: Fragment[] = [
123
183
  fragment`// Auto-generated. Do not edit.
@@ -180,12 +240,7 @@ Decoder<${fragmentFromString(typeName)}> ${fragmentFromString(decoderName)}() {
180
240
  ${fragmentFromString(decFields)}
181
241
  ]);
182
242
 
183
- return transformDecoder(
184
- structDecoder,
185
- (Map<String, Object?> map, Uint8List bytes, int offset) => ${fragmentFromString(typeName)}(
186
- ${fragmentFromString(fromMapFields)}
187
- ),
188
- );
243
+ ${topLevelDecoder}
189
244
  }
190
245
 
191
246
  Codec<${fragmentFromString(typeName)}, ${fragmentFromString(typeName)}> ${fragmentFromString(codecName)}() {
@@ -204,6 +259,24 @@ Account<${fragmentFromString(typeName)}> ${fragmentFromString(decodeFnName)}(Enc
204
259
  result.imports.mergeWith(manifest.decoder.imports);
205
260
  result.imports.mergeWith(manifest.type.imports);
206
261
  }
262
+ for (const defaultValue of fieldDefaults.values()) {
263
+ result.imports.mergeWith(defaultValue.imports);
264
+ }
207
265
 
208
266
  return result;
209
267
  }
268
+
269
+ function isOmittedDefaultField(field: StructFieldTypeNode): boolean {
270
+ return field.defaultValue != null && field.defaultValueStrategy === "omitted";
271
+ }
272
+
273
+ function isFieldDiscriminator(
274
+ field: StructFieldTypeNode,
275
+ node: AccountNode,
276
+ ): boolean {
277
+ return (node.discriminators ?? []).some(
278
+ (discriminator) =>
279
+ discriminator.kind === "fieldDiscriminatorNode" &&
280
+ discriminator.name === field.name,
281
+ );
282
+ }