UNPKG

fvtt-types

Version:
810 lines (699 loc) 26.3 kB
import type { DataModel } from "../abstract/data.d.mts"; import type { AnyMutableObject, GetKey, NullishCoalesce, RemoveIndexSignatures, ToMethod, ValueOf } from "#utils"; import type { SchemaField } from "./fields.d.mts"; import fields = foundry.data.fields; import documents = foundry.documents; import Document = foundry.abstract.Document; type DataSchema = foundry.data.fields.DataSchema; declare namespace LightData { type Parent = TokenDocument.Implementation | AmbientLightDocument.Implementation; interface AnimationData extends fields.SchemaField.InitializedData<LightAnimationDataSchema> {} interface LightAnimationDataSchema extends DataSchema { /** * The animation type which is applied * @defaultValue `null` * @remarks While not enforced by the data model, this should be in `keyof CONFIG.Canvas.lightAnimations` * (or `.darknessAnimations` as appropriate) or the animation will be ignored */ type: fields.StringField<{ nullable: true; blank: false; initial: null }>; /** * The speed of the animation, a number between 0 and 10 * @defaultValue `5` */ speed: fields.NumberField<{ required: true; nullable: false; integer: true; initial: 5; min: 0; max: 10; validationError: "Light animation speed must be an integer between 0 and 10"; }>; /** * The intensity of the animation, a number between 1 and 10 * @defaultValue `5` */ intensity: fields.NumberField<{ required: true; nullable: false; integer: true; initial: 5; min: 1; max: 10; validationError: "Light animation intensity must be an integer between 1 and 10"; }>; /** * Reverse the direction of animation. * @defaultValue `false` */ reverse: fields.BooleanField; } interface DarknessSchema extends DataSchema { /** * @defaultValue `0` */ min: fields.AlphaField<{ initial: 0 }>; /** * @defaultValue `1` */ max: fields.AlphaField<{ initial: 1 }>; } interface Schema extends DataSchema { /** * Is this light source a negative source? (i.e. darkness source) * @defaultValue `false` */ negative: fields.BooleanField; /** * @defaultValue `0` */ priority: fields.NumberField<{ required: true; nullable: false; integer: true; initial: 0; min: 0 }>; /** * An opacity for the emitted light, if any * @defaultValue `0.5` */ alpha: fields.AlphaField<{ initial: 0.5 }>; /** * The angle of emission for this point source * @defaultValue `0` */ angle: fields.AngleField<{ initial: 360; normalize: false }>; /** * The allowed radius of bright vision or illumination * @defaultValue `0` */ bright: fields.NumberField<{ required: true; nullable: false; initial: 0; min: 0; step: 0.01 }>; /** * A tint color for the emitted light, if any * @defaultValue `null` */ color: fields.ColorField; /** * The coloration technique applied in the shader * @defaultValue `1` * @remarks This should match the `id` of the desired property of {@linkcode AdaptiveLightingShader.SHADER_TECHNIQUES} */ coloration: fields.NumberField<{ required: true; integer: true; initial: 1 }>; /** * The allowed radius of dim vision or illumination * @defaultValue `0` */ dim: fields.NumberField<{ required: true; nullable: false; initial: 0; min: 0; step: 0.01 }>; /** * Fade the difference between bright, dim, and dark gradually? * @defaultValue `0.5` */ attenuation: fields.AlphaField<{ initial: 0.5 }>; /** * The luminosity applied in the shader * @defaultValue `0.5` */ luminosity: fields.NumberField<{ required: true; nullable: false; initial: 0.5; min: 0; max: 1 }>; /** * The amount of color saturation this light applies to the background texture * @defaultValue `0` */ saturation: fields.NumberField<{ required: true; nullable: false; initial: 0; min: -1; max: 1 }>; /** * The amount of contrast this light applies to the background texture * @defaultValue `0` */ contrast: fields.NumberField<{ required: true; nullable: false; initial: 0; min: -1; max: 1 }>; /** * The depth of shadows this light applies to the background texture * @defaultValue `0` */ shadows: fields.NumberField<{ required: true; nullable: false; initial: 0; min: 0; max: 1 }>; /** * An animation configuration for the source * @defaultValue see properties */ animation: fields.SchemaField<LightAnimationDataSchema>; /** * A darkness range (min and max) for which the source should be active * @defaultValue see properties */ darkness: fields.SchemaField< DarknessSchema, { validate: (d: unknown) => boolean; validationError: "darkness.max may not be less than darkness.min"; } >; } } /** * A reusable document structure for the internal data used to render the appearance of a light source. * This is re-used by both the AmbientLightData and TokenData classes. */ declare class LightData extends DataModel<LightData.Schema, LightData.Parent> { static override defineSchema(): LightData.Schema; /** @defaultValue `["LIGHT"]` */ static override LOCALIZATION_PREFIXES: string[]; /** * @remarks * Migrations: * - negative `luminosity`s to `1 - luminosity` and setting `negative` true */ static override migrateData(source: AnyMutableObject): AnyMutableObject; } declare namespace ShapeData { interface Schema extends DataSchema { /** * The type of shape, a value in ShapeData.TYPES. * For rectangles, the x/y coordinates are the top-left corner. * For circles, the x/y coordinates are the center of the circle. * For polygons, the x/y coordinates are the first point of the polygon. * @defaultValue `"r"` */ type: fields.StringField<{ required: true; blank: false; choices: ValueOf<TYPES>[]; initial: "r" }>; /** * For rectangles, the pixel width of the shape. * @defaultValue `null` */ width: fields.NumberField<{ required: false; integer: true; min: 0 }>; /** * For rectangles, the pixel width of the shape. * @defaultValue `null` */ height: fields.NumberField<{ required: false; integer: true; min: 0 }>; /** * For circles, the pixel radius of the shape. * @defaultValue `null` */ radius: fields.NumberField<{ required: false; integer: true; positive: true }>; /** * For polygons, the array of polygon coordinates which comprise the shape. * @defaultValue `[]` */ points: fields.ArrayField<fields.NumberField<{ nullable: false }>>; } interface TYPES { RECTANGLE: "r"; CIRCLE: "c"; ELLIPSE: "e"; POLYGON: "p"; } } /** * A data model intended to be used as an inner EmbeddedDataField which defines a geometric shape. */ declare class ShapeData extends DataModel<ShapeData.Schema> { static override defineSchema(): ShapeData.Schema; static TYPES: ShapeData.TYPES; } declare namespace BaseShapeData { interface Source extends fields.SchemaField.SourceData<Schema> {} interface CreateData extends fields.SchemaField.CreateData<Schema> {} interface InitializedData extends fields.SchemaField.InitializedData<Schema> {} interface UpdateData extends fields.SchemaField.UpdateData<Schema> {} interface Schema<ShapeType extends ShapeTypes = ShapeTypes> extends DataSchema { /** * The type of shape, a value in BaseShapeData.TYPES. * @defaultValue `this.TYPE` * @remarks `this.TYPE` is `""` in `BaseShapeData`, and must be defined by subclasses */ type: fields.StringField<{ required: true; blank: false; initial: ShapeType; validate: (value: unknown) => value is ShapeType; // TODO: The following `choices` does not exist in Foundry, it's a type hack to get this field to report as the only valid value it can have // TODO: The validation function enough might be able to be made to sufficiently limit the value choices: [ShapeType]; validationError: `must be equal to "${ShapeType}"`; }>; /** * Is this shape a hole? * @defaultValue `false` */ hole: fields.BooleanField; } type ShapeTypes = keyof RemoveIndexSignatures<BaseShapeData.Types>; interface Types extends foundry.data.fields.TypedSchemaField.Types { rectangle: typeof RectangleShapeData; circle: typeof CircleShapeData; ellipse: typeof EllipseShapeData; polygon: typeof PolygonShapeData; } } /** * A data model intended to be used as an inner EmbeddedDataField which defines a geometric shape. */ declare abstract class BaseShapeData< ShapeSchema extends BaseShapeData.Schema = BaseShapeData.Schema, > extends DataModel<ShapeSchema> { /** * The possible shape types. */ static get TYPES(): Readonly<BaseShapeData.Types>; static #TYPES: Readonly<BaseShapeData.Types>; /** * The type of this shape. */ static TYPE: string; static override defineSchema(): BaseShapeData.Schema; } declare namespace RectangleShapeData { interface Schema extends BaseShapeData.Schema<"rectangle"> { /** * The top-left x-coordinate in pixels before rotation. * @defaultValue `undefined` */ x: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The top-left y-coordinate in pixels before rotation. * @defaultValue `undefined` */ y: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The width of the rectangle in pixels. * @defaultValue `undefined` */ width: fields.NumberField<{ required: true; nullable: false; initial: undefined; positive: true }>; /** * The height of the rectangle in pixels. * @defaultValue `undefined` */ height: fields.NumberField<{ required: true; nullable: false; initial: undefined; positive: true }>; /** * The rotation around the center of the rectangle in degrees. * @defaultValue `0` */ rotation: fields.AngleField; } } /** * The data model for a rectangular shape. */ declare class RectangleShapeData extends BaseShapeData<RectangleShapeData.Schema> { static override TYPE: "rectangle"; static override defineSchema(): RectangleShapeData.Schema; } declare namespace CircleShapeData { interface Schema extends BaseShapeData.Schema<"circle"> { /** * The x-coordinate of the center point in pixels. * @defaultValue `undefined` */ x: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The y-coordinate of the center point in pixels. * @defaultValue `undefined` */ y: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The radius of the circle in pixels. * @defaultValue `undefined` */ radius: fields.NumberField<{ required: true; nullable: false; initial: undefined; positive: true }>; } } /** * The data model for a circle shape. */ declare class CircleShapeData extends BaseShapeData<CircleShapeData.Schema> { static override TYPE: "circle"; static override defineSchema(): CircleShapeData.Schema; } declare namespace EllipseShapeData { interface Schema extends BaseShapeData.Schema<"ellipse"> { /** * The x-coordinate of the center point in pixels. * @defaultValue `undefined` */ x: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The y-coordinate of the center point in pixels. * @defaultValue `undefined` */ y: fields.NumberField<{ required: true; nullable: false; initial: undefined }>; /** * The x-radius of the circle in pixels. * @defaultValue `undefined` */ radiusX: fields.NumberField<{ required: true; nullable: false; initial: undefined; positive: true }>; /** * The y-radius of the circle in pixels. * @defaultValue `undefined` */ radiusY: fields.NumberField<{ required: true; nullable: false; initial: undefined; positive: true }>; /** * The rotation around the center of the rectangle in degrees. * @defaultValue `0` */ rotation: fields.AngleField; } } /** * The data model for an ellipse shape. */ declare class EllipseShapeData extends BaseShapeData<EllipseShapeData.Schema> { static override TYPE: "ellipse"; static override defineSchema(): EllipseShapeData.Schema; } declare namespace PolygonShapeData { interface Schema extends BaseShapeData.Schema<"polygon"> { /** * The points of the polygon ([x0, y0, x1, y1, ...]). * The polygon must not be self-intersecting. * @defaultValue `[]` */ points: fields.ArrayField< fields.NumberField<{ required: true; nullable: false; initial: undefined }>, { validate: (value: []) => void } >; } } /** * The data model for a polygon shape. */ declare class PolygonShapeData extends BaseShapeData<PolygonShapeData.Schema> { static override TYPE: "polygon"; static override defineSchema(): PolygonShapeData.Schema; } declare namespace TextureData { /** The parameter defaults for `srcOptions` in the {@link TextureData} constructor */ interface DefaultOptions { categories: ["IMAGE", "VIDEO"]; // Avoid using `EmptyObject` as that creates a broken index signature. // eslint-disable-next-line @typescript-eslint/no-empty-object-type initial: {}; wildcard: false; label: ""; } /** * The `initial` property of the `srcOptions` parameter of the {@linkcode TextureData} constructor * is not the `initial` for any one field, but instead is an object that gets parcelled out by key to the * fields of the schema * * @internal */ type _SrcOptionsInitial<T> = { [K in keyof T]: fields.DataField.Options.InitialType<T[K]>; }; /** @remarks The keys picked directly are passed on to the `src: FilePathField` field, but `initial` is an object of initial values for potentially every field in the schema */ interface SrcOptions extends Pick<fields.FilePathField.Options, "categories" | "wildcard" | "label"> { // eslint-disable-next-line @typescript-eslint/no-deprecated initial: _SrcOptionsInitial<fields.SchemaField.AssignmentData<Schema<DefaultOptions>>>; } interface Schema<Options extends SrcOptions = DefaultOptions> extends DataSchema { /** * The URL of the texture source. * @defaultValue `initial.src ?? null` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ src: fields.FilePathField<{ categories: NullishCoalesce<Options["categories"], DefaultOptions["categories"]>; initial: NullishCoalesce<GetKey<Options["initial"], "src", null>, null>; wildcard: NullishCoalesce<Options["wildcard"], DefaultOptions["wildcard"]>; label: NullishCoalesce<Options["label"], DefaultOptions["label"]>; }>; /** * The X coordinate of the texture anchor. * @defaultValue `initial.anchorX ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ anchorX: fields.NumberField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "anchorX", 0>, 0>; }>; /** * The Y coordinate of the texture anchor. * @defaultValue `initial.anchorY ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ anchorY: fields.NumberField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "anchorY", 0>, 0>; }>; /** * The X offset of the texture with (0,0) in the top left. * @defaultValue `initial.offsetX ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ offsetX: fields.NumberField<{ nullable: false; integer: true; initial: NullishCoalesce<GetKey<Options["initial"], "offsetX", 0>, 0>; }>; /** * The Y offset of the texture with (0,0) in the top left. * @defaultValue `initial.offsetY ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ offsetY: fields.NumberField<{ nullable: false; integer: true; initial: NullishCoalesce<GetKey<Options["initial"], "offsetY", 0>, 0>; }>; /** * @defaultValue `initial.fit ?? "fill"` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ fit: fields.StringField< { initial: NullishCoalesce<GetKey<Options["initial"], "fit", "fill">, "fill">; choices: typeof CONST.TEXTURE_DATA_FIT_MODES; }, ValueOf<typeof CONST.TEXTURE_DATA_FIT_MODES> | null | undefined, ValueOf<typeof CONST.TEXTURE_DATA_FIT_MODES>, ValueOf<typeof CONST.TEXTURE_DATA_FIT_MODES> >; /** * The scale of the texture in the X dimension. * @defaultValue `initial.scaleX ?? 1` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ scaleX: fields.NumberField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "scaleX", 1>, 1>; }>; /** * The scale of the texture in the Y dimension. * @defaultValue `initial.scaleY ?? 1` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ scaleY: fields.NumberField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "scaleY", 1>, 1>; }>; /** * An angle of rotation by which this texture is rotated around its center. * @defaultValue `initial.rotation ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ rotation: fields.AngleField<{ initial: NullishCoalesce<GetKey<Options["initial"], "rotation", 0>, 0>; }>; /** * The tint applied to the texture. * @defaultValue `initial.tint ?? "#ffffff"` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ tint: fields.ColorField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "tint", "#ffffff">, "#ffffff">; }>; /** * Only pixels with an alpha value at or above this value are consider solid * w.r.t. to occlusion testing and light/weather blocking. * @defaultValue `initial.alphaThreshold ?? 0` * @remarks The `initial` in the above default value is the property from the `srcOptions` * parameter of the {@linkcode TextureData} constructor */ alphaThreshold: fields.AlphaField<{ nullable: false; initial: NullishCoalesce<GetKey<Options["initial"], "alphaThreshold", 0>, 0>; }>; } } /** * A {@linkcode fields.SchemaField} subclass used to represent texture data. */ declare class TextureData< const SrcOptions extends TextureData.SrcOptions = TextureData.DefaultOptions, // eslint-disable-next-line @typescript-eslint/no-empty-object-type const SchemaOptions extends fields.SchemaField.Options<TextureData.Schema<SrcOptions>> = {}, > extends fields.SchemaField<TextureData.Schema<SrcOptions>, SchemaOptions> { /** * @param options - Options which are forwarded to the SchemaField constructor * @param srcOptions - Additional options for the src field */ constructor(options?: SchemaOptions, srcOptions?: SrcOptions); } declare namespace PrototypeToken { type Parent = documents.BaseActor; /** * The fields foundry omits from the BaseToken schema. Not used, left as reference * * @internal */ type ExcludedProperties = | "_id" | "actorId" | "delta" | "x" | "y" | "elevation" | "sort" | "hidden" | "locked" | "_regions"; /** * @remarks This has `PrototypeToken.#applyDefaultTokenSettings` run on it before actually being returned, so `initial` * values may not be exactly accurate as typed * @privateRemarks Since the {@link TokenDocument.Schema | `TokenDocument` schema} also extends `SharedProtoSchema`, * overrides & extensions specific to {@linkcode PrototypeToken} must go here */ interface Schema extends TokenDocument.SharedProtoSchema { /** * The name used to describe the Token * @defaultValue `""` * @privateRemarks Only change from parent schema is `textSearch: false` */ name: fields.StringField<{ required: true; blank: true; textSearch: false }>; /** * Does the prototype token use a random wildcard image? * @defaultValue `false` * @privateRemarks New field, not in parent schema */ randomImg: fields.BooleanField; } /** * @deprecated Replace with {@linkcode PrototypeToken.CreateData}. */ type ConstructorData = CreateData; interface CreateData extends fields.SchemaField.CreateData<Schema> {} interface UpdateData extends fields.SchemaField.UpdateData<Schema> {} interface Source extends fields.SchemaField.SourceData<Schema> {} export import Flags = TokenDocument.Flags; } /** * Extend the base TokenData to define a PrototypeToken which exists within a parent Actor. */ declare class PrototypeToken extends DataModel<PrototypeToken.Schema, PrototypeToken.Parent> { // options: not null (destructured when passed to super) constructor(data?: PrototypeToken.Source | null, options?: DataModel.ConstructionContext<PrototypeToken.Parent>); /** * @defaultValue `{}` * @remarks Created via `defineProperty` in constructor */ apps: Record<string, foundry.appv1.api.Application.Any | foundry.applications.api.ApplicationV2.Any>; static override defineSchema(): PrototypeToken.Schema; /** * @defaultValue `["TOKEN"]` */ static override LOCALIZATION_PREFIXES: string[]; /** * The Actor which owns this Prototype Token */ get actor(): this["parent"]; override toObject( source?: boolean | null, ): SchemaField.SourceData<PrototypeToken.Schema> & { actorId: string | undefined }; static get database(): CONFIG["DatabaseBackend"]; /** * Apply configured default token settings to the schema. * @param schema - The schema to apply the settings to. */ static #applyDefaultTokenSettings(schema: DataSchema): void; /** * @see {@link foundry.abstract.Document.update | `foundry.abstract.Document#update`} * @remarks Despite the above `@see`, forwards to {@link Actor.update | `this.actor.update`} after wrapping `data` * in `{prototypeToken: data}` */ update( data: PrototypeToken.UpdateData | undefined, operation?: Actor.Database.UpdateOperation, ): Promise<Actor.Implementation | undefined>; /** * @see {@link foundry.abstract.Document.getFlag | `foundry.abstract.Document#getFlag`} */ getFlag<Scope extends TokenDocument.Flags.Scope, Key extends TokenDocument.Flags.Key<Scope>>( scope: Scope, key: Key, ): TokenDocument.Flags.Get<Scope, Key>; /** * @see {@link foundry.abstract.Document.setFlag | `foundry.abstract.Document#setFlag`} */ setFlag< Scope extends TokenDocument.Flags.Scope, Key extends TokenDocument.Flags.Key<Scope>, Value extends TokenDocument.Flags.Get<Scope, Key>, >(scope: Scope, key: Key, value: Value): Promise<this>; /** * @see {@link foundry.abstract.Document.unsetFlag | `foundry.abstract.Document#unsetFlag`} */ unsetFlag<Scope extends TokenDocument.Flags.Scope, Key extends TokenDocument.Flags.Key<Scope>>( scope: Scope, key: Key, ): Promise<this>; /** * @see {@link Document.testUserPermission | `Document#testUserPermission`} * @remarks Forwards to {@link Actor.testUserPermission | `this.actor.testUserPermission`}. Core's `Actor` implementation * doesn't override this method, so without further extension, that's equivalent to `Document#testUserPermission` */ // options: not null (destructured) testUserPermission( user: User.Implementation, permission: Document.ActionPermission, options?: Document.TestUserPermissionOptions, ): boolean; /** * @see {@link foundry.abstract.Document.isOwner | `foundry.abstract.Document#isOwner`} */ get isOwner(): boolean; /** * @see {@link TokenDocument.getBarAttribute | `TokenDocument#getBarAttribute`} * * @remarks This is monkey patched in from `token.js`, put here due to issues with the merge process */ getBarAttribute: ToMethod<TokenDocument.Implementation["getBarAttribute"]>; } declare namespace TombstoneData { interface Schema extends DataSchema { /** * The _id of the base Document that this tombstone represents. * @defaultValue `null` */ _id: fields.DocumentIdField; /** * A property that identifies this entry as a tombstone. * @defaultValue `true` */ _tombstone: fields.BooleanField<{ initial: true; validate: (v: unknown) => boolean; validationError: "must be true"; }>; } } /** * A minimal data model used to represent a tombstone entry inside an EmbeddedCollectionDelta. */ declare class TombstoneData extends DataModel<TombstoneData.Schema> { static override defineSchema(): TombstoneData.Schema; } export { LightData, PrototypeToken, ShapeData, BaseShapeData, RectangleShapeData, CircleShapeData, EllipseShapeData, PolygonShapeData, TextureData, TombstoneData, };