UNPKG

@platform/cell.schema

Version:

URI and database schemas for the `cell.os`.

170 lines (169 loc) 4.88 kB
import { cuid, slug, hash, coord, Mime } from '../common'; import { FileSchema } from '../File'; import { RefSchema } from '../Ref'; import { Uri } from '../Uri'; import { Urls } from '../Url'; export class Schema { } Schema.mime = Mime; Schema.uri = Uri; Schema.file = FileSchema; Schema.ref = RefSchema; Schema.cuid = cuid; Schema.slug = slug; Schema.hash = hash; Schema.coord = coord; Schema.Urls = Urls; Schema.urls = (host) => Urls.create(host); Schema.ns = (id) => new NsSchema({ id }); Schema.query = { cells: '/CELL/*', rows: '/ROW/*', columns: '/COL/*', files: '/FILE/*', }; Schema.from = { ns(input) { return from({ input, toUri: path => NsSchema.uri({ path }), toPath: uri => Schema.ns(uri).path, }); }, cell(input) { return from({ input, toUri: path => CoordSchema.uri({ path }), toPath: uri => { const { parts } = Uri.parse(uri); return Schema.ns(parts.ns).cell(parts.key).path; }, }); }, row(input) { return from({ input, toUri: path => CoordSchema.uri({ path }), toPath: uri => { const { parts } = Uri.parse(uri); return Schema.ns(parts.ns).row(parts.key).path; }, }); }, column(input) { return from({ input, toUri: path => CoordSchema.uri({ path }), toPath: uri => { const { parts } = Uri.parse(uri); return Schema.ns(parts.ns).column(parts.key).path; }, }); }, file(input) { return from({ input, toUri: path => FileSchema.uri({ path }), toPath: uri => { const { parts } = Uri.parse(uri); return Schema.ns(parts.ns).file(parts.file).path; }, }); }, }; export class NsSchema { constructor(args) { let id = args.id || cuid(); if (Uri.is.uri(id)) { const uri = Uri.parse(id); if (uri.error) { throw new Error(uri.error.message); } if (uri.parts.type !== 'NS') { throw new Error(`The given URI does not represent a namespace ("${uri.toString()}").`); } id = uri.parts.id; } this.id = id; this.path = `NS/${id}`; this.uri = Uri.create.ns(id); } cell(key) { const uri = Uri.create.cell(this.id, key); return new CoordSchema({ type: 'CELL', nsPath: this.path, id: key, uri }); } column(key) { const uri = Uri.create.column(this.id, key); return new CoordSchema({ type: 'COL', nsPath: this.path, id: key, uri }); } row(key) { const uri = Uri.create.row(this.id, key); return new CoordSchema({ type: 'ROW', nsPath: this.path, id: key, uri }); } file(fileid) { const uri = Uri.create.file(this.id, fileid); return FileSchema.create({ nsPath: this.path, fileid, uri }); } static uri(args) { const parts = args.path.split('/'); const type = parts[0]; const id = parts[1]; if (type === 'NS') { return Uri.create.ns(id); } throw new Error(`Model path could not be converted to URI ("${args.path}")`); } } export class CoordSchema { constructor(args) { this.id = args.id; this.type = args.type; this.path = `${args.nsPath}/${args.type}/${this.id}`; this._uri = args.uri; } static uri(args) { const parts = args.path.split('/'); const ns = parts[1]; const type = parts[2]; const key = parts[3]; if (type === 'CELL') { return Uri.create.cell(ns, key); } if (type === 'ROW') { return Uri.create.row(ns, key); } if (type === 'COL') { return Uri.create.column(ns, key); } throw new Error(`Model path could not be converted to URI ("${args.path}")`); } get uri() { return Uri.parse(this._uri).parts; } } const from = (args) => { let path = ''; let uri = ''; if (typeof args.input === 'object') { path = args.input.path; uri = args.toUri(path); } else { if (Uri.is.uri(args.input)) { uri = args.input; path = args.toPath(uri); } else { path = args.input; uri = args.toUri(path); } } if (!path) { throw new Error(`Model schema [path] could not be derived.`); } if (!uri) { throw new Error(`Model URI could not be derived.`); } const parts = Uri.parse(uri); return Object.assign(Object.assign({}, parts), { path }); };