Package Exports
- @trezor/schema-utils
- @trezor/schema-utils/lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@trezor/schema-utils) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@trezor/schema-utils
A schema definition and validation library for TypeScript, based on TypeBox.
Example usage
Schema definition
Let's say we have a TypeScript type that we want to convert to a schema.
export interface Example {
coordinator: string;
coin?: string;
maxRounds: number;
maxFeePerKvbyte: Uint;
data: ArrayBuffer;
path: DerivationPath;
}The schema for this type can be defined as follows:
import { Type, Static } from '@trezor/schema-utils';
// ...
export const Example = Type.Object({
coordinator: Type.String(),
coin: Type.Optional(Type.String()),
maxRounds: Type.Number(),
maxFeePerKvbyte: Type.Uint(),
data: Type.ArrayBuffer(),
path: DerivationPath, // Reference to another schema
});
// Inferred TS type
export type Example = Static<typeof schema>;We can see that primitive and common types are defined using the Type object. This is also used for constructs such as unions, intersects, etc. The full list of available types can be found in the TypeBox documentation
If done correctly, the new schema should be equivalent to the old TypeScript type. Since the inferred TypeScript type is exported with the same name, it can be used both as a type and for runtime validation.
Validation
We have two main functions for validation: Assert and Validate.
Assert throws an error if the payload does not match the schema, also functioning as a type assertion.
import { Assert } from '@trezor/schema-utils';
Assert(Example, payload);
// payload now must be of type ExampleValidate does not throw, but simply returns a boolean. It can also be used as a type guard.
import { Validate } from '@trezor/schema-utils';
if (Validate(Example, payload)) {
// payload now must be of type Example
}Code generation
To generate schemas from TypeScript types automatically, you can use the code generation tool.
yarn workspace @trezor/schema-utils codegen <file>This tool is also used in Protobuf code generation to generate schemas for the messages.
Custom types
There are a few behavior changes and custom types that are used in the schemas.
Enums
enum MyExample {
Foo = 'foo',
Bar = 'bar',
}
const EnumMyExample = Type.Enum(MyExample);To use an enum as a schema, you need to use the Type.Enum function.
The convention is to prefix the name of the schema with Enum.
That way, the original enum can be used as a TypeScript type, and the schema can be used for validation.
To get the schema for the keys of the enum, you can use the KeyOfEnum type. The parameter it takes is directly the original Enum, not the schema. Don't use Typebox's Type.KeyOf function for this, as it will not work correctly.
const MyExampleKey: Type.KeyOfEnum(MyExample);Uint
Type.Uint();
// Can also be used for Sint
Type.Uint({ allowNegative: true });The Uint type is a custom type that is used in the Protobuf messages.
It is a unsigned integer that can be represented as a string or a number.
By using the allowNegative option, it can also be used for signed integers.
ArrayBuffer and Buffer
Type.ArrayBuffer();
Type.Buffer();Instances of the ArrayBuffer JS built-in object and Buffer in Node.js.