Skip to content

Commit

Permalink
reworked generic types, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dovrosenberg committed Dec 10, 2024
1 parent ab67314 commit a44e98f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 52 deletions.
41 changes: 19 additions & 22 deletions src/foundry/client/data/collections/compendium-collection.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {
DatabaseUpdateOperation,
} from "../../../common/abstract/_types.d.mts";
import type Document from "../../../common/abstract/document.d.mts";
import type { ObjectField } from '../../../common/data/fields.d.mts';
import type { DirectoryCollectionMixin_DocumentCollection_Interface } from "../abstract/directory-collection-mixin.d.mts";

declare const DirectoryCollectionMixin_DocumentCollection: DirectoryCollectionMixin_DocumentCollection_Interface;
Expand Down Expand Up @@ -51,7 +50,7 @@ declare global {
T extends CompendiumCollection.Metadata,
> extends DirectoryCollectionMixin_DocumentCollection<Document.ConfiguredClassForName<T["type"]>, T["name"]> {
/** @param metadata - The compendium metadata, an object provided by game.data */
constructor(metadata: CompendiumCollection.ConstructorMetadata<T["type"]>);
constructor(metadata: CompendiumCollection.ConstructorMetadata<T>);

/** The compendium metadata which defines the compendium content and location */
metadata: T;
Expand Down Expand Up @@ -132,7 +131,7 @@ declare global {
/**
* The visibility configuration of this compendium pack.
* */
get ownership(): foundry.packages.BasePackage.OwnershipRecord;
get ownership(): InexactPartial<foundry.packages.BasePackage.OwnershipRecord>;

/** Is this Compendium pack visible to the current game User? */
get visible(): boolean;
Expand Down Expand Up @@ -316,7 +315,7 @@ declare global {
* Prompt the gamemaster with a dialog to configure ownership of this Compendium pack.
* @returns The configured ownership for the pack
*/
configureOwnershipDialog(): Promise<foundry.packages.BasePackage.OwnershipRecord>;
configureOwnershipDialog(): Promise<InexactPartial<foundry.packages.BasePackage.OwnershipRecord>>;

/**
* Activate the Socket event listeners used to receive responses to compendium management events.
Expand All @@ -331,10 +330,10 @@ declare global {
* @param options - Additional options which modify the Compendium creation request
* default `{}`
*/
static createCompendium<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES>(
static createCompendium<T extends CompendiumCollection.Metadata>(
metadata: CompendiumCollection.CreateCompendiumMetadata<T>,
options?: Document.OnCreateOptions<T>,
): Promise<CompendiumCollection<CompendiumCollection.Metadata<T>>>;
options?: Document.OnCreateOptions<T["type"]>,
): Promise<CompendiumCollection<T>>;

/**
* Generate a UUID for a given primary document ID within this Compendium pack
Expand Down Expand Up @@ -417,33 +416,31 @@ declare global {
type Any = CompendiumCollection<any>;

interface Configuration {
ownership: foundry.packages.BasePackage.OwnershipRecord;
ownership: InexactPartial<foundry.packages.BasePackage.OwnershipRecord>;
locked: boolean;
}

// The type that's passed to `createCompendium`.
interface CreateCompendiumMetadata<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> {
type: T;
interface CreateCompendiumMetadata<T extends CompendiumCollection.Metadata> {
type: T["type"];
label: string;
name?: string | null | undefined;
}

// The type that's passed to `new CompendiumCollection(...)`
interface ConstructorMetadata<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> {
type: T;

type ConstructorMetadata<T extends CompendiumCollection.Metadata> = T & {
index: IndexTypeForMetadata<T>;
folders: Folder[];
}

// The type that appears in `compendium.metadata` after initialization.
interface Metadata<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> {
type: T;
interface Metadata {
type: foundry.CONST.COMPENDIUM_DOCUMENT_TYPES;
label: string;
name: string;

flags: ObjectField.FlagsField<T>,
ownership: foundry.packages.BasePackage.OwnershipRecord;
flags: Record<string, never>; // created by the server, but always empty and no way to change it in a way that is s
ownership: InexactPartial<foundry.packages.BasePackage.OwnershipRecord>;
path: string;
package: string;
system: string;
Expand All @@ -454,17 +451,17 @@ declare global {
packageName: string;
}

interface GetIndexOptions<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> {
interface GetIndexOptions<T extends CompendiumCollection.Metadata> {
/**
* An array of fields to return as part of the index
* @defaultValue `[]`
*/
fields?: (keyof Document.ConfiguredInstanceForName<T>["_source"])[];
fields?: (keyof Document.ConfiguredInstanceForName<T["type"]>["_source"])[];
}

// TODO: Improve automatic index properties based on document type
type IndexEntry<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> = { _id: string; uuid: string } & DeepPartial<
Document.ConfiguredInstanceForName<T>["_source"]
type IndexEntry<T extends CompendiumCollection.Metadata> = { _id: string; uuid: string } & DeepPartial<
Document.ConfiguredInstanceForName<T["type"]>["_source"]
>;
}
}
Expand All @@ -487,6 +484,6 @@ interface ImportAllOptions {
options?: (Document.ModificationContext<Document.Any | null> & WorldCollection.FromCompendiumOptions) | undefined;
}

type IndexTypeForMetadata<T extends foundry.CONST.COMPENDIUM_DOCUMENT_TYPES> = foundry.utils.Collection<
type IndexTypeForMetadata<T extends CompendiumCollection.Metadata> = foundry.utils.Collection<
CompendiumCollection.IndexEntry<T>
>;
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
import { expectTypeOf } from "vitest";
import type { DeepPartial } from "../../../../../src/types/utils.d.mts";
import type Document from "../../../../../src/foundry/common/abstract/document.d.mts";
// import type Document from "../../../../../src/foundry/common/abstract/document.d.mts";
import "../../../../../src/foundry/client/data/collections/compendium-collection.d.mts";
import "../../../../../src/foundry/client/data/abstract/document-collection.d.mts";
import "../../../../../src/foundry/client/data/documents/journal-entry.d.mts";
import "../../../../../src/foundry/client/data/documents/item.d.mts";

const metadata = {

const compendiumCollection = await CompendiumCollection.createCompendium({
type: "JournalEntry" as const,
label: "Important Plotholes",
id: "world.plotholes",
name: "plotholes",
package: "some-package",
path: "path/to/file",
private: false,
});

expectTypeOf(compendiumCollection).toEqualTypeOf<CompendiumCollection<CompendiumCollection.Metadata>>();
expectTypeOf(compendiumCollection.metadata).toEqualTypeOf<CompendiumCollection.Metadata>();

const metadata: CompendiumCollection.Metadata = {
name: "plotholes",
type: "JournalEntry" as const,
label: "Important Plotholes",
flags: {},
id: "plotholes",
system: "core",
package: "plotholes",
packageName: "plotholes",
packageType: "module",
path: "path",
ownership: {
PLAYER: "OWNER",
}
};

const compendiumCollection = new CompendiumCollection(metadata);
expectTypeOf(compendiumCollection.get("", { strict: true })).toEqualTypeOf<Document.Stored<JournalEntry>>();
const constructorMetadata: CompendiumCollection.ConstructorMetadata<typeof metadata> = {
...(metadata as CompendiumCollection.Metadata),
index: new foundry.utils.Collection(),
folders: [],
};

const compendium2 = new CompendiumCollection(constructorMetadata);

expectTypeOf(compendium2).toEqualTypeOf<CompendiumCollection<CompendiumCollection.Metadata>>();
expectTypeOf(compendium2.metadata).toEqualTypeOf<CompendiumCollection.Metadata>();

// expectTypeOf(compendiumCollection.get("", { strict: true })).toEqualTypeOf<Document.Stored<JournalEntry>>();
// expectTypeOf(compendiumCollection.toJSON()).toEqualTypeOf<
// Array<Document.Stored<foundry.documents.BaseJournalEntry>["_source"]>
// >();
Expand All @@ -35,25 +65,22 @@ expectTypeOf((await compendiumCollection.getIndex()).get("some id", { strict: tr

expectTypeOf(compendiumCollection.documentClass).toEqualTypeOf<typeof JournalEntry>();

const itemCollection = new CompendiumCollection({
type: "Item",
label: "Important items",
id: "world.items",
name: "items",
package: "other-package",
path: "path/to/items",
private: false,
});
expectTypeOf((await itemCollection.getIndex()).get("some id", { strict: true })).toEqualTypeOf<
{ _id: string; uuid: string } & DeepPartial<foundry.documents.BaseItem["_source"]>
>();
expectTypeOf(
(await itemCollection.getIndex({ fields: ["name", "effects", "system"] })).get("some id", { strict: true }),
).toEqualTypeOf<{ _id: string; uuid: string } & DeepPartial<foundry.documents.BaseItem["_source"]>>();

expectTypeOf(await itemCollection.getDocuments()).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items
expectTypeOf(await itemCollection.getDocuments({})).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items
expectTypeOf(await itemCollection.getDocuments({ name: "foo" })).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items called "foo"
expectTypeOf(
await itemCollection.getDocuments({ $or: [{ name: "baz" }, { name: "bar" }], effects: { $size: 2 } }), // only get items called "baz" or "bar" that have exactly 2 effects
).toEqualTypeOf<Document.Stored<Item>[]>();
// const itemCollection = new CompendiumCollection({
// ...metadata,
// type: "Item" as const,
// index: new foundry.utils.Collection(),
// folders: [],
// });
// expectTypeOf((await itemCollection.getIndex()).get("some id", { strict: true })).toEqualTypeOf<
// { _id: string; uuid: string } & DeepPartial<foundry.documents.BaseItem["_source"]>
// >();
// expectTypeOf(
// (await itemCollection.getIndex({ fields: ["name", "effects", "system"] })).get("some id", { strict: true }),
// ).toEqualTypeOf<{ _id: string; uuid: string } & DeepPartial<foundry.documents.BaseItem["_source"]>>();

// expectTypeOf(await itemCollection.getDocuments()).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items
// expectTypeOf(await itemCollection.getDocuments({})).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items
// expectTypeOf(await itemCollection.getDocuments({ name: "foo" })).toEqualTypeOf<Document.Stored<Item>[]>(); // get all items called "foo"
// expectTypeOf(
// await itemCollection.getDocuments({ $or: [{ name: "baz" }, { name: "bar" }], effects: { $size: 2 } }), // only get items called "baz" or "bar" that have exactly 2 effects
// ).toEqualTypeOf<Document.Stored<Item>[]>();

0 comments on commit a44e98f

Please sign in to comment.