-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from bachmateus/development
Release v2.1.1
- Loading branch information
Showing
35 changed files
with
693 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { filesManagerService } from "../manager/manager.module"; | ||
import { ComponentBuilderService } from "./service/component-builder.service"; | ||
import { ScreenBuilderService } from "./service/screen-builder.service"; | ||
import { RouteBuilderService } from "./service/route-builder.service"; | ||
|
||
export const componentBuilderService = new ComponentBuilderService(filesManagerService); | ||
export const screenBuilderService = new ScreenBuilderService(filesManagerService); | ||
export const screenBuilderService = new ScreenBuilderService(filesManagerService); | ||
export const routeBuilderService = new RouteBuilderService(filesManagerService); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { generateRouteNameFile, getRouteNameByFileName } from './route-constants'; | ||
|
||
describe('route-words-rename', () => { | ||
describe('generateRouteNameFile', () => { | ||
it('success to generate component file name composed by one word', () => { | ||
const componentName = 'LoggedRoutes'; | ||
const fileName = 'logged.routes'; | ||
expect(generateRouteNameFile(componentName)).toEqual(fileName); | ||
}); | ||
it('success to generate component file name composed by more than one word', () => { | ||
const componentName = 'UserLoggedRoutes'; | ||
const fileName = 'user-logged.routes'; | ||
expect(generateRouteNameFile(componentName)).toEqual(fileName); | ||
}); | ||
it('success to generate component file name composed by lowercase words', () => { | ||
const componentName = 'user-logged-routes'; | ||
const fileName = 'user-logged.routes'; | ||
expect(generateRouteNameFile(componentName)).toEqual(fileName); | ||
}); | ||
}) | ||
|
||
describe('getRouteNameByFileName', () => { | ||
it('success to get component name composed by one word', () => { | ||
const fileName = 'logged.routes.js'; | ||
const componentName = 'LoggedRoutes'; | ||
expect(getRouteNameByFileName(fileName)).toEqual(componentName); | ||
}); | ||
it('success to get component name composed by more than one word', () => { | ||
const fileName = 'user-logged.routes.js'; | ||
const componentName = 'UserLoggedRoutes'; | ||
expect(getRouteNameByFileName(fileName)).toEqual(componentName); | ||
}); | ||
}) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
export const routeWordsToRename = { | ||
// TODO: change interface to use routesTypesEnum | ||
routeFile: { | ||
routeNameToRename: 'MyRoutes', | ||
library: { | ||
stack: [ | ||
{ find: 'ROUTE_CREATOR', replaceTo: 'createNativeStackNavigator' }, | ||
{ find: 'ROUTE_LIB', replaceTo: '@react-navigation/native-stack' }, | ||
], | ||
bottomTab: [ | ||
{ find: 'ROUTE_CREATOR', replaceTo: 'createBottomTabNavigator' }, | ||
{ find: 'ROUTE_LIB', replaceTo: '@react-navigation/bottom-tabs' }, | ||
], | ||
drawer: [ | ||
{ find: 'ROUTE_CREATOR', replaceTo: 'createDrawerNavigator' }, | ||
{ find: 'ROUTE_LIB', replaceTo: '@react-navigation/drawer' }, | ||
], | ||
}, | ||
} | ||
} | ||
|
||
export const routeFileToCopy = { | ||
JavaScript:(routeName:string) => ({ | ||
routeName, templateFileName: 'routes.js', fileName: `${generateRouteNameFile(routeName)}.js` | ||
}), | ||
TypeScript:(routeName:string) => ({ | ||
routeName, templateFileName: 'routes.js', fileName: `${generateRouteNameFile(routeName)}.tsx` | ||
}), | ||
} | ||
|
||
export const mainRouteFileName = { | ||
JavaScript: { templateFileName: 'main.routes.js', fileName: 'index.js'}, | ||
TypeScript: { templateFileName: 'main.routes.js', fileName: 'index.tsx'}, | ||
}; | ||
|
||
export const generateRouteNameFile = (componentRouteName:string) => { | ||
const routeName = componentRouteName.replace('Routes', '').replace('-routes', ''); | ||
if (routeName.length === 0) return componentRouteName.toLocaleLowerCase(); | ||
const lowercaseName = routeName | ||
.split('') | ||
.map(char => { | ||
if(char === char.toUpperCase()) return `-${char.toLocaleLowerCase()}`; | ||
return char; | ||
}) | ||
.join('') | ||
.replace('-', ''); | ||
return `${lowercaseName}.routes`.toLocaleLowerCase(); | ||
} | ||
|
||
export const getRouteNameByFileName = (fileName:string): string => { | ||
const fileNameWithouExtension = fileName.replace('.tsx', '').replace('.js', ''); | ||
return fileNameWithouExtension | ||
.split('-') | ||
.map(word=>word.charAt(0).toUpperCase() + word.slice(1)) | ||
.join('') | ||
.replace('.routes', 'Routes'); | ||
} | ||
|
||
export const generateImportCodeLine = (routeName: string): string => `import ${routeName.split('.')[0]} from './${generateRouteNameFile(routeName)}'`; | ||
|
||
export const generateJsxCodeLine = (routeName: string, isMainRoute: boolean): string => isMainRoute ? ` <${routeName} />` : ` <Screen name="${routeName}" component={${routeName}} />` ; | ||
|
||
export const getMainRoutePathAndTagReference = (mainRouteName: string) => { | ||
return { | ||
importTermToFind: 'import', | ||
nestedRouteTagReference: (!mainRouteName) ? '<NavigationContainer' : '<Navigator', | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { configFileLanguageType, RnFilesCreatorConfigFile } from '../../cli/data/rn-files-creator-config-file'; | ||
import { FilesManagerService } from "../../manager/service/files-manager.service"; | ||
import { RouteCliParams } from '../../cli/data/creator-params'; | ||
import { cliTemplatePath, userProjectDirectory } from '../../manager/constants/paths'; | ||
import { ComponentAlreadyExistsLogger } from '../logger/component-already-exists.logger'; | ||
import { NativeStringFunction } from '../../common/functions/nativeStringFunction'; | ||
import { generateImportCodeLine, generateJsxCodeLine, getMainRoutePathAndTagReference, mainRouteFileName, routeFileToCopy, routeWordsToRename } from '../data/route-constants'; | ||
import { routesTypesEnum } from '../../cli/data/args-cli-options'; | ||
|
||
export class RouteBuilderService { | ||
private routeCliParams: RouteCliParams = {} as RouteCliParams | ||
private projectConfig: RnFilesCreatorConfigFile = {} as RnFilesCreatorConfigFile | ||
|
||
constructor(private readonly filesManagerService: FilesManagerService) {} | ||
|
||
async handle(routeCliParams: RouteCliParams, projectConfig: RnFilesCreatorConfigFile) { | ||
this.setConfigVars(routeCliParams, projectConfig); | ||
const wasRouteCreated = await this.createRoute(); | ||
|
||
// TODO: include route on main route or where it belongs | ||
if(wasRouteCreated) await this.includeRouteOnMainRoute(this.routeCliParams.route, '', projectConfig.language); | ||
return wasRouteCreated; | ||
// TODO: return which libs the cli shall install | ||
} | ||
|
||
private setConfigVars(routeCliParams: RouteCliParams, projectConfig: RnFilesCreatorConfigFile) { | ||
this.routeCliParams = routeCliParams | ||
this.projectConfig = projectConfig | ||
} | ||
|
||
private async createRoute(): Promise<boolean> { | ||
// TODO: if fail remove dir | ||
const { fileName, templateFileName} = routeFileToCopy[this.projectConfig.language](this.routeCliParams.route); | ||
if (await this.checkIfRouteExists(fileName)) return false; | ||
return await this.createRouteFile(this.routeCliParams.route, this.routeCliParams.routeType, fileName, templateFileName); | ||
} | ||
|
||
private async checkIfRouteExists(fileName: string): Promise<boolean> { | ||
const routeName = this.routeCliParams.route; | ||
const doesExist = await this.filesManagerService.checkIfPathExists(`${userProjectDirectory.route}\/${fileName}`); | ||
if (doesExist) new ComponentAlreadyExistsLogger(routeName); | ||
const doesPathExist = await this.filesManagerService.checkIfPathExists(`${userProjectDirectory.route}\/`); | ||
if (!doesPathExist) await this.filesManagerService.createDirectory(userProjectDirectory.route) | ||
return doesExist; | ||
} | ||
|
||
private async createRouteFile(routeName: string, routeType: routesTypesEnum, fileName: string, templateFileName: string): Promise<boolean> { | ||
const fileData = await this.filesManagerService.readFile(`${cliTemplatePath.route}\/${templateFileName}`); | ||
const newContent = this.replaceWordsFromTemplateFile(fileData!, routeName, routeType); | ||
return await this.filesManagerService.writeFile(userProjectDirectory.route, fileName, newContent) | ||
} | ||
|
||
private replaceWordsFromTemplateFile(content: string, routeName: string, routeType: routesTypesEnum): string { | ||
const libraryWords = routeWordsToRename.routeFile.library[routeType]; | ||
let newContent = content; | ||
newContent = NativeStringFunction.replaceAll(newContent, routeWordsToRename.routeFile.routeNameToRename, routeName); | ||
libraryWords.forEach(item => newContent = NativeStringFunction.replaceAll(newContent, item.find, item.replaceTo)); | ||
return newContent; | ||
} | ||
|
||
private async createMainRouteFile(language: configFileLanguageType): Promise<boolean> { | ||
const mainFileExists = await this.filesManagerService.checkIfPathExists(userProjectDirectory.route + mainRouteFileName[language].fileName); | ||
if(mainFileExists) return false; | ||
return await this.filesManagerService.copyFile( | ||
`${cliTemplatePath.route}\/${mainRouteFileName[language].templateFileName}`, | ||
userProjectDirectory.route, | ||
mainRouteFileName[language].fileName | ||
); | ||
} | ||
|
||
private async includeRouteOnMainRoute(routeName: string, nestedRouteName: string, language: configFileLanguageType): Promise<boolean> { | ||
const { nestedRouteTagReference, importTermToFind } = getMainRoutePathAndTagReference(nestedRouteName); | ||
const routeFileName = (!nestedRouteName) ? mainRouteFileName[language].fileName : routeFileToCopy[this.projectConfig.language](nestedRouteName).fileName; | ||
if(!nestedRouteName) await this.createMainRouteFile(language); | ||
|
||
const nestedRouteData = await this.filesManagerService.readFile(userProjectDirectory.route + routeFileName); | ||
if(!nestedRouteData) return false; | ||
const codeLines = nestedRouteData?.split('\n') as string[]; | ||
// TODO: convert app.route.tsx to AppRoute | ||
const lineOfLastImport = this.getLineNumberFromLastOcorrency(codeLines, importTermToFind) | ||
codeLines?.splice(lineOfLastImport+1, 0, generateImportCodeLine(routeName)); | ||
|
||
// TODO: get space number from the file | ||
const lineOfNavigatorContentTag = this.getLineNumberFromLastOcorrency(codeLines, nestedRouteTagReference) | ||
codeLines?.splice(lineOfNavigatorContentTag+1, 0, generateJsxCodeLine(routeName, !nestedRouteName)); | ||
|
||
return await this.filesManagerService.updateFile(userProjectDirectory.route, routeFileName, codeLines?.join('\n')) | ||
} | ||
|
||
private getLineNumberFromLastOcorrency(codeLines: string[], textToFind: string): number { | ||
return codeLines?.reduce( | ||
(previousValue, codeLine: string, index) => { | ||
const found = codeLine.indexOf(textToFind); | ||
if (found > -1) return index; | ||
return previousValue; | ||
}, | ||
-1 | ||
) as number; | ||
} | ||
} |
Oops, something went wrong.