[refactor] record migrations (#1430)
This PR removes comments from our record types, makes initial version optional, and unifies the order of initial / current version. - Initial versions are zero by default - If no current version is provided to `defineMigrations`, migrations should be undefined - Fixes TypeScript quirks in versioning (e.g. only initial version) This PR also: - Makes migrations optional when empty - Removes reference to empty migrations ### Change Type - [x] `major` — Breaking Change ### Test Plan - [x] Unit Tests - [ ] Webdriver tests ### Release Notes - [tlschema] Improve `defineMigrations` - [editor] Simplify migration definitions
This commit is contained in:
parent
d48e403ed1
commit
53be923921
54 changed files with 427 additions and 691 deletions
|
@ -12,4 +12,6 @@
|
|||
apps/docs/content.json
|
||||
apps/vscode/extension/editor/index.js
|
||||
apps/vscode/extension/editor/tldraw-assets.json
|
||||
apps/webdriver/www/index.js
|
||||
apps/webdriver/www/index.js
|
||||
apps/vscode/extension/editor/*
|
||||
apps/examples/www
|
|
@ -11,7 +11,7 @@ import {
|
|||
VecLike,
|
||||
} from '@tldraw/primitives'
|
||||
import {
|
||||
arrowShapeMigrations,
|
||||
arrowShapeTypeMigrations,
|
||||
arrowShapeTypeValidator,
|
||||
TLArrowheadType,
|
||||
TLArrowShape,
|
||||
|
@ -1141,5 +1141,5 @@ export const TLArrowShapeDef = defineShape<TLArrowShape, TLArrowUtil>({
|
|||
type: 'arrow',
|
||||
getShapeUtil: () => TLArrowUtil,
|
||||
validator: arrowShapeTypeValidator,
|
||||
migrations: arrowShapeMigrations,
|
||||
migrations: arrowShapeTypeMigrations,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { toDomPrecision } from '@tldraw/primitives'
|
||||
import {
|
||||
bookmarkShapeMigrations,
|
||||
bookmarkShapeTypeMigrations,
|
||||
bookmarkShapeTypeValidator,
|
||||
TLAsset,
|
||||
TLAssetId,
|
||||
|
@ -197,5 +197,5 @@ export const TLBookmarkShapeDef = defineShape<TLBookmarkShape, TLBookmarkUtil>({
|
|||
type: 'bookmark',
|
||||
getShapeUtil: () => TLBookmarkUtil,
|
||||
validator: bookmarkShapeTypeValidator,
|
||||
migrations: bookmarkShapeMigrations,
|
||||
migrations: bookmarkShapeTypeMigrations,
|
||||
})
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
VecLike,
|
||||
} from '@tldraw/primitives'
|
||||
import {
|
||||
drawShapeMigrations,
|
||||
drawShapeTypeMigrations,
|
||||
drawShapeTypeValidator,
|
||||
TLDrawShape,
|
||||
TLDrawShapeSegment,
|
||||
|
@ -314,7 +314,7 @@ export class TLDrawUtil extends TLShapeUtil<TLDrawShape> {
|
|||
export const TLDrawShapeDef = defineShape<TLDrawShape, TLDrawUtil>({
|
||||
type: 'draw',
|
||||
getShapeUtil: () => TLDrawUtil,
|
||||
migrations: drawShapeMigrations,
|
||||
migrations: drawShapeTypeMigrations,
|
||||
validator: drawShapeTypeValidator,
|
||||
})
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { toDomPrecision } from '@tldraw/primitives'
|
||||
import {
|
||||
embedShapeMigrations,
|
||||
embedShapeTypeMigrations,
|
||||
embedShapeTypeValidator,
|
||||
TLEmbedShape,
|
||||
tlEmbedShapePermissionDefaults,
|
||||
|
@ -236,5 +236,5 @@ export const TLEmbedShapeDef = defineShape<TLEmbedShape, TLEmbedUtil>({
|
|||
type: 'embed',
|
||||
getShapeUtil: () => TLEmbedUtil,
|
||||
validator: embedShapeTypeValidator,
|
||||
migrations: embedShapeMigrations,
|
||||
migrations: embedShapeTypeMigrations,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { canolicalizeRotation, SelectionEdge, toDomPrecision } from '@tldraw/primitives'
|
||||
import {
|
||||
frameShapeMigrations,
|
||||
frameShapeTypeValidator,
|
||||
TLFrameShape,
|
||||
TLShape,
|
||||
|
@ -218,5 +217,4 @@ export const TLFrameShapeDef = defineShape<TLFrameShape, TLFrameUtil>({
|
|||
type: 'frame',
|
||||
getShapeUtil: () => TLFrameUtil,
|
||||
validator: frameShapeTypeValidator,
|
||||
migrations: frameShapeMigrations,
|
||||
})
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
VecLike,
|
||||
} from '@tldraw/primitives'
|
||||
import {
|
||||
geoShapeMigrations,
|
||||
geoShapeTypeMigrations,
|
||||
geoShapeTypeValidator,
|
||||
TLDashType,
|
||||
TLGeoShape,
|
||||
|
@ -1008,5 +1008,5 @@ export const TLGeoShapeDef = defineShape<TLGeoShape, TLGeoUtil>({
|
|||
type: 'geo',
|
||||
getShapeUtil: () => TLGeoUtil,
|
||||
validator: geoShapeTypeValidator,
|
||||
migrations: geoShapeMigrations,
|
||||
migrations: geoShapeTypeMigrations,
|
||||
})
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import { Box2d, Matrix2d } from '@tldraw/primitives'
|
||||
import {
|
||||
TLGroupShape,
|
||||
Vec2dModel,
|
||||
groupShapeMigrations,
|
||||
groupShapeTypeValidator,
|
||||
} from '@tldraw/tlschema'
|
||||
import { TLGroupShape, Vec2dModel, groupShapeTypeValidator } from '@tldraw/tlschema'
|
||||
import { SVGContainer } from '../../../components/SVGContainer'
|
||||
import { defineShape } from '../../../config/TLShapeDefinition'
|
||||
import { OnChildrenChangeHandler, TLShapeUtil } from '../TLShapeUtil'
|
||||
|
@ -115,5 +110,4 @@ export const TLGroupShapeDef = defineShape<TLGroupShape, TLGroupUtil>({
|
|||
type: 'group',
|
||||
getShapeUtil: () => TLGroupUtil,
|
||||
validator: groupShapeTypeValidator,
|
||||
migrations: groupShapeMigrations,
|
||||
})
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Vec2d, toDomPrecision } from '@tldraw/primitives'
|
|||
import {
|
||||
TLImageShape,
|
||||
TLShapePartial,
|
||||
imageShapeMigrations,
|
||||
imageShapeTypeMigrations,
|
||||
imageShapeTypeValidator,
|
||||
} from '@tldraw/tlschema'
|
||||
import { deepCopy } from '@tldraw/utils'
|
||||
|
@ -275,7 +275,7 @@ export const TLImageShapeDef = defineShape<TLImageShape, TLImageUtil>({
|
|||
type: 'image',
|
||||
getShapeUtil: () => TLImageUtil,
|
||||
validator: imageShapeTypeValidator,
|
||||
migrations: imageShapeMigrations,
|
||||
migrations: imageShapeTypeMigrations,
|
||||
})
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,12 +9,7 @@ import {
|
|||
intersectLineSegmentPolyline,
|
||||
pointNearToPolyline,
|
||||
} from '@tldraw/primitives'
|
||||
import {
|
||||
TLHandle,
|
||||
TLLineShape,
|
||||
lineShapeMigrations,
|
||||
lineShapeTypeValidator,
|
||||
} from '@tldraw/tlschema'
|
||||
import { TLHandle, TLLineShape, lineShapeTypeValidator } from '@tldraw/tlschema'
|
||||
import { deepCopy } from '@tldraw/utils'
|
||||
import { SVGContainer } from '../../../components/SVGContainer'
|
||||
import { defineShape } from '../../../config/TLShapeDefinition'
|
||||
|
@ -345,7 +340,6 @@ export const TLLineShapeDef = defineShape<TLLineShape, TLLineUtil>({
|
|||
type: 'line',
|
||||
getShapeUtil: () => TLLineUtil,
|
||||
validator: lineShapeTypeValidator,
|
||||
migrations: lineShapeMigrations,
|
||||
})
|
||||
|
||||
/** @public */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Box2d, toDomPrecision, Vec2d } from '@tldraw/primitives'
|
||||
import { noteShapeMigrations, noteShapeTypeValidator, TLNoteShape } from '@tldraw/tlschema'
|
||||
import { noteShapeTypeMigrations, noteShapeTypeValidator, TLNoteShape } from '@tldraw/tlschema'
|
||||
import { defineShape } from '../../../config/TLShapeDefinition'
|
||||
import { FONT_FAMILIES, LABEL_FONT_SIZES, TEXT_PROPS } from '../../../constants'
|
||||
import { App } from '../../App'
|
||||
|
@ -202,7 +202,7 @@ export const TLNoteShapeDef = defineShape<TLNoteShape, TLNoteUtil>({
|
|||
getShapeUtil: () => TLNoteUtil,
|
||||
type: 'note',
|
||||
validator: noteShapeTypeValidator,
|
||||
migrations: noteShapeMigrations,
|
||||
migrations: noteShapeTypeMigrations,
|
||||
})
|
||||
|
||||
function getGrowY(app: App, shape: TLNoteShape, prevGrowY = 0) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { Box2d, toDomPrecision, Vec2d } from '@tldraw/primitives'
|
||||
import { textShapeMigrations, textShapeTypeValidator, TLTextShape } from '@tldraw/tlschema'
|
||||
import { textShapeTypeMigrations, textShapeTypeValidator, TLTextShape } from '@tldraw/tlschema'
|
||||
import { HTMLContainer } from '../../../components/HTMLContainer'
|
||||
import { defineShape } from '../../../config/TLShapeDefinition'
|
||||
import { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from '../../../constants'
|
||||
|
@ -374,7 +374,7 @@ export const TLTextShapeDef = defineShape<TLTextShape, TLTextUtil>({
|
|||
type: 'text',
|
||||
getShapeUtil: () => TLTextUtil,
|
||||
validator: textShapeTypeValidator,
|
||||
migrations: textShapeMigrations,
|
||||
migrations: textShapeTypeMigrations,
|
||||
})
|
||||
|
||||
function getTextSize(app: App, props: TLTextShape['props']) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { toDomPrecision } from '@tldraw/primitives'
|
||||
import { TLVideoShape, videoShapeMigrations, videoShapeTypeValidator } from '@tldraw/tlschema'
|
||||
import { TLVideoShape, videoShapeTypeMigrations, videoShapeTypeValidator } from '@tldraw/tlschema'
|
||||
import * as React from 'react'
|
||||
import { track } from 'signia-react'
|
||||
import { HTMLContainer } from '../../../components/HTMLContainer'
|
||||
|
@ -54,7 +54,7 @@ export const TLVideoShapeDef = defineShape<TLVideoShape, TLVideoUtil>({
|
|||
type: 'video',
|
||||
getShapeUtil: () => TLVideoUtil,
|
||||
validator: videoShapeTypeValidator,
|
||||
migrations: videoShapeMigrations,
|
||||
migrations: videoShapeTypeMigrations,
|
||||
})
|
||||
|
||||
// Function from v1, could be improved bu explicitly using this.model.time (?)
|
||||
|
|
|
@ -45,7 +45,7 @@ const __TopLeftSnapOnlyShapeDef = defineShape<__TopLeftSnapOnlyShape, __TopLeftS
|
|||
type: '__test_top_left_snap_only',
|
||||
getShapeUtil: () => __TopLeftSnapOnlyShapeUtil,
|
||||
validator: { validate: (record) => record as __TopLeftSnapOnlyShape },
|
||||
migrations: defineMigrations({ currentVersion: 0, firstVersion: 0, migrators: {} }),
|
||||
migrations: defineMigrations({}),
|
||||
})
|
||||
|
||||
const configWithCustomShape = new TldrawEditorConfig({ shapes: [__TopLeftSnapOnlyShapeDef] })
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
```ts
|
||||
|
||||
import { BaseRecord } from '@tldraw/tlstore';
|
||||
import { defineMigrations } from '@tldraw/tlstore';
|
||||
import { ID } from '@tldraw/tlstore';
|
||||
import { Migrations } from '@tldraw/tlstore';
|
||||
import { RecordType } from '@tldraw/tlstore';
|
||||
|
@ -24,7 +23,7 @@ export const alignValidator: T.Validator<"end" | "middle" | "start">;
|
|||
export const arrowheadValidator: T.Validator<"arrow" | "bar" | "diamond" | "dot" | "inverted" | "none" | "pipe" | "square" | "triangle">;
|
||||
|
||||
// @public (undocumented)
|
||||
export const arrowShapeMigrations: Migrations;
|
||||
export const arrowShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const arrowShapeTypeValidator: T.Validator<TLArrowShape>;
|
||||
|
@ -48,7 +47,7 @@ export const bookmarkAssetMigrations: Migrations;
|
|||
export const bookmarkAssetTypeValidator: T.Validator<TLBookmarkAsset>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const bookmarkShapeMigrations: Migrations;
|
||||
export const bookmarkShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const bookmarkShapeTypeValidator: T.Validator<TLBookmarkShape>;
|
||||
|
@ -65,9 +64,6 @@ export interface Box2dModel {
|
|||
y: number;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const cameraTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const cameraTypeValidator: T.Validator<TLCamera>;
|
||||
|
||||
|
@ -124,7 +120,7 @@ export const cursorValidator: T.Validator<TLCursor>;
|
|||
// @public (undocumented)
|
||||
export type CustomShapeTypeInfo = {
|
||||
type: string;
|
||||
migrations: ReturnType<typeof defineMigrations>;
|
||||
migrations?: Migrations;
|
||||
validator?: StoreValidator<TLShape>;
|
||||
};
|
||||
|
||||
|
@ -134,14 +130,11 @@ export const dashValidator: T.Validator<"dashed" | "dotted" | "draw" | "solid">;
|
|||
// @internal (undocumented)
|
||||
export const defaultDerivePresenceState: (store: TLStore) => Signal<null | TLInstancePresence>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const documentTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const documentTypeValidator: T.Validator<TLDocument>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const drawShapeMigrations: Migrations;
|
||||
export const drawShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const drawShapeTypeValidator: T.Validator<TLDrawShape>;
|
||||
|
@ -334,7 +327,7 @@ export type EmbedDefinition = {
|
|||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const embedShapeMigrations: Migrations;
|
||||
export const embedShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const embedShapeTypeValidator: T.Validator<TLEmbedShape>;
|
||||
|
@ -351,14 +344,11 @@ export function fixupRecord(oldRecord: TLRecord): {
|
|||
// @internal (undocumented)
|
||||
export const fontValidator: T.Validator<"draw" | "mono" | "sans" | "serif">;
|
||||
|
||||
// @public (undocumented)
|
||||
export const frameShapeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const frameShapeTypeValidator: T.Validator<TLFrameShape>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const geoShapeMigrations: Migrations;
|
||||
export const geoShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const geoShapeTypeValidator: T.Validator<TLGeoShape>;
|
||||
|
@ -366,18 +356,12 @@ export const geoShapeTypeValidator: T.Validator<TLGeoShape>;
|
|||
// @internal (undocumented)
|
||||
export const geoValidator: T.Validator<"arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box">;
|
||||
|
||||
// @public (undocumented)
|
||||
export const groupShapeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const groupShapeTypeValidator: T.Validator<TLGroupShape>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const handleTypeValidator: T.Validator<TLHandle>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const iconShapeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const iconShapeTypeValidator: T.Validator<TLIconShape>;
|
||||
|
||||
|
@ -394,7 +378,7 @@ export const imageAssetMigrations: Migrations;
|
|||
export const imageAssetTypeValidator: T.Validator<TLImageAsset>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const imageShapeMigrations: Migrations;
|
||||
export const imageShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const imageShapeTypeValidator: T.Validator<TLImageShape>;
|
||||
|
@ -420,14 +404,11 @@ export function isShape(record?: BaseRecord<string>): record is TLShape;
|
|||
// @public (undocumented)
|
||||
export function isShapeId(id?: string): id is TLShapeId;
|
||||
|
||||
// @public (undocumented)
|
||||
export const lineShapeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const lineShapeTypeValidator: T.Validator<TLLineShape>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const noteShapeMigrations: Migrations;
|
||||
export const noteShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const noteShapeTypeValidator: T.Validator<TLNoteShape>;
|
||||
|
@ -441,9 +422,6 @@ export const opacityValidator: T.Validator<"0.1" | "0.25" | "0.5" | "0.75" | "1"
|
|||
// @internal (undocumented)
|
||||
export const pageIdValidator: T.Validator<TLPageId>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const pageTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const pageTypeValidator: T.Validator<TLPage>;
|
||||
|
||||
|
@ -477,7 +455,7 @@ export const splineValidator: T.Validator<"cubic" | "line">;
|
|||
export const storeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const textShapeMigrations: Migrations;
|
||||
export const textShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const textShapeTypeValidator: T.Validator<TLTextShape>;
|
||||
|
@ -1390,9 +1368,6 @@ export const userPresenceTypeMigrations: Migrations;
|
|||
// @public (undocumented)
|
||||
export const userPresenceTypeValidator: T.Validator<TLUserPresence>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const userTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const userTypeValidator: T.Validator<TLUser>;
|
||||
|
||||
|
@ -1413,7 +1388,7 @@ export const videoAssetMigrations: Migrations;
|
|||
export const videoAssetTypeValidator: T.Validator<TLVideoAsset>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const videoShapeMigrations: Migrations;
|
||||
export const videoShapeTypeMigrations: Migrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const videoShapeTypeValidator: T.Validator<TLVideoShape>;
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
"scripts": {
|
||||
"test": "lazy inherit",
|
||||
"test-coverage": "lazy inherit",
|
||||
"new-record": "node ./scripts/new-record.js",
|
||||
"new-shape": "node ./scripts/new-shape.js",
|
||||
"new-asset": "node ./scripts/new-asset.js",
|
||||
"index": "node ./scripts/build-index.js && yarn format",
|
||||
"format": "yarn run -T prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
||||
"build": "yarn run -T tsx ../../scripts/build-package.ts",
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
// @ts-check
|
||||
/* eslint-disable */
|
||||
|
||||
const kleur = require('kleur')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const typeName = process.argv[2]
|
||||
const lowerAssetName = typeName[2].toLowerCase() + typeName.slice(3)
|
||||
|
||||
if (!typeName.match(/^TL[A-Z][a-z]+[a-zA-Z0-9]+Asset$/)) {
|
||||
console.error(
|
||||
kleur.red('ERROR: Type name must start with'),
|
||||
`'${kleur.bold('TL')}'`,
|
||||
kleur.red('and be in'),
|
||||
kleur.bold('PascalCase'),
|
||||
kleur.red('and end in'),
|
||||
kleur.bold('Asset')
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const recordsDir = path.join(__dirname, '..', 'src', 'assets')
|
||||
if (!fs.existsSync(recordsDir)) {
|
||||
console.error(kleur.red("ERROR: Can't find assets directory at path"), recordsDir)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const filePath = path.join(recordsDir, `${typeName}.ts`)
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.error(kleur.red('ERROR: File already exists at path'), filePath)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const snakeCaseName =
|
||||
typeName[2].toLowerCase() +
|
||||
typeName
|
||||
.slice(3, -5)
|
||||
.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)
|
||||
.trimStart()
|
||||
|
||||
fs.writeFileSync(
|
||||
filePath,
|
||||
`import { defineMigrations } from '@tldraw/tlstore'
|
||||
import { TLAsset } from '../records/TLAsset'
|
||||
|
||||
declare module '../records/TLAsset' {
|
||||
interface GlobalAssetPropsMap {
|
||||
${snakeCaseName}: ${typeName}Props
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORTANT: If you update this interface, you must also bump the version number and add a migration
|
||||
export type ${typeName}Props = {}
|
||||
|
||||
export type ${typeName} = Extract<TLAsset, { type: '${snakeCaseName}' }>
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
export const ${lowerAssetName}Migrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
console.log(kleur.green('Created new record type at path'), filePath)
|
|
@ -1,78 +0,0 @@
|
|||
// @ts-check
|
||||
/* eslint-disable */
|
||||
|
||||
const kleur = require('kleur')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const typeName = process.argv[2]
|
||||
|
||||
if (!typeName.match(/^TL[A-Z][a-z]+[a-zA-Z0-9]+$/)) {
|
||||
console.error(
|
||||
kleur.red('ERROR: Type name must start with'),
|
||||
`'${kleur.bold('TL')}'`,
|
||||
kleur.red('and be in'),
|
||||
kleur.bold('PascalCase')
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const lowerCaseName = typeName[2].toLowerCase() + typeName.slice(3)
|
||||
|
||||
const recordsDir = path.join(__dirname, '..', 'src', 'records')
|
||||
if (!fs.existsSync(recordsDir)) {
|
||||
console.error(kleur.red("ERROR: Can't find records directory at path"), recordsDir)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const filePath = path.join(recordsDir, `${typeName}.ts`)
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.error(kleur.red('ERROR: File already exists at path'), filePath)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const snakeCaseName =
|
||||
typeName[2].toLowerCase() +
|
||||
typeName
|
||||
.slice(3)
|
||||
.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)
|
||||
.trimStart()
|
||||
|
||||
fs.writeFileSync(
|
||||
filePath,
|
||||
`import { BaseRecord, defineMigrations, createRecordType, ID } from '@tldraw/tlstore'
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
export const ${lowerCaseName}TypeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* ${typeName}
|
||||
*/
|
||||
export interface ${typeName} extends BaseRecord<'${snakeCaseName}'> {}
|
||||
|
||||
|
||||
export const ${typeName} = createRecordType<${typeName}>('${snakeCaseName}', {
|
||||
migrations: ${lowerCaseName}TypeMigrations,
|
||||
}).withDefaultProperties(() => ({
|
||||
}))
|
||||
|
||||
export type ${typeName}Id = ID<${typeName}>
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
console.log(kleur.green('Created new record type at path'), filePath)
|
|
@ -14,7 +14,6 @@ export type TLBookmarkAsset = TLBaseAsset<
|
|||
}
|
||||
>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const bookmarkAssetTypeValidator: T.Validator<TLBookmarkAsset> = createAssetValidator(
|
||||
'bookmark',
|
||||
|
@ -26,18 +25,5 @@ export const bookmarkAssetTypeValidator: T.Validator<TLBookmarkAsset> = createAs
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const bookmarkAssetMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {},
|
||||
})
|
||||
export const bookmarkAssetMigrations = defineMigrations({})
|
||||
|
|
|
@ -16,7 +16,6 @@ export type TLImageAsset = TLBaseAsset<
|
|||
}
|
||||
>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const imageAssetTypeValidator: T.Validator<TLImageAsset> = createAssetValidator(
|
||||
'image',
|
||||
|
@ -30,21 +29,14 @@ export const imageAssetTypeValidator: T.Validator<TLImageAsset> = createAssetVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddIsAnimated: 1,
|
||||
RenameWidthHeight: 2,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const imageAssetMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.RenameWidthHeight,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {
|
||||
[Versions.AddIsAnimated]: {
|
||||
up: (asset) => {
|
||||
|
|
|
@ -17,7 +17,6 @@ export type TLVideoAsset = TLBaseAsset<
|
|||
}
|
||||
>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const videoAssetTypeValidator: T.Validator<TLVideoAsset> = createAssetValidator(
|
||||
'video',
|
||||
|
@ -31,21 +30,14 @@ export const videoAssetTypeValidator: T.Validator<TLVideoAsset> = createAssetVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddIsAnimated: 1,
|
||||
RenameWidthHeight: 2,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const videoAssetMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.RenameWidthHeight,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {
|
||||
[Versions.AddIsAnimated]: {
|
||||
up: (asset) => {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { StoreSchema, StoreValidator, createRecordType, defineMigrations } from '@tldraw/tlstore'
|
||||
import {
|
||||
Migrations,
|
||||
StoreSchema,
|
||||
StoreValidator,
|
||||
createRecordType,
|
||||
defineMigrations,
|
||||
} from '@tldraw/tlstore'
|
||||
import { T } from '@tldraw/tlvalidate'
|
||||
import { Signal } from 'signia'
|
||||
import { TLRecord } from './TLRecord'
|
||||
|
@ -16,42 +22,42 @@ import { TLUser } from './records/TLUser'
|
|||
import { TLUserDocument } from './records/TLUserDocument'
|
||||
import { TLUserPresence } from './records/TLUserPresence'
|
||||
import { storeMigrations } from './schema'
|
||||
import { arrowShapeMigrations, arrowShapeTypeValidator } from './shapes/TLArrowShape'
|
||||
import { bookmarkShapeMigrations, bookmarkShapeTypeValidator } from './shapes/TLBookmarkShape'
|
||||
import { drawShapeMigrations, drawShapeTypeValidator } from './shapes/TLDrawShape'
|
||||
import { embedShapeMigrations, embedShapeTypeValidator } from './shapes/TLEmbedShape'
|
||||
import { frameShapeMigrations, frameShapeTypeValidator } from './shapes/TLFrameShape'
|
||||
import { geoShapeMigrations, geoShapeTypeValidator } from './shapes/TLGeoShape'
|
||||
import { groupShapeMigrations, groupShapeTypeValidator } from './shapes/TLGroupShape'
|
||||
import { imageShapeMigrations, imageShapeTypeValidator } from './shapes/TLImageShape'
|
||||
import { lineShapeMigrations, lineShapeTypeValidator } from './shapes/TLLineShape'
|
||||
import { noteShapeMigrations, noteShapeTypeValidator } from './shapes/TLNoteShape'
|
||||
import { textShapeMigrations, textShapeTypeValidator } from './shapes/TLTextShape'
|
||||
import { videoShapeMigrations, videoShapeTypeValidator } from './shapes/TLVideoShape'
|
||||
import { arrowShapeTypeMigrations, arrowShapeTypeValidator } from './shapes/TLArrowShape'
|
||||
import { bookmarkShapeTypeMigrations, bookmarkShapeTypeValidator } from './shapes/TLBookmarkShape'
|
||||
import { drawShapeTypeMigrations, drawShapeTypeValidator } from './shapes/TLDrawShape'
|
||||
import { embedShapeTypeMigrations, embedShapeTypeValidator } from './shapes/TLEmbedShape'
|
||||
import { frameShapeTypeMigrations, frameShapeTypeValidator } from './shapes/TLFrameShape'
|
||||
import { geoShapeTypeMigrations, geoShapeTypeValidator } from './shapes/TLGeoShape'
|
||||
import { groupShapeTypeMigrations, groupShapeTypeValidator } from './shapes/TLGroupShape'
|
||||
import { imageShapeTypeMigrations, imageShapeTypeValidator } from './shapes/TLImageShape'
|
||||
import { lineShapeTypeMigrations, lineShapeTypeValidator } from './shapes/TLLineShape'
|
||||
import { noteShapeTypeMigrations, noteShapeTypeValidator } from './shapes/TLNoteShape'
|
||||
import { textShapeTypeMigrations, textShapeTypeValidator } from './shapes/TLTextShape'
|
||||
import { videoShapeTypeMigrations, videoShapeTypeValidator } from './shapes/TLVideoShape'
|
||||
|
||||
const CORE_SHAPE_DEFS: readonly CustomShapeTypeInfo[] = [
|
||||
{ type: 'draw', migrations: drawShapeMigrations, validator: drawShapeTypeValidator },
|
||||
{ type: 'text', migrations: textShapeMigrations, validator: textShapeTypeValidator },
|
||||
{ type: 'line', migrations: lineShapeMigrations, validator: lineShapeTypeValidator },
|
||||
{ type: 'arrow', migrations: arrowShapeMigrations, validator: arrowShapeTypeValidator },
|
||||
{ type: 'image', migrations: imageShapeMigrations, validator: imageShapeTypeValidator },
|
||||
{ type: 'video', migrations: videoShapeMigrations, validator: videoShapeTypeValidator },
|
||||
{ type: 'geo', migrations: geoShapeMigrations, validator: geoShapeTypeValidator },
|
||||
{ type: 'note', migrations: noteShapeMigrations, validator: noteShapeTypeValidator },
|
||||
{ type: 'group', migrations: groupShapeMigrations, validator: groupShapeTypeValidator },
|
||||
{ type: 'draw', migrations: drawShapeTypeMigrations, validator: drawShapeTypeValidator },
|
||||
{ type: 'text', migrations: textShapeTypeMigrations, validator: textShapeTypeValidator },
|
||||
{ type: 'line', migrations: lineShapeTypeMigrations, validator: lineShapeTypeValidator },
|
||||
{ type: 'arrow', migrations: arrowShapeTypeMigrations, validator: arrowShapeTypeValidator },
|
||||
{ type: 'image', migrations: imageShapeTypeMigrations, validator: imageShapeTypeValidator },
|
||||
{ type: 'video', migrations: videoShapeTypeMigrations, validator: videoShapeTypeValidator },
|
||||
{ type: 'geo', migrations: geoShapeTypeMigrations, validator: geoShapeTypeValidator },
|
||||
{ type: 'note', migrations: noteShapeTypeMigrations, validator: noteShapeTypeValidator },
|
||||
{ type: 'group', migrations: groupShapeTypeMigrations, validator: groupShapeTypeValidator },
|
||||
{
|
||||
type: 'bookmark',
|
||||
migrations: bookmarkShapeMigrations,
|
||||
migrations: bookmarkShapeTypeMigrations,
|
||||
validator: bookmarkShapeTypeValidator,
|
||||
},
|
||||
{ type: 'frame', migrations: frameShapeMigrations, validator: frameShapeTypeValidator },
|
||||
{ type: 'embed', migrations: embedShapeMigrations, validator: embedShapeTypeValidator },
|
||||
{ type: 'frame', migrations: frameShapeTypeMigrations, validator: frameShapeTypeValidator },
|
||||
{ type: 'embed', migrations: embedShapeTypeMigrations, validator: embedShapeTypeValidator },
|
||||
]
|
||||
|
||||
/** @public */
|
||||
export type CustomShapeTypeInfo = {
|
||||
type: string
|
||||
migrations: ReturnType<typeof defineMigrations>
|
||||
migrations?: Migrations
|
||||
validator?: StoreValidator<TLShape>
|
||||
}
|
||||
|
||||
|
@ -79,7 +85,9 @@ export function createTLSchema({
|
|||
firstVersion: rootShapeTypeMigrations.firstVersion,
|
||||
migrators: rootShapeTypeMigrations.migrators,
|
||||
subTypeKey: 'type',
|
||||
subTypeMigrations: Object.fromEntries(allShapeDefs.map((def) => [def.type, def.migrations])),
|
||||
subTypeMigrations: Object.fromEntries(
|
||||
allShapeDefs.map((def) => [def.type, def.migrations ?? {}])
|
||||
) as Record<string, Migrations>,
|
||||
})
|
||||
|
||||
let shapeValidator = T.union('type', {
|
||||
|
|
|
@ -37,18 +37,8 @@ export {
|
|||
type TLAssetPartial,
|
||||
type TLAssetShape,
|
||||
} from './records/TLAsset'
|
||||
export {
|
||||
TLCamera,
|
||||
cameraTypeMigrations,
|
||||
cameraTypeValidator,
|
||||
type TLCameraId,
|
||||
} from './records/TLCamera'
|
||||
export {
|
||||
TLDOCUMENT_ID,
|
||||
TLDocument,
|
||||
documentTypeMigrations,
|
||||
documentTypeValidator,
|
||||
} from './records/TLDocument'
|
||||
export { TLCamera, cameraTypeValidator, type TLCameraId } from './records/TLCamera'
|
||||
export { TLDOCUMENT_ID, TLDocument, documentTypeValidator } from './records/TLDocument'
|
||||
export {
|
||||
TLInstance,
|
||||
instanceTypeMigrations,
|
||||
|
@ -63,7 +53,7 @@ export {
|
|||
type TLInstancePageStateId,
|
||||
} from './records/TLInstancePageState'
|
||||
export { TLInstancePresence } from './records/TLInstancePresence'
|
||||
export { TLPage, pageTypeMigrations, pageTypeValidator, type TLPageId } from './records/TLPage'
|
||||
export { TLPage, pageTypeValidator, type TLPageId } from './records/TLPage'
|
||||
export {
|
||||
createCustomShapeId,
|
||||
createShapeId,
|
||||
|
@ -80,7 +70,7 @@ export {
|
|||
type TLShapeType,
|
||||
type TLUnknownShape,
|
||||
} from './records/TLShape'
|
||||
export { TLUser, userTypeMigrations, userTypeValidator, type TLUserId } from './records/TLUser'
|
||||
export { TLUser, userTypeValidator, type TLUserId } from './records/TLUser'
|
||||
export {
|
||||
TLUserDocument,
|
||||
userDocumentTypeMigrations,
|
||||
|
@ -96,7 +86,7 @@ export {
|
|||
export { storeMigrations } from './schema'
|
||||
export {
|
||||
TL_ARROW_TERMINAL_TYPE,
|
||||
arrowShapeMigrations,
|
||||
arrowShapeTypeMigrations,
|
||||
arrowShapeTypeValidator,
|
||||
arrowTerminalTypeValidator,
|
||||
type TLArrowHeadModel,
|
||||
|
@ -106,14 +96,14 @@ export {
|
|||
type TLArrowTerminalType,
|
||||
} from './shapes/TLArrowShape'
|
||||
export {
|
||||
bookmarkShapeMigrations,
|
||||
bookmarkShapeTypeMigrations,
|
||||
bookmarkShapeTypeValidator,
|
||||
type TLBookmarkShape,
|
||||
type TLBookmarkShapeProps,
|
||||
} from './shapes/TLBookmarkShape'
|
||||
export {
|
||||
TL_DRAW_SHAPE_SEGMENT_TYPE,
|
||||
drawShapeMigrations,
|
||||
drawShapeTypeMigrations,
|
||||
drawShapeTypeValidator,
|
||||
type TLDrawShape,
|
||||
type TLDrawShapeProps,
|
||||
|
@ -121,7 +111,7 @@ export {
|
|||
} from './shapes/TLDrawShape'
|
||||
export {
|
||||
EMBED_DEFINITIONS,
|
||||
embedShapeMigrations,
|
||||
embedShapeTypeMigrations,
|
||||
embedShapeTypeValidator,
|
||||
tlEmbedShapePermissionDefaults,
|
||||
type EmbedDefinition,
|
||||
|
@ -131,56 +121,52 @@ export {
|
|||
type TLEmbedShapeProps,
|
||||
} from './shapes/TLEmbedShape'
|
||||
export {
|
||||
frameShapeMigrations,
|
||||
frameShapeTypeValidator,
|
||||
type TLFrameShape,
|
||||
type TLFrameShapeProps,
|
||||
} from './shapes/TLFrameShape'
|
||||
export {
|
||||
geoShapeMigrations,
|
||||
geoShapeTypeMigrations,
|
||||
geoShapeTypeValidator,
|
||||
type TLGeoShape,
|
||||
type TLGeoShapeProps,
|
||||
} from './shapes/TLGeoShape'
|
||||
export {
|
||||
groupShapeMigrations,
|
||||
groupShapeTypeValidator,
|
||||
type TLGroupShape,
|
||||
type TLGroupShapeProps,
|
||||
} from './shapes/TLGroupShape'
|
||||
export {
|
||||
iconShapeMigrations,
|
||||
iconShapeTypeValidator,
|
||||
type TLIconShape,
|
||||
type TLIconShapeProps,
|
||||
} from './shapes/TLIconShape'
|
||||
export {
|
||||
imageShapeMigrations,
|
||||
imageShapeTypeMigrations,
|
||||
imageShapeTypeValidator,
|
||||
type TLImageCrop,
|
||||
type TLImageShape,
|
||||
type TLImageShapeProps,
|
||||
} from './shapes/TLImageShape'
|
||||
export {
|
||||
lineShapeMigrations,
|
||||
lineShapeTypeValidator,
|
||||
type TLLineShape,
|
||||
type TLLineShapeProps,
|
||||
} from './shapes/TLLineShape'
|
||||
export {
|
||||
noteShapeMigrations,
|
||||
noteShapeTypeMigrations,
|
||||
noteShapeTypeValidator,
|
||||
type TLNoteShape,
|
||||
type TLNoteShapeProps,
|
||||
} from './shapes/TLNoteShape'
|
||||
export {
|
||||
textShapeMigrations,
|
||||
textShapeTypeMigrations,
|
||||
textShapeTypeValidator,
|
||||
type TLTextShape,
|
||||
type TLTextShapeProps,
|
||||
} from './shapes/TLTextShape'
|
||||
export {
|
||||
videoShapeMigrations,
|
||||
videoShapeTypeMigrations,
|
||||
videoShapeTypeValidator,
|
||||
type TLVideoShape,
|
||||
type TLVideoShapeProps,
|
||||
|
|
|
@ -10,15 +10,15 @@ import { rootShapeTypeMigrations, TLShape } from './records/TLShape'
|
|||
import { userDocumentTypeMigrations, userDocumentVersions } from './records/TLUserDocument'
|
||||
import { userPresenceTypeMigrations } from './records/TLUserPresence'
|
||||
import { storeMigrations } from './schema'
|
||||
import { arrowShapeMigrations } from './shapes/TLArrowShape'
|
||||
import { bookmarkShapeMigrations } from './shapes/TLBookmarkShape'
|
||||
import { drawShapeMigrations } from './shapes/TLDrawShape'
|
||||
import { embedShapeMigrations } from './shapes/TLEmbedShape'
|
||||
import { geoShapeMigrations } from './shapes/TLGeoShape'
|
||||
import { imageShapeMigrations } from './shapes/TLImageShape'
|
||||
import { noteShapeMigrations } from './shapes/TLNoteShape'
|
||||
import { textShapeMigrations } from './shapes/TLTextShape'
|
||||
import { videoShapeMigrations } from './shapes/TLVideoShape'
|
||||
import { arrowShapeTypeMigrations } from './shapes/TLArrowShape'
|
||||
import { bookmarkShapeTypeMigrations } from './shapes/TLBookmarkShape'
|
||||
import { drawShapeTypeMigrations } from './shapes/TLDrawShape'
|
||||
import { embedShapeTypeMigrations } from './shapes/TLEmbedShape'
|
||||
import { geoShapeTypeMigrations } from './shapes/TLGeoShape'
|
||||
import { imageShapeTypeMigrations } from './shapes/TLImageShape'
|
||||
import { noteShapeTypeMigrations } from './shapes/TLNoteShape'
|
||||
import { textShapeTypeMigrations } from './shapes/TLTextShape'
|
||||
import { videoShapeTypeMigrations } from './shapes/TLVideoShape'
|
||||
|
||||
const assetModules = fs
|
||||
.readdirSync('src/assets')
|
||||
|
@ -90,7 +90,9 @@ for (const [fileName, module] of allModules) {
|
|||
|
||||
test('all modules export migrations', () => {
|
||||
const modulesWithoutMigrations = allModules
|
||||
.filter(([, module]) => !Object.keys(module).find((k) => k.endsWith('igrations')))
|
||||
.filter(([, module]) => {
|
||||
return !Object.keys(module).find((k) => k.endsWith('igrations'))
|
||||
})
|
||||
.map(([fileName]) => fileName)
|
||||
|
||||
// IF THIS LINE IS FAILING YOU NEED TO MAKE SURE THE MIGRATIONS ARE EXPORTED
|
||||
|
@ -280,10 +282,10 @@ describe('Adding snap mode', () => {
|
|||
|
||||
describe('Adding url props', () => {
|
||||
for (const [name, { up, down }] of [
|
||||
['video shape', videoShapeMigrations.migrators[1]],
|
||||
['note shape', noteShapeMigrations.migrators[1]],
|
||||
['geo shape', geoShapeMigrations.migrators[1]],
|
||||
['image shape', imageShapeMigrations.migrators[1]],
|
||||
['video shape', videoShapeTypeMigrations.migrators[1]],
|
||||
['note shape', noteShapeTypeMigrations.migrators[1]],
|
||||
['geo shape', geoShapeTypeMigrations.migrators[1]],
|
||||
['image shape', imageShapeTypeMigrations.migrators[1]],
|
||||
] as const) {
|
||||
test(`${name}: up works as expected`, () => {
|
||||
const before = { props: {} }
|
||||
|
@ -300,7 +302,7 @@ describe('Adding url props', () => {
|
|||
})
|
||||
|
||||
describe('Bookmark null asset id', () => {
|
||||
const { up, down } = bookmarkShapeMigrations.migrators[1]
|
||||
const { up, down } = bookmarkShapeTypeMigrations.migrators[1]
|
||||
test('up works as expected', () => {
|
||||
const before = { props: {} }
|
||||
const after = { props: { assetId: null } }
|
||||
|
@ -376,7 +378,7 @@ describe('Cleaning up junk data in instance.propsForNextShape', () => {
|
|||
})
|
||||
|
||||
describe('Generating original URL from embed URL in GenOriginalUrlInEmbed', () => {
|
||||
const { up, down } = embedShapeMigrations.migrators[1]
|
||||
const { up, down } = embedShapeTypeMigrations.migrators[1]
|
||||
test('up works as expected', () => {
|
||||
expect(up({ props: { url: 'https://codepen.io/Rplus/embed/PWZYRM' } })).toEqual({
|
||||
props: {
|
||||
|
@ -417,7 +419,7 @@ describe('Generating original URL from embed URL in GenOriginalUrlInEmbed', () =
|
|||
})
|
||||
|
||||
describe('Adding isPen prop', () => {
|
||||
const { up, down } = drawShapeMigrations.migrators[1]
|
||||
const { up, down } = drawShapeTypeMigrations.migrators[1]
|
||||
|
||||
test('up works as expected with a shape that is not a pen shape', () => {
|
||||
expect(
|
||||
|
@ -502,8 +504,8 @@ describe('Adding isLocked prop', () => {
|
|||
|
||||
describe('Adding labelColor prop to geo / arrow shapes', () => {
|
||||
for (const [name, { up, down }] of [
|
||||
['arrow shape', arrowShapeMigrations.migrators[1]],
|
||||
['geo shape', geoShapeMigrations.migrators[2]],
|
||||
['arrow shape', arrowShapeTypeMigrations.migrators[1]],
|
||||
['geo shape', geoShapeTypeMigrations.migrators[2]],
|
||||
] as const) {
|
||||
test(`${name}: up works as expected`, () => {
|
||||
expect(up({ props: { color: 'red' } })).toEqual({
|
||||
|
@ -600,9 +602,9 @@ describe('Adding zoomBrush prop to instance', () => {
|
|||
|
||||
describe('Removing align=justify from shape align props', () => {
|
||||
for (const [name, { up, down }] of [
|
||||
['text', textShapeMigrations.migrators[1]],
|
||||
['note', noteShapeMigrations.migrators[2]],
|
||||
['geo', geoShapeMigrations.migrators[3]],
|
||||
['text', textShapeTypeMigrations.migrators[1]],
|
||||
['note', noteShapeTypeMigrations.migrators[2]],
|
||||
['geo', geoShapeTypeMigrations.migrators[3]],
|
||||
] as const) {
|
||||
test(`${name}: up works as expected`, () => {
|
||||
expect(up({ props: { align: 'justify' } })).toEqual({
|
||||
|
@ -622,7 +624,7 @@ describe('Removing align=justify from shape align props', () => {
|
|||
})
|
||||
|
||||
describe('Add crop=null to image shapes', () => {
|
||||
const { up, down } = imageShapeMigrations.migrators[2]
|
||||
const { up, down } = imageShapeTypeMigrations.migrators[2]
|
||||
test('up works as expected', () => {
|
||||
expect(up({ props: { w: 100 } })).toEqual({
|
||||
props: { w: 100, crop: null },
|
||||
|
@ -655,7 +657,7 @@ describe('Adding instance_presence to the schema', () => {
|
|||
})
|
||||
|
||||
describe('Adding check-box to geo shape', () => {
|
||||
const { up, down } = geoShapeMigrations.migrators[4]
|
||||
const { up, down } = geoShapeTypeMigrations.migrators[4]
|
||||
|
||||
test('up works as expected', () => {
|
||||
expect(up({ props: { geo: 'rectangle' } })).toEqual({ props: { geo: 'rectangle' } })
|
||||
|
@ -667,7 +669,7 @@ describe('Adding check-box to geo shape', () => {
|
|||
})
|
||||
|
||||
describe('Add verticalAlign to geo shape', () => {
|
||||
const { up, down } = geoShapeMigrations.migrators[5]
|
||||
const { up, down } = geoShapeTypeMigrations.migrators[5]
|
||||
|
||||
test('up works as expected', () => {
|
||||
expect(up({ props: { type: 'ellipse' } })).toEqual({
|
||||
|
|
|
@ -14,7 +14,6 @@ import { TLShape } from './TLShape'
|
|||
/** @public */
|
||||
export type TLAsset = TLImageAsset | TLVideoAsset | TLBookmarkAsset
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const assetTypeValidator: T.Validator<TLAsset> = T.model(
|
||||
'asset',
|
||||
|
@ -25,20 +24,8 @@ export const assetTypeValidator: T.Validator<TLAsset> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const assetTypeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {},
|
||||
subTypeKey: 'type',
|
||||
subTypeMigrations: {
|
||||
image: imageAssetMigrations,
|
||||
|
|
|
@ -16,7 +16,6 @@ export interface TLCamera extends BaseRecord<'camera'> {
|
|||
/** @public */
|
||||
export type TLCameraId = ID<TLCamera>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const cameraTypeValidator: T.Validator<TLCamera> = T.model(
|
||||
'camera',
|
||||
|
@ -29,25 +28,8 @@ export const cameraTypeValidator: T.Validator<TLCamera> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const cameraTypeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {},
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const TLCamera = createRecordType<TLCamera>('camera', {
|
||||
migrations: cameraTypeMigrations,
|
||||
validator: cameraTypeValidator,
|
||||
scope: 'instance',
|
||||
}).withDefaultProperties(
|
||||
|
@ -57,3 +39,6 @@ export const TLCamera = createRecordType<TLCamera>('camera', {
|
|||
z: 1,
|
||||
})
|
||||
)
|
||||
|
||||
/** @public */
|
||||
export const cameraTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -10,7 +10,6 @@ export interface TLDocument extends BaseRecord<'document'> {
|
|||
gridSize: number
|
||||
}
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const documentTypeValidator: T.Validator<TLDocument> = T.model(
|
||||
'document',
|
||||
|
@ -21,25 +20,8 @@ export const documentTypeValidator: T.Validator<TLDocument> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const documentTypeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {},
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const TLDocument = createRecordType<TLDocument>('document', {
|
||||
migrations: documentTypeMigrations,
|
||||
validator: documentTypeValidator,
|
||||
scope: 'document',
|
||||
}).withDefaultProperties(
|
||||
|
@ -51,3 +33,6 @@ export const TLDocument = createRecordType<TLDocument>('document', {
|
|||
// all document records have the same ID: 'document:document'
|
||||
/** @public */
|
||||
export const TLDOCUMENT_ID: ID<TLDocument> = TLDocument.createCustomId('document')
|
||||
|
||||
/** @public */
|
||||
export const documentTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -53,7 +53,6 @@ export interface TLInstance extends BaseRecord<'instance'> {
|
|||
/** @public */
|
||||
export type TLInstanceId = ID<TLInstance>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const instanceTypeValidator: T.Validator<TLInstance> = T.model(
|
||||
'instance',
|
||||
|
@ -91,11 +90,7 @@ export const instanceTypeValidator: T.Validator<TLInstance> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddTransparentExportBgs: 1,
|
||||
RemoveDialog: 2,
|
||||
AddToolLockMode: 3,
|
||||
|
@ -110,10 +105,7 @@ const Versions = {
|
|||
|
||||
/** @public */
|
||||
export const instanceTypeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.AddScribbleDelay,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {
|
||||
[Versions.AddTransparentExportBgs]: {
|
||||
up: (instance: TLInstance) => {
|
||||
|
|
|
@ -26,7 +26,6 @@ export interface TLInstancePageState extends BaseRecord<'instance_page_state'> {
|
|||
focusLayerId: TLShapeId | null
|
||||
}
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const instancePageStateTypeValidator: T.Validator<TLInstancePageState> = T.model(
|
||||
'instance_page_state',
|
||||
|
@ -46,17 +45,12 @@ export const instancePageStateTypeValidator: T.Validator<TLInstancePageState> =
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddCroppingId: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const instancePageStateMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.AddCroppingId,
|
||||
migrators: {
|
||||
[Versions.AddCroppingId]: {
|
||||
|
|
|
@ -65,20 +65,13 @@ export const instancePresenceTypeValidator: T.Validator<TLInstancePresence> = T.
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddScribbleDelay: 1,
|
||||
} as const
|
||||
|
||||
export const instancePresenceTypeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.AddScribbleDelay,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddScribbleDelay]: {
|
||||
up: (instance) => {
|
||||
if (instance.scribble !== null) {
|
||||
|
|
|
@ -15,7 +15,6 @@ export interface TLPage extends BaseRecord<'page'> {
|
|||
/** @public */
|
||||
export type TLPageId = ID<TLPage>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const pageTypeValidator: T.Validator<TLPage> = T.model(
|
||||
'page',
|
||||
|
@ -27,25 +26,11 @@ export const pageTypeValidator: T.Validator<TLPage> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const pageTypeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {},
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const TLPage = createRecordType<TLPage>('page', {
|
||||
migrations: pageTypeMigrations,
|
||||
validator: pageTypeValidator,
|
||||
scope: 'document',
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const pageTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -68,21 +68,14 @@ export type TLParentId = TLPageId | TLShapeId
|
|||
/** @public */
|
||||
export type TLNullableShapeProps = { [K in TLShapeProp]?: TLShapeProps[K] | null }
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddIsLocked: 1,
|
||||
} as const
|
||||
|
||||
/** @internal */
|
||||
export const rootShapeTypeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.AddIsLocked,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddIsLocked]: {
|
||||
up: (record) => {
|
||||
return {
|
||||
|
|
|
@ -15,7 +15,6 @@ export interface TLUser extends BaseRecord<'user'> {
|
|||
/** @public */
|
||||
export type TLUserId = ID<TLUser>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const userTypeValidator: T.Validator<TLUser> = T.model(
|
||||
'user',
|
||||
|
@ -27,26 +26,8 @@ export const userTypeValidator: T.Validator<TLUser> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const userTypeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const TLUser = createRecordType<TLUser>('user', {
|
||||
migrations: userTypeMigrations,
|
||||
validator: userTypeValidator,
|
||||
scope: 'instance',
|
||||
}).withDefaultProperties((): Omit<TLUser, 'id' | 'typeName'> => {
|
||||
|
@ -59,3 +40,6 @@ export const TLUser = createRecordType<TLUser>('user', {
|
|||
locale,
|
||||
}
|
||||
})
|
||||
|
||||
/** @public */
|
||||
export const userTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -26,7 +26,6 @@ export interface TLUserDocument extends BaseRecord<'user_document'> {
|
|||
/** @public */
|
||||
export type TLUserDocumentId = ID<TLUserDocument>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const userDocumentTypeValidator: T.Validator<TLUserDocument> = T.model(
|
||||
'user_document',
|
||||
|
@ -44,11 +43,7 @@ export const userDocumentTypeValidator: T.Validator<TLUserDocument> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
export const userDocumentVersions = {
|
||||
Initial: 0,
|
||||
export const Versions = {
|
||||
AddSnapMode: 1,
|
||||
AddMissingIsMobileMode: 2,
|
||||
RemoveIsReadOnly: 3,
|
||||
|
@ -56,12 +51,9 @@ export const userDocumentVersions = {
|
|||
|
||||
/** @public */
|
||||
export const userDocumentTypeMigrations = defineMigrations({
|
||||
firstVersion: userDocumentVersions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: userDocumentVersions.RemoveIsReadOnly,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
currentVersion: Versions.RemoveIsReadOnly,
|
||||
migrators: {
|
||||
[userDocumentVersions.AddSnapMode]: {
|
||||
[Versions.AddSnapMode]: {
|
||||
up: (userDocument: TLUserDocument) => {
|
||||
return { ...userDocument, isSnapMode: false }
|
||||
},
|
||||
|
@ -69,7 +61,7 @@ export const userDocumentTypeMigrations = defineMigrations({
|
|||
return userDocument
|
||||
},
|
||||
},
|
||||
[userDocumentVersions.AddMissingIsMobileMode]: {
|
||||
[Versions.AddMissingIsMobileMode]: {
|
||||
up: (userDocument: TLUserDocument) => {
|
||||
return { ...userDocument, isMobileMode: userDocument.isMobileMode ?? false }
|
||||
},
|
||||
|
@ -77,7 +69,7 @@ export const userDocumentTypeMigrations = defineMigrations({
|
|||
return userDocument
|
||||
},
|
||||
},
|
||||
[userDocumentVersions.RemoveIsReadOnly]: {
|
||||
[Versions.RemoveIsReadOnly]: {
|
||||
up: ({ isReadOnly: _, ...userDocument }: TLUserDocument & { isReadOnly: boolean }) => {
|
||||
return userDocument
|
||||
},
|
||||
|
@ -107,3 +99,5 @@ export const TLUserDocument = createRecordType<TLUserDocument>('user_document',
|
|||
lastUsedTabId: null,
|
||||
})
|
||||
)
|
||||
|
||||
export { Versions as userDocumentVersions }
|
||||
|
|
|
@ -18,7 +18,6 @@ export interface TLUserPresence extends BaseRecord<'user_presence'> {
|
|||
/** @public */
|
||||
export type TLUserPresenceId = ID<TLUserPresence>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const userPresenceTypeValidator: T.Validator<TLUserPresence> = T.model(
|
||||
'user_presence',
|
||||
|
@ -34,21 +33,14 @@ export const userPresenceTypeValidator: T.Validator<TLUserPresence> = T.model(
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddViewportPageBounds: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const userPresenceTypeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.AddViewportPageBounds,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddViewportPageBounds]: {
|
||||
up: (record) => {
|
||||
return {
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
import { defineMigrations, StoreSnapshot } from '@tldraw/tlstore'
|
||||
import { TLRecord } from './TLRecord'
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
RemoveCodeAndIconShapeTypes: 1,
|
||||
AddInstancePresenceType: 2,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const storeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.AddInstancePresenceType,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.RemoveCodeAndIconShapeTypes]: {
|
||||
up: (store: StoreSnapshot<TLRecord>) => {
|
||||
return Object.fromEntries(
|
||||
|
|
|
@ -70,7 +70,6 @@ export interface TLArrowHeadModel {
|
|||
type: TLArrowheadType
|
||||
}
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const arrowTerminalTypeValidator: T.Validator<TLArrowTerminal> = T.union('type', {
|
||||
binding: T.object({
|
||||
|
@ -106,21 +105,14 @@ export const arrowShapeTypeValidator: T.Validator<TLArrowShape> = createShapeVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddLabelColor: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const arrowShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
export const arrowShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.AddLabelColor,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddLabelColor]: {
|
||||
up: (record) => {
|
||||
return {
|
||||
|
|
|
@ -17,7 +17,6 @@ export type TLBookmarkShapeProps = {
|
|||
/** @public */
|
||||
export type TLBookmarkShape = TLBaseShape<'bookmark', TLBookmarkShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const bookmarkShapeTypeValidator: T.Validator<TLBookmarkShape> = createShapeValidator(
|
||||
'bookmark',
|
||||
|
@ -30,20 +29,13 @@ export const bookmarkShapeTypeValidator: T.Validator<TLBookmarkShape> = createSh
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
NullAssetId: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const bookmarkShapeMigrations = defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
export const bookmarkShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.NullAssetId,
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
migrators: {
|
||||
[Versions.NullAssetId]: {
|
||||
up: (shape: TLBookmarkShape) => {
|
||||
|
|
|
@ -37,7 +37,6 @@ export type TLDrawShapeProps = {
|
|||
/** @public */
|
||||
export type TLDrawShape = TLBaseShape<'draw', TLDrawShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const drawShapeTypeValidator: T.Validator<TLDrawShape> = createShapeValidator(
|
||||
'draw',
|
||||
|
@ -59,21 +58,14 @@ export const drawShapeTypeValidator: T.Validator<TLDrawShape> = createShapeValid
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddInPen: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const drawShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const drawShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.AddInPen,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddInPen]: {
|
||||
up: (shape) => {
|
||||
// Rather than checking to see whether the shape is a pen at runtime,
|
||||
|
|
|
@ -78,7 +78,6 @@ export type TLEmbedShapeProps = {
|
|||
/** @public */
|
||||
export type TLEmbedShape = TLBaseShape<'embed', TLEmbedShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const embedShapeTypeValidator: T.Validator<TLEmbedShape> = createShapeValidator(
|
||||
'embed',
|
||||
|
@ -605,21 +604,14 @@ export const EMBED_DEFINITIONS = [
|
|||
},
|
||||
] as const satisfies readonly EmbedDefinition[]
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
GenOriginalUrlInEmbed: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const embedShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
export const embedShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.GenOriginalUrlInEmbed,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.GenOriginalUrlInEmbed]: {
|
||||
// add tmpOldUrl property
|
||||
up: (shape) => {
|
||||
|
|
|
@ -15,7 +15,6 @@ export type TLFrameShapeProps = {
|
|||
/** @public */
|
||||
export type TLFrameShape = TLBaseShape<'frame', TLFrameShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const frameShapeTypeValidator: T.Validator<TLFrameShape> = createShapeValidator(
|
||||
'frame',
|
||||
|
@ -27,19 +26,5 @@ export const frameShapeTypeValidator: T.Validator<TLFrameShape> = createShapeVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const frameShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
export const frameShapeTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -46,7 +46,6 @@ export type TLGeoShapeProps = {
|
|||
/** @public */
|
||||
export type TLGeoShape = TLBaseShape<'geo', TLGeoShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const geoShapeTypeValidator: T.Validator<TLGeoShape> = createShapeValidator(
|
||||
'geo',
|
||||
|
@ -69,11 +68,7 @@ export const geoShapeTypeValidator: T.Validator<TLGeoShape> = createShapeValidat
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddUrlProp: 1,
|
||||
AddLabelColor: 2,
|
||||
RemoveJustify: 3,
|
||||
|
@ -82,12 +77,9 @@ const Versions = {
|
|||
} as const
|
||||
|
||||
/** @public */
|
||||
export const geoShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const geoShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.AddVerticalAlign,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddUrlProp]: {
|
||||
up: (shape) => {
|
||||
return { ...shape, props: { ...shape.props, url: '' } }
|
||||
|
|
|
@ -12,7 +12,6 @@ export type TLGroupShapeProps = {
|
|||
/** @public */
|
||||
export type TLGroupShape = TLBaseShape<'group', TLGroupShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const groupShapeTypeValidator: T.Validator<TLGroupShape> = createShapeValidator(
|
||||
'group',
|
||||
|
@ -21,19 +20,5 @@ export const groupShapeTypeValidator: T.Validator<TLGroupShape> = createShapeVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const groupShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
export const groupShapeTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -23,7 +23,6 @@ export type TLIconShapeProps = {
|
|||
/** @public */
|
||||
export type TLIconShape = TLBaseShape<'icon', TLIconShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const iconShapeTypeValidator: T.Validator<TLIconShape> = createShapeValidator(
|
||||
'icon',
|
||||
|
@ -37,19 +36,5 @@ export const iconShapeTypeValidator: T.Validator<TLIconShape> = createShapeValid
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const iconShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
export const iconShapeTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -32,7 +32,6 @@ export const cropValidator = T.object({
|
|||
/** @public */
|
||||
export type TLImageShape = TLBaseShape<'image', TLImageShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const imageShapeTypeValidator: T.Validator<TLImageShape> = createShapeValidator(
|
||||
'image',
|
||||
|
@ -47,22 +46,15 @@ export const imageShapeTypeValidator: T.Validator<TLImageShape> = createShapeVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddUrlProp: 1,
|
||||
AddCropProp: 2,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const imageShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const imageShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.AddCropProp,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddUrlProp]: {
|
||||
up: (shape) => {
|
||||
return { ...shape, props: { ...shape.props, url: '' } }
|
||||
|
|
|
@ -26,7 +26,6 @@ export type TLLineShapeProps = {
|
|||
/** @public */
|
||||
export type TLLineShape = TLBaseShape<'line', TLLineShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const lineShapeTypeValidator: T.Validator<TLLineShape> = createShapeValidator(
|
||||
'line',
|
||||
|
@ -40,19 +39,5 @@ export const lineShapeTypeValidator: T.Validator<TLLineShape> = createShapeValid
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const lineShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
currentVersion: Versions.Initial,
|
||||
firstVersion: Versions.Initial,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
},
|
||||
})
|
||||
export const lineShapeTypeMigrations = defineMigrations({})
|
||||
|
|
|
@ -25,7 +25,6 @@ export type TLNoteShapeProps = {
|
|||
/** @public */
|
||||
export type TLNoteShape = TLBaseShape<'note', TLNoteShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const noteShapeTypeValidator: T.Validator<TLNoteShape> = createShapeValidator(
|
||||
'note',
|
||||
|
@ -41,22 +40,15 @@ export const noteShapeTypeValidator: T.Validator<TLNoteShape> = createShapeValid
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddUrlProp: 1,
|
||||
RemoveJustify: 2,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const noteShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const noteShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.RemoveJustify,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddUrlProp]: {
|
||||
up: (shape) => {
|
||||
return { ...shape, props: { ...shape.props, url: '' } }
|
||||
|
|
|
@ -26,7 +26,6 @@ export type TLTextShapeProps = {
|
|||
/** @public */
|
||||
export type TLTextShape = TLBaseShape<'text', TLTextShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const textShapeTypeValidator: T.Validator<TLTextShape> = createShapeValidator(
|
||||
'text',
|
||||
|
@ -43,18 +42,12 @@ export const textShapeTypeValidator: T.Validator<TLTextShape> = createShapeValid
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
RemoveJustify: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const textShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const textShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.RemoveJustify,
|
||||
migrators: {
|
||||
[Versions.RemoveJustify]: {
|
||||
|
|
|
@ -19,7 +19,6 @@ export type TLVideoShapeProps = {
|
|||
/** @public */
|
||||
export type TLVideoShape = TLBaseShape<'video', TLVideoShapeProps>
|
||||
|
||||
// --- VALIDATION ---
|
||||
/** @public */
|
||||
export const videoShapeTypeValidator: T.Validator<TLVideoShape> = createShapeValidator(
|
||||
'video',
|
||||
|
@ -34,21 +33,14 @@ export const videoShapeTypeValidator: T.Validator<TLVideoShape> = createShapeVal
|
|||
})
|
||||
)
|
||||
|
||||
// --- MIGRATIONS ---
|
||||
// STEP 1: Add a new version number here, give it a meaningful name.
|
||||
// It should be 1 higher than the current version
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
AddUrlProp: 1,
|
||||
} as const
|
||||
|
||||
/** @public */
|
||||
export const videoShapeMigrations = defineMigrations({
|
||||
// STEP 2: Update the current version to point to your latest version
|
||||
firstVersion: Versions.Initial,
|
||||
export const videoShapeTypeMigrations = defineMigrations({
|
||||
currentVersion: Versions.AddUrlProp,
|
||||
migrators: {
|
||||
// STEP 3: Add an up+down migration for the new version here
|
||||
[Versions.AddUrlProp]: {
|
||||
up: (shape) => {
|
||||
return { ...shape, props: { ...shape.props, url: '' } }
|
||||
|
|
|
@ -47,12 +47,16 @@ export function createRecordType<R extends BaseRecord>(typeName: R['typeName'],
|
|||
}): RecordType<R, keyof Omit<R, 'id' | 'typeName'>>;
|
||||
|
||||
// @public (undocumented)
|
||||
export function defineMigrations<FirstVersion extends number, CurrentVersion extends number>({ firstVersion, currentVersion, migrators, subTypeKey, subTypeMigrations, }: {
|
||||
firstVersion: FirstVersion;
|
||||
currentVersion: CurrentVersion;
|
||||
migrators: {
|
||||
export function defineMigrations<FirstVersion extends EMPTY_SYMBOL | number = EMPTY_SYMBOL, CurrentVersion extends EMPTY_SYMBOL | Exclude<number, 0> = EMPTY_SYMBOL>(opts: {
|
||||
firstVersion?: CurrentVersion extends number ? FirstVersion : never;
|
||||
currentVersion?: CurrentVersion;
|
||||
migrators?: CurrentVersion extends number ? FirstVersion extends number ? CurrentVersion extends FirstVersion ? {
|
||||
[version in Exclude<Range_2<1, CurrentVersion>, 0>]: Migration;
|
||||
} : {
|
||||
[version in Exclude<Range_2<FirstVersion, CurrentVersion>, FirstVersion>]: Migration;
|
||||
};
|
||||
} : {
|
||||
[version in Exclude<Range_2<1, CurrentVersion>, 0>]: Migration;
|
||||
} : never;
|
||||
subTypeKey?: string;
|
||||
subTypeMigrations?: Record<string, BaseMigrationsInfo>;
|
||||
}): Migrations;
|
||||
|
@ -106,9 +110,9 @@ export function migrateRecord<R extends BaseRecord>({ record, migrations, fromVe
|
|||
}): MigrationResult<R>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type Migration<T = any> = {
|
||||
up: (oldState: T) => T;
|
||||
down: (newState: T) => T;
|
||||
export type Migration<Before = any, After = any> = {
|
||||
up: (oldState: Before) => After;
|
||||
down: (newState: After) => Before;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
|
|
|
@ -1,29 +1,49 @@
|
|||
import { BaseRecord, isRecord } from './BaseRecord'
|
||||
import { SerializedSchema } from './StoreSchema'
|
||||
|
||||
type EMPTY_SYMBOL = symbol
|
||||
|
||||
/** @public */
|
||||
export function defineMigrations<FirstVersion extends number, CurrentVersion extends number>({
|
||||
firstVersion,
|
||||
currentVersion,
|
||||
migrators,
|
||||
subTypeKey,
|
||||
subTypeMigrations,
|
||||
}: {
|
||||
firstVersion: FirstVersion
|
||||
currentVersion: CurrentVersion
|
||||
migrators: {
|
||||
[version in Exclude<Range<FirstVersion, CurrentVersion>, FirstVersion>]: Migration
|
||||
}
|
||||
export function defineMigrations<
|
||||
FirstVersion extends number | EMPTY_SYMBOL = EMPTY_SYMBOL,
|
||||
CurrentVersion extends Exclude<number, 0> | EMPTY_SYMBOL = EMPTY_SYMBOL
|
||||
>(opts: {
|
||||
firstVersion?: CurrentVersion extends number ? FirstVersion : never
|
||||
currentVersion?: CurrentVersion
|
||||
migrators?: CurrentVersion extends number
|
||||
? FirstVersion extends number
|
||||
? CurrentVersion extends FirstVersion
|
||||
? { [version in Exclude<Range<1, CurrentVersion>, 0>]: Migration }
|
||||
: { [version in Exclude<Range<FirstVersion, CurrentVersion>, FirstVersion>]: Migration }
|
||||
: { [version in Exclude<Range<1, CurrentVersion>, 0>]: Migration }
|
||||
: never
|
||||
subTypeKey?: string
|
||||
subTypeMigrations?: Record<string, BaseMigrationsInfo>
|
||||
}): Migrations {
|
||||
return { currentVersion, firstVersion, migrators, subTypeKey, subTypeMigrations }
|
||||
const { currentVersion, firstVersion, migrators = {}, subTypeKey, subTypeMigrations } = opts
|
||||
|
||||
// Some basic guards against impossible version combinations, some of which will be caught by TypeScript
|
||||
if (typeof currentVersion === 'number' && typeof firstVersion === 'number') {
|
||||
if ((currentVersion as number) === (firstVersion as number)) {
|
||||
throw Error(`Current version is equal to initial version.`)
|
||||
} else if (currentVersion < firstVersion) {
|
||||
throw Error(`Current version is lower than initial version.`)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
firstVersion: (firstVersion as number) ?? 0, // defaults
|
||||
currentVersion: (currentVersion as number) ?? 0, // defaults
|
||||
migrators,
|
||||
subTypeKey,
|
||||
subTypeMigrations,
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type Migration<T = any> = {
|
||||
up: (oldState: T) => T
|
||||
down: (newState: T) => T
|
||||
export type Migration<Before = any, After = any> = {
|
||||
up: (oldState: Before) => After
|
||||
down: (newState: After) => Before
|
||||
}
|
||||
|
||||
interface BaseMigrationsInfo {
|
||||
|
|
229
packages/tlstore/src/lib/test/defineMigrations.test.ts
Normal file
229
packages/tlstore/src/lib/test/defineMigrations.test.ts
Normal file
|
@ -0,0 +1,229 @@
|
|||
import { defineMigrations } from '../migrate'
|
||||
|
||||
const Versions = {
|
||||
Initial: 0,
|
||||
January: 1,
|
||||
February: 2,
|
||||
March: 3,
|
||||
} as const
|
||||
|
||||
describe('define migrations tests', () => {
|
||||
it('defines migrations', () => {
|
||||
expect(() => {
|
||||
// no versions
|
||||
defineMigrations({
|
||||
// @ts-expect-error first version without current version
|
||||
firstVersion: Versions.Initial,
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// no versions
|
||||
defineMigrations({
|
||||
// @ts-expect-error first version without current version
|
||||
firstVersion: Versions.February,
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// empty migrators
|
||||
defineMigrations({
|
||||
// @ts-expect-error
|
||||
migrators: {},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// no versions!
|
||||
defineMigrations({
|
||||
// @ts-expect-error
|
||||
migrators: {
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// wrong current version!
|
||||
defineMigrations({
|
||||
currentVersion: Versions.January,
|
||||
migrators: {
|
||||
// @ts-expect-error
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
defineMigrations({
|
||||
currentVersion: Versions.February,
|
||||
migrators: {
|
||||
// has a default zero version
|
||||
[Versions.January]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
// has a current version
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// can't provide only first version
|
||||
defineMigrations({
|
||||
// @ts-expect-error first version without current version
|
||||
firstVersion: Versions.January,
|
||||
// @ts-expect-error migrators without current version
|
||||
migrators: {},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// same version
|
||||
defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.Initial,
|
||||
migrators: {},
|
||||
})
|
||||
}).toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// only first version
|
||||
defineMigrations({
|
||||
// @ts-expect-error
|
||||
firstVersion: Versions.January,
|
||||
// @ts-expect-error
|
||||
migrators: {},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// missing only version
|
||||
defineMigrations({
|
||||
firstVersion: Versions.January,
|
||||
currentVersion: Versions.January,
|
||||
// @ts-expect-error
|
||||
migrators: {},
|
||||
})
|
||||
}).toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// only version, explicit start and current
|
||||
defineMigrations({
|
||||
firstVersion: Versions.January,
|
||||
currentVersion: Versions.January,
|
||||
migrators: {
|
||||
[Versions.January]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// missing later versions
|
||||
defineMigrations({
|
||||
firstVersion: Versions.January,
|
||||
currentVersion: Versions.February,
|
||||
// @ts-expect-error
|
||||
migrators: {},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// missing later versions
|
||||
defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.February,
|
||||
// @ts-expect-error
|
||||
migrators: {
|
||||
[Versions.January]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// missing earlier versions
|
||||
defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.February,
|
||||
// @ts-expect-error
|
||||
migrators: {
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// got em all
|
||||
defineMigrations({
|
||||
firstVersion: Versions.Initial,
|
||||
currentVersion: Versions.February,
|
||||
migrators: {
|
||||
[Versions.January]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// got em all starting later
|
||||
defineMigrations({
|
||||
firstVersion: Versions.January,
|
||||
currentVersion: Versions.March,
|
||||
migrators: {
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
[Versions.March]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
|
||||
expect(() => {
|
||||
// first migration should be first version + 1
|
||||
defineMigrations({
|
||||
firstVersion: Versions.February,
|
||||
currentVersion: Versions.March,
|
||||
migrators: {
|
||||
// @ts-expect-error
|
||||
[Versions.February]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
[Versions.March]: {
|
||||
up: (rec: any) => rec,
|
||||
down: (rec: any) => rec,
|
||||
},
|
||||
},
|
||||
})
|
||||
}).not.toThrowError()
|
||||
})
|
||||
})
|
|
@ -4,20 +4,12 @@ import { createRecordType } from '../RecordType'
|
|||
import { StoreSchema } from '../StoreSchema'
|
||||
import { defineMigrations } from '../migrate'
|
||||
|
||||
const UserVersion = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
/** A user of tldraw */
|
||||
interface User extends BaseRecord<'user'> {
|
||||
name: string
|
||||
}
|
||||
|
||||
const userMigrations = defineMigrations({
|
||||
currentVersion: UserVersion.Initial,
|
||||
firstVersion: UserVersion.Initial,
|
||||
migrators: {},
|
||||
})
|
||||
const userMigrations = defineMigrations({})
|
||||
|
||||
const User = createRecordType<User>('user', {
|
||||
migrations: userMigrations,
|
||||
|
@ -32,14 +24,6 @@ const User = createRecordType<User>('user', {
|
|||
scope: 'document',
|
||||
})
|
||||
|
||||
const ShapeVersion = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
const RectangleVersion = {
|
||||
Initial: 0,
|
||||
} as const
|
||||
|
||||
interface Shape<Props> extends BaseRecord<'shape'> {
|
||||
type: string
|
||||
x: number
|
||||
|
@ -58,22 +42,15 @@ interface OvalProps {
|
|||
borderStyle: 'solid' | 'dashed'
|
||||
}
|
||||
|
||||
const shapeMigrations = defineMigrations({
|
||||
currentVersion: ShapeVersion.Initial,
|
||||
firstVersion: ShapeVersion.Initial,
|
||||
migrators: {},
|
||||
const shapeTypeMigrations = defineMigrations({
|
||||
subTypeKey: 'type',
|
||||
subTypeMigrations: {
|
||||
rectangle: defineMigrations({
|
||||
currentVersion: RectangleVersion.Initial,
|
||||
firstVersion: RectangleVersion.Initial,
|
||||
migrators: {},
|
||||
}),
|
||||
rectangle: defineMigrations({}),
|
||||
},
|
||||
})
|
||||
|
||||
const Shape = createRecordType<Shape<RectangleProps | OvalProps>>('shape', {
|
||||
migrations: shapeMigrations,
|
||||
migrations: shapeTypeMigrations,
|
||||
validator: {
|
||||
validate: (record) => {
|
||||
assert(
|
||||
|
@ -100,7 +77,7 @@ interface Org extends BaseRecord<'org'> {
|
|||
}
|
||||
|
||||
const Org = createRecordType<Org>('org', {
|
||||
migrations: defineMigrations({ currentVersion: 0, firstVersion: 0, migrators: {} }),
|
||||
migrations: defineMigrations({}),
|
||||
validator: {
|
||||
validate: (record) => {
|
||||
assert(
|
||||
|
@ -119,6 +96,6 @@ export const testSchemaV0 = StoreSchema.create(
|
|||
org: Org,
|
||||
},
|
||||
{
|
||||
snapshotMigrations: defineMigrations({ currentVersion: 0, firstVersion: 0, migrators: {} }),
|
||||
snapshotMigrations: defineMigrations({}),
|
||||
}
|
||||
)
|
||||
|
|
|
@ -6,7 +6,6 @@ import { StoreSchema } from '../StoreSchema'
|
|||
import { defineMigrations } from '../migrate'
|
||||
|
||||
const UserVersion = {
|
||||
Initial: 0,
|
||||
AddLocale: 1,
|
||||
AddPhoneNumber: 2,
|
||||
} as const
|
||||
|
@ -20,7 +19,6 @@ interface User extends BaseRecord<'user'> {
|
|||
|
||||
const userMigrations = defineMigrations({
|
||||
currentVersion: UserVersion.AddPhoneNumber,
|
||||
firstVersion: UserVersion.Initial,
|
||||
migrators: {
|
||||
[UserVersion.AddLocale]: {
|
||||
up: (record) => ({
|
||||
|
@ -69,18 +67,15 @@ const User = createRecordType<User>('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
|
||||
|
||||
|
@ -104,9 +99,8 @@ interface OvalProps {
|
|||
borderStyle: 'solid' | 'dashed'
|
||||
}
|
||||
|
||||
const shapeMigrations = defineMigrations({
|
||||
const shapeTypeMigrations = defineMigrations({
|
||||
currentVersion: ShapeVersion.AddParent,
|
||||
firstVersion: ShapeVersion.Initial,
|
||||
migrators: {
|
||||
[ShapeVersion.AddRotation]: {
|
||||
up: (record) => ({
|
||||
|
@ -135,7 +129,6 @@ const shapeMigrations = defineMigrations({
|
|||
subTypeMigrations: {
|
||||
rectangle: defineMigrations({
|
||||
currentVersion: RectangleVersion.AddOpacity,
|
||||
firstVersion: RectangleVersion.Initial,
|
||||
migrators: {
|
||||
[RectangleVersion.AddOpacity]: {
|
||||
up: (record) => ({
|
||||
|
@ -157,7 +150,6 @@ const shapeMigrations = defineMigrations({
|
|||
}),
|
||||
oval: defineMigrations({
|
||||
currentVersion: OvalVersion.AddBorderStyle,
|
||||
firstVersion: OvalVersion.Initial,
|
||||
migrators: {
|
||||
[OvalVersion.AddBorderStyle]: {
|
||||
up: (record) => ({
|
||||
|
@ -181,7 +173,7 @@ const shapeMigrations = defineMigrations({
|
|||
})
|
||||
|
||||
const Shape = createRecordType<Shape<RectangleProps | OvalProps>>('shape', {
|
||||
migrations: shapeMigrations,
|
||||
migrations: shapeTypeMigrations,
|
||||
validator: {
|
||||
validate: (record) => {
|
||||
assert(record && typeof record === 'object')
|
||||
|
@ -202,13 +194,11 @@ const Shape = createRecordType<Shape<RectangleProps | OvalProps>>('shape', {
|
|||
}))
|
||||
|
||||
const StoreVersions = {
|
||||
Initial: 0,
|
||||
RemoveOrg: 1,
|
||||
}
|
||||
|
||||
const snapshotMigrations = defineMigrations({
|
||||
currentVersion: StoreVersions.RemoveOrg,
|
||||
firstVersion: StoreVersions.Initial,
|
||||
migrators: {
|
||||
[StoreVersions.RemoveOrg]: {
|
||||
up: (store: StoreSnapshot<any>) => {
|
||||
|
|
Loading…
Reference in a new issue