codama-renderers-dart 0.5.5 → 0.5.6

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.
@@ -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,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"}
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;eAC7C,aAAa"}
@@ -1 +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"}
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,CA+DV"}
@@ -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;IAgC3D;;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,CAGxB;IAED;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAKpC;IAED;;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,CA8B1D;IAED;;OAEG;IACH,QAAQ,CAAC,WAAW,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,CAwBzD;CACF"}
@@ -1,6 +1,28 @@
1
1
  import type { LinkableDictionary } from "@codama/visitors-core";
2
2
  import type { DartNameApi } from "./nameTransformers.js";
3
3
  import type { TypeManifestVisitor } from "../visitors/getTypeManifestVisitor.js";
4
+ /**
5
+ * A hand-written codec that backs a defined-type link in the rendered IDL.
6
+ *
7
+ * Some IDL fields cannot be expressed with Codama type nodes and need a
8
+ * hand-written codec instead — for example, the Token-2022 TLV extension
9
+ * region, which stops at the first `Uninitialized` header rather than
10
+ * consuming every trailing byte. Codama has no "stop at a discriminator" type
11
+ * node, so the IDL is prepared to link the inner type to a name and the
12
+ * renderer is told which hand-written codec backs that link. Wrappers around
13
+ * the link (`Option`, `HiddenPrefix`, …) still come from the IDL, so the wire
14
+ * format is unchanged.
15
+ */
16
+ export interface LinkOverride {
17
+ /** The Dart file the codec lives in, relative to the package's `lib/`. */
18
+ path: string;
19
+ /** The Dart type the link resolves to, e.g. `List<Extension>`. */
20
+ type: string;
21
+ /** The encoder expression, e.g. `getExtensionsEncoder()`. */
22
+ encoder: string;
23
+ /** The decoder expression, e.g. `getExtensionsDecoder()`. */
24
+ decoder: string;
25
+ }
4
26
  /**
5
27
  * Options for the top-level renderVisitor.
6
28
  */
@@ -22,6 +44,13 @@ export interface GetRenderMapOptions {
22
44
  nameApi?: Partial<DartNameApi>;
23
45
  /** Dependency map overrides (logical module -> Dart package URI). */
24
46
  dependencyMap?: Record<string, string>;
47
+ /**
48
+ * Hand-written codec overrides for defined-type links, keyed by the link
49
+ * name as it appears in Codama nodes. A link with a matching key emits the
50
+ * override's type and codec expressions instead of resolving to a generated
51
+ * type file, and imports the override's Dart file.
52
+ */
53
+ linkOverrides?: Record<string, LinkOverride>;
25
54
  }
26
55
  /**
27
56
  * Shared rendering context passed to fragment generators.
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/utils/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,2EAA2E;IAC3E,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,OAAO,EAAE,WAAW,CAAC;IACrB,0DAA0D;IAC1D,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,sDAAsD;IACtD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gEAAgE;IAChE,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/utils/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACxD,2EAA2E;IAC3E,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,OAAO,EAAE,WAAW,CAAC;IACrB,0DAA0D;IAC1D,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,sDAAsD;IACtD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gEAAgE;IAChE,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C"}
@@ -1 +1 @@
1
- {"version":3,"file":"wellKnownAddresses.d.ts","sourceRoot":"","sources":["../../../src/utils/wellKnownAddresses.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAsD3D,CAAC"}
1
+ {"version":3,"file":"wellKnownAddresses.d.ts","sourceRoot":"","sources":["../../../src/utils/wellKnownAddresses.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAuD3D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getRenderMapVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/getRenderMapVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,OAAO,EASb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,qBAAqB,CAAC;AAa5E;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,SAAS,CAAC,CA2K9H"}
1
+ {"version":3,"file":"getRenderMapVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/getRenderMapVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,OAAO,EASb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,qBAAqB,CAAC;AAa5E;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,iBAAiB,GAAG,iBAAiB,GAAG,SAAS,CAAC,CA4K9H"}
@@ -2,6 +2,7 @@ import { type CamelCaseString } from "@codama/nodes";
2
2
  import { type LinkableDictionary, type NodeStack, type Visitor } from "@codama/visitors-core";
3
3
  import { type TypeManifest } from "../utils/index.js";
4
4
  import { type DartNameApi } from "../utils/nameTransformers.js";
5
+ import type { LinkOverride } from "../utils/options.js";
5
6
  /**
6
7
  * Type alias for the type manifest visitor.
7
8
  */
