@tldraw/tlschema 4.6.0-next.d8328a2dcc3d → 4.6.0-next.e390fde97eab
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/assets/TLBaseAsset.js +4 -3
- package/dist-cjs/assets/TLBaseAsset.js.map +2 -2
- package/dist-cjs/assets/TLBookmarkAsset.js +9 -7
- package/dist-cjs/assets/TLBookmarkAsset.js.map +2 -2
- package/dist-cjs/assets/TLImageAsset.js +12 -10
- package/dist-cjs/assets/TLImageAsset.js.map +2 -2
- package/dist-cjs/assets/TLVideoAsset.js +11 -9
- package/dist-cjs/assets/TLVideoAsset.js.map +2 -2
- package/dist-cjs/createTLSchema.js +10 -4
- package/dist-cjs/createTLSchema.js.map +2 -2
- package/dist-cjs/index.d.ts +601 -343
- package/dist-cjs/index.js +17 -7
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/records/TLAsset.js +29 -14
- package/dist-cjs/records/TLAsset.js.map +2 -2
- package/dist-cjs/shapes/TLFrameShape.js +3 -1
- package/dist-cjs/shapes/TLFrameShape.js.map +2 -2
- package/dist-cjs/shapes/TLNoteShape.js +12 -2
- package/dist-cjs/shapes/TLNoteShape.js.map +2 -2
- package/dist-cjs/styles/StyleProp.js +38 -1
- package/dist-cjs/styles/StyleProp.js.map +2 -2
- package/dist-cjs/styles/TLColorStyle.js +36 -487
- package/dist-cjs/styles/TLColorStyle.js.map +2 -2
- package/dist-cjs/styles/TLDashStyle.js +1 -1
- package/dist-cjs/styles/TLDashStyle.js.map +2 -2
- package/dist-cjs/styles/TLFontFace.js +17 -0
- package/dist-cjs/styles/TLFontFace.js.map +7 -0
- package/dist-cjs/styles/TLFontStyle.js +36 -1
- package/dist-cjs/styles/TLFontStyle.js.map +2 -2
- package/dist-cjs/styles/TLTheme.js +17 -0
- package/dist-cjs/styles/TLTheme.js.map +7 -0
- package/dist-esm/assets/TLBaseAsset.mjs +4 -3
- package/dist-esm/assets/TLBaseAsset.mjs.map +2 -2
- package/dist-esm/assets/TLBookmarkAsset.mjs +9 -7
- package/dist-esm/assets/TLBookmarkAsset.mjs.map +2 -2
- package/dist-esm/assets/TLImageAsset.mjs +12 -10
- package/dist-esm/assets/TLImageAsset.mjs.map +2 -2
- package/dist-esm/assets/TLVideoAsset.mjs +11 -9
- package/dist-esm/assets/TLVideoAsset.mjs.map +2 -2
- package/dist-esm/createTLSchema.mjs +17 -8
- package/dist-esm/createTLSchema.mjs.map +2 -2
- package/dist-esm/index.d.mts +601 -343
- package/dist-esm/index.mjs +28 -14
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/records/TLAsset.mjs +29 -14
- package/dist-esm/records/TLAsset.mjs.map +2 -2
- package/dist-esm/shapes/TLFrameShape.mjs +3 -1
- package/dist-esm/shapes/TLFrameShape.mjs.map +2 -2
- package/dist-esm/shapes/TLNoteShape.mjs +12 -2
- package/dist-esm/shapes/TLNoteShape.mjs.map +2 -2
- package/dist-esm/styles/StyleProp.mjs +38 -1
- package/dist-esm/styles/StyleProp.mjs.map +2 -2
- package/dist-esm/styles/TLColorStyle.mjs +36 -487
- package/dist-esm/styles/TLColorStyle.mjs.map +2 -2
- package/dist-esm/styles/TLDashStyle.mjs +1 -1
- package/dist-esm/styles/TLDashStyle.mjs.map +2 -2
- package/dist-esm/styles/TLFontFace.mjs +1 -0
- package/dist-esm/styles/TLFontFace.mjs.map +7 -0
- package/dist-esm/styles/TLFontStyle.mjs +36 -1
- package/dist-esm/styles/TLFontStyle.mjs.map +2 -2
- package/dist-esm/styles/TLTheme.mjs +1 -0
- package/dist-esm/styles/TLTheme.mjs.map +7 -0
- package/package.json +5 -5
- package/src/assets/TLBaseAsset.ts +25 -28
- package/src/assets/TLBookmarkAsset.ts +13 -33
- package/src/assets/TLImageAsset.ts +16 -42
- package/src/assets/TLVideoAsset.ts +15 -40
- package/src/createTLSchema.ts +54 -15
- package/src/index.ts +31 -11
- package/src/migrations.test.ts +22 -0
- package/src/records/TLAsset.ts +139 -74
- package/src/shapes/TLFrameShape.ts +3 -1
- package/src/shapes/TLNoteShape.ts +19 -5
- package/src/styles/StyleProp.ts +42 -5
- package/src/styles/TLColorStyle.ts +55 -698
- package/src/styles/TLDashStyle.ts +1 -1
- package/src/styles/TLFontFace.ts +65 -0
- package/src/styles/TLFontStyle.ts +53 -4
- package/src/styles/TLTheme.ts +240 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var TLFontFace_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(TLFontFace_exports);
|
|
17
|
+
//# sourceMappingURL=TLFontFace.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/styles/TLFontFace.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Represents the `src` property of a {@link TLFontFace}.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`} for details of the properties here.\n * @public\n */\nexport interface TLFontFaceSource {\n\t/**\n\t * A URL from which to load the font. If the value here is a key in\n\t * {@link tldraw#TLEditorAssetUrls.fonts}, the value from there will be used instead.\n\t */\n\turl: string\n\tformat?: string\n\ttech?: string\n}\n\n/**\n * A font face that can be used in the editor. The properties of this are largely the same as the\n * ones in the\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face | css `@font-face` rule}.\n * @public\n */\nexport interface TLFontFace {\n\t/**\n\t * How this font can be referred to in CSS.\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family | `font-family`}.\n\t */\n\treadonly family: string\n\t/**\n\t * The source of the font. This\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`}.\n\t */\n\treadonly src: TLFontFaceSource\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/ascent-override | `ascent-override`}.\n\t */\n\treadonly ascentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/descent-override | `descent-override`}.\n\t */\n\treadonly descentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch | `font-stretch`}.\n\t */\n\treadonly stretch?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-style | `font-style`}.\n\t */\n\treadonly style?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight | `font-weight`}.\n\t */\n\treadonly weight?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings | `font-feature-settings`}.\n\t */\n\treadonly featureSettings?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/line-gap-override | `line-gap-override`}.\n\t */\n\treadonly lineGapOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range | `unicode-range`}.\n\t */\n\treadonly unicodeRange?: string\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -19,7 +19,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var TLFontStyle_exports = {};
|
|
20
20
|
__export(TLFontStyle_exports, {
|
|
21
21
|
DefaultFontFamilies: () => DefaultFontFamilies,
|
|
22
|
-
DefaultFontStyle: () => DefaultFontStyle
|
|
22
|
+
DefaultFontStyle: () => DefaultFontStyle,
|
|
23
|
+
isFontEntry: () => isFontEntry,
|
|
24
|
+
registerFontsFromThemes: () => registerFontsFromThemes
|
|
23
25
|
});
|
|
24
26
|
module.exports = __toCommonJS(TLFontStyle_exports);
|
|
25
27
|
var import_StyleProp = require("./StyleProp");
|
|
@@ -33,4 +35,37 @@ const DefaultFontFamilies = {
|
|
|
33
35
|
serif: "'tldraw_serif', serif",
|
|
34
36
|
mono: "'tldraw_mono', monospace"
|
|
35
37
|
};
|
|
38
|
+
function isFontEntry(value) {
|
|
39
|
+
return typeof value === "object" && value !== null && "fontFamily" in value;
|
|
40
|
+
}
|
|
41
|
+
function registerFontsFromThemes(definitions) {
|
|
42
|
+
const fontNames = /* @__PURE__ */ new Set();
|
|
43
|
+
for (const def of Object.values(definitions)) {
|
|
44
|
+
if (!def.fonts) continue;
|
|
45
|
+
for (const [key, value] of Object.entries(def.fonts)) {
|
|
46
|
+
if (isFontEntry(value)) {
|
|
47
|
+
fontNames.add(key);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const toAdd = [...fontNames].filter((v) => !DefaultFontStyle.values.includes(v));
|
|
52
|
+
if (toAdd.length > 0) {
|
|
53
|
+
DefaultFontStyle.addValues(...toAdd);
|
|
54
|
+
}
|
|
55
|
+
const toRemove = DefaultFontStyle.values.filter((v) => !fontNames.has(v));
|
|
56
|
+
if (toRemove.length > 0) {
|
|
57
|
+
DefaultFontStyle.removeValues(...toRemove);
|
|
58
|
+
}
|
|
59
|
+
if (process.env.NODE_ENV !== "production") {
|
|
60
|
+
for (const def of Object.values(definitions)) {
|
|
61
|
+
for (const font of fontNames) {
|
|
62
|
+
if (!def.fonts || !(font in def.fonts)) {
|
|
63
|
+
console.warn(
|
|
64
|
+
`Theme '${def.id}' is missing font '${font}'. Shapes using this font won't render correctly in this theme.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
36
71
|
//# sourceMappingURL=TLFontStyle.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/styles/TLFontStyle.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { StyleProp } from './StyleProp'\nimport { TLThemeFont, TLThemeFonts, TLThemes } from './TLTheme'\n\n/**\n * Default font style property used by tldraw shapes for text styling.\n * Controls which typeface is used for text content within shapes.\n *\n * Available values:\n * - `draw` - Hand-drawn, sketchy font style\n * - `sans` - Clean sans-serif font\n * - `serif` - Traditional serif font\n * - `mono` - Monospace font for code-like text\n *\n * @example\n * ```ts\n * import { DefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Use in shape props definition\n * interface MyTextShapeProps {\n * font: typeof DefaultFontStyle\n * // other props...\n * }\n *\n * // Create a text shape with monospace font\n * const textShape = {\n * // ... other properties\n * props: {\n * font: 'mono' as const,\n * // ... other props\n * }\n * }\n * ```\n *\n * @public\n */\nexport const DefaultFontStyle = StyleProp.defineEnum('tldraw:font', {\n\tdefaultValue: 'draw',\n\tvalues: ['draw', 'sans', 'serif', 'mono'],\n})\n\n/**\n * The names of all available font styles, derived from {@link TLThemeFonts}.\n * Extend {@link TLThemeFonts} to add custom font names.\n *\n * @example\n * ```ts\n * import { TLDefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Valid font style values\n * const drawFont: TLDefaultFontStyle = 'draw'\n * const sansFont: TLDefaultFontStyle = 'sans'\n * const serifFont: TLDefaultFontStyle = 'serif'\n * const monoFont: TLDefaultFontStyle = 'mono'\n *\n * // Use in a function parameter\n * function setTextFont(font: TLDefaultFontStyle) {\n * // Apply font style to text\n * }\n * ```\n *\n * @public\n */\nexport type TLDefaultFontStyle = keyof TLThemeFonts & string\n\n/**\n * Mapping of font style names to their corresponding CSS font-family declarations.\n * These are the actual CSS font families used when rendering text with each font style.\n *\n * @example\n * ```ts\n * import { DefaultFontFamilies, TLDefaultFontStyle } from '@tldraw/tlschema'\n *\n * // Get CSS font family for a font style\n * const fontStyle: TLDefaultFontStyle = 'mono'\n * const cssFamily = DefaultFontFamilies[fontStyle] // \"'tldraw_mono', monospace\"\n *\n * // Apply to DOM element\n * element.style.fontFamily = DefaultFontFamilies.sans\n * ```\n *\n * @public\n */\nexport const DefaultFontFamilies = {\n\tdraw: \"'tldraw_draw', sans-serif\",\n\tsans: \"'tldraw_sans', sans-serif\",\n\tserif: \"'tldraw_serif', serif\",\n\tmono: \"'tldraw_mono', monospace\",\n}\n\n/** @internal */\nexport function isFontEntry(value: unknown): value is TLThemeFont {\n\treturn typeof value === 'object' && value !== null && 'fontFamily' in value\n}\n\n/**\n * Scan theme definitions and sync font registrations to match.\n * A font entry is any key in `TLThemeFonts` whose value is a {@link TLThemeFont}\n * object (i.e. has a `fontFamily` property).\n *\n * Fonts present in themes but not yet registered will be added.\n * Fonts currently registered but absent from all themes will be removed.\n *\n * @public\n */\nexport function registerFontsFromThemes(definitions: TLThemes): void {\n\tconst fontNames = new Set<string>()\n\tfor (const def of Object.values(definitions)) {\n\t\tif (!def.fonts) continue\n\t\tfor (const [key, value] of Object.entries(def.fonts)) {\n\t\t\tif (isFontEntry(value)) {\n\t\t\t\tfontNames.add(key)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst toAdd = [...fontNames].filter((v) => !DefaultFontStyle.values.includes(v as any))\n\tif (toAdd.length > 0) {\n\t\tDefaultFontStyle.addValues(...(toAdd as any))\n\t}\n\n\tconst toRemove = DefaultFontStyle.values.filter((v) => !fontNames.has(v as string))\n\tif (toRemove.length > 0) {\n\t\tDefaultFontStyle.removeValues(...toRemove)\n\t}\n\n\tif (process.env.NODE_ENV !== 'production') {\n\t\tfor (const def of Object.values(definitions)) {\n\t\t\tfor (const font of fontNames) {\n\t\t\t\tif (!def.fonts || !(font in def.fonts)) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`Theme '${def.id}' is missing font '${font}'. Shapes using this font won't render correctly in this theme.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA0B;AAmCnB,MAAM,mBAAmB,2BAAU,WAAW,eAAe;AAAA,EACnE,cAAc;AAAA,EACd,QAAQ,CAAC,QAAQ,QAAQ,SAAS,MAAM;AACzC,CAAC;AA4CM,MAAM,sBAAsB;AAAA,EAClC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AACP;AAGO,SAAS,YAAY,OAAsC;AACjE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,gBAAgB;AACvE;AAYO,SAAS,wBAAwB,aAA6B;AACpE,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,OAAO,OAAO,OAAO,WAAW,GAAG;AAC7C,QAAI,CAAC,IAAI,MAAO;AAChB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,KAAK,GAAG;AACrD,UAAI,YAAY,KAAK,GAAG;AACvB,kBAAU,IAAI,GAAG;AAAA,MAClB;AAAA,IACD;AAAA,EACD;AAEA,QAAM,QAAQ,CAAC,GAAG,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,OAAO,SAAS,CAAQ,CAAC;AACtF,MAAI,MAAM,SAAS,GAAG;AACrB,qBAAiB,UAAU,GAAI,KAAa;AAAA,EAC7C;AAEA,QAAM,WAAW,iBAAiB,OAAO,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,CAAW,CAAC;AAClF,MAAI,SAAS,SAAS,GAAG;AACxB,qBAAiB,aAAa,GAAG,QAAQ;AAAA,EAC1C;AAEA,MAAI,QAAQ,IAAI,aAAa,cAAc;AAC1C,eAAW,OAAO,OAAO,OAAO,WAAW,GAAG;AAC7C,iBAAW,QAAQ,WAAW;AAC7B,YAAI,CAAC,IAAI,SAAS,EAAE,QAAQ,IAAI,QAAQ;AACvC,kBAAQ;AAAA,YACP,UAAU,IAAI,EAAE,sBAAsB,IAAI;AAAA,UAC3C;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var TLTheme_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(TLTheme_exports);
|
|
17
|
+
//# sourceMappingURL=TLTheme.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/styles/TLTheme.ts"],
|
|
4
|
+
"sourcesContent": ["import type { TLFontFace } from './TLFontFace'\n\n/**\n * Defines the color variants available for each color in the default theme.\n * Each color has multiple variants for different use cases like fills, strokes,\n * patterns, and UI elements like frames and notes.\n *\n * @example\n * ```ts\n * import { TLDefaultColor } from '@tldraw/tlschema'\n *\n * const blueColor: TLDefaultColor = {\n * solid: '#4465e9',\n * semi: '#dce1f8',\n * pattern: '#6681ee',\n * fill: '#4465e9',\n * // ... other variants\n * }\n * ```\n *\n * @public\n */\nexport interface TLDefaultColor {\n\tsolid: string\n\tsemi: string\n\tpattern: string\n\tfill: string // usually same as solid\n\tlinedFill: string // usually slightly lighter than fill\n\tframeHeadingStroke: string\n\tframeHeadingFill: string\n\tframeStroke: string\n\tframeFill: string\n\tframeText: string\n\tnoteFill: string\n\tnoteText: string\n\thighlightSrgb: string\n\thighlightP3: string\n}\n\n/**\n * The color palette for a theme. Contains base UI colors (as strings) and\n * named shape colors (as {@link TLDefaultColor} objects).\n *\n * Extend this interface via module augmentation to add custom colors:\n *\n * @example\n * ```ts\n * declare module '@tldraw/tlschema' {\n * interface TLThemeColors {\n * pink: TLDefaultColor\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface TLThemeDefaultColors {\n\ttext: string\n\tbackground: string\n\tnegativeSpace: string\n\tsolid: string\n\tcursor: string\n\tnoteBorder: string\n\tblack: TLDefaultColor\n\tgrey: TLDefaultColor\n\t'light-violet': TLDefaultColor\n\tviolet: TLDefaultColor\n\tblue: TLDefaultColor\n\t'light-blue': TLDefaultColor\n\tyellow: TLDefaultColor\n\torange: TLDefaultColor\n\tgreen: TLDefaultColor\n\t'light-green': TLDefaultColor\n\t'light-red': TLDefaultColor\n\tred: TLDefaultColor\n\twhite: TLDefaultColor\n}\n\n/**\n * A font definition within a theme. Maps a font style name to a CSS font-family\n * declaration and optional font face descriptors for loading.\n *\n * @example\n * ```ts\n * import { TLThemeFont } from '@tldraw/tlschema'\n *\n * const customSans: TLThemeFont = {\n * fontFamily: \"'Inter', sans-serif\",\n * faces: [\n * { family: 'Inter', src: { url: 'https://example.com/Inter-Regular.woff2', format: 'woff2' }, weight: 'normal' },\n * { family: 'Inter', src: { url: 'https://example.com/Inter-Bold.woff2', format: 'woff2' }, weight: 'bold' },\n * ]\n * }\n * ```\n *\n * @public\n */\nexport interface TLThemeFont {\n\t/** CSS font-family declaration, e.g. `\"'Inter', sans-serif\"` */\n\tfontFamily: string\n\t/** Font face definitions for loading. Omit for system fonts that don't need loading. */\n\tfaces?: TLFontFace[]\n\t/**\n\t * Icon for the style panel. Accepts a string icon ID (resolved via `assetUrls.icons`)\n\t * or a React element (`TLUiIconJsx`). Defaults to the built-in icon for known fonts,\n\t * or `'font-draw'` for custom fonts.\n\t */\n\ticon?: unknown\n}\n\n/**\n * The font palette for a theme. Contains named font definitions mapping font style\n * names to their CSS font-family strings and font face descriptors.\n *\n * Extend this interface via module augmentation to add custom fonts:\n *\n * @example\n * ```ts\n * declare module '@tldraw/tlschema' {\n * interface TLThemeFonts {\n * cursive: TLThemeFont\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface TLThemeFonts {\n\tdraw: TLThemeFont\n\tsans: TLThemeFont\n\tserif: TLThemeFont\n\tmono: TLThemeFont\n}\n\n/**\n * Augment this interface to remove built-in palette colors from themes.\n * Each key you add will be omitted from {@link TLThemeColors}.\n *\n * @example\n * ```ts\n * declare module '@tldraw/tlschema' {\n * interface TLRemovedDefaultThemeColors {\n * 'light-violet': true\n * 'light-blue': true\n * }\n * }\n * ```\n *\n * @public\n */\n// oxlint-disable-next-line typescript/no-empty-object-type\nexport interface TLRemovedDefaultThemeColors {}\n\n/**\n * Keys in {@link TLThemeDefaultColors} that are required UI infrastructure colors\n * and cannot be removed via {@link TLRemovedDefaultThemeColors}.\n *\n * @public\n */\nexport type TLThemeUiColorKeys =\n\t| 'text'\n\t| 'background'\n\t| 'negativeSpace'\n\t| 'solid'\n\t| 'cursor'\n\t| 'noteBorder'\n\n/**\n * A color palette for one color mode. UI colors are always required.\n * Palette colors removed via {@link TLRemovedDefaultThemeColors} are omitted.\n *\n * @public\n */\nexport type TLThemeColors = Pick<TLThemeDefaultColors, TLThemeUiColorKeys> &\n\tOmit<TLThemeDefaultColors, TLThemeUiColorKeys | keyof TLRemovedDefaultThemeColors>\n\n/**\n * A theme definition containing shared properties and color/font palettes for\n * both light and dark modes.\n *\n * To remove palette colors from themes, augment {@link TLRemovedDefaultThemeColors}.\n * UI colors (`text`, `background`, `negativeSpace`, `solid`, `cursor`, `noteBorder`)\n * are always required.\n *\n * @example\n * ```ts\n * const myTheme: TLTheme = {\n * id: 'custom',\n * fontSize: 16,\n * lineHeight: 1.35,\n * strokeWidth: 2,\n * fonts: DEFAULT_THEME.fonts,\n * colors: {\n * light: { ... },\n * dark: { ... },\n * },\n * }\n * editor.updateTheme(myTheme)\n * ```\n *\n * @public\n */\nexport interface TLTheme {\n\t/** Unique identifier for this theme. Used as the key in the theme registry. */\n\tid: TLThemeId\n\t/** Base font size in pixels. Shape font sizes are derived by multiplying this value. */\n\tfontSize: number\n\t/** Base line height multiplier. */\n\tlineHeight: number\n\t/** Base stroke width in pixels. Shape stroke widths are derived by multiplying this value. */\n\tstrokeWidth: number\n\t/** Font definitions. Individual fonts may be absent if removed by a custom theme. */\n\tfonts: TLThemeFonts\n\tcolors: {\n\t\tlight: TLThemeColors\n\t\tdark: TLThemeColors\n\t}\n}\n\n/**\n * A registry of available themes. Extend this interface via module\n * augmentation to register custom themes for type-safe theme IDs.\n *\n * @example\n * ```ts\n * declare module '@tldraw/tlschema' {\n * interface TLThemes {\n * corporate: TLTheme\n * }\n * }\n * ```\n *\n * @public\n */\nexport interface TLThemes {\n\tdefault: TLTheme\n}\n\n/** @public */\nexport type TLThemeId = keyof TLThemes & string\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { T } from "@tldraw/validate";
|
|
2
2
|
import { idValidator } from "../misc/id-validator.mjs";
|
|
3
3
|
const assetIdValidator = idValidator("asset");
|
|
4
|
-
function createAssetValidator(type, props) {
|
|
4
|
+
function createAssetValidator(type, props, meta) {
|
|
5
|
+
const propsValidator = props instanceof T.Validator ? props : props ? T.object(props) : T.jsonValue;
|
|
5
6
|
return T.object({
|
|
6
7
|
id: assetIdValidator,
|
|
7
8
|
typeName: T.literal("asset"),
|
|
8
9
|
type: T.literal(type),
|
|
9
|
-
props,
|
|
10
|
-
meta: T.jsonValue
|
|
10
|
+
props: propsValidator,
|
|
11
|
+
meta: meta ? T.object(meta) : T.jsonValue
|
|
11
12
|
});
|
|
12
13
|
}
|
|
13
14
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/assets/TLBaseAsset.ts"],
|
|
4
|
-
"sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLAssetId } from '../records/TLAsset'\n\n/**\n * Base interface for all asset records in tldraw. Assets represent external resources\n * like images, videos, or bookmarks that shapes can reference. This interface extends\n * the base record system with asset-specific typing.\n *\n * @param Type - The specific asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param Props - The properties object specific to this asset type\n *\n * @example\n * ```ts\n * // Define a custom asset type\n * interface MyCustomAsset extends TLBaseAsset<'custom', { url: string; title: string }> {}\n *\n * const customAsset: MyCustomAsset = {\n * id: 'asset:custom123',\n * typeName: 'asset',\n * type: 'custom',\n * props: {\n * url: 'https://example.com',\n * title: 'My Custom Asset'\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> {\n\t/** The specific type of this asset (e.g., 'image', 'video', 'bookmark') */\n\ttype: Type\n\t/** Type-specific properties for this asset */\n\tprops: Props\n\t/** User-defined metadata that can be attached to this asset */\n\tmeta: JsonObject\n}\n\n/**\n * A validator for asset record type IDs. This validator ensures that asset IDs\n * follow the correct format and type structure required by tldraw's asset system.\n * Asset IDs are prefixed with 'asset:' followed by a unique identifier.\n *\n * @example\n * ```ts\n * import { assetIdValidator } from '@tldraw/tlschema'\n *\n * // Valid asset ID\n * const validId = 'asset:abc123'\n * console.log(assetIdValidator.isValid(validId)) // true\n *\n * // Invalid asset ID\n * const invalidId = 'shape:abc123'\n * console.log(assetIdValidator.isValid(invalidId)) // false\n * ```\n *\n * @public\n */\nexport const assetIdValidator = idValidator<TLAssetId>('asset')\n\n/**\n * Creates a validator for a specific asset record type. This factory function generates\n * a complete validator that validates the entire asset record structure including the\n * base properties (id, typeName, type, meta) and the type-specific props.\n *\n * @param type - The asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param props -
|
|
5
|
-
"mappings": "AAEA,SAAS,SAAS;AAClB,SAAS,mBAAmB;AA2DrB,MAAM,mBAAmB,YAAuB,OAAO;
|
|
4
|
+
"sourcesContent": ["import { BaseRecord } from '@tldraw/store'\nimport { JsonObject } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { idValidator } from '../misc/id-validator'\nimport { TLAssetId } from '../records/TLAsset'\n\n/**\n * Base interface for all asset records in tldraw. Assets represent external resources\n * like images, videos, or bookmarks that shapes can reference. This interface extends\n * the base record system with asset-specific typing.\n *\n * @param Type - The specific asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param Props - The properties object specific to this asset type\n *\n * @example\n * ```ts\n * // Define a custom asset type\n * interface MyCustomAsset extends TLBaseAsset<'custom', { url: string; title: string }> {}\n *\n * const customAsset: MyCustomAsset = {\n * id: 'asset:custom123',\n * typeName: 'asset',\n * type: 'custom',\n * props: {\n * url: 'https://example.com',\n * title: 'My Custom Asset'\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> {\n\t/** The specific type of this asset (e.g., 'image', 'video', 'bookmark') */\n\ttype: Type\n\t/** Type-specific properties for this asset */\n\tprops: Props\n\t/** User-defined metadata that can be attached to this asset */\n\tmeta: JsonObject\n}\n\n/**\n * A validator for asset record type IDs. This validator ensures that asset IDs\n * follow the correct format and type structure required by tldraw's asset system.\n * Asset IDs are prefixed with 'asset:' followed by a unique identifier.\n *\n * @example\n * ```ts\n * import { assetIdValidator } from '@tldraw/tlschema'\n *\n * // Valid asset ID\n * const validId = 'asset:abc123'\n * console.log(assetIdValidator.isValid(validId)) // true\n *\n * // Invalid asset ID\n * const invalidId = 'shape:abc123'\n * console.log(assetIdValidator.isValid(invalidId)) // false\n * ```\n *\n * @public\n */\nexport const assetIdValidator = idValidator<TLAssetId>('asset')\n\n/**\n * Creates a validator for a specific asset record type. This factory function generates\n * a complete validator that validates the entire asset record structure including the\n * base properties (id, typeName, type, meta) and the type-specific props.\n *\n * @param type - The asset type identifier (e.g., 'image', 'video', 'bookmark')\n * @param props - A validator or per-key validator record for the asset's type-specific properties\n * @param meta - An optional per-key validator record for the asset's meta properties\n * @returns A complete validator for the asset record type\n *\n * @example\n * ```ts\n * import { createAssetValidator, TLBaseAsset } from '@tldraw/tlschema'\n * import { T } from '@tldraw/validate'\n *\n * // Define a custom asset type\n * type TLCustomAsset = TLBaseAsset<'custom', {\n * url: string\n * title: string\n * description?: string\n * }>\n *\n * // Create validator using a per-key record (recommended)\n * const customAssetValidator = createAssetValidator('custom', {\n * url: T.string,\n * title: T.string,\n * description: T.string.optional()\n * })\n *\n * // Or using a T.object validator\n * const customAssetValidator2 = createAssetValidator('custom', T.object({\n * url: T.string,\n * title: T.string,\n * description: T.string.optional()\n * }))\n * ```\n *\n * @public\n */\nexport function createAssetValidator<\n\tType extends string,\n\tProps extends JsonObject,\n\tMeta extends JsonObject = JsonObject,\n>(\n\ttype: Type,\n\tprops?: T.Validator<Props> | { [K in keyof Props]: T.Validatable<Props[K]> },\n\tmeta?: { [K in keyof Meta]: T.Validatable<Meta[K]> }\n) {\n\t// Determine if props is a Validator instance or a per-key record\n\tconst propsValidator =\n\t\tprops instanceof T.Validator ? props : props ? T.object(props) : (T.jsonValue as any)\n\n\treturn T.object<TLBaseAsset<Type, Props>>({\n\t\tid: assetIdValidator,\n\t\ttypeName: T.literal('asset'),\n\t\ttype: T.literal(type),\n\t\tprops: propsValidator,\n\t\tmeta: meta ? T.object(meta) : (T.jsonValue as T.ObjectValidator<JsonObject>),\n\t})\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,SAAS;AAClB,SAAS,mBAAmB;AA2DrB,MAAM,mBAAmB,YAAuB,OAAO;AAyCvD,SAAS,qBAKf,MACA,OACA,MACC;AAED,QAAM,iBACL,iBAAiB,EAAE,YAAY,QAAQ,QAAQ,EAAE,OAAO,KAAK,IAAK,EAAE;AAErE,SAAO,EAAE,OAAiC;AAAA,IACzC,IAAI;AAAA,IACJ,UAAU,EAAE,QAAQ,OAAO;AAAA,IAC3B,MAAM,EAAE,QAAQ,IAAI;AAAA,IACpB,OAAO;AAAA,IACP,MAAM,OAAO,EAAE,OAAO,IAAI,IAAK,EAAE;AAAA,EAClC,CAAC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from "@tldraw/store";
|
|
2
2
|
import { T } from "@tldraw/validate";
|
|
3
3
|
import { createAssetValidator } from "./TLBaseAsset.mjs";
|
|
4
|
+
const bookmarkAssetProps = {
|
|
5
|
+
title: T.string,
|
|
6
|
+
description: T.string,
|
|
7
|
+
image: T.string,
|
|
8
|
+
favicon: T.string,
|
|
9
|
+
src: T.srcUrl.nullable()
|
|
10
|
+
};
|
|
4
11
|
const bookmarkAssetValidator = createAssetValidator(
|
|
5
12
|
"bookmark",
|
|
6
|
-
T.object(
|
|
7
|
-
title: T.string,
|
|
8
|
-
description: T.string,
|
|
9
|
-
image: T.string,
|
|
10
|
-
favicon: T.string,
|
|
11
|
-
src: T.srcUrl.nullable()
|
|
12
|
-
})
|
|
13
|
+
T.object(bookmarkAssetProps)
|
|
13
14
|
);
|
|
14
15
|
const Versions = createMigrationIds("com.tldraw.asset.bookmark", {
|
|
15
16
|
MakeUrlsValid: 1,
|
|
@@ -45,6 +46,7 @@ const bookmarkAssetMigrations = createRecordMigrationSequence({
|
|
|
45
46
|
});
|
|
46
47
|
export {
|
|
47
48
|
bookmarkAssetMigrations,
|
|
49
|
+
bookmarkAssetProps,
|
|
48
50
|
bookmarkAssetValidator,
|
|
49
51
|
Versions as bookmarkAssetVersions
|
|
50
52
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/assets/TLBookmarkAsset.ts"],
|
|
4
|
-
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;
|
|
4
|
+
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { RecordProps } from '../recordsWithProps'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset used for URL bookmarks, used by the TLBookmarkShape.\n *\n * @public */\nexport type TLBookmarkAsset = TLBaseAsset<\n\t'bookmark',\n\t{\n\t\ttitle: string\n\t\tdescription: string\n\t\timage: string\n\t\tfavicon: string\n\t\tsrc: string | null\n\t}\n>\n\n/** @public */\nexport const bookmarkAssetProps = {\n\ttitle: T.string,\n\tdescription: T.string,\n\timage: T.string,\n\tfavicon: T.string,\n\tsrc: T.srcUrl.nullable(),\n} satisfies RecordProps<TLBookmarkAsset>\n\n/** Validator for bookmark assets. @public */\nexport const bookmarkAssetValidator: T.Validator<TLBookmarkAsset> = createAssetValidator(\n\t'bookmark',\n\tT.object(bookmarkAssetProps)\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.bookmark', {\n\tMakeUrlsValid: 1,\n\tAddFavicon: 2,\n} as const)\n\n/**\n * Migration version identifiers for bookmark assets. These versions track\n * the evolution of the bookmark asset schema over time.\n *\n * Available versions:\n * - `MakeUrlsValid` (v1): Ensures src URLs are valid or empty\n * - `AddFavicon` (v2): Adds favicon property to bookmark assets\n *\n * @example\n * ```ts\n * import { bookmarkAssetVersions } from '@tldraw/tlschema'\n *\n * // Check if a migration exists\n * console.log(bookmarkAssetVersions.AddFavicon) // 2\n * ```\n *\n * @public\n */\nexport { Versions as bookmarkAssetVersions }\n\n/**\n * Migration sequence for bookmark assets. Handles the evolution of bookmark asset\n * data structure over time, ensuring backward and forward compatibility.\n *\n * The migration sequence includes:\n * 1. **MakeUrlsValid** (v1): Validates and cleans up src URLs, setting invalid URLs to empty string\n * 2. **AddFavicon** (v2): Adds the favicon property and validates it, setting invalid favicons to empty string\n *\n * @public\n */\nexport const bookmarkAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.bookmark',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLBookmarkAsset).type === 'bookmark',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFavicon,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.favicon)) {\n\t\t\t\t\tasset.props.favicon = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.favicon\n\t\t\t},\n\t\t},\n\t],\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;AAkB3C,MAAM,qBAAqB;AAAA,EACjC,OAAO,EAAE;AAAA,EACT,aAAa,EAAE;AAAA,EACf,OAAO,EAAE;AAAA,EACT,SAAS,EAAE;AAAA,EACX,KAAK,EAAE,OAAO,SAAS;AACxB;AAGO,MAAM,yBAAuD;AAAA,EACnE;AAAA,EACA,EAAE,OAAO,kBAAkB;AAC5B;AAEA,MAAM,WAAW,mBAAmB,6BAA6B;AAAA,EAChE,eAAe;AAAA,EACf,YAAY;AACb,CAAU;AAgCH,MAAM,0BAA0B,8BAA8B;AAAA,EACpE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAA0B,SAAS;AAAA,EACvD,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,EAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,EAAE,OAAO,QAAQ,MAAM,MAAM,OAAO,GAAG;AAC3C,gBAAM,MAAM,UAAU;AAAA,QACvB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from "@tldraw/store";
|
|
2
2
|
import { T } from "@tldraw/validate";
|
|
3
3
|
import { createAssetValidator } from "./TLBaseAsset.mjs";
|
|
4
|
+
const imageAssetProps = {
|
|
5
|
+
w: T.number,
|
|
6
|
+
h: T.number,
|
|
7
|
+
name: T.string,
|
|
8
|
+
isAnimated: T.boolean,
|
|
9
|
+
mimeType: T.string.nullable(),
|
|
10
|
+
src: T.srcUrl.nullable(),
|
|
11
|
+
fileSize: T.nonZeroNumber.optional(),
|
|
12
|
+
pixelRatio: T.positiveNumber.optional()
|
|
13
|
+
};
|
|
4
14
|
const imageAssetValidator = createAssetValidator(
|
|
5
15
|
"image",
|
|
6
|
-
T.object(
|
|
7
|
-
w: T.number,
|
|
8
|
-
h: T.number,
|
|
9
|
-
name: T.string,
|
|
10
|
-
isAnimated: T.boolean,
|
|
11
|
-
mimeType: T.string.nullable(),
|
|
12
|
-
src: T.srcUrl.nullable(),
|
|
13
|
-
fileSize: T.nonZeroNumber.optional(),
|
|
14
|
-
pixelRatio: T.positiveNumber.optional()
|
|
15
|
-
})
|
|
16
|
+
T.object(imageAssetProps)
|
|
16
17
|
);
|
|
17
18
|
const Versions = createMigrationIds("com.tldraw.asset.image", {
|
|
18
19
|
AddIsAnimated: 1,
|
|
@@ -95,6 +96,7 @@ const imageAssetMigrations = createRecordMigrationSequence({
|
|
|
95
96
|
});
|
|
96
97
|
export {
|
|
97
98
|
imageAssetMigrations,
|
|
99
|
+
imageAssetProps,
|
|
98
100
|
imageAssetValidator,
|
|
99
101
|
Versions as imageAssetVersions
|
|
100
102
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/assets/TLImageAsset.ts"],
|
|
4
|
-
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;
|
|
4
|
+
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { RecordProps } from '../recordsWithProps'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset for images such as PNGs and JPEGs, used by the TLImageShape.\n *\n * @public */\nexport type TLImageAsset = TLBaseAsset<\n\t'image',\n\t{\n\t\tw: number\n\t\th: number\n\t\tname: string\n\t\tisAnimated: boolean\n\t\tmimeType: string | null\n\t\tsrc: string | null\n\t\tfileSize?: number\n\t\tpixelRatio?: number\n\t}\n>\n\n/** @public */\nexport const imageAssetProps = {\n\tw: T.number,\n\th: T.number,\n\tname: T.string,\n\tisAnimated: T.boolean,\n\tmimeType: T.string.nullable(),\n\tsrc: T.srcUrl.nullable(),\n\tfileSize: T.nonZeroNumber.optional(),\n\tpixelRatio: T.positiveNumber.optional(),\n} satisfies RecordProps<TLImageAsset>\n\n/** Validator for image assets. @public */\nexport const imageAssetValidator: T.Validator<TLImageAsset> = createAssetValidator(\n\t'image',\n\tT.object(imageAssetProps)\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.image', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n\tAddPixelRatio: 6,\n} as const)\n\n/**\n * Migration version identifiers for image assets. These define the different schema versions\n * that image assets have gone through during the evolution of the tldraw data model.\n *\n * @example\n * ```ts\n * import { imageAssetVersions } from '@tldraw/tlschema'\n *\n * // Access specific version IDs\n * console.log(imageAssetVersions.AddIsAnimated) // Version when isAnimated was added\n * console.log(imageAssetVersions.RenameWidthHeight) // Version when width/height became w/h\n * ```\n *\n * @public\n */\nexport { Versions as imageAssetVersions }\n\n/**\n * Migration sequence for image assets. Handles the evolution of the image asset schema\n * over time, providing both forward (up) and backward (down) migration functions to\n * maintain compatibility across different versions of the tldraw data model.\n *\n * The sequence includes migrations for:\n * - Adding the `isAnimated` property to track animated images\n * - Renaming `width`/`height` properties to shorter `w`/`h` names\n * - Ensuring URLs are valid format\n * - Adding file size tracking\n * - Making file size optional\n *\n *\n * @public\n */\nexport const imageAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.image',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLImageAsset).type === 'image',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddPixelRatio,\n\t\t\tup: (_asset: any) => {\n\t\t\t\t// noop \u2014 pixelRatio is optional and undefined by default\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.pixelRatio\n\t\t\t},\n\t\t},\n\t],\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;AAqB3C,MAAM,kBAAkB;AAAA,EAC9B,GAAG,EAAE;AAAA,EACL,GAAG,EAAE;AAAA,EACL,MAAM,EAAE;AAAA,EACR,YAAY,EAAE;AAAA,EACd,UAAU,EAAE,OAAO,SAAS;AAAA,EAC5B,KAAK,EAAE,OAAO,SAAS;AAAA,EACvB,UAAU,EAAE,cAAc,SAAS;AAAA,EACnC,YAAY,EAAE,eAAe,SAAS;AACvC;AAGO,MAAM,sBAAiD;AAAA,EAC7D;AAAA,EACA,EAAE,OAAO,eAAe;AACzB;AAEA,MAAM,WAAW,mBAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AAAA,EACtB,eAAe;AAChB,CAAU;AAkCH,MAAM,uBAAuB,8BAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAuB,SAAS;AAAA,EACpD,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,EAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,WAAgB;AAAA,MAErB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { createMigrationIds, createRecordMigrationSequence } from "@tldraw/store";
|
|
2
2
|
import { T } from "@tldraw/validate";
|
|
3
3
|
import { createAssetValidator } from "./TLBaseAsset.mjs";
|
|
4
|
+
const videoAssetProps = {
|
|
5
|
+
w: T.number,
|
|
6
|
+
h: T.number,
|
|
7
|
+
name: T.string,
|
|
8
|
+
isAnimated: T.boolean,
|
|
9
|
+
mimeType: T.string.nullable(),
|
|
10
|
+
src: T.srcUrl.nullable(),
|
|
11
|
+
fileSize: T.number.optional()
|
|
12
|
+
};
|
|
4
13
|
const videoAssetValidator = createAssetValidator(
|
|
5
14
|
"video",
|
|
6
|
-
T.object(
|
|
7
|
-
w: T.number,
|
|
8
|
-
h: T.number,
|
|
9
|
-
name: T.string,
|
|
10
|
-
isAnimated: T.boolean,
|
|
11
|
-
mimeType: T.string.nullable(),
|
|
12
|
-
src: T.srcUrl.nullable(),
|
|
13
|
-
fileSize: T.number.optional()
|
|
14
|
-
})
|
|
15
|
+
T.object(videoAssetProps)
|
|
15
16
|
);
|
|
16
17
|
const Versions = createMigrationIds("com.tldraw.asset.video", {
|
|
17
18
|
AddIsAnimated: 1,
|
|
@@ -85,6 +86,7 @@ const videoAssetMigrations = createRecordMigrationSequence({
|
|
|
85
86
|
});
|
|
86
87
|
export {
|
|
87
88
|
videoAssetMigrations,
|
|
89
|
+
videoAssetProps,
|
|
88
90
|
videoAssetValidator,
|
|
89
91
|
Versions as videoAssetVersions
|
|
90
92
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/assets/TLVideoAsset.ts"],
|
|
4
|
-
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;
|
|
4
|
+
"sourcesContent": ["import { createMigrationIds, createRecordMigrationSequence } from '@tldraw/store'\nimport { T } from '@tldraw/validate'\nimport { RecordProps } from '../recordsWithProps'\nimport { TLBaseAsset, createAssetValidator } from './TLBaseAsset'\n\n/**\n * An asset record representing video files that can be displayed in video shapes.\n * Video assets store metadata about video files including dimensions, MIME type,\n * animation status, and file source information. They are referenced by TLVideoShape\n * instances to display video content on the canvas.\n *\n * @example\n * ```ts\n * import { TLVideoAsset } from '@tldraw/tlschema'\n *\n * const videoAsset: TLVideoAsset = {\n * id: 'asset:video123',\n * typeName: 'asset',\n * type: 'video',\n * props: {\n * w: 1920,\n * h: 1080,\n * name: 'my-video.mp4',\n * isAnimated: true,\n * mimeType: 'video/mp4',\n * src: 'https://example.com/video.mp4',\n * fileSize: 5242880\n * },\n * meta: {}\n * }\n * ```\n *\n * @public\n */\nexport type TLVideoAsset = TLBaseAsset<\n\t'video',\n\t{\n\t\t/** The width of the video in pixels */\n\t\tw: number\n\t\t/** The height of the video in pixels */\n\t\th: number\n\t\t/** The original filename or display name of the video */\n\t\tname: string\n\t\t/** Whether the video contains animation/motion (true for most videos) */\n\t\tisAnimated: boolean\n\t\t/** The MIME type of the video file (e.g., 'video/mp4', 'video/webm'), null if unknown */\n\t\tmimeType: string | null\n\t\t/** The source URL or data URI for the video file, null if not yet available */\n\t\tsrc: string | null\n\t\t/** The file size in bytes, optional for backward compatibility */\n\t\tfileSize?: number\n\t}\n>\n\n/** @public */\nexport const videoAssetProps = {\n\tw: T.number,\n\th: T.number,\n\tname: T.string,\n\tisAnimated: T.boolean,\n\tmimeType: T.string.nullable(),\n\tsrc: T.srcUrl.nullable(),\n\tfileSize: T.number.optional(),\n} satisfies RecordProps<TLVideoAsset>\n\n/** Validator for video assets. @public */\nexport const videoAssetValidator: T.Validator<TLVideoAsset> = createAssetValidator(\n\t'video',\n\tT.object(videoAssetProps)\n)\n\nconst Versions = createMigrationIds('com.tldraw.asset.video', {\n\tAddIsAnimated: 1,\n\tRenameWidthHeight: 2,\n\tMakeUrlsValid: 3,\n\tAddFileSize: 4,\n\tMakeFileSizeOptional: 5,\n} as const)\n\n/**\n * Version identifiers for video asset migration sequences. These versions track\n * the evolution of the video asset schema over time, enabling proper data migration\n * when the asset structure changes.\n *\n * @example\n * ```ts\n * import { videoAssetVersions } from '@tldraw/tlschema'\n *\n * // Check the current version of a specific migration\n * console.log(videoAssetVersions.AddFileSize) // 4\n * ```\n *\n * @public\n */\nexport { Versions as videoAssetVersions }\n\n/**\n * Migration sequence for video assets that handles schema evolution over time.\n * This sequence defines how video asset data should be transformed when upgrading\n * or downgrading between different schema versions. Each migration step handles\n * specific changes like adding properties, renaming fields, or changing data formats.\n *\n * The migrations handle:\n * - Adding animation detection (isAnimated property)\n * - Renaming width/height properties to w/h for consistency\n * - Ensuring URL validity for src properties\n * - Adding file size tracking\n * - Making file size optional for backward compatibility\n *\n * @public\n */\nexport const videoAssetMigrations = createRecordMigrationSequence({\n\tsequenceId: 'com.tldraw.asset.video',\n\trecordType: 'asset',\n\tfilter: (asset) => (asset as TLVideoAsset).type === 'video',\n\tsequence: [\n\t\t{\n\t\t\tid: Versions.AddIsAnimated,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.isAnimated = false\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.isAnimated\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.RenameWidthHeight,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.w = asset.props.width\n\t\t\t\tasset.props.h = asset.props.height\n\t\t\t\tdelete asset.props.width\n\t\t\t\tdelete asset.props.height\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tasset.props.width = asset.props.w\n\t\t\t\tasset.props.height = asset.props.h\n\t\t\t\tdelete asset.props.w\n\t\t\t\tdelete asset.props.h\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeUrlsValid,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (!T.srcUrl.isValid(asset.props.src)) {\n\t\t\t\t\tasset.props.src = ''\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (_asset) => {\n\t\t\t\t// noop\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.AddFileSize,\n\t\t\tup: (asset: any) => {\n\t\t\t\tasset.props.fileSize = -1\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tdelete asset.props.fileSize\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: Versions.MakeFileSizeOptional,\n\t\t\tup: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === -1) {\n\t\t\t\t\tasset.props.fileSize = undefined\n\t\t\t\t}\n\t\t\t},\n\t\t\tdown: (asset: any) => {\n\t\t\t\tif (asset.props.fileSize === undefined) {\n\t\t\t\t\tasset.props.fileSize = -1\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t],\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB,qCAAqC;AAClE,SAAS,SAAS;AAElB,SAAsB,4BAA4B;AAoD3C,MAAM,kBAAkB;AAAA,EAC9B,GAAG,EAAE;AAAA,EACL,GAAG,EAAE;AAAA,EACL,MAAM,EAAE;AAAA,EACR,YAAY,EAAE;AAAA,EACd,UAAU,EAAE,OAAO,SAAS;AAAA,EAC5B,KAAK,EAAE,OAAO,SAAS;AAAA,EACvB,UAAU,EAAE,OAAO,SAAS;AAC7B;AAGO,MAAM,sBAAiD;AAAA,EAC7D;AAAA,EACA,EAAE,OAAO,eAAe;AACzB;AAEA,MAAM,WAAW,mBAAmB,0BAA0B;AAAA,EAC7D,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,sBAAsB;AACvB,CAAU;AAkCH,MAAM,uBAAuB,8BAA8B;AAAA,EACjE,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAW,MAAuB,SAAS;AAAA,EACpD,UAAU;AAAA,IACT;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,aAAa;AAAA,MAC1B;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,cAAM,MAAM,IAAI,MAAM,MAAM;AAC5B,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,cAAM,MAAM,QAAQ,MAAM,MAAM;AAChC,cAAM,MAAM,SAAS,MAAM,MAAM;AACjC,eAAO,MAAM,MAAM;AACnB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,CAAC,EAAE,OAAO,QAAQ,MAAM,MAAM,GAAG,GAAG;AACvC,gBAAM,MAAM,MAAM;AAAA,QACnB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,WAAW;AAAA,MAElB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,cAAM,MAAM,WAAW;AAAA,MACxB;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,eAAO,MAAM,MAAM;AAAA,MACpB;AAAA,IACD;AAAA,IACA;AAAA,MACC,IAAI,SAAS;AAAA,MACb,IAAI,CAAC,UAAe;AACnB,YAAI,MAAM,MAAM,aAAa,IAAI;AAChC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,MACA,MAAM,CAAC,UAAe;AACrB,YAAI,MAAM,MAAM,aAAa,QAAW;AACvC,gBAAM,MAAM,WAAW;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { StoreSchema } from "@tldraw/store";
|
|
2
2
|
import { objectMapValues } from "@tldraw/utils";
|
|
3
|
-
import { bookmarkAssetMigrations } from "./assets/TLBookmarkAsset.mjs";
|
|
4
|
-
import { imageAssetMigrations } from "./assets/TLImageAsset.mjs";
|
|
5
|
-
import { videoAssetMigrations } from "./assets/TLVideoAsset.mjs";
|
|
3
|
+
import { bookmarkAssetMigrations, bookmarkAssetProps } from "./assets/TLBookmarkAsset.mjs";
|
|
4
|
+
import { imageAssetMigrations, imageAssetProps } from "./assets/TLImageAsset.mjs";
|
|
5
|
+
import { videoAssetMigrations, videoAssetProps } from "./assets/TLVideoAsset.mjs";
|
|
6
6
|
import { arrowBindingMigrations, arrowBindingProps } from "./bindings/TLArrowBinding.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
assetMigrations,
|
|
9
|
+
createAssetRecordType
|
|
10
|
+
} from "./records/TLAsset.mjs";
|
|
8
11
|
import { createBindingRecordType } from "./records/TLBinding.mjs";
|
|
9
12
|
import { CameraRecordType, cameraMigrations } from "./records/TLCamera.mjs";
|
|
10
13
|
import {
|
|
@@ -57,9 +60,15 @@ const defaultShapeSchemas = {
|
|
|
57
60
|
const defaultBindingSchemas = {
|
|
58
61
|
arrow: { migrations: arrowBindingMigrations, props: arrowBindingProps }
|
|
59
62
|
};
|
|
63
|
+
const defaultAssetSchemas = {
|
|
64
|
+
image: { migrations: imageAssetMigrations, props: imageAssetProps },
|
|
65
|
+
video: { migrations: videoAssetMigrations, props: videoAssetProps },
|
|
66
|
+
bookmark: { migrations: bookmarkAssetMigrations, props: bookmarkAssetProps }
|
|
67
|
+
};
|
|
60
68
|
function createTLSchema({
|
|
61
69
|
shapes = defaultShapeSchemas,
|
|
62
70
|
bindings = defaultBindingSchemas,
|
|
71
|
+
assets = defaultAssetSchemas,
|
|
63
72
|
user,
|
|
64
73
|
records = {},
|
|
65
74
|
migrations
|
|
@@ -75,6 +84,7 @@ function createTLSchema({
|
|
|
75
84
|
}
|
|
76
85
|
const ShapeRecordType = createShapeRecordType(shapes);
|
|
77
86
|
const BindingRecordType = createBindingRecordType(bindings);
|
|
87
|
+
const _AssetRecordType = createAssetRecordType(assets);
|
|
78
88
|
const InstanceRecordType = createInstanceRecordType(stylesById);
|
|
79
89
|
const CustomUserRecordType = user ? createUserRecordType(user) : UserRecordType;
|
|
80
90
|
const builtInTypeNames = /* @__PURE__ */ new Set([
|
|
@@ -102,7 +112,7 @@ function createTLSchema({
|
|
|
102
112
|
}
|
|
103
113
|
return StoreSchema.create(
|
|
104
114
|
{
|
|
105
|
-
asset:
|
|
115
|
+
asset: _AssetRecordType,
|
|
106
116
|
binding: BindingRecordType,
|
|
107
117
|
camera: CameraRecordType,
|
|
108
118
|
document: DocumentRecordType,
|
|
@@ -128,9 +138,7 @@ function createTLSchema({
|
|
|
128
138
|
pointerMigrations,
|
|
129
139
|
rootShapeMigrations,
|
|
130
140
|
userMigrations,
|
|
131
|
-
|
|
132
|
-
imageAssetMigrations,
|
|
133
|
-
videoAssetMigrations,
|
|
141
|
+
...processPropsMigrations("asset", assets),
|
|
134
142
|
...processPropsMigrations("shape", shapes),
|
|
135
143
|
...processPropsMigrations("binding", bindings),
|
|
136
144
|
...processCustomRecordMigrations(records),
|
|
@@ -144,6 +152,7 @@ function createTLSchema({
|
|
|
144
152
|
}
|
|
145
153
|
export {
|
|
146
154
|
createTLSchema,
|
|
155
|
+
defaultAssetSchemas,
|
|
147
156
|
defaultBindingSchemas,
|
|
148
157
|
defaultShapeSchemas
|
|
149
158
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/createTLSchema.ts"],
|
|
4
|
-
"sourcesContent": ["import { LegacyMigrations, MigrationSequence, StoreSchema, StoreValidator } from '@tldraw/store'\nimport { objectMapValues } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { bookmarkAssetMigrations } from './assets/TLBookmarkAsset'\nimport { imageAssetMigrations } from './assets/TLImageAsset'\nimport { videoAssetMigrations } from './assets/TLVideoAsset'\nimport { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'\nimport { AssetRecordType, assetMigrations } from './records/TLAsset'\nimport { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'\nimport { CameraRecordType, cameraMigrations } from './records/TLCamera'\nimport {\n\tCustomRecordInfo,\n\tcreateCustomRecordType,\n\tprocessCustomRecordMigrations,\n} from './records/TLCustomRecord'\nimport { DocumentRecordType, documentMigrations } from './records/TLDocument'\nimport { createInstanceRecordType, instanceMigrations } from './records/TLInstance'\nimport { PageRecordType, pageMigrations } from './records/TLPage'\nimport { InstancePageStateRecordType, instancePageStateMigrations } from './records/TLPageState'\nimport { PointerRecordType, pointerMigrations } from './records/TLPointer'\nimport { InstancePresenceRecordType, instancePresenceMigrations } from './records/TLPresence'\nimport { TLRecord } from './records/TLRecord'\nimport {\n\tTLDefaultShape,\n\tTLShape,\n\tcreateShapeRecordType,\n\tgetShapePropKeysByStyle,\n\trootShapeMigrations,\n} from './records/TLShape'\nimport { UserRecordType, createUserRecordType, userMigrations } from './records/TLUser'\nimport { RecordProps, TLPropsMigrations, processPropsMigrations } from './recordsWithProps'\nimport { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\nimport { TLBaseShape } from './shapes/TLBaseShape'\nimport { bookmarkShapeMigrations, bookmarkShapeProps } from './shapes/TLBookmarkShape'\nimport { drawShapeMigrations, drawShapeProps } from './shapes/TLDrawShape'\nimport { embedShapeMigrations, embedShapeProps } from './shapes/TLEmbedShape'\nimport { frameShapeMigrations, frameShapeProps } from './shapes/TLFrameShape'\nimport { geoShapeMigrations, geoShapeProps } from './shapes/TLGeoShape'\nimport { groupShapeMigrations, groupShapeProps } from './shapes/TLGroupShape'\nimport { highlightShapeMigrations, highlightShapeProps } from './shapes/TLHighlightShape'\nimport { imageShapeMigrations, imageShapeProps } from './shapes/TLImageShape'\nimport { lineShapeMigrations, lineShapeProps } from './shapes/TLLineShape'\nimport { noteShapeMigrations, noteShapeProps } from './shapes/TLNoteShape'\nimport { textShapeMigrations, textShapeProps } from './shapes/TLTextShape'\nimport { videoShapeMigrations, videoShapeProps } from './shapes/TLVideoShape'\nimport { storeMigrations } from './store-migrations'\nimport { StyleProp } from './styles/StyleProp'\nimport { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'\n\n/**\n * Configuration information for a schema type (shape or binding), including its properties,\n * metadata, and migration sequences for data evolution over time.\n *\n * @public\n * @example\n * ```ts\n * import { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\n *\n * const myShapeSchema: SchemaPropsInfo = {\n * migrations: arrowShapeMigrations,\n * props: arrowShapeProps,\n * meta: {\n * customField: T.string,\n * },\n * }\n * ```\n */\nexport interface SchemaPropsInfo {\n\t/**\n\t * Migration sequences for handling data evolution over time. Can be legacy migrations,\n\t * props-specific migrations, or general migration sequences.\n\t */\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\n\t/**\n\t * Validation schema for the shape or binding properties. Maps property names to their validators.\n\t */\n\tprops?: Record<string, StoreValidator<any>>\n\n\t/**\n\t * Validation schema for metadata fields. Maps metadata field names to their validators.\n\t */\n\tmeta?: Record<string, StoreValidator<any>>\n}\n\n/**\n * The complete schema definition for a tldraw store, encompassing all record types,\n * validation rules, and migration sequences. This schema defines the structure of\n * the persistent data model used by tldraw.\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * const schema: TLSchema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * const store = new Store({ schema })\n * ```\n */\nexport type TLSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/**\n * Default shape schema configurations for all built-in tldraw shape types.\n * Each shape type includes its validation props and migration sequences.\n *\n * This object contains schema information for:\n * - arrow: Directional lines that can bind to other shapes\n * - bookmark: Website bookmark cards with preview information\n * - draw: Freehand drawing paths created with drawing tools\n * - embed: Embedded content from external services (YouTube, Figma, etc.)\n * - frame: Container shapes for organizing content\n * - geo: Geometric shapes (rectangles, ellipses, triangles, etc.)\n * - group: Logical groupings of multiple shapes\n * - highlight: Highlighting strokes from the highlighter tool\n * - image: Raster image shapes referencing image assets\n * - line: Multi-point lines and splines\n * - note: Sticky note shapes with text content\n * - text: Rich text shapes with formatting support\n * - video: Video shapes referencing video assets\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n *\n * // Use all default shapes\n * const schema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * // Use only specific default shapes\n * const minimalSchema = createTLSchema({\n * shapes: {\n * geo: defaultShapeSchemas.geo,\n * text: defaultShapeSchemas.text,\n * },\n * })\n * ```\n */\nexport const defaultShapeSchemas = {\n\tarrow: { migrations: arrowShapeMigrations, props: arrowShapeProps },\n\tbookmark: { migrations: bookmarkShapeMigrations, props: bookmarkShapeProps },\n\tdraw: { migrations: drawShapeMigrations, props: drawShapeProps },\n\tembed: { migrations: embedShapeMigrations, props: embedShapeProps },\n\tframe: { migrations: frameShapeMigrations, props: frameShapeProps },\n\tgeo: { migrations: geoShapeMigrations, props: geoShapeProps },\n\tgroup: { migrations: groupShapeMigrations, props: groupShapeProps },\n\thighlight: { migrations: highlightShapeMigrations, props: highlightShapeProps },\n\timage: { migrations: imageShapeMigrations, props: imageShapeProps },\n\tline: { migrations: lineShapeMigrations, props: lineShapeProps },\n\tnote: { migrations: noteShapeMigrations, props: noteShapeProps },\n\ttext: { migrations: textShapeMigrations, props: textShapeProps },\n\tvideo: { migrations: videoShapeMigrations, props: videoShapeProps },\n} satisfies {\n\t[T in TLDefaultShape['type']]: {\n\t\tmigrations: SchemaPropsInfo['migrations']\n\t\tprops: RecordProps<TLBaseShape<T, Extract<TLDefaultShape, { type: T }>['props']>>\n\t}\n}\n\n/**\n * Default binding schema configurations for all built-in tldraw binding types.\n * Bindings represent relationships between shapes, such as arrows connected to shapes.\n *\n * Currently includes:\n * - arrow: Bindings that connect arrow shapes to other shapes at specific anchor points\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultBindingSchemas } from '@tldraw/tlschema'\n *\n * // Use default bindings\n * const schema = createTLSchema({\n * bindings: defaultBindingSchemas,\n * })\n *\n * // Add custom binding alongside defaults\n * const customSchema = createTLSchema({\n * bindings: {\n * ...defaultBindingSchemas,\n * myCustomBinding: {\n * props: myCustomBindingProps,\n * migrations: myCustomBindingMigrations,\n * },\n * },\n * })\n * ```\n */\nexport const defaultBindingSchemas = {\n\tarrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },\n} satisfies { [T in TLDefaultBinding['type']]: SchemaPropsInfo }\n\n/**\n * Configuration for extending the user record type with custom metadata\n * validators and migration sequences.\n *\n * @example\n * ```ts\n * import { T } from '@tldraw/validate'\n *\n * const userSchema: UserSchemaInfo = {\n * meta: {\n * isAdmin: T.boolean,\n * department: T.string,\n * },\n * }\n * ```\n *\n * @public\n */\nexport interface UserSchemaInfo {\n\t/**\n\t * Validators for custom metadata fields on user records. Each field is\n\t * treated as optional \u2014 user records without these fields remain valid,\n\t * but when present, values are validated against the provided validators.\n\t */\n\tmeta?: Record<string, T.Validatable<any>>\n\n\t/**\n\t * Additional migration sequences for evolving custom user data over time.\n\t */\n\tmigrations?: readonly MigrationSequence[]\n}\n\n/**\n * Creates a complete TLSchema for use with tldraw stores. This schema defines the structure,\n * validation, and migration sequences for all record types in a tldraw application.\n *\n * The schema includes all core record types (pages, cameras, instances, etc.) plus the\n * shape, binding, and custom record types you specify. Style properties are automatically\n * collected from all shapes to ensure consistency across the application.\n *\n * @param options - Configuration options for the schema\n * - shapes - Shape schema configurations. Defaults to defaultShapeSchemas if not provided\n * - bindings - Binding schema configurations. Defaults to defaultBindingSchemas if not provided\n * - user - Custom user record configuration with meta validators and migrations\n * - records - Custom record type configurations. These are additional record types beyond\n * the built-in shapes, bindings, assets, etc.\n * - migrations - Additional migration sequences to include in the schema\n * @returns A complete TLSchema ready for use with Store creation\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas, defaultBindingSchemas } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * // Create schema with all default shapes and bindings\n * const schema = createTLSchema()\n *\n * // Create schema with custom shapes added\n * const customSchema = createTLSchema({\n * shapes: {\n * ...defaultShapeSchemas,\n * myCustomShape: {\n * props: myCustomShapeProps,\n * migrations: myCustomShapeMigrations,\n * },\n * },\n * })\n *\n * // Create schema with custom user metadata\n * const schemaWithCustomUser = createTLSchema({\n * user: {\n * meta: {\n * isAdmin: T.boolean,\n * department: T.string,\n * },\n * },\n * })\n *\n * // Create schema with custom record types\n * const schemaWithCustomRecords = createTLSchema({\n * records: {\n * comment: {\n * scope: 'document',\n * validator: T.object({\n * id: T.string,\n * typeName: T.literal('comment'),\n * text: T.string,\n * shapeId: T.string,\n * }),\n * },\n * },\n * })\n *\n * // Use the schema with a store\n * const store = new Store({\n * schema: customSchema,\n * props: {\n * defaultName: 'My Drawing',\n * },\n * })\n * ```\n */\nexport function createTLSchema({\n\tshapes = defaultShapeSchemas,\n\tbindings = defaultBindingSchemas,\n\tuser,\n\trecords = {},\n\tmigrations,\n}: {\n\tshapes?: Record<string, SchemaPropsInfo>\n\tbindings?: Record<string, SchemaPropsInfo>\n\tuser?: UserSchemaInfo\n\trecords?: Record<string, CustomRecordInfo>\n\tmigrations?: readonly MigrationSequence[]\n} = {}): TLSchema {\n\tconst stylesById = new Map<string, StyleProp<unknown>>()\n\tfor (const shape of objectMapValues(shapes)) {\n\t\tfor (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {\n\t\t\tif (stylesById.has(style.id) && stylesById.get(style.id) !== style) {\n\t\t\t\tthrow new Error(`Multiple StyleProp instances with the same id: ${style.id}`)\n\t\t\t}\n\t\t\tstylesById.set(style.id, style)\n\t\t}\n\t}\n\n\tconst ShapeRecordType = createShapeRecordType(shapes)\n\tconst BindingRecordType = createBindingRecordType(bindings)\n\tconst InstanceRecordType = createInstanceRecordType(stylesById)\n\tconst CustomUserRecordType = user ? createUserRecordType(user) : UserRecordType\n\n\t// Create RecordTypes for custom records\n\tconst builtInTypeNames = new Set([\n\t\t'asset',\n\t\t'binding',\n\t\t'camera',\n\t\t'document',\n\t\t'instance',\n\t\t'instance_page_state',\n\t\t'page',\n\t\t'instance_presence',\n\t\t'pointer',\n\t\t'shape',\n\t\t'store',\n\t\t'user',\n\t])\n\tconst customRecordTypes: Record<string, { createId: any }> = {}\n\tfor (const [typeName, config] of Object.entries(records)) {\n\t\tif (builtInTypeNames.has(typeName)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Custom record type name '${typeName}' conflicts with tldraw's built-in record type of that name. Choose a different name instead.`\n\t\t\t)\n\t\t}\n\t\tcustomRecordTypes[typeName] = createCustomRecordType(typeName, config)\n\t}\n\n\treturn StoreSchema.create(\n\t\t{\n\t\t\tasset: AssetRecordType,\n\t\t\tbinding: BindingRecordType,\n\t\t\tcamera: CameraRecordType,\n\t\t\tdocument: DocumentRecordType,\n\t\t\tinstance: InstanceRecordType,\n\t\t\tinstance_page_state: InstancePageStateRecordType,\n\t\t\tpage: PageRecordType,\n\t\t\tinstance_presence: InstancePresenceRecordType,\n\t\t\tpointer: PointerRecordType,\n\t\t\tshape: ShapeRecordType,\n\t\t\tuser: CustomUserRecordType,\n\t\t\t...customRecordTypes,\n\t\t},\n\t\t{\n\t\t\tmigrations: [\n\t\t\t\tstoreMigrations,\n\t\t\t\tassetMigrations,\n\t\t\t\tcameraMigrations,\n\t\t\t\tdocumentMigrations,\n\t\t\t\tinstanceMigrations,\n\t\t\t\tinstancePageStateMigrations,\n\t\t\t\tpageMigrations,\n\t\t\t\tinstancePresenceMigrations,\n\t\t\t\tpointerMigrations,\n\t\t\t\trootShapeMigrations,\n\n\t\t\t\tuserMigrations,\n\t\t\t\tbookmarkAssetMigrations,\n\t\t\t\timageAssetMigrations,\n\t\t\t\tvideoAssetMigrations,\n\n\t\t\t\t...processPropsMigrations<TLShape>('shape', shapes),\n\t\t\t\t...processPropsMigrations<TLBinding>('binding', bindings),\n\t\t\t\t...processCustomRecordMigrations(records),\n\n\t\t\t\t...(user?.migrations ?? []),\n\t\t\t\t...(migrations ?? []),\n\t\t\t],\n\t\t\tonValidationFailure,\n\t\t\tcreateIntegrityChecker,\n\t\t}\n\t)\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAA8C,mBAAmC;AACjF,SAAS,uBAAuB;
|
|
4
|
+
"sourcesContent": ["import { LegacyMigrations, MigrationSequence, StoreSchema, StoreValidator } from '@tldraw/store'\nimport { objectMapValues } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { TLBaseAsset } from './assets/TLBaseAsset'\nimport { bookmarkAssetMigrations, bookmarkAssetProps } from './assets/TLBookmarkAsset'\nimport { imageAssetMigrations, imageAssetProps } from './assets/TLImageAsset'\nimport { videoAssetMigrations, videoAssetProps } from './assets/TLVideoAsset'\nimport { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'\nimport {\n\tTLDefaultAsset,\n\tTLUnknownAsset,\n\tassetMigrations,\n\tcreateAssetRecordType,\n} from './records/TLAsset'\nimport { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'\nimport { CameraRecordType, cameraMigrations } from './records/TLCamera'\nimport {\n\tCustomRecordInfo,\n\tcreateCustomRecordType,\n\tprocessCustomRecordMigrations,\n} from './records/TLCustomRecord'\nimport { DocumentRecordType, documentMigrations } from './records/TLDocument'\nimport { createInstanceRecordType, instanceMigrations } from './records/TLInstance'\nimport { PageRecordType, pageMigrations } from './records/TLPage'\nimport { InstancePageStateRecordType, instancePageStateMigrations } from './records/TLPageState'\nimport { PointerRecordType, pointerMigrations } from './records/TLPointer'\nimport { InstancePresenceRecordType, instancePresenceMigrations } from './records/TLPresence'\nimport { TLRecord } from './records/TLRecord'\nimport {\n\tTLDefaultShape,\n\tTLShape,\n\tcreateShapeRecordType,\n\tgetShapePropKeysByStyle,\n\trootShapeMigrations,\n} from './records/TLShape'\nimport { UserRecordType, createUserRecordType, userMigrations } from './records/TLUser'\nimport { RecordProps, TLPropsMigrations, processPropsMigrations } from './recordsWithProps'\nimport { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\nimport { TLBaseShape } from './shapes/TLBaseShape'\nimport { bookmarkShapeMigrations, bookmarkShapeProps } from './shapes/TLBookmarkShape'\nimport { drawShapeMigrations, drawShapeProps } from './shapes/TLDrawShape'\nimport { embedShapeMigrations, embedShapeProps } from './shapes/TLEmbedShape'\nimport { frameShapeMigrations, frameShapeProps } from './shapes/TLFrameShape'\nimport { geoShapeMigrations, geoShapeProps } from './shapes/TLGeoShape'\nimport { groupShapeMigrations, groupShapeProps } from './shapes/TLGroupShape'\nimport { highlightShapeMigrations, highlightShapeProps } from './shapes/TLHighlightShape'\nimport { imageShapeMigrations, imageShapeProps } from './shapes/TLImageShape'\nimport { lineShapeMigrations, lineShapeProps } from './shapes/TLLineShape'\nimport { noteShapeMigrations, noteShapeProps } from './shapes/TLNoteShape'\nimport { textShapeMigrations, textShapeProps } from './shapes/TLTextShape'\nimport { videoShapeMigrations, videoShapeProps } from './shapes/TLVideoShape'\nimport { storeMigrations } from './store-migrations'\nimport { StyleProp } from './styles/StyleProp'\nimport { TLStoreProps, createIntegrityChecker, onValidationFailure } from './TLStore'\n\n/**\n * Configuration information for a schema type (shape, binding, or asset), including its properties,\n * metadata, and migration sequences for data evolution over time.\n *\n * @public\n * @example\n * ```ts\n * import { arrowShapeMigrations, arrowShapeProps } from './shapes/TLArrowShape'\n *\n * const myShapeSchema: SchemaPropsInfo = {\n * migrations: arrowShapeMigrations,\n * props: arrowShapeProps,\n * meta: {\n * customField: T.string,\n * },\n * }\n * ```\n */\nexport interface SchemaPropsInfo {\n\t/**\n\t * Migration sequences for handling data evolution over time. Can be legacy migrations,\n\t * props-specific migrations, or general migration sequences.\n\t */\n\tmigrations?: LegacyMigrations | TLPropsMigrations | MigrationSequence\n\n\t/**\n\t * Validation schema for the shape, binding, or asset properties.\n\t */\n\tprops?: Record<string, StoreValidator<any>>\n\n\t/**\n\t * Validation schema for metadata fields.\n\t */\n\tmeta?: Record<string, StoreValidator<any>>\n}\n\n/**\n * The complete schema definition for a tldraw store, encompassing all record types,\n * validation rules, and migration sequences. This schema defines the structure of\n * the persistent data model used by tldraw.\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * const schema: TLSchema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * const store = new Store({ schema })\n * ```\n */\nexport type TLSchema = StoreSchema<TLRecord, TLStoreProps>\n\n/**\n * Default shape schema configurations for all built-in tldraw shape types.\n * Each shape type includes its validation props and migration sequences.\n *\n * This object contains schema information for:\n * - arrow: Directional lines that can bind to other shapes\n * - bookmark: Website bookmark cards with preview information\n * - draw: Freehand drawing paths created with drawing tools\n * - embed: Embedded content from external services (YouTube, Figma, etc.)\n * - frame: Container shapes for organizing content\n * - geo: Geometric shapes (rectangles, ellipses, triangles, etc.)\n * - group: Logical groupings of multiple shapes\n * - highlight: Highlighting strokes from the highlighter tool\n * - image: Raster image shapes referencing image assets\n * - line: Multi-point lines and splines\n * - note: Sticky note shapes with text content\n * - text: Rich text shapes with formatting support\n * - video: Video shapes referencing video assets\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultShapeSchemas } from '@tldraw/tlschema'\n *\n * // Use all default shapes\n * const schema = createTLSchema({\n * shapes: defaultShapeSchemas,\n * })\n *\n * // Use only specific default shapes\n * const minimalSchema = createTLSchema({\n * shapes: {\n * geo: defaultShapeSchemas.geo,\n * text: defaultShapeSchemas.text,\n * },\n * })\n * ```\n */\nexport const defaultShapeSchemas = {\n\tarrow: { migrations: arrowShapeMigrations, props: arrowShapeProps },\n\tbookmark: { migrations: bookmarkShapeMigrations, props: bookmarkShapeProps },\n\tdraw: { migrations: drawShapeMigrations, props: drawShapeProps },\n\tembed: { migrations: embedShapeMigrations, props: embedShapeProps },\n\tframe: { migrations: frameShapeMigrations, props: frameShapeProps },\n\tgeo: { migrations: geoShapeMigrations, props: geoShapeProps },\n\tgroup: { migrations: groupShapeMigrations, props: groupShapeProps },\n\thighlight: { migrations: highlightShapeMigrations, props: highlightShapeProps },\n\timage: { migrations: imageShapeMigrations, props: imageShapeProps },\n\tline: { migrations: lineShapeMigrations, props: lineShapeProps },\n\tnote: { migrations: noteShapeMigrations, props: noteShapeProps },\n\ttext: { migrations: textShapeMigrations, props: textShapeProps },\n\tvideo: { migrations: videoShapeMigrations, props: videoShapeProps },\n} satisfies {\n\t[T in TLDefaultShape['type']]: {\n\t\tmigrations: SchemaPropsInfo['migrations']\n\t\tprops: RecordProps<TLBaseShape<T, Extract<TLDefaultShape, { type: T }>['props']>>\n\t}\n}\n\n/**\n * Default binding schema configurations for all built-in tldraw binding types.\n * Bindings represent relationships between shapes, such as arrows connected to shapes.\n *\n * Currently includes:\n * - arrow: Bindings that connect arrow shapes to other shapes at specific anchor points\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultBindingSchemas } from '@tldraw/tlschema'\n *\n * // Use default bindings\n * const schema = createTLSchema({\n * bindings: defaultBindingSchemas,\n * })\n *\n * // Add custom binding alongside defaults\n * const customSchema = createTLSchema({\n * bindings: {\n * ...defaultBindingSchemas,\n * myCustomBinding: {\n * props: myCustomBindingProps,\n * migrations: myCustomBindingMigrations,\n * },\n * },\n * })\n * ```\n */\nexport const defaultBindingSchemas = {\n\tarrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },\n} satisfies { [T in TLDefaultBinding['type']]: SchemaPropsInfo }\n\n/**\n * Default asset schema configurations for all built-in tldraw asset types.\n *\n * @public\n * @example\n * ```ts\n * import { createTLSchema, defaultAssetSchemas } from '@tldraw/tlschema'\n *\n * const schema = createTLSchema({\n * assets: defaultAssetSchemas,\n * })\n * ```\n */\nexport const defaultAssetSchemas = {\n\timage: { migrations: imageAssetMigrations, props: imageAssetProps },\n\tvideo: { migrations: videoAssetMigrations, props: videoAssetProps },\n\tbookmark: { migrations: bookmarkAssetMigrations, props: bookmarkAssetProps },\n} satisfies {\n\t[T in TLDefaultAsset['type']]: {\n\t\tmigrations: SchemaPropsInfo['migrations']\n\t\tprops: RecordProps<TLBaseAsset<T, Extract<TLDefaultAsset, { type: T }>['props']>>\n\t}\n}\n\n/**\n * Configuration for extending the user record type with custom metadata\n * validators and migration sequences.\n *\n * @example\n * ```ts\n * import { T } from '@tldraw/validate'\n *\n * const userSchema: UserSchemaInfo = {\n * meta: {\n * isAdmin: T.boolean,\n * department: T.string,\n * },\n * }\n * ```\n *\n * @public\n */\nexport interface UserSchemaInfo {\n\t/**\n\t * Validators for custom metadata fields on user records. Each field is\n\t * treated as optional \u2014 user records without these fields remain valid,\n\t * but when present, values are validated against the provided validators.\n\t */\n\tmeta?: Record<string, T.Validatable<any>>\n\n\t/**\n\t * Additional migration sequences for evolving custom user data over time.\n\t */\n\tmigrations?: readonly MigrationSequence[]\n}\n\n/**\n * Creates a complete TLSchema for use with tldraw stores. This schema defines the structure,\n * validation, and migration sequences for all record types in a tldraw application.\n *\n * The schema includes all core record types (pages, cameras, instances, etc.) plus the\n * shape, binding, asset, and custom record types you specify. Style properties are\n * automatically collected from all shapes to ensure consistency across the application.\n *\n * @param options - Configuration options for the schema\n * - shapes - Shape schema configurations. Defaults to defaultShapeSchemas if not provided\n * - bindings - Binding schema configurations. Defaults to defaultBindingSchemas if not provided\n * - assets - Asset schema configurations. Defaults to defaultAssetSchemas if not provided\n * - user - Custom user record configuration with meta validators and migrations\n * - records - Custom record type configurations. These are additional record types beyond\n * the built-in shapes, bindings, assets, etc.\n * - migrations - Additional migration sequences to include in the schema\n * @returns A complete TLSchema ready for use with Store creation\n *\n * @public\n * @example\n * ```ts\n * import {\n * createTLSchema,\n * defaultShapeSchemas,\n * defaultBindingSchemas,\n * defaultAssetSchemas,\n * } from '@tldraw/tlschema'\n * import { Store } from '@tldraw/store'\n *\n * // Create schema with all default shapes, bindings, and assets\n * const schema = createTLSchema()\n *\n * // Create schema with custom shapes added\n * const customSchema = createTLSchema({\n * shapes: {\n * ...defaultShapeSchemas,\n * myCustomShape: {\n * props: myCustomShapeProps,\n * migrations: myCustomShapeMigrations,\n * },\n * },\n * bindings: defaultBindingSchemas,\n * assets: defaultAssetSchemas,\n * })\n *\n * // Create schema with custom user metadata\n * const schemaWithCustomUser = createTLSchema({\n * user: {\n * meta: {\n * isAdmin: T.boolean,\n * department: T.string,\n * },\n * },\n * })\n *\n * // Create schema with custom record types\n * const schemaWithCustomRecords = createTLSchema({\n * records: {\n * comment: {\n * scope: 'document',\n * validator: T.object({\n * id: T.string,\n * typeName: T.literal('comment'),\n * text: T.string,\n * shapeId: T.string,\n * }),\n * },\n * },\n * })\n *\n * // Use the schema with a store\n * const store = new Store({\n * schema: customSchema,\n * props: {\n * defaultName: 'My Drawing',\n * },\n * })\n * ```\n */\nexport function createTLSchema({\n\tshapes = defaultShapeSchemas,\n\tbindings = defaultBindingSchemas,\n\tassets = defaultAssetSchemas,\n\tuser,\n\trecords = {},\n\tmigrations,\n}: {\n\tshapes?: Record<string, SchemaPropsInfo>\n\tbindings?: Record<string, SchemaPropsInfo>\n\tassets?: Record<string, SchemaPropsInfo>\n\tuser?: UserSchemaInfo\n\trecords?: Record<string, CustomRecordInfo>\n\tmigrations?: readonly MigrationSequence[]\n} = {}): TLSchema {\n\tconst stylesById = new Map<string, StyleProp<unknown>>()\n\tfor (const shape of objectMapValues(shapes)) {\n\t\tfor (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) {\n\t\t\tif (stylesById.has(style.id) && stylesById.get(style.id) !== style) {\n\t\t\t\tthrow new Error(`Multiple StyleProp instances with the same id: ${style.id}`)\n\t\t\t}\n\t\t\tstylesById.set(style.id, style)\n\t\t}\n\t}\n\n\tconst ShapeRecordType = createShapeRecordType(shapes)\n\tconst BindingRecordType = createBindingRecordType(bindings)\n\tconst _AssetRecordType = createAssetRecordType(assets)\n\tconst InstanceRecordType = createInstanceRecordType(stylesById)\n\tconst CustomUserRecordType = user ? createUserRecordType(user) : UserRecordType\n\n\t// Create RecordTypes for custom records\n\tconst builtInTypeNames = new Set([\n\t\t'asset',\n\t\t'binding',\n\t\t'camera',\n\t\t'document',\n\t\t'instance',\n\t\t'instance_page_state',\n\t\t'page',\n\t\t'instance_presence',\n\t\t'pointer',\n\t\t'shape',\n\t\t'store',\n\t\t'user',\n\t])\n\tconst customRecordTypes: Record<string, { createId: any }> = {}\n\tfor (const [typeName, config] of Object.entries(records)) {\n\t\tif (builtInTypeNames.has(typeName)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Custom record type name '${typeName}' conflicts with tldraw's built-in record type of that name. Choose a different name instead.`\n\t\t\t)\n\t\t}\n\t\tcustomRecordTypes[typeName] = createCustomRecordType(typeName, config)\n\t}\n\n\treturn StoreSchema.create(\n\t\t{\n\t\t\tasset: _AssetRecordType,\n\t\t\tbinding: BindingRecordType,\n\t\t\tcamera: CameraRecordType,\n\t\t\tdocument: DocumentRecordType,\n\t\t\tinstance: InstanceRecordType,\n\t\t\tinstance_page_state: InstancePageStateRecordType,\n\t\t\tpage: PageRecordType,\n\t\t\tinstance_presence: InstancePresenceRecordType,\n\t\t\tpointer: PointerRecordType,\n\t\t\tshape: ShapeRecordType,\n\t\t\tuser: CustomUserRecordType,\n\t\t\t...customRecordTypes,\n\t\t},\n\t\t{\n\t\t\tmigrations: [\n\t\t\t\tstoreMigrations,\n\t\t\t\tassetMigrations,\n\t\t\t\tcameraMigrations,\n\t\t\t\tdocumentMigrations,\n\t\t\t\tinstanceMigrations,\n\t\t\t\tinstancePageStateMigrations,\n\t\t\t\tpageMigrations,\n\t\t\t\tinstancePresenceMigrations,\n\t\t\t\tpointerMigrations,\n\t\t\t\trootShapeMigrations,\n\n\t\t\t\tuserMigrations,\n\n\t\t\t\t...processPropsMigrations<TLUnknownAsset>('asset', assets),\n\t\t\t\t...processPropsMigrations<TLShape>('shape', shapes),\n\t\t\t\t...processPropsMigrations<TLBinding>('binding', bindings),\n\t\t\t\t...processCustomRecordMigrations(records),\n\n\t\t\t\t...(user?.migrations ?? []),\n\t\t\t\t...(migrations ?? []),\n\t\t\t],\n\t\t\tonValidationFailure,\n\t\t\tcreateIntegrityChecker,\n\t\t}\n\t)\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAA8C,mBAAmC;AACjF,SAAS,uBAAuB;AAGhC,SAAS,yBAAyB,0BAA0B;AAC5D,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,wBAAwB,yBAAyB;AAC1D;AAAA,EAGC;AAAA,EACA;AAAA,OACM;AACP,SAAsC,+BAA+B;AACrE,SAAS,kBAAkB,wBAAwB;AACnD;AAAA,EAEC;AAAA,EACA;AAAA,OACM;AACP,SAAS,oBAAoB,0BAA0B;AACvD,SAAS,0BAA0B,0BAA0B;AAC7D,SAAS,gBAAgB,sBAAsB;AAC/C,SAAS,6BAA6B,mCAAmC;AACzE,SAAS,mBAAmB,yBAAyB;AACrD,SAAS,4BAA4B,kCAAkC;AAEvE;AAAA,EAGC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,gBAAgB,sBAAsB,sBAAsB;AACrE,SAAyC,8BAA8B;AACvE,SAAS,sBAAsB,uBAAuB;AAEtD,SAAS,yBAAyB,0BAA0B;AAC5D,SAAS,qBAAqB,sBAAsB;AACpD,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,oBAAoB,qBAAqB;AAClD,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,0BAA0B,2BAA2B;AAC9D,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,qBAAqB,sBAAsB;AACpD,SAAS,qBAAqB,sBAAsB;AACpD,SAAS,qBAAqB,sBAAsB;AACpD,SAAS,sBAAsB,uBAAuB;AACtD,SAAS,uBAAuB;AAEhC,SAAuB,wBAAwB,2BAA2B;AAgGnE,MAAM,sBAAsB;AAAA,EAClC,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,UAAU,EAAE,YAAY,yBAAyB,OAAO,mBAAmB;AAAA,EAC3E,MAAM,EAAE,YAAY,qBAAqB,OAAO,eAAe;AAAA,EAC/D,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,KAAK,EAAE,YAAY,oBAAoB,OAAO,cAAc;AAAA,EAC5D,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,WAAW,EAAE,YAAY,0BAA0B,OAAO,oBAAoB;AAAA,EAC9E,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,MAAM,EAAE,YAAY,qBAAqB,OAAO,eAAe;AAAA,EAC/D,MAAM,EAAE,YAAY,qBAAqB,OAAO,eAAe;AAAA,EAC/D,MAAM,EAAE,YAAY,qBAAqB,OAAO,eAAe;AAAA,EAC/D,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AACnE;AAoCO,MAAM,wBAAwB;AAAA,EACpC,OAAO,EAAE,YAAY,wBAAwB,OAAO,kBAAkB;AACvE;AAeO,MAAM,sBAAsB;AAAA,EAClC,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,OAAO,EAAE,YAAY,sBAAsB,OAAO,gBAAgB;AAAA,EAClE,UAAU,EAAE,YAAY,yBAAyB,OAAO,mBAAmB;AAC5E;AAsHO,SAAS,eAAe;AAAA,EAC9B,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AACD,IAOI,CAAC,GAAa;AACjB,QAAM,aAAa,oBAAI,IAAgC;AACvD,aAAW,SAAS,gBAAgB,MAAM,GAAG;AAC5C,eAAW,SAAS,wBAAwB,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG;AACtE,UAAI,WAAW,IAAI,MAAM,EAAE,KAAK,WAAW,IAAI,MAAM,EAAE,MAAM,OAAO;AACnE,cAAM,IAAI,MAAM,kDAAkD,MAAM,EAAE,EAAE;AAAA,MAC7E;AACA,iBAAW,IAAI,MAAM,IAAI,KAAK;AAAA,IAC/B;AAAA,EACD;AAEA,QAAM,kBAAkB,sBAAsB,MAAM;AACpD,QAAM,oBAAoB,wBAAwB,QAAQ;AAC1D,QAAM,mBAAmB,sBAAsB,MAAM;AACrD,QAAM,qBAAqB,yBAAyB,UAAU;AAC9D,QAAM,uBAAuB,OAAO,qBAAqB,IAAI,IAAI;AAGjE,QAAM,mBAAmB,oBAAI,IAAI;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAC;AACD,QAAM,oBAAuD,CAAC;AAC9D,aAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AACzD,QAAI,iBAAiB,IAAI,QAAQ,GAAG;AACnC,YAAM,IAAI;AAAA,QACT,4BAA4B,QAAQ;AAAA,MACrC;AAAA,IACD;AACA,sBAAkB,QAAQ,IAAI,uBAAuB,UAAU,MAAM;AAAA,EACtE;AAEA,SAAO,YAAY;AAAA,IAClB;AAAA,MACC,OAAO;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,qBAAqB;AAAA,MACrB,MAAM;AAAA,MACN,mBAAmB;AAAA,MACnB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,MAAM;AAAA,MACN,GAAG;AAAA,IACJ;AAAA,IACA;AAAA,MACC,YAAY;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEA;AAAA,QAEA,GAAG,uBAAuC,SAAS,MAAM;AAAA,QACzD,GAAG,uBAAgC,SAAS,MAAM;AAAA,QAClD,GAAG,uBAAkC,WAAW,QAAQ;AAAA,QACxD,GAAG,8BAA8B,OAAO;AAAA,QAExC,GAAI,MAAM,cAAc,CAAC;AAAA,QACzB,GAAI,cAAc,CAAC;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|