Files
AFFiNE-Mirror/packages/backend/server/src/utils/doc.ts
T
2023-11-02 18:25:30 +08:00

117 lines
2.7 KiB
TypeScript

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;
}
}
}