From be8fbe8fd8ab2a473681c4d0afafc01532f241fb Mon Sep 17 00:00:00 2001 From: Amine Abdelli Date: Fri, 3 Mar 2023 17:53:17 +0100 Subject: [PATCH] Develop (#3) * chore(.gitignore): add .env * docs(changelog): Create changelog.md file * chore(cross-env): Install cross-env * feat(config.json): Enable customizing path * chore(branching): Create dev branch * chore(CI): Create CIs * chore(ci): test * chore(ci): test * chore(CI): Update package.json version * Update version to { 'react-component-files-generator': '1.0.8', npm: '9.3.1', node: '18.14.1', v8: '10.2.154.23-node.22', uv: '1.44.2', zlib: '1.2.13', brotli: '1.0.9', ares: '1.18.1', modules: '108', nghttp2: '1.51.0', napi: '8', llhttp: '6.0.10', uvwasi: '0.0.14', acorn: '8.8.1', simdutf: '3.1.0', undici: '5.19.1', openssl: '3.0.8+quic', cldr: '42.0', icu: '72.1', tz: '2022g', unicode: '15.0', ngtcp2: '0.8.1', nghttp3: '0.7.0' } * chore(CI): Update package.json version * chore(CI): Update version to { 'react-component-files-generator': '1.0.8', npm: '9.3.1', node: '18.14.1', v8: '10.2.154.23-node.22', uv: '1.44.2', zlib: '1.2.13', brotli: '1.0.9', ares: '1.18.1', modules: '108', nghttp2: '1.51.0', napi: '8', llhttp: '6.0.10', uvwasi: '0.0.14', acorn: '8.8.1', simdutf: '3.1.0', undici: '5.19.1', openssl: '3.0.8+quic', cldr: '42.0', icu: '72.1', tz: '2022g', unicode: '15.0', ngtcp2: '0.8.1', nghttp3: '0.7.0' } * chore(CI): Update package.json version * chore(CI): Update package.json version * chore(CI): Update package.json version * chore(CI): Update package.json version * chore(CI): Update package.json version * chore(ci): enhance package version update * chore(release): update package version [skip ci] * ci(github-workflows): Create ci that check that the changelog has been modified * docs(CHANGELOG): Update CHANGELOG.md * ci(github-workflows): Apply minor change * chore(release): update package version [skip ci] * ci(changelog-check): Change trigger condition * ci(workflows): change runner for ubuntu * docs(CHANGELOG): Update changelog * chore(release): update package version [skip ci] --------- Co-authored-by: GitHub Actions --- .env | 1 + .github/workflows/changelog-check.yml | 22 ++++ .github/workflows/update-version.yml | 35 +++++ .gitignore | 5 +- CHANGELOG.md | 26 ++++ README.md | 51 +++++++- lib/builder/build.ts | 23 ++-- lib/help/help.ts | 10 +- lib/index.ts | 10 +- lib/init/init.ts | 4 +- lib/init/prompt.init.ts | 4 +- lib/utils/fileSystem.utils.ts | 23 +++- lib/utils/path.utils.ts | 67 +++++----- lib/utils/sanitize.utils.ts | 14 +- package-lock.json | 176 +++++++++++++++++++++++++- package.json | 8 +- 16 files changed, 400 insertions(+), 79 deletions(-) create mode 100644 .env create mode 100644 .github/workflows/changelog-check.yml create mode 100644 .github/workflows/update-version.yml create mode 100644 CHANGELOG.md diff --git a/.env b/.env new file mode 100644 index 0000000..083c815 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +NODE_ENV=development \ No newline at end of file diff --git a/.github/workflows/changelog-check.yml b/.github/workflows/changelog-check.yml new file mode 100644 index 0000000..2991bb1 --- /dev/null +++ b/.github/workflows/changelog-check.yml @@ -0,0 +1,22 @@ +name: Changelog Check + +on: + pull_request: + types: [opened, reopened, synchronize] + +jobs: + changelog_check: + runs-on: ubuntu-latest + name: 🩺 Check Changelog + steps: + - uses: actions/checkout@v2 + - name: Check Changelog + run: | + git fetch + echo "base ref is main checking changelog..." + if [ -z "$(git diff --name-only origin/${{ github.base_ref }} | grep CHANGELOG.md)" ]; then + echo "[FAIL] - Changelog has not been updated" + exit 1 + else + echo "[SUCCESS] - Changelog has been updated" + fi diff --git a/.github/workflows/update-version.yml b/.github/workflows/update-version.yml new file mode 100644 index 0000000..249458b --- /dev/null +++ b/.github/workflows/update-version.yml @@ -0,0 +1,35 @@ +name: Update package version + +on: + pull_request: + types: [closed] + branches: + - develop + +jobs: + update_version: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Update package version + run: | + if [[ ${{ github.ref }} == refs/heads/feat/* ]]; then + npm version minor --no-git-tag-version + else + npm version patch --no-git-tag-version + fi + + - name: Commit version update + run: | + git config --global user.email "amine.abdelli@outlook.fr" + git config --global user.name "amine-abdelli" + git commit -am "chore(release): update package version [skip ci]" + + - name: Push changes + uses: ad-m/github-push-action@v0.6.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} + force: true diff --git a/.gitignore b/.gitignore index 987e9aa..1495883 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -/node_modules +node_modules rcfg.config.json src dist yarn.lock -.yarn-integrity \ No newline at end of file +.yarn-integrity +.env \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fcb0c86 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# CHANGELOG + +## 1.1.3 - (03.03.2023) + +_Fix_ + + - Fix CHANGELOG check + +## 1.1.2 - (03.03.2023) + +_CI_ + + - Check that the CHANGELOG has been well updated + +## 1.1.1 - (03.03.2023) + +_CI_ + + - Update package version based on branch name + +## 1.1.0 - (07.02.2023) + +_Feat_ + + - Create customizable path in rcfg.config.json + - Improve README.md \ No newline at end of file diff --git a/README.md b/README.md index 72c1ee6..04766d8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ npx rcfg --init ``` ![carbon](https://user-images.githubusercontent.com/77112257/205501760-78b104a0-013c-4074-baf0-10b7c98b3960.png) -#### By default, components are generated in the same folder but you can change it by editing the config file: +#### By default, components are generated in the same folder but you can customize paths by adding `"path"` props in the config file: ``` |-- /src |-- /components @@ -33,6 +33,7 @@ ### Files generated are autofilled with generic content and the imports needed : ##### Component - (e.g. Button.component.tsx) +Imports are dynamically generated depending on files location in the file tree. ```jsx import React from 'react'; import './Button.module.scss'; @@ -78,7 +79,12 @@ describe('[Component] Button', () => { When you run --init for the first time, it will ask you a series of questions to customize the cli to your needs and will generate a "rcfg.config.json" config file. -#### Example of the **rfsb.config.json** config file: +#### Example of the **rcfg.config.json** config file: +Note that the path prop can handle this template `<%component_name%>` to dynamically create file in a folder holding the component name you're creating : + +Example for a Button.component.tsx component: +```"./src/style/<%component_name%>"``` +```"./src/style/Button/Button.component.tsx"``` ```json { @@ -87,16 +93,18 @@ When you run --init for the first time, it will ask you a series of questions to "component": { "extension": ".tsx", "nameExtension": ".component.tsx", - "export": "default" + "export": "default" // For component file only }, "style": { "extension": ".less", "nameExtension": ".module.less", - "module": true + "module": true, // For style file only + "path": "./src/style/<%component_name%>" }, "test": { "extension": ".tsx", - "nameExtension": ".test.tsx" + "nameExtension": ".test.tsx", + "path": "./src/__test__/<%component_name%>" }, "props": { "extension": ".ts", @@ -108,3 +116,36 @@ When you run --init for the first time, it will ask you a series of questions to } } ``` + +# Config options + +### `extension` (required) +- Type: `string` +- Example value: `.js`, `.jsx`, `.ts`, `.tsx`, `.scss`, `.less`, ... +This value must start with a dot. +define ... + +### `nameExtension` (required) +- Type: `string` +- Example value: `.component.tsx`, `.props.js`, `.module.css`, `null`, ... +This value must start with a dot +define ... + +### `module` (optional) - For style file only + - Type: `boolean` + - Value: `true`, `false` + +### `export` (optional) - For component only +// output: export { Component }; OR export default Component; +### `path` (optional) - For component only + - Type: `string` + - Example value: `./src/__test__/<%component_name%>`, `src/style`, ... +Boolean +default style +"extension" - ts tsx js jsx scss less css +"nameExtension" - e.g Button.props.ts +"path" - you can specify a path where you want to deploy. Path will be dynamically changed depending on where other elements are located. + +### For style related file +"module" boolean - rather if the element is a css module or not + diff --git a/lib/builder/build.ts b/lib/builder/build.ts index 2d278c7..5865fe9 100644 --- a/lib/builder/build.ts +++ b/lib/builder/build.ts @@ -1,6 +1,7 @@ import fs from 'fs'; +import { generateFullPath } from '../utils/path.utils'; import { ComponentExportTemplate, ComponentImportTemplate, ComponentNameTemplate, PropsImportTemplate, PropsTemplate, StyleImportTemplate } from '../constants'; -import { sanitizeConfigPaths, sanitizePath, createDirIfNotExist, buildFile, readTemplateFile, doesConfigFileExists, log, getFullFileNames } from '../utils'; +import { sanitizeConfigPaths, removeLeadingSlashes, writeFile, readTemplateFile, doesConfigFileExists, log, getFullFileNames, createFiles } from '../utils'; import { quitPrompt } from '../utils/prompt.utils'; import { componentBuildPrompt } from './prompt.build'; @@ -11,9 +12,10 @@ export async function runBuild() { log(' Please first run the following command : rcfg --init'); quitPrompt(); } - const { name, componentEntryPoint, ...configRest } = JSON.parse(fs.readFileSync('rcfg.config.json', { encoding: 'utf8' })); + const config = JSON.parse(fs.readFileSync('rcfg.config.json', { encoding: 'utf8' })); + const { name, componentEntryPoint, ...configRest } = config; // Clean component entry point path - const COMPONENTS_ROOT_DIR = sanitizePath(componentEntryPoint); + const COMPONENTS_ROOT_DIR = removeLeadingSlashes(componentEntryPoint); const { chosenComponentName: ComponentName, promptResponse } = await componentBuildPrompt(configRest, componentEntryPoint); @@ -21,11 +23,14 @@ export async function runBuild() { const FILE_NAMES = getFullFileNames(configRest, ComponentName); const RELATIVE_PATH = `${COMPONENTS_ROOT_DIR}/${ComponentName}/`; + // Create all files + // We need to create files first in order to get dynamically generated imports at the right place + createFiles(config, ComponentName, responsesType); // For each key create a file dynamically filled with template file's content for (const [key, aConfig] of Object.entries(sanitizeConfigPaths(configRest, ComponentName))) { + const PATH_TO_CREATE_IF_NOT_EXIST = aConfig.path?.replace(ComponentNameTemplate, ComponentName) || RELATIVE_PATH; const FILE_NAME = FILE_NAMES[key]; - createDirIfNotExist(RELATIVE_PATH); // Go to the next config if this one hasn't been picked by the user if (!responsesType.includes(key)) continue; @@ -53,7 +58,7 @@ export async function runBuild() { .replace(new RegExp(PropsTemplate, 'g'), props); // Build component file - buildFile(`${RELATIVE_PATH}/${FILE_NAME}`, JSON.parse(formatedTemplate)); + writeFile(PATH_TO_CREATE_IF_NOT_EXIST, FILE_NAME, JSON.parse(formatedTemplate)); } if (key === 'test') { const COMPONENT_IMPORT_PATH = `./${FILE_NAMES['component']}`; @@ -65,7 +70,7 @@ export async function runBuild() { .replace(new RegExp(ComponentImportTemplate, 'g'), FULL_COMPONENT_FILE_IMPORT_STRING); // Build test file - buildFile(`${RELATIVE_PATH}/${FILE_NAME}`, JSON.parse(formatedTemplate)); + writeFile(PATH_TO_CREATE_IF_NOT_EXIST, FILE_NAME, JSON.parse(formatedTemplate)); } if (key === 'props') { // Dynamically replace template's tags with the right content @@ -73,13 +78,13 @@ export async function runBuild() { .replace(new RegExp(ComponentNameTemplate, 'g'), ComponentName); // Build props file - buildFile(`${COMPONENTS_ROOT_DIR}/${ComponentName}/${FILE_NAME}`, JSON.parse(formatedTemplate)); + writeFile(`${PATH_TO_CREATE_IF_NOT_EXIST}`, FILE_NAME, JSON.parse(formatedTemplate)); } if (key === 'style') { // Build style sheet - buildFile(`${RELATIVE_PATH}/${FILE_NAME}`, ''); + writeFile(PATH_TO_CREATE_IF_NOT_EXIST, FILE_NAME, ''); } - buildFile(`${RELATIVE_PATH}/${FILE_NAME}`, ''); + writeFile(PATH_TO_CREATE_IF_NOT_EXIST, FILE_NAME, ''); } }; diff --git a/lib/help/help.ts b/lib/help/help.ts index 5c589c1..54d42d9 100644 --- a/lib/help/help.ts +++ b/lib/help/help.ts @@ -2,10 +2,10 @@ export function runHelp() { console.log(` Basic options: - rsfb --help / -h Show help. - rsfb --init / -i Run config initialization and creates a rcfg.config.json file. - rsfb --version / -v Output the version number. - rsfb --build / -b Build component. - rsfb --update / -u Update config. + rcfg --help / -h Show help. + rcfg --init / -i Run config initialization and creates a rcfg.config.json file. + rcfg --version / -v Output the version number. + rcfg --build / -b Build component. + rcfg --update / -u Update config. `) } \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts index 210f81b..c6c335c 100755 --- a/lib/index.ts +++ b/lib/index.ts @@ -8,7 +8,7 @@ import jsonPackage from '../package.json'; const knownOptions = ['--build', '-b', '--init', '-i', '--update', '-u', '--version', '-v', '--help', '-h']; -if(process.argv[2] === '--build' || process.argv[2] === '--b') { +if(process.argv[2] === '--build' || process.argv[2] === '-b') { runBuild(); } if(process.argv[2] === '--init' || process.argv[2] === '-i' || process.argv[2] === '--update' || process.argv[2] === '-u') { @@ -27,10 +27,16 @@ if(!knownOptions.includes(process.argv[2])) { process.exit(0); } -// TODO: Check node version before requiring/doing anything else +// TODO : Check node version before requiring/doing anything else // TODO : When we have no style import go one line upward'\b' // TODO : "fill": false /* if user doesn't want his file filled up // TODO : Trigger errors when necessary like if there is 2 files that could have the same name in the same folder in case of nameExtension missing // TODO : Make it possible to change file name like Button.component.tsx ButtonProps.ts // TODO : Make it possible to add pages +// TODO : Allow template in file path to be able to create a component folder +// TODO : Allow to create a component in a folder +// TODO : Parse config file and highlith errors like + // - If there is the possibility to have 2 files with the same name in the same folder. + // - If there is 2 files with the same name but in different folders WARN the user that he should add a nameExtension + // - If there is 2 dots in any extension like .component..tsx or ..tsx. or any stupid thing like that // !: The user may be on a very old node version \ No newline at end of file diff --git a/lib/init/init.ts b/lib/init/init.ts index 321a38c..a0ecd87 100644 --- a/lib/init/init.ts +++ b/lib/init/init.ts @@ -1,11 +1,10 @@ import { doesConfigFileExists, isReactOrNextInstalled, log } from '../utils'; -import { filewalker } from '../utils/path.utils'; import { quitPrompt } from '../utils/prompt.utils'; import { checkConfigFilePrompt, triggerPromptOption } from './prompt.init'; export async function runInit() { - if (!isReactOrNextInstalled()) { + if (!isReactOrNextInstalled() && process.env.NODE_ENV !== 'development') { return log('No React or Next.js project could be found in your dependencies, please install one of theme before going further'); } if (doesConfigFileExists()) { @@ -13,7 +12,6 @@ export async function runInit() { if (overwriteResponse.overwrite) { triggerPromptOption(); } else { - // TODO: Add some cool emojis :D log('Goodbye !'); quitPrompt(); } diff --git a/lib/init/prompt.init.ts b/lib/init/prompt.init.ts index b970afe..5a58305 100644 --- a/lib/init/prompt.init.ts +++ b/lib/init/prompt.init.ts @@ -1,6 +1,6 @@ import inquirer from 'inquirer'; import path from 'path'; -import { findDependenciesFromJsonPackage, sanitizePath, writeJsonConfigFile } from '../utils'; +import { findDependenciesFromJsonPackage, removeLeadingSlashes, writeJsonConfigFile } from '../utils'; import { formatResponseObjectToConfigFile } from '../utils/config.utils'; import { IPromptResponse } from '../types'; @@ -98,7 +98,7 @@ async function buildConfig(promptResponse: IPromptResponse) { name: 'overwrite', message() { return `Here is what your component folder will look like, but you will always have the option to select only those that you need ! Does that suit you ? - ./${sanitizePath(componentEntryPoint)}/ + ./${removeLeadingSlashes(componentEntryPoint)}/ - ${BaseComponentName}${componentFileNameExtension === 'none' ? componentFileExtension : componentFileNameExtension} (Component) - ${BaseComponentName}.props${deductedFileExtension} (Props) - ${BaseComponentName}${styleSheetFileSuffixExtension === 'none' ? styleSheetFileExtension : styleSheetFileSuffixExtension} (Style) diff --git a/lib/utils/fileSystem.utils.ts b/lib/utils/fileSystem.utils.ts index 5f27ac0..b39ab34 100644 --- a/lib/utils/fileSystem.utils.ts +++ b/lib/utils/fileSystem.utils.ts @@ -1,7 +1,10 @@ +import { ComponentNameTemplate } from '../constants/template'; import fs from 'fs'; import path from 'path'; import { IConfigObject } from '../types'; +import { getFullFileNames } from './config.utils'; import { log } from './log.utils'; +import { sanitizeConfigPaths } from './sanitize.utils'; /** * Create a config file filled with prompt user response @@ -45,8 +48,9 @@ function createDirIfNotExist(path: string): void { * @param path * @param content The content we want to populate the new file with */ -function buildFile(path: string, content: string) { - fs.writeFile(path, content, err => { +function writeFile(path: string, fileName: string, content: string) { + createDirIfNotExist(path); + fs.writeFile(`${path}/${fileName}`, content, err => { if (err) { console.error(err); } @@ -111,7 +115,18 @@ function doesFileExists(componentName: string, componentDir: string) { return dir.includes(componentName) } +function createFiles(config: IConfigObject, componentName: string, responseTypes: any[]) { + const { componentEntryPoint } = config; + for (const [key, aConfig] of Object.entries(sanitizeConfigPaths(config, componentName))) { + const FILE_NAMES = getFullFileNames(config, componentName); + const PATH_TO_CREATE_IF_NOT_EXIST = aConfig.path?.replace(ComponentNameTemplate, componentName) || `${componentEntryPoint}/${componentName}`; + const FILE_NAME = FILE_NAMES[key]; + if (!responseTypes.includes(key)) continue; + writeFile(`${PATH_TO_CREATE_IF_NOT_EXIST}`, FILE_NAME, ''); + } +} + export { - createDirIfNotExist, buildFile, readTemplateFile, getProjectDependencies, writeJsonConfigFile, doesConfigFileExists, isReactOrNextInstalled, - findDependenciesFromJsonPackage, doesFileExists + createDirIfNotExist, writeFile, readTemplateFile, getProjectDependencies, writeJsonConfigFile, doesConfigFileExists, isReactOrNextInstalled, + findDependenciesFromJsonPackage, doesFileExists, createFiles }; \ No newline at end of file diff --git a/lib/utils/path.utils.ts b/lib/utils/path.utils.ts index 069c1ed..55df6fa 100644 --- a/lib/utils/path.utils.ts +++ b/lib/utils/path.utils.ts @@ -1,33 +1,40 @@ -const fs = require('fs'); -const path = require('path'); -const FILE_NAMES = ['Button.component.tsx', -'Button.spec.tsx', -'Button.style.css'] +import * as path from 'path'; +import * as fs from 'fs'; + /** - * Explores recursively a directory and returns all the filepaths and folderpaths in the callback. - * - * @see http://stackoverflow.com/a/5827895/4241030 - * @param {String} dir + * Return the relative path of a file (to) compared with file of reference (from) + * @param from file of reference + * @param to file to find the relative path + * @returns a path */ -export function filewalker(dir: any) { - const RESULTS: string[] = [] - fs.readdir(dir, {}, function (_: any, list: any) { - list - .filter((folder: string) => folder !== 'node_modules' && folder !== '.git') - .forEach(function (file: any) { - if(FILE_NAMES.includes(file)) { - RESULTS.push(path.resolve(dir, file)) - console.log(path.resolve(dir, file)) +export function findRelativePath(from: string, to: string): string { + const findFile = (dir: string, fileName: string): string => { + if (path.basename(dir) === 'node_modules') { + return ''; } - if(FILE_NAMES.length === RESULTS.length) return RESULTS - file = path.resolve(dir, file); - fs.stat(file, function (err: any, stat: any) { - // If directory, execute a recursive call - if (stat && stat.isDirectory()) { - filewalker(file); - } - }); - }); - return RESULTS; - }); -}; \ No newline at end of file + + const files = fs.readdirSync(dir); + for (const file of files) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + if (stat.isDirectory()) { + const result = findFile(filePath, fileName); + if (result) { + return result; + } + } else if (file === fileName) { + return filePath; + } + } + return ''; + }; + + const fromPath = findFile(process.cwd(), from); + const toPath = findFile(process.cwd(), to); + return path.relative(path.dirname(fromPath), path.dirname(toPath)); +} + +// Generate a full path +export function generateFullPath(from: string, to: string) { + return `${findRelativePath(from, to).replace(/\\/g, '/')}/${to}` +} \ No newline at end of file diff --git a/lib/utils/sanitize.utils.ts b/lib/utils/sanitize.utils.ts index e4010d5..d3787ed 100644 --- a/lib/utils/sanitize.utils.ts +++ b/lib/utils/sanitize.utils.ts @@ -4,16 +4,12 @@ import { IConfigObject } from '../types'; /** * Remove ./ or / at the begining of the path and / at the end of the path - * e.g ./components/Button/ => components/Button + * e.g "./components/Button/" => "components/Button" * @param path * @returns {string} */ -function sanitizePath(path: string): string { - let sanitizedPath = path; - if(path[path.length - 1] === '/') { - sanitizedPath = path.slice(0, -1); - } - return sanitizedPath.replace(PathPolicyRegex, ''); +function removeLeadingSlashes(path: string): string { + return path.replace(/^(\.\/|\/)+/, '').replace(/\/+$/, ''); } /** @@ -24,9 +20,9 @@ function sanitizePath(path: string): string { */ function sanitizeConfigPaths(config: IConfigObject, componentName: string) { for(const aConfig of Object.values(config)) { - if(aConfig.path) aConfig.path = sanitizePath(aConfig.path).replace(ComponentNameTemplate, componentName); + if(aConfig.path) aConfig.path = removeLeadingSlashes(aConfig.path).replace(ComponentNameTemplate, componentName); } return config; } -export { sanitizeConfigPaths, sanitizePath} \ No newline at end of file +export { sanitizeConfigPaths, removeLeadingSlashes} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3b550c2..db17e35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "rfsb", - "version": "1.0.0", + "name": "react-component-files-generator", + "version": "1.1.3", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "rfsb", - "version": "1.0.0", + "name": "react-component-files-generator", + "version": "1.1.3", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -14,11 +14,13 @@ "ts-node-dev": "^2.0.0" }, "bin": { - "rfsb": "dist/index.js" + "rcfg": "dist/lib/index.js" }, "devDependencies": { "@types/inquirer": "^9.0.3", "@types/node": "^18.11.9", + "cross-env": "^7.0.3", + "react-component-files-generator": "^1.0.8", "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.9.3" @@ -383,6 +385,38 @@ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -678,6 +712,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -826,6 +866,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -842,6 +891,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/react-component-files-generator": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/react-component-files-generator/-/react-component-files-generator-1.0.8.tgz", + "integrity": "sha512-VSECjnSabMluPS+5p4oODfeWfb2txas4WoPIfLRlVx1J0lw6LGjYmZVVvguQkv/4VnPzboDRYMFWTavRRZ26+Q==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "inquirer": "^8.0.0", + "ts-node-dev": "^2.0.0" + }, + "bin": { + "rcfg": "dist/lib/index.js" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -945,6 +1008,27 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -1218,6 +1302,21 @@ "defaults": "^1.0.3" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -1514,6 +1613,26 @@ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -1719,6 +1838,12 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -1819,6 +1944,12 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -1829,6 +1960,17 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, + "react-component-files-generator": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/react-component-files-generator/-/react-component-files-generator-1.0.8.tgz", + "integrity": "sha512-VSECjnSabMluPS+5p4oODfeWfb2txas4WoPIfLRlVx1J0lw6LGjYmZVVvguQkv/4VnPzboDRYMFWTavRRZ26+Q==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "inquirer": "^8.0.0", + "ts-node-dev": "^2.0.0" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1897,6 +2039,21 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -2083,6 +2240,15 @@ "defaults": "^1.0.3" } }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index f31d51d..d787184 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-component-files-generator", "description": "A CLI that helps developers generating react folder structure for your project", - "version": "1.0.8", + "version": "1.1.3", "main": "lib/index.ts", "author": "Amine Abdelli ", "keywords": [ @@ -17,8 +17,8 @@ "scripts": { "build": "rm -rf ./dist/ && tsc -p tsconfig.json && cp -r lib/templates dist/lib && npm run link", "link": "npm link && rm -rf chmod a+x /home/aabdelli/.nvm/versions/node/v18.12.1/bin/rcfg", - "dev:init": "ts-node-dev lib/index.ts --init", - "dev:build": "ts-node-dev lib/index.ts --build" + "dev:init": "cross-env NODE_ENV=development ts-node-dev lib/index.ts --init", + "dev:build": "cross-env NODE_ENV=development ts-node-dev lib/index.ts --build" }, "license": "MIT", "bin": { @@ -27,6 +27,8 @@ "devDependencies": { "@types/inquirer": "^9.0.3", "@types/node": "^18.11.9", + "cross-env": "^7.0.3", + "react-component-files-generator": "^1.0.8", "ts-node": "^10.9.1", "tsconfig-paths": "^4.1.0", "typescript": "^4.9.3"