-
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 #2 from tareqdayya/dev
Dev
- Loading branch information
Showing
16 changed files
with
238 additions
and
262 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module.exports = { | ||
env: { | ||
commonjs: true, | ||
es6: true, | ||
node: true, | ||
}, | ||
extends: [ | ||
'standard', 'eslint', | ||
], | ||
parserOptions: { | ||
ecmaVersion: 11, | ||
}, | ||
rules: { | ||
'require-jsdoc': 'off', | ||
'jsdoc/require-returns': 'off', | ||
'jsdoc/require-description': 'off', | ||
'jsdoc/require-jsdoc': 'off', | ||
quotes: ['error', 'single'], | ||
strict: 'off', | ||
'valid-jsdoc': 'off', | ||
'comma-dangle': ['error', { | ||
arrays: 'always-multiline', | ||
objects: 'always-multiline', | ||
imports: 'always-multiline', | ||
exports: 'always-multiline', | ||
functions: 'always-multiline', | ||
}], | ||
semi: ['error', 'always'], | ||
'prefer-template': 'error', | ||
curly: ['error', 'multi-line'], | ||
}, | ||
}; |
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,143 +1,47 @@ | ||
#!/usr/bin/env node | ||
const fs = require('fs'); | ||
const promisify = require('util').promisify; | ||
const fsWrite = promisify(fs.writeFile); | ||
const fsRead = promisify(fs.readFile); | ||
const path = require('path'); | ||
const inquirer = require('inquirer'); | ||
const mustache = require('mustache'); | ||
const mkdirp = require('mkdirp'); | ||
|
||
let componentName = ''; | ||
let isFunctionComponent = false; | ||
let styleSheetExtension = 'css'; | ||
let hasTestFile = false; | ||
let targetPath = './src/components'; | ||
let isReactNative = false; | ||
|
||
// get component name and css preprocessor | ||
const writeFile = require('./lib/writeFile'); | ||
const { stylesheetType } = require('./lib/constants'); | ||
|
||
const styleSheetTypes = [ | ||
{ name: 'CSS', value: { extension: 'css', type: stylesheetType.cssBased } }, | ||
{ name: 'SCSS', value: { extension: 'scss', type: stylesheetType.cssBased } }, | ||
{ name: 'Less', value: { extension: 'less', type: stylesheetType.cssBased } }, | ||
{ name: 'Sass', value: { extension: 'sass', type: stylesheetType.cssBased } }, | ||
{ name: 'React Native Style', value: { extension: 'ts', type: stylesheetType.reactNative } }, | ||
{ name: 'Styled Components', value: { extension: 'ts', type: stylesheetType.styledComponents } }, | ||
]; | ||
|
||
// PROMPT | ||
inquirer | ||
.prompt([ | ||
{ type: 'input', name: 'componentName', message: 'whats your component\'s name?' }, | ||
{ | ||
type: 'input', | ||
name: 'isFunction', | ||
message: 'is this a function component? (y for yes, or press enter) : ' | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'styleSheetExtension', | ||
message: 'whats stylesheet preprocessor are u using? (leave empty for css for web and ts for RN)' | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'hasTestFile', | ||
message: 'Do you want to generate a test file? (y for yes, or press enter) : ', | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'finalPath', | ||
message: 'what\'s the path to the folder? (leave empty for ./src/components)' | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'isReactNative', | ||
message: 'is this a react native component? (y for yes, or press enter) : ' | ||
}, | ||
]) | ||
.then(answers => { | ||
componentName = answers['componentName']; | ||
if (answers['isFunction'] && answers['isFunction'] === 'y') isFunctionComponent = true; | ||
if (answers['styleSheetExtension']) styleSheetExtension = answers['styleSheetExtension']; | ||
if (answers['hasTestFile'] && answers['hasTestFile'].toLowerCase() === 'y') hasTestFile = true; | ||
if (answers['finalPath']) targetPath = answers['finalPath']; | ||
if (answers['isReactNative'] && answers['isReactNative'].toLowerCase() === 'y') isReactNative = true; | ||
main(); | ||
}); | ||
|
||
async function readFile(path) { | ||
return await fsRead(path, 'utf-8'); | ||
} | ||
|
||
async function writeFileToDir(dir, fileName, content) { | ||
await fsWrite(path.join(dir, fileName), content); | ||
} | ||
|
||
function convertCamelCaseToSpinal(string) { | ||
let i = 0; | ||
let convertedString = ''; | ||
let character = ''; | ||
while (i <= string.length) { | ||
character = string.charAt(i); | ||
if (!isNaN(character * 1)) { | ||
convertedString += character; | ||
} else { | ||
if (character == character.toUpperCase()) { | ||
if (i) convertedString += '-'; | ||
convertedString += character.toLowerCase(); | ||
} else convertedString += character; | ||
} | ||
i++; | ||
} | ||
|
||
return convertedString; | ||
|
||
} | ||
|
||
function main() { | ||
const targetDir = path.join(process.cwd(), targetPath, componentName); | ||
|
||
async function pipeTemplateToFile() { | ||
const componentTemplate = isFunctionComponent ? 'reactFunctionalComponentTemplate.txt' : 'reactComponentTemplate.txt'; | ||
|
||
const templatePaths = [ | ||
path.join(__dirname, 'templates', componentTemplate), | ||
path.join(__dirname, 'templates', 'index.txt'), | ||
path.join(__dirname, 'templates', 'reactWebStyleSheet.txt'), | ||
]; | ||
|
||
const finalFileNames = [`${componentName}.tsx`, 'index.tsx', `${componentName}.${styleSheetExtension}`]; | ||
|
||
if (isReactNative) { | ||
if (styleSheetExtension === 'css') styleSheetExtension = 'ts'; | ||
|
||
templatePaths.pop(); | ||
templatePaths.push(path.join(__dirname, 'templates', 'reactNativeStyleSheet.txt')); | ||
|
||
finalFileNames.pop(); | ||
finalFileNames.push(`${componentName}Styles.${styleSheetExtension}`); | ||
} | ||
|
||
if (hasTestFile) { | ||
templatePaths.push(path.join(__dirname, 'templates', 'testTemplate.txt')); | ||
finalFileNames.push(`${componentName}.test.tsx`); | ||
} | ||
|
||
for (let templatePathIndex = 0; templatePathIndex < templatePaths.length; templatePathIndex++) { | ||
const templatePath = templatePaths[templatePathIndex]; | ||
|
||
const template = await readFile(templatePath); | ||
|
||
const output = mustache.render(template, | ||
.prompt([ | ||
{ type: 'input', name: 'componentName', message: 'whats your component\'s name?' }, | ||
{ | ||
COMPONENT_NAME: componentName, | ||
STYLESHEET_FILENAME: componentName + (isReactNative ? 'Styles' : ''), | ||
STYLESHEET_EXTENSION: styleSheetExtension, | ||
WEB_CLASS_NAME: convertCamelCaseToSpinal(componentName), | ||
}); | ||
|
||
writeFileToDir(targetDir, finalFileNames[templatePathIndex], output); | ||
} | ||
} | ||
|
||
if (!fs.existsSync(targetDir)) { | ||
mkdirp(targetDir, (err) => { | ||
if (err) return console.error(err); | ||
pipeTemplateToFile(); | ||
}); | ||
} else return pipeTemplateToFile(); | ||
} | ||
|
||
|
||
|
||
|
||
type: 'confirm', | ||
name: 'isFunction', | ||
message: 'is this a function component?', | ||
}, | ||
{ | ||
type: 'list', | ||
name: 'styleSheetExtension', | ||
message: 'whats stylesheet preprocessor are u using?', | ||
choices: styleSheetTypes, | ||
}, | ||
{ | ||
type: 'confirm', | ||
name: 'hasTestFile', | ||
message: 'Do you want to generate a test file?', | ||
}, | ||
{ | ||
type: 'input', | ||
name: 'finalPath', | ||
message: 'what\'s the path to the folder? (leave empty for ./src/components)', | ||
}, | ||
]) | ||
.then(answers => writeFile( | ||
answers.componentName, | ||
answers.finalPath || './src/components', | ||
!!answers.isFunction, | ||
answers.styleSheetExtension, | ||
!!answers.hasTestFile, | ||
)); |
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,7 @@ | ||
const stylesheetType = { | ||
cssBased: 'cssBased', | ||
styledComponents: 'styledComponents', | ||
reactNative: 'reactNativeStyles', | ||
}; | ||
|
||
module.exports = { stylesheetType }; |
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,24 @@ | ||
function convertCamelCaseToSpinal(string) { | ||
if (!(typeof string === 'string')) return string; | ||
let convertedString = ''; | ||
let character = ''; | ||
|
||
// LOOP OVER CHARACTERS | ||
for (let i = 0; i < string.length; i++) { | ||
character = string.charAt(i); | ||
|
||
// NUMERIC CHARACTER: KEEP AS IS | ||
if (!isNaN(parseInt(character, 10))) convertedString += String(character); | ||
|
||
// ALPHA CHARACTER | ||
else { // SEPARATE AT UPPERCASE WITH '-' | ||
if (character === character.toUpperCase() && i > 0) convertedString += '-'; | ||
|
||
convertedString += character.toLowerCase(); | ||
} | ||
} | ||
|
||
return convertedString; | ||
} | ||
|
||
module.exports = { convertCamelCaseToSpinal }; |
4 changes: 2 additions & 2 deletions
4
templates/reactComponentTemplate.txt → ...tes/components/reactComponentTemplate.txt
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
File renamed without changes.
File renamed without changes.
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,3 @@ | ||
import { StyleSheet } from 'react-native'; | ||
|
||
export default StyleSheet.create({}); |
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,5 @@ | ||
import styled from 'styled-components'; | ||
|
||
export default { | ||
Container: styled.div``, | ||
}; |
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,24 @@ | ||
import React from 'react'; | ||
import {{COMPONENT_NAME}} from './{{COMPONENT_NAME}}'; | ||
import { shallow } from 'enzyme'; | ||
|
||
const mockInputs = {}; | ||
const mockOutputs = {}; | ||
|
||
describe.skip('{{COMPONENT_NAME}}', () => { | ||
describe('What are we testing?', () => { | ||
it('should pass smoke test', async () => { | ||
wrapper = shallow(<{{COMPONENT_NAME}} />); | ||
expect(wrapper).not.toBeEmptyRender(); | ||
wrapper.unmount(); | ||
}); | ||
}); | ||
|
||
describe('Snapshot Test', () => { | ||
it('should match', async () => { | ||
const tree = renderer.create(<{{COMPONENT_NAME}} />); | ||
expect(tree.toJSON()).toMatchSnapshot(); | ||
tree.unmount(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.