@@ -15,5 +16,6 @@ export declare function getTypeManifestVisitor(input: {
15
16
  linkables: LinkableDictionary;
16
17
  stack: NodeStack;
17
18
  nonScalarEnums?: CamelCaseString[];
18
- }): Visitor<TypeManifest, "accountBumpValueNode" | "accountFieldValueNode" | "accountValueNode" | "argumentValueNode" | "conditionalValueNode" | "identityValueNode" | "payerValueNode" | "pdaValueNode" | "programIdValueNode" | "resolverValueNode" | "programLinkNode" | "arrayValueNode" | "booleanValueNode" | "bytesValueNode" | "constantValueNode" | "enumValueNode" | "injectedValueNode" | "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" | "structFieldDisplayNode" | "constantDiscriminatorNode" | "fieldDiscriminatorNode" | "sizeDiscriminatorNode" | "instructionAccountDisplayNode" | "instructionStatusNode" | "accountNode" | "constantNode" | "definedTypeNode" | "errorNode" | "eventNode" | "instructionAccountNode" | "instructionArgumentNode" | "instructionByteDeltaNode" | "instructionNode" | "instructionRemainingAccountsNode" | "pdaNode" | "pluginNode" | "programNode" | "providedNode" | "pdaSeedValueNode" | "fixedCountNode" | "prefixedCountNode" | "remainderCountNode" | "amountNumberDisplayNode" | "dateTimeNumberDisplayNode" | "durationNumberDisplayNode" | "enumVariantDisplayNode" | "instructionDisplayNode" | "stringDisplayNode" | "accountLinkNode" | "definedTypeLinkNode" | "instructionAccountLinkNode" | "instructionArgumentLinkNode" | "instructionLinkNode" | "pdaLinkNode" | "constantPdaSeedNode" | "variablePdaSeedNode" | "enumEmptyVariantTypeNode" | "enumStructVariantTypeNode" | "enumTupleVariantTypeNode" | "structFieldTypeNode" | "mapEntryValueNode" | "structFieldValueNode" | "rootNode">;
19
+ linkOverrides?: Record<string, LinkOverride>;
20
+ }): Visitor<TypeManifest, "accountBumpValueNode" | "accountFieldValueNode" | "accountLinkNode" | "accountNode" | "accountValueNode" | "amountNumberDisplayNode" | "amountTypeNode" | "argumentValueNode" | "arrayTypeNode" | "arrayValueNode" | "booleanTypeNode" | "booleanValueNode" | "bytesTypeNode" | "bytesValueNode" | "conditionalValueNode" | "constantDiscriminatorNode" | "constantNode" | "constantPdaSeedNode" | "constantValueNode" | "dateTimeNumberDisplayNode" | "dateTimeTypeNode" | "definedTypeLinkNode" | "definedTypeNode" | "durationNumberDisplayNode" | "enumEmptyVariantTypeNode" | "enumStructVariantTypeNode" | "enumTupleVariantTypeNode" | "enumTypeNode" | "enumValueNode" | "enumVariantDisplayNode" | "errorNode" | "eventNode" | "fieldDiscriminatorNode" | "fixedCountNode" | "fixedSizeTypeNode" | "hiddenPrefixTypeNode" | "hiddenSuffixTypeNode" | "identityValueNode" | "injectedValueNode" | "instructionAccountDisplayNode" | "instructionAccountLinkNode" | "instructionAccountNode" | "instructionArgumentLinkNode" | "instructionArgumentNode" | "instructionByteDeltaNode" | "instructionDisplayNode" | "instructionLinkNode" | "instructionNode" | "instructionRemainingAccountsNode" | "instructionStatusNode" | "mapEntryValueNode" | "mapTypeNode" | "mapValueNode" | "noneValueNode" | "numberTypeNode" | "numberValueNode" | "optionTypeNode" | "payerValueNode" | "pdaLinkNode" | "pdaNode" | "pdaSeedValueNode" | "pdaValueNode" | "pluginNode" | "postOffsetTypeNode" | "preOffsetTypeNode" | "prefixedCountNode" | "programIdValueNode" | "programLinkNode" | "programNode" | "providedNode" | "publicKeyTypeNode" | "publicKeyValueNode" | "remainderCountNode" | "remainderOptionTypeNode" | "resolverValueNode" | "rootNode" | "sentinelTypeNode" | "setTypeNode" | "setValueNode" | "sizeDiscriminatorNode" | "sizePrefixTypeNode" | "solAmountTypeNode" | "someValueNode" | "stringDisplayNode" | "stringTypeNode" | "stringValueNode" | "structFieldDisplayNode" | "structFieldTypeNode" | "structFieldValueNode" | "structTypeNode" | "structValueNode" | "tupleTypeNode" | "tupleValueNode" | "variablePdaSeedNode" | "zeroableOptionTypeNode">;
19
21
  //# 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,EAgCrB,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;AAG3E;;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,8kEA8mBA"}
