import { BaseRecord, ID } from '../BaseRecord' import { defineMigrations } from '../migrate' import { createRecordType } from '../RecordType' import { Store } from '../Store' import { StoreSchema } from '../StoreSchema' const UserVersion = { Initial: 0, AddLocale: 1, AddPhoneNumber: 2, } as const /** * A user of tldraw */ interface User extends BaseRecord<'user'> { name: string locale: string phoneNumber: string | null } const userMigrations = defineMigrations({ currentVersion: UserVersion.AddPhoneNumber, firstVersion: UserVersion.Initial, migrators: { [UserVersion.AddLocale]: { up: (record) => ({ ...record, locale: 'en', }), down: (record) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { locale, ...rest } = record return rest }, }, [UserVersion.AddPhoneNumber]: { up: (record) => ({ ...record, phoneNumber: null, }), down: (record) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { phoneNumber, ...rest } = record return rest }, }, }, }) const User = createRecordType('user', { migrations: userMigrations, }).withDefaultProperties(() => ({ /* STEP 6: Add any new default values for properties here */ name: 'New User', })) const ShapeVersion = { Initial: 0, AddRotation: 1, AddParent: 2, } as const const RectangleVersion = { Initial: 0, AddOpacity: 1, } as const const OvalVersion = { Initial: 0, AddBorderStyle: 1, } as const interface Shape extends BaseRecord<'shape'> { type: string x: number y: number rotation: number parentId: ID> | null props: Props } interface RectangleProps { width: number height: number opactiy: number } interface OvalProps { radius: number borderStyle: 'solid' | 'dashed' } const shapeMigrations = defineMigrations({ currentVersion: ShapeVersion.AddParent, firstVersion: ShapeVersion.Initial, migrators: { [ShapeVersion.AddRotation]: { up: (record) => ({ ...record, rotation: 0, }), down: (record) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { rotation, ...rest } = record return rest }, }, [ShapeVersion.AddParent]: { up: (record) => ({ ...record, parentId: null, }), down: (record) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { parentId, ...rest } = record return rest }, }, }, subTypeKey: 'type', subTypeMigrations: { rectangle: defineMigrations({ currentVersion: RectangleVersion.AddOpacity, firstVersion: RectangleVersion.Initial, migrators: { [RectangleVersion.AddOpacity]: { up: (record) => ({ ...record, props: { ...record.props, opacity: 1, }, }), // eslint-disable-next-line @typescript-eslint/no-unused-vars down: ({ props: { opacity, ...others }, ...record }) => ({ ...record, props: { ...others, }, }), }, }, }), oval: defineMigrations({ currentVersion: OvalVersion.AddBorderStyle, firstVersion: OvalVersion.Initial, migrators: { [OvalVersion.AddBorderStyle]: { up: (record) => ({ ...record, props: { ...record.props, borderStyle: 'solid', }, }), // eslint-disable-next-line @typescript-eslint/no-unused-vars down: ({ props: { borderStyle, ...others }, ...record }) => ({ ...record, props: { ...others, }, }), }, }, }), }, }) const Shape = createRecordType>('shape', { migrations: shapeMigrations, }).withDefaultProperties(() => ({ x: 0, y: 0, rotation: 0, parentId: null, })) const StoreVersions = { Initial: 0, RemoveOrg: 1, } const storeMigrations = defineMigrations({ currentVersion: StoreVersions.RemoveOrg, firstVersion: StoreVersions.Initial, migrators: { [StoreVersions.RemoveOrg]: { up: (store: Store) => { const orgs = store.allRecords().filter((record) => record.typeName === 'org') store.remove(orgs.map((org) => org.id)) return store }, down: (store: Store) => { // noop return store }, }, }, }) export const testSchemaV1 = new StoreSchema>( [User, Shape] as any, storeMigrations )