UNPKG

lun-cli

Version:

generator react component using cli

344 lines (307 loc) 11 kB
'use strict'; const fs = require('node:fs'); const colors = require('picocolors'); const path = require('node:path'); const config_constants = require('./lun-cli.bf48af4c.cjs'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const fs__default = /*#__PURE__*/_interopDefaultCompat(fs); const colors__default = /*#__PURE__*/_interopDefaultCompat(colors); const path__default = /*#__PURE__*/_interopDefaultCompat(path); const getExt = (conditional) => { const typescriptFile = ["ts", "tsx"]; const javascriptFile = ["js", "jsx"]; const finalCond = conditional === "react-ts" ? typescriptFile : javascriptFile; return { extIndex: finalCond[0], extComponent: finalCond[1] }; }; const updateIndex = ({ path, type, newFile }) => { const indexPath = `${path}/index.${type === "react-ts" ? "ts" : "js"}`; if (!fs__default.existsSync(indexPath)) { fs__default.writeFileSync(indexPath, ""); } const data = fs__default.readFileSync(indexPath, "utf-8"); const finalText = `export { ${newFile}${type === "react-ts" ? `, type ${newFile}Props` : ""} } from './${newFile}'${type === "react-ts" ? ";" : ""}`; const newExportComponent = data.length === 0 ? finalText : `${data} ${finalText}`; fs__default.writeFileSync(indexPath, newExportComponent); }; const getRootPath = (...args) => path__default.resolve(process.cwd(), ...args); const componentWithJs = (componentName, type) => { return `import { forwardRef } from 'react' import cn from 'clsx' ${type === "module" ? `import s from './${componentName}.module.css'` : `import './${componentName}.css'`} const ${componentName} = forwardRef(({ className, chilren, ...props }, ref) => { return ( <div ref={ref} className={cn(s.container, className)} {...props}> {children} </div> ) }) export default ${componentName} `; }; const componentWithTsx = (componentName, type) => { return `import type { FC, ComponentProps } from 'react'; import cn from 'clsx'; ${type === "module" ? `import s from './${componentName}.module.css'` : `import './${componentName}.css'`} interface ${componentName}Props extends ComponentProps<'div'> { // } const ${componentName}: FC<${componentName}Props> = ({ ref, className, children, ...props }) => { return ( <div ref={ref} className={cn(s.container, className)} {...props}> {children} </div> ); }; export default ${componentName}; export type { ${componentName}Props }; `; }; const templateComponent = ({ component, type, cssType }) => { const fun = type === "react" ? componentWithJs : componentWithTsx; return fun(component, cssType); }; const templateCSS = `.container { border: 1px solid #09f; }`; const templateIndexComponent = ({ component, type }) => { if (type === "react") { return `export { default as ${component} } from './${component}' `; } return `export { default as ${component}, type ${component}Props } from './${component}'; `; }; const withJs$1 = ({ name }) => { return `export default function ${name}() { return ( <section> <h1>page: ${name}</h1> </section> ) } `; }; const indexWithJs$1 = ({ name }) => `export { default as ${name} } from './${name}'; `; const withTs$1 = ({ name }) => { return `export default function ${name}() { return ( <section> <h1>page: ${name}</h1> </section> ) } `; }; const indexWithTs$1 = ({ name }) => `export { default as ${name} } from './${name}'; `; const getTemplatePage = ({ name, type }) => { const fn = type === "react-ts" ? withTs$1 : withJs$1; return fn({ name }); }; const getTemplateIndex = ({ name, type }) => { const fn = type === "react-ts" ? indexWithTs$1 : indexWithJs$1; return fn({ name }); }; const withJs = ({ name }) => { return `import { useState, useContext, createContext } from 'react' const ${name}Context = createContext({ state: {}, setState: () => {} }) function ${name}Provider({ children }) { const [state, setState] = useState({}) return ( <${name}Context.Provider value={{ state, setState }}> {children} </${name}Context.Provider> ) } /** * export this hook in another file into hook folder. * it's a suggestion if you be using Vite with HMR (Hot Module Replace) */ const use${name} = () => useContext(${name}Context) export default ${name}Provider export { ${name}Context, use${name} } `; }; const indexWithJs = ({ name }) => { return `export { default as ${name}Provider, ${name}Context, use${name} } from './${name}'; `; }; const withTs = ({ name }) => { return `import { useState, useContext, createContext } from 'react'; interface ${name}ContextType { state: {}; setState: () => void; } const ${name}Context = createContext<${name}ContextType>({ state: {}, setState: () => {}, }); function ${name}Provider({ children }) { const [state, setState] = useState({}); return ( <${name}Context.Provider value={{ state, setState }}> {children} </${name}Context.Provider> ); } /** * export this hook in another file into hook folder. * it's a suggestion if you be using Vite with HMR (Hot Module Replace) */ const use${name} = () => useContext(${name}Context); export default ${name}Provider; export { ${name}Context, use${name} }; `; }; const indexWithTs = ({ name }) => { return `export { default as ${name}Provider, ${name}Context, use${name} } from './${name}'; `; }; const getTemplateContext = ({ name, type }) => { const fn = type === "react-ts" ? withTs : withJs; return fn({ name }); }; const getTemplateIndexContext = ({ name, type }) => { const fn = type === "react-ts" ? indexWithTs : indexWithJs; return fn({ name }); }; class Lun { options = config_constants.defaultConfig; dir = getRootPath(config_constants.defaultConfig.root); dirFolderPage = getRootPath( config_constants.defaultConfig.root, config_constants.defaultConfig.pagesFolder ); dirFolderContext = getRootPath( config_constants.defaultConfig.root, config_constants.defaultConfig.provider ); cssType = "module"; setOptions(value) { this.options = value; this.dir = getRootPath(this.options.root); this.dirFolderPage = getRootPath(this.options.root, this.options.pagesFolder); this.dirFolderContext = getRootPath(this.options.root, this.options.provider); this.cssType = this.options.css; } printCreate = ({ type, name }) => { console.log(colors__default.cyan(`[+] ${type} ${name} has created \u{1F355}`)); }; printMissing = ({ type }) => { console.log(colors__default.bgRed(`[-] you need set name to the new ${type}`)); }; getFullPathComponent = (componentName, filename) => getRootPath(this.dir, `components/${componentName}/${filename}`); getPathComponentsFolder = (folder = "") => getRootPath(this.dir, `components/${folder}`); createComponent({ componentName, type }) { if (!componentName || typeof componentName === "object") { this.printMissing({ type: "component" }); return; } const { defaultTemplate } = this.options; const typeTemplate = type ?? defaultTemplate; const fileComponent = templateComponent({ component: componentName, type: typeTemplate, cssType: this.cssType }); const fileIndex = templateIndexComponent({ component: componentName, type: typeTemplate }); const { extIndex, extComponent } = getExt(typeTemplate); const filenameComponent = `${componentName}.${extComponent}`; const filenameIndex = `index.${extIndex}`; const filenameCss = `${componentName}.module.css`; const pathComponent = this.getFullPathComponent(componentName, filenameComponent); const pathIndexComponent = this.getFullPathComponent(componentName, filenameIndex); const pathStyles = this.getFullPathComponent(componentName, filenameCss); const pathIndexFolderComponents = this.getPathComponentsFolder(); const folderComponent = this.getPathComponentsFolder(componentName); const folderBaseComponent = this.getPathComponentsFolder(); if (!fs__default.existsSync(folderBaseComponent)) fs__default.mkdirSync(folderBaseComponent); if (!fs__default.existsSync(folderComponent)) fs__default.mkdirSync(folderComponent); fs__default.writeFileSync(pathComponent, fileComponent); fs__default.writeFileSync(pathIndexComponent, fileIndex); fs__default.writeFileSync(pathStyles, templateCSS); updateIndex({ path: pathIndexFolderComponents, newFile: componentName, type: typeTemplate }); this.printCreate({ type: "component", name: componentName }); } createContext({ contextName, type }) { if (typeof contextName !== "string") { this.printMissing({ type: "context" }); return; } const { defaultTemplate } = this.options; const typeTemplate = type ?? defaultTemplate; const { extIndex, extComponent } = getExt(typeTemplate); const folderPath = this.dirFolderContext; const folderContextComponent = path__default.resolve(folderPath, contextName); const templateContext = path__default.resolve( folderContextComponent, `${contextName}.${extComponent}` ); const templateIndexContext = path__default.resolve( folderContextComponent, `index.${extIndex}` ); if (!fs__default.existsSync(folderPath)) fs__default.mkdirSync(folderPath); if (!fs__default.existsSync(folderContextComponent)) fs__default.mkdirSync(folderContextComponent); fs__default.writeFileSync( templateContext, getTemplateContext({ name: contextName, type: typeTemplate }) ); fs__default.writeFileSync( templateIndexContext, getTemplateIndexContext({ name: contextName, type: typeTemplate }) ); this.printCreate({ type: "context", name: contextName }); } createPage({ pageName, type }) { if (typeof pageName !== "string") { this.printMissing({ type: "page" }); return; } const { defaultTemplate } = this.options; const typeTemplate = type ?? defaultTemplate; const { extIndex, extComponent } = getExt(typeTemplate); const folderPath = this.dirFolderPage; const folderPageComponent = path__default.resolve(folderPath, pageName); const templatePage = path__default.resolve(folderPageComponent, `${pageName}.${extComponent}`); const templateIndexPage = path__default.resolve(folderPageComponent, `index.${extIndex}`); if (!fs__default.existsSync(folderPath)) fs__default.mkdirSync(folderPath); if (!fs__default.existsSync(folderPageComponent)) fs__default.mkdirSync(folderPageComponent); fs__default.writeFileSync( templatePage, getTemplatePage({ name: pageName, type: typeTemplate }) ); fs__default.writeFileSync( templateIndexPage, getTemplateIndex({ name: pageName, type: typeTemplate }) ); this.printCreate({ type: "page", name: pageName }); } } exports.Lun = Lun; exports.getRootPath = getRootPath;