Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Value nodes #123

Merged
merged 12 commits into from
Dec 29, 2023
5 changes: 5 additions & 0 deletions .changeset/dull-bees-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@metaplex-foundation/kinobi': minor
---

Create Value nodes
1 change: 0 additions & 1 deletion src/idl/IdlType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export type IdlTypeStructField = {
name: string;
type: IdlType;
docs?: string[];
defaultsValue?: any;
};

// Enums.
Expand Down
16 changes: 12 additions & 4 deletions src/nodes/AccountNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import {
mainCase,
} from '../shared';
import { AccountDataNode, accountDataNode } from './AccountDataNode';
import { bytesTypeNode } from './typeNodes/BytesTypeNode';
import type { Node } from './Node';
import { remainderSizeNode } from './sizeNodes';
import { bytesTypeNode } from './typeNodes/BytesTypeNode';
import { stringTypeNode } from './typeNodes/StringTypeNode';
import { assertStructTypeNode } from './typeNodes/StructTypeNode';
import { TypeNode, createTypeNodeFromIdl } from './typeNodes/TypeNode';
import { vScalar } from './ValueNode';
import { remainderSizeNode } from './sizeNodes';
import {
booleanValueNode,
numberValueNode,
stringValueNode,
} from './valueNodes';

export type AccountNode = {
readonly kind: 'accountNode';
Expand Down Expand Up @@ -60,7 +64,11 @@ export function accountNodeFromIdl(idl: Partial<IdlAccount>): AccountNode {
assertStructTypeNode(struct);
const seeds = (idl.seeds ?? []).map((seed): AccountSeed => {
if (seed.kind === 'constant') {
const value = vScalar(seed.value);
const value = (() => {
if (typeof seed.value === 'string') return stringValueNode(seed.value);
if (typeof seed.value === 'number') return numberValueNode(seed.value);
return booleanValueNode(seed.value);
})();
let type: TypeNode;
if (seed.type === 'string') {
type = stringTypeNode({ size: remainderSizeNode() });
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/InstructionNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
structTypeNodeFromIdl,
} from './typeNodes/StructTypeNode';
import { createTypeNodeFromIdl } from './typeNodes/TypeNode';
import { vScalar } from './ValueNode';
import { numberValueNode } from './valueNodes';

export type InstructionNode = {
readonly kind: 'instructionNode';
Expand Down Expand Up @@ -102,7 +102,7 @@ export function instructionNodeFromIdl(
child: createTypeNodeFromIdl(idl.discriminant.type),
defaultsTo: {
strategy: 'omitted',
value: vScalar(idl.discriminant.value),
value: numberValueNode(idl.discriminant.value),
},
});
dataArgs = structTypeNode([discriminatorField, ...dataArgs.fields]);
Expand Down
4 changes: 3 additions & 1 deletion src/nodes/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { ProgramNode } from './ProgramNode';
import type { RootNode } from './RootNode';
import { REGISTERED_SIZE_NODES } from './sizeNodes';
import { REGISTERED_TYPE_NODES } from './typeNodes';
import { REGISTERED_VALUE_NODES } from './valueNodes';

const REGISTERED_NODES = {
rootNode: {} as RootNode,
Expand All @@ -24,8 +25,9 @@ const REGISTERED_NODES = {
definedTypeNode: {} as DefinedTypeNode,

// Groups.
...REGISTERED_TYPE_NODES,
...REGISTERED_SIZE_NODES,
...REGISTERED_TYPE_NODES,
...REGISTERED_VALUE_NODES,
};

export const REGISTERED_NODES_KEYS = Object.keys(
Expand Down
94 changes: 0 additions & 94 deletions src/nodes/ValueNode.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/nodes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export * from './InstructionNode';
export * from './Node';
export * from './ProgramNode';
export * from './RootNode';
export * from './ValueNode';

export * from './sizeNodes';
export * from './typeNodes';
export * from './valueNodes';
7 changes: 2 additions & 5 deletions src/nodes/typeNodes/StructFieldTypeNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { IdlTypeStructField } from '../../idl';
import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared';
import type { Node } from '../Node';
import { ValueNode } from '../valueNodes';
import { TypeNode, createTypeNodeFromIdl } from './TypeNode';
import { ValueNode, vScalar } from '../ValueNode';

export type StructFieldTypeNode = {
readonly kind: 'structFieldTypeNode';
Expand Down Expand Up @@ -44,10 +44,7 @@ export function structFieldTypeNodeFromIdl(
name: idl.name ?? '',
child: createTypeNodeFromIdl(idl.type),
docs: idl.docs ?? [],
defaultsTo:
idl.defaultsValue !== undefined
? { strategy: 'optional', value: vScalar(idl.defaultsValue) }
: null,
defaultsTo: null,
});
}

Expand Down
23 changes: 23 additions & 0 deletions src/nodes/valueNodes/ArrayValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Node } from '../Node';
import { ValueNode } from './ValueNode';

export type ArrayValueNode = {
readonly kind: 'arrayValueNode';
readonly items: ValueNode[];
};

export function arrayValueNode(items: ValueNode[]): ArrayValueNode {
return { kind: 'arrayValueNode', items };
}

export function isArrayValueNode(node: Node | null): node is ArrayValueNode {
return !!node && node.kind === 'arrayValueNode';
}

export function assertArrayValueNode(
node: Node | null
): asserts node is ArrayValueNode {
if (!isArrayValueNode(node)) {
throw new Error(`Expected arrayValueNode, got ${node?.kind ?? 'null'}.`);
}
}
24 changes: 24 additions & 0 deletions src/nodes/valueNodes/BooleanValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Node } from '../Node';

export type BooleanValueNode = {
readonly kind: 'booleanValueNode';
readonly boolean: boolean;
};

export function booleanValueNode(boolean: boolean): BooleanValueNode {
return { kind: 'booleanValueNode', boolean };
}

export function isBooleanValueNode(
node: Node | null
): node is BooleanValueNode {
return !!node && node.kind === 'booleanValueNode';
}

export function assertBooleanValueNode(
node: Node | null
): asserts node is BooleanValueNode {
if (!isBooleanValueNode(node)) {
throw new Error(`Expected booleanValueNode, got ${node?.kind ?? 'null'}.`);
}
}
39 changes: 39 additions & 0 deletions src/nodes/valueNodes/EnumValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ImportFrom, MainCaseString, mainCase } from '../../shared';
import { Node } from '../Node';
import { StructValueNode } from './StructValueNode';
import { TupleValueNode } from './TupleValueNode';

export type EnumValueNode = {
readonly kind: 'enumValueNode';
readonly enumType: MainCaseString;
readonly variant: MainCaseString;
readonly value: StructValueNode | TupleValueNode | 'empty' | 'scalar';
readonly importFrom: ImportFrom | null;
};

export function enumValueNode(
enumType: string,
variant: string,
value?: StructValueNode | TupleValueNode | 'empty' | 'scalar',
importFrom?: ImportFrom | null
): EnumValueNode {
return {
kind: 'enumValueNode',
enumType: mainCase(enumType),
variant: mainCase(variant),
value: value ?? 'scalar',
importFrom: importFrom ?? null,
};
}

export function isEnumValueNode(node: Node | null): node is EnumValueNode {
return !!node && node.kind === 'enumValueNode';
}

export function assertEnumValueNode(
node: Node | null
): asserts node is EnumValueNode {
if (!isEnumValueNode(node)) {
throw new Error(`Expected enumValueNode, got ${node?.kind ?? 'null'}.`);
}
}
23 changes: 23 additions & 0 deletions src/nodes/valueNodes/MapValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Node } from '../Node';
import { ValueNode } from './ValueNode';

export type MapValueNode = {
readonly kind: 'mapValueNode';
readonly entries: [ValueNode, ValueNode][];
};

export function mapValueNode(entries: [ValueNode, ValueNode][]): MapValueNode {
return { kind: 'mapValueNode', entries };
}

export function isMapValueNode(node: Node | null): node is MapValueNode {
return !!node && node.kind === 'mapValueNode';
}

export function assertMapValueNode(
node: Node | null
): asserts node is MapValueNode {
if (!isMapValueNode(node)) {
throw new Error(`Expected mapValueNode, got ${node?.kind ?? 'null'}.`);
}
}
21 changes: 21 additions & 0 deletions src/nodes/valueNodes/NoneValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Node } from '../Node';

export type NoneValueNode = {
readonly kind: 'noneValueNode';
};

export function noneValueNode(): NoneValueNode {
return { kind: 'noneValueNode' };
}

export function isNoneValueNode(node: Node | null): node is NoneValueNode {
return !!node && node.kind === 'noneValueNode';
}

export function assertNoneValueNode(
node: Node | null
): asserts node is NoneValueNode {
if (!isNoneValueNode(node)) {
throw new Error(`Expected noneValueNode, got ${node?.kind ?? 'null'}.`);
}
}
22 changes: 22 additions & 0 deletions src/nodes/valueNodes/NumberValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Node } from '../Node';

