UNPKG

fvtt-types

Version:
355 lines (332 loc) 15.5 kB
// This file pertains to setting up documents, including defaults. For this reason there's a lot of references to `SomeDocument` instead of `SomeDocument.implementation`. /* eslint-disable @typescript-eslint/no-restricted-types, no-restricted-syntax */ import type { documents } from "../foundry/client/client.d.mts"; import type { Document } from "../foundry/common/abstract/_module.d.mts"; import type { InterfaceToObject, MakeConform, MustConform, FixedInstanceType } from "#utils"; import type * as configuration from "#configuration"; type DocumentConform<T> = MakeConform<T, Document.AnyConstructor>; interface DefaultDocumentClasses { ActiveEffect: typeof ActiveEffect; ActorDelta: typeof ActorDelta; Actor: typeof Actor; Adventure: typeof Adventure; Card: typeof Card; Cards: typeof Cards; ChatMessage: typeof ChatMessage; Combat: typeof Combat; Combatant: typeof Combatant; CombatantGroup: typeof CombatantGroup; FogExploration: typeof FogExploration; Folder: typeof Folder; Item: typeof Item; JournalEntryCategory: typeof JournalEntryCategory; JournalEntryPage: typeof JournalEntryPage; JournalEntry: typeof JournalEntry; Macro: typeof Macro; PlaylistSound: typeof PlaylistSound; Playlist: typeof Playlist; RegionBehavior: typeof RegionBehavior; RollTable: typeof RollTable; Scene: typeof Scene; Setting: typeof Setting; TableResult: typeof TableResult; User: typeof User; AmbientLight: typeof AmbientLightDocument; AmbientSound: typeof AmbientSoundDocument; Drawing: typeof DrawingDocument; MeasuredTemplate: typeof MeasuredTemplateDocument; Region: typeof RegionDocument; Note: typeof NoteDocument; Tile: typeof TileDocument; Token: typeof TokenDocument; Wall: typeof WallDocument; } interface DefaultDocumentInstance { ActiveEffect: ActiveEffect; ActorDelta: ActorDelta; Actor: Actor; Adventure: Adventure; Card: Card; Cards: Cards; ChatMessage: ChatMessage; Combat: Combat; Combatant: Combatant; CombatantGroup: CombatantGroup; FogExploration: FogExploration; Folder: Folder; Item: Item; JournalEntryCategory: JournalEntryCategory; JournalEntryPage: JournalEntryPage; JournalEntry: JournalEntry; Macro: Macro; PlaylistSound: PlaylistSound; Playlist: Playlist; RegionBehavior: RegionBehavior; RollTable: RollTable; Scene: Scene; Setting: Setting; TableResult: TableResult; User: User; AmbientLight: AmbientLightDocument; AmbientSound: AmbientSoundDocument; Drawing: DrawingDocument; MeasuredTemplate: MeasuredTemplateDocument; Note: NoteDocument; Region: RegionDocument; Tile: TileDocument; Token: TokenDocument; Wall: WallDocument; } type ResolvedDefaultDocuments = { [Type in Document.Type]: DefaultDocumentClasses[Type]; }; type TestDefaultDocumentsValid = MustConform<ResolvedDefaultDocuments, Record<string, Document.AnyConstructor>>; // Note(LukeAbby): This helper type is structured this way to make it as simple as possible for TypeScript to figure out that it's always a Document. // This also uses `ConcreteDocumentType extends keyof DocumentClassConfig` instead of `GetKey` or equivalent for the critical purposes of stymying circular errors. // See https://gist.github.com/LukeAbby/f9561689e5cad8a4b1e9cb92a8c63982 for more information. type GetDocumentClass<ConcreteDocumentType extends Document.Type> = ConcreteDocumentType extends keyof DocumentClassConfig ? DocumentClassConfig[ConcreteDocumentType] : DefaultDocumentClasses[ConcreteDocumentType]; type GetDocumentInstance<ConcreteDocumentType extends Document.Type> = ConcreteDocumentType extends keyof configuration.DocumentInstanceConfig ? configuration.DocumentInstanceConfig[ConcreteDocumentType] : ConcreteDocumentType extends keyof DocumentClassConfig ? FixedInstanceType<DocumentClassConfig[ConcreteDocumentType]> : DefaultDocumentInstance[ConcreteDocumentType]; // This interface exists as a way to catch circular errors easier. // This makes it more verbose than it might seem it has to be but it's important to stay this way. export interface ConfiguredDocumentClass { ActiveEffect: GetDocumentClass<"ActiveEffect">; ActorDelta: GetDocumentClass<"ActorDelta">; Actor: GetDocumentClass<"Actor">; Adventure: GetDocumentClass<"Adventure">; Card: GetDocumentClass<"Card">; Cards: GetDocumentClass<"Cards">; ChatMessage: GetDocumentClass<"ChatMessage">; Combat: GetDocumentClass<"Combat">; Combatant: GetDocumentClass<"Combatant">; CombatantGroup: GetDocumentClass<"CombatantGroup">; FogExploration: GetDocumentClass<"FogExploration">; Folder: GetDocumentClass<"Folder">; Item: GetDocumentClass<"Item">; JournalEntryCategory: GetDocumentClass<"JournalEntryCategory">; JournalEntryPage: GetDocumentClass<"JournalEntryPage">; JournalEntry: GetDocumentClass<"JournalEntry">; Macro: GetDocumentClass<"Macro">; PlaylistSound: GetDocumentClass<"PlaylistSound">; Playlist: GetDocumentClass<"Playlist">; RegionBehavior: GetDocumentClass<"RegionBehavior">; Region: GetDocumentClass<"Region">; RollTable: GetDocumentClass<"RollTable">; Scene: GetDocumentClass<"Scene">; Setting: GetDocumentClass<"Setting">; TableResult: GetDocumentClass<"TableResult">; User: GetDocumentClass<"User">; AmbientLight: GetDocumentClass<"AmbientLight">; AmbientSound: GetDocumentClass<"AmbientSound">; Drawing: GetDocumentClass<"Drawing">; MeasuredTemplate: GetDocumentClass<"MeasuredTemplate">; Note: GetDocumentClass<"Note">; Tile: GetDocumentClass<"Tile">; Token: GetDocumentClass<"Token">; Wall: GetDocumentClass<"Wall">; } export interface ConfiguredDocumentInstance { ActiveEffect: GetDocumentInstance<"ActiveEffect">; ActorDelta: GetDocumentInstance<"ActorDelta">; Actor: GetDocumentInstance<"Actor">; Adventure: GetDocumentInstance<"Adventure">; Card: GetDocumentInstance<"Card">; Cards: GetDocumentInstance<"Cards">; ChatMessage: GetDocumentInstance<"ChatMessage">; Combat: GetDocumentInstance<"Combat">; Combatant: GetDocumentInstance<"Combatant">; CombatantGroup: GetDocumentInstance<"CombatantGroup">; FogExploration: GetDocumentInstance<"FogExploration">; Folder: GetDocumentInstance<"Folder">; Item: GetDocumentInstance<"Item">; JournalEntryCategory: GetDocumentInstance<"JournalEntryCategory">; JournalEntryPage: GetDocumentInstance<"JournalEntryPage">; JournalEntry: GetDocumentInstance<"JournalEntry">; Macro: GetDocumentInstance<"Macro">; PlaylistSound: GetDocumentInstance<"PlaylistSound">; Playlist: GetDocumentInstance<"Playlist">; RegionBehavior: GetDocumentInstance<"RegionBehavior">; Region: GetDocumentInstance<"Region">; RollTable: GetDocumentInstance<"RollTable">; Scene: GetDocumentInstance<"Scene">; Setting: GetDocumentInstance<"Setting">; TableResult: GetDocumentInstance<"TableResult">; User: GetDocumentInstance<"User">; AmbientLight: GetDocumentInstance<"AmbientLight">; AmbientSound: GetDocumentInstance<"AmbientSound">; Drawing: GetDocumentInstance<"Drawing">; MeasuredTemplate: GetDocumentInstance<"MeasuredTemplate">; Note: GetDocumentInstance<"Note">; Tile: GetDocumentInstance<"Tile">; Token: GetDocumentInstance<"Token">; Wall: GetDocumentInstance<"Wall">; } type TestConfiguredClassesValid = MustConform< InterfaceToObject<ConfiguredDocumentClass>, Record<string, Document.AnyConstructor> >; type TestConfiguredInstanceValid = MustConform< InterfaceToObject<ConfiguredDocumentInstance>, Record<string, Document.Any> >; export interface ConfiguredMetadata { ActiveEffect: ActiveEffect.Metadata; ActorDelta: ActorDelta.Metadata; Actor: Actor.Metadata; Adventure: Adventure.Metadata; AmbientLight: AmbientLightDocument.Metadata; AmbientSound: AmbientSoundDocument.Metadata; Card: Card.Metadata; Cards: Cards.Metadata; ChatMessage: ChatMessage.Metadata; Combat: Combat.Metadata; Combatant: Combatant.Metadata; CombatantGroup: CombatantGroup.Metadata; Drawing: DrawingDocument.Metadata; FogExploration: FogExploration.Metadata; Folder: Folder.Metadata; Item: Item.Metadata; JournalEntryCategory: JournalEntryCategory.Metadata; JournalEntryPage: JournalEntryPage.Metadata; JournalEntry: JournalEntry.Metadata; Macro: Macro.Metadata; MeasuredTemplate: MeasuredTemplateDocument.Metadata; Note: NoteDocument.Metadata; PlaylistSound: PlaylistSound.Metadata; Playlist: Playlist.Metadata; RegionBehavior: RegionBehavior.Metadata; Region: RegionDocument.Metadata; RollTable: RollTable.Metadata; Scene: Scene.Metadata; Setting: Setting.Metadata; TableResult: TableResult.Metadata; Tile: TileDocument.Metadata; Token: TokenDocument.Metadata; User: User.Metadata; Wall: WallDocument.Metadata; } type MetadataShape = { [Name in Document.Type]: Document.Metadata<Document.Any>; }; type TestConfiguredMetadataValid = MustConform<ConfiguredMetadata, MetadataShape>; export interface CreateData { ActiveEffect: documents.BaseActiveEffect.CreateData; ActorDelta: documents.BaseActorDelta.CreateData; Actor: documents.BaseActor.CreateData; Adventure: documents.BaseAdventure.CreateData; Card: documents.BaseCard.CreateData; Cards: documents.BaseCards.CreateData; ChatMessage: documents.BaseChatMessage.CreateData; Combat: documents.BaseCombat.CreateData; Combatant: documents.BaseCombatant.CreateData; CombatantGroup: documents.BaseCombatantGroup.CreateData; FogExploration: documents.BaseFogExploration.CreateData; Folder: documents.BaseFolder.CreateData; Item: documents.BaseItem.CreateData; JournalEntryCategory: documents.BaseJournalEntryCategory.CreateData; JournalEntryPage: documents.BaseJournalEntryPage.CreateData; JournalEntry: documents.BaseJournalEntry.CreateData; Macro: documents.BaseMacro.CreateData; PlaylistSound: documents.BasePlaylistSound.CreateData; Playlist: documents.BasePlaylist.CreateData; RegionBehavior: documents.BaseRegionBehavior.CreateData; RollTable: documents.BaseRollTable.CreateData; Scene: documents.BaseScene.CreateData; Setting: documents.BaseSetting.CreateData; TableResult: documents.BaseTableResult.CreateData; User: documents.BaseUser.CreateData; AmbientLight: documents.BaseAmbientLight.CreateData; AmbientSound: documents.BaseAmbientSound.CreateData; Drawing: documents.BaseDrawing.CreateData; MeasuredTemplate: documents.BaseMeasuredTemplate.CreateData; Note: documents.BaseNote.CreateData; Region: documents.BaseRegion.CreateData; Tile: documents.BaseTile.CreateData; Token: documents.BaseToken.CreateData; Wall: documents.BaseWall.CreateData; } // This is a more paranoid version of `MakeConform` that catches `any`, `errorType`, etc. and returns // `Document.AnyConstructor` instead of letting them cascade. type ConformToDocumentConstructor<T extends Document.AnyConstructor> = [T] extends [Document.AnyConstructor] ? [1 & T] extends [2] ? Document.AnyConstructor : T : Document.AnyConstructor; interface MisconfiguredActiveEffect extends ConformToDocumentConstructor<typeof ActiveEffect> {} interface MisconfiguredActorDelta extends ConformToDocumentConstructor<typeof ActorDelta> {} interface MisconfiguredActor extends ConformToDocumentConstructor<typeof Actor> {} interface MisconfiguredAdventure extends ConformToDocumentConstructor<typeof Adventure> {} interface MisconfiguredCard extends ConformToDocumentConstructor<typeof Card> {} interface MisconfiguredCards extends ConformToDocumentConstructor<typeof Cards> {} interface MisconfiguredChatMessage extends ConformToDocumentConstructor<typeof ChatMessage> {} interface MisconfiguredCombat extends ConformToDocumentConstructor<typeof Combat> {} interface MisconfiguredCombatant extends ConformToDocumentConstructor<typeof Combatant> {} interface MisconfiguredCombatantGroup extends ConformToDocumentConstructor<typeof CombatantGroup> {} interface MisconfiguredFogExploration extends ConformToDocumentConstructor<typeof FogExploration> {} interface MisconfiguredFolder extends ConformToDocumentConstructor<typeof Folder> {} interface MisconfiguredItem extends ConformToDocumentConstructor<typeof Item> {} interface MisconfiguredJournalEntryCategory extends ConformToDocumentConstructor<typeof JournalEntryCategory> {} interface MisconfiguredJournalEntryPage extends ConformToDocumentConstructor<typeof JournalEntryPage> {} interface MisconfiguredJournalEntry extends ConformToDocumentConstructor<typeof JournalEntry> {} interface MisconfiguredMacro extends ConformToDocumentConstructor<typeof Macro> {} interface MisconfiguredPlaylistSound extends ConformToDocumentConstructor<typeof PlaylistSound> {} interface MisconfiguredPlaylist extends ConformToDocumentConstructor<typeof Playlist> {} interface MisconfiguredRegionBehavior extends ConformToDocumentConstructor<typeof RegionBehavior> {} interface MisconfiguredRollTable extends ConformToDocumentConstructor<typeof RollTable> {} interface MisconfiguredScene extends ConformToDocumentConstructor<typeof Scene> {} interface MisconfiguredSetting extends ConformToDocumentConstructor<typeof Setting> {} interface MisconfiguredTableResult extends ConformToDocumentConstructor<typeof TableResult> {} interface MisconfiguredUser extends ConformToDocumentConstructor<typeof User> {} interface MisconfiguredAmbientLight extends ConformToDocumentConstructor<typeof AmbientLightDocument> {} interface MisconfiguredAmbientSound extends ConformToDocumentConstructor<typeof AmbientSoundDocument> {} interface MisconfiguredDrawing extends ConformToDocumentConstructor<typeof DrawingDocument> {} interface MisconfiguredMeasuredTemplate extends ConformToDocumentConstructor<typeof MeasuredTemplateDocument> {} interface MisconfiguredNote extends ConformToDocumentConstructor<typeof NoteDocument> {} interface MisconfiguredRegion extends ConformToDocumentConstructor<typeof RegionDocument> {} interface MisconfiguredTile extends ConformToDocumentConstructor<typeof TileDocument> {} interface MisconfiguredToken extends ConformToDocumentConstructor<typeof TokenDocument> {} interface MisconfiguredWall extends ConformToDocumentConstructor<typeof WallDocument> {} /* eslint-enable */ export interface ConfigurationFailure { ActiveEffect: MisconfiguredActiveEffect; ActorDelta: MisconfiguredActorDelta; Actor: MisconfiguredActor; Adventure: MisconfiguredAdventure; Card: MisconfiguredCard; Cards: MisconfiguredCards; ChatMessage: MisconfiguredChatMessage; Combat: MisconfiguredCombat; Combatant: MisconfiguredCombatant; CombatantGroup: MisconfiguredCombatantGroup; FogExploration: MisconfiguredFogExploration; Folder: MisconfiguredFolder; Item: MisconfiguredItem; JournalEntryCategory: MisconfiguredJournalEntryCategory; JournalEntryPage: MisconfiguredJournalEntryPage; JournalEntry: MisconfiguredJournalEntry; Macro: MisconfiguredMacro; PlaylistSound: MisconfiguredPlaylistSound; Playlist: MisconfiguredPlaylist; RegionBehavior: MisconfiguredRegionBehavior; RollTable: MisconfiguredRollTable; Scene: MisconfiguredScene; Setting: MisconfiguredSetting; TableResult: MisconfiguredTableResult; User: MisconfiguredUser; AmbientLight: MisconfiguredAmbientLight; AmbientSound: MisconfiguredAmbientSound; Drawing: MisconfiguredDrawing; MeasuredTemplate: MisconfiguredMeasuredTemplate; Note: MisconfiguredNote; Region: MisconfiguredRegion; Tile: MisconfiguredTile; Token: MisconfiguredToken; Wall: MisconfiguredWall; }