UNPKG

appwrite

Version:

Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API

151 lines (119 loc) 3.89 kB
interface Root {} interface Database { _db: any } interface Collection { _coll: any } interface Document { _doc: any } interface TablesDB { _tdb: any } interface Table { _tbl: any } interface Row { _row: any } interface Bucket { _bkt: any } interface File { _file: any } interface Func { _fn: any } interface Execution { _exec: any } interface Team { _team: any } interface Membership { _mem: any } interface Resolved { _res: any } type Actionable = Document | Row | File | Team | Membership; function normalize(id: string): string { const trimmed = id.trim(); return trimmed === "" ? "*" : trimmed; } export class Channel<T> { declare _type: T; private constructor(private readonly segments: string[]) {} private next<N>(segment: string, id?: string): Channel<N> { const segments = id === undefined ? [...this.segments, segment] : [...this.segments, segment, normalize(id)]; return new Channel<N>(segments) as any; } private resolve(action: string): Channel<Resolved> { return new Channel<Resolved>([...this.segments, action]) as any; } toString(): string { return this.segments.join("."); } // --- DATABASE ROUTE --- // Only available on Channel<Database> collection(this: Channel<Database>, id?: string): Channel<Collection> { // Default: wildcard collection ID return this.next<Collection>("collections", id ?? "*"); } // Only available on Channel<Collection> document(this: Channel<Collection>, id?: string): Channel<Document> { // Default: no document ID segment return this.next<Document>("documents", id); } // --- TABLESDB ROUTE --- table(this: Channel<TablesDB>, id?: string): Channel<Table> { // Default: wildcard table ID return this.next<Table>("tables", id ?? "*"); } row(this: Channel<Table>, id?: string): Channel<Row> { // Default: no row ID segment return this.next<Row>("rows", id); } // --- BUCKET ROUTE --- file(this: Channel<Bucket>, id?: string): Channel<File> { // Default: no file ID segment return this.next<File>("files", id); } // --- TERMINAL ACTIONS --- // Restricted to the Actionable union create(this: Channel<Actionable>): Channel<Resolved> { return this.resolve("create"); } update(this: Channel<Actionable>): Channel<Resolved> { return this.resolve("update"); } delete(this: Channel<Actionable>): Channel<Resolved> { return this.resolve("delete"); } // --- ROOT FACTORIES --- static database(id: string = "*") { return new Channel<Database>(["databases", normalize(id)]); } static execution(id: string = "*") { return new Channel<Execution>(["executions", normalize(id)]); } static tablesdb(id: string = "*") { return new Channel<TablesDB>(["tablesdb", normalize(id)]); } static bucket(id: string = "*") { return new Channel<Bucket>(["buckets", normalize(id)]); } static function(id: string = "*") { return new Channel<Func>(["functions", normalize(id)]); } static team(id: string = "*") { return new Channel<Team>(["teams", normalize(id)]); } static membership(id: string = "*") { return new Channel<Membership>(["memberships", normalize(id)]); } static account(): string { return "account"; } // Global events static documents(): string { return "documents"; } static rows(): string { return "rows"; } static files(): string { return "files"; } static executions(): string { return "executions"; } static teams(): string { return "teams"; } static memberships(): string { return "memberships"; } } // Export types for backward compatibility with realtime export type ActionableChannel = Channel<Document> | Channel<Row> | Channel<File> | Channel<Execution> | Channel<Team> | Channel<Membership>; export type ResolvedChannel = Channel<Resolved>;