Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit e2a45e4

Browse files
committed
feat(generators): generators for page, component, directive, pipe, provider
generators for page, component, directive, pipe, provider
1 parent 333c7d0 commit e2a45e4

File tree

7 files changed

+126
-29
lines changed

7 files changed

+126
-29
lines changed

src/generators.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
import { Logger} from './logger/logger';
22
import { generateContext } from './util/config';
33
import * as Constants from './util/constants';
4-
import { BuildContext, GeneratorOption, GeneratorRequest } from './util/interfaces';
4+
import { BuildContext } from './util/interfaces';
5+
import { applyTemplates, filterOutTemplates, GeneratorOption, GeneratorRequest, hydrateRequest, readTemplates, writeGeneratedFiles } from './generators/util';
6+
7+
export { GeneratorOption };
8+
export { GeneratorRequest };
59

610
export function generateNonTab(request: GeneratorRequest) {
711
const context = generateContext();
812
return processNonTabRequest(context, request);
913
}
1014

11-
function processNonTabRequest(context: BuildContext, request: GeneratorRequest) {
12-
15+
function processNonTabRequest(context: BuildContext, request: GeneratorRequest): Promise<string[]> {
16+
Logger.debug('[Generators] processNonTabRequest: Hydrating the request with project data ...');
17+
const hydratedRequest = hydrateRequest(context, request);
18+
Logger.debug('[Generators] processNonTabRequest: Reading templates ...');
19+
return readTemplates(hydratedRequest.dirToRead).then((map: Map<string, string>) => {
20+
Logger.debug('[Generators] processNonTabRequest: Filtering out NgModule and Specs if needed ...');
21+
return filterOutTemplates(hydratedRequest, map);
22+
}).then((filteredMap: Map<string, string>) => {
23+
Logger.debug('[Generators] processNonTabRequest: Applying tempaltes ...');
24+
const appliedTemplateMap = applyTemplates(hydratedRequest, filteredMap);
25+
Logger.debug('[Generators] processNonTabRequest: Writing generated files to disk ...');
26+
return writeGeneratedFiles(hydratedRequest, appliedTemplateMap);
27+
});
1328
}
1429

1530
export function listOptions() {
@@ -20,6 +35,7 @@ export function listOptions() {
2035
list.push({type: Constants.PIPE, multiple: false});
2136
list.push({type: Constants.PROVIDER, multiple: false});
2237
list.push({type: Constants.TABS, multiple: true});
38+
return list;
2339
}
2440

2541

src/generators/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export const CLASSNAME_VARIABLE = '$CLASSNAME';
22
export const FILENAME_VARIABLE = '$FILENAME';
3+
export const SUPPLIEDNAME_VARIABLE = '$SUPPLIEDNAME';
34

45
export const KNOWN_FILE_EXTENSION = '.tmpl';
56

src/generators/util.spec.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,28 +177,86 @@ export class $CLASSNAMEComponent {
177177
178178
`;
179179

180+
const fileFive = '/Users/dan/fileFive';
181+
const fileFiveContent = `
182+
import { NgModule } from '@angular/core';
183+
import { $CLASSNAME } from './$FILENAME';
184+
import { IonicModule } from 'ionic-angular';
185+
186+
@NgModule({
187+
declarations: [
188+
$CLASSNAME,
189+
],
190+
imports: [
191+
IonicModule.forChild($CLASSNAME)
192+
],
193+
entryComponents: [
194+
$CLASSNAME
195+
],
196+
providers: []
197+
})
198+
export class $CLASSNAMEModule {}
199+
`;
200+
201+
const fileSix = '/Users/dan/fileSix';
202+
const fileSixContent = `
203+
<!--
204+
Generated template for the $CLASSNAME page.
205+
206+
See http://ionicframework.com/docs/v2/components/#navigation for more info on
207+
Ionic pages and navigation.
208+
-->
209+
<ion-header>
210+
211+
<ion-navbar>
212+
<ion-title>$SUPPLIEDNAME</ion-title>
213+
</ion-navbar>
214+
215+
</ion-header>
216+
217+
218+
<ion-content padding>
219+
220+
</ion-content>
221+
`;
222+
180223
const map = new Map<string, string>();
181224
map.set(fileOne, fileOneContent);
182225
map.set(fileTwo, fileTwoContent);
183226
map.set(fileThree, fileThreeContent);
184227
map.set(fileFour, fileFourContent);
228+
map.set(fileFive, fileFiveContent);
229+
map.set(fileSix, fileSixContent);
185230

186231
const className = 'SettingsView';
187232
const fileName = 'settings-view';
233+
const suppliedName = 'settings view';
188234

189-
const results = util.applyTemplates({ className: className, fileName: fileName}, map);
235+
const results = util.applyTemplates({ name: suppliedName, className: className, fileName: fileName}, map);
190236
const modifiedContentOne = results.get(fileOne);
191237
const modifiedContentTwo = results.get(fileTwo);
192238
const modifiedContentThree = results.get(fileThree);
193239
const modifiedContentFour = results.get(fileFour);
240+
const modifiedContentFive = results.get(fileFive);
241+
const modifiedContentSix = results.get(fileSix);
194242
expect(modifiedContentOne.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
195243
expect(modifiedContentOne.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
244+
expect(modifiedContentOne.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
196245
expect(modifiedContentTwo.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
197246
expect(modifiedContentTwo.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
247+
expect(modifiedContentTwo.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
198248
expect(modifiedContentThree.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
199249
expect(modifiedContentThree.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
250+
expect(modifiedContentThree.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
200251
expect(modifiedContentFour.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
201252
expect(modifiedContentFour.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
253+
expect(modifiedContentFour.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
254+
expect(modifiedContentFive.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
255+
expect(modifiedContentFive.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
256+
expect(modifiedContentFive.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
257+
expect(modifiedContentSix.indexOf(GeneratorConstants.CLASSNAME_VARIABLE)).toEqual(-1);
258+
expect(modifiedContentSix.indexOf(GeneratorConstants.FILENAME_VARIABLE)).toEqual(-1);
259+
expect(modifiedContentSix.indexOf(GeneratorConstants.SUPPLIEDNAME_VARIABLE)).toEqual(-1);
202260
});
203261
});
204262

src/generators/util.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { basename, join } from 'path';
1+
import { basename, dirname, join } from 'path';
22
import { readdirSync} from 'fs';
33

44
import { paramCase, pascalCase } from 'change-case';
55

66
import * as Constants from '../util/constants';
77
import * as GeneratorConstants from './constants';
8-
import { getPropertyValue, readFileAsync, replaceAll, writeFileAsync } from '../util/helpers';
9-
import { BuildContext, GeneratorRequest, HydratedGeneratorRequest } from '../util/interfaces';
8+
import { getPropertyValue, mkDirpAsync, readFileAsync, replaceAll, writeFileAsync } from '../util/helpers';
9+
import { BuildContext } from '../util/interfaces';
1010

1111
export function hydrateRequest(context: BuildContext, request: GeneratorRequest) {
1212
const hydrated = Object.assign({}, request) as HydratedGeneratorRequest;
@@ -32,6 +32,7 @@ export function readTemplates(pathToRead: string): Promise<Map<string, string>>
3232
promise.then((fileContent: string) => {
3333
filePathToContent.set(absolutePath, fileContent);
3434
});
35+
return promise;
3536
});
3637
return Promise.all(promises).then(() => {
3738
return filePathToContent;
@@ -55,7 +56,8 @@ export function applyTemplates(request: HydratedGeneratorRequest, templates: Map
5556
templates.forEach((fileContent: string, filePath: string) => {
5657
const classnameRemovedContent = replaceAll(fileContent, GeneratorConstants.CLASSNAME_VARIABLE, request.className);
5758
const fileNameRemovedContent = replaceAll(classnameRemovedContent, GeneratorConstants.FILENAME_VARIABLE, request.fileName);
58-
appliedTemplateMap.set(filePath, fileNameRemovedContent);
59+
const suppliedNameRemovedContent = replaceAll(fileNameRemovedContent, GeneratorConstants.SUPPLIEDNAME_VARIABLE, request.name);
60+
appliedTemplateMap.set(filePath, suppliedNameRemovedContent);
5961
});
6062
return appliedTemplateMap;
6163
}
@@ -68,13 +70,20 @@ export function writeGeneratedFiles(request: HydratedGeneratorRequest, processed
6870
const newFileName = `${request.fileName}.${newFileExtension}`;
6971
const fileToWrite = join(request.dirToWrite, newFileName);
7072
createdFileList.push(fileToWrite);
71-
promises.push(writeFileAsync(fileToWrite, fileContent));
73+
promises.push(createDirAndWriteFile(fileToWrite, fileContent));
7274
});
7375
return Promise.all(promises).then(() => {
7476
return createdFileList;
7577
});
7678
}
7779

80+
function createDirAndWriteFile(filePath: string, fileContent: string) {
81+
const directory = dirname(filePath);
82+
return mkDirpAsync(directory).then(() => {
83+
return writeFileAsync(filePath, fileContent);
84+
});
85+
}
86+
7887
export function getDirToWriteToByType(context: BuildContext, type: string) {
7988
if (type === Constants.COMPONENT) {
8089
return context.componentsDir;
@@ -89,3 +98,22 @@ export function getDirToWriteToByType(context: BuildContext, type: string) {
8998
}
9099
throw new Error(`Unknown Generator Type: ${type}`);
91100
}
101+
102+
export interface GeneratorOption {
103+
type: string;
104+
multiple: boolean;
105+
};
106+
107+
export interface GeneratorRequest {
108+
type?: string;
109+
name?: string;
110+
includeSpec?: boolean;
111+
includeNgModule?: boolean;
112+
};
113+
114+
export interface HydratedGeneratorRequest extends GeneratorRequest {
115+
fileName?: string;
116+
className?: string;
117+
dirToRead?: string;
118+
dirToWrite?: string;
119+
};

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export * from './util/config';
1515
export * from './util/helpers';
1616
export * from './util/interfaces';
1717

18+
export * from './generators';
19+
1820
import { generateContext } from './util/config';
1921
import { getAppScriptsVersion } from './util/helpers';
2022
import { Logger } from './logger/logger';

src/util/helpers.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { randomBytes } from 'crypto';
22
import { basename, dirname, extname, join } from 'path';
3-
import { createReadStream, createWriteStream, readdir, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
3+
import { createReadStream, createWriteStream, ensureDir, readdir, readFile, readFileSync, readJsonSync, remove, unlink, writeFile } from 'fs-extra';
44
import * as osName from 'os-name';
55

66
import * as Constants from './constants';
@@ -184,6 +184,17 @@ export function copyFileAsync(srcPath: string, destPath: string) {
184184
});
185185
}
186186

187+
export function mkDirpAsync(directoryPath: string) {
188+
return new Promise((resolve, reject) => {
189+
ensureDir(directoryPath, (err: Error) => {
190+
if (err) {
191+
return reject(err);
192+
}
193+
return resolve();
194+
});
195+
});
196+
}
197+
187198
export function readDirAsync(pathToDir: string) {
188199
return new Promise<string[]>((resolve, reject) => {
189200
readdir(pathToDir, (err: Error, fileNames: string[]) => {

src/util/interfaces.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -189,22 +189,3 @@ export interface WebpackModule {
189189
export interface WebpackDependency {
190190
moduleIdentifier: string;
191191
};
192-
193-
export interface GeneratorOption {
194-
type: string;
195-
multiple: boolean;
196-
};
197-
198-
export interface GeneratorRequest {
199-
type?: string;
200-
name?: string;
201-
includeSpec?: boolean;
202-
includeNgModule?: boolean;
203-
};
204-
205-
export interface HydratedGeneratorRequest extends GeneratorRequest {
206-
fileName?: string;
207-
className?: string;
208-
dirToRead?: string;
209-
dirToWrite?: string;
210-
};

0 commit comments

Comments
 (0)