stackpress
Version:
Incept is a content management framework.
254 lines (253 loc) • 9.17 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.typemap = void 0;
exports.default = schema;
exports.field = field;
exports.clen = clen;
exports.numdata = numdata;
const Create_1 = __importDefault(require("@stackpress/inquire/Create"));
exports.typemap = {
String: 'string',
Text: 'text',
Number: 'number',
Integer: 'number',
Float: 'number',
Boolean: 'boolean',
Date: 'date',
Datetime: 'datetime',
Time: 'time',
Json: 'json',
Object: 'json',
Hash: 'json'
};
function schema(model, onDelete = 'CASCADE', onUpdate = 'RESTRICT') {
const schema = new Create_1.default(model.snake);
for (const column of model.columns.values()) {
field(column, schema);
}
for (const column of model.ids) {
schema.addPrimaryKey(column.snake);
}
for (const column of model.uniques) {
schema.addUniqueKey(`${column.snake}_unique`, column.snake);
}
for (const column of model.indexables) {
schema.addKey(`${model.lower}_${column.snake}_index`, column.snake);
}
const relations = model.relations.map(column => {
var _a, _b, _c;
const table = (_a = column.model) === null || _a === void 0 ? void 0 : _a.snake;
const foreign = (_b = column.relation) === null || _b === void 0 ? void 0 : _b.parent.key.snake;
const local = (_c = column.relation) === null || _c === void 0 ? void 0 : _c.child.key.snake;
return { table, foreign, local, delete: onDelete, update: onUpdate };
});
for (const relation of relations) {
schema.addForeignKey(`${model.snake}_${relation.local}_foreign`, relation);
}
return schema;
}
;
function field(column, schema) {
var _a;
const type = exports.typemap[column.type];
if (!type && !column.fieldset && !column.enum) {
return;
}
const comment = (_a = column.attribute('comment')) === null || _a === void 0 ? void 0 : _a[0];
if (column.multiple) {
let hasDefault = false;
try {
hasDefault = typeof column.default === 'string'
&& Array.isArray(JSON.parse(column.default));
}
catch (e) { }
return schema.addField(column.snake, {
type: 'JSON',
default: hasDefault ? column.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'json' || column.fieldset) {
let hasDefault = false;
try {
hasDefault = typeof column.default === 'string'
&& !!column.default
&& typeof JSON.parse(column.default) === 'object';
}
catch (e) { }
return schema.addField(column.snake, {
type: 'JSON',
default: hasDefault ? column.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'string') {
const length = clen(column);
const hasDefault = typeof column.attributes.default === 'string'
&& !column.attributes.default.startsWith('uuid(')
&& !column.attributes.default.startsWith('cuid(')
&& !column.attributes.default.startsWith('nanoid(');
return schema.addField(column.snake, {
type: length[0] === length[1] ? 'CHAR' : 'VARCHAR',
length: length[1],
default: hasDefault ? column.attributes.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'text') {
return schema.addField(column.snake, {
type: 'TEXT',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'boolean') {
return schema.addField(column.snake, {
type: 'BOOLEAN',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'number') {
const { minmax, integerLength, decimalLength } = numdata(column);
if (decimalLength > 0) {
const length = integerLength + decimalLength;
return schema.addField(column.snake, {
type: 'FLOAT',
length: [length, decimalLength],
default: column.attributes.default,
nullable: !column.required,
unsigned: minmax[0] < 0,
comment: comment ? String(comment) : undefined
});
}
else {
return schema.addField(column.snake, {
type: 'INTEGER',
length: integerLength,
default: column.attributes.default,
nullable: !column.required,
unsigned: minmax[0] < 0,
comment: comment ? String(comment) : undefined
});
}
}
else if (type === 'date') {
return schema.addField(column.snake, {
type: 'DATE',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'datetime') {
return schema.addField(column.snake, {
type: 'DATETIME',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (type === 'time') {
return schema.addField(column.snake, {
type: 'TIME',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
else if (column.enum) {
return schema.addField(column.snake, {
type: 'VARCHAR',
length: 255,
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
});
}
}
function clen(column) {
const length = [0, 255];
column.assertions.forEach(assertion => {
if (assertion.method === 'ceq') {
length[0] = assertion.args[0];
length[1] = assertion.args[0];
}
else if (assertion.method === 'cgt') {
length[0] = assertion.args[0];
}
else if (assertion.method === 'clt') {
length[1] = assertion.args[0];
}
else if (assertion.method === 'cge') {
length[0] = assertion.args[0];
}
else if (assertion.method === 'cle') {
length[1] = assertion.args[0];
}
});
if (length[1] < 1) {
length[1] = 255;
}
return length;
}
function numdata(column) {
const minmax = [0, 0];
column.assertions.forEach(assertion => {
if (assertion.method === 'eq') {
minmax[0] = assertion.args[0];
minmax[1] = assertion.args[0];
}
else if (assertion.method === 'gt') {
minmax[0] = assertion.args[0];
}
else if (assertion.method === 'lt') {
minmax[1] = assertion.args[0];
}
else if (assertion.method === 'ge') {
minmax[0] = assertion.args[0];
}
else if (assertion.method === 'le') {
minmax[1] = assertion.args[0];
}
});
const step = Array.isArray(column.attributes.step)
? column.attributes.step[0]
: column.type.toLowerCase() === 'float'
? 10000000.01
: 0;
const stepIntegerLength = step.toString().split('.')[0].length;
const stepDecimalLength = (step.toString().split('.')[1] || '').length;
if (minmax[1] === 0) {
const minDecimalLength = (minmax[0].toString().split('.')[1] || '').length;
const maxDecimalLength = (minmax[1].toString().split('.')[1] || '').length;
const decimalLength = Math.max(minDecimalLength, maxDecimalLength, stepDecimalLength);
minmax[1] = Number('1' + '0'.repeat(9 - decimalLength));
}
const minIntegerLength = minmax[0].toString().split('.')[0].length;
const maxIntegerLength = minmax[1].toString().split('.')[0].length;
const minDecimalLength = (minmax[0].toString().split('.')[1] || '').length;
const maxDecimalLength = (minmax[1].toString().split('.')[1] || '').length;
const integerLength = Math.max(minIntegerLength, maxIntegerLength, stepIntegerLength);
const decimalLength = Math.max(minDecimalLength, maxDecimalLength, stepDecimalLength);
return {
step,
minmax,
minIntegerLength,
maxIntegerLength,
minDecimalLength,
maxDecimalLength,
stepIntegerLength,
stepDecimalLength,
integerLength,
decimalLength
};
}