@platform/cell.schema
Version:
URI and database schemas for the `cell.os`.
170 lines (169 loc) • 4.88 kB
JavaScript
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 });
};