stackpress
Version:
Incept is a content management framework.
191 lines (190 loc) • 7.36 kB
JavaScript
import { clen, numdata } from '../schema.js';
export default function generate(directory, registry) {
for (const model of registry.model.values()) {
const relations = model.relations.map(column => {
const table = column.model?.snake;
const foreign = column.relation?.parent.key.snake;
const local = column.relation?.child.key.snake;
return { table, foreign, local, delete: 'CASCADE', update: 'RESTRICT' };
});
const source = directory.createSourceFile(`${model.name}/schema.ts`, '', { overwrite: true });
source.addImportDeclaration({
moduleSpecifier: '@stackpress/inquire/Create',
defaultImport: 'Create'
});
source.addFunction({
name: 'create',
isExported: true,
statements: (`
const schema = new Create('${model.snake}');
${Array
.from(model.columns.values())
.map(column => field(column))
.filter(Boolean)
.join('\n')}
${model.ids.map(column => `schema.addPrimaryKey('${column.snake}');`).join('\n')}
${model.uniques.map(column => `schema.addUniqueKey('${model.snake}_${column.snake}_unique', '${column.snake}');`).join('\n')}
${model.indexables.map(column => `schema.addKey('${model.snake}_${column.snake}_index', '${column.snake}');`).join('\n')}
${relations.map(relation => {
return `schema.addForeignKey('${model.snake}_${relation.local}_foreign', ${JSON.stringify(relation, null, 2)});`;
}).join('\n')}
return schema;
`)
});
source.addStatements(`
const schema = create();
export default schema;
`);
}
}
;
export const 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'
};
export function field(column) {
const type = typemap[column.type];
if (!type && !column.fieldset && !column.enum) {
return false;
}
const comment = column.attribute('comment')?.[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}', ${JSON.stringify({
type: 'JSON',
default: hasDefault ? column.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
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}', ${JSON.stringify({
type: 'JSON',
default: hasDefault ? column.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
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(');
if (length[0] === length[1]) {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'CHAR',
length: length[1],
default: hasDefault ? column.attributes.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'VARCHAR',
length: length[1],
default: hasDefault ? column.attributes.default : undefined,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
}
else if (type === 'text') {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'TEXT',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else if (type === 'boolean') {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'BOOLEAN',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else if (type === 'number') {
const { minmax, integerLength, decimalLength } = numdata(column);
if (decimalLength > 0) {
const length = integerLength + decimalLength;
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'FLOAT',
length: `${length}, ${decimalLength}`,
default: column.attributes.default,
nullable: !column.required,
unsigned: minmax[0] < 0,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'INTEGER',
length: integerLength,
default: column.attributes.default,
nullable: !column.required,
unsigned: minmax[0] < 0,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
}
else if (type === 'date') {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'DATE',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else if (type === 'datetime') {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'DATETIME',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else if (type === 'time') {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'TIME',
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
else if (column.enum) {
return `schema.addField('${column.snake}', ${JSON.stringify({
type: 'VARCHAR',
length: 255,
default: column.attributes.default,
nullable: !column.required,
comment: comment ? String(comment) : undefined
}, null, 2)});`;
}
return false;
}
;