diff --git a/src/describe/index.ts b/src/describe/index.ts index 5c5fc80..33a9723 100644 --- a/src/describe/index.ts +++ b/src/describe/index.ts @@ -54,3 +54,13 @@ export const keyed = >( key: K, inner: (ref: IUnstableSchema>) => P, ) => new KeyedSchema(key, inner); + +export const concat = []>( + objs: Objs, +) => { + return new ObjectSchema( + Object.fromEntries( + objs.map(({ properties }) => Object.entries(properties)).flat(), + ) as unknown as SchemaMap, + ); +}; diff --git a/src/test/object.test.ts b/src/test/object.test.ts index 2638b6d..7d94588 100644 --- a/src/test/object.test.ts +++ b/src/test/object.test.ts @@ -1,6 +1,6 @@ import * as chai from 'chai'; import { encodeAndDecode, makeIO } from './helpers/mock'; -import { generic, genericEnum, object, optional } from '../describe'; +import { concat, generic, genericEnum, object, optional } from '../describe'; import { byte, i32, string, MaxValue } from '../structure'; import { Parsed } from '../utilityTypes'; @@ -128,4 +128,64 @@ describe('ObjectSchema', () => { expect(input.readInt32()).to.equal(3); // c expect(input.readInt32()).to.equal(2); // b }); + + it('allows to extend it with more properties', () => { + const schema = object({ + a: i32, + b: i32, + }); + + const extended = concat([ + schema, + object({ + c: i32, + d: i32, + }), + ]); + + const value: Parsed = { + a: 1, + b: 2, + c: 3, + d: 4, + }; + + const { output, input } = makeIO(extended.measure(value).size); + extended.write(output, value); + + expect(input.readInt32()).to.equal(1); // a + expect(input.readInt32()).to.equal(2); // b + expect(input.readInt32()).to.equal(3); // c + expect(input.readInt32()).to.equal(4); // d + }); + + it('allows to prepend it with more properties', () => { + const schema = object({ + a: i32, + b: i32, + }); + + const prepended = concat([ + object({ + c: i32, + d: i32, + }), + schema, + ]); + + const value: Parsed = { + a: 1, + b: 2, + c: 3, + d: 4, + }; + + const { output, input } = makeIO(prepended.measure(value).size); + prepended.write(output, value); + + expect(input.readInt32()).to.equal(3); // c + expect(input.readInt32()).to.equal(4); // d + expect(input.readInt32()).to.equal(1); // a + expect(input.readInt32()).to.equal(2); // b + }); });