@platform/cell.typesystem
Version:
The 'strongly typed sheets' system of the CellOS.
88 lines (87 loc) • 3.27 kB
JavaScript
import { coord, defaultValue, Uri } from '../common';
import { TypeScript } from '../TypeSystem.core';
import { TypeBuilderProp } from './TypeBuilderProp';
export class TypeBuilderType {
constructor(args) {
this._props = [];
this.onPropChange = e => {
if (e.prop === 'column') {
this.onColumnChange(e.value);
}
};
const validation = TypeScript.validate.objectTypename(args.typename);
if (!validation.isValid) {
throw new Error(validation.error);
}
let startColumn = defaultValue(args.startColumn, 0);
if (typeof startColumn === 'string') {
if (!coord.cell.isColumn(startColumn)) {
throw new Error(`The given start-column key (${startColumn}) is not a valid column`);
}
startColumn = coord.cell.toAxisIndex('COLUMN', startColumn);
}
if (typeof startColumn === 'number' && startColumn < 0) {
throw new Error(`The given start-column index (${startColumn}) is less than zero`);
}
this.uri = Uri.ns(args.uri);
this.typename = (args.typename || '').trim();
this.startColumn = startColumn;
}
get props() {
return this._props;
}
toObject() {
return { columns: {} };
}
prop(name, arg) {
name = (name || '').trim();
const validName = TypeScript.validate.propname(name);
if (validName.error) {
throw new Error(validName.error);
}
const exists = this.props.some(prop => prop.toObject().name === name);
if (exists) {
const err = `A property named '${name}' has already been added`;
throw new Error(err);
}
const onChange = this.onPropChange;
const column = this.nextColumn(typeof arg === 'object' ? arg.column : undefined);
const toBuilder = (arg) => {
const options = typeof arg === 'string' || arg === undefined ? { type: arg } : arg;
return TypeBuilderProp.create(Object.assign(Object.assign({}, options), { column, name, onChange }));
};
const builder = typeof arg === 'function'
? TypeBuilderProp.create({ column, name, onChange })
: toBuilder(arg);
if (typeof arg === 'function') {
arg(builder);
}
this._props.push(builder);
return this;
}
nextColumn(input) {
let column = -1;
if (input !== undefined) {
column = typeof input === 'string' ? coord.cell.toAxisIndex('COLUMN', input) : input;
}
else {
if (this._lastColumn === undefined) {
column = this.startColumn;
}
else {
column = this._lastColumn + 1;
}
}
if (this._lastColumn === undefined || column > this._lastColumn) {
this._lastColumn = column;
}
return column;
}
onColumnChange(key) {
const index = coord.cell.toAxisIndex('COLUMN', key);
if (this._lastColumn === undefined || index > this._lastColumn) {
this._lastColumn = index;
}
}
}
TypeBuilderType.create = (args) => new TypeBuilderType(args);