1
+ {"version":3,"file":"getTypeManifestVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/getTypeManifestVisitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EAgCrB,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;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;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;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C,8kEAooBA"}
@@ -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;AAMzD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,6DAmE5B"}
1
+ {"version":3,"file":"renderVisitor.d.ts","sourceRoot":"","sources":["../../../src/visitors/renderVisitor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AAMvE;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,aAAkB,6DA2E5B"}
package/package.json CHANGED
@@ -9,12 +9,12 @@
9
9
  "devDependencies": {
10
10
  "@codama/nodes-from-anchor": "^1.5.5",
11
11
  "@codama/renderers-js": "^2.4.0",
12
- "@types/node": "25.3.0",
13
- "@vitest/coverage-v8": "4.1.0",
12
+ "@types/node": "26.5.1",
13
+ "@vitest/coverage-v8": "5.0.0",
14
14
  "rimraf": "6.1.3",
15
15
  "tsup": "8.5.1",
16
- "typescript": "5.9.3",
17
- "vitest": "4.1.0"
16
+ "typescript": "7.0.2",
17
+ "vitest": "5.0.0"
18
18
  },
19
19
  "engines": {
20
20
  "node": ">=18"
@@ -53,6 +53,9 @@
53
53
  "access": "public"
54
54
  },
55
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.6",
56
59
  "scripts": {
57
60
  "build": "pnpm exec rimraf dist && pnpm exec tsup && pnpm exec tsc -p tsconfig.declarations.json",
58
61
  "lint": "eslint --ext .ts src",
@@ -60,8 +63,5 @@
60
63
  "test:coverage": "pnpm exec vitest run --coverage.enabled --coverage.reporter=lcov",
61
64
  "test:watch": "pnpm exec vitest",
62
65
  "typecheck": "pnpm exec tsc --noEmit"
63
- },
64
- "type": "module",
65
- "types": "./dist/types/index.d.ts",
66
- "version": "0.5.5"
67
- }
66
+ }
67
+ }
@@ -67,7 +67,14 @@ export function getDiscriminatorValidationFragment(
67
67
  `Discriminator size must be a non-negative safe integer, got ${discriminator.size}.`,
68
68
  );
69
69
  }
