UNPKG

fvtt-types

Version:
660 lines (580 loc) 27.6 kB
import type { Mixin, FixedInstanceType, Coalesce, AnyObject, Identity, MaybePromise, NullishProps, NullishCoalesce, InexactPartial, } from "#utils"; import type Document from "#common/abstract/document.d.mts"; import type { Application, FormApplication } from "#client/appv1/api/_module.d.mts"; import type ApplicationV2 from "#client/applications/api/application.d.mts"; import type TextEditor from "#client/applications/ux/text-editor.mjs"; declare class InternalClientDocument<DocumentName extends Document.Type> { /** @privateRemarks All mixin classses should accept anything for its constructor. */ constructor(...args: any[]); /** * A collection of Application instances which should be re-rendered whenever this document is updated. * The keys of this object are the application ids and the values are Application instances. * @defaultValue `{}` * @remarks Created during construction via `defineProperty`, with options `{value: {}, writable: false, enumerable: false}` */ readonly apps: Record<string, Application.Any | ApplicationV2.Any>; /** * A cached reference to the Application instance used to configure this Document. * @defaultValue `null` * @remarks Created during construction via `defineProperty`, with options `{value: null, writable: true, enumerable: false}` * @internal */ protected readonly _sheet: FixedInstanceType<Document.SheetClassFor<DocumentName>> | null; static name: "ClientDocumentMixin"; /** * @see {@link foundry.abstract.Document._initialize | `abstract.Document#_initialize`} * @remarks ClientDocument override calls `super`, then if `game._documentsReady`, calls {@link InternalClientDocument._safePrepareData | `this._safePrepareData`} */ // options: not null (parameter default only) protected _initialize(options?: Document.InitializeOptions): void; /** * Return a reference to the parent Collection instance which contains this Document. */ get collection(): Collection<this> | null; /** * A reference to the Compendium Collection which contains this Document, if any, otherwise undefined. */ get compendium(): DocumentName extends foundry.documents.collections.CompendiumCollection.DocumentName ? foundry.documents.collections.CompendiumCollection<DocumentName> : null; /** * Is this document in a compendium? A stricter check than {@link Document.inCompendium | `Document#inCompendium`}. */ // Note(LukeAbby): See https://github.com/microsoft/TypeScript/issues/61967 // get inCompendium(): boolean; /** * A boolean indicator for whether the current game User has ownership rights for this Document. * Different Document types may have more specialized rules for what constitutes ownership. */ get isOwner(): boolean; /** * Test whether this Document is owned by any non-Gamemaster User. */ get hasPlayerOwner(): boolean; /** * A boolean indicator for whether the current game User has exactly LIMITED visibility (and no greater). */ get limited(): boolean; /** * Return a string which creates a dynamic link to this Document instance. */ get link(): string; /** * Return the permission level that the current game User has over this Document. * See the CONST.DOCUMENT_OWNERSHIP_LEVELS object for an enumeration of these levels. * * @example * ```typescript * game.user.id; // "dkasjkkj23kjf" * actor.data.permission; // {default: 1, "dkasjkkj23kjf": 2}; * actor.permission; // 2 * ``` */ get permission(): CONST.DOCUMENT_OWNERSHIP_LEVELS | null; /** * Lazily obtain a FormApplication instance used to configure this Document, or null if no sheet is available. */ get sheet(): FormApplication.Any | ApplicationV2.Any | null; /** * A boolean indicator for whether or not the current game User has at least limited visibility for this Document. * Different Document types may have more specialized rules for what determines visibility. */ get visible(): boolean; /** * Obtain the FormApplication class constructor which should be used to configure this Document. */ protected _getSheetClass(): FormApplication.AnyConstructor | ApplicationV2.AnyConstructor | null; /** * Safely prepare data for a Document, catching any errors. */ protected _safePrepareData(): void; /** * Prepare data for the Document. This method is called automatically by the DataModel#_initialize workflow. * This method provides an opportunity for Document classes to define special data preparation logic. * The work done by this method should be idempotent. There are situations in which prepareData may be called more * than once. */ prepareData(): void; /** * Prepare data related to this Document itself, before any embedded Documents or derived data is computed. */ prepareBaseData(): void; /** * Prepare all embedded Document instances which exist within this primary Document. */ prepareEmbeddedDocuments(): void; /** * Apply transformations or derivations to the values of the source data object. * Compute data fields whose values are not stored to the database. */ prepareDerivedData(): void; /** * Render all Application instances which are connected to this document by calling their respective * @see {@link foundry.applications.api.ApplicationV2.render | `foundry.applications.api.ApplicationV2#render`} * @param force - Force rendering * (default: `false`) * @param context - Optional context * (default: `{}`) */ render(force?: boolean, context?: Application.RenderOptions | ApplicationV2.RenderOptions): void; /** * Determine the sort order for this Document by positioning it relative a target sibling. * See SortingHelper.performIntegerSort for more details * @param options - Sorting options provided to SortingHelper.performIntegerSort * @returns The Document after it has been re-sorted */ sortRelative(options?: ClientDocument.SortOptions<this>): Promise<this>; /** * Construct a UUID relative to another document. * @param doc - The document to compare against. */ getRelativeUUID(relative: ClientDocument): string; /** * Create a content link for this document * @param eventData - The parsed object of data provided by the drop transfer event. * @param options - Additional options to configure link generation. * @remarks Core's implementation doesn't use `eventData` here, but when it's passed in it's the return from * {@link TextEditor.getDragEventData | `TextEditor.getDragEventData(someDragEvent)`} */ // options: not null (destructured) _createDocumentLink(eventData?: AnyObject | null, options?: ClientDocument.CreateDocumentLinkOptions): string; /** * Handle clicking on a content link for this document. * @param event - The triggering click event. * @remarks * In `ClientDocument`, returns `this.sheet.render(true)`: * - AppV1: returns that sheet * - AppV2: returns a Promise of that sheet * * However it unfortunately has to be typed as `MaybePromise<unknown>` due to the {@link Macro._onClickDocumentLink | `Macro`} override, * where `##executeScript` could return whatever a user-provided macro wants. */ _onClickDocumentLink(event: MouseEvent): MaybePromise<unknown>; // _preCreate, _preUpdate, and _preDelete are all overridden with no signature changes, // just to call `this.system._preX` if `super` doesn't return `false` // _onCreate, _onUpdate, and _onDelete are all overridden but with no signature changes. // For type simplicity they are left off. These methods historically have been the source of a large amount of computation from tsc. /** * Orchestrate dispatching descendant document events to parent documents when embedded children are modified. * @param event - The event name, preCreate, onCreate, etc... * @param collection - The collection name being modified within this parent document * @param args - Arguments passed to each dispatched function * @param _parent - The document with directly modified embedded documents. * Either this document or a descendant of this one. * @internal * @remarks This has not been typed per-document as there does not appear to be a reason for users to ever extend or call this method. * If you have a use case for this, please file an issue. */ protected _dispatchDescendantDocumentEvents( event: ClientDocument.LifeCycleEventName, collection: string, args: never, _parent: never, ): void; /** * Actions taken after descendant documents have been created, but before changes are applied to the client data. * @param parent - The direct parent of the created Documents, may be this Document or a child * @param collection - The collection within which documents are being created * @param data - The source data for new documents that are being created * @param options - Options which modified the creation operation * @param userId - The ID of the User who triggered the operation */ protected _preCreateDescendantDocuments( parent: never, collection: never, data: never, options: never, userId: string, ): void; /** * Actions taken after descendant documents have been created and changes have been applied to client data. * @param parent - The direct parent of the created Documents, may be this Document or a child * @param collection - The collection within which documents were created * @param documents - The array of created Documents * @param data - The source data for new documents that were created * @param options - Options which modified the creation operation * @param userId - The ID of the User who triggered the operation */ protected _onCreateDescendantDocuments( parent: never, collection: never, documents: never, data: never, options: never, userId: string, ): void; /** * Actions taken after descendant documents have been updated, but before changes are applied to the client data. * @param parent - The direct parent of the updated Documents, may be this Document or a child * @param collection - The collection within which documents are being updated * @param changes - The array of differential Document updates to be applied * @param options - Options which modified the update operation * @param userId - The ID of the User who triggered the operation */ protected _preUpdateDescendantDocuments( parent: never, collection: never, changes: never, options: never, userId: string, ): void; /** * Actions taken after descendant documents have been updated and changes have been applied to client data. * @param parent - The direct parent of the updated Documents, may be this Document or a child * @param collection - The collection within which documents were updated * @param documents - The array of updated Documents * @param changes - The array of differential Document updates which were applied * @param options - Options which modified the update operation * @param userId - The ID of the User who triggered the operation */ protected _onUpdateDescendantDocuments( parent: never, collection: never, documents: never, changes: never, options: never, userId: string, ): void; /** * Actions taken after descendant documents have been deleted, but before deletions are applied to the client data. * @param parent - The direct parent of the deleted Documents, may be this Document or a child * @param collection - The collection within which documents were deleted * @param ids - The array of document IDs which were deleted * @param options - Options which modified the deletion operation * @param userId - The ID of the User who triggered the operation */ protected _preDeleteDescendantDocuments( parent: never, collection: never, ids: never, options: never, userId: string, ): void; /** * Actions taken after descendant documents have been deleted and those deletions have been applied to client data. * @param parent - The direct parent of the deleted Documents, may be this Document or a child * @param collection - The collection within which documents were deleted * @param documents - The array of Documents which were deleted * @param ids - The array of document IDs which were deleted * @param options - Options which modified the deletion operation * @param userId - The ID of the User who triggered the operation */ protected _onDeleteDescendantDocuments( parent: never, collection: never, documents: never, ids: string[], options: never, userId: string, ): void; /** * Whenever the Document's sheet changes, close any existing applications for this Document, and re-render the new * sheet if one was already open. */ protected _onSheetChange(options?: ClientDocument.OnSheetChangeOptions): Promise<void>; /** * Gets the default new name for a Document * @param context - The context for which to create the Document name. */ static defaultName(context: never): string; /** * Present a Dialog form to create a new Document of this type. * Choose a name and a type from a select menu of types. * @param data - Document creation data (default: `{}`) * @param createOptions - Document creation options (default: `{}`) * @param options - Options forwarded to DialogV2.prompt (default: `{}`) * @returns A Promise which resolves to the created Document, or null if the dialog was closed. * @throws If the document has * @privateRemarks `| undefined` is included in the return types of the specific document overrides due to {@link Document.create | `Document.create`} * possibly being `undefined` if creation is cancelled by preCreate methods or hooks */ static createDialog(data: never, createOptions: never, options?: never): Promise<unknown>; /** * Present a Dialog form to confirm deletion of this Document. * @param options - Additional options passed to `DialogV2.confirm` * (default: `{}`) * @param operation - Document deletion options. * (default: `{}`) * @returns A Promise that resolves to the deleted Document */ // options: not null (parameter default only) deleteDialog( options?: InexactPartial<foundry.applications.api.DialogV2.ConfirmConfig>, operation?: never, ): Promise<this | false | null | undefined>; /** * Export document data to a JSON file which can be saved by the client and later imported into a different session. * @param options - Additional options passed to the {@link ClientDocument.toCompendium | `ClientDocument#toCompendium`} method */ // options: not null (destructured where forwarded) exportToJSON(options?: ClientDocument.ToCompendiumOptions): void; /** * Serialize salient information about this Document when dragging it. */ toDragData(): Document.DropDataFor<DocumentName>; /** * A helper function to handle obtaining the relevant Document from dropped data provided via a DataTransfer event. * The dropped data could have: * 1. A data object explicitly provided * 2. A UUID * * @param data - The data object extracted from a DataTransfer event * @param options - Additional options which affect drop data behavior * @returns The resolved Document * @throws If a Document could not be retrieved from the provided data. * @remarks Core's implementation in `ClientDocument` does not use `options` at all, no call passes any `options` * anywhere in Foundry, and the JSDoc types it as simply `object`, so it cannot be typed more exactly than this. */ // options: not null (parameter default only) static fromDropData(data: never, options?: Document.DropDataOptions): Promise<unknown>; /** * Create the Document from the given source with migration applied to it. * Only primary Documents may be imported. * * This function must be used to create a document from data that predates the current core version. * It must be given nonpartial data matching the schema it had in the core version it is coming from. * It applies legacy migrations to the source data before calling {@linkcode Document.fromSource}. * If this function is not used to import old data, necessary migrations may not applied to the data * resulting in an incorrectly imported document. * * The core version is recorded in the `_stats` field, which all primary documents have. If the given source data * doesn't contain a `_stats` field, the data is assumed to be pre-V10, when the `_stats` field didn't exist yet. * The `_stats` field must not be stripped from the data before it is exported! * @param source - The document data that is imported. * @param context - The model construction context passed to {@linkcode Document.fromSource}. * (default: `context.strict=true`) Strict validation is enabled by default. */ // context: allowed to be null because spreading a variable with the value `null` into an object is allowed static fromImport(source: never, context?: never): Promise<unknown>; /** * Update this Document using a provided JSON string. * @param json - JSON data string * @returns The updated Document instance */ importFromJSON(json: string): Promise<this>; /** * Render an import dialog for updating the data related to this Document through an exported JSON file */ importFromJSONDialog(): Promise<void>; /** * Transform the Document data to be stored in a Compendium pack. * Remove any features of the data which are world-specific. * @param pack - A specific pack being exported to * @param options - Additional options which modify how the document is converted * (default: `{}`) * @returns A data object of cleaned data suitable for compendium import */ // options: not null (destructured) toCompendium<Options extends ClientDocument.ToCompendiumOptions | undefined = undefined>( pack?: foundry.documents.collections.CompendiumCollection<foundry.documents.collections.CompendiumCollection.DocumentName> | null, options?: Options, ): ClientDocument.ToCompendiumReturnType<DocumentName, Options>; /** * Create a content link for this Document. * @param options - Additional options to configure how the link is constructed. */ // options: not null (parameter default only) toAnchor(options?: TextEditor.EnrichmentAnchorOptions): HTMLAnchorElement; /** * Convert a Document to some HTML display for embedding purposes. * @param config - Configuration for embedding behavior. * @param options - The original enrichment options for cases where the Document embed content also contains text that must be enriched. * @returns A representation of the Document as HTML content, or null if such a representation could not be generated. */ // options: not null (parameter default only) toEmbed( config: TextEditor.DocumentHTMLEmbedConfig, options?: TextEditor.EnrichmentOptions, ): Promise<HTMLElement | null>; /** * Specific callback actions to take when the embedded HTML for this document has been added to the DOM. * @param element - The embedded document HTML */ onEmbed(element: foundry.applications.elements.HTMLDocumentEmbedElement): void; /** * A method that can be overridden by subclasses to customize embedded HTML generation. * @param config - Configuration for embedding behavior. * @param options - The original enrichment options for cases where the Document embed content also contains text that must be enriched. * @returns Either a single root element to append, or a collection of elements that comprise the embedded content */ protected _buildEmbedHTML( config: TextEditor.DocumentHTMLEmbedConfig, options?: TextEditor.EnrichmentOptions, ): Promise<HTMLElement | HTMLCollection | null>; /** * A method that can be overridden by subclasses to customize inline embedded HTML generation. * @param content - The embedded content. * @param config - Configuration for embedding behavior. * @param options - The original enrichment options for cases where the Document embed content also contains text that must be enriched. */ protected _createInlineEmbed( content: HTMLElement | HTMLCollection, config: TextEditor.DocumentHTMLEmbedConfig, options?: TextEditor.EnrichmentOptions, ): Promise<HTMLElement | null>; /** * A method that can be overridden by subclasses to customize the generation of the embed figure. * @param content - The embedded content. * @param config - Configuration for embedding behavior. * @param options - The original enrichment options for cases where the Document embed content also contains text that must be enriched. */ protected _createFigureEmbed( content: HTMLElement | HTMLCollection, config: TextEditor.DocumentHTMLEmbedConfig, options?: TextEditor.EnrichmentOptions, ): Promise<HTMLElement | null>; } type _ClientDocumentType = InternalClientDocument<Document.Type> & Document.AnyConstructor; declare const _ClientDocument: _ClientDocumentType; /** * A mixin which extends each Document definition with specialized client-side behaviors. * This mixin defines the client-side interface for database operations and common document behaviors. */ // FIXME(LukeAbby): Unlike most mixins, `ClientDocumentMixin` actually requires a specific constructor, the same as `Document`. // This means that `BaseClass extends Document.Internal.Constructor` is actually too permissive. // However this easily leads to circularities. declare function ClientDocumentMixin<BaseClass extends Document.Internal.Constructor>( Base: BaseClass, ): ClientDocumentMixin.Mix<BaseClass>; declare namespace ClientDocumentMixin { type Mix<BaseClass extends Document.Internal.Constructor> = Mixin< typeof InternalClientDocument<Document.NameFor<BaseClass>>, BaseClass >; } // TODO: Namespaces typically match the Mixin, not the non-exported class, but we're exporting the class for type reasons, // TODO: so this is an exception? declare global { interface ClientDocument extends FixedInstanceType<typeof _ClientDocument> {} interface ClientDocumentConstructor extends Identity<typeof _ClientDocument> {} namespace ClientDocument { interface SortOptions<T, SortKey extends string = "sort"> extends foundry.utils.SortOptions<T, SortKey> { /** * Additional data changes which are applied to each sorted document * @defaultValue `{}` */ updateData?: AnyObject; } // TODO: This may be better defined elsewhere type LifeCycleEventName = "preCreate" | "onCreate" | "preUpdate" | "onUpdate" | "preDelete" | "onDelete"; // Note(LukeAbby): If the property could be omitted it is. This is the safest option because in indeterminate cases access would be unsafe. // In the future the indeterminate case could turn the property optional but that isn't done today because that's annoying to do for little benefit. /** @internal */ type _OmitProperty< Omit extends boolean | null | undefined, Default extends boolean, ToOmit extends string, > = Omit extends true | (Default extends true ? undefined : never) ? ToOmit : never; /** @internal */ type _ToCompendiumOptions = NullishProps<{ /** * Clear the flags object * @defaultValue `false` */ clearFlags: boolean; /** * Clear any prior source information * @defaultValue `true` * @remarks Deletes `_stats.compendiumSource` and `_stats.duplicateSource`, won't delete legacy source flags */ clearSource: boolean; /** * Clear the currently assigned folder and sort order * @defaultValue `true` */ clearSort: boolean; /** * Clear the currently assigned folder * @defaultValue `false` */ clearFolder: boolean; /** * Clear document ownership * @defaultValue `true` */ clearOwnership: boolean; /** * Clear fields which store document state * @defaultValue `true` */ clearState: boolean; /** * Retain the current Document id * @defaultValue `false` */ keepId: boolean; }>; interface ToCompendiumOptions extends _ToCompendiumOptions {} /** @internal */ type _CreateDocumentLinkOptions = NullishProps<{ /** * A document to generate a link relative to. * @remarks Ignored if falsey */ relativeTo: ClientDocument; /** * A custom label to use instead of the document's name. * @defaultValue `this.name` */ label: string; }>; interface CreateDocumentLinkOptions extends _CreateDocumentLinkOptions {} /** The return type of {@link ClientDocument._onClickDocumentLink | `ClientDocument#_onClickDocumentLink`} if not overridden */ type OnClickDocumentLinkReturn = FormApplication.Any | Promise<ApplicationV2.Any>; type ToCompendiumReturnType< DocumentName extends Document.Type, Options extends ToCompendiumOptions | undefined, // eslint-disable-next-line @typescript-eslint/no-empty-object-type > = _ToCompendiumReturnType<DocumentName, Coalesce<Options, {}>>; type _ToCompendiumReturnType<DocumentName extends Document.Type, Options extends ToCompendiumOptions> = _ClearFog< Options["clearState"], _ClearStats< Options["clearSource"], Omit< Document.ImplementationFor<DocumentName>["_source"], | ClientDocument._OmitProperty<Options["clearFlags"], false, "flags"> | ClientDocument._OmitProperty<Options["clearSort"], true, "sort" | "navigation" | "navOrder"> // helping out Scene | ClientDocument._OmitProperty<Options["clearFolder"], true, "folder"> | ClientDocument._OmitProperty<Options["clearOwnership"], true, "ownership"> | ClientDocument._OmitProperty<Options["clearState"], true, "active" | "playing"> // helping out Playlist, Scene | (Options["keepId"] extends true ? never : "_id") > > >; /** @internal */ type _ClearStats<ClearSource extends boolean | null | undefined, SourceData extends object> = [ NullishCoalesce<ClearSource, true>, ] extends [true] ? { [K in keyof SourceData]: "_stats" extends K ? Omit<SourceData[K], "compendiumSource" | "duplicateSource"> : never; } : SourceData; /** @internal */ type _ClearFog<ClearState extends boolean | null | undefined, SourceData extends object> = [ NullishCoalesce<ClearState, true>, ] extends [true] ? { [K in keyof SourceData]: "fog" extends K ? Omit<SourceData[K], "reset"> : never; } : SourceData; /** @internal */ type _OnSheetChangeOptions = NullishProps<{ /** Whether the sheet was originally open and needs to be re-opened. */ sheetOpen: boolean; }>; interface OnSheetChangeOptions extends _OnSheetChangeOptions {} } } export { ClientDocumentMixin as default, InternalClientDocument };