@codama/spec 1.6.0-rc.3 → 1.6.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -0
- package/dist/api.browser.cjs +94 -27
- package/dist/api.browser.cjs.map +1 -1
- package/dist/api.browser.mjs +91 -27
- package/dist/api.browser.mjs.map +1 -1
- package/dist/api.node.cjs +94 -27
- package/dist/api.node.cjs.map +1 -1
- package/dist/api.node.mjs +91 -27
- package/dist/api.node.mjs.map +1 -1
- package/dist/api.react-native.mjs +91 -27
- package/dist/api.react-native.mjs.map +1 -1
- package/dist/index.browser.cjs +791 -568
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +791 -568
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.cjs +791 -568
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +791 -568
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.react-native.mjs +791 -568
- package/dist/index.react-native.mjs.map +1 -1
- package/dist/types/api/attribute.d.ts +2 -2
- package/dist/types/api/attribute.d.ts.map +1 -1
- package/dist/types/api/defineCategory.d.ts +19 -0
- package/dist/types/api/defineCategory.d.ts.map +1 -0
- package/dist/types/api/defineEnumeration.d.ts +2 -2
- package/dist/types/api/defineEnumeration.d.ts.map +1 -1
- package/dist/types/api/defineNestedUnion.d.ts +29 -0
- package/dist/types/api/defineNestedUnion.d.ts.map +1 -0
- package/dist/types/api/defineNode.d.ts +2 -2
- package/dist/types/api/defineNode.d.ts.map +1 -1
- package/dist/types/api/defineUnion.d.ts +2 -2
- package/dist/types/api/defineUnion.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +6 -4
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/primitives.d.ts +14 -4
- package/dist/types/api/primitives.d.ts.map +1 -1
- package/dist/types/api/public.d.ts +1 -1
- package/dist/types/api/public.d.ts.map +1 -1
- package/dist/types/api/types.d.ts +78 -24
- package/dist/types/api/types.d.ts.map +1 -1
- package/dist/types/api/validate.d.ts +4 -5
- package/dist/types/api/validate.d.ts.map +1 -1
- package/dist/types/v1/enumerations.d.ts.map +1 -1
- package/dist/types/v1/index.d.ts.map +1 -1
- package/dist/types/v1/nestedUnions.d.ts +9 -0
- package/dist/types/v1/nestedUnions.d.ts.map +1 -0
- package/dist/types/v1/nodes/AccountNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/EventNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/InstructionAccountNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/InstructionByteDeltaNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/InstructionNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/InstructionRemainingAccountsNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/InstructionStatusNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/PdaNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/ProgramNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/RootNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/contextualValueNodes/ConditionalValueNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/contextualValueNodes/ContextualValueNode.d.ts +2 -2
- package/dist/types/v1/nodes/contextualValueNodes/ContextualValueNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/contextualValueNodes/ResolverValueNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/linkNodes/InstructionAccountLinkNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/linkNodes/InstructionArgumentLinkNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/linkNodes/InstructionLinkNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/pdaSeedNodes/PdaSeedNode.d.ts +1 -1
- package/dist/types/v1/nodes/typeNodes/AmountTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/ArrayTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/BytesTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/DateTimeTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/EnumEmptyVariantTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/EnumStructVariantTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/EnumTupleVariantTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/HiddenPrefixTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/HiddenSuffixTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/MapTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/OptionTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/PostOffsetTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/PreOffsetTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/RemainderOptionTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/SentinelTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/SetTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/StringTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/StructTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/typeNodes/TypeNode.d.ts +4 -4
- package/dist/types/v1/nodes/typeNodes/ZeroableOptionTypeNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/valueNodes/EnumValueNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/valueNodes/NumberValueNode.d.ts.map +1 -1
- package/dist/types/v1/nodes/valueNodes/ValueNode.d.ts +4 -4
- package/dist/v1.browser.cjs +791 -568
- package/dist/v1.browser.cjs.map +1 -1
- package/dist/v1.browser.mjs +791 -568
- package/dist/v1.browser.mjs.map +1 -1
- package/dist/v1.node.cjs +791 -568
- package/dist/v1.node.cjs.map +1 -1
- package/dist/v1.node.mjs +791 -568
- package/dist/v1.node.mjs.map +1 -1
- package/dist/v1.react-native.mjs +791 -568
- package/dist/v1.react-native.mjs.map +1 -1
- package/package.json +45 -31
- package/dist/types/v1/nestedTypeNodeWrappers.d.ts +0 -10
- package/dist/types/v1/nestedTypeNodeWrappers.d.ts.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Codama Spec
|
|
2
|
+
|
|
3
|
+
The canonical Codama node specification.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Codama is a standard for describing on-chain Solana programs as a graph of typed nodes (accounts, instructions, types, …). This repository contains:
|
|
8
|
+
|
|
9
|
+
- **The spec.** A machine-readable description of every node in the Codama node graph, authored in TypeScript under `src/` and emitted as `v1/spec.json`. Future Codama majors will land alongside as `v2/spec.json`, `v3/spec.json`, …
|
|
10
|
+
- **The meta-model API.** Authoring helpers (`defineNode`, `attribute`, primitives, compounds, …) exposed at `@codama/spec/api` for hand-authoring specs and test fixtures.
|
|
11
|
+
- **Internal codegen.** Generators under `generators/` produce the public artifacts that mirror each spec major (`v<n>/spec.json`, `v<n>/schema.json`, `v<n>/docs/`). They are not exported from the `@codama/spec` package; they exist as internal tooling for this repo.
|
|
12
|
+
|
|
13
|
+
Reference implementations (TypeScript node types, node factories, visitors, validators, renderers, the CLI) live in [codama-idl/codama](https://github.com/codama-idl/codama) and consume the published `@codama/spec` package. The Rust reference implementation lives in [codama-idl/codama-rs](https://github.com/codama-idl/codama-rs).
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
pnpm add @codama/spec
|
|
19
|
+
# or: npm install @codama/spec
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
`@codama/spec` exposes three entrypoints:
|
|
25
|
+
|
|
26
|
+
- `@codama/spec` — the latest stable major's public surface. Re-exports `@codama/spec/v1` today; will track future majors.
|
|
27
|
+
- `@codama/spec/v1` — the v1 spec data, accessors (`getSpec`, `getNode`, `getUnion`, `getEnumeration`), and the version-agnostic types (`NodeSpec`, `UnionSpec`, …).
|
|
28
|
+
- `@codama/spec/api` — the meta-model authoring API (`defineNode`, `attribute`, primitives, compounds, …) for hand-authoring specs and test fixtures.
|
|
29
|
+
|
|
30
|
+
### Read the spec
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { getSpec, getNode, SPEC_VERSION } from '@codama/spec/v1';
|
|
34
|
+
|
|
35
|
+
const spec = getSpec();
|
|
36
|
+
console.log(spec.version); // → '1.6.0'
|
|
37
|
+
console.log(SPEC_VERSION); // → '1.6.0'
|
|
38
|
+
|
|
39
|
+
const account = getNode('accountNode');
|
|
40
|
+
console.log(account?.attributes.map(a => a.name));
|
|
41
|
+
// → ['name', 'size', 'docs', 'data', 'pda', 'discriminators']
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Hand-author a node
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { attribute, defineNode, string, u32 } from '@codama/spec/api';
|
|
48
|
+
|
|
49
|
+
const myNode = defineNode('myNode', {
|
|
50
|
+
docs: ['A custom node, hand-authored.'],
|
|
51
|
+
attributes: [attribute('name', string()), attribute('size', u32(), { docs: ['Size in bytes.'] })],
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Repository layout
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
src/ # package source (the @codama/spec public surface)
|
|
59
|
+
tests/ # package tests
|
|
60
|
+
generators/ # internal codegen orchestrator + per-target generators
|
|
61
|
+
index.ts # runs every registered generator sequentially
|
|
62
|
+
json-spec/ # emits v<n>/spec.json
|
|
63
|
+
json-schema/ # emits v<n>/schema.json (stub)
|
|
64
|
+
docs/ # emits v<n>/docs/ (stub)
|
|
65
|
+
v1/ # generated artifacts mirroring the @codama/spec/v1 surface
|
|
66
|
+
spec.json
|
|
67
|
+
schema.json
|
|
68
|
+
docs/
|
|
69
|
+
.changeset/ # release intent files (managed by @changesets/cli)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Releasing
|
|
73
|
+
|
|
74
|
+
`@codama/spec` is released through [changesets](https://github.com/changesets/changesets):
|
|
75
|
+
|
|
76
|
+
1. Run `pnpm changeset` on your branch to record a bump and a user-facing summary.
|
|
77
|
+
2. Commit the generated `.changeset/*.md` alongside your changes.
|
|
78
|
+
3. On merge to `main`, the [`Main` workflow](./.github/workflows/main.yml) either opens a "Release package" PR (when changesets are pending) or publishes `@codama/spec` to npm (when versions have been bumped).
|
|
79
|
+
|
|
80
|
+
The repo is currently in **release-candidate mode** under the `rc` tag (see `.changeset/pre.json`). Every `pnpm changeset version` produces a `1.6.0-rc.N` version. To cut the stable release, run `pnpm changeset pre exit`, then `pnpm changeset version` and merge the resulting "Release package" PR.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
[MIT](./LICENSE) — same as the rest of the Codama ecosystem.
|
package/dist/api.browser.cjs
CHANGED
|
@@ -6,7 +6,7 @@ function attribute(name, type, options = {}) {
|
|
|
6
6
|
name,
|
|
7
7
|
type,
|
|
8
8
|
...options.optional ? { optional: true } : {},
|
|
9
|
-
...options.docs !== void 0 ? { docs: options.docs } : {}
|
|
9
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
function optionalAttribute(name, type, options = {}) {
|
|
@@ -21,11 +21,23 @@ function tuple(...items) {
|
|
|
21
21
|
return Object.freeze({ kind: "tuple", items: Object.freeze([...items]) });
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// src/api/defineCategory.ts
|
|
25
|
+
function defineCategory(name, options = {}) {
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
name,
|
|
28
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
|
|
29
|
+
nodes: Object.freeze([...options.nodes ?? []]),
|
|
30
|
+
unions: Object.freeze([...options.unions ?? []]),
|
|
31
|
+
enumerations: Object.freeze([...options.enumerations ?? []]),
|
|
32
|
+
nestedUnions: Object.freeze([...options.nestedUnions ?? []])
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
// src/api/defineEnumeration.ts
|
|
25
37
|
function variant(name, options = {}) {
|
|
26
38
|
return Object.freeze({
|
|
27
39
|
name,
|
|
28
|
-
...options.docs !== void 0 ? { docs: options.docs } : {}
|
|
40
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
|
|
29
41
|
});
|
|
30
42
|
}
|
|
31
43
|
function defineEnumeration(name, options) {
|
|
@@ -42,7 +54,17 @@ function defineEnumeration(name, options) {
|
|
|
42
54
|
return Object.freeze({
|
|
43
55
|
name,
|
|
44
56
|
variants: Object.freeze([...options.variants]),
|
|
45
|
-
...options.docs !== void 0 ? { docs: options.docs } : {}
|
|
57
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/api/defineNestedUnion.ts
|
|
62
|
+
function defineNestedUnion(name, options) {
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
name,
|
|
65
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
|
|
66
|
+
base: options.base,
|
|
67
|
+
wrappers: Object.freeze([...options.wrappers])
|
|
46
68
|
});
|
|
47
69
|
}
|
|
48
70
|
|
|
@@ -50,7 +72,7 @@ function defineEnumeration(name, options) {
|
|
|
50
72
|
function defineNode(kind, options) {
|
|
51
73
|
return Object.freeze({
|
|
52
74
|
kind,
|
|
53
|
-
...options.docs !== void 0 ? { docs: options.docs } : {},
|
|
75
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {},
|
|
54
76
|
attributes: Object.freeze([...options.attributes]),
|
|
55
77
|
examples: Object.freeze([...options.examples ?? []])
|
|
56
78
|
});
|
|
@@ -62,7 +84,7 @@ function defineUnion(name, options) {
|
|
|
62
84
|
return Object.freeze({
|
|
63
85
|
name,
|
|
64
86
|
members: Object.freeze(normalised),
|
|
65
|
-
...options.docs !== void 0 ? { docs: options.docs } : {}
|
|
87
|
+
...options.docs !== void 0 ? { docs: Object.freeze([...options.docs]) } : {}
|
|
66
88
|
});
|
|
67
89
|
}
|
|
68
90
|
function normaliseMember(input) {
|
|
@@ -77,6 +99,9 @@ function normaliseMember(input) {
|
|
|
77
99
|
}
|
|
78
100
|
|
|
79
101
|
// src/api/primitives.ts
|
|
102
|
+
function address() {
|
|
103
|
+
return Object.freeze({ kind: "address" });
|
|
104
|
+
}
|
|
80
105
|
function string() {
|
|
81
106
|
return Object.freeze({ kind: "string" });
|
|
82
107
|
}
|
|
@@ -131,8 +156,8 @@ function node(name) {
|
|
|
131
156
|
function union(name) {
|
|
132
157
|
return Object.freeze({ kind: "union", name });
|
|
133
158
|
}
|
|
134
|
-
function
|
|
135
|
-
return Object.freeze({ kind: "
|
|
159
|
+
function nestedUnion(alias, name) {
|
|
160
|
+
return Object.freeze({ kind: "nestedUnion", alias, name });
|
|
136
161
|
}
|
|
137
162
|
|
|
138
163
|
// src/api/semanticAliases.ts
|
|
@@ -150,26 +175,46 @@ function docs() {
|
|
|
150
175
|
}
|
|
151
176
|
|
|
152
177
|
// src/api/validate.ts
|
|
178
|
+
var CAMEL_CASE_REGEX = /^[a-z][A-Za-z0-9]*$/;
|
|
179
|
+
var NODE_KIND_REGEX = /^[a-z][A-Za-z0-9]*Node$/;
|
|
153
180
|
function validate(spec) {
|
|
154
181
|
const errors = [];
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
const
|
|
182
|
+
const allNodes = [];
|
|
183
|
+
const allUnions = [];
|
|
184
|
+
const allEnumerations = [];
|
|
185
|
+
const allNestedUnions = [];
|
|
186
|
+
for (const c of spec.categories) {
|
|
187
|
+
allNodes.push(...c.nodes);
|
|
188
|
+
allUnions.push(...c.unions);
|
|
189
|
+
allEnumerations.push(...c.enumerations);
|
|
190
|
+
allNestedUnions.push(...c.nestedUnions);
|
|
191
|
+
}
|
|
192
|
+
const nodeKinds = new Set(allNodes.map((n) => n.kind));
|
|
193
|
+
const unionNames = new Set(allUnions.map((u) => u.name));
|
|
194
|
+
const enumerationNames = new Set(allEnumerations.map((e) => e.name));
|
|
195
|
+
const nestedUnionNames = new Set(allNestedUnions.map((nu) => nu.name));
|
|
159
196
|
const registrations = /* @__PURE__ */ new Map();
|
|
160
197
|
const record = (name, kind) => {
|
|
161
198
|
const list = registrations.get(name);
|
|
162
199
|
if (list) list.push(kind);
|
|
163
200
|
else registrations.set(name, [kind]);
|
|
164
201
|
};
|
|
165
|
-
for (const n of
|
|
166
|
-
for (const u of
|
|
167
|
-
for (const e of
|
|
202
|
+
for (const n of allNodes) record(n.kind, "node");
|
|
203
|
+
for (const u of allUnions) record(u.name, "union");
|
|
204
|
+
for (const e of allEnumerations) record(e.name, "enumeration");
|
|
205
|
+
for (const nu of allNestedUnions) record(nu.name, "nestedUnion");
|
|
168
206
|
for (const [name, kinds] of registrations) {
|
|
169
207
|
if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));
|
|
170
208
|
}
|
|
171
|
-
|
|
172
|
-
|
|
209
|
+
const seenCategories = /* @__PURE__ */ new Set();
|
|
210
|
+
for (const c of spec.categories) {
|
|
211
|
+
if (seenCategories.has(c.name)) {
|
|
212
|
+
errors.push(`Category "${c.name}" is declared more than once.`);
|
|
213
|
+
}
|
|
214
|
+
seenCategories.add(c.name);
|
|
215
|
+
}
|
|
216
|
+
for (const n of allNodes) {
|
|
217
|
+
if (!NODE_KIND_REGEX.test(n.kind)) {
|
|
173
218
|
errors.push(`Node kind "${n.kind}" does not match the camelCase ...Node naming convention.`);
|
|
174
219
|
}
|
|
175
220
|
const seenAttrs = /* @__PURE__ */ new Set();
|
|
@@ -180,11 +225,14 @@ function validate(spec) {
|
|
|
180
225
|
seenAttrs.add(a.name);
|
|
181
226
|
walkTypeExpr(
|
|
182
227
|
a.type,
|
|
183
|
-
(expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames)
|
|
228
|
+
(expr) => checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames)
|
|
184
229
|
);
|
|
185
230
|
}
|
|
186
231
|
}
|
|
187
|
-
for (const u of
|
|
232
|
+
for (const u of allUnions) {
|
|
233
|
+
if (!CAMEL_CASE_REGEX.test(u.name)) {
|
|
234
|
+
errors.push(`Union "${u.name}" does not match the camelCase naming convention.`);
|
|
235
|
+
}
|
|
188
236
|
if (u.members.length === 0) {
|
|
189
237
|
errors.push(`Union "${u.name}" has no members.`);
|
|
190
238
|
}
|
|
@@ -203,9 +251,22 @@ function validate(spec) {
|
|
|
203
251
|
}
|
|
204
252
|
}
|
|
205
253
|
}
|
|
206
|
-
for (const
|
|
207
|
-
if (!
|
|
208
|
-
errors.push(`
|
|
254
|
+
for (const e of allEnumerations) {
|
|
255
|
+
if (!CAMEL_CASE_REGEX.test(e.name)) {
|
|
256
|
+
errors.push(`Enumeration "${e.name}" does not match the camelCase naming convention.`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
for (const nu of allNestedUnions) {
|
|
260
|
+
if (!CAMEL_CASE_REGEX.test(nu.name)) {
|
|
261
|
+
errors.push(`Nested union "${nu.name}" does not match the camelCase naming convention.`);
|
|
262
|
+
}
|
|
263
|
+
if (nu.wrappers.length === 0) {
|
|
264
|
+
errors.push(`Nested union "${nu.name}" has no wrappers.`);
|
|
265
|
+
}
|
|
266
|
+
for (const w of nu.wrappers) {
|
|
267
|
+
if (!nodeKinds.has(w)) {
|
|
268
|
+
errors.push(`Nested union "${nu.name}" wrapper "${w}" is not a defined node.`);
|
|
269
|
+
}
|
|
209
270
|
}
|
|
210
271
|
}
|
|
211
272
|
return errors;
|
|
@@ -214,7 +275,7 @@ function formatCollisionError(name, kinds) {
|
|
|
214
275
|
const counts = /* @__PURE__ */ new Map();
|
|
215
276
|
for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);
|
|
216
277
|
const breakdown = [...counts.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([k, n]) => `${n} ${k}${n > 1 ? "s" : ""}`).join(", ");
|
|
217
|
-
return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, and
|
|
278
|
+
return `Name "${name}" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, enumerations, and nested unions.`;
|
|
218
279
|
}
|
|
219
280
|
function walkTypeExpr(expr, visit) {
|
|
220
281
|
visit(expr);
|
|
@@ -224,7 +285,7 @@ function walkTypeExpr(expr, visit) {
|
|
|
224
285
|
for (const item of expr.items) walkTypeExpr(item, visit);
|
|
225
286
|
}
|
|
226
287
|
}
|
|
227
|
-
function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames) {
|
|
288
|
+
function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames) {
|
|
228
289
|
const where = `Node "${nodeKind}", attribute "${attrName}":`;
|
|
229
290
|
switch (expr.kind) {
|
|
230
291
|
case "node":
|
|
@@ -242,9 +303,12 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
|
|
|
242
303
|
errors.push(`${where} references undefined enumeration "${expr.name}".`);
|
|
243
304
|
}
|
|
244
305
|
break;
|
|
245
|
-
case "
|
|
306
|
+
case "nestedUnion":
|
|
246
307
|
if (!nodeKinds.has(expr.name)) {
|
|
247
|
-
errors.push(`${where}
|
|
308
|
+
errors.push(`${where} nestedUnion references undefined node "${expr.name}".`);
|
|
309
|
+
}
|
|
310
|
+
if (!nestedUnionNames.has(expr.alias)) {
|
|
311
|
+
errors.push(`${where} nestedUnion references undefined alias "${expr.alias}".`);
|
|
248
312
|
}
|
|
249
313
|
break;
|
|
250
314
|
}
|
|
@@ -252,7 +316,7 @@ function checkRef(expr, nodeKind, attrName, errors, nodeKinds, unionNames, enume
|
|
|
252
316
|
function isChildAttribute(type) {
|
|
253
317
|
switch (type.kind) {
|
|
254
318
|
case "node":
|
|
255
|
-
case "
|
|
319
|
+
case "nestedUnion":
|
|
256
320
|
case "union":
|
|
257
321
|
return true;
|
|
258
322
|
case "array":
|
|
@@ -264,6 +328,7 @@ function isChildAttribute(type) {
|
|
|
264
328
|
}
|
|
265
329
|
}
|
|
266
330
|
|
|
331
|
+
exports.address = address;
|
|
267
332
|
exports.array = array;
|
|
268
333
|
exports.attribute = attribute;
|
|
269
334
|
exports.boolean = boolean;
|
|
@@ -271,7 +336,9 @@ exports.byteOffset = byteOffset;
|
|
|
271
336
|
exports.byteSize = byteSize;
|
|
272
337
|
exports.codamaVersion = codamaVersion;
|
|
273
338
|
exports.count = count;
|
|
339
|
+
exports.defineCategory = defineCategory;
|
|
274
340
|
exports.defineEnumeration = defineEnumeration;
|
|
341
|
+
exports.defineNestedUnion = defineNestedUnion;
|
|
275
342
|
exports.defineNode = defineNode;
|
|
276
343
|
exports.defineUnion = defineUnion;
|
|
277
344
|
exports.docs = docs;
|
|
@@ -286,7 +353,7 @@ exports.i8 = i8;
|
|
|
286
353
|
exports.isChildAttribute = isChildAttribute;
|
|
287
354
|
exports.literal = literal;
|
|
288
355
|
exports.literalUnion = literalUnion;
|
|
289
|
-
exports.
|
|
356
|
+
exports.nestedUnion = nestedUnion;
|
|
290
357
|
exports.node = node;
|
|
291
358
|
exports.optionalAttribute = optionalAttribute;
|
|
292
359
|
exports.string = string;
|
package/dist/api.browser.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/attribute.ts","../src/api/compounds.ts","../src/api/defineEnumeration.ts","../src/api/defineNode.ts","../src/api/defineUnion.ts","../src/api/primitives.ts","../src/api/semanticAliases.ts","../src/api/validate.ts"],"names":[],"mappings":"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","file":"api.browser.cjs","sourcesContent":["/**\n * Attribute factories — produce frozen `AttributeSpec` values directly.\n *\n * Every attribute of a node MUST be constructed via one of these helpers.\n * The returned value IS the encoded form; `defineNode` consumes them as-is.\n */\n\nimport type { AttributeSpec, TypeExpr } from './types';\n\nexport interface AttributeOptions {\n /** Free-form prose description for codegen / docs. */\n readonly docs?: string;\n /** When `true`, the attribute may be absent in encoded values. */\n readonly optional?: boolean;\n}\n\n/**\n * Declare an attribute. The default is a required attribute; pass\n * `{ optional: true }` (or use `optionalAttribute`) to mark it optional.\n */\nexport function attribute(name: string, type: TypeExpr, options: AttributeOptions = {}): AttributeSpec {\n return Object.freeze({\n name,\n type,\n ...(options.optional ? { optional: true as const } : {}),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\n/**\n * Sugar for `attribute(name, type, { optional: true, ...rest })` — the most\n * common attribute shape after required ones.\n */\nexport function optionalAttribute(\n name: string,\n type: TypeExpr,\n options: Omit<AttributeOptions, 'optional'> = {},\n): AttributeSpec {\n return attribute(name, type, { ...options, optional: true });\n}\n","/**\n * Compound type-expression constructors — wrap or combine other type\n * expressions. Returned values are frozen.\n *\n * Optionality is intentionally NOT a compound: it's an attribute-level\n * concern, expressed via `optionalAttribute(...)` or\n * `attribute(..., { optional: true })`.\n */\n\nimport type { TypeExpr } from './types';\n\n/** An array (homogeneous list) of `inner`. */\nexport function array(inner: TypeExpr): TypeExpr {\n return Object.freeze({ kind: 'array' as const, of: inner });\n}\n\n/**\n * A heterogeneous fixed-length tuple. Each positional slot has its own type.\n *\n * Tuples use `items` (plural) rather than `of` to signal cardinality > 1.\n */\nexport function tuple(...items: TypeExpr[]): TypeExpr {\n return Object.freeze({ kind: 'tuple' as const, items: Object.freeze([...items]) });\n}\n","/**\n * `defineEnumeration(name, options)` — declares a named enumeration.\n *\n * Codegen emits a string-literal union (TS), a real `enum` (Rust), a class\n * (Python), etc., according to each language's idiom. Per-variant docs are\n * carried through to language-native member documentation.\n */\n\nimport type { EnumerationSpec, EnumerationVariantSpec } from './types';\n\nexport interface VariantOptions {\n readonly docs?: string;\n}\n\n/** Construct a single enumeration variant. */\nexport function variant(name: string, options: VariantOptions = {}): EnumerationVariantSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\nexport interface DefineEnumerationOptions {\n readonly docs?: string;\n readonly variants: readonly EnumerationVariantSpec[];\n}\n\nexport function defineEnumeration(name: string, options: DefineEnumerationOptions): EnumerationSpec {\n if (options.variants.length === 0) {\n throw new Error(`defineEnumeration(\"${name}\"): variants must be non-empty`);\n }\n const seen = new Set<string>();\n for (const v of options.variants) {\n if (seen.has(v.name)) {\n throw new Error(`defineEnumeration(\"${name}\"): duplicate variant \"${v.name}\"`);\n }\n seen.add(v.name);\n }\n return Object.freeze({\n name,\n variants: Object.freeze([...options.variants]),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n","/**\n * `defineNode(kind, options)` — declares a single Codama node.\n *\n * The `kind` string is the discriminator value. By convention it ends in\n * `Node` and uses camelCase (e.g. `accountNode`, `arrayTypeNode`).\n *\n * `attributes` is an ordered array of values produced by `attribute(...)` or\n * `optionalAttribute(...)`. Order is preserved in the encoded spec and, by\n * extension, in generated code. The `kind: literal(<kind>)` discriminator\n * is implicit and is NOT declared by authors.\n *\n * The data-vs-children distinction is derived at codegen time from each\n * attribute's type tree (see `isChildAttribute` in `validate.ts`); the\n * meta-model itself just stores a flat list.\n */\n\nimport type { AttributeSpec, NodeSpec } from './types';\n\nexport interface DefineNodeOptions {\n /** Free-form prose description for codegen / docs. */\n readonly docs?: string;\n /**\n * Attributes of the node, in declaration order. Construct each entry\n * via `attribute(...)` or `optionalAttribute(...)`.\n */\n readonly attributes: readonly AttributeSpec[];\n /** Free-form examples (shape defined per spec major version). */\n readonly examples?: readonly unknown[];\n}\n\nexport function defineNode(kind: string, options: DefineNodeOptions): NodeSpec {\n return Object.freeze({\n kind,\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n attributes: Object.freeze([...options.attributes]),\n examples: Object.freeze([...(options.examples ?? [])]),\n });\n}\n","/**\n * `defineUnion(name, options)` — declares a named union of nodes.\n *\n * Members can be:\n * - a node kind string (e.g. `'arrayTypeNode'`), or\n * - a `node(...)` / `union(...)` reference (a `TypeExpr` produced by\n * `primitives.ts`).\n *\n * Nested unions are preserved structurally in the encoded spec rather than\n * flattened. This serves two purposes:\n * - DRY authoring (`union('StandaloneTypeNode')` instead of repeating 23\n * kind names).\n * - A signal to the Rust codegen to emit `From`/`Into` trait impls between\n * the parent union and each nested union.\n */\n\nimport type { TypeExpr, UnionMember, UnionSpec } from './types';\n\nexport type UnionMemberInput = TypeExpr | string;\n\nexport interface DefineUnionOptions {\n readonly docs?: string;\n readonly members: readonly UnionMemberInput[];\n}\n\nexport function defineUnion(name: string, options: DefineUnionOptions): UnionSpec {\n const normalised: UnionMember[] = options.members.map(normaliseMember);\n return Object.freeze({\n name,\n members: Object.freeze(normalised),\n ...(options.docs !== undefined ? { docs: options.docs } : {}),\n });\n}\n\nfunction normaliseMember(input: UnionMemberInput): UnionMember {\n if (typeof input === 'string') {\n // Bare strings are treated as node kinds (the most common case).\n return Object.freeze({ kind: 'node' as const, name: input });\n }\n if (input.kind === 'node') return Object.freeze({ kind: 'node' as const, name: input.name });\n if (input.kind === 'union') return Object.freeze({ kind: 'union' as const, name: input.name });\n throw new Error(\n `defineUnion: members must be node kind strings, node(...) or union(...) references; got ${JSON.stringify(input)}`,\n );\n}\n","/**\n * Type-expression primitives — the leaves of any attribute's type tree.\n *\n * Each function returns a frozen `TypeExpr` value. The encoded spec stores\n * those objects verbatim; codegen targets read them and emit native types.\n */\n\nimport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr } from './types';\n\n// Strings.\n\n/** Plain UTF-8 string. */\nexport function string(): TypeExpr {\n return Object.freeze({ kind: 'string' as const });\n}\n\n/**\n * A string that must be a valid IDL identifier (stored canonically in\n * camelCase). Renderers may convert to other casings at output time.\n */\nexport function stringIdentifier(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'identifier' as const });\n}\n\n/** A string that must be a valid version (e.g. `\"1.6.0\"`). */\nexport function stringVersion(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'version' as const });\n}\n\n/**\n * The version string of the surrounding Codama spec. Treat as a brand on\n * top of `stringVersion()` — the value is always pinned to the spec\n * version of the IDL document. Codegen targets typically emit a literal\n * type or a constant.\n */\nexport function codamaVersion(): TypeExpr {\n return Object.freeze({ kind: 'codamaVersion' as const });\n}\n\n// Integers (explicit bit widths — no machine-dependent usize/isize).\n\nconst integer = (width: IntegerWidth): TypeExpr => Object.freeze({ kind: 'integer' as const, width });\n\nexport const u8 = (): TypeExpr => integer('u8');\nexport const u16 = (): TypeExpr => integer('u16');\nexport const u32 = (): TypeExpr => integer('u32');\nexport const u64 = (): TypeExpr => integer('u64');\nexport const u128 = (): TypeExpr => integer('u128');\nexport const i8 = (): TypeExpr => integer('i8');\nexport const i16 = (): TypeExpr => integer('i16');\nexport const i32 = (): TypeExpr => integer('i32');\nexport const i64 = (): TypeExpr => integer('i64');\nexport const i128 = (): TypeExpr => integer('i128');\n\n// Floats.\n\nconst float = (width: FloatWidth): TypeExpr => Object.freeze({ kind: 'float' as const, width });\n\nexport const f32 = (): TypeExpr => float('f32');\nexport const f64 = (): TypeExpr => float('f64');\n\n// Booleans and literals.\n\nexport function boolean(): TypeExpr {\n return Object.freeze({ kind: 'boolean' as const });\n}\n\n/** A single fixed value of a primitive type. */\nexport function literal(value: LiteralValue): TypeExpr {\n return Object.freeze({ kind: 'literal' as const, value });\n}\n\n/**\n * A heterogeneous union of literal values — for sum types like\n * `boolean | 'either'` that don't fit a string-only enumeration.\n *\n * Codegen targets render this as the appropriate language idiom (a literal\n * union in TS, a tagged enum with custom serde in Rust, etc.).\n */\nexport function literalUnion(...values: LiteralValue[]): TypeExpr {\n if (values.length === 0) {\n throw new Error('literalUnion: at least one value required');\n }\n const seen = new Set<LiteralValue>();\n for (const v of values) {\n if (seen.has(v)) {\n throw new Error(`literalUnion: duplicate value ${JSON.stringify(v)}`);\n }\n seen.add(v);\n }\n return Object.freeze({ kind: 'literalUnion' as const, values: Object.freeze([...values]) });\n}\n\n// Named references.\n\n/** Reference to a named enumeration declared via `defineEnumeration`. */\nexport function enumeration(name: string): TypeExpr {\n return Object.freeze({ kind: 'enumeration' as const, name });\n}\n\n/** Reference to a named node declared via `defineNode`. */\nexport function node(name: string): TypeExpr {\n return Object.freeze({ kind: 'node' as const, name });\n}\n\n/** Reference to a named union declared via `defineUnion`. */\nexport function union(name: string): TypeExpr {\n return Object.freeze({ kind: 'union' as const, name });\n}\n\n/**\n * Reference to a named node, with implicit `NestedTypeNode<…>` wrapping.\n * The list of recognised wrapper nodes is supplied per spec major version;\n * see `v1/nestedTypeNodeWrappers.ts`.\n */\nexport function nestedTypeNode(name: string): TypeExpr {\n return Object.freeze({ kind: 'nestedTypeNode' as const, name });\n}\n\n// Re-exports for type ergonomics.\nexport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr };\n","/**\n * Author-side semantic aliases.\n *\n * Most aliases desugar at call time so the encoded spec only ever shows\n * the underlying primitive (e.g. `{ kind: \"integer\", width: \"u64\" }` for\n * both `u64()` and `byteSize()`). Each language's codegen may further\n * specialise rendering for these widths (e.g. Rust may render `u64` as\n * `usize` for byte-size fields if it wants). Those are codegen policies\n * — not spec content.\n *\n * `docs()` is the exception: it returns its own `'docs'` `TypeExpr` kind\n * so the documentation intent survives in the encoded spec rather than\n * collapsing to `array(string())`.\n */\n\nimport { i64, u32, u64 } from './primitives';\nimport type { TypeExpr } from './types';\n\n/** Number of bytes; non-negative. Encoded as `u64`. */\nexport function byteSize(): TypeExpr {\n return u64();\n}\n\n/** Signed byte offset. Encoded as `i64`. */\nexport function byteOffset(): TypeExpr {\n return i64();\n}\n\n/** Count of items in a collection; non-negative. Encoded as `u32`. */\nexport function count(): TypeExpr {\n return u32();\n}\n\n/**\n * Documentation for a node — semantically a list of paragraph strings,\n * but rendered per language at codegen time (e.g. `Array<string>` in\n * TypeScript, `Vec<String>` in Rust). Returns its own `'docs'` kind so\n * the intent isn't lost in the encoded spec.\n */\nexport function docs(): TypeExpr {\n return Object.freeze({ kind: 'docs' as const });\n}\n","/**\n * Self-consistency validation for an assembled spec.\n *\n * Returns an array of human-readable error strings. An empty array means\n * the spec is internally coherent — every reference resolves, no duplicate\n * names, naming conventions hold.\n */\n\nimport type { Spec, TypeExpr } from './types';\n\ntype RegistryKind = 'enumeration' | 'node' | 'union';\n\nexport function validate(spec: Spec): string[] {\n const errors: string[] = [];\n\n const nodeKinds = new Set(spec.nodes.map(n => n.kind));\n const unionNames = new Set(spec.unions.map(u => u.name));\n const enumerationNames = new Set(spec.enumerations.map(e => e.name));\n const wrappers = new Set(spec.nestedTypeNodeWrappers);\n\n // Single-pass name-collision check. Detects both within-kind duplicates\n // (\"two nodes called `accountNode`\") and cross-kind collisions (\"there's\n // a node and a union both called `TypeNode`\") in one report per\n // offending name.\n const registrations = new Map<string, RegistryKind[]>();\n const record = (name: string, kind: RegistryKind): void => {\n const list = registrations.get(name);\n if (list) list.push(kind);\n else registrations.set(name, [kind]);\n };\n for (const n of spec.nodes) record(n.kind, 'node');\n for (const u of spec.unions) record(u.name, 'union');\n for (const e of spec.enumerations) record(e.name, 'enumeration');\n\n for (const [name, kinds] of registrations) {\n if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));\n }\n\n // Per-node validation.\n for (const n of spec.nodes) {\n if (!/^[a-z][A-Za-z0-9]*Node$/.test(n.kind)) {\n errors.push(`Node kind \"${n.kind}\" does not match the camelCase ...Node naming convention.`);\n }\n const seenAttrs = new Set<string>();\n for (const a of n.attributes) {\n if (seenAttrs.has(a.name)) {\n errors.push(`Node \"${n.kind}\" declares attribute \"${a.name}\" more than once.`);\n }\n seenAttrs.add(a.name);\n walkTypeExpr(a.type, expr =>\n checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames),\n );\n }\n }\n\n // Union member resolution.\n for (const u of spec.unions) {\n if (u.members.length === 0) {\n errors.push(`Union \"${u.name}\" has no members.`);\n }\n const seenMembers = new Set<string>();\n for (const m of u.members) {\n const key = `${m.kind}:${m.name}`;\n if (seenMembers.has(key)) {\n errors.push(`Union \"${u.name}\" lists member ${key} more than once.`);\n }\n seenMembers.add(key);\n if (m.kind === 'node' && !nodeKinds.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined node \"${m.name}\".`);\n }\n if (m.kind === 'union' && !unionNames.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined union \"${m.name}\".`);\n }\n }\n }\n\n // nestedTypeNode wrapper sanity.\n for (const wrapper of wrappers) {\n if (!nodeKinds.has(wrapper)) {\n errors.push(`Nested-type-node wrapper \"${wrapper}\" is not a defined node.`);\n }\n }\n\n return errors;\n}\n\nfunction formatCollisionError(name: string, kinds: RegistryKind[]): string {\n const counts = new Map<RegistryKind, number>();\n for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);\n const breakdown = [...counts.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([k, n]) => `${n} ${k}${n > 1 ? 's' : ''}`)\n .join(', ');\n return `Name \"${name}\" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, and enumerations.`;\n}\n\nfunction walkTypeExpr(expr: TypeExpr, visit: (expr: TypeExpr) => void): void {\n visit(expr);\n if (expr.kind === 'array') {\n walkTypeExpr(expr.of, visit);\n } else if (expr.kind === 'tuple') {\n for (const item of expr.items) walkTypeExpr(item, visit);\n }\n}\n\nfunction checkRef(\n expr: TypeExpr,\n nodeKind: string,\n attrName: string,\n errors: string[],\n nodeKinds: Set<string>,\n unionNames: Set<string>,\n enumerationNames: Set<string>,\n): void {\n const where = `Node \"${nodeKind}\", attribute \"${attrName}\":`;\n switch (expr.kind) {\n case 'node':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} references undefined node \"${expr.name}\".`);\n }\n break;\n case 'union':\n if (!unionNames.has(expr.name)) {\n errors.push(`${where} references undefined union \"${expr.name}\".`);\n }\n break;\n case 'enumeration':\n if (!enumerationNames.has(expr.name)) {\n errors.push(`${where} references undefined enumeration \"${expr.name}\".`);\n }\n break;\n case 'nestedTypeNode':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} nestedTypeNode references undefined node \"${expr.name}\".`);\n }\n break;\n default:\n break;\n }\n}\n\n/**\n * Child-detection helper used by codegen, docs, and visitor-table\n * generators.\n *\n * A \"child\" attribute is one whose value contains another node. Specifically,\n * any attribute whose type tree includes a `node`, `nestedTypeNode`, or\n * `union` is treated as a child. Optionality (the `optional` flag on the\n * attribute itself) is orthogonal to this classification.\n */\nexport function isChildAttribute(type: TypeExpr): boolean {\n switch (type.kind) {\n case 'node':\n case 'nestedTypeNode':\n case 'union':\n return true;\n case 'array':\n return isChildAttribute(type.of);\n case 'tuple':\n return type.items.some(isChildAttribute);\n default:\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/attribute.ts","../src/api/compounds.ts","../src/api/defineCategory.ts","../src/api/defineEnumeration.ts","../src/api/defineNestedUnion.ts","../src/api/defineNode.ts","../src/api/defineUnion.ts","../src/api/primitives.ts","../src/api/semanticAliases.ts","../src/api/validate.ts"],"names":[],"mappings":"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","file":"api.browser.cjs","sourcesContent":["/**\n * Attribute factories — produce frozen `AttributeSpec` values directly.\n *\n * Every attribute of a node MUST be constructed via one of these helpers.\n * The returned value IS the encoded form; `defineNode` consumes them as-is.\n */\n\nimport type { AttributeSpec, TypeExpr } from './types';\n\nexport interface AttributeOptions {\n /** Free-form prose paragraphs describing this attribute. */\n readonly docs?: readonly string[];\n /** When `true`, the attribute may be absent in encoded values. */\n readonly optional?: boolean;\n}\n\n/**\n * Declare an attribute. The default is a required attribute; pass\n * `{ optional: true }` (or use `optionalAttribute`) to mark it optional.\n */\nexport function attribute(name: string, type: TypeExpr, options: AttributeOptions = {}): AttributeSpec {\n return Object.freeze({\n name,\n type,\n ...(options.optional ? { optional: true as const } : {}),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\n/**\n * Sugar for `attribute(name, type, { optional: true, ...rest })` — the most\n * common attribute shape after required ones.\n */\nexport function optionalAttribute(\n name: string,\n type: TypeExpr,\n options: Omit<AttributeOptions, 'optional'> = {},\n): AttributeSpec {\n return attribute(name, type, { ...options, optional: true });\n}\n","/**\n * Compound type-expression constructors — wrap or combine other type\n * expressions. Returned values are frozen.\n *\n * Optionality is intentionally NOT a compound: it's an attribute-level\n * concern, expressed via `optionalAttribute(...)` or\n * `attribute(..., { optional: true })`.\n */\n\nimport type { TypeExpr } from './types';\n\n/** An array (homogeneous list) of `inner`. */\nexport function array(inner: TypeExpr): TypeExpr {\n return Object.freeze({ kind: 'array' as const, of: inner });\n}\n\n/**\n * A heterogeneous fixed-length tuple. Each positional slot has its own type.\n *\n * Tuples use `items` (plural) rather than `of` to signal cardinality > 1.\n */\nexport function tuple(...items: TypeExpr[]): TypeExpr {\n return Object.freeze({ kind: 'tuple' as const, items: Object.freeze([...items]) });\n}\n","/**\n * `defineCategory(name, options)` — group a coherent set of nodes,\n * unions, enumerations, and nested unions under a single name.\n *\n * Categories double as a filing hint for codegen targets that organise\n * output by category (e.g. the TypeScript node-types generator emits\n * each category into its own subdirectory). Category names are arbitrary\n * strings; the spec doesn't constrain them.\n */\n\nimport type { CategorySpec, EnumerationSpec, NestedUnionSpec, NodeSpec, UnionSpec } from './types';\n\nexport interface DefineCategoryOptions {\n readonly docs?: readonly string[];\n readonly nodes?: readonly NodeSpec[];\n readonly unions?: readonly UnionSpec[];\n readonly enumerations?: readonly EnumerationSpec[];\n readonly nestedUnions?: readonly NestedUnionSpec[];\n}\n\nexport function defineCategory(name: string, options: DefineCategoryOptions = {}): CategorySpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n nodes: Object.freeze([...(options.nodes ?? [])]),\n unions: Object.freeze([...(options.unions ?? [])]),\n enumerations: Object.freeze([...(options.enumerations ?? [])]),\n nestedUnions: Object.freeze([...(options.nestedUnions ?? [])]),\n });\n}\n","/**\n * `defineEnumeration(name, options)` — declares a named enumeration.\n *\n * Codegen emits a string-literal union (TS), a real `enum` (Rust), a class\n * (Python), etc., according to each language's idiom. Per-variant docs are\n * carried through to language-native member documentation.\n */\n\nimport type { EnumerationSpec, EnumerationVariantSpec } from './types';\n\nexport interface VariantOptions {\n readonly docs?: readonly string[];\n}\n\n/** Construct a single enumeration variant. */\nexport function variant(name: string, options: VariantOptions = {}): EnumerationVariantSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\nexport interface DefineEnumerationOptions {\n readonly docs?: readonly string[];\n readonly variants: readonly EnumerationVariantSpec[];\n}\n\nexport function defineEnumeration(name: string, options: DefineEnumerationOptions): EnumerationSpec {\n if (options.variants.length === 0) {\n throw new Error(`defineEnumeration(\"${name}\"): variants must be non-empty`);\n }\n const seen = new Set<string>();\n for (const v of options.variants) {\n if (seen.has(v.name)) {\n throw new Error(`defineEnumeration(\"${name}\"): duplicate variant \"${v.name}\"`);\n }\n seen.add(v.name);\n }\n return Object.freeze({\n name,\n variants: Object.freeze([...options.variants]),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n","/**\n * `defineNestedUnion(name, options)` — declares a recursive type alias,\n * e.g. `nestedTypeNode<T>`.\n *\n * Codegen renders one alternative per wrapper kind, plus the base case:\n *\n * ```ts\n * type Alias<T extends Base> = Wrapper1<Alias<T>> | Wrapper2<Alias<T>> | … | T;\n * ```\n *\n * Use the `nestedUnion(alias, innerKind)` `TypeExpr` helper to reference\n * an instance of this alias from an attribute.\n */\n\nimport type { NestedUnionSpec, TypeExpr } from './types';\n\nexport interface DefineNestedUnionOptions {\n readonly docs?: readonly string[];\n /**\n * The base type the recursion bottoms out in. Codegen renders this\n * as the alias's type-parameter constraint and as the final union arm.\n */\n readonly base: TypeExpr;\n /**\n * Node kinds that act as wrappers in the recursion. Each must be a\n * node whose attribute structure can wrap another `NestedUnion<T>`.\n */\n readonly wrappers: readonly string[];\n}\n\nexport function defineNestedUnion(name: string, options: DefineNestedUnionOptions): NestedUnionSpec {\n return Object.freeze({\n name,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n base: options.base,\n wrappers: Object.freeze([...options.wrappers]),\n });\n}\n","/**\n * `defineNode(kind, options)` — declares a single Codama node.\n *\n * The `kind` string is the discriminator value. By convention it ends in\n * `Node` and uses camelCase (e.g. `accountNode`, `arrayTypeNode`).\n *\n * `attributes` is an ordered array of values produced by `attribute(...)` or\n * `optionalAttribute(...)`. Order is preserved in the encoded spec and, by\n * extension, in generated code. The `kind: literal(<kind>)` discriminator\n * is implicit and is NOT declared by authors.\n *\n * The data-vs-children distinction is derived at codegen time from each\n * attribute's type tree (see `isChildAttribute` in `validate.ts`); the\n * meta-model itself just stores a flat list.\n */\n\nimport type { AttributeSpec, NodeSpec } from './types';\n\nexport interface DefineNodeOptions {\n /** Free-form prose paragraphs describing this node. */\n readonly docs?: readonly string[];\n /**\n * Attributes of the node, in declaration order. Construct each entry\n * via `attribute(...)` or `optionalAttribute(...)`.\n */\n readonly attributes: readonly AttributeSpec[];\n /** Free-form examples (shape defined per spec major version). */\n readonly examples?: readonly unknown[];\n}\n\nexport function defineNode(kind: string, options: DefineNodeOptions): NodeSpec {\n return Object.freeze({\n kind,\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n attributes: Object.freeze([...options.attributes]),\n examples: Object.freeze([...(options.examples ?? [])]),\n });\n}\n","/**\n * `defineUnion(name, options)` — declares a named union of nodes.\n *\n * Members can be:\n * - a node kind string (e.g. `'arrayTypeNode'`), or\n * - a `node(...)` / `union(...)` reference (a `TypeExpr` produced by\n * `primitives.ts`).\n *\n * Nested unions are preserved structurally in the encoded spec rather than\n * flattened. This serves two purposes:\n * - DRY authoring (`union('standaloneTypeNode')` instead of repeating 23\n * kind names).\n * - A signal to the Rust codegen to emit `From`/`Into` trait impls between\n * the parent union and each nested union.\n */\n\nimport type { TypeExpr, UnionMember, UnionSpec } from './types';\n\nexport type UnionMemberInput = TypeExpr | string;\n\nexport interface DefineUnionOptions {\n readonly docs?: readonly string[];\n readonly members: readonly UnionMemberInput[];\n}\n\nexport function defineUnion(name: string, options: DefineUnionOptions): UnionSpec {\n const normalised: UnionMember[] = options.members.map(normaliseMember);\n return Object.freeze({\n name,\n members: Object.freeze(normalised),\n ...(options.docs !== undefined ? { docs: Object.freeze([...options.docs]) } : {}),\n });\n}\n\nfunction normaliseMember(input: UnionMemberInput): UnionMember {\n if (typeof input === 'string') {\n // Bare strings are treated as node kinds (the most common case).\n return Object.freeze({ kind: 'node' as const, name: input });\n }\n if (input.kind === 'node') return Object.freeze({ kind: 'node' as const, name: input.name });\n if (input.kind === 'union') return Object.freeze({ kind: 'union' as const, name: input.name });\n throw new Error(\n `defineUnion: members must be node kind strings, node(...) or union(...) references; got ${JSON.stringify(input)}`,\n );\n}\n","/**\n * Type-expression primitives — the leaves of any attribute's type tree.\n *\n * Each function returns a frozen `TypeExpr` value. The encoded spec stores\n * those objects verbatim; codegen targets read them and emit native types.\n */\n\nimport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr } from './types';\n\n// Addresses.\n\n/**\n * A Solana address (a base58-encoded ed25519 public key on the wire).\n * Codegen targets emit a dedicated address type — e.g. `Address` in Rust —\n * rather than treating it as a generic string.\n */\nexport function address(): TypeExpr {\n return Object.freeze({ kind: 'address' as const });\n}\n\n// Strings.\n\n/** Plain UTF-8 string. */\nexport function string(): TypeExpr {\n return Object.freeze({ kind: 'string' as const });\n}\n\n/**\n * A string that must be a valid IDL identifier (stored canonically in\n * camelCase). Renderers may convert to other casings at output time.\n */\nexport function stringIdentifier(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'identifier' as const });\n}\n\n/** A string that must be a valid version (e.g. `\"1.6.0\"`). */\nexport function stringVersion(): TypeExpr {\n return Object.freeze({ kind: 'string' as const, constraint: 'version' as const });\n}\n\n/**\n * The version string of the surrounding Codama spec. Treat as a brand on\n * top of `stringVersion()` — the value is always pinned to the spec\n * version of the IDL document. Codegen targets typically emit a literal\n * type or a constant.\n */\nexport function codamaVersion(): TypeExpr {\n return Object.freeze({ kind: 'codamaVersion' as const });\n}\n\n// Integers (explicit bit widths — no machine-dependent usize/isize).\n\nconst integer = (width: IntegerWidth): TypeExpr => Object.freeze({ kind: 'integer' as const, width });\n\nexport const u8 = (): TypeExpr => integer('u8');\nexport const u16 = (): TypeExpr => integer('u16');\nexport const u32 = (): TypeExpr => integer('u32');\nexport const u64 = (): TypeExpr => integer('u64');\nexport const u128 = (): TypeExpr => integer('u128');\nexport const i8 = (): TypeExpr => integer('i8');\nexport const i16 = (): TypeExpr => integer('i16');\nexport const i32 = (): TypeExpr => integer('i32');\nexport const i64 = (): TypeExpr => integer('i64');\nexport const i128 = (): TypeExpr => integer('i128');\n\n// Floats.\n\nconst float = (width: FloatWidth): TypeExpr => Object.freeze({ kind: 'float' as const, width });\n\nexport const f32 = (): TypeExpr => float('f32');\nexport const f64 = (): TypeExpr => float('f64');\n\n// Booleans and literals.\n\nexport function boolean(): TypeExpr {\n return Object.freeze({ kind: 'boolean' as const });\n}\n\n/** A single fixed value of a primitive type. */\nexport function literal(value: LiteralValue): TypeExpr {\n return Object.freeze({ kind: 'literal' as const, value });\n}\n\n/**\n * A heterogeneous union of literal values — for sum types like\n * `boolean | 'either'` that don't fit a string-only enumeration.\n *\n * Codegen targets render this as the appropriate language idiom (a literal\n * union in TS, a tagged enum with custom serde in Rust, etc.).\n */\nexport function literalUnion(...values: LiteralValue[]): TypeExpr {\n if (values.length === 0) {\n throw new Error('literalUnion: at least one value required');\n }\n const seen = new Set<LiteralValue>();\n for (const v of values) {\n if (seen.has(v)) {\n throw new Error(`literalUnion: duplicate value ${JSON.stringify(v)}`);\n }\n seen.add(v);\n }\n return Object.freeze({ kind: 'literalUnion' as const, values: Object.freeze([...values]) });\n}\n\n// Named references.\n\n/** Reference to a named enumeration declared via `defineEnumeration`. */\nexport function enumeration(name: string): TypeExpr {\n return Object.freeze({ kind: 'enumeration' as const, name });\n}\n\n/** Reference to a named node declared via `defineNode`. */\nexport function node(name: string): TypeExpr {\n return Object.freeze({ kind: 'node' as const, name });\n}\n\n/** Reference to a named union declared via `defineUnion`. */\nexport function union(name: string): TypeExpr {\n return Object.freeze({ kind: 'union' as const, name });\n}\n\n/**\n * Reference to a named node, wrapped by a named recursive `NestedUnion`\n * alias. `alias` selects which `NestedUnion` declared via\n * `defineNestedUnion` the wrapping uses (e.g. `'nestedTypeNode'`); `name`\n * is the inner node kind.\n *\n * Renderers emit `<alias><<innerInterface>>` and an import for the alias\n * file.\n */\nexport function nestedUnion(alias: string, name: string): TypeExpr {\n return Object.freeze({ kind: 'nestedUnion' as const, alias, name });\n}\n\n// Re-exports for type ergonomics.\nexport type { FloatWidth, IntegerWidth, LiteralValue, StringConstraint, TypeExpr };\n","/**\n * Author-side semantic aliases.\n *\n * Most aliases desugar at call time so the encoded spec only ever shows\n * the underlying primitive (e.g. `{ kind: \"integer\", width: \"u64\" }` for\n * both `u64()` and `byteSize()`). Each language's codegen may further\n * specialise rendering for these widths (e.g. Rust may render `u64` as\n * `usize` for byte-size fields if it wants). Those are codegen policies\n * — not spec content.\n *\n * `docs()` is the exception: it returns its own `'docs'` `TypeExpr` kind\n * so the documentation intent survives in the encoded spec rather than\n * collapsing to `array(string())`.\n */\n\nimport { i64, u32, u64 } from './primitives';\nimport type { TypeExpr } from './types';\n\n/** Number of bytes; non-negative. Encoded as `u64`. */\nexport function byteSize(): TypeExpr {\n return u64();\n}\n\n/** Signed byte offset. Encoded as `i64`. */\nexport function byteOffset(): TypeExpr {\n return i64();\n}\n\n/** Count of items in a collection; non-negative. Encoded as `u32`. */\nexport function count(): TypeExpr {\n return u32();\n}\n\n/**\n * Documentation for a node — semantically a list of paragraph strings,\n * but rendered per language at codegen time (e.g. `Array<string>` in\n * TypeScript, `Vec<String>` in Rust). Returns its own `'docs'` kind so\n * the intent isn't lost in the encoded spec.\n */\nexport function docs(): TypeExpr {\n return Object.freeze({ kind: 'docs' as const });\n}\n","/**\n * Self-consistency validation for an assembled spec.\n *\n * Returns an array of human-readable error strings. An empty array means\n * the spec is internally coherent — every reference resolves, no\n * duplicate names, naming conventions hold.\n */\n\nimport type { EnumerationSpec, NestedUnionSpec, NodeSpec, Spec, TypeExpr, UnionSpec } from './types';\n\ntype RegistryKind = 'enumeration' | 'nestedUnion' | 'node' | 'union';\n\n/**\n * The canonical camelCase identifier shape used across the spec for\n * unions, enumerations, and nested-union aliases. Node kinds must also\n * end in `Node` — see `NODE_KIND_REGEX`.\n */\nconst CAMEL_CASE_REGEX = /^[a-z][A-Za-z0-9]*$/;\nconst NODE_KIND_REGEX = /^[a-z][A-Za-z0-9]*Node$/;\n\nexport function validate(spec: Spec): string[] {\n const errors: string[] = [];\n\n const allNodes: NodeSpec[] = [];\n const allUnions: UnionSpec[] = [];\n const allEnumerations: EnumerationSpec[] = [];\n const allNestedUnions: NestedUnionSpec[] = [];\n for (const c of spec.categories) {\n allNodes.push(...c.nodes);\n allUnions.push(...c.unions);\n allEnumerations.push(...c.enumerations);\n allNestedUnions.push(...c.nestedUnions);\n }\n\n const nodeKinds = new Set(allNodes.map(n => n.kind));\n const unionNames = new Set(allUnions.map(u => u.name));\n const enumerationNames = new Set(allEnumerations.map(e => e.name));\n const nestedUnionNames = new Set(allNestedUnions.map(nu => nu.name));\n\n // Single-pass name-collision check across nodes, unions, enumerations,\n // and nested unions. One error per offending name.\n const registrations = new Map<string, RegistryKind[]>();\n const record = (name: string, kind: RegistryKind): void => {\n const list = registrations.get(name);\n if (list) list.push(kind);\n else registrations.set(name, [kind]);\n };\n for (const n of allNodes) record(n.kind, 'node');\n for (const u of allUnions) record(u.name, 'union');\n for (const e of allEnumerations) record(e.name, 'enumeration');\n for (const nu of allNestedUnions) record(nu.name, 'nestedUnion');\n\n for (const [name, kinds] of registrations) {\n if (kinds.length > 1) errors.push(formatCollisionError(name, kinds));\n }\n\n // Duplicate category names.\n const seenCategories = new Set<string>();\n for (const c of spec.categories) {\n if (seenCategories.has(c.name)) {\n errors.push(`Category \"${c.name}\" is declared more than once.`);\n }\n seenCategories.add(c.name);\n }\n\n // Per-node validation.\n for (const n of allNodes) {\n if (!NODE_KIND_REGEX.test(n.kind)) {\n errors.push(`Node kind \"${n.kind}\" does not match the camelCase ...Node naming convention.`);\n }\n const seenAttrs = new Set<string>();\n for (const a of n.attributes) {\n if (seenAttrs.has(a.name)) {\n errors.push(`Node \"${n.kind}\" declares attribute \"${a.name}\" more than once.`);\n }\n seenAttrs.add(a.name);\n walkTypeExpr(a.type, expr =>\n checkRef(expr, n.kind, a.name, errors, nodeKinds, unionNames, enumerationNames, nestedUnionNames),\n );\n }\n }\n\n // Union member resolution.\n for (const u of allUnions) {\n if (!CAMEL_CASE_REGEX.test(u.name)) {\n errors.push(`Union \"${u.name}\" does not match the camelCase naming convention.`);\n }\n if (u.members.length === 0) {\n errors.push(`Union \"${u.name}\" has no members.`);\n }\n const seenMembers = new Set<string>();\n for (const m of u.members) {\n const key = `${m.kind}:${m.name}`;\n if (seenMembers.has(key)) {\n errors.push(`Union \"${u.name}\" lists member ${key} more than once.`);\n }\n seenMembers.add(key);\n if (m.kind === 'node' && !nodeKinds.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined node \"${m.name}\".`);\n }\n if (m.kind === 'union' && !unionNames.has(m.name)) {\n errors.push(`Union \"${u.name}\" references undefined union \"${m.name}\".`);\n }\n }\n }\n\n // Enumeration naming.\n for (const e of allEnumerations) {\n if (!CAMEL_CASE_REGEX.test(e.name)) {\n errors.push(`Enumeration \"${e.name}\" does not match the camelCase naming convention.`);\n }\n }\n\n // Nested-union wrapper sanity.\n for (const nu of allNestedUnions) {\n if (!CAMEL_CASE_REGEX.test(nu.name)) {\n errors.push(`Nested union \"${nu.name}\" does not match the camelCase naming convention.`);\n }\n if (nu.wrappers.length === 0) {\n errors.push(`Nested union \"${nu.name}\" has no wrappers.`);\n }\n for (const w of nu.wrappers) {\n if (!nodeKinds.has(w)) {\n errors.push(`Nested union \"${nu.name}\" wrapper \"${w}\" is not a defined node.`);\n }\n }\n }\n\n return errors;\n}\n\nfunction formatCollisionError(name: string, kinds: RegistryKind[]): string {\n const counts = new Map<RegistryKind, number>();\n for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);\n const breakdown = [...counts.entries()]\n .sort((a, b) => a[0].localeCompare(b[0]))\n .map(([k, n]) => `${n} ${k}${n > 1 ? 's' : ''}`)\n .join(', ');\n return `Name \"${name}\" is registered ${kinds.length} times (${breakdown}); names must be unique across nodes, unions, enumerations, and nested unions.`;\n}\n\nfunction walkTypeExpr(expr: TypeExpr, visit: (expr: TypeExpr) => void): void {\n visit(expr);\n if (expr.kind === 'array') {\n walkTypeExpr(expr.of, visit);\n } else if (expr.kind === 'tuple') {\n for (const item of expr.items) walkTypeExpr(item, visit);\n }\n}\n\nfunction checkRef(\n expr: TypeExpr,\n nodeKind: string,\n attrName: string,\n errors: string[],\n nodeKinds: Set<string>,\n unionNames: Set<string>,\n enumerationNames: Set<string>,\n nestedUnionNames: Set<string>,\n): void {\n const where = `Node \"${nodeKind}\", attribute \"${attrName}\":`;\n switch (expr.kind) {\n case 'node':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} references undefined node \"${expr.name}\".`);\n }\n break;\n case 'union':\n if (!unionNames.has(expr.name)) {\n errors.push(`${where} references undefined union \"${expr.name}\".`);\n }\n break;\n case 'enumeration':\n if (!enumerationNames.has(expr.name)) {\n errors.push(`${where} references undefined enumeration \"${expr.name}\".`);\n }\n break;\n case 'nestedUnion':\n if (!nodeKinds.has(expr.name)) {\n errors.push(`${where} nestedUnion references undefined node \"${expr.name}\".`);\n }\n if (!nestedUnionNames.has(expr.alias)) {\n errors.push(`${where} nestedUnion references undefined alias \"${expr.alias}\".`);\n }\n break;\n default:\n break;\n }\n}\n\n/**\n * Discriminator helper used by codegen, docs, and visitor-table generators.\n *\n * A \"child\" attribute is one whose value contains another node. Specifically,\n * any attribute whose type tree includes a `node`, `nestedUnion`, or\n * `union` is treated as a child. Optionality (the `optional` flag on the\n * attribute itself) is orthogonal to this classification.\n */\nexport function isChildAttribute(type: TypeExpr): boolean {\n switch (type.kind) {\n case 'node':\n case 'nestedUnion':\n case 'union':\n return true;\n case 'array':\n return isChildAttribute(type.of);\n case 'tuple':\n return type.items.some(isChildAttribute);\n default:\n return false;\n }\n}\n"]}
|