diff --git a/.changeset/plugins-on-every-node.md b/.changeset/plugins-on-every-node.md new file mode 100644 index 0000000..ed65445 --- /dev/null +++ b/.changeset/plugins-on-every-node.md @@ -0,0 +1,5 @@ +--- +'@codama/spec': major +--- + +Give every node a `plugins` list via a new base-attribute mechanism. The meta-model's `Spec` type gains an optional `base` block (authored with the new `defineBase` helper) declaring attributes shared by every node; codegen targets append them after each node's declared attributes, so they always serialise last. The spec declares one base attribute — `plugins`, an optional array of `pluginNode` — making every node extensible with namespaced, consumer-defined data. `instructionNode` no longer declares `plugins` locally (the universal base attribute replaces it), and `validate` rejects base attributes that collide with declared attributes or carry unresolved references. diff --git a/README.md b/README.md index ea3379c..82f6bb6 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,14 @@ Each node declares its attributes as an ordered array in `defineNode(...)`, and Preserving declaration order keeps encoded IDLs readable: the identifying scalars of a node (`kind`, `name`, …) appear before its potentially large children, so a node's identity is legible at a glance even in a deeply nested IDL. +### Base attributes serialise last + +The spec may declare **base attributes** (`Spec.base`): attributes shared by every node, declared once via `defineBase(...)` instead of repeated on each node. The current spec declares one — `plugins`, an optional array of `pluginNode`, making every node extensible with namespaced, consumer-defined data. + +- **Codegen targets append base attributes after each node's declared attributes**, so they always serialise last (after the implicit `kind` discriminator and the declared attributes). They may also emit a shared `BaseNode` interface that every generated node type extends. +- Base attribute names never collide with declared attributes — `validate` rejects such specs. +- The array conventions above apply unchanged: an absent `plugins` array means "no plugins". + ## Repository layout ``` diff --git a/docs/AccountNode.md b/docs/AccountNode.md index 752e91f..4ff9ca7 100644 --- a/docs/AccountNode.md +++ b/docs/AccountNode.md @@ -22,6 +22,7 @@ An on-chain account: its name, data structure, optional fixed size, optional PDA | `data` | [`NestedTypeNode`](./typeNodes/NestedTypeNode.md)<[`StructTypeNode`](./typeNodes/StructTypeNode.md)> | The struct describing the account data. It must be a struct so its fields can be referenced by other nodes — e.g. `accountFieldValueNode`. | | `pda` | [`PdaLinkNode`](./linkNodes/PdaLinkNode.md) _(optional)_ | A link to the PDA the account is derived from, if applicable. | | `discriminators` | [`DiscriminatorNode`](./discriminatorNodes/DiscriminatorNode.md)[] _(optional)_ | Discriminators that distinguish this account from others in the program. When multiple are listed, they are combined with a logical AND. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/ConstantNode.md b/docs/ConstantNode.md index d050790..e805cad 100644 --- a/docs/ConstantNode.md +++ b/docs/ConstantNode.md @@ -14,10 +14,11 @@ A named constant exposed by the program: a typed value associated with a name. ### Children -| Attribute | Type | Description | -| --------- | ---------------------------------------- | ----------------------------------- | -| `type` | [`TypeNode`](./typeNodes/TypeNode.md) | The type of the constant. | -| `value` | [`ValueNode`](./valueNodes/ValueNode.md) | The concrete value of the constant. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./typeNodes/TypeNode.md) | The type of the constant. | +| `value` | [`ValueNode`](./valueNodes/ValueNode.md) | The concrete value of the constant. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/DefinedTypeNode.md b/docs/DefinedTypeNode.md index 9c85a24..aa1a1b1 100644 --- a/docs/DefinedTypeNode.md +++ b/docs/DefinedTypeNode.md @@ -16,9 +16,10 @@ A reusable named type that can be referenced by `definedTypeLinkNode` from elsew ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------- | -------------------- | -| `type` | [`TypeNode`](./typeNodes/TypeNode.md) | The type definition. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./typeNodes/TypeNode.md) | The type definition. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/ErrorNode.md b/docs/ErrorNode.md index 6ff9ce6..e7e91d5 100644 --- a/docs/ErrorNode.md +++ b/docs/ErrorNode.md @@ -16,6 +16,12 @@ A program error — a numeric code paired with a name and human-readable message | `message` | `string` | A human-readable description of the error. | | `docs` | `string[]` _(optional)_ | Markdown documentation for the error. | +### Children + +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an error node from an input object diff --git a/docs/EventNode.md b/docs/EventNode.md index 78fd71c..2467093 100644 --- a/docs/EventNode.md +++ b/docs/EventNode.md @@ -14,10 +14,11 @@ A program event: its data shape and optional discriminators used to identify it ### Children -| Attribute | Type | Description | -| ---------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| `data` | [`TypeNode`](./typeNodes/TypeNode.md) | The type describing the event payload. | -| `discriminators` | [`DiscriminatorNode`](./discriminatorNodes/DiscriminatorNode.md)[] _(optional)_ | Discriminators that distinguish this event from others. When multiple are listed, they are combined with a logical AND. | +| Attribute | Type | Description | +| ---------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `data` | [`TypeNode`](./typeNodes/TypeNode.md) | The type describing the event payload. | +| `discriminators` | [`DiscriminatorNode`](./discriminatorNodes/DiscriminatorNode.md)[] _(optional)_ | Discriminators that distinguish this event from others. When multiple are listed, they are combined with a logical AND. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionAccountNode.md b/docs/InstructionAccountNode.md index 48e7cb6..ed6508c 100644 --- a/docs/InstructionAccountNode.md +++ b/docs/InstructionAccountNode.md @@ -24,6 +24,7 @@ An account participating in an instruction, with its name, signing/writability f | `defaultValue` | [`InstructionInputValueNode`](./contextualValueNodes/InstructionInputValueNode.md) _(optional)_ | A default value used to fill the slot when the caller does not provide one. | | `accountLink` | [`AccountLinkNode`](./linkNodes/AccountLinkNode.md) _(optional)_ | A reference to the account's data layout. Required for consumers (e.g. `accountFieldValueNode`) to read fields from the account. The link's optional `program` allows cross-program references via the root's `additionalPrograms`. | | `display` | [`InstructionAccountDisplayNode`](./displayNodes/InstructionAccountDisplayNode.md) _(optional)_ | Display metadata describing how the account is presented. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionArgumentNode.md b/docs/InstructionArgumentNode.md index 179d740..5e3ba11 100644 --- a/docs/InstructionArgumentNode.md +++ b/docs/InstructionArgumentNode.md @@ -23,6 +23,7 @@ Serialised next to each other, the arguments of an instruction form its data. | `type` | [`TypeNode`](./typeNodes/TypeNode.md) | The type of the argument. | | `defaultValue` | [`InstructionInputValueNode`](./contextualValueNodes/InstructionInputValueNode.md) _(optional)_ | A default value used when the argument is omitted by callers. | | `display` | [`StructFieldDisplayNode`](./displayNodes/StructFieldDisplayNode.md) _(optional)_ | Display metadata describing how the argument is presented. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionByteDeltaNode.md b/docs/InstructionByteDeltaNode.md index 6d5ee19..633a6a0 100644 --- a/docs/InstructionByteDeltaNode.md +++ b/docs/InstructionByteDeltaNode.md @@ -15,9 +15,10 @@ For instance, if an instruction creates a new account of 42 bytes, this node can ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| `value` | [`InstructionByteDeltaValue`](./InstructionByteDeltaValue.md) | The source of the delta value — a literal number, a referenced account or argument, or a resolver. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | [`InstructionByteDeltaValue`](./InstructionByteDeltaValue.md) | The source of the delta value — a literal number, a referenced account or argument, or a resolver. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionNode.md b/docs/InstructionNode.md index 903b1cd..dbb7325 100644 --- a/docs/InstructionNode.md +++ b/docs/InstructionNode.md @@ -29,7 +29,7 @@ A program instruction: its accounts, arguments, byte-delta hints, discriminators | `subInstructions` | [`InstructionNode`](./InstructionNode.md)[] _(optional)_ | Nested instructions that split this instruction into distinct scenarios — e.g. one sub-instruction per version of the instruction. | | `provides` | [`ProvidedNode`](./ProvidedNode.md)[] _(optional)_ | Named nodes exposed to consumers in the surrounding scope. Each entry pairs with an `injectedValueNode` that references it by key, so reusable types can pull contextual values without naming siblings directly. | | `display` | [`InstructionDisplayNode`](./displayNodes/InstructionDisplayNode.md) _(optional)_ | Display metadata describing how the instruction is presented. | -| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionRemainingAccountsNode.md b/docs/InstructionRemainingAccountsNode.md index 1b1b45a..ac7460d 100644 --- a/docs/InstructionRemainingAccountsNode.md +++ b/docs/InstructionRemainingAccountsNode.md @@ -16,10 +16,11 @@ A "remaining accounts" slot in an instruction — a variable-length tail of acco ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `value` | [`InstructionRemainingAccountsValue`](./InstructionRemainingAccountsValue.md) | The source of the remaining-accounts list — a referenced argument or a resolver. | -| `display` | [`InstructionAccountDisplayNode`](./displayNodes/InstructionAccountDisplayNode.md) _(optional)_ | Display metadata describing how the remaining-accounts group is presented as a whole. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | [`InstructionRemainingAccountsValue`](./InstructionRemainingAccountsValue.md) | The source of the remaining-accounts list — a referenced argument or a resolver. | +| `display` | [`InstructionAccountDisplayNode`](./displayNodes/InstructionAccountDisplayNode.md) _(optional)_ | Display metadata describing how the remaining-accounts group is presented as a whole. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/InstructionStatusNode.md b/docs/InstructionStatusNode.md index 8ef7841..a050db6 100644 --- a/docs/InstructionStatusNode.md +++ b/docs/InstructionStatusNode.md @@ -14,9 +14,10 @@ An instruction without a status is considered live — a status node is typicall ### Children -| Attribute | Type | Description | -| ----------- | --------------------------------------------------------------- | -------------------- | -| `lifecycle` | [`InstructionLifecycle`](./sharedNodes/InstructionLifecycle.md) | The lifecycle stage. | +| Attribute | Type | Description | +| ----------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `lifecycle` | [`InstructionLifecycle`](./sharedNodes/InstructionLifecycle.md) | The lifecycle stage. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/PdaNode.md b/docs/PdaNode.md index 5cb9377..b171972 100644 --- a/docs/PdaNode.md +++ b/docs/PdaNode.md @@ -17,9 +17,10 @@ A program-derived address: its name, optional program ID override, and the seeds ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------ | ------------------------------------------- | -| `seeds` | [`PdaSeedNode`](./pdaSeedNodes/PdaSeedNode.md)[] | The seeds used to derive the PDA, in order. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `seeds` | [`PdaSeedNode`](./pdaSeedNodes/PdaSeedNode.md)[] | The seeds used to derive the PDA, in order. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/PluginNode.md b/docs/PluginNode.md index 8a337bb..989e37e 100644 --- a/docs/PluginNode.md +++ b/docs/PluginNode.md @@ -2,6 +2,7 @@ Attaches named, plugin-specific data to a node. A plugin is uniquely identified by its `name`; the optional `payload` carries arbitrary, consumer-defined data that only the matching plugin knows how to interpret. Codama itself treats the payload as opaque. +Every node can carry plugins via the `plugins` base attribute. ## Attributes @@ -13,6 +14,12 @@ A plugin is uniquely identified by its `name`; the optional `payload` carries ar | `name` | `CamelCaseString` | The unique name identifying the plugin this data belongs to. | | `payload` | `Json` _(optional)_ | Arbitrary, plugin-specific data. Its shape is defined by the plugin, not by Codama, and is carried through the graph verbatim. | +### Children + +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### A plugin carrying custom structured data diff --git a/docs/ProgramNode.md b/docs/ProgramNode.md index 35f56f0..9676796 100644 --- a/docs/ProgramNode.md +++ b/docs/ProgramNode.md @@ -18,16 +18,17 @@ A Solana program: its identity, version, accounts, instructions, defined types, ### Children -| Attribute | Type | Description | -| -------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------- | -| `origin` | [`ProgramOrigin`](./sharedNodes/ProgramOrigin.md) _(optional)_ | The toolchain that originally generated the program description, if known. | -| `accounts` | [`AccountNode`](./AccountNode.md)[] | The accounts owned by the program. | -| `instructions` | [`InstructionNode`](./InstructionNode.md)[] | The instructions exposed by the program. | -| `definedTypes` | [`DefinedTypeNode`](./DefinedTypeNode.md)[] | The reusable types defined by the program. | -| `pdas` | [`PdaNode`](./PdaNode.md)[] | The PDAs derived by the program. | -| `events` | [`EventNode`](./EventNode.md)[] | The events emitted by the program. | -| `errors` | [`ErrorNode`](./ErrorNode.md)[] | The errors returned by the program. | -| `constants` | [`ConstantNode`](./ConstantNode.md)[] | The constants exposed by the program. | +| Attribute | Type | Description | +| -------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `origin` | [`ProgramOrigin`](./sharedNodes/ProgramOrigin.md) _(optional)_ | The toolchain that originally generated the program description, if known. | +| `accounts` | [`AccountNode`](./AccountNode.md)[] | The accounts owned by the program. | +| `instructions` | [`InstructionNode`](./InstructionNode.md)[] | The instructions exposed by the program. | +| `definedTypes` | [`DefinedTypeNode`](./DefinedTypeNode.md)[] | The reusable types defined by the program. | +| `pdas` | [`PdaNode`](./PdaNode.md)[] | The PDAs derived by the program. | +| `events` | [`EventNode`](./EventNode.md)[] | The events emitted by the program. | +| `errors` | [`ErrorNode`](./ErrorNode.md)[] | The errors returned by the program. | +| `constants` | [`ConstantNode`](./ConstantNode.md)[] | The constants exposed by the program. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/ProvidedNode.md b/docs/ProvidedNode.md index 91ca004..c42b321 100644 --- a/docs/ProvidedNode.md +++ b/docs/ProvidedNode.md @@ -14,9 +14,10 @@ Sits inside a host's `provides` list and pairs with `injectedValueNode` on the c ### Children -| Attribute | Type | Description | -| --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `node` | `anyNode` | The exposed node. The provider is a transparent pipe — any node may be supplied; the family check happens at the injection point against the consumer's expected family. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `node` | `anyNode` | The exposed node. The provider is a transparent pipe — any node may be supplied; the family check happens at the injection point against the consumer's expected family. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/README.md b/docs/README.md index dcfa81a..b996ac4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,15 @@ Spec version: 1.9.2 · Other majors: [v1](https://github.com/codama-idl/spec/blo Pages marked _(abstract)_ document unions: sets of nodes that can be used interchangeably. Pages marked _(recursive)_ document nested unions: wrapper nodes that may nest before reaching a base type. +## Base attributes + +Attributes shared by every node. +Codegen targets append them after each node's declared attributes, so they always serialise last. + +| Attribute | Type | Description | +| --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Categories - [ContextualValue](./contextualValueNodes/README.md) - Contextual-value nodes — references resolved at instruction-build time (account values, argument values, …). diff --git a/docs/RootNode.md b/docs/RootNode.md index 28de42f..ef6cdfb 100644 --- a/docs/RootNode.md +++ b/docs/RootNode.md @@ -17,10 +17,11 @@ Pairs a primary program with any number of additional programs and tags the IDL ### Children -| Attribute | Type | Description | -| -------------------- | ----------------------------------- | ------------------------------------------------------ | -| `program` | [`ProgramNode`](./ProgramNode.md) | The primary program described by the IDL. | -| `additionalPrograms` | [`ProgramNode`](./ProgramNode.md)[] | Additional programs referenced by the primary program. | +| Attribute | Type | Description | +| -------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `program` | [`ProgramNode`](./ProgramNode.md) | The primary program described by the IDL. | +| `additionalPrograms` | [`ProgramNode`](./ProgramNode.md)[] | Additional programs referenced by the primary program. | +| `plugins` | [`PluginNode`](./PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/contextualValueNodes/AccountBumpValueNode.md b/docs/contextualValueNodes/AccountBumpValueNode.md index e452bd3..e248dfe 100644 --- a/docs/contextualValueNodes/AccountBumpValueNode.md +++ b/docs/contextualValueNodes/AccountBumpValueNode.md @@ -11,6 +11,12 @@ Refers to the bump seed of a named PDA-derived account in the surrounding instru | `kind` | `"accountBumpValueNode"` | The node discriminator. | | `name` | `CamelCaseString` | The name of the account whose bump seed is referenced. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an account bump value node from an account name diff --git a/docs/contextualValueNodes/AccountFieldValueNode.md b/docs/contextualValueNodes/AccountFieldValueNode.md index 6355f8e..04c38ae 100644 --- a/docs/contextualValueNodes/AccountFieldValueNode.md +++ b/docs/contextualValueNodes/AccountFieldValueNode.md @@ -14,6 +14,12 @@ Resolving the value requires reading the account state at presentation time. | `account` | `CamelCaseString` | The name of the referenced account in the surrounding instruction. | | `path` | `CamelCaseString` _(optional)_ | The name of the field within the account's decoded data. When absent, the value is the whole decoded account data. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an account field value node from an account name and a field path diff --git a/docs/contextualValueNodes/AccountValueNode.md b/docs/contextualValueNodes/AccountValueNode.md index f86cba4..d780e56 100644 --- a/docs/contextualValueNodes/AccountValueNode.md +++ b/docs/contextualValueNodes/AccountValueNode.md @@ -11,6 +11,12 @@ Refers to a named account in the surrounding instruction. | `kind` | `"accountValueNode"` | The node discriminator. | | `name` | `CamelCaseString` | The name of the referenced account. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an account value node from an account name diff --git a/docs/contextualValueNodes/ArgumentValueNode.md b/docs/contextualValueNodes/ArgumentValueNode.md index df1f18a..d8bae0c 100644 --- a/docs/contextualValueNodes/ArgumentValueNode.md +++ b/docs/contextualValueNodes/ArgumentValueNode.md @@ -11,6 +11,12 @@ Refers to a named argument of the surrounding instruction. | `kind` | `"argumentValueNode"` | The node discriminator. | | `name` | `CamelCaseString` | The name of the referenced argument. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an argument value node from an argument name diff --git a/docs/contextualValueNodes/ConditionalValueNode.md b/docs/contextualValueNodes/ConditionalValueNode.md index cc0048b..d91fd8e 100644 --- a/docs/contextualValueNodes/ConditionalValueNode.md +++ b/docs/contextualValueNodes/ConditionalValueNode.md @@ -19,6 +19,7 @@ The condition resolves to a value at instruction time; that result selects betwe | `value` | [`ValueNode`](../valueNodes/ValueNode.md) _(optional)_ | When present, the condition result is compared for equality against this value. When omitted, the condition passes if the referenced account or argument exists in the current context, regardless of its value. | | `ifTrue` | [`InstructionInputValueNode`](./InstructionInputValueNode.md) _(optional)_ | The value used when the condition passes — i.e. it matches `value` or, without a `value`, exists. | | `ifFalse` | [`InstructionInputValueNode`](./InstructionInputValueNode.md) _(optional)_ | The value used when the condition fails — i.e. it does not match `value` or, without a `value`, does not exist. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/contextualValueNodes/IdentityValueNode.md b/docs/contextualValueNodes/IdentityValueNode.md index 90692f7..744a9e1 100644 --- a/docs/contextualValueNodes/IdentityValueNode.md +++ b/docs/contextualValueNodes/IdentityValueNode.md @@ -12,6 +12,12 @@ A similar node exists for the main wallet that should pay for things — `payerV | --------- | --------------------- | ----------------------- | | `kind` | `"identityValueNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create an identity value node diff --git a/docs/contextualValueNodes/PayerValueNode.md b/docs/contextualValueNodes/PayerValueNode.md index 23b092f..90dac5a 100644 --- a/docs/contextualValueNodes/PayerValueNode.md +++ b/docs/contextualValueNodes/PayerValueNode.md @@ -12,6 +12,12 @@ A similar node exists for the main wallet that should own things — `identityVa | --------- | ------------------ | ----------------------- | | `kind` | `"payerValueNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a payer value node diff --git a/docs/contextualValueNodes/PdaSeedValueNode.md b/docs/contextualValueNodes/PdaSeedValueNode.md index 92e2404..d7b08c2 100644 --- a/docs/contextualValueNodes/PdaSeedValueNode.md +++ b/docs/contextualValueNodes/PdaSeedValueNode.md @@ -13,9 +13,10 @@ Pairs a PDA seed name with the value to substitute when deriving the PDA. ### Children -| Attribute | Type | Description | -| --------- | --------------------------------------------- | ------------------------------------- | -| `value` | [`PdaSeedValueValue`](./PdaSeedValueValue.md) | The value to substitute for the seed. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | [`PdaSeedValueValue`](./PdaSeedValueValue.md) | The value to substitute for the seed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/contextualValueNodes/PdaValueNode.md b/docs/contextualValueNodes/PdaValueNode.md index 960a9a5..c9d9867 100644 --- a/docs/contextualValueNodes/PdaValueNode.md +++ b/docs/contextualValueNodes/PdaValueNode.md @@ -12,11 +12,12 @@ Resolves to a PDA derived from a list of seed values. ### Children -| Attribute | Type | Description | -| ----------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `pda` | [`PdaValuePda`](./PdaValuePda.md) | The PDA being derived — either a link to a defined PDA or an inline `pdaNode`. | -| `seeds` | [`PdaSeedValueNode`](./PdaSeedValueNode.md)[] | The seed values used to derive the PDA, paired with their seed names. | -| `programId` | [`PdaValueProgramId`](./PdaValueProgramId.md) _(optional)_ | The program ID used to derive the PDA. When omitted, the PDA’s declared program is used. | +| Attribute | Type | Description | +| ----------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `pda` | [`PdaValuePda`](./PdaValuePda.md) | The PDA being derived — either a link to a defined PDA or an inline `pdaNode`. | +| `seeds` | [`PdaSeedValueNode`](./PdaSeedValueNode.md)[] | The seed values used to derive the PDA, paired with their seed names. | +| `programId` | [`PdaValueProgramId`](./PdaValueProgramId.md) _(optional)_ | The program ID used to derive the PDA. When omitted, the PDA’s declared program is used. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/contextualValueNodes/ProgramIdValueNode.md b/docs/contextualValueNodes/ProgramIdValueNode.md index b1a2b7f..63a6a5b 100644 --- a/docs/contextualValueNodes/ProgramIdValueNode.md +++ b/docs/contextualValueNodes/ProgramIdValueNode.md @@ -10,6 +10,12 @@ Refers to the program ID of the surrounding instruction — that is, the address | --------- | ---------------------- | ----------------------- | | `kind` | `"programIdValueNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a program id value node diff --git a/docs/contextualValueNodes/ResolverValueNode.md b/docs/contextualValueNodes/ResolverValueNode.md index a18f5d4..a87f690 100644 --- a/docs/contextualValueNodes/ResolverValueNode.md +++ b/docs/contextualValueNodes/ResolverValueNode.md @@ -16,9 +16,10 @@ This node acts as a fallback for any value or logic that cannot easily be descri ### Children -| Attribute | Type | Description | -| ----------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -| `dependsOn` | [`ResolverDependency`](./ResolverDependency.md)[] _(optional)_ | The accounts and arguments the resolver depends on. Used by clients to ensure the dependencies are resolved first. | +| Attribute | Type | Description | +| ----------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `dependsOn` | [`ResolverDependency`](./ResolverDependency.md)[] _(optional)_ | The accounts and arguments the resolver depends on. Used by clients to ensure the dependencies are resolved first. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/countNodes/FixedCountNode.md b/docs/countNodes/FixedCountNode.md index 19743dd..eb399f5 100644 --- a/docs/countNodes/FixedCountNode.md +++ b/docs/countNodes/FixedCountNode.md @@ -12,6 +12,12 @@ This enables nodes such as `arrayTypeNode` to represent collections of a fixed l | `kind` | `"fixedCountNode"` | The node discriminator. | | `value` | `u64` | The fixed number of items. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a fixed count node from a number diff --git a/docs/countNodes/PrefixedCountNode.md b/docs/countNodes/PrefixedCountNode.md index d43ad80..5c65d39 100644 --- a/docs/countNodes/PrefixedCountNode.md +++ b/docs/countNodes/PrefixedCountNode.md @@ -13,9 +13,10 @@ This enables nodes such as `arrayTypeNode` to represent collections whose length ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------ | -| `prefix` | [`NestedTypeNode`](../typeNodes/NestedTypeNode.md)<[`NumberTypeNode`](../typeNodes/NumberTypeNode.md)> | The numeric type used as the count prefix. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `prefix` | [`NestedTypeNode`](../typeNodes/NestedTypeNode.md)<[`NumberTypeNode`](../typeNodes/NumberTypeNode.md)> | The numeric type used as the count prefix. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/countNodes/RemainderCountNode.md b/docs/countNodes/RemainderCountNode.md index 22e2535..93fb4f4 100644 --- a/docs/countNodes/RemainderCountNode.md +++ b/docs/countNodes/RemainderCountNode.md @@ -12,6 +12,12 @@ This strategy is therefore only meaningful for the last variable-size region of | --------- | ---------------------- | ----------------------- | | `kind` | `"remainderCountNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a remainder count node diff --git a/docs/discriminatorNodes/ConstantDiscriminatorNode.md b/docs/discriminatorNodes/ConstantDiscriminatorNode.md index 74df7c9..37ca33b 100644 --- a/docs/discriminatorNodes/ConstantDiscriminatorNode.md +++ b/docs/discriminatorNodes/ConstantDiscriminatorNode.md @@ -13,9 +13,10 @@ Identifies a node by a constant value at a known byte offset (e.g. a magic heade ### Children -| Attribute | Type | Description | -| ---------- | --------------------------------------------------------- | ------------------------------------------ | -| `constant` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) | The constant value expected at the offset. | +| Attribute | Type | Description | +| ---------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `constant` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) | The constant value expected at the offset. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/discriminatorNodes/FieldDiscriminatorNode.md b/docs/discriminatorNodes/FieldDiscriminatorNode.md index 3512e68..7b392fe 100644 --- a/docs/discriminatorNodes/FieldDiscriminatorNode.md +++ b/docs/discriminatorNodes/FieldDiscriminatorNode.md @@ -12,6 +12,12 @@ Identifies a node by the value of a named field at a known byte offset. | `name` | `CamelCaseString` | The name of the discriminating field — a `structFieldTypeNode` of the account data or an argument of the instruction. | | `offset` | `u64` | The byte offset of the field. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a field discriminator node from a field name and an optional offset diff --git a/docs/discriminatorNodes/SizeDiscriminatorNode.md b/docs/discriminatorNodes/SizeDiscriminatorNode.md index b02691f..e1d7868 100644 --- a/docs/discriminatorNodes/SizeDiscriminatorNode.md +++ b/docs/discriminatorNodes/SizeDiscriminatorNode.md @@ -11,6 +11,12 @@ Identifies a node by its expected total byte size. | `kind` | `"sizeDiscriminatorNode"` | The node discriminator. | | `size` | `u64` | The expected byte size. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a size discriminator node from a size diff --git a/docs/displayNodes/AmountNumberDisplayNode.md b/docs/displayNodes/AmountNumberDisplayNode.md index b7c23c1..e52e619 100644 --- a/docs/displayNodes/AmountNumberDisplayNode.md +++ b/docs/displayNodes/AmountNumberDisplayNode.md @@ -17,6 +17,7 @@ The value is divided by `10 ^ decimals` and rendered alongside `unit` (e.g. `"US | ---------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `decimals` | [`InjectableNumberValueNode`](../valueNodes/InjectableNumberValueNode.md) _(optional)_ | How many decimal places scale the underlying integer. Resolved as a number value: either a literal `numberValueNode` or a key resolved from a surrounding provider. A value of `1000000` with `decimals` resolving to `6` renders as `1`. When this input cannot resolve, renderers should fall back to presenting the raw value rather than guess the scale. | | `unit` | [`InjectableStringValueNode`](../valueNodes/InjectableStringValueNode.md) _(optional)_ | A label appended after the scaled value (e.g. `"USDC"`, `"%"`, `"bps"`). Resolved as a string value: either a literal `stringValueNode` or a key resolved from a surrounding provider. When this input cannot resolve, renderers should present the scaled value without a unit. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/displayNodes/DateTimeNumberDisplayNode.md b/docs/displayNodes/DateTimeNumberDisplayNode.md index bf87e70..229b3b2 100644 --- a/docs/displayNodes/DateTimeNumberDisplayNode.md +++ b/docs/displayNodes/DateTimeNumberDisplayNode.md @@ -12,6 +12,12 @@ The underlying value counts ticks since the Unix epoch; `ticksPerSecond` is the | `kind` | `"dateTimeNumberDisplayNode"` | The node discriminator. | | `ticksPerSecond` | `u64` _(optional)_ | How many ticks make one second. Defaults to `1` (the value is already in seconds). Common choices are `1000` (milliseconds), `1000000` (microseconds), and `1000000000` (nanoseconds). | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### A Unix timestamp already in seconds diff --git a/docs/displayNodes/DurationNumberDisplayNode.md b/docs/displayNodes/DurationNumberDisplayNode.md index 971cf15..62e6c2a 100644 --- a/docs/displayNodes/DurationNumberDisplayNode.md +++ b/docs/displayNodes/DurationNumberDisplayNode.md @@ -13,6 +13,12 @@ Renderers typically format the result as `HH:mm:ss` or a coarser human-readable | `kind` | `"durationNumberDisplayNode"` | The node discriminator. | | `ticksPerSecond` | `u64` _(optional)_ | How many ticks make one second. Defaults to `1` (the value is already in seconds). Common choices are `1000` (milliseconds), `1000000` (microseconds), and `1000000000` (nanoseconds). | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### A duration already in seconds diff --git a/docs/displayNodes/EnumVariantDisplayNode.md b/docs/displayNodes/EnumVariantDisplayNode.md index 90f642c..3ccf6af 100644 --- a/docs/displayNodes/EnumVariantDisplayNode.md +++ b/docs/displayNodes/EnumVariantDisplayNode.md @@ -12,6 +12,12 @@ Display metadata for an enum variant: its label and whether to hide its inner pa | `label` | `string` _(optional)_ | An override label shown for the variant (e.g. `"Buy"`). When absent, renderers derive a label from the variant `name`. | | `skipInnerData` | `boolean` _(optional)_ | When `true`, the variant's payload is hidden — only the label is rendered. Useful for tuple payloads that have no per-field handle, or when the payload is purely structural. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Relabelling a struct variant diff --git a/docs/displayNodes/InstructionAccountDisplayNode.md b/docs/displayNodes/InstructionAccountDisplayNode.md index eb0f227..449f09c 100644 --- a/docs/displayNodes/InstructionAccountDisplayNode.md +++ b/docs/displayNodes/InstructionAccountDisplayNode.md @@ -13,9 +13,10 @@ Display metadata for an instruction account: its label in the fallback list and ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `skip` | [`DisplaySkip`](../sharedNodes/DisplaySkip.md) _(optional)_ | Whether the account is shown in the fallback list. Defaults to `"never"` (always shown). | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `skip` | [`DisplaySkip`](../sharedNodes/DisplaySkip.md) _(optional)_ | Whether the account is shown in the fallback list. Defaults to `"never"` (always shown). | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/displayNodes/InstructionDisplayNode.md b/docs/displayNodes/InstructionDisplayNode.md index df3b88d..289b78e 100644 --- a/docs/displayNodes/InstructionDisplayNode.md +++ b/docs/displayNodes/InstructionDisplayNode.md @@ -13,6 +13,12 @@ Either form may be absent; presentation strategy is left to the renderer. | `intent` | `string` _(optional)_ | A short imperative label describing what the instruction does (e.g. `"Transfer"`). | | `interpolatedIntent` | `string` _(optional)_ | A sentence template that composes the instruction into prose with `${root.path}` placeholders. Roots are `data.` (an instruction argument) and `accounts.` (an instruction account); the path is flat after the root (e.g. `${data.amount}`, `${accounts.destination}`). A placeholder renders through its referent's own presentation; the `skip` rule governs the fallback list only and never the sentence. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### An intent label plus an interpolated sentence diff --git a/docs/displayNodes/StringDisplayNode.md b/docs/displayNodes/StringDisplayNode.md index e7f02e3..0a3c43a 100644 --- a/docs/displayNodes/StringDisplayNode.md +++ b/docs/displayNodes/StringDisplayNode.md @@ -13,6 +13,12 @@ The string's wire encoding is carried by `stringTypeNode.encoding`; this node on | `sliceStart` | `u64` _(optional)_ | The start index of the displayed slice, inclusive. Defaults to the start of the string. Indices apply to the decoded character sequence. | | `sliceEnd` | `u64` _(optional)_ | The end index of the displayed slice, exclusive. Defaults to the end of the string. Indices apply to the decoded character sequence. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Displaying the whole string diff --git a/docs/displayNodes/StructFieldDisplayNode.md b/docs/displayNodes/StructFieldDisplayNode.md index f655a4e..981eae2 100644 --- a/docs/displayNodes/StructFieldDisplayNode.md +++ b/docs/displayNodes/StructFieldDisplayNode.md @@ -16,9 +16,10 @@ Value presentation is carried by the member's type; this node only addresses nam ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------- | -| `skip` | [`DisplaySkip`](../sharedNodes/DisplaySkip.md) _(optional)_ | Whether the member is shown in the fallback list. Defaults to `"never"` (always shown). | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `skip` | [`DisplaySkip`](../sharedNodes/DisplaySkip.md) _(optional)_ | Whether the member is shown in the fallback list. Defaults to `"never"` (always shown). | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/AccountLinkNode.md b/docs/linkNodes/AccountLinkNode.md index 5516577..fca7a22 100644 --- a/docs/linkNodes/AccountLinkNode.md +++ b/docs/linkNodes/AccountLinkNode.md @@ -13,9 +13,10 @@ A reference to an account defined elsewhere — possibly in a different program. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | -| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced account belongs to. When omitted, the surrounding program is assumed. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced account belongs to. When omitted, the surrounding program is assumed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/DefinedTypeLinkNode.md b/docs/linkNodes/DefinedTypeLinkNode.md index 0f8fe05..d2510bf 100644 --- a/docs/linkNodes/DefinedTypeLinkNode.md +++ b/docs/linkNodes/DefinedTypeLinkNode.md @@ -13,9 +13,10 @@ A reference to a defined type — possibly in a different program. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | -| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced type is defined in. When omitted, the surrounding program is assumed. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced type is defined in. When omitted, the surrounding program is assumed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/InstructionAccountLinkNode.md b/docs/linkNodes/InstructionAccountLinkNode.md index 9f89972..e8e46f8 100644 --- a/docs/linkNodes/InstructionAccountLinkNode.md +++ b/docs/linkNodes/InstructionAccountLinkNode.md @@ -16,6 +16,7 @@ A reference to an account of another instruction. | Attribute | Type | Description | | ------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `instruction` | [`InstructionLinkNode`](./InstructionLinkNode.md) _(optional)_ | The instruction the referenced account belongs to. When omitted, the surrounding instruction is assumed. The instruction link may itself point to a different program if needed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/InstructionArgumentLinkNode.md b/docs/linkNodes/InstructionArgumentLinkNode.md index 705b86a..796d4de 100644 --- a/docs/linkNodes/InstructionArgumentLinkNode.md +++ b/docs/linkNodes/InstructionArgumentLinkNode.md @@ -16,6 +16,7 @@ A reference to an argument of another instruction. | Attribute | Type | Description | | ------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `instruction` | [`InstructionLinkNode`](./InstructionLinkNode.md) _(optional)_ | The instruction the referenced argument belongs to. When omitted, the surrounding instruction is assumed. The instruction link may itself point to a different program if needed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/InstructionLinkNode.md b/docs/linkNodes/InstructionLinkNode.md index 8ec0c1a..45a3038 100644 --- a/docs/linkNodes/InstructionLinkNode.md +++ b/docs/linkNodes/InstructionLinkNode.md @@ -13,9 +13,10 @@ A reference to an instruction defined elsewhere — possibly in a different prog ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | -| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced instruction belongs to. When omitted, the surrounding program is assumed. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced instruction belongs to. When omitted, the surrounding program is assumed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/PdaLinkNode.md b/docs/linkNodes/PdaLinkNode.md index de3f36c..c2a7406 100644 --- a/docs/linkNodes/PdaLinkNode.md +++ b/docs/linkNodes/PdaLinkNode.md @@ -13,9 +13,10 @@ A reference to a PDA defined elsewhere — possibly in a different program. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------- | -| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced PDA belongs to. When omitted, the surrounding program is assumed. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `program` | [`ProgramLinkNode`](./ProgramLinkNode.md) _(optional)_ | The program the referenced PDA belongs to. When omitted, the surrounding program is assumed. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/linkNodes/ProgramLinkNode.md b/docs/linkNodes/ProgramLinkNode.md index 73fe08c..558e35a 100644 --- a/docs/linkNodes/ProgramLinkNode.md +++ b/docs/linkNodes/ProgramLinkNode.md @@ -11,6 +11,12 @@ A reference to a program by name. | `kind` | `"programLinkNode"` | The node discriminator. | | `name` | `CamelCaseString` | The name of the referenced program. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a program link node from a program name diff --git a/docs/pdaSeedNodes/ConstantPdaSeedNode.md b/docs/pdaSeedNodes/ConstantPdaSeedNode.md index 4e97420..ed283d2 100644 --- a/docs/pdaSeedNodes/ConstantPdaSeedNode.md +++ b/docs/pdaSeedNodes/ConstantPdaSeedNode.md @@ -12,10 +12,11 @@ A PDA seed with a constant value (e.g. a UTF-8 string or a fixed byte sequence). ### Children -| Attribute | Type | Description | -| --------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The type of the seed value. | -| `value` | [`ConstantPdaSeedValue`](./ConstantPdaSeedValue.md) | The constant value to use as the seed — either a literal value or the program ID placeholder. | +| Attribute | Type | Description | +| --------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The type of the seed value. | +| `value` | [`ConstantPdaSeedValue`](./ConstantPdaSeedValue.md) | The constant value to use as the seed — either a literal value or the program ID placeholder. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/pdaSeedNodes/VariablePdaSeedNode.md b/docs/pdaSeedNodes/VariablePdaSeedNode.md index 1584d70..d960f5c 100644 --- a/docs/pdaSeedNodes/VariablePdaSeedNode.md +++ b/docs/pdaSeedNodes/VariablePdaSeedNode.md @@ -14,9 +14,10 @@ A PDA seed whose value is provided at derivation time, identified by name. ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------- | ------------------------------------ | -| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The expected type of the seed value. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The expected type of the seed value. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/AmountTypeNode.md b/docs/typeNodes/AmountTypeNode.md index f779c2a..2bcdecb 100644 --- a/docs/typeNodes/AmountTypeNode.md +++ b/docs/typeNodes/AmountTypeNode.md @@ -15,9 +15,10 @@ Particularly useful for representing financial values as integers, since floatin ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------------------------------------------------- | --------------------------------- | -| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The number type the amount wraps. | +| Attribute | Type | Description | +| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The number type the amount wraps. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/ArrayTypeNode.md b/docs/typeNodes/ArrayTypeNode.md index 6b081f7..84d070d 100644 --- a/docs/typeNodes/ArrayTypeNode.md +++ b/docs/typeNodes/ArrayTypeNode.md @@ -12,10 +12,11 @@ A homogeneous list of items. The item type is defined by `item`; the length is d ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------- | --------------------------------------------------- | -| `item` | [`TypeNode`](./TypeNode.md) | The type of each item in the array. | -| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of items. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `item` | [`TypeNode`](./TypeNode.md) | The type of each item in the array. | +| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of items. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/BooleanTypeNode.md b/docs/typeNodes/BooleanTypeNode.md index e15e8b8..3647709 100644 --- a/docs/typeNodes/BooleanTypeNode.md +++ b/docs/typeNodes/BooleanTypeNode.md @@ -13,9 +13,10 @@ A decoded number of `1` yields `true`; any other value yields `false`. ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------------------------------------------------- | ----------------------------------------------- | -| `size` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the boolean. | +| Attribute | Type | Description | +| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `size` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the boolean. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/BytesTypeNode.md b/docs/typeNodes/BytesTypeNode.md index 9243ca2..cda1720 100644 --- a/docs/typeNodes/BytesTypeNode.md +++ b/docs/typeNodes/BytesTypeNode.md @@ -10,6 +10,12 @@ A raw sequence of bytes. Typically used inside a fixed-size, size-prefixed, or s | --------- | ----------------- | ----------------------- | | `kind` | `"bytesTypeNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a bytes type node diff --git a/docs/typeNodes/DateTimeTypeNode.md b/docs/typeNodes/DateTimeTypeNode.md index c91b745..c78aa03 100644 --- a/docs/typeNodes/DateTimeTypeNode.md +++ b/docs/typeNodes/DateTimeTypeNode.md @@ -12,9 +12,10 @@ A timestamp encoded as a number, typically seconds since the Unix epoch. The wra ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------- | -| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the timestamp. | +| Attribute | Type | Description | +| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the timestamp. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/EnumEmptyVariantTypeNode.md b/docs/typeNodes/EnumEmptyVariantTypeNode.md index ad6206b..d5921c9 100644 --- a/docs/typeNodes/EnumEmptyVariantTypeNode.md +++ b/docs/typeNodes/EnumEmptyVariantTypeNode.md @@ -14,9 +14,10 @@ A unit-style variant of an enum that carries no payload. ### Children -| Attribute | Type | Description | -| --------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/EnumStructVariantTypeNode.md b/docs/typeNodes/EnumStructVariantTypeNode.md index 11c4fcf..8e86aea 100644 --- a/docs/typeNodes/EnumStructVariantTypeNode.md +++ b/docs/typeNodes/EnumStructVariantTypeNode.md @@ -14,10 +14,11 @@ A variant of an enum that carries a struct payload (named fields). ### Children -| Attribute | Type | Description | -| --------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `struct` | [`NestedTypeNode`](./NestedTypeNode.md)<[`StructTypeNode`](./StructTypeNode.md)> | The struct of named fields carried by the variant. | -| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `struct` | [`NestedTypeNode`](./NestedTypeNode.md)<[`StructTypeNode`](./StructTypeNode.md)> | The struct of named fields carried by the variant. | +| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/EnumTupleVariantTypeNode.md b/docs/typeNodes/EnumTupleVariantTypeNode.md index cf7ca59..e55ce0f 100644 --- a/docs/typeNodes/EnumTupleVariantTypeNode.md +++ b/docs/typeNodes/EnumTupleVariantTypeNode.md @@ -14,10 +14,11 @@ A variant of an enum that carries a tuple payload (positional fields). ### Children -| Attribute | Type | Description | -| --------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `tuple` | [`NestedTypeNode`](./NestedTypeNode.md)<[`TupleTypeNode`](./TupleTypeNode.md)> | The tuple of positional fields carried by the variant. | -| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| Attribute | Type | Description | +| --------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `tuple` | [`NestedTypeNode`](./NestedTypeNode.md)<[`TupleTypeNode`](./TupleTypeNode.md)> | The tuple of positional fields carried by the variant. | +| `display` | [`EnumVariantDisplayNode`](../displayNodes/EnumVariantDisplayNode.md) _(optional)_ | Display metadata describing how the variant is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/EnumTypeNode.md b/docs/typeNodes/EnumTypeNode.md index cfed0d9..944b771 100644 --- a/docs/typeNodes/EnumTypeNode.md +++ b/docs/typeNodes/EnumTypeNode.md @@ -16,6 +16,7 @@ A tagged union: a numeric discriminator followed by one of several variant paylo | ---------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `variants` | [`EnumVariantTypeNode`](./EnumVariantTypeNode.md)[] | The variants of the enum, in declaration order. | | `size` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the discriminator. The discriminator prepends the serialised variant payload to identify which variant was selected. By default it is the index of the variant (starting at 0), unless the variant provides its own custom discriminator value. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/FixedSizeTypeNode.md b/docs/typeNodes/FixedSizeTypeNode.md index 2cd870f..91dc2cd 100644 --- a/docs/typeNodes/FixedSizeTypeNode.md +++ b/docs/typeNodes/FixedSizeTypeNode.md @@ -13,9 +13,10 @@ Wraps another type and asserts a fixed total byte size. Padding or truncation is ### Children -| Attribute | Type | Description | -| --------- | --------------------------- | ---------------------------------------------------- | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is constrained. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is constrained. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/HiddenPrefixTypeNode.md b/docs/typeNodes/HiddenPrefixTypeNode.md index 5e332ef..29cd45b 100644 --- a/docs/typeNodes/HiddenPrefixTypeNode.md +++ b/docs/typeNodes/HiddenPrefixTypeNode.md @@ -13,10 +13,11 @@ When decoding, the prefixed constants are consumed and checked against their exp ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------------- | ---------------------------------------------------------------------- | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by the hidden prefix. | -| `prefix` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md)[] | The constant values written before the wrapped type, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by the hidden prefix. | +| `prefix` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md)[] | The constant values written before the wrapped type, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/HiddenSuffixTypeNode.md b/docs/typeNodes/HiddenSuffixTypeNode.md index f9eccc3..f81b16f 100644 --- a/docs/typeNodes/HiddenSuffixTypeNode.md +++ b/docs/typeNodes/HiddenSuffixTypeNode.md @@ -13,10 +13,11 @@ When decoding, the suffixed constants are consumed and checked against their exp ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------------- | ---------------------------------------------------------------------- | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is followed by the hidden suffix. | -| `suffix` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md)[] | The constant values written after the wrapped type, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is followed by the hidden suffix. | +| `suffix` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md)[] | The constant values written after the wrapped type, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/MapTypeNode.md b/docs/typeNodes/MapTypeNode.md index 585df7b..00ef5eb 100644 --- a/docs/typeNodes/MapTypeNode.md +++ b/docs/typeNodes/MapTypeNode.md @@ -14,11 +14,12 @@ Entries are serialised one after the other, each key immediately followed by its ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------- | ----------------------------------------------------- | -| `key` | [`TypeNode`](./TypeNode.md) | The type of each entry key. | -| `value` | [`TypeNode`](./TypeNode.md) | The type of each entry value. | -| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of entries. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `key` | [`TypeNode`](./TypeNode.md) | The type of each entry key. | +| `value` | [`TypeNode`](./TypeNode.md) | The type of each entry value. | +| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of entries. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/NumberTypeNode.md b/docs/typeNodes/NumberTypeNode.md index 0f43931..173c5d2 100644 --- a/docs/typeNodes/NumberTypeNode.md +++ b/docs/typeNodes/NumberTypeNode.md @@ -12,11 +12,12 @@ A numeric type with a fixed wire format and byte order. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------------------------ | -------------------------------------------------------- | -| `format` | [`NumberFormat`](../sharedNodes/NumberFormat.md) | The wire format used to serialise the number. | -| `endian` | [`Endianness`](../sharedNodes/Endianness.md) | The byte order used to serialise the number. | -| `display` | [`NumberDisplayNode`](../displayNodes/NumberDisplayNode.md) _(optional)_ | Display metadata describing how the number is presented. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `format` | [`NumberFormat`](../sharedNodes/NumberFormat.md) | The wire format used to serialise the number. | +| `endian` | [`Endianness`](../sharedNodes/Endianness.md) | The byte order used to serialise the number. | +| `display` | [`NumberDisplayNode`](../displayNodes/NumberDisplayNode.md) _(optional)_ | Display metadata describing how the number is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/OptionTypeNode.md b/docs/typeNodes/OptionTypeNode.md index 925daba..59e4f1e 100644 --- a/docs/typeNodes/OptionTypeNode.md +++ b/docs/typeNodes/OptionTypeNode.md @@ -17,6 +17,7 @@ A value that may be present or absent (Some/None), with an explicit numeric pref | --------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `item` | [`TypeNode`](./TypeNode.md) | The type carried by the option when present. | | `prefix` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used as the presence flag. A prefix value of `1` means the item is present and follows the prefix; a value of `0` means the item is absent and nothing further is serialised. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/PostOffsetTypeNode.md b/docs/typeNodes/PostOffsetTypeNode.md index fd5db29..6ba4c15 100644 --- a/docs/typeNodes/PostOffsetTypeNode.md +++ b/docs/typeNodes/PostOffsetTypeNode.md @@ -78,10 +78,11 @@ offset = -2 ### Children -| Attribute | Type | Description | -| ---------- | ------------------------------------------------------------ | --------------------------------------------------------------- | -| `strategy` | [`PostOffsetStrategy`](../sharedNodes/PostOffsetStrategy.md) | How the `offset` value is interpreted. | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is followed by the offset. | +| Attribute | Type | Description | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `strategy` | [`PostOffsetStrategy`](../sharedNodes/PostOffsetStrategy.md) | How the `offset` value is interpreted. | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is followed by the offset. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/PreOffsetTypeNode.md b/docs/typeNodes/PreOffsetTypeNode.md index 22f6b5f..24f95f7 100644 --- a/docs/typeNodes/PreOffsetTypeNode.md +++ b/docs/typeNodes/PreOffsetTypeNode.md @@ -63,10 +63,11 @@ offset = -2 ### Children -| Attribute | Type | Description | -| ---------- | ---------------------------------------------------------- | --------------------------------------------------------------- | -| `strategy` | [`PreOffsetStrategy`](../sharedNodes/PreOffsetStrategy.md) | How the `offset` value is interpreted. | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by the offset. | +| Attribute | Type | Description | +| ---------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `strategy` | [`PreOffsetStrategy`](../sharedNodes/PreOffsetStrategy.md) | How the `offset` value is interpreted. | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by the offset. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/PublicKeyTypeNode.md b/docs/typeNodes/PublicKeyTypeNode.md index a162121..45223ec 100644 --- a/docs/typeNodes/PublicKeyTypeNode.md +++ b/docs/typeNodes/PublicKeyTypeNode.md @@ -10,6 +10,12 @@ A 32-byte Solana public key. | --------- | --------------------- | ----------------------- | | `kind` | `"publicKeyTypeNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a public key type node diff --git a/docs/typeNodes/RemainderOptionTypeNode.md b/docs/typeNodes/RemainderOptionTypeNode.md index 77a0b84..d76a5d6 100644 --- a/docs/typeNodes/RemainderOptionTypeNode.md +++ b/docs/typeNodes/RemainderOptionTypeNode.md @@ -12,9 +12,10 @@ A value that may be present or absent. Presence is signalled by whether any byte ### Children -| Attribute | Type | Description | -| --------- | --------------------------- | -------------------------------------------- | -| `item` | [`TypeNode`](./TypeNode.md) | The type carried by the option when present. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `item` | [`TypeNode`](./TypeNode.md) | The type carried by the option when present. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/SentinelTypeNode.md b/docs/typeNodes/SentinelTypeNode.md index b8a0985..df48b8f 100644 --- a/docs/typeNodes/SentinelTypeNode.md +++ b/docs/typeNodes/SentinelTypeNode.md @@ -17,10 +17,11 @@ When decoding, the wrapped type is decoded until the sentinel value is encounter ### Children -| Attribute | Type | Description | -| ---------- | --------------------------------------------------------- | ------------------------------------------------------------------------------ | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose extent is delimited by the sentinel. | -| `sentinel` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) | The constant value written immediately after the wrapped type to mark its end. | +| Attribute | Type | Description | +| ---------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose extent is delimited by the sentinel. | +| `sentinel` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) | The constant value written immediately after the wrapped type to mark its end. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/SetTypeNode.md b/docs/typeNodes/SetTypeNode.md index b3f7375..50752a7 100644 --- a/docs/typeNodes/SetTypeNode.md +++ b/docs/typeNodes/SetTypeNode.md @@ -12,10 +12,11 @@ A unique-valued collection. The item type is defined by `item`; the size is dete ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------- | --------------------------------------------------- | -| `item` | [`TypeNode`](./TypeNode.md) | The type of each item in the set. | -| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of items. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `item` | [`TypeNode`](./TypeNode.md) | The type of each item in the set. | +| `count` | [`CountNode`](../countNodes/CountNode.md) | The strategy used to determine the number of items. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/SizePrefixTypeNode.md b/docs/typeNodes/SizePrefixTypeNode.md index 2470f5f..d2eb1f9 100644 --- a/docs/typeNodes/SizePrefixTypeNode.md +++ b/docs/typeNodes/SizePrefixTypeNode.md @@ -13,10 +13,11 @@ When decoding, the size is read first and determines how many bytes the wrapped ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------- | -| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by its size. | -| `prefix` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used as the size prefix. | +| Attribute | Type | Description | +| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](./TypeNode.md) | The wrapped type whose serialisation is preceded by its size. | +| `prefix` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used as the size prefix. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/SolAmountTypeNode.md b/docs/typeNodes/SolAmountTypeNode.md index f34c17f..c7c7b97 100644 --- a/docs/typeNodes/SolAmountTypeNode.md +++ b/docs/typeNodes/SolAmountTypeNode.md @@ -13,9 +13,10 @@ Equivalent to an `amountTypeNode` with 9 decimals and `SOL` as the unit. ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------ | -| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the lamport amount. | +| Attribute | Type | Description | +| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `number` | [`NestedTypeNode`](./NestedTypeNode.md)<[`NumberTypeNode`](./NumberTypeNode.md)> | The numeric type used to serialise the lamport amount. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/StringTypeNode.md b/docs/typeNodes/StringTypeNode.md index 34443bd..beb1892 100644 --- a/docs/typeNodes/StringTypeNode.md +++ b/docs/typeNodes/StringTypeNode.md @@ -14,10 +14,11 @@ The byte length is determined by an enclosing wrapper such as `sizePrefixTypeNod ### Children -| Attribute | Type | Description | -| ---------- | ------------------------------------------------------------------------ | -------------------------------------------------------- | -| `encoding` | [`BytesEncoding`](../sharedNodes/BytesEncoding.md) | The byte encoding used to serialise the string. | -| `display` | [`StringDisplayNode`](../displayNodes/StringDisplayNode.md) _(optional)_ | Display metadata describing how the string is presented. | +| Attribute | Type | Description | +| ---------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `encoding` | [`BytesEncoding`](../sharedNodes/BytesEncoding.md) | The byte encoding used to serialise the string. | +| `display` | [`StringDisplayNode`](../displayNodes/StringDisplayNode.md) _(optional)_ | Display metadata describing how the string is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/StructFieldTypeNode.md b/docs/typeNodes/StructFieldTypeNode.md index 28cd181..4827621 100644 --- a/docs/typeNodes/StructFieldTypeNode.md +++ b/docs/typeNodes/StructFieldTypeNode.md @@ -14,12 +14,13 @@ A named field within a struct type. ### Children -| Attribute | Type | Description | -| ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| `defaultValueStrategy` | [`DefaultValueStrategy`](../sharedNodes/DefaultValueStrategy.md) _(optional)_ | How a configured default value is exposed in generated APIs. Required when `defaultValue` is set. | -| `type` | [`TypeNode`](./TypeNode.md) | The type of the field. | -| `defaultValue` | [`ValueNode`](../valueNodes/ValueNode.md) _(optional)_ | A default value used when the field is omitted by callers. | -| `display` | [`StructFieldDisplayNode`](../displayNodes/StructFieldDisplayNode.md) _(optional)_ | Display metadata describing how the field is presented. | +| Attribute | Type | Description | +| ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `defaultValueStrategy` | [`DefaultValueStrategy`](../sharedNodes/DefaultValueStrategy.md) _(optional)_ | How a configured default value is exposed in generated APIs. Required when `defaultValue` is set. | +| `type` | [`TypeNode`](./TypeNode.md) | The type of the field. | +| `defaultValue` | [`ValueNode`](../valueNodes/ValueNode.md) _(optional)_ | A default value used when the field is omitted by callers. | +| `display` | [`StructFieldDisplayNode`](../displayNodes/StructFieldDisplayNode.md) _(optional)_ | Display metadata describing how the field is presented. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/StructTypeNode.md b/docs/typeNodes/StructTypeNode.md index 3d22c97..b043af0 100644 --- a/docs/typeNodes/StructTypeNode.md +++ b/docs/typeNodes/StructTypeNode.md @@ -12,9 +12,10 @@ A composite type made of an ordered list of named fields. Fields are encoded and ### Children -| Attribute | Type | Description | -| --------- | --------------------------------------------------- | ----------------------------------------------- | -| `fields` | [`StructFieldTypeNode`](./StructFieldTypeNode.md)[] | The fields of the struct, in declaration order. | +| Attribute | Type | Description | +| --------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `fields` | [`StructFieldTypeNode`](./StructFieldTypeNode.md)[] | The fields of the struct, in declaration order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/TupleTypeNode.md b/docs/typeNodes/TupleTypeNode.md index 6b7ee01..2742d13 100644 --- a/docs/typeNodes/TupleTypeNode.md +++ b/docs/typeNodes/TupleTypeNode.md @@ -12,9 +12,10 @@ A heterogeneous fixed-length sequence in which each positional slot has its own ### Children -| Attribute | Type | Description | -| --------- | ----------------------------- | ------------------------------------------- | -| `items` | [`TypeNode`](./TypeNode.md)[] | The type of each positional slot, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `items` | [`TypeNode`](./TypeNode.md)[] | The type of each positional slot, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/typeNodes/ZeroableOptionTypeNode.md b/docs/typeNodes/ZeroableOptionTypeNode.md index 590e17c..e084699 100644 --- a/docs/typeNodes/ZeroableOptionTypeNode.md +++ b/docs/typeNodes/ZeroableOptionTypeNode.md @@ -12,10 +12,11 @@ An optional value whose absence is signalled by a designated zero value rather t ### Children -| Attribute | Type | Description | -| ----------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `item` | [`TypeNode`](./TypeNode.md) | The type carried by the option when present. Must be of fixed size. | -| `zeroValue` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) _(optional)_ | The constant value that signals absence. When omitted, the all-zero byte pattern of the item type is used. | +| Attribute | Type | Description | +| ----------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `item` | [`TypeNode`](./TypeNode.md) | The type carried by the option when present. Must be of fixed size. | +| `zeroValue` | [`ConstantValueNode`](../valueNodes/ConstantValueNode.md) _(optional)_ | The constant value that signals absence. When omitted, the all-zero byte pattern of the item type is used. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/ArrayValueNode.md b/docs/valueNodes/ArrayValueNode.md index 1edcee5..2160468 100644 --- a/docs/valueNodes/ArrayValueNode.md +++ b/docs/valueNodes/ArrayValueNode.md @@ -12,9 +12,10 @@ A concrete array value: a list of value nodes. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------- | --------------------------------- | -| `items` | [`ValueNode`](./ValueNode.md)[] | The items of the array, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `items` | [`ValueNode`](./ValueNode.md)[] | The items of the array, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/BooleanValueNode.md b/docs/valueNodes/BooleanValueNode.md index 299baf8..aa86a0e 100644 --- a/docs/valueNodes/BooleanValueNode.md +++ b/docs/valueNodes/BooleanValueNode.md @@ -11,6 +11,12 @@ A concrete boolean value. | `kind` | `"booleanValueNode"` | The node discriminator. | | `boolean` | `boolean` | The boolean value. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a boolean value node from a boolean diff --git a/docs/valueNodes/BytesValueNode.md b/docs/valueNodes/BytesValueNode.md index b8d956a..7eb980b 100644 --- a/docs/valueNodes/BytesValueNode.md +++ b/docs/valueNodes/BytesValueNode.md @@ -13,9 +13,10 @@ A concrete bytes value, encoded as text in the chosen encoding. ### Children -| Attribute | Type | Description | -| ---------- | -------------------------------------------------- | ------------------------------------------------- | -| `encoding` | [`BytesEncoding`](../sharedNodes/BytesEncoding.md) | The encoding used to represent the bytes as text. | +| Attribute | Type | Description | +| ---------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `encoding` | [`BytesEncoding`](../sharedNodes/BytesEncoding.md) | The encoding used to represent the bytes as text. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/ConstantValueNode.md b/docs/valueNodes/ConstantValueNode.md index a718e74..dbc3816 100644 --- a/docs/valueNodes/ConstantValueNode.md +++ b/docs/valueNodes/ConstantValueNode.md @@ -12,10 +12,11 @@ A typed constant: a type node paired with a concrete value node. ### Children -| Attribute | Type | Description | -| --------- | -------------------------------------- | ----------------------------------- | -| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The type of the constant. | -| `value` | [`ValueNode`](./ValueNode.md) | The concrete value of the constant. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [`TypeNode`](../typeNodes/TypeNode.md) | The type of the constant. | +| `value` | [`ValueNode`](./ValueNode.md) | The concrete value of the constant. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/EnumValueNode.md b/docs/valueNodes/EnumValueNode.md index 38ee3e2..4c1f256 100644 --- a/docs/valueNodes/EnumValueNode.md +++ b/docs/valueNodes/EnumValueNode.md @@ -13,10 +13,11 @@ A concrete value of a defined enum: a variant identifier plus an optional payloa ### Children -| Attribute | Type | Description | -| --------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | -| `enum` | [`DefinedTypeLinkNode`](../linkNodes/DefinedTypeLinkNode.md) | A link to the defined enum type the value belongs to. The linked defined type must contain an `enumTypeNode`. | -| `value` | [`EnumValuePayload`](./EnumValuePayload.md) _(optional)_ | The variant payload — a struct value for struct variants or a tuple value for tuple variants. Omitted for unit variants. | +| Attribute | Type | Description | +| --------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | +| `enum` | [`DefinedTypeLinkNode`](../linkNodes/DefinedTypeLinkNode.md) | A link to the defined enum type the value belongs to. The linked defined type must contain an `enumTypeNode`. | +| `value` | [`EnumValuePayload`](./EnumValuePayload.md) _(optional)_ | The variant payload — a struct value for struct variants or a tuple value for tuple variants. Omitted for unit variants. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/InjectedValueNode.md b/docs/valueNodes/InjectedValueNode.md index 69a289e..afafd44 100644 --- a/docs/valueNodes/InjectedValueNode.md +++ b/docs/valueNodes/InjectedValueNode.md @@ -15,9 +15,10 @@ Resolution is a per-context property: a value with the same key may resolve in o ### Children -| Attribute | Type | Description | -| ---------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| `fallback` | [`ValueNode`](./ValueNode.md) _(optional)_ | A value used when no provider supplies the key. When absent, the key is required: a provider must supply it for the surrounding context to be valid. | +| Attribute | Type | Description | +| ---------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fallback` | [`ValueNode`](./ValueNode.md) _(optional)_ | A value used when no provider supplies the key. When absent, the key is required: a provider must supply it for the surrounding context to be valid. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/MapEntryValueNode.md b/docs/valueNodes/MapEntryValueNode.md index 9c15976..7c4f8db 100644 --- a/docs/valueNodes/MapEntryValueNode.md +++ b/docs/valueNodes/MapEntryValueNode.md @@ -13,10 +13,11 @@ For example, the map `{ total: 42 }` has one entry whose key is the string `"tot ### Children -| Attribute | Type | Description | -| --------- | ----------------------------- | ---------------- | -| `key` | [`ValueNode`](./ValueNode.md) | The entry key. | -| `value` | [`ValueNode`](./ValueNode.md) | The entry value. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `key` | [`ValueNode`](./ValueNode.md) | The entry key. | +| `value` | [`ValueNode`](./ValueNode.md) | The entry value. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/MapValueNode.md b/docs/valueNodes/MapValueNode.md index 7c92b88..7b3c658 100644 --- a/docs/valueNodes/MapValueNode.md +++ b/docs/valueNodes/MapValueNode.md @@ -12,9 +12,10 @@ A concrete map value: a list of (key, value) entries. ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------- | --------------------------------- | -| `entries` | [`MapEntryValueNode`](./MapEntryValueNode.md)[] | The entries of the map, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `entries` | [`MapEntryValueNode`](./MapEntryValueNode.md)[] | The entries of the map, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/NoneValueNode.md b/docs/valueNodes/NoneValueNode.md index e29203b..7caee08 100644 --- a/docs/valueNodes/NoneValueNode.md +++ b/docs/valueNodes/NoneValueNode.md @@ -11,6 +11,12 @@ For instance, this can be set as the default value of a field whose type is an ` | --------- | ----------------- | ----------------------- | | `kind` | `"noneValueNode"` | The node discriminator. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a none value node diff --git a/docs/valueNodes/NumberValueNode.md b/docs/valueNodes/NumberValueNode.md index f250561..767f982 100644 --- a/docs/valueNodes/NumberValueNode.md +++ b/docs/valueNodes/NumberValueNode.md @@ -12,6 +12,12 @@ Stored as a 64-bit float; consumers narrow to a specific integer or float width | `kind` | `"numberValueNode"` | The node discriminator. | | `number` | `f64` | The numeric value. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a number value node from a number diff --git a/docs/valueNodes/PublicKeyValueNode.md b/docs/valueNodes/PublicKeyValueNode.md index 4e62450..6e94003 100644 --- a/docs/valueNodes/PublicKeyValueNode.md +++ b/docs/valueNodes/PublicKeyValueNode.md @@ -12,6 +12,12 @@ A concrete 32-byte public key, with an optional symbolic identifier for the addr | `publicKey` | `Address` | The base58-encoded public key. | | `identifier` | `CamelCaseString` _(optional)_ | A symbolic name for the address, useful in generated client code. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a public key value node from a base58 public key diff --git a/docs/valueNodes/SetValueNode.md b/docs/valueNodes/SetValueNode.md index 4aadd21..1a85499 100644 --- a/docs/valueNodes/SetValueNode.md +++ b/docs/valueNodes/SetValueNode.md @@ -12,9 +12,10 @@ A concrete set value: a list of unique value nodes. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------- | --------------------- | -| `items` | [`ValueNode`](./ValueNode.md)[] | The items of the set. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `items` | [`ValueNode`](./ValueNode.md)[] | The items of the set. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/SomeValueNode.md b/docs/valueNodes/SomeValueNode.md index a3f7e04..859003c 100644 --- a/docs/valueNodes/SomeValueNode.md +++ b/docs/valueNodes/SomeValueNode.md @@ -13,9 +13,10 @@ For instance, this can be set as the default value of a field whose type is an ` ### Children -| Attribute | Type | Description | -| --------- | ----------------------------- | ------------------ | -| `value` | [`ValueNode`](./ValueNode.md) | The wrapped value. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | [`ValueNode`](./ValueNode.md) | The wrapped value. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/StringValueNode.md b/docs/valueNodes/StringValueNode.md index e152e5f..e1f4f3d 100644 --- a/docs/valueNodes/StringValueNode.md +++ b/docs/valueNodes/StringValueNode.md @@ -11,6 +11,12 @@ A concrete string value. | `kind` | `"stringValueNode"` | The node discriminator. | | `string` | `string` | The string value. | +### Children + +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | + ## Examples ### Create a string value node from a string diff --git a/docs/valueNodes/StructFieldValueNode.md b/docs/valueNodes/StructFieldValueNode.md index 0dec0ac..69d9db9 100644 --- a/docs/valueNodes/StructFieldValueNode.md +++ b/docs/valueNodes/StructFieldValueNode.md @@ -13,9 +13,10 @@ A named field of a `structValueNode`. ### Children -| Attribute | Type | Description | -| --------- | ----------------------------- | -------------------------------- | -| `value` | [`ValueNode`](./ValueNode.md) | The concrete value of the field. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `value` | [`ValueNode`](./ValueNode.md) | The concrete value of the field. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/StructValueNode.md b/docs/valueNodes/StructValueNode.md index 4145779..80b0203 100644 --- a/docs/valueNodes/StructValueNode.md +++ b/docs/valueNodes/StructValueNode.md @@ -12,9 +12,10 @@ A concrete struct value: a list of named field values. ### Children -| Attribute | Type | Description | -| --------- | ----------------------------------------------------- | ------------------------------------- | -| `fields` | [`StructFieldValueNode`](./StructFieldValueNode.md)[] | The named fields of the struct value. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `fields` | [`StructFieldValueNode`](./StructFieldValueNode.md)[] | The named fields of the struct value. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/docs/valueNodes/TupleValueNode.md b/docs/valueNodes/TupleValueNode.md index ca2521b..ea93431 100644 --- a/docs/valueNodes/TupleValueNode.md +++ b/docs/valueNodes/TupleValueNode.md @@ -12,9 +12,10 @@ A concrete tuple value: a fixed-length sequence of positional value nodes. ### Children -| Attribute | Type | Description | -| --------- | ------------------------------- | -------------------------------------------- | -| `items` | [`ValueNode`](./ValueNode.md)[] | The positional items of the tuple, in order. | +| Attribute | Type | Description | +| --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `items` | [`ValueNode`](./ValueNode.md)[] | The positional items of the tuple, in order. | +| `plugins` | [`PluginNode`](../PluginNode.md)[] _(optional)_ | Namespaced plugins with custom structured data. The universal extension point for renderer-specific or not-yet-standardised metadata. | ## Examples diff --git a/generators/docs/generateDocs.ts b/generators/docs/generateDocs.ts index 40da440..de19ea9 100644 --- a/generators/docs/generateDocs.ts +++ b/generators/docs/generateDocs.ts @@ -19,7 +19,7 @@ export function generateDocs(spec: Spec): DocModel { function link(from: DocRef, to: DocRef): string { return relativePageLink(registry.lookup(from), registry.lookup(to)); } - const ctx: RenderCtx = { markup: markdownRenderer, registry, link }; + const ctx: RenderCtx = { markup: markdownRenderer, registry, link, base: spec.base?.attributes ?? [] }; const pages: DocPage[] = []; for (const category of spec.categories) { diff --git a/generators/docs/render/renderPages.ts b/generators/docs/render/renderPages.ts index c5c9955..376691f 100644 --- a/generators/docs/render/renderPages.ts +++ b/generators/docs/render/renderPages.ts @@ -30,6 +30,8 @@ export interface RenderCtx { readonly markup: MarkupRenderer; readonly registry: NavRegistry; readonly link: (from: DocRef, to: DocRef) => string; + /** Attributes shared by every node (the spec's base), rendered on each node page and the root page. */ + readonly base: readonly AttributeSpec[]; } /** Binds a page as the link source, so renderers resolve hrefs by target ref alone. */ @@ -42,10 +44,12 @@ export function renderNodePage(node: NodeSpec, ctx: RenderCtx): DocPage { const ref: DocRef = { kind: 'node', name: node.kind }; const linkTo = linkFrom(ctx, ref); - // classify: synthesized `kind` row first, then each attribute into Data or Children (declaration order) + // classify: synthesized `kind` row first, then each attribute into Data or Children (declaration order). + // Base attributes go through the same classification but always trail their table, mirroring the + // serialise-last convention — so the table order matches the wire order. const dataRows: string[][] = [[markup.code('kind'), markup.code(`"${node.kind}"`), 'The node discriminator.']]; const childRows: string[][] = []; - for (const attribute of node.attributes) { + for (const attribute of [...node.attributes, ...ctx.base]) { const row = [markup.code(attribute.name), typeCell(attribute, markup, linkTo), cellDoc(attribute.docs, markup)]; if (isDocChild(attribute.type)) { childRows.push(row); @@ -244,6 +248,8 @@ export function renderRootIndexPage(spec: Spec, ctx: RenderCtx): DocPage { `interchangeably. Pages marked ${markup.italic('(recursive)')} document nested unions: wrapper ` + `nodes that may nest before reaching a base type.`, ), + // base attributes shared by every node (omitted when the spec declares none) + renderBaseSection(spec, ctx, linkTo), // body: linked categories `${markup.heading(2, 'Categories')}${BLOCK_SEPARATOR}${markup.list('bulleted', categories)}`, // body: one section per root-level category (topLevel) @@ -256,6 +262,23 @@ export function renderRootIndexPage(spec: Spec, ctx: RenderCtx): DocPage { }; } +/** The root page's "Base attributes" section: the attributes every node carries, serialised last. */ +function renderBaseSection(spec: Spec, ctx: RenderCtx, linkTo: (r: DocRef) => string): string | undefined { + const { markup } = ctx; + if (!spec.base || spec.base.attributes.length === 0) return undefined; + const rows = spec.base.attributes.map(attribute => [ + markup.code(attribute.name), + typeCell(attribute, markup, linkTo), + cellDoc(attribute.docs, markup), + ]); + const parts: (string | undefined)[] = [ + markup.heading(2, 'Base attributes'), + renderSpecDocs(spec.base.docs, markup), + markup.table(['Attribute', 'Type', 'Description'], rows), + ]; + return parts.filter(Boolean).join(BLOCK_SEPARATOR); +} + /** A root-level category (no own directory, e.g. topLevel) as its own section: heading, docs, entity list. */ function renderRootCategorySection(category: CategorySpec, ctx: RenderCtx, linkTo: (r: DocRef) => string): string { const { markup } = ctx; diff --git a/spec.json b/spec.json index a1c73f1..a449972 100644 --- a/spec.json +++ b/spec.json @@ -1,5 +1,28 @@ { "version": "1.9.2", + "base": { + "docs": [ + "Attributes shared by every node.", + "Codegen targets append them after each node's declared attributes, so they always serialise last." + ], + "attributes": [ + { + "name": "plugins", + "type": { + "kind": "array", + "of": { + "kind": "node", + "name": "pluginNode" + } + }, + "optional": true, + "docs": [ + "Namespaced plugins with custom structured data.", + "The universal extension point for renderer-specific or not-yet-standardised metadata." + ] + } + ] + }, "categories": [ { "name": "type", @@ -6458,20 +6481,6 @@ "docs": [ "Display metadata describing how the instruction is presented." ] - }, - { - "name": "plugins", - "type": { - "kind": "array", - "of": { - "kind": "node", - "name": "pluginNode" - } - }, - "optional": true, - "docs": [ - "Namespaced plugins with custom structured data." - ] } ], "examples": [ @@ -6943,7 +6952,8 @@ "kind": "pluginNode", "docs": [ "Attaches named, plugin-specific data to a node.", - "A plugin is uniquely identified by its `name`; the optional `payload` carries arbitrary, consumer-defined data that only the matching plugin knows how to interpret. Codama itself treats the payload as opaque." + "A plugin is uniquely identified by its `name`; the optional `payload` carries arbitrary, consumer-defined data that only the matching plugin knows how to interpret. Codama itself treats the payload as opaque.", + "Every node can carry plugins via the `plugins` base attribute." ], "attributes": [ { diff --git a/src/api/defineBase.ts b/src/api/defineBase.ts new file mode 100644 index 0000000..46bf1e3 --- /dev/null +++ b/src/api/defineBase.ts @@ -0,0 +1,28 @@ +/** + * `defineBase(options)` — declares the attributes shared by every node of + * a spec (its "base node" shape). + * + * `attributes` is an ordered array of values produced by `attribute(...)` + * or `optionalAttribute(...)`, exactly as in `defineNode`. Codegen targets + * append them after each node's declared attributes, so base attributes + * always serialise last. Name collisions with any node's declared + * attributes are rejected by `validate`. + */ + +import type { AttributeSpec, BaseSpec, Docs } from './types'; + +export interface DefineBaseOptions { + readonly docs?: Docs; + /** + * Attributes shared by every node, in declaration order. Construct each + * entry via `attribute(...)` or `optionalAttribute(...)`. + */ + readonly attributes: readonly AttributeSpec[]; +} + +export function defineBase(options: DefineBaseOptions): BaseSpec { + return Object.freeze({ + ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}), + attributes: Object.freeze([...options.attributes]), + }); +} diff --git a/src/api/index.ts b/src/api/index.ts index 9153723..84d0644 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -7,6 +7,7 @@ export * from './attribute'; export * from './compounds'; +export * from './defineBase'; export * from './defineCategory'; export * from './defineEnumeration'; export * from './defineNestedUnion'; diff --git a/src/api/public.ts b/src/api/public.ts index b004583..a203988 100644 --- a/src/api/public.ts +++ b/src/api/public.ts @@ -10,6 +10,7 @@ export type { CodeBlock, CodeLanguage, DocExample, DocExamples } from './example'; export type { AttributeSpec, + BaseSpec, CategorySpec, Docs, EnumerationSpec, diff --git a/src/api/types.ts b/src/api/types.ts index 9882a92..2abf8f8 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -175,6 +175,20 @@ export interface NestedUnionSpec { readonly wrappers: readonly string[]; } +/** + * Attributes shared by every node of a spec — its "base node" shape. + * + * Codegen targets append these after each node's declared attributes (and + * after the implicit `kind` discriminator), so base attributes always + * serialise last. They may also emit a shared `BaseNode` interface that + * every generated node type extends. Base attribute names must not collide + * with any node's declared attributes — `validate` enforces this. + */ +export interface BaseSpec { + readonly attributes: readonly AttributeSpec[]; + readonly docs?: Docs; +} + /** * A category groups together a coherent set of nodes, unions, * enumerations, and nested unions. The category name doubles as a @@ -199,5 +213,7 @@ export interface CategorySpec { /** The full Codama spec for a single Codama major version. */ export interface Spec { readonly version: string; + /** Attributes shared by every node — absent when the spec declares none. */ + readonly base?: BaseSpec; readonly categories: readonly CategorySpec[]; } diff --git a/src/api/validate.ts b/src/api/validate.ts index f659f09..4d303e1 100644 --- a/src/api/validate.ts +++ b/src/api/validate.ts @@ -63,6 +63,29 @@ export function validate(spec: Spec): string[] { seenCategories.add(c.name); } + // Base-attribute validation: duplicates within the base, resolvable + // references, and no collisions with any node's declared attributes + // (base attributes are appended to every node by codegen targets). + const baseAttributes = spec.base?.attributes ?? []; + const baseAttributeNames = new Set(); + for (const a of baseAttributes) { + if (baseAttributeNames.has(a.name)) { + errors.push(`Base attribute "${a.name}" is declared more than once.`); + } + baseAttributeNames.add(a.name); + walkTypeExpr(a.type, expr => + checkRef( + expr, + `Base attribute "${a.name}":`, + errors, + nodeKinds, + unionNames, + enumerationNames, + nestedUnionNames, + ), + ); + } + // Per-node validation. for (const n of allNodes) { if (!NODE_KIND_REGEX.test(n.kind)) { @@ -74,8 +97,19 @@ export function validate(spec: Spec): string[] { errors.push(`Node "${n.kind}" declares attribute "${a.name}" more than once.`); } seenAttrs.add(a.name); + if (baseAttributeNames.has(a.name)) { + errors.push(`Node "${n.kind}" declares attribute "${a.name}", which collides with a base attribute.`); + } walkTypeExpr(a.type, expr => - checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames), + checkRef( + expr, + `Node "${n.kind}", attribute "${a.name}":`, + errors, + nodeKinds, + unionNames, + enumerationNames, + nestedUnionNames, + ), ); } } @@ -150,15 +184,13 @@ function walkTypeExpr(expr: TypeExpr, visit: (expr: TypeExpr) => void): void { function checkRef( expr: TypeExpr, - nodeKind: string, - attrName: string, + where: string, errors: string[], nodeKinds: Set, unionNames: Set, enumerationNames: Set, nestedUnionNames: Set, ): void { - const where = `Node "${nodeKind}", attribute "${attrName}":`; switch (expr.kind) { case 'node': if (!nodeKinds.has(expr.name)) { diff --git a/src/spec/index.ts b/src/spec/index.ts index 0c645dd..006c0ec 100644 --- a/src/spec/index.ts +++ b/src/spec/index.ts @@ -10,7 +10,7 @@ */ import type { CategorySpec, EnumerationSpec, NodeSpec, Spec, UnionSpec } from '../api'; -import { defineCategory, validate } from '../api'; +import { array, defineBase, defineCategory, node, optionalAttribute, validate } from '../api'; import { ALL_ENUMERATIONS } from './enumerations'; import { nestedTypeNode } from './nestedUnions'; import { accountNode } from './nodes/AccountNode'; @@ -43,6 +43,21 @@ import { SPEC_VERSION } from './version'; export * from '../api/public'; export { SPEC_VERSION } from './version'; +const BASE = defineBase({ + docs: [ + 'Attributes shared by every node.', + "Codegen targets append them after each node's declared attributes, so they always serialise last.", + ], + attributes: [ + optionalAttribute('plugins', array(node('pluginNode')), { + docs: [ + 'Namespaced plugins with custom structured data.', + 'The universal extension point for renderer-specific or not-yet-standardised metadata.', + ], + }), + ], +}); + const TYPE_CATEGORY = defineCategory('type', { docs: ['Type nodes — the building blocks of every value shape.'], nestedUnions: [nestedTypeNode], @@ -148,6 +163,7 @@ export function getSpec(): Spec { if (cached) return cached; const built: Spec = { version: SPEC_VERSION, + base: BASE, categories: ALL_CATEGORIES, }; const errors = validate(built); diff --git a/src/spec/nodes/InstructionNode.ts b/src/spec/nodes/InstructionNode.ts index cb1c298..46bb1f1 100644 --- a/src/spec/nodes/InstructionNode.ts +++ b/src/spec/nodes/InstructionNode.ts @@ -74,9 +74,6 @@ export const instructionNode = defineNode('instructionNode', { optionalAttribute('display', node('instructionDisplayNode'), { docs: ['Display metadata describing how the instruction is presented.'], }), - optionalAttribute('plugins', array(node('pluginNode')), { - docs: ['Namespaced plugins with custom structured data.'], - }), ], examples, }); diff --git a/src/spec/nodes/PluginNode.ts b/src/spec/nodes/PluginNode.ts index b512045..1c8fc2d 100644 --- a/src/spec/nodes/PluginNode.ts +++ b/src/spec/nodes/PluginNode.ts @@ -5,6 +5,7 @@ export const pluginNode = defineNode('pluginNode', { docs: [ 'Attaches named, plugin-specific data to a node.', 'A plugin is uniquely identified by its `name`; the optional `payload` carries arbitrary, consumer-defined data that only the matching plugin knows how to interpret. Codama itself treats the payload as opaque.', + 'Every node can carry plugins via the `plugins` base attribute.', ], attributes: [ attribute('name', stringIdentifier(), { diff --git a/tests/docs/docs.test.ts b/tests/docs/docs.test.ts index 0153692..4568c66 100644 --- a/tests/docs/docs.test.ts +++ b/tests/docs/docs.test.ts @@ -125,6 +125,21 @@ describe('docs generation over the real spec', () => { expect(root).toContain('- [`InstructionByteDeltaValue`](./InstructionByteDeltaValue.md)'); }); + it('renders the base attributes on the root index and at the end of every node page attribute tables', () => { + const root = rootContent(MODEL); + expect(root).toContain('## Base attributes'); + expect(root).toContain('`plugins`'); + + for (const page of MODEL.pages) { + if (page.ref.kind !== 'node') continue; + const where = `node page ${page.pathSegments.join('/')}`; + // plugins is child-classified, so every node page has a Children table ending with it + expect(page.content, `${where} should render the plugins base attribute`).toContain('`plugins`'); + const lastRow = page.content.split('## Examples')[0].trimEnd().split('\n').at(-1)!; + expect(lastRow, `${where} should list plugins as the last attribute row`).toContain('`plugins`'); + } + }); + it('renders the accountNode page with a Data/Children split and the nested-union data link', () => { const content = pageOf(MODEL, 'node', 'accountNode').content; expect(content.startsWith('# AccountNode')).toBe(true); diff --git a/tests/docs/renderPages.test.ts b/tests/docs/renderPages.test.ts index c21661d..26f6e0d 100644 --- a/tests/docs/renderPages.test.ts +++ b/tests/docs/renderPages.test.ts @@ -7,7 +7,7 @@ import type { DocRef, NavRegistry } from '../../generators/docs/types'; import type { EnumerationSpec, NodeSpec } from '../../src/api'; /** A minimal RenderCtx over the real markdown renderer - lookup returns fixed path segments, links resolve to '#'. */ -function makeCtx(): RenderCtx { +function makeCtx(overrides: Partial = {}): RenderCtx { const registry: NavRegistry = { entries: [], lookup: (ref: DocRef) => ({ ref, pathSegments: ['generated', 'page'] }), @@ -16,6 +16,8 @@ function makeCtx(): RenderCtx { markup: markdownRenderer, registry, link: () => '#', + base: [], + ...overrides, }; } @@ -41,6 +43,30 @@ describe('renderNodePage', () => { expect(page.content).toContain('`u64`'); }); + it('appends base attributes to the end of their classified table, mirroring the wire order', () => { + const node: NodeSpec = { + kind: 'numberValueNode', + attributes: [{ name: 'number', type: { kind: 'integer', width: 'u64' } }], + examples: [], + }; + const base = [ + { + name: 'plugins', + optional: true as const, + type: { kind: 'array', of: { kind: 'node', name: 'pluginNode' } } as const, + }, + ]; + + // plugins is child-classified, so the Children table materialises even without declared children + const withBase = renderNodePage(node, makeCtx({ base })); + expect(withBase.content).toContain('### Children'); + expect(withBase.content).toContain('`plugins`'); + + const withoutBase = renderNodePage(node, makeCtx()); + expect(withoutBase.content).not.toContain('### Children'); + expect(withoutBase.content).not.toContain('`plugins`'); + }); + it('escapes pipes from a literalUnion cell so union values do not spawn extra table columns', () => { const node: NodeSpec = { kind: 'sideNode', diff --git a/tests/spec.test.ts b/tests/spec.test.ts index b0aab90..7091181 100644 --- a/tests/spec.test.ts +++ b/tests/spec.test.ts @@ -479,15 +479,28 @@ describe('spec — pluginNode shape', () => { }); }); -describe('spec — instructionNode.plugins', () => { - it('declares an optional array of pluginNode', () => { - const n = getNode('instructionNode')!; - const plugins = n.attributes.find(a => a.name === 'plugins')!; - expect(plugins).toBeDefined(); +describe('spec — base attributes', () => { + it('declares plugins as the only base attribute, an optional array of pluginNode', () => { + const base = getSpec().base!; + expect(base).toBeDefined(); + expect(base.attributes.map(a => a.name)).toEqual(['plugins']); + + const plugins = base.attributes[0]; expect(plugins.optional).toBe(true); expect(plugins.type).toEqual({ kind: 'array', of: { kind: 'node', name: 'pluginNode' } }); expect(isChildAttribute(plugins.type)).toBe(true); }); + + it('no node declares a plugins attribute locally — the base attribute is universal', () => { + for (const category of getSpec().categories) { + for (const n of category.nodes) { + expect( + n.attributes.some(a => a.name === 'plugins'), + `node "${n.kind}" should not declare plugins locally`, + ).toBe(false); + } + } + }); }); describe('spec — instructionAccountNode.accountLink', () => { diff --git a/tests/validate.test.ts b/tests/validate.test.ts index 2671612..a83cd11 100644 --- a/tests/validate.test.ts +++ b/tests/validate.test.ts @@ -5,6 +5,7 @@ import { array, attribute, type CategorySpec, + defineBase, defineCategory, defineEnumeration, defineNestedUnion, @@ -268,6 +269,44 @@ describe('validate — categories', () => { }); }); +describe('validate — base attributes', () => { + const pluginsBase = () => defineBase({ attributes: [optionalAttribute('plugins', array(node('pluginNode')))] }); + + it('accepts a base whose references resolve and whose names are free', () => { + const errors = validate({ + ...baseSpec({ nodes: [defineNode('pluginNode', { attributes: [attribute('name', string())] })] }), + base: pluginsBase(), + }); + expect(errors).toEqual([]); + }); + + it('reports a base attribute referencing an undefined node', () => { + const errors = validate({ ...baseSpec(), base: pluginsBase() }); + expect(errors.some(e => e.includes('Base attribute "plugins"') && e.includes('"pluginNode"'))).toBe(true); + }); + + it('reports a duplicate base attribute', () => { + const errors = validate({ + ...baseSpec(), + base: defineBase({ attributes: [attribute('docs', string()), attribute('docs', string())] }), + }); + expect(errors.some(e => e.includes('Base attribute "docs"') && e.includes('more than once'))).toBe(true); + }); + + it('reports a node attribute colliding with a base attribute', () => { + const errors = validate({ + ...baseSpec({ + nodes: [ + defineNode('pluginNode', { attributes: [attribute('name', string())] }), + defineNode('aNode', { attributes: [attribute('plugins', string())] }), + ], + }), + base: pluginsBase(), + }); + expect(errors.some(e => e.includes('"aNode"') && e.includes('collides with a base attribute'))).toBe(true); + }); +}); + describe('validate — enumerations', () => { it('accepts a valid enumeration referenced by a node', () => { const enumSpec = defineEnumeration('e', { variants: [variant('a'), variant('b')] });