@sirctseb/bolt-typegen
v2.0.0
Published
Generate TypeScript types from bolt security rules
Downloads
3
Readme
Bolt Type Generator :zap:
Generate TypesScript types from types declared in Bolt security rules.
This tool is useful if you use Bolt Compiler to author your security rules and you use typescript to write client code.
Consider some trivial security rules like:
path / is ToySchema {
read() { true }
}
type ToySchema {
stringChild: String;
nullableChild: Number | Null;
}
You can use this tool to generate types that reflect what the rules enforce:
export interface ToySchema {
stringChild: string;
nullableChild?: number;
}
Then you can use the emitted types to gain static typing of the values retrieved from firebase:
firebase.database().ref('/').once('value').then(snapshot => {
// 🎉
const x: ToySchema = snapshot.val();
})
Features
Optional properties
In the Firebase realtime database, a field cannot hold null as a value. Assigning null to a field removes the field from the object entirely. Therefore, given a bolt type like:
type MyObject {
nonNullableField: String;
nullableField: String | Null;
}
a naive translation to nullableField: string | null;
is incorrect, and we make the property optional instead:
export interface MyObject {
nonNullableField: string;
nullableField?: string;
}
Fields in the realtime database also cannot hold an empty object as a value. When all the fields on an object are assigned null (are deleted), the field that held the object is also removed entirely. Consider the type:
type MyObject {
nullableField: String | null;
}
type MyOtherObject {
myObject: MyObject;
}
The field myObject
does not explicitly include Null
in a union like in the first example, but the field must still be optional because if nullableField
is set to null, the value would be an empty object, and the myObject
field is removed.
See the basic nullable, implicit nullability, and implicity nullability via type params tests for more cases and examples.
Usage
import { generateTypes } from 'bolt-typegen';
generateTypes('type Person { name: String }')
// => 'export interface Person { name: string; }'