import { registerEnumType } from '@nestjs/graphql'; export enum DocVariant { Workspace = 'workspace', Page = 'page', Space = 'space', Settings = 'settings', Unknown = 'unknown', } registerEnumType(DocVariant, { name: 'DocVariant', }); export class DocID { raw: string; workspace: string; variant: DocVariant; private sub: string | null; static parse(raw: string): DocID | null { try { return new DocID(raw); } catch (e) { return null; } } /** * pure guid for workspace and subdoc without any prefix */ get guid(): string { return this.variant === DocVariant.Workspace ? this.workspace : // sub is always truthy when variant is not workspace // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.sub!; } get full(): string { return this.variant === DocVariant.Workspace ? this.workspace : `${this.workspace}:${this.variant}:${this.sub}`; } get isWorkspace(): boolean { return this.variant === DocVariant.Workspace; } constructor(raw: string, workspaceId?: string) { if (!raw.length) { throw new Error('Invalid Empty Doc ID'); } let parts = raw.split(':'); if (parts.length > 3) { throw new Error(`Invalid format of Doc ID: ${raw}`); } else if (parts.length === 2) { // `${variant}:${guid}` if (!workspaceId) { throw new Error('Workspace is required'); } parts.unshift(workspaceId); } else if (parts.length === 1) { // ${ws} or ${pageId} if (workspaceId && parts[0] !== workspaceId) { parts = [workspaceId, DocVariant.Unknown, parts[0]]; } else { // parts:[ws] equals [workspaceId] } } let workspace = parts.at(0); // fix for `${non-workspaceId}:${variant}:${guid}` if (workspaceId) { workspace = workspaceId; } const variant = parts.at(1); const docId = parts.at(2); if (!workspace) { throw new Error('Workspace is required'); } if (variant) { if (!Object.values(DocVariant).includes(variant as any)) { throw new Error(`Invalid ID variant: ${variant}`); } if (!docId) { throw new Error('ID is required for non-workspace doc'); } } else if (docId) { throw new Error('Variant is required for non-workspace doc'); } this.raw = raw; this.workspace = workspace; this.variant = (variant as DocVariant | undefined) ?? DocVariant.Workspace; this.sub = docId || null; } toString() { return this.full; } fixWorkspace(workspaceId: string) { if (!this.isWorkspace && this.workspace !== workspaceId) { this.workspace = workspaceId; } } }