export type NumberValueNode = {
readonly kind: 'numberValueNode';
readonly number: number;
};

export function numberValueNode(number: number): NumberValueNode {
return { kind: 'numberValueNode', number };
}

export function isNumberValueNode(node: Node | null): node is NumberValueNode {
return !!node && node.kind === 'numberValueNode';
}

export function assertNumberValueNode(
node: Node | null
): asserts node is NumberValueNode {
if (!isNumberValueNode(node)) {
throw new Error(`Expected numberValueNode, got ${node?.kind ?? 'null'}.`);
}
}
26 changes: 26 additions & 0 deletions src/nodes/valueNodes/PublicKeyValueNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Node } from '../Node';

export type PublicKeyValueNode = {
readonly kind: 'publicKeyValueNode';
readonly publicKey: string;
};

export function publicKeyValueNode(publicKey: string): PublicKeyValueNode {
return { kind: 'publicKeyValueNode', publicKey };
}

export function isPublicKeyValueNode(
node: Node | null
): node is PublicKeyValueNode {
return !!node && node.kind === 'publicKeyValueNode';
}

export function assertPublicKeyValueNode(
node: Node | null
): asserts node is PublicKeyValueNode {
if (!isPublicKeyValueNode(node)) {
throw new Error(
`Expected publicKeyValueNode, got ${node?.kind ?? 'null'}.`
);
}
}
Loading