TypeScript type generator for Orbit schema definitions.
Fork of https://github.com/exivity/react-orbitjs/tree/next/packages/orbit-type-generator
Added withPrefix param that allows to prepend generated interfaces with provided prefix in order to follow naming conventions of specific project.
Feel free to start watching and ⭐ project in order not miss the release or updates.
Example use case:
import { generateTypes } from 'orbit-type-generator'
const definition = {
models: {
user: {
attributes: {
username: { type: 'string' }
},
relationships: {
group: { type: 'hasOne', model: 'group' }
}
},
group: {
attributes: {
name: { type: 'string' }
},
relationships: {
users: { type: 'hasMany', model: 'user' }
}
}
}
}
const schema = new Schema(definition)
generateTypes(schema)
Would returns this string:
// some statements omitted for brevity
export interface UserRecord extends Record, UserRecordIdentity {
attributes?: UserAttributes;
relationships?: UserRelationships;
}
export interface UserRecordIdentity extends RecordIdentity {
type: "user";
id: string;
}
export interface UserAttributes extends Dict<any> {
username: string;
}
export interface UserRelationships extends Dict<RecordRelationship> {
group: RecordHasOneRelationship<GroupRecordIdentity>;
}
export interface GroupRecord extends Record, GroupRecordIdentity {
attributes?: GroupAttributes;
relationships?: GroupRelationships;
}
export interface GroupRecordIdentity extends RecordIdentity {
type: "group";
id: string;
}
export interface GroupAttributes extends Dict<any> {
name: string;
}
export interface GroupRelationships extends Dict<RecordRelationship> {
users: RecordHasManyRelationship<UserRecordIdentity>;
}
If you want to keep some name consistency of your project, you could also pass withPrefix
option.
(I
prefix for the most cases).
generateTypes(schema, { withPrefix: 'i' })
will generate `
export interface IUserRecord extends Record, IUserRecordIdentity {
attributes?: IUserAttributes;
relationships?: IUserRelationships;
}
export interface IUserRecordIdentity extends RecordIdentity {
type: "user";
id: string;
}
export interface IUserAttributes extends Dict<any> {
username: string;
}
export interface IUserRelationships extends Dict<RecordRelationship> {
group: RecordHasOneRelationship<IGroupRecordIdentity>;
}
orbit-type-generator inputFile outputFile
For example, if you have a file schema.js
:
export default {
models: {
user: {
attributes: {
username: { type: 'string' }
}
}
}
}
you can generate the types with:
orbit-type-generator schema.js models.d.ts
withPrefix
option is also supported:
orbit-type-generator schema.js models.d.ts --with-prefix=i
You can type attributes using TypeScript types or interfaces.
The generator will automatically import the type based on a resolved
tsconfig.json
in the directory you're executing from.
const definition = {
models: {
user: {
attributes: {
permission: { type: 'UserPermission' }
}
}
}
}
You can optionally specify a fallback type to use if TypeScript can't resolve the specified type:
const definition = {
models: {
user: {
attributes: {
permission: { type: 'string', ts: 'UserPermission' }
}
}
}
}
const schema = new Schema(definition)
const types = generateTypes(schema, { tsProperty: 'ts' })
If you want your imports to be relative to a different directory than the directory you're executing from, use:
const types = generateTypes(schema, {
basePath: path.resolve(__dirname, 'src')
})
- Do not generate optional attributes and relationships, if they are not in schema.
- Properly generate types for relationships
- Option to allow extra properties (toggle attr/rel extends statements)
- Support .ts files in CLI using on-the-fly compiling
If you want to get involved, please do so by creating issues or submitting pull requests. Before undertaking any major PR effort, please check the existing (open and closed) issues. If there isn't one, please file a new issue so we can discuss and assign the work so effort is not duplicated. Thank you!
- Use
yarn
and tasks from package.json. - Write tests for you changes, obvious and covering.