Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .changeset/proud-queens-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@codama/node-types': minor
'@codama/nodes-from-anchor': patch
---

Regenerate the entire `@codama/node-types` source surface from the encoded `@codama/spec` description, via the new private `@codama-internal/spec-generators` package.

The bulk of the surface lives under `src/generated/` and is produced by the `gen-ts-node-types` generator from the spec. The previously hand-maintained interfaces are gone; every node, union, enumeration, and per-spec shared type is rebuilt from the spec on every `pnpm generate` run.

A small set of static helpers — the brand types, the `Docs` alias, and the `Version` template-literal type — live as hand-written sibling files at the top of `packages/node-types/src/`, alongside the existing `ProgramVersion` deprecated alias. They are imported by the generated surface but never regenerated, since their content doesn't depend on the spec. The generator wipes only `src/generated/` on every run; hand-written content at the top level survives. The per-spec `CodamaVersion` literal stays generated, in its own `src/generated/shared/codamaVersion.ts` file pinned to the spec version at generation time.

Most of the rebuild is structural: imports now point at per-file paths (`./linkNodes/PdaLinkNode`) instead of subdirectory barrels, every interface and field carries a JSDoc block sourced from the spec, and array fields are emitted as `Array<T>` rather than `T[]` so an inline-union element type doesn't need extra parentheses to preserve precedence. A handful of named API differences also shake out from this:

- `accountNode.size` is now typed as `number | undefined` (the previous `| null` arm had no consumer and is dropped).
- `programNode.origin` is now typed as the named `ProgramOrigin` union (`'anchor' | 'shank'`) instead of an inline literal union.
- `instructionAccountNode.isSigner` and `instructionRemainingAccountsNode.isSigner` now read `boolean | 'either'` instead of `true | false | 'either'` (a TypeScript-only readability normalisation; the encoded spec keeps the explicit `true | false` form so other codegen targets can still emit a multi-variant enum).
- `numberTypeNode.format` and `stringTypeNode.encoding` are emitted as named `NumberFormat` / `BytesEncoding` aliases imported from `./shared/`, with the same generic-narrowing behaviour preserved.
- `programNode.version` is now typed as the unified `Version` template-literal alias (`` `${number}.${number}.${number}` ``) — a tighter shape than the previous plain string, so non-conforming literal strings will now surface as TypeScript errors at the call site. The historical `ProgramVersion` name is preserved as a hand-written `@deprecated` re-export so existing consumers continue to compile; `@codama/nodes-from-anchor` is updated to import `Version` directly.
- `docs?` fields use a `Docs = Array<string>` alias mirroring the `'docs'` `TypeExpr` kind in `@codama/spec`. The alias is hand-written and lives at `packages/node-types/src/Docs.ts`.
- Documentation strings that ship as multiple paragraphs in the spec now render as multi-paragraph JSDoc blocks. Affected fields and types include `accountNode.discriminators`, `instructionNode.discriminators`, `instructionAccountNode.isSigner`, `instructionRemainingAccountsNode.isSigner`, `rootNode`, the `ConditionalValueNode` interface and its `condition`, `InstructionInputValueNode`, `ResolverValueNode`, `AmountTypeNode` and its `unit`, `MapTypeNode.size`, `NestedTypeNode`, `StringTypeNode.size`, `EnumValueNode.value`, and `NumberValueNode.number`.

Alongside the per-node interfaces, the package now exports seven `Registered<Category>Node` category-registry unions (`RegisteredContextualValueNode`, `RegisteredCountNode`, `RegisteredDiscriminatorNode`, `RegisteredLinkNode`, `RegisteredPdaSeedNode`, `RegisteredTypeNode`, `RegisteredValueNode`) corresponding one-to-one with `@codama/spec`'s category registries, plus a `GetNodeFromKind<TKind extends NodeKind>` helper that resolves to the concrete interface for a given kind. The registry unions are the recommended extension point for downstream packages that need to introduce custom node kinds.

