working and no errors on front or back ends

This commit is contained in:
2021-07-08 03:15:36 -05:00
parent 9869125965
commit 7b18b0842a
12 changed files with 157 additions and 41 deletions

View File

@ -7,13 +7,13 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import { Component, Prop, Vue } from 'vue-property-decorator';
import { {{Component}}Config } from './{{component}}Types.ts'; import { {{Component}}Config } from './{{component}}Types';
import { {{component}}Service } from './{{component}}Service.ts'; import { {{component}}Service } from './{{component}}Service';
@Component @Component
export default class {{Component}}Editor extends Vue { export default class {{Component}}Editor extends Vue {
@Prop() private id!: string; @Prop() private id!: string;
private {{component}}!: {{Component}}Config = { private {{component}}: {{Component}}Config = {
// SYSTEM-BUILDER-init-props // SYSTEM-BUILDER-init-props
}; };
private loading: boolean = false; private loading: boolean = false;

View File

@ -13,13 +13,13 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import { Component, Prop, Vue } from 'vue-property-decorator';
import { {{component}}Service } from './{{component}}Service.ts'; import { {{component}}Service } from './{{component}}Service';
import { {{Component}}Config } from './{{component}}Types.ts'; import { {{Component}}Config } from './{{component}}Types';
@Component @Component
export default class {{Component}}Editor extends Vue { export default class {{Component}}Editor extends Vue {
@Prop() private id!: string; @Prop() private {{component}}_id!: string;
private {{component}}!: {{Component}}Config = { private {{component}}: {{Component}}Config = {
// SYSTEM-BUILDER-init-props // SYSTEM-BUILDER-init-props
}; };
private loading: boolean = false; private loading: boolean = false;
@ -40,7 +40,7 @@ export default class {{Component}}Editor extends Vue {
private loadDetails() { private loadDetails() {
this.loading = true; this.loading = true;
this.errorMessage = ''; this.errorMessage = '';
{{component}}Service.get{{Component}}(this.id).then((res: {{Component}}Config) => { {{component}}Service.get{{Component}}(this.{{component}}_id).then((res: {{Component}}Config) => {
this.loading = false; this.loading = false;
this.errorMessage = ''; this.errorMessage = '';
this.{{component}} = res; this.{{component}} = res;
@ -59,7 +59,7 @@ export default class {{Component}}Editor extends Vue {
this.close(); this.close();
}).catch(this.handleError.bind(this)); }).catch(this.handleError.bind(this));
} else { } else {
{{component}}Service.update{{Component}}(this.{{component}}).then(() => { {{component}}Service.update{{Component}}(this.{{component}}.{{component}}_id, this.{{component}}).then(() => {
// success // success
this.loading = false; this.loading = false;
this.errorMessage = ''; this.errorMessage = '';

View File

@ -15,8 +15,8 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import { Component, Prop, Vue } from 'vue-property-decorator';
import { {{component}}Service } from './{{component}}Service.ts'; import { {{component}}Service } from './{{component}}Service';
import { {{Component}}Config } from './{{component}}Types.ts'; import { {{Component}}Config } from './{{component}}Types';
@Component @Component
export default class {{Component}}Editor extends Vue { export default class {{Component}}Editor extends Vue {
@ -31,7 +31,7 @@ export default class {{Component}}Editor extends Vue {
// SYSTEM-BUILDER-component-functions // SYSTEM-BUILDER-component-functions
private mounted() { private mounted() {
get{{Components}}(); this.get{{Components}}();
} }
// TODO: add a search function if there is an endpoint with type 'search' // TODO: add a search function if there is an endpoint with type 'search'

View File

@ -1,4 +1,5 @@
import { del, get, post, put } from '@/services/fetch'; import { del, get, post, put } from '@/services/fetch';
import { {{Component}}Config } from './{{component}}Types';
class {{Component}}Service { class {{Component}}Service {
// SYSTEM-BUILDER-service-variables // SYSTEM-BUILDER-service-variables

View File

@ -123,7 +123,7 @@ let def: SystemDef = {
], ],
filters: [ filters: [
{ {
param: 'list', param: 'list_id',
type: 'string', type: 'string',
column: { column: {
name: 'list_id', name: 'list_id',
@ -177,7 +177,7 @@ let def: SystemDef = {
], ],
filters: [ filters: [
{ {
param: 'list', param: 'list_id',
type: 'string', type: 'string',
column: { column: {
name: 'list_id', name: 'list_id',
@ -251,7 +251,7 @@ let def: SystemDef = {
], ],
filters: [ filters: [
{ {
param: 'list', param: 'list_id',
type: 'string', type: 'string',
column: { column: {
name: 'list_id', name: 'list_id',
@ -342,7 +342,7 @@ let def: SystemDef = {
table: 'task' table: 'task'
}, },
comparison: '=', comparison: '=',
param: 'task', param: 'task_id',
type: 'string', type: 'string',
required: true required: true
}, },
@ -360,7 +360,7 @@ let def: SystemDef = {
table: 'task' table: 'task'
}, },
comparison: '=', comparison: '=',
param: 'task', param: 'task_id',
type: 'string', type: 'string',
required: true required: true
}, },
@ -399,7 +399,7 @@ let def: SystemDef = {
table: 'task' table: 'task'
}, },
comparison: '=', comparison: '=',
param: 'task', param: 'task_id',
type: 'string', type: 'string',
required: true required: true
}, },
@ -446,7 +446,7 @@ let def: SystemDef = {
], ],
filters: [ filters: [
{ {
param: 'user', param: 'user_id',
type: 'string', type: 'string',
column: { column: {
name: 'user_id', name: 'user_id',

View File

@ -1,6 +1,6 @@
import {ComponentDef, EndpointDef, SystemDef} from "../systemGenService"; import {ComponentDef, EndpointDef, SystemDef} from "../systemGenService";
import path from "path"; import path from "path";
import {initializeComponentFile, removeTemplateFiles} from "../helpers"; import {initializeComponentFile, removeTemplateFiles, removeTemplateFolder, uppercaseFirstLetter} from "../helpers";
import fs from "fs"; import fs from "fs";
import {buildServiceFunctionName, getFuncParams} from "../views/service-creator"; import {buildServiceFunctionName, getFuncParams} from "../views/service-creator";
import {METHOD, URL} from "../views/routes-creator"; import {METHOD, URL} from "../views/routes-creator";
@ -10,17 +10,20 @@ import {buildEditorView} from "./editor-view-builder";
import {buildTypesView} from "./types-view-builder"; import {buildTypesView} from "./types-view-builder";
const ncp = require('ncp').ncp; const ncp = require('ncp').ncp;
export function createFrontend(systemDef: SystemDef): Promise<void[]> { export function createFrontend(systemDef: SystemDef): Promise<void> {
let fePromises = []; let fePromises = [];
for (let i in systemDef.components) { for (let i in systemDef.components) {
fePromises.push(createComponent(systemDef.components[i], systemDef)); fePromises.push(createComponent(systemDef.components[i], systemDef).then(() => {
return removeTemplateFiles(componentDestination(systemDef.name, systemDef.components[i].component));
}));
// TODO: add a vue view and add it to App.vue // TODO: add a vue view and add it to App.vue
// TODO: build app router logic // TODO: build app router logic
} }
// TODO: after all is done clean up the template files // TODO: after all is done clean up the template files
return Promise.all(fePromises).then((res: void[]) => { return Promise.all(fePromises).then((res: void[]) => {
removeTemplateFiles(componentSource()) return removeTemplateFolder(componentDestination(systemDef.name, '{{component}}')).catch((err) => {
return res; console.log(err);
});
}); });
} }
@ -131,17 +134,21 @@ function createFEServiceFunc(view: EndpointDef): string {
if (method === 'delete') { if (method === 'delete') {
method = 'del'; method = 'del';
} }
let addTypeDeclaration = method === 'get' || method === 'post';
let useList = view.type === 'list' || view.type === 'search';
let url = URL[view.type](view).replace(':' + view.component + '_id', '\' + ' + view.component + '_id');
let isUpdateOrCreate = view.type === 'update' || view.type === 'create';
func = ` func = `
public ${funcName}(${funcParams.join(', ')}) {`; public ${funcName}(${view.type === 'update' ? view.component + '_id: string, ': ''}${isUpdateOrCreate ? 'params: ' + uppercaseFirstLetter(view.component) + 'Config' : funcParams.join(', ')}) {`;
if (!isGetOrDelete) { if (!isGetOrDelete && !isUpdateOrCreate) {
func = func + ` func = func + `
let params = {${columnParams}${columnParams.length ? ',' : ''}${filterParams} let params = {${columnParams}${columnParams.length ? ',' : ''}${filterParams}
};`; };`;
} }
func = func + ` func = func + `
return ${method}('/api/v1/${URL[view.type](view)}${isGetOrDelete ? '/\' + ' + funcParams[0].split(":")[0] : '\', params'}); return ${method}${addTypeDeclaration ? '<' + uppercaseFirstLetter(view.component) + 'Config' + (useList ? '[]' : '') + '>': ''}('/api/v1/${url}${isGetOrDelete ? '' : (view.type === 'update' ? ', params' : '\', params')});
} }
`; `;
return func; return func;

View File

@ -184,13 +184,16 @@ function createListMarkup(view: EndpointDef, hasDeleteEndpoint: boolean): string
function createListRequestFunc(view: EndpointDef, systemDef: SystemDef, hasDeleteEndpoint: boolean) { function createListRequestFunc(view: EndpointDef, systemDef: SystemDef, hasDeleteEndpoint: boolean) {
let isSearch: boolean = view.type === 'search'; let isSearch: boolean = view.type === 'search';
let params: string[] = getFuncParams(view); let params: string[] = getFuncParams(view);
params = params.map((param: string) => {
return 'this.filterItems.' + param;
});
params.push('0'); // offset params.push('0'); // offset
params.push('1000'); // limit params.push('1000'); // limit
let out = `private ${isSearch ? 'search' : 'get'}${uppercaseFirstLetter(pluralize(view.component))}() { let out = `private ${isSearch ? 'search' : 'get'}${uppercaseFirstLetter(pluralize(view.component))}() {
this.loading = true; this.loading = true;
this.errorMessage = ''; this.errorMessage = '';
${view.component}Service.${isSearch ? 'search' : 'get'}${uppercaseFirstLetter(pluralize(view.component))}(${params.join(', ')}).then((listItems: ${view.component}Config[]) => { ${view.component}Service.${isSearch ? 'search' : 'get'}${uppercaseFirstLetter(pluralize(view.component))}(${params.join(', ')}).then((listItems: ${uppercaseFirstLetter(view.component)}Config[]) => {
// success // success
this.loading = false; this.loading = false;
this.errorMessage = ''; this.errorMessage = '';
@ -206,7 +209,7 @@ function createFEDeleteCode(view: EndpointDef) {
let out = `private deleteItem(itemKey: string) { let out = `private deleteItem(itemKey: string) {
this.loading = true; this.loading = true;
this.errorMessage = ''; this.errorMessage = '';
${view.component}Service.delete${uppercaseFirstLetter(pluralize(view.component))}(itemKey).then(() => { ${view.component}Service.delete${uppercaseFirstLetter(view.component)}(itemKey).then(() => {
this.loading = false; this.loading = false;
this.errorMessage = ''; this.errorMessage = '';
return this.get${uppercaseFirstLetter(pluralize(view.component))}(); return this.get${uppercaseFirstLetter(pluralize(view.component))}();

View File

@ -1,5 +1,14 @@
import fs from "fs"; import fs from "fs";
import {ColumnDef, ColumnRef, EndpointDef, Filter, SystemDef, TableDef} from "./systemGenService"; import {
BelongsToDef,
ColumnDef,
ColumnRef,
EndpointDef,
Filter,
ManyToManyDef,
SystemDef,
TableDef
} from "./systemGenService";
import path from "path"; import path from "path";
import {createServiceFunc} from "./views/service-creator"; import {createServiceFunc} from "./views/service-creator";
import pluralize from "pluralize"; import pluralize from "pluralize";
@ -48,11 +57,11 @@ function initializeComponentFile(sourceFile: string, destinationFile: string, co
}) })
} }
function removeTemplateFiles(destinationFolder: string) { function removeTemplateFolder(destinationFolder: string) {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
fs.rmdir(destinationFolder, (err) => { fs.rmdir(destinationFolder, { recursive: true }, (err) => {
if (err) { if (err) {
reject(); reject(err);
} else { } else {
resolve(); resolve();
} }
@ -60,6 +69,14 @@ function removeTemplateFiles(destinationFolder: string) {
}); });
} }
function removeTemplateFiles(destinationFolder: string) {
let regex = /\{\{component\}\}.*$/
fs.readdirSync(destinationFolder)
.filter(f => regex.test(f))
.map(f => fs.unlinkSync(path.join(destinationFolder, f)));
return Promise.resolve();
}
function insertServiceCode(view: EndpointDef, outDir: string): Promise<void> { function insertServiceCode(view: EndpointDef, outDir: string): Promise<void> {
return new Promise<void>((resolve) => { return new Promise<void>((resolve) => {
const separator: string = `// SYSTEM-BUILDER-${view.component}-service`; const separator: string = `// SYSTEM-BUILDER-${view.component}-service`;
@ -111,6 +128,26 @@ function createDetailsInitValues(view: EndpointDef, systemDef: SystemDef) {
`; `;
} }
}); });
// TODO: get relations to add as properties
let storageTable: TableDef | undefined = systemDef.storage.tables.find((table: TableDef) => {
return table.name === view.component;
});
if (storageTable) {
storageTable.relations.forEach((rel: BelongsToDef) => {
out = out + `${rel.table}_id: '',
`;
});
}
systemDef.storage.relations.forEach((rel:ManyToManyDef) => {
if (rel.right === view.component) {
out = out + `${rel.left}_id: '',
`;
}
if (rel.left === view.component) {
out = out + `${rel.right}_id: '',
`;
}
});
return out; return out;
} }
@ -118,6 +155,26 @@ function createDetailsInitValues(view: EndpointDef, systemDef: SystemDef) {
function createDetailsTypeValues(view: EndpointDef, systemDef: SystemDef) { function createDetailsTypeValues(view: EndpointDef, systemDef: SystemDef) {
let out = ``; let out = ``;
let storageTable = systemDef.storage.tables.find((table: TableDef) => {
return table.name === view.component;
});
let relations: string[] = [];
if (storageTable) {
storageTable.relations.map((rel: BelongsToDef) => {
relations.push(rel.table);
});
systemDef.storage.relations.forEach((rel: ManyToManyDef) => {
// @ts-ignore
if (rel.left === storageTable.name) {
relations.push(rel.right);
}
// @ts-ignore
if (rel.right === storageTable.name) {
relations.push(rel.left);
}
});
}
view.columns.forEach((column: ColumnRef) => { view.columns.forEach((column: ColumnRef) => {
let colDef: ColumnDef | undefined = findColumn(column, systemDef); let colDef: ColumnDef | undefined = findColumn(column, systemDef);
if (colDef) { if (colDef) {
@ -125,6 +182,10 @@ function createDetailsTypeValues(view: EndpointDef, systemDef: SystemDef) {
`; `;
} }
}); });
relations.forEach((rel: string) => {
out = out + `${rel}_id: string
`;
});
return out; return out;
} }
@ -138,5 +199,6 @@ export {
lowercaseFirstLetter, lowercaseFirstLetter,
makeSet, makeSet,
removeTemplateFiles, removeTemplateFiles,
removeTemplateFolder,
uppercaseFirstLetter, uppercaseFirstLetter,
} }

View File

@ -3,7 +3,7 @@ const ncp = require('ncp').ncp;
import { createDatabase, writeMigrationsToFile } from './database/database-creator'; import { createDatabase, writeMigrationsToFile } from './database/database-creator';
import { createViews } from './views/views-creator'; import { createViews } from './views/views-creator';
import {createFrontend} from "./frontend-services/fe-service-creator"; import {createFrontend} from "./frontend-services/fe-service-creator";
import {removeTemplateFiles} from "./helpers"; import {removeTemplateFolder} from "./helpers";
class SystemGenService { class SystemGenService {

View File

@ -22,11 +22,11 @@ const URL = {
}, },
'delete': (view: EndpointDef) => { 'delete': (view: EndpointDef) => {
// TODO: needs the params added to select the right one (id) // TODO: needs the params added to select the right one (id)
return `${view.component}`; return `${view.component}/:${view.component}_id`;
}, },
'item': (view: EndpointDef) => { 'item': (view: EndpointDef) => {
// TODO: needs the params added to select the right one (id) // TODO: needs the params added to select the right one (id)
return `${view.component}`; return `${view.component}/:${view.component}_id`;
}, },
'list': (view: EndpointDef) => { 'list': (view: EndpointDef) => {
return `${pluralize(view.component)}`; return `${pluralize(view.component)}`;
@ -36,7 +36,7 @@ const URL = {
}, },
'update': (view: EndpointDef) => { 'update': (view: EndpointDef) => {
// TODO: needs the params added to select the right one (id) // TODO: needs the params added to select the right one (id)
return `${view.component}`; return `${view.component}/:${view.component}_id`;
}, },
} }

View File

@ -1,4 +1,4 @@
import {ColumnDef, EndpointDef, Filter} from "../systemGenService"; import {BelongsToDef, ColumnDef, EndpointDef, Filter, ManyToManyDef, SystemDef, TableDef} from "../systemGenService";
import {lowercaseFirstLetter} from "../helpers"; import {lowercaseFirstLetter} from "../helpers";
import {buildMapperFunctionName} from "./mapper-creator"; import {buildMapperFunctionName} from "./mapper-creator";
@ -31,7 +31,7 @@ function buildServiceFunction(view: EndpointDef): string {
return func; return func;
} }
function getFuncParams(view: EndpointDef, addTypes=false): string[] { function getFuncParams(view: EndpointDef, addTypes=false, systemDef?: SystemDef): string[] {
let filters = view.filters || []; let filters = view.filters || [];
let columnList: ParamDef[] = view.columns?.filter((column) => {return column.param;}).map((column) => { let columnList: ParamDef[] = view.columns?.filter((column) => {return column.param;}).map((column) => {
return { return {
@ -49,8 +49,44 @@ function getFuncParams(view: EndpointDef, addTypes=false): string[] {
}; };
}); });
let relationsList: ParamDef[] = [];
if (systemDef) {
let storageTable: TableDef | undefined = systemDef.storage.tables.find((table: TableDef) => {
return view.component === table.name;
});
if (storageTable) {
relationsList = storageTable.relations.map((rel: BelongsToDef) => {
return {
param: rel.table + '_id',
required: false,
type: 'string'
}
});
}
relationsList = [...relationsList, ...systemDef.storage.relations.filter((rel: ManyToManyDef) => {
if (rel.left === view.component || rel.right === view.component) {
return true;
}
return false;
}).map((rel: ManyToManyDef) => {
if (rel.left === view.component) {
return {
param: rel.right + '_id',
required: false,
type: 'string'
};
} else {
return {
param: rel.left + '_id',
required: false,
type: 'string'
};
}
})];
}
// funcParams should be sorted by 'required' so the optional params can come last and be left off when calling // funcParams should be sorted by 'required' so the optional params can come last and be left off when calling
let combinedList = columnList.concat(filterList).sort((a, b) => { let combinedList = relationsList.concat(columnList).concat(filterList).sort((a, b) => {
if (a.required && b.required) { if (a.required && b.required) {
return 0; return 0;
} }

View File

@ -46,7 +46,8 @@
// "typeRoots": [], /* List of folders to include type definitions from. */ // "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */ // "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "esModuleInterop": true,
/* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */ /* Source Map Options */
@ -58,6 +59,12 @@
/* Experimental Options */ /* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
"lib": [
"dom",
"es5",
"scripthost",
"es2015.promise"
]
}, },
"include": ["src"], "include": ["src"],
"exclude": ["node_modules", "**/__tests__/*"] "exclude": ["node_modules", "**/__tests__/*"]