70
- return fragment`if (bytes.length - offset != ${fragmentFromString(String(discriminator.size))}) {
70
+ // For an instruction, the discriminated size is the whole payload and
71
+ // identification depends on an exact match. For an account, the size
72
+ // describes the fixed prefix: accounts whose trailing fields are
73
+ // variable — a Token-2022 account with a TLV extension region, for
74
+ // example — are legitimately longer, so the check is a minimum.
75
+ const comparison =
76
+ node.kind === "accountNode" ? "<" : "!=";
77
+ return fragment`if (bytes.length - offset ${fragmentFromString(comparison)} ${fragmentFromString(String(discriminator.size))}) {
71
78
  throw ${use("SolanaError", "solanaErrors")}(
72
79
  ${use("SolanaErrorCode", "solanaErrors")}.codecsInvalidByteLength,
73
80
  {
@@ -5,6 +5,29 @@ import type {
5
5
  import type { DartNameApi } from "./nameTransformers.js";
6
6
  import type { TypeManifestVisitor } from "../visitors/getTypeManifestVisitor.js";
7
7
 
8
+ /**
9
+ * A hand-written codec that backs a defined-type link in the rendered IDL.
10
+ *
11
+ * Some IDL fields cannot be expressed with Codama type nodes and need a
12
+ * hand-written codec instead — for example, the Token-2022 TLV extension
13
+ * region, which stops at the first `Uninitialized` header rather than
14
+ * consuming every trailing byte. Codama has no "stop at a discriminator" type
15
+ * node, so the IDL is prepared to link the inner type to a name and the
16
+ * renderer is told which hand-written codec backs that link. Wrappers around
17
+ * the link (`Option`, `HiddenPrefix`, …) still come from the IDL, so the wire
18
+ * format is unchanged.
19
+ */
20
+ export interface LinkOverride {
21
+ /** The Dart file the codec lives in, relative to the package's `lib/`. */
22
+ path: string;
23
+ /** The Dart type the link resolves to, e.g. `List<Extension>`. */
24
+ type: string;
25
+ /** The encoder expression, e.g. `getExtensionsEncoder()`. */
26
+ encoder: string;
27
+ /** The decoder expression, e.g. `getExtensionsDecoder()`. */
28
+ decoder: string;
29
+ }
30
+
8
31
  /**
9
32
  * Options for the top-level renderVisitor.
10
33
  */
@@ -27,6 +50,13 @@ export interface GetRenderMapOptions {
27
50
  nameApi?: Partial<DartNameApi>;
28
51
  /** Dependency map overrides (logical module -> Dart package URI). */
29
52
  dependencyMap?: Record<string, string>;
53
+ /**
54
+ * Hand-written codec overrides for defined-type links, keyed by the link
55
+ * name as it appears in Codama nodes. A link with a matching key emits the
56
+ * override's type and codec expressions instead of resolving to a generated
57
+ * type file, and imports the override's Dart file.
58
+ */
59
+ linkOverrides?: Record<string, LinkOverride>;
30
60
  }
31
61
 
32
62
  /**
@@ -46,7 +46,8 @@ export const WELL_KNOWN_ADDRESSES: ReadonlyMap<string, string> = new Map([
46
46
  ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', 'tokenProgramAddress'],
47
47
  ['TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb', 'token2022ProgramAddress'],
48
48
  ['ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL', 'associatedTokenProgramAddress'],
49
- ['MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr', 'memoProgramAddress'],
49
+ ['Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH', 'memoProgramAddress'],
50
+ ['MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr', 'memoLegacyProgramAddressV3'],
50
51
  ['Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo', 'memoLegacyProgramAddress'],
51
52
 
52
53
  // Metaplex programs
@@ -57,6 +57,7 @@ export function getRenderMapVisitor(
57
57
  nameApi,
58
58
  linkables,
59
59
  stack,
60
+ linkOverrides: options.linkOverrides,
60
61
  });
61
62
 
62
63
  const scope: RenderScope = {
@@ -57,6 +57,7 @@ import {
57
57
  use,
58
58
  } from "../utils/index.js";
59
59
  import { type DartNameApi, snakeCase } from "../utils/nameTransformers.js";
60
+ import type { LinkOverride } from "../utils/options.js";
60
61
  import { getDartValueFragment, getNonNegativeInteger, toDartStringLiteral } from "../utils/valueNodes.js";
61
62
 
62
63
  /**
@@ -73,8 +74,14 @@ export function getTypeManifestVisitor(input: {
73
74
  linkables: LinkableDictionary;
74
75
  stack: NodeStack;
75
76
  nonScalarEnums?: CamelCaseString[];
77
+ linkOverrides?: Record<string, LinkOverride>;
76
78
  }) {
77
- const { nameApi, linkables, nonScalarEnums = [] } = input;
79
+ const {
80
+ nameApi,
81
+ linkables,
82
+ nonScalarEnums = [],
83
+ linkOverrides = {},
84
+ } = input;
78
85
 
79
86
  const baseVisitor = staticVisitor<TypeManifest>(
80
87
  (node): TypeManifest => {
@@ -670,6 +677,23 @@ export function getTypeManifestVisitor(input: {
670
677
  { self }: { self: Visitor<TypeManifest> },
671
678
  ) {
672
679
  const name = node.name as string;
680
+
681
+ // A link may be backed by a hand-written codec. This keeps whatever
682
+ // wrappers the IDL puts around the link (`Option`, `HiddenPrefix`, …)
683
+ // while replacing the inner type and codecs, which is what a type that
684
+ // Codama cannot express needs.
685
+ const override = linkOverrides[name];
686
+ if (override != null) {
687
+ const moduleKey = `linkOverride:${override.path}`;
688
+ return {
689
+ type: use(override.type, moduleKey),
690
+ encoder: use(override.encoder, moduleKey),
691
+ decoder: use(override.decoder, moduleKey),
692
+ value: emptyTypeManifest().value,
693
+ isEnum: false,
694
+ };
695
+ }
696
+
673
697
  const typeName = nameApi.dataType(name);
674
698
  const isNonScalar = nonScalarEnums.includes(node.name);
675
699
  const moduleKey = `definedType:${snakeCase(name)}`;
@@ -6,7 +6,7 @@ import { rootNodeVisitor, visit } from "@codama/visitors-core";
6
6
  import { deleteDirectory, writeRenderMap } from "@codama/renderers-core";
7
7
 
8
8
  import type { Fragment } from "../utils/fragment.js";
9
- import type { RenderOptions } from "../utils/options.js";
9
+ import type { RenderOptions, LinkOverride } from "../utils/options.js";
10
10
  import { DartImportMap, DART_EXTERNAL_PACKAGE_MAP } from "../utils/importMap.js";
11
11
  import { formatDartDirectory } from "../utils/formatCode.js";
12
12
  import { normalizeRootNode } from "../utils/normalizeRootNode.js";
@@ -27,6 +27,7 @@ export function renderVisitor(
27
27
  formatCode = false,
28
28
  nameApi,
29
29
  dependencyMap,
30
+ linkOverrides,
30
31
  } = options;
31
32
 
32
33
  return rootNodeVisitor((root: RootNode) => {
@@ -35,7 +36,7 @@ export function renderVisitor(
35
36
  // 2. Build the render map
36
37
  const renderMap = visit(
37
38
  normalizedRoot,
38
- getRenderMapVisitor({ nameApi, dependencyMap }),
39
+ getRenderMapVisitor({ nameApi, dependencyMap, linkOverrides }),
39
40
  );
40
41
 
41
42
  // 3. Build a map of definedType module keys to their render map paths
@@ -69,7 +70,14 @@ export function renderVisitor(
69
70
  }
70
71
 
71
72
  // Resolve fragment content with imports
72
- const content = resolveFragmentContent(frag, dependencyMap ?? {}, internalMap);
73
+ const content = resolveFragmentContent(
74
+ frag,
75
+ {
76
+ ...(dependencyMap ?? {}),
77
+ ...linkOverrideImports(outputDir, filePath, options.linkOverrides ?? {}),
78
+ },
79
+ internalMap,
80
+ );
73
81
  files.push([fullPath, content]);
74
82
  }
75
83
 
@@ -89,6 +97,62 @@ export function renderVisitor(
89
97
  });
90
98
  }
91
99
 
100
+ /**
101
+ * Resolve `linkOverride:` logical import keys into relative Dart imports.
102
+ *
103
+ * Override paths are relative to the package's `lib/` directory, while
104
+ * generated files live under `lib/src/generated/...`, so each consuming file
105
+ * needs its own relative path. Both sides are resolved against the package's
106
+ * `lib/` root, which is located by walking up from the output directory.
107
+ */
108
+ function linkOverrideImports(
109
+ outputDir: string,
110
+ generatedFilePath: string,
111
+ overrides: Record<string, LinkOverride>,
112
+ ): Record<string, string> {
113
+ const resolved: Record<string, string> = {};
114
+ if (Object.keys(overrides).length === 0) return resolved;
115
+
116
+ // Override paths are resolved against the package's `lib/` directory, so
117
+ // without one there is nothing to anchor them to. Failing loudly beats
118
+ // emitting an import that cannot resolve.
119
+ const libRoot = findLibRoot(outputDir);
120
+ if (libRoot == null) {
121
+ throw new Error(
122
+ `Cannot resolve linkOverrides because the render output directory ` +
123
+ `"${outputDir}" has no "lib" ancestor.`,
124
+ );
125
+ }
126
+
127
+ const generatedAbsolute = posix.join(
128
+ posix.resolve(outputDir),
129
+ generatedFilePath,
130
+ );
131
+
132
+ for (const override of Object.values(overrides)) {
133
+ const overrideAbsolute = posix.join(libRoot, override.path);
134
+ let rel = posix.relative(posix.dirname(generatedAbsolute), overrideAbsolute);
135
+ if (!rel.startsWith(".")) {
136
+ rel = `./${rel}`;
137
+ }
138
+ resolved[`linkOverride:${override.path}`] = rel;
139
+ }
140
+
141
+ return resolved;
142
+ }
143
+
144
+ /**
145
+ * Find the package `lib/` directory containing the render output, so relative
146
+ * imports can point outside the generated tree. Returns null when the output
147
+ * directory has no `lib` ancestor, in which case overrides cannot be linked.
148
+ */
149
+ function findLibRoot(outputDir: string): string | null {
150
+ const segments = posix.resolve(outputDir).split("/");
151
+ const libIndex = segments.lastIndexOf("lib");
152
+ if (libIndex < 0) return null;
153
+ return segments.slice(0, libIndex + 1).join("/");
154
+ }
155
+
92
156
  /**
93
157
  * Resolve a fragment into its final Dart file content,
94
158
  * prepending the resolved import statements.