160 lines
3.3 KiB
TypeScript
160 lines
3.3 KiB
TypeScript
import * as path from 'path';
|
|
const ncp = require('ncp').ncp;
|
|
import { createDatabase, writeMigrationsToFile } from './database/database-creator';
|
|
import { createViews } from './views/views-creator';
|
|
import {createFrontend} from "./frontend-services/fe-service-creator";
|
|
import {removeTemplateFolder} from "./helpers";
|
|
|
|
class SystemGenService {
|
|
|
|
public runSysGen(defs: SystemDef) {
|
|
ncp(path.join(process.cwd(), 'frame'), path.join(process.cwd(), defs.name), (err: any) => {
|
|
if (err) {
|
|
console.log("error in ncp");
|
|
console.log(err);
|
|
} else {
|
|
console.log('success copying files');
|
|
this.buildDatabase(defs.storage, defs.name);
|
|
this.buildViews(defs, defs.name);
|
|
}
|
|
});
|
|
|
|
ncp(path.join(process.cwd(), 'frontend-frame'), path.join(process.cwd(), `frontend-${defs.name}`), (err: any) => {
|
|
if (err) {
|
|
console.log("error in frontend ncp");
|
|
console.log(err);
|
|
} else {
|
|
console.log("success copying frontend files");
|
|
this.buildFrontend(defs);
|
|
}
|
|
});
|
|
}
|
|
|
|
public buildDatabase(storage: StorageDef, outDir: string) {
|
|
let creationMigrations = createDatabase(storage);
|
|
writeMigrationsToFile(creationMigrations, outDir);
|
|
}
|
|
|
|
public buildViews(systemDef: SystemDef, outDir: string) {
|
|
createViews(systemDef);
|
|
}
|
|
|
|
public buildFrontend(systemDef: SystemDef) {
|
|
createFrontend(systemDef);
|
|
}
|
|
|
|
public cleanup() {
|
|
// TODO: remove 'component/{{component}}' folder
|
|
|
|
}
|
|
}
|
|
|
|
const systemGenService = new SystemGenService();
|
|
|
|
|
|
interface SystemDef {
|
|
name: string;
|
|
storage: StorageDef;
|
|
components: ComponentDef[];
|
|
// TODO: add ACLs, Behaviors, UX
|
|
}
|
|
|
|
interface StorageDef {
|
|
tables: TableDef[];
|
|
relations: ManyToManyDef[];
|
|
}
|
|
|
|
interface ComponentDef {
|
|
component: string;
|
|
endpoints: EndpointDef[];
|
|
}
|
|
|
|
interface EndpointDef {
|
|
component: string;
|
|
table: string;
|
|
type: ('list' | 'count' | 'item' | 'update' | 'create' | 'delete' | 'search');
|
|
columns: ColumnRef[];
|
|
values?: ValueDef[];
|
|
join?: JoinDef[];
|
|
orderBy?: Order[];
|
|
filters?: Filter[];
|
|
// if type is 'list' it will always include skip and limit for pagination
|
|
}
|
|
|
|
interface Order {
|
|
column: ColumnRef;
|
|
direction: 'asc' | 'desc';
|
|
}
|
|
|
|
interface Filter {
|
|
param: string; // the query param used to get the value
|
|
column: ColumnRef;
|
|
comparison: '=' | '!=' | '>' | '<' | 'contains' | 'LIKE';
|
|
required?: boolean;
|
|
type?: string;
|
|
}
|
|
|
|
interface TableDef {
|
|
name: string;
|
|
columns: ColumnDef[],
|
|
relations: BelongsToDef[],
|
|
}
|
|
|
|
interface ColumnDef {
|
|
name: string;
|
|
type: "blob" | "boolean" | "date" | "dateTIME" | "number" | "string";
|
|
nullable: boolean;
|
|
unique?: boolean;
|
|
autoIncrement?: boolean;
|
|
default?: string;
|
|
}
|
|
|
|
interface ColumnRef {
|
|
name: string;
|
|
table: string;
|
|
param?: string;
|
|
required?: boolean;
|
|
type?: string;
|
|
}
|
|
|
|
interface ValueDef {
|
|
column: string;
|
|
required: boolean;
|
|
}
|
|
|
|
interface JoinDef {
|
|
table: string;
|
|
on: {
|
|
left: ColumnRef;
|
|
right: ColumnRef;
|
|
}
|
|
}
|
|
|
|
interface BelongsToDef {
|
|
type: 'belongs-to';
|
|
table: string;
|
|
}
|
|
|
|
interface ManyToManyDef {
|
|
left: string;
|
|
relation: 'many-to-many';
|
|
right: string;
|
|
columns?: ColumnDef[];
|
|
}
|
|
|
|
export {
|
|
BelongsToDef,
|
|
ColumnDef,
|
|
ColumnRef,
|
|
ComponentDef,
|
|
EndpointDef,
|
|
Filter,
|
|
JoinDef,
|
|
ManyToManyDef,
|
|
Order,
|
|
StorageDef,
|
|
SystemDef,
|
|
TableDef,
|
|
systemGenService
|
|
}
|