UNPKG

rgen-cli

Version:

A developer CLI for initializing React projects, managing utilities, and scaffolding components, hooks, pages, layouts, routes, and contexts quickly.

79 lines (75 loc) 3.99 kB
import chalk from 'chalk'; import fs from 'node:fs'; import path from 'node:path'; import Build from './build.js'; export default class Context extends Build { constructor(cmd, name) { super(cmd, name, 'contexts'); } async setup() { try { await this.init(); // * Context Template const contextTemplate = `import { createContext } from 'react' ${this.typescript ? `import { type ${this.uname}ContextValue } from './types'\n` : ''} export const ${this.uname}Context = createContext${this.typescript ? `<${this.uname}ContextValue | undefined>` : ''}(undefined)\n`; // * Provider Template const providerTemplate = `import { ${this.typescript ? `type ReactNode, ` : ''}useState } from 'react' import { ${this.uname}Context } from './${this.uname}Context' ${this.typescript ? `import { type ${this.uname}ContextValue } from './types'\ninterface Props { children: ReactNode }\n` : ''} export const ${this.uname}Provider = ({ children }${this.typescript ? ': Props' : ''})${this.typescript ? ': React.JSX.Element' : ''} => { const [state, setState] = useState${this.typescript ? '<unknown>' : ''}(null) const value${this.typescript ? `: ${this.uname}ContextValue` : ''} = { state, setState } return <${this.uname}Context.Provider value={value}>{children}</${this.uname}Context.Provider> }\n`; const useTemplate = `import { useContext } from 'react' import { ${this.uname}Context } from './${this.uname}Context'${this.typescript ? `\nimport { type ${this.uname}ContextValue } from './types'` : ''} export function use${this.uname}()${this.typescript ? `: ${this.uname}ContextValue` : ''} { const context = useContext(${this.uname}Context) if (!context) { throw new Error('use${this.uname} must be used within a ${this.uname}Provider') } return context }\n`; const typeTemplate = `export interface ${this.uname}ContextValue { state: unknown setState: React.Dispatch<React.SetStateAction<unknown>> }\n`; const indexTemplate = `export * from './${this.uname}Context' export * from './${this.uname}Provider' export * from './use${this.uname}' export * from './types'\n`; const contextPath = path.join(this.baseDir, `${this.uname}Context.${this.typescript ? 'tsx' : 'jsx'}`); const providerPath = path.join(this.baseDir, `${this.uname}Provider.${this.typescript ? 'tsx' : 'jsx'}`); const usePath = path.join(this.baseDir, `use${this.uname}.${this.typescript ? 'ts' : 'js'}`); const typePath = path.join(this.baseDir, 'types.ts'); const indexPath = path.join(this.baseDir, `index.${this.typescript ? 'ts' : 'js'}`); if (fs.existsSync(usePath)) { this.cmd.error(`${chalk.blue('[X]')} Already exists! - ${chalk.blue(usePath)}`); } fs.writeFileSync(contextPath, contextTemplate); fs.writeFileSync(providerPath, providerTemplate); fs.writeFileSync(usePath, useTemplate); if (this.typescript) { fs.writeFileSync(typePath, typeTemplate); } fs.writeFileSync(indexPath, indexTemplate); this.cmd.log(`${chalk.blue('[+]')} Creating new ${this.uname}Context - ${chalk.blue(contextPath)}`); this.cmd.log(`${chalk.blue('[+]')} Creating new ${this.uname}Provider - ${chalk.blue(providerPath)}`); this.cmd.log(`${chalk.blue('[+]')} Creating new use${this.uname} - ${chalk.blue(usePath)}`); if (this.typescript) { this.cmd.log(`${chalk.blue('[+]')} Creating new types - ${chalk.blue(typePath)}`); } this.cmd.log(`${chalk.blue('[+]')} Creating new index - ${chalk.blue(indexPath)}`); } catch (error) { if (error instanceof Error) { this.cmd.error(error); } } } }