Skip to content

Commit 020b0d5

Browse files
committed
generateTemplateFilesCommandLine and output.overwrite
1 parent 186d117 commit 020b0d5

File tree

9 files changed

+186
-163
lines changed

9 files changed

+186
-163
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ The `generateTemplateFiles` function takes an array of `IConfigItem` items.
9696
- `dynamicReplacers` - (Optional) An array of IReplacer used to replace content in the designated `entry.folderPath`.
9797
- `output.path` - The desired output path for generated files. [Case Converters](#case-converters) and [Replacer Slots](#replacer-slots-or-ireplacerslotquestion) can be used to make the path somewhat dynamic.
9898
- `output.pathAndFileNameDefaultCase` - The [Case Converters](#case-converters) to use for the file path and file name(s).
99+
- `output.overwrite` - (Optional) When `true` it will overwrite any files that are named the same.
99100
- `onComplete` - (Optional) Takes a callback function that is called once the file(s) have been outputted. A [IResults](#iresults) object will be passed to the callback.
100101

101102
###### Example

examples/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"---------- Normal Example -------------------------------------------": "",
77
"generate": "node ./tools/generate.js",
88
"---------- Command Line Example -------------------------------------": "",
9-
"commandline": "node ./tools/generate.js angular-ngrx-store __name__=some-name __model__=some-other-name --outputpath=./src/here --overwrite"
9+
"commandline": "node ./tools/commandLine.js angular-ngrx-store __name__=some-name __model__=some-other-name --outputpath=./src/here --overwrite"
1010
},
1111
"devDependencies": {
1212
"file-name": "0.1.0",

examples/tools/commandLine.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const {items} = require('./items');
2+
const {generateTemplateFilesCommandLine} = require('../../dist/generate-template-files.cjs');
3+
// Note: In your file it will be like this:
4+
// const {generateTemplateFilesCommandLine} = require('generate-template-files');
5+
6+
// node ./tools/generate.js angular-ngrx-store __name__=some-name __model__=some-other-name --outputpath=asdf/asdf/ --overwrite
7+
8+
generateTemplateFilesCommandLine(items);

examples/tools/generate.js

Lines changed: 4 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,6 @@
1-
const {generateTemplateFiles, StringUtility} = require('../../dist/generate-template-files.cjs');
1+
const {items} = require('./items');
2+
const {generateTemplateFiles} = require('../../dist/generate-template-files.cjs');
23
// Note: In your file it will be like this:
3-
// const {generateTemplateFiles, StringUtility} = require('generate-template-files');
4+
// const {generateTemplateFiles} = require('generate-template-files');
45

5-
const filename = require('file-name');
6-
const insertLine = require('insert-line');
7-
8-
const config = require('../package.json');
9-
10-
generateTemplateFiles([
11-
// Angular
12-
{
13-
option: 'Angular Ngrx Store',
14-
defaultCase: '(pascalCase)',
15-
entry: {
16-
folderPath: './tools/templates/angular/ngrx-store/',
17-
},
18-
stringReplacers: ['__name__', {question: 'Insert model name', slot: '__model__'}],
19-
dynamicReplacers: [
20-
{slot: '__version__', slotValue: config.version},
21-
{slot: '__description__', slotValue: config.description},
22-
],
23-
output: {
24-
path: './src/app/stores/__name__(lowerCase)',
25-
pathAndFileNameDefaultCase: '(kebabCase)',
26-
},
27-
onComplete: async (results) => {
28-
// console.log(`results`, results);
29-
},
30-
},
31-
// Vue
32-
{
33-
option: 'Vue Vuex Store',
34-
defaultCase: '(pascalCase)',
35-
entry: {
36-
folderPath: './tools/templates/vue/vuex-store/',
37-
},
38-
stringReplacers: ['__store__', '__model__'],
39-
output: {
40-
path: './src/stores/__store__(kebabCase)',
41-
pathAndFileNameDefaultCase: '(pascalCase)',
42-
},
43-
onComplete: async (results) => {
44-
console.log(`results`, results);
45-
await importVuexStore(results);
46-
},
47-
},
48-
// React
49-
{
50-
option: 'React Redux Store',
51-
defaultCase: '(pascalCase)',
52-
entry: {
53-
folderPath: './tools/templates/react/redux-store/',
54-
},
55-
stringReplacers: ['__store__', '__model__'],
56-
output: {
57-
path: './src/stores/__store__(kebabCase)',
58-
pathAndFileNameDefaultCase: '(pascalCase)',
59-
},
60-
onComplete: (results) => {
61-
console.log(`results`, results);
62-
},
63-
},
64-
{
65-
option: 'React Component',
66-
defaultCase: '(pascalCase)',
67-
entry: {
68-
folderPath: './tools/templates/react/component/',
69-
},
70-
stringReplacers: ['__name__'],
71-
output: {
72-
path: './src/views/__name__(kebabCase)',
73-
pathAndFileNameDefaultCase: '(pascalCase)',
74-
},
75-
},
76-
{
77-
option: 'React Connected Component',
78-
defaultCase: '(pascalCase)',
79-
entry: {
80-
folderPath: './tools/templates/react/connected-component/',
81-
},
82-
stringReplacers: ['__name__'],
83-
output: {
84-
path: './src/views/__name__(kebabCase)',
85-
pathAndFileNameDefaultCase: '(pascalCase)',
86-
},
87-
},
88-
{
89-
option: 'Selector',
90-
defaultCase: '(pascalCase)',
91-
entry: {
92-
folderPath: './tools/templates/react/selectors/',
93-
},
94-
stringReplacers: ['__name__'],
95-
output: {
96-
path: './src/selectors/__name__(kebabCase)',
97-
pathAndFileNameDefaultCase: '(pascalCase)',
98-
},
99-
},
100-
{
101-
option: 'Model',
102-
defaultCase: '(pascalCase)',
103-
entry: {
104-
folderPath: './tools/templates/react/__model__Model.ts',
105-
},
106-
stringReplacers: ['__model__'],
107-
output: {
108-
path: './src/models/__model__Model.ts',
109-
pathAndFileNameDefaultCase: '(pascalCase)',
110-
},
111-
},
112-
{
113-
option: 'Interface',
114-
defaultCase: '(pascalCase)',
115-
entry: {
116-
folderPath: './tools/templates/react/I__interface__.ts',
117-
},
118-
stringReplacers: ['__interface__'],
119-
output: {
120-
path: './src/models/I__interface__.ts',
121-
pathAndFileNameDefaultCase: '(pascalCase)',
122-
},
123-
},
124-
{
125-
option: 'Enum',
126-
defaultCase: '(pascalCase)',
127-
entry: {
128-
folderPath: './tools/templates/react/__enum__Enum.ts',
129-
},
130-
stringReplacers: ['__enum__'],
131-
output: {
132-
path: './src/constants/__enum__Enum.ts',
133-
pathAndFileNameDefaultCase: '(pascalCase)',
134-
},
135-
},
136-
]);
137-
138-
/*
139-
* NOTE: there is many ways you can do this. This is just an example on how you might approch it.
140-
*/
141-
async function importVuexStore(results) {
142-
const files = results.output.files;
143-
144-
const fullPaths = files
145-
.map((folderPath) => folderPath.replace('src/', '')) // remove 'src' from path
146-
.map((path) => `import ${filename(path)} from '${path}'`) // create import statement
147-
.join('\n'); // put all imports on there own line
148-
149-
try {
150-
await insertLine('src/import-test.ts').append(fullPaths);
151-
} catch (error) {
152-
console.log(``, error);
153-
}
154-
}
6+
generateTemplateFiles(items);

examples/tools/items.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
const filename = require('file-name');
2+
const insertLine = require('insert-line');
3+
4+
const config = require('../package.json');
5+
6+
const items = [
7+
// Angular
8+
{
9+
option: 'Angular Ngrx Store',
10+
defaultCase: '(pascalCase)',
11+
entry: {
12+
folderPath: './tools/templates/angular/ngrx-store/',
13+
},
14+
stringReplacers: ['__name__', {question: 'Insert model name', slot: '__model__'}],
15+
dynamicReplacers: [
16+
{slot: '__version__', slotValue: config.version},
17+
{slot: '__description__', slotValue: config.description},
18+
],
19+
output: {
20+
path: './src/app/stores/__name__(lowerCase)',
21+
pathAndFileNameDefaultCase: '(kebabCase)',
22+
overwrite: true,
23+
},
24+
onComplete: async (results) => {
25+
// console.log(`results`, results);
26+
},
27+
},
28+
// Vue
29+
{
30+
option: 'Vue Vuex Store',
31+
defaultCase: '(pascalCase)',
32+
entry: {
33+
folderPath: './tools/templates/vue/vuex-store/',
34+
},
35+
stringReplacers: ['__store__', '__model__'],
36+
output: {
37+
path: './src/stores/__store__(kebabCase)',
38+
pathAndFileNameDefaultCase: '(pascalCase)',
39+
},
40+
onComplete: async (results) => {
41+
console.log(`results`, results);
42+
await importVuexStore(results);
43+
},
44+
},
45+
// React
46+
{
47+
option: 'React Redux Store',
48+
defaultCase: '(pascalCase)',
49+
entry: {
50+
folderPath: './tools/templates/react/redux-store/',
51+
},
52+
stringReplacers: ['__store__', '__model__'],
53+
output: {
54+
path: './src/stores/__store__(kebabCase)',
55+
pathAndFileNameDefaultCase: '(pascalCase)',
56+
},
57+
onComplete: (results) => {
58+
console.log(`results`, results);
59+
},
60+
},
61+
{
62+
option: 'React Component',
63+
defaultCase: '(pascalCase)',
64+
entry: {
65+
folderPath: './tools/templates/react/component/',
66+
},
67+
stringReplacers: ['__name__'],
68+
output: {
69+
path: './src/views/__name__(kebabCase)',
70+
pathAndFileNameDefaultCase: '(pascalCase)',
71+
},
72+
},
73+
{
74+
option: 'React Connected Component',
75+
defaultCase: '(pascalCase)',
76+
entry: {
77+
folderPath: './tools/templates/react/connected-component/',
78+
},
79+
stringReplacers: ['__name__'],
80+
output: {
81+
path: './src/views/__name__(kebabCase)',
82+
pathAndFileNameDefaultCase: '(pascalCase)',
83+
},
84+
},
85+
{
86+
option: 'Selector',
87+
defaultCase: '(pascalCase)',
88+
entry: {
89+
folderPath: './tools/templates/react/selectors/',
90+
},
91+
stringReplacers: ['__name__'],
92+
output: {
93+
path: './src/selectors/__name__(kebabCase)',
94+
pathAndFileNameDefaultCase: '(pascalCase)',
95+
},
96+
},
97+
{
98+
option: 'Model',
99+
defaultCase: '(pascalCase)',
100+
entry: {
101+
folderPath: './tools/templates/react/__model__Model.ts',
102+
},
103+
stringReplacers: ['__model__'],
104+
output: {
105+
path: './src/models/__model__Model.ts',
106+
pathAndFileNameDefaultCase: '(pascalCase)',
107+
},
108+
},
109+
{
110+
option: 'Interface',
111+
defaultCase: '(pascalCase)',
112+
entry: {
113+
folderPath: './tools/templates/react/I__interface__.ts',
114+
},
115+
stringReplacers: ['__interface__'],
116+
output: {
117+
path: './src/models/I__interface__.ts',
118+
pathAndFileNameDefaultCase: '(pascalCase)',
119+
},
120+
},
121+
{
122+
option: 'Enum',
123+
defaultCase: '(pascalCase)',
124+
entry: {
125+
folderPath: './tools/templates/react/__enum__Enum.ts',
126+
},
127+
stringReplacers: ['__enum__'],
128+
output: {
129+
path: './src/constants/__enum__Enum.ts',
130+
pathAndFileNameDefaultCase: '(pascalCase)',
131+
},
132+
},
133+
];
134+
135+
/*
136+
* NOTE: there is many ways you can do this. This is just an example on how you might approach it.
137+
*/
138+
async function importVuexStore(results) {
139+
const files = results.output.files;
140+
141+
const fullPaths = files
142+
.map((folderPath) => folderPath.replace('src/', '')) // remove 'src' from path
143+
.map((path) => `import ${filename(path)} from '${path}'`) // create import statement
144+
.join('\n'); // put all imports on there own line
145+
146+
try {
147+
await insertLine('src/import-test.ts').append(fullPaths);
148+
} catch (error) {
149+
console.log(``, error);
150+
}
151+
}
152+
153+
exports.items = items;

src/GenerateTemplateFiles.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import IReplacerSlotQuestion from './models/IReplacerSlotQuestion';
1515
import yargs from 'yargs';
1616

1717
export default class GenerateTemplateFiles {
18-
public static isCommandLine: boolean = Boolean(yargs.argv._.length);
18+
private _isCommandLine: boolean = false;
1919

2020
/**
2121
* Main method to create your template files. Accepts an array of `IConfigItem` items.
@@ -77,14 +77,16 @@ export default class GenerateTemplateFiles {
7777
const contentReplacers: IReplacer[] = this._getReplacers(replacers, contentCase);
7878
const outputPathReplacers: IReplacer[] = this._getReplacers(replacers, outputPathCase);
7979
const outputPath: string = await this._getOutputPath(outputPathReplacers, selectedConfigItem);
80-
const shouldWriteFiles: boolean = GenerateTemplateFiles.isCommandLine
81-
? yargs.argv.overwrite === true
82-
: await this._shouldWriteFiles(outputPath);
80+
let shouldWriteFiles: boolean = selectedConfigItem.output.overwrite || yargs.argv.overwrite === true;
81+
82+
if (!this._isCommandLine) {
83+
shouldWriteFiles = selectedConfigItem.output.overwrite || (await this._shouldWriteFiles(outputPath));
84+
}
8385

8486
if (shouldWriteFiles === false) {
8587
console.info('No new files created');
8688

87-
if (GenerateTemplateFiles.isCommandLine) {
89+
if (this._isCommandLine) {
8890
console.info('Use --overwrite option to overwrite existing files');
8991
}
9092

@@ -206,7 +208,7 @@ export default class GenerateTemplateFiles {
206208
return replaceString(outputPath, replacer.slot, replacer.slotValue);
207209
}, selectedConfigItem.output.path);
208210

209-
if (GenerateTemplateFiles.isCommandLine) {
211+
if (this._isCommandLine) {
210212
const outputPath = yargs.argv.outputpath as string | undefined;
211213

212214
return outputPath ?? outputPathFormatted;

src/index.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ export type IReplacerSlotQuestion = IReplacerSlotQuestionDefault;
1919
* Main method to create your template files. Accepts an array of `IConfigItem` items.
2020
*/
2121
export function generateTemplateFiles(data: IConfigItem[]): Promise<void> {
22-
if (GenerateTemplateFiles.isCommandLine) {
23-
return new GenerateTemplateFiles().commandLine(data);
24-
}
25-
2622
return new GenerateTemplateFiles().generate(data);
2723
}
24+
25+
/**
26+
* Main method to create your template files with command line.
27+
*/
28+
export function generateTemplateFilesCommandLine(data: IConfigItem[]): Promise<void> {
29+
return new GenerateTemplateFiles().commandLine(data);
30+
}

0 commit comments

Comments
 (0)