UNPKG

@tldraw/tlschema

Version:

tldraw infinite canvas SDK (schema).

125 lines (120 loc) 4 kB
import { BaseRecord } from '@tldraw/store' import { JsonObject } from '@tldraw/utils' import { T } from '@tldraw/validate' import { idValidator } from '../misc/id-validator' import { TLAssetId } from '../records/TLAsset' /** * Base interface for all asset records in tldraw. Assets represent external resources * like images, videos, or bookmarks that shapes can reference. This interface extends * the base record system with asset-specific typing. * * @param Type - The specific asset type identifier (e.g., 'image', 'video', 'bookmark') * @param Props - The properties object specific to this asset type * * @example * ```ts * // Define a custom asset type * interface MyCustomAsset extends TLBaseAsset<'custom', { url: string; title: string }> {} * * const customAsset: MyCustomAsset = { * id: 'asset:custom123', * typeName: 'asset', * type: 'custom', * props: { * url: 'https://example.com', * title: 'My Custom Asset' * }, * meta: {} * } * ``` * * @public */ export interface TLBaseAsset<Type extends string, Props> extends BaseRecord<'asset', TLAssetId> { /** The specific type of this asset (e.g., 'image', 'video', 'bookmark') */ type: Type /** Type-specific properties for this asset */ props: Props /** User-defined metadata that can be attached to this asset */ meta: JsonObject } /** * A validator for asset record type IDs. This validator ensures that asset IDs * follow the correct format and type structure required by tldraw's asset system. * Asset IDs are prefixed with 'asset:' followed by a unique identifier. * * @example * ```ts * import { assetIdValidator } from '@tldraw/tlschema' * * // Valid asset ID * const validId = 'asset:abc123' * console.log(assetIdValidator.isValid(validId)) // true * * // Invalid asset ID * const invalidId = 'shape:abc123' * console.log(assetIdValidator.isValid(invalidId)) // false * ``` * * @public */ export const assetIdValidator = idValidator<TLAssetId>('asset') /** * Creates a validator for a specific asset record type. This factory function generates * a complete validator that validates the entire asset record structure including the * base properties (id, typeName, type, meta) and the type-specific props. * * @param type - The asset type identifier (e.g., 'image', 'video', 'bookmark') * @param props - A validator or per-key validator record for the asset's type-specific properties * @param meta - An optional per-key validator record for the asset's meta properties * @returns A complete validator for the asset record type * * @example * ```ts * import { createAssetValidator, TLBaseAsset } from '@tldraw/tlschema' * import { T } from '@tldraw/validate' * * // Define a custom asset type * type TLCustomAsset = TLBaseAsset<'custom', { * url: string * title: string * description?: string * }> * * // Create validator using a per-key record (recommended) * const customAssetValidator = createAssetValidator('custom', { * url: T.string, * title: T.string, * description: T.string.optional() * }) * * // Or using a T.object validator * const customAssetValidator2 = createAssetValidator('custom', T.object({ * url: T.string, * title: T.string, * description: T.string.optional() * })) * ``` * * @public */ export function createAssetValidator< Type extends string, Props extends JsonObject, Meta extends JsonObject = JsonObject, >( type: Type, props?: T.Validator<Props> | { [K in keyof Props]: T.Validatable<Props[K]> }, meta?: { [K in keyof Meta]: T.Validatable<Meta[K]> } ) { // Determine if props is a Validator instance or a per-key record const propsValidator = props instanceof T.Validator ? props : props ? T.object(props) : (T.jsonValue as any) return T.object<TLBaseAsset<Type, Props>>({ id: assetIdValidator, typeName: T.literal('asset'), type: T.literal(type), props: propsValidator, meta: meta ? T.object(meta) : (T.jsonValue as T.ObjectValidator<JsonObject>), }) }