add support for all crud and list in the service files
This commit is contained in:
@ -7,7 +7,6 @@ class {{Component}}Service {
|
|||||||
public initialize() {
|
public initialize() {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SYSTEM-BUILDER-{{component}}-service
|
// SYSTEM-BUILDER-{{component}}-service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ interface ComponentDef {
|
|||||||
interface EndpointDef {
|
interface EndpointDef {
|
||||||
component: string;
|
component: string;
|
||||||
table: string;
|
table: string;
|
||||||
type: ('list' | 'count' | 'item' | 'distinct' | 'update' | 'create' | 'delete' | 'search');
|
type: ('list' | 'count' | 'item' | 'update' | 'create' | 'delete' | 'search');
|
||||||
columns: ColumnRef[];
|
columns: ColumnRef[];
|
||||||
values?: ValueDef[];
|
values?: ValueDef[];
|
||||||
join?: JoinDef[];
|
join?: JoinDef[];
|
||||||
|
@ -22,7 +22,7 @@ function createMapperFunc(view: EndpointDef): string {
|
|||||||
|
|
||||||
function buildDeleteItem(view: EndpointDef): string {
|
function buildDeleteItem(view: EndpointDef): string {
|
||||||
let func: string = '';
|
let func: string = '';
|
||||||
let funcName = buildFunctionName(view);
|
let funcName = buildMapperFunctionName(view);
|
||||||
let tables: string = `${view.table}`;
|
let tables: string = `${view.table}`;
|
||||||
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
||||||
let query: string = `DELETE FROM ${tables}${filters}`;
|
let query: string = `DELETE FROM ${tables}${filters}`;
|
||||||
@ -45,7 +45,7 @@ function buildDeleteItem(view: EndpointDef): string {
|
|||||||
|
|
||||||
function buildGetItem(view: EndpointDef): string {
|
function buildGetItem(view: EndpointDef): string {
|
||||||
let func: string = '';
|
let func: string = '';
|
||||||
let funcName = buildFunctionName(view);
|
let funcName = buildMapperFunctionName(view);
|
||||||
let columns: string = `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
let columns: string = `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
||||||
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
||||||
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
||||||
@ -69,23 +69,60 @@ function buildGetItem(view: EndpointDef): string {
|
|||||||
|
|
||||||
function buildCreateFunc(view: EndpointDef): string {
|
function buildCreateFunc(view: EndpointDef): string {
|
||||||
let func: string = '';
|
let func: string = '';
|
||||||
let query: string = `INSERT INTO ${view.table} SET `;
|
let inQuery: string = `INSERT INTO ${view.table} SET `;
|
||||||
func = getCreateOrUpdateFunc(query, view);
|
let {funcName, query, requiredQueryValues, optionalValuesCode} = getCreateOrUpdateFunc(inQuery, view);
|
||||||
|
|
||||||
|
func = `
|
||||||
|
public ${funcName}(params: {[key: string]: string}) {
|
||||||
|
|
||||||
|
let query: string = '${query}';
|
||||||
|
let queryValues: string[] = [${requiredQueryValues}];
|
||||||
|
|
||||||
|
// optional params?
|
||||||
|
${optionalValuesCode}
|
||||||
|
return super.runQuery(query, [...queryValues]);
|
||||||
|
}
|
||||||
|
`;
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildUpdateFunc(view: EndpointDef): string {
|
function buildUpdateFunc(view: EndpointDef): string {
|
||||||
let func: string = '';
|
let func: string = '';
|
||||||
let query: string = `UPDATE ${view.table} SET `;
|
let inQuery: string = `UPDATE ${view.table} SET `;
|
||||||
func = getCreateOrUpdateFunc(query, view);
|
let {funcName, query, requiredQueryValues, optionalValuesCode} = getCreateOrUpdateFunc(inQuery, view);
|
||||||
|
let postQuery = ` WHERE `;
|
||||||
|
for (let i in view.filters) {
|
||||||
|
// @ts-ignore
|
||||||
|
let filter: Filter = view.filters[i];
|
||||||
|
if (!postQuery.endsWith('WHERE ')) {
|
||||||
|
postQuery = postQuery + ` AND `;
|
||||||
|
}
|
||||||
|
postQuery = postQuery + `${filter.column.table}.${filter.column.name} = ?`;
|
||||||
|
if (requiredQueryValues.length) {
|
||||||
|
requiredQueryValues = requiredQueryValues + `, `;
|
||||||
|
}
|
||||||
|
requiredQueryValues = requiredQueryValues + `params.${filter.param}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
func = `
|
||||||
|
public ${funcName}(params: {[key: string]: string}) {
|
||||||
|
|
||||||
|
let query: string = '${query}';
|
||||||
|
let queryValues: string[] = [${requiredQueryValues}];
|
||||||
|
|
||||||
|
// optional params?
|
||||||
|
${optionalValuesCode}
|
||||||
|
|
||||||
|
query = query + '${postQuery}';
|
||||||
|
return super.runQuery(query, [...queryValues]);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCreateOrUpdateFunc(query: string, view: EndpointDef): string {
|
function getCreateOrUpdateFunc(query: string, view: EndpointDef) {
|
||||||
let func: string = '';
|
let funcName = buildMapperFunctionName(view);
|
||||||
let funcName = buildFunctionName(view);
|
|
||||||
let requiredQueryValues: string = '';
|
let requiredQueryValues: string = '';
|
||||||
let optionalValuesCode: string = '';
|
let optionalValuesCode: string = '';
|
||||||
for (let i in view.columns) {
|
for (let i in view.columns) {
|
||||||
@ -108,20 +145,7 @@ function getCreateOrUpdateFunc(query: string, view: EndpointDef): string {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {funcName, query, requiredQueryValues, optionalValuesCode};
|
||||||
func = `
|
|
||||||
public ${funcName}(params: {[key: string]: string}) {
|
|
||||||
|
|
||||||
let query: string = '${query}';
|
|
||||||
let queryValues: string[] = [${requiredQueryValues}];
|
|
||||||
|
|
||||||
// optional params?
|
|
||||||
${optionalValuesCode}
|
|
||||||
return super.runQuery(query, [...queryValues]);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function constructFilters(view: EndpointDef, isSearch=false) {
|
function constructFilters(view: EndpointDef, isSearch=false) {
|
||||||
@ -165,7 +189,7 @@ function buildGetList(view: EndpointDef, isSearch=false): string {
|
|||||||
let columns: string = view.type === 'count' ? `count(*)` : `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
let columns: string = view.type === 'count' ? `count(*)` : `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
||||||
let query: string = '';
|
let query: string = '';
|
||||||
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
||||||
funcName = buildFunctionName(view);
|
funcName = buildMapperFunctionName(view);
|
||||||
|
|
||||||
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view, isSearch);
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view, isSearch);
|
||||||
|
|
||||||
@ -201,49 +225,6 @@ function buildGetList(view: EndpointDef, isSearch=false): string {
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSearches(view: EndpointDef): {filters: string, requiredFilterValues: string, optionalFiltersCode: string} {
|
|
||||||
let filtersObj: {filters: string, requiredFilterValues: string, optionalFiltersCode: string} = {
|
|
||||||
filters: '',
|
|
||||||
requiredFilterValues: '',
|
|
||||||
optionalFiltersCode: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
let filters: string = '';
|
|
||||||
let requiredFilterStrings = [];
|
|
||||||
let requiredQueryValues = '';
|
|
||||||
let optionalFilterParts = '';
|
|
||||||
if (view.filters) {
|
|
||||||
for (let i in view.filters) {
|
|
||||||
let f: Filter = view.filters[i];
|
|
||||||
if (f.required) {
|
|
||||||
requiredFilterStrings.push(`${f.column.table}.${f.column.name} ${f.comparison} ?`); // e.g. 'table.id = ?'
|
|
||||||
if (requiredQueryValues.length) {
|
|
||||||
requiredQueryValues = requiredQueryValues + `, `;
|
|
||||||
}
|
|
||||||
requiredQueryValues = requiredQueryValues + `params.${f.param}`;
|
|
||||||
} else {
|
|
||||||
/* e.g.
|
|
||||||
if (eventLog.app) {
|
|
||||||
query = query + ', app = ?';
|
|
||||||
queryValues.push(eventLog.app);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
optionalFilterParts = optionalFilterParts + `
|
|
||||||
if (params.${f.param}) {
|
|
||||||
query = query + ' OR ${f.column.table}.${f.column.name} ${f.comparison} ?';
|
|
||||||
queryValues.push('%' + params.${f.param} + '%');
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filters = ` WHERE ${requiredFilterStrings.join(' AND ')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
filtersObj.filters = filters;
|
|
||||||
filtersObj.requiredFilterValues = requiredQueryValues;
|
|
||||||
filtersObj.optionalFiltersCode = optionalFilterParts;
|
|
||||||
return filtersObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildJoin(view: EndpointDef): string {
|
function buildJoin(view: EndpointDef): string {
|
||||||
if (view.join?.length) {
|
if (view.join?.length) {
|
||||||
let join = `${view.table}`;
|
let join = `${view.table}`;
|
||||||
@ -271,7 +252,7 @@ function buildOrderBy(view: EndpointDef): string {
|
|||||||
return orderBy;
|
return orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFunctionName(view: EndpointDef): string {
|
function buildMapperFunctionName(view: EndpointDef): string {
|
||||||
let selector: {[type: string]: (view: EndpointDef) => string} = {
|
let selector: {[type: string]: (view: EndpointDef) => string} = {
|
||||||
'list': (view: EndpointDef) => `get${pluralize(uppercaseFirstLetter(view.component))}` + (view.type === 'count' ? 'Count' : ''),
|
'list': (view: EndpointDef) => `get${pluralize(uppercaseFirstLetter(view.component))}` + (view.type === 'count' ? 'Count' : ''),
|
||||||
'count': (view: EndpointDef) => `get${pluralize(uppercaseFirstLetter(view.component))}` + (view.type === 'count' ? 'Count' : ''),
|
'count': (view: EndpointDef) => `get${pluralize(uppercaseFirstLetter(view.component))}` + (view.type === 'count' ? 'Count' : ''),
|
||||||
@ -285,5 +266,6 @@ function buildFunctionName(view: EndpointDef): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createMapperFunc
|
createMapperFunc,
|
||||||
|
buildMapperFunctionName
|
||||||
}
|
}
|
46
src/views/service-creator.ts
Normal file
46
src/views/service-creator.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import {EndpointDef} from "../systemGenService";
|
||||||
|
import {lowercaseFirstLetter} from "./helpers";
|
||||||
|
import {buildMapperFunctionName} from "./mapper-creator";
|
||||||
|
|
||||||
|
|
||||||
|
function createServiceFunc(view: EndpointDef) {
|
||||||
|
// TODO: add support for doing things other than talking to the mapper e.g. API calls and cache checks
|
||||||
|
return buildServiceFunction(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildServiceFunction(view: EndpointDef): string {
|
||||||
|
let func: string = '';
|
||||||
|
let isListOrSearch: boolean = view.type === 'list' || view.type === 'search';
|
||||||
|
let funcName: string = buildServiceFunctionName(view);
|
||||||
|
// there should never be an 'undefined' item in funcParams but the compiler complained that it was possible
|
||||||
|
// TODO: funcParams should be sorted by 'required' so the optional params can come last and be left off when calling
|
||||||
|
let funcParams: (string | undefined)[] = (view.columns?.filter(column => column.param).map(column => column.param) || []).concat(view.filters?.filter(filter => filter.param).map(filter => filter.param) || []);
|
||||||
|
let columnParams: string[] = view.columns?.filter(column => column.param).map(column => { return '\n ' + column.param + ': ' + column.param; });
|
||||||
|
let filterParams: string[] = view.filters?.filter(filter => filter.param).map(filter => { return '\n ' + filter.param + ': ' + filter.param; }) || [];
|
||||||
|
|
||||||
|
if (isListOrSearch) {
|
||||||
|
funcParams.push('offset');
|
||||||
|
funcParams.push('limit');
|
||||||
|
}
|
||||||
|
|
||||||
|
func = `
|
||||||
|
public ${funcName}(${funcParams.join(', ')}) {
|
||||||
|
let params = {${columnParams}${columnParams.length ? ',' : ''}${filterParams}
|
||||||
|
};
|
||||||
|
return this.${mapperInstance(view)}.${buildMapperFunctionName(view)}(params${isListOrSearch ? ', offset, limit' : ''});
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildServiceFunctionName(view: EndpointDef): string {
|
||||||
|
return buildMapperFunctionName(view); // the functions should have the same name... I'm pretty sure...
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapperInstance(view: EndpointDef): string {
|
||||||
|
return `${lowercaseFirstLetter(view.component)}Mapper`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
createServiceFunc
|
||||||
|
}
|
@ -7,6 +7,7 @@ import * as path from 'path';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {createMapperFunc} from "./mapper-creator";
|
import {createMapperFunc} from "./mapper-creator";
|
||||||
import {uppercaseFirstLetter, lowercaseFirstLetter} from "./helpers";
|
import {uppercaseFirstLetter, lowercaseFirstLetter} from "./helpers";
|
||||||
|
import {createServiceFunc} from "./service-creator";
|
||||||
|
|
||||||
const ncp = require('ncp').ncp;
|
const ncp = require('ncp').ncp;
|
||||||
|
|
||||||
@ -35,6 +36,11 @@ function createComponent(component: ComponentDef, systemDef: SystemDef) {
|
|||||||
addInitializeRoutesCode(component.component, systemDef.name);
|
addInitializeRoutesCode(component.component, systemDef.name);
|
||||||
let serviceFileLocation: string = path.join(process.cwd(), systemDef.name, 'src', 'components', component.component, `${component.component}Service.ts`);
|
let serviceFileLocation: string = path.join(process.cwd(), systemDef.name, 'src', 'components', component.component, `${component.component}Service.ts`);
|
||||||
let servicePromise = initializeComponentFile(path.join(process.cwd(), systemDef.name, 'src', 'components', component.component, '{{component}}Service.ets'), serviceFileLocation, component.component, systemDef.name);
|
let servicePromise = initializeComponentFile(path.join(process.cwd(), systemDef.name, 'src', 'components', component.component, '{{component}}Service.ets'), serviceFileLocation, component.component, systemDef.name);
|
||||||
|
for (let i in component.endpoints) {
|
||||||
|
servicePromise = servicePromise.then(() => {
|
||||||
|
return insertServiceCode(component.endpoints[i], systemDef.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
addInitializeServiceCode(component.component, systemDef.name);
|
addInitializeServiceCode(component.component, systemDef.name);
|
||||||
Promise.all([mapperPromise, routesPromise, servicePromise]).then(() => {
|
Promise.all([mapperPromise, routesPromise, servicePromise]).then(() => {
|
||||||
console.log(`success creating component ${component.component}`);
|
console.log(`success creating component ${component.component}`);
|
||||||
@ -98,4 +104,18 @@ function insertMapperCode(view: EndpointDef, outDir: string): Promise<void> {
|
|||||||
fs.writeFileSync(fileLocation, newMapperFile, 'utf8');
|
fs.writeFileSync(fileLocation, newMapperFile, 'utf8');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function insertServiceCode(view: EndpointDef, outDir: string): Promise<void> {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
const separator: string = `// SYSTEM-BUILDER-${view.component}-service`;
|
||||||
|
let fileLocation = path.join(process.cwd(), outDir, 'src', 'components', view.component, `${view.component}Service.ts`);
|
||||||
|
let initServiceFile: string = fs.readFileSync(fileLocation, 'utf8');
|
||||||
|
let parts = initServiceFile.split(separator);
|
||||||
|
parts[0] = parts[0] + createServiceFunc(view);
|
||||||
|
let newServiceFile = parts.join(separator);
|
||||||
|
fs.writeFileSync(fileLocation, newServiceFile, 'utf8');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user