import type { RecordModel } from "pocketbase"; export type Id = string & { __type: T }; export type UserId = Id<"User">; export type CampaignId = Id<"Campaign">; export type DocumentId = Id<"Document">; export type ISO8601Date = string & { __type: "iso8601date" }; export type Campaign = RecordModel & { id: CampaignId; name: string; owner: UserId; }; /****************************************** * Relationships ******************************************/ export const RelationshipType = { DiscoveredIn: "discoveredIn", Locations: "locations", Monsters: "monsters", Npcs: "npcs", Scenes: "scenes", Secrets: "secrets", Treasures: "treasures", } as const; export type RelationshipType = (typeof RelationshipType)[keyof typeof RelationshipType]; export type Relationship = RecordModel & { primary: DocumentId; secondary: DocumentId[]; type: RelationshipType; }; /****************************************** * Documents ******************************************/ export type DocumentData = { data: Record; }; export type Document = RecordModel & { id: DocumentId; campaign: CampaignId; data: { [K in DocumentType]?: unknown; }; // These two are not in Pocketbase's types, but they seem to always be present created: ISO8601Date; updated: ISO8601Date; }; export type DocumentType = | "location" | "monster" | "npc" | "scene" | "secret" | "session" | "treasure"; export type AnyDocument = | Location | Monster | Npc | Scene | Secret | Session | Treasure; export function getDocumentType(doc: AnyDocument): DocumentType { if (isLocation(doc)) { return "location"; } else if (isMonster(doc)) { return "monster"; } else if (isNpc(doc)) { return "npc"; } else if (isScene(doc)) { return "scene"; } else if (isSecret(doc)) { return "secret"; } else if (isSession(doc)) { return "session"; } else if (isTreasure(doc)) { return "treasure"; } throw new Error(`Document type not found: ${JSON.stringify(doc)}`); } /** Locations **/ export type Location = Document & DocumentData< "location", { name: string; description: string; } >; export function isLocation(doc: Document): doc is Location { return Object.hasOwn(doc.data, "location"); } /** Monsters **/ export type Monster = Document & DocumentData< "monster", { name: string; } >; export function isMonster(doc: Document): doc is Monster { return Object.hasOwn(doc.data, "monster"); } /** NPCs **/ export type Npc = Document & DocumentData< "npc", { name: string; description: string; } >; export function isNpc(doc: Document): doc is Npc { return Object.hasOwn(doc.data, "npc"); } /** Session **/ export type Session = Document & DocumentData< "session", { strongStart: string; } >; export function isSession(doc: Document): doc is Session { return Object.hasOwn(doc.data, "session"); } /** Scene **/ export type Scene = Document & DocumentData< "scene", { text: string; } >; export function isScene(doc: Document): doc is Scene { return Object.hasOwn(doc.data, "scene"); } /** Secret **/ export type Secret = Document & DocumentData< "secret", { text: string; discovered: boolean; } >; export function isSecret(doc: Document): doc is Secret { return Object.hasOwn(doc.data, "secret"); } /** Treasure **/ export type Treasure = Document & DocumentData< "treasure", { text: string; discovered: boolean; } >; export function isTreasure(doc: Document): doc is Treasure { return Object.hasOwn(doc.data, "treasure"); }