diff --git a/.changeset/slimy-lobsters-live.md b/.changeset/slimy-lobsters-live.md new file mode 100644 index 0000000..0dc0dfd --- /dev/null +++ b/.changeset/slimy-lobsters-live.md @@ -0,0 +1,5 @@ +--- +'@mysten/bcs': minor +--- + +Allow BcsType.transform to omit input or output transform diff --git a/packages/bcs/src/bcs-type.ts b/packages/bcs/src/bcs-type.ts index 5ab84d3..2c92f53 100644 --- a/packages/bcs/src/bcs-type.ts +++ b/packages/bcs/src/bcs-type.ts @@ -79,24 +79,25 @@ export class BcsType { return this.parse(fromBase64(b64)); } - transform({ + transform({ name, input, output, validate, }: { - input: (val: Input2) => Input; - output: (value: T) => T2; + input?: (val: Input2) => Input; + output?: (value: T) => T2; } & BcsTypeOptions) { return new BcsType({ name: name ?? this.name, - read: (reader) => output(this.read(reader)), - write: (value, writer) => this.#write(input(value), writer), - serializedSize: (value) => this.serializedSize(input(value)), - serialize: (value, options) => this.#serialize(input(value), options), + read: (reader) => (output ? output(this.read(reader)) : (this.read(reader) as never)), + write: (value, writer) => this.#write(input ? input(value) : (value as never), writer), + serializedSize: (value) => this.serializedSize(input ? input(value) : (value as never)), + serialize: (value, options) => + this.#serialize(input ? input(value) : (value as never), options), validate: (value) => { validate?.(value); - this.validate(input(value)); + this.validate(input ? input(value) : (value as never)); }, }); } diff --git a/packages/bcs/tests/builder.test.ts b/packages/bcs/tests/builder.test.ts index b91962e..0240ee4 100644 --- a/packages/bcs/tests/builder.test.ts +++ b/packages/bcs/tests/builder.test.ts @@ -249,6 +249,31 @@ describe('bcs', () => { Variant2: 'hello', }); }); + + describe('transform', () => { + const stringU8 = bcs.u8().transform({ + input: (val: string) => parseInt(val), + output: (val) => val.toString(), + }); + + testType('transform', stringU8, '1', '01', '1'); + + // Output only + const bigIntu64 = bcs.u64().transform({ + output: (val) => BigInt(val), + }); + + testType('transform', bigIntu64, '1', '0100000000000000', 1n); + testType('transform', bigIntu64, 1, '0100000000000000', 1n); + testType('transform', bigIntu64, 1n, '0100000000000000', 1n); + + // Input only + const hexU8 = bcs.u8().transform({ + input: (val: string) => Number.parseInt(val, 16), + }); + + testType('transform', hexU8, 'ff', 'ff', 255); + }); }); function testType(