The generator consumes `@codama/spec@1.6.0-rc.4`, which reshapes the spec into per-category groups (`spec.categories[]`) and renames the `nestedTypeNode` `TypeExpr` kind to `nestedUnion` (with an explicit `alias` field). All `docs?` fields throughout the spec are arrays of paragraph strings rather than single newline-separated strings — the renderer accepts the array shape directly. Internally, the generator's renderers are layout-agnostic: they emit `use(...)` calls keyed by symbolic module strings (e.g. `'node:numberTypeNode'`, `'enumeration:Endianness'`, `'brand:CamelCaseString'`), and a single per-spec `RenderScope` resolves those symbolic keys to concrete file locations at write time. Adding a new file kind to the generator means extending the `RenderScope` symbol map; renderers themselves stay free of file-layout knowledge.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"private": true,
"scripts": {
"build": "turbo run build --log-order grouped",
"generate": "pnpm --filter @codama-internal/spec-generators generate",
"lint": "turbo run lint --log-order grouped",
"lint:fix": "turbo lint:fix --log-order grouped && pnpm prettier --ignore-unknown --write '{.,!packages}/*'",
"test": "turbo run test --log-order grouped",
Expand Down
22 changes: 0 additions & 22 deletions packages/node-types/src/AccountNode.ts

This file was deleted.

13 changes: 0 additions & 13 deletions packages/node-types/src/DefinedTypeNode.ts

This file was deleted.

12 changes: 12 additions & 0 deletions packages/node-types/src/Docs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Hand-written `Docs` alias used by every `docs?` field in the generated
* node-type surface.
*
* Lives outside `./generated/` because it's a static type alias — there's
* nothing the spec contributes beyond the array shape itself. The
* generator's symbol map points at this file when emitting `import type
* { Docs } from '../Docs';` lines.
*/

/** Markdown documentation for a node — one paragraph per array entry. */
export type Docs = Array<string>;
11 changes: 0 additions & 11 deletions packages/node-types/src/ErrorNode.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/node-types/src/EventNode.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/node-types/src/InstructionAccountNode.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/node-types/src/InstructionArgumentNode.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/node-types/src/InstructionByteDeltaNode.ts

This file was deleted.

40 changes: 0 additions & 40 deletions packages/node-types/src/InstructionNode.ts

This file was deleted.

17 changes: 0 additions & 17 deletions packages/node-types/src/InstructionRemainingAccountsNode.ts

This file was deleted.

9 changes: 0 additions & 9 deletions packages/node-types/src/InstructionStatusNode.ts

This file was deleted.

14 changes: 0 additions & 14 deletions packages/node-types/src/PdaNode.ts

This file was deleted.

36 changes: 0 additions & 36 deletions packages/node-types/src/ProgramNode.ts

This file was deleted.

10 changes: 10 additions & 0 deletions packages/node-types/src/ProgramVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Version } from './Version';

/**
* Hand-written compatibility alias for the program version string.
*
* @deprecated Use `Version` instead. This alias is kept so existing
* imports continue to compile and will be removed in a future major
* release.
*/
export type ProgramVersion = Version;
17 changes: 0 additions & 17 deletions packages/node-types/src/RootNode.ts

This file was deleted.

12 changes: 12 additions & 0 deletions packages/node-types/src/Version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Hand-written `Version` alias — a semver-shaped template-literal type
* used wherever the generated surface needs to validate that a string
* looks like a version number.
*
* Lives outside `./generated/` because it's static. The per-spec
* `CodamaVersion` literal — which pins to the spec version at generation
* time — stays under `./generated/shared/`.
*/

/** A semver-shaped version string (e.g. "1.6.0"). */
export type Version = `${number}.${number}.${number}`;
39 changes: 39 additions & 0 deletions packages/node-types/src/brands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Hand-written branded string types used throughout the generated
* node-type surface to mark identifiers that must conform to a specific
* casing convention.
*
* These types live outside `./generated/` because they're static — they
* never change with the spec — so there's nothing to regenerate. The
* generator's symbol map points at this file when emitting `import type
* { CamelCaseString } from '../brands';` lines.
*
* The brand is purely a TypeScript marker; runtime parsing and
* validation happen wherever string identifiers cross the package
* boundary.
*/

/** A string asserted to be in camelCase form. */
export type CamelCaseString = string & {
readonly ['__stringCase:codama']: 'camelCase';
};

/** A string asserted to be in kebabCase form. */
export type KebabCaseString = string & {
readonly ['__stringCase:codama']: 'kebabCase';
};

/** A string asserted to be in pascalCase form. */
export type PascalCaseString = string & {
readonly ['__stringCase:codama']: 'pascalCase';
};

/** A string asserted to be in snakeCase form. */
export type SnakeCaseString = string & {
readonly ['__stringCase:codama']: 'snakeCase';
};

/** A string asserted to be in titleCase form. */
export type TitleCaseString = string & {
readonly ['__stringCase:codama']: 'titleCase';
};

This file was deleted.

This file was deleted.

Loading
Loading