Skip to content
This repository was archived by the owner on Nov 21, 2024. It is now read-only.

Commit 6e5ca68

Browse files
committed
feat(generator): Add generator for model, service, grid, lookup input and modals
1 parent c038f43 commit 6e5ca68

25 files changed

Lines changed: 838 additions & 31 deletions

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"@types/del": "^3.0.0",
6767
"@types/dotenv": "^4.0.2",
6868
"@types/fs-extra": "^4.0.5",
69+
"@types/inflection": "^1.5.28",
6970
"@types/lodash": "^4.14.87",
7071
"@types/loglevel": "^1.5.3",
7172
"cheerio": "^1.0.0-rc.2",
@@ -78,6 +79,7 @@
7879
"dotenv": "^4.0.0",
7980
"fs-extra": "^4.0.2",
8081
"gh-pages": "^1.1.0",
82+
"inflection": "^1.12.0",
8183
"lodash": "^4.17.4",
8284
"loglevel": "^1.6.0",
8385
"loglevel-colored-level-prefix": "^1.0.0",

src/lib/base.ts

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ export class Base {
241241
return result;
242242
}
243243
async po2ts(customOptions?: { i18nFolder?: string, package?: any }) {
244-
this.log('po2ts').debug('start');
245244
let folder = path.resolve(this.folder + '/src/i18n');
246245
let packageData: any = { name: '' };
247246
if (customOptions && customOptions.i18nFolder) {
@@ -250,7 +249,6 @@ export class Base {
250249
if (customOptions && customOptions.package) {
251250
packageData = customOptions.package;
252251
}
253-
this.log('po2ts').debug(folder);
254252
const options = _.merge(
255253
{
256254
'po': {
@@ -266,25 +264,13 @@ export class Base {
266264
'package': packageData
267265
}
268266
);
269-
this.log('po2ts').debug(options);
270-
const srcgenTemplate = path.resolve(__dirname + '/../../srcgen/convert.po.to.ts');
271-
const optionsFile = path.resolve(__dirname + '/../../srcgen/temp_' + process.hrtime() + '-convert.po.to.ts.json');
272-
fsExtra.writeJSONSync(optionsFile, options);
273-
if (!fsExtra.existsSync(optionsFile)) {
274-
this.log('po2ts').error(`File does not exists: ${optionsFile}`);
275-
}
276-
const commandString = 'node ./node_modules/srcgen/bin/srcgen.js -x -t ' + srcgenTemplate + ' -f ' + optionsFile;
277-
if (!fsExtra.existsSync(folder)) {
278-
this.log('po2ts').debug(commandString);
279-
this.log('po2ts').error(`Folder does not exists: ${path.resolve(folder)}`);
280-
this.log('po2ts').debug('end');
281-
return await false;
282-
}
283-
let result = await this.commandRunner(commandString);
284-
if (fsExtra.existsSync(optionsFile)) {
285-
del.sync([optionsFile], { force: true });
286-
}
287-
return result;
267+
return await this.srcgen(
268+
folder,
269+
packageData,
270+
'po2ts',
271+
'convert.po.to.ts',
272+
options
273+
);
288274
}
289275
async prepare(customOptions?: {
290276
i18nFolder?: string,
@@ -306,7 +292,6 @@ export class Base {
306292
return results.reduce((all: boolean, current: boolean) => { return all && current; }, true);
307293
}
308294
async makeTsList(customOptions?: { srcFolder?: string, package?: any, listComponentsPostfix?: string }) {
309-
this.log('makeTsList').debug('start');
310295
let folder = path.resolve(this.folder + '/src');
311296
let packageData: any = { name: '' };
312297
let listComponentsPostfix = '';
@@ -319,7 +304,6 @@ export class Base {
319304
if (customOptions && customOptions.listComponentsPostfix) {
320305
listComponentsPostfix = customOptions.listComponentsPostfix;
321306
}
322-
this.log('makeTsList').debug(folder);
323307
const options = _.merge(
324308
{
325309
'scan': {
@@ -331,25 +315,42 @@ export class Base {
331315
'package': packageData
332316
}
333317
);
334-
this.log('makeTsList').debug(options);
335-
const srcgenTemplate = path.resolve(__dirname + '/../../srcgen/make.list.ts.files');
336-
const optionsFile = path.resolve(__dirname + '/../../srcgen/temp_' + process.hrtime() + '-make.list.ts.files.json');
318+
return await this.srcgen(
319+
folder,
320+
packageData,
321+
'makeTsList',
322+
'make.list.ts.files',
323+
options
324+
);
325+
}
326+
async srcgen(
327+
folder: string,
328+
packageData: any,
329+
name: string,
330+
templateName: string,
331+
options: any
332+
) {
333+
this.log(name).debug('start');
334+
this.log(name).debug(folder);
335+
this.log(name).debug(options);
336+
const srcgenTemplate = path.resolve(__dirname + '/../../srcgen/' + templateName);
337+
const optionsFile = path.resolve(__dirname + '/../../srcgen/temp_' + process.hrtime() + '-' + templateName + '.json');
337338
fsExtra.writeJSONSync(optionsFile, options);
338339
if (!fsExtra.existsSync(optionsFile)) {
339-
this.log('makeTsList').error(`File does not exists: ${optionsFile}`);
340+
this.log(name).error(`File does not exists: ${optionsFile}`);
340341
}
341342
const commandString = 'node ./node_modules/srcgen/bin/srcgen.js -x -t ' + srcgenTemplate + ' -f ' + optionsFile;
342343
if (!fsExtra.existsSync(folder)) {
343-
this.log('makeTsList').debug(commandString);
344-
this.log('makeTsList').error(`Folder does not exists: ${folder}`);
345-
this.log('makeTsList').debug('end');
344+
this.log(name).debug(commandString);
345+
this.log(name).error(`Folder does not exists: ${folder}`);
346+
this.log(name).debug('end');
346347
return await false;
347348
}
348349
let result = await this.commandRunner(commandString);
349350
if (fsExtra.existsSync(optionsFile)) {
350351
del.sync([optionsFile], { force: true });
351352
}
352-
this.log('makeTsList').debug('end');
353+
this.log(name).debug('end');
353354
return result;
354355
}
355356
}

src/lib/project.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as path from 'path';
44

55
import { Base } from './base';
66

7+
const inflection = require('inflection');
78
export class Project extends Base {
89

910
name = 'project';
@@ -23,6 +24,7 @@ export class Project extends Base {
2324
(this.agularCliJson.apps ? this.agularCliJson.apps : []).
2425
filter((app: any) => app.appRoot === '').
2526
map((lib: any) => {
27+
lib.shortName = lib.root.split('/')[1];
2628
lib.rootPath = path.resolve(this.rootFolder + '/' + _.trimStart(lib.root, './') + '/../');
2729
return lib;
2830
});
@@ -73,4 +75,117 @@ export class Project extends Base {
7375
}
7476
return angularCliJson;
7577
}
78+
async generatorGrid(customOptions?: {
79+
entityName: string,
80+
appName?: string,
81+
pkFields?: string,
82+
fields?: string[],
83+
dateFields?: string[],
84+
srcFolder?: string,
85+
package?: any,
86+
coreLib?: string,
87+
platformLib?: string,
88+
coreFolder?: string,
89+
platformFolder?: string
90+
}) {
91+
let folder = path.resolve(this.folder + '/src');
92+
let packageData: any = { name: '' };
93+
let entityName = '';
94+
let appName = this.appsConfigs[0] && this.appsConfigs[0].name ? this.appsConfigs[0].name : 'app';
95+
let coreLib = this.libsConfigs[0] && this.libsConfigs[0].shortName ? this.libsConfigs[0].shortName : 'core';
96+
let platformLib = this.libsConfigs[1] && this.libsConfigs[1].shortName ? this.libsConfigs[1].shortName : 'web';
97+
let coreFolder = this.libsConfigs[0] && this.libsConfigs[0].name ? this.libsConfigs[0].name : 'core';
98+
let platformFolder = this.libsConfigs[1] && this.libsConfigs[1].name ? this.libsConfigs[1].name : 'web';
99+
let pkFields: string = 'id';
100+
let fields: string[] = [
101+
'name',
102+
'title',
103+
'createdAt',
104+
'updatedAt'
105+
];
106+
let dateFields: string[] = [
107+
'createdAt',
108+
'updatedAt'
109+
];
110+
if (customOptions && customOptions.appName) {
111+
appName = customOptions.appName;
112+
}
113+
if (customOptions && customOptions.srcFolder) {
114+
folder = customOptions.srcFolder;
115+
}
116+
if (customOptions && customOptions.package) {
117+
packageData = customOptions.package;
118+
}
119+
if (customOptions && customOptions.coreLib) {
120+
coreLib = customOptions.coreLib;
121+
}
122+
if (customOptions && customOptions.platformLib) {
123+
platformLib = customOptions.platformLib;
124+
}
125+
if (customOptions && customOptions.pkFields) {
126+
pkFields = customOptions.pkFields;
127+
}
128+
if (customOptions && customOptions.fields) {
129+
fields = customOptions.fields;
130+
}
131+
if (customOptions && customOptions.dateFields) {
132+
dateFields = customOptions.dateFields;
133+
}
134+
const options = _.merge(
135+
{
136+
'app': {
137+
'name': appName
138+
},
139+
'libs': {
140+
'core': coreLib,
141+
'platform': platformLib,
142+
'coreFolder': coreFolder,
143+
'platformFolder': platformFolder
144+
},
145+
'grid': {
146+
'list': {
147+
'name': {
148+
'kebab': _.kebabCase(inflection(entityName)),
149+
'camel': _.upperFirst(_.camelCase(inflection(entityName))),
150+
'lower': {
151+
'camel': _.camelCase(inflection(entityName))
152+
},
153+
'caption': _.upperFirst(_.words(inflection(entityName)).join(' ')),
154+
'snake': _.snakeCase(inflection(entityName))
155+
}
156+
},
157+
'name': {
158+
'kebab': _.kebabCase(entityName),
159+
'camel': _.upperFirst(_.camelCase(entityName)),
160+
'lower': {
161+
'camel': _.camelCase(entityName)
162+
},
163+
'caption': _.upperFirst(_.words(entityName).join(' ')),
164+
'snake': _.snakeCase(entityName)
165+
},
166+
'item': {
167+
'name': {
168+
'caption': _.words(entityName).join(' ').toLowerCase()
169+
}
170+
},
171+
'table': {
172+
'fields': {
173+
'names': fields,
174+
'dates': dateFields
175+
},
176+
'pk': {
177+
'name': pkFields
178+
}
179+
}
180+
}
181+
}
182+
);
183+
return await this.srcgen(
184+
folder,
185+
packageData,
186+
'generatorGrid',
187+
'grid.select.input.modal',
188+
options
189+
);
190+
}
76191
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"app": {
3+
"name": {
4+
"kebab": "todo"
5+
}
6+
},
7+
"module": {
8+
"name": {
9+
"kebab": "@rucken/todo"
10+
}
11+
},
12+
"grid": {
13+
"list": {
14+
"name": {
15+
"kebab": "todo-states",
16+
"camel": "TodoStates",
17+
"lower": {
18+
"camel": "todoStates"
19+
},
20+
"caption": "Todo states",
21+
"snake": "todo_states"
22+
}
23+
},
24+
"name": {
25+
"kebab": "todo-state",
26+
"camel": "TodoState",
27+
"lower": {
28+
"camel": "todoState"
29+
},
30+
"caption": "Todo state",
31+
"snake": "todo_state"
32+
},
33+
"item": {
34+
"name": {
35+
"caption": "todo state"
36+
}
37+
},
38+
"table": {
39+
"fields": {
40+
"names": [
41+
"name",
42+
"title",
43+
"createdAt",
44+
"updatedAt"
45+
],
46+
"dates": [
47+
"createdAt",
48+
"updatedAt"
49+
]
50+
},
51+
"pk": {
52+
"name": "id"
53+
}
54+
}
55+
}
56+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# VARIABLES
2+
```
3+
<prompt name="app.name" message="Application name">appname</prompt>
4+
<prompt name="module.core" message="Core module">core</prompt>
5+
<prompt name="module.platform" message="Platform module">web</prompt>
6+
<prompt name="module.coreFolder" message="Core module">core</prompt>
7+
<prompt name="module.platformFolder" message="Platform module">web</prompt>
8+
<prompt name="grid.list.name.kebab" message="Grid component name">name-types</prompt>
9+
<prompt name="grid.name.kebab" message="Modal window component name">name-type</prompt>
10+
<prompt name="grid.list.name.camel" message="Service name">NameTypes</prompt>
11+
<prompt name="grid.name.camel" message="Entity name">NameType</prompt>
12+
<prompt name="grid.list.name.lower.camel" message="Service name if it use in local var">nameTypes</prompt>
13+
<prompt name="grid.name.lower.camel" message="Entity name if it use in local var">nameType</prompt>
14+
<prompt name="grid.list.name.caption" message="Grid title">Name types</prompt>
15+
<prompt name="grid.name.caption" message="Item title">Name type</prompt>
16+
<prompt name="grid.item.name.caption" message="Entity title">name type</prompt>
17+
<prompt name="grid.name.snake" message="Resource url postfix for work with more entities">name_type</prompt>
18+
<prompt name="grid.list.name.snake" message="Resource url postfix for work with one entities">name_types</prompt>
19+
<prompt name="grid.table.fields.names" message="Entity fields" updater="javascript:
20+
if (_.isArray(__value)){
21+
return __value;
22+
}
23+
__value=__value.split(',');
24+
__value=_.map(__value,function(item){return _.camelCase(_.trim(item,'\t '));});
25+
return __value">name, title, createdAt, updatedAt</prompt>
26+
<prompt name="grid.table.pk.name" message="Entity primary field name">id</prompt>
27+
<prompt name="grid.table.fields.dates" message="Entity date fields" updater="javascript:
28+
if (_.isArray(__value)){
29+
return __value;
30+
}
31+
__value=__value.split(',');
32+
__value=_.map(__value,function(item){return _.camelCase(_.trim(item,'\t '));});
33+
return __value">createdAt, updatedAt</prompt>
34+
```

0 commit comments

Comments
 (0)