@teispace/next-maker 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/index.js +47 -47
- package/dist/index.js.map +3 -3
- package/dist/src/core/git.d.ts +1 -1
- package/dist/src/core/git.d.ts.map +1 -1
- package/dist/src/prompts/create-app.prompt.d.ts +1 -0
- package/dist/src/prompts/create-app.prompt.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core/files.ts", "../src/config/paths.ts", "../src/services/setup/http-client/injectors.ts", "../src/index.ts", "../src/commands/app.ts", "../src/config/spinner.ts", "../src/prompts/create-app.prompt.ts", "../src/core/git.ts", "../src/core/package-manager.ts", "../src/config/output.ts", "../src/config/errorHandlers.ts", "../src/config/utils.ts", "../src/config/index.ts", "../src/services/init/template.service.ts", "../src/services/init/config.service.ts", "../src/config/packages.ts", "../src/services/init/cleanup.service.ts", "../src/services/init/providers.service.ts", "../src/services/init/devtools.service.ts", "../src/commands/feature.ts", "../src/prompts/feature.prompt.ts", "../src/services/feature/detection.service.ts", "../src/services/feature/templates.service.ts", "../src/services/feature/registration.service.ts", "../src/services/common/api-registration.service.ts", "../src/commands/slice.ts", "../src/prompts/slice.prompt.ts", "../src/services/slice/slice.service.ts", "../src/services/slice/detection.service.ts", "../src/commands/service.ts", "../src/prompts/service.prompt.ts", "../src/services/service/service.service.ts", "../src/services/service/detection.service.ts", "../src/commands/setup.ts", "../src/services/setup/dark-theme/index.ts", "../src/services/setup/dark-theme/checks.ts", "../src/services/setup/dark-theme/utils.ts", "../src/services/setup/dark-theme/assets.ts", "../src/services/setup/dark-theme/injectors.ts", "../src/services/setup/redux/index.ts", "../src/services/setup/redux/checks.ts", "../src/services/setup/redux/assets.ts", "../src/services/setup/redux/injectors.ts", "../src/services/setup/i18n/index.ts", "../src/services/setup/i18n/checks.ts", "../src/services/setup/i18n/assets.ts", "../src/services/setup/i18n/injectors.ts", "../src/services/setup/http-client/index.ts", "../src/services/setup/http-client/checks.ts", "../src/services/setup/http-client/assets.ts", "../src/commands/index.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\n\nexport const readFile = async (filePath: string): Promise<string> => {\n return fs.readFile(filePath, 'utf-8');\n};\n\nexport const writeFile = async (filePath: string, content: string): Promise<void> => {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf-8');\n};\n\nexport const copyFile = async (source: string, destination: string): Promise<void> => {\n await fs.mkdir(path.dirname(destination), { recursive: true });\n await fs.copyFile(source, destination);\n};\n\nexport const deleteFile = async (filePath: string): Promise<void> => {\n if (existsSync(filePath)) {\n await fs.unlink(filePath);\n }\n};\n\nexport const deleteDirectory = async (dirPath: string): Promise<void> => {\n if (existsSync(dirPath)) {\n await fs.rm(dirPath, { recursive: true, force: true });\n }\n};\n\nexport const updateJson = async <T = any>(\n filePath: string,\n update: (json: T) => T,\n): Promise<void> => {\n const content = await readFile(filePath);\n const json = JSON.parse(content) as T;\n const updatedJson = update(json);\n await writeFile(filePath, JSON.stringify(updatedJson, null, 2));\n};\n\nexport const fileExists = (filePath: string): boolean => {\n return existsSync(filePath);\n};\n", "export const PROJECT_PATHS = {\n // Config\n NEXT_CONFIG: 'next.config.ts',\n TAILWIND_CONFIG: 'tailwind.config.ts',\n POSTCSS_CONFIG: 'postcss.config.mjs',\n ESLINT_CONFIG: 'eslint.config.mjs',\n TS_CONFIG: 'tsconfig.json',\n PACKAGE_JSON: 'package.json',\n ENV_EXAMPLE: '.env.example',\n GITIGNORE: '.gitignore',\n README: 'README.md',\n LICENSE: 'LICENSE',\n CHANGELOG: 'CHANGELOG.md',\n NVM_RC: '.nvmrc',\n NPM_RC: '.npmrc',\n\n // Source\n SRC: 'src',\n APP: 'src/app',\n COMPONENTS: 'src/components',\n LIB: 'src/lib',\n PROVIDERS: 'src/providers',\n STYLES: 'src/styles',\n TYPES: 'src/types',\n UTILS: 'src/lib/utils',\n HOOKS: 'src/hooks',\n SERVICES: 'src/services',\n STORE: 'src/store',\n I18N: 'src/i18n',\n\n // Specific Files\n GLOBALS_CSS: 'src/styles/globals.css',\n ROOT_LAYOUT: 'src/app/layout.tsx',\n ROOT_PAGE: 'src/app/page.tsx',\n ROOT_PROVIDER: 'src/providers/RootProvider.tsx',\n PROVIDERS_INDEX: 'src/providers/index.ts',\n COMPONENTS_INDEX: 'src/components/index.ts',\n TYPES_INDEX: 'src/types/index.ts',\n UTILS_INDEX: 'src/lib/utils/index.ts',\n CONFIG_INDEX: 'src/lib/config/index.ts',\n CONSTANTS: 'src/lib/config/constants.ts',\n APP_LOCALES: 'src/lib/config/app-locales.ts',\n MIDDLEWARE: 'src/middleware.ts',\n PROXY: 'src/proxy.ts',\n I18N_TYPES: 'src/types/i18n.ts',\n\n // Directories to Cleanup\n HTTP_UTILS: 'src/lib/utils/http',\n AXIOS_CLIENT: 'src/lib/utils/http/axios-client',\n FETCH_CLIENT: 'src/lib/utils/http/fetch-client',\n AXIOS_CLIENT_FILE: 'src/lib/utils/http/axios-client/index.ts',\n FETCH_CLIENT_FILE: 'src/lib/utils/http/fetch-client/index.ts',\n CLIENT_UTILS: 'src/lib/utils/http/client-utils.ts',\n APP_APIS: 'src/lib/config/app-apis.ts',\n STORAGE_SERVICE: 'src/services/storage',\n COUNTER_FEATURE: 'src/features/counter',\n I18N_DIR: 'src/i18n',\n LOCALE_DIR: 'src/app/[locale]',\n ERRORS_DIR: 'src/lib/errors',\n UTILITY_TYPES_DIR: 'src/types/utility',\n COMMON_TYPES_DIR: 'src/types/common',\n HTTP_TYPES: 'src/types/common/http.types.ts',\n GITHUB_DIR: '.github',\n HUSKY_DIR: '.husky',\n STORE_PROVIDER: 'src/providers/StoreProvider.tsx',\n THEME_PROVIDER: 'src/providers/CustomThemeProvider.tsx',\n COUNTER_COMPONENT: 'src/features/counter/components/Counter.tsx',\n LOCALE_PAGE: 'src/app/[locale]/page.tsx',\n\n // Config files\n COMMITLINT_CONFIG: 'commitlint.config.mjs',\n LINTSTAGED_RC: '.lintstagedrc.mjs',\n CZRC: '.czrc',\n DOCKERIGNORE: '.dockerignore',\n DOCKERFILE: 'Dockerfile',\n DOCKER_COMPOSE: 'docker-compose.yml',\n\n // GitHub\n GITHUB_WORKFLOWS: '.github/workflows',\n GITHUB_ISSUE_TEMPLATE: 'ISSUE_TEMPLATE',\n GITHUB_PR_TEMPLATE: 'PULL_REQUEST_TEMPLATE.md',\n\n // Community files\n CODE_OF_CONDUCT: 'CODE_OF_CONDUCT.md',\n CONTRIBUTING: 'CONTRIBUTING.md',\n SECURITY: 'SECURITY.md',\n} as const;\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const updateHttpIndex = async (\n projectPath: string,\n clients: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpIndexPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS, 'index.ts');\n if (fileExists(httpIndexPath)) {\n let content = await readFile(httpIndexPath);\n\n // Remove all client exports first\n content = content.replace(/export .* from '\\.\\/axios-client';?\\n?/g, '');\n content = content.replace(/export .* from '\\.\\/fetch-client';?\\n?/g, '');\n\n // Add exports for active clients\n if (clients.includes('fetch') && !content.includes('fetch-client')) {\n content += \"export * from './fetch-client';\\n\";\n }\n if (clients.includes('axios') && !content.includes('axios-client')) {\n content += \"export * from './axios-client';\\n\";\n }\n\n await writeFile(httpIndexPath, content);\n }\n};\n\nexport const updateUtilsIndex = async (projectPath: string): Promise<void> => {\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n if (!content.includes('./http')) {\n content += \"export * from './http';\\n\";\n await writeFile(utilsIndexPath, content);\n }\n }\n};\n\nexport const updateTypesIndex = async (projectPath: string): Promise<void> => {\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n if (!content.includes('./common')) {\n content += \"export * from './common';\\n\";\n }\n if (!content.includes('./utility')) {\n content += \"export * from './utility';\\n\";\n }\n await writeFile(typesIndexPath, content);\n }\n};\n\nexport const updateConfigIndex = async (projectPath: string): Promise<void> => {\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n if (!content.includes('./app-apis')) {\n content += \"export * from './app-apis';\\n\";\n await writeFile(configIndexPath, content);\n }\n }\n};\n\nexport const cleanupHttpTypes = async (\n projectPath: string,\n clients: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let content = await readFile(httpTypesPath);\n\n // If axios is NOT in clients, remove the axios module declaration\n if (!clients.includes('axios')) {\n // Remove declare module 'axios' { ... } block\n // Matches: declare module 'axios' { export interface AxiosRequestConfig { ... } }\n content = content.replace(\n /declare module 'axios'\\s*\\{\\s*export interface AxiosRequestConfig\\s*\\{[\\s\\S]*?\\}\\s*\\}/g,\n '',\n );\n // Clean up any double newlines left behind\n content = content.replace(/\\n\\s*\\n/g, '\\n\\n').trim() + '\\n';\n await writeFile(httpTypesPath, content);\n }\n }\n};\n\n/**\n * Migrate all HTTP client import and usage patterns when replacing one client with another\n * Example: fetch -> axios will replace all fetchClient imports/usages with axiosClient\n */\nexport const migrateClientUsages = async (\n projectPath: string,\n fromClient: 'fetch' | 'axios',\n toClient: 'fetch' | 'axios',\n): Promise<void> => {\n if (fromClient === toClient) return;\n\n const fromName = fromClient === 'fetch' ? 'fetchClient' : 'axiosClient';\n const toName = toClient === 'fetch' ? 'fetchClient' : 'axiosClient';\n const fromPath = fromClient === 'fetch' ? 'fetch-client' : 'axios-client';\n const toPath = toClient === 'fetch' ? 'fetch-client' : 'axios-client';\n\n // Find all .ts and .tsx files in src directory\n const srcPath = path.join(projectPath, 'src');\n\n try {\n // Use grep to find files with HTTP client imports\n const grepCommand = `grep -rl \"${fromName}\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n // No files found with the client name\n return;\n }\n\n const filePaths = stdout\n .trim()\n .split('\\n')\n .filter((f) => f);\n\n for (const filePath of filePaths) {\n if (!fileExists(filePath)) continue;\n\n let content = await readFile(filePath);\n let modified = false;\n\n // Replace import statements\n // Pattern 1: import { fetchClient } from '@/lib/http'\n const namedImportRegex = new RegExp(\n `(import\\\\s*\\\\{[^}]*?)\\\\b${fromName}\\\\b([^}]*?\\\\}\\\\s*from\\\\s*['\"][^'\"]*?/http['\"])`,\n 'g',\n );\n if (namedImportRegex.test(content)) {\n content = content.replace(namedImportRegex, `$1${toName}$2`);\n modified = true;\n }\n\n // Pattern 2: import fetchClient from '@/lib/http/fetch-client'\n const defaultImportRegex = new RegExp(\n `import\\\\s+${fromName}\\\\s+from\\\\s+['\"]([^'\"]*?)/${fromPath}['\"]`,\n 'g',\n );\n if (defaultImportRegex.test(content)) {\n content = content.replace(defaultImportRegex, `import ${toName} from '$1/${toPath}'`);\n modified = true;\n }\n\n // Pattern 3: Replace all usage instances (e.g., fetchClient.get -> axiosClient.get)\n const usageRegex = new RegExp(`\\\\b${fromName}\\\\b(?=\\\\.)`, 'g');\n if (usageRegex.test(content)) {\n content = content.replace(usageRegex, toName);\n modified = true;\n }\n\n // Pattern 4: Replace standalone references (e.g., const api = fetchClient)\n const standaloneRegex = new RegExp(`\\\\b${fromName}\\\\b(?![.\\\\w])`, 'g');\n if (standaloneRegex.test(content)) {\n content = content.replace(standaloneRegex, toName);\n modified = true;\n }\n\n if (modified) {\n await writeFile(filePath, content);\n }\n }\n } catch (error) {\n // If grep fails or no matches found, silently continue\n console.warn('Warning: Could not scan for HTTP client usages:', error);\n }\n};\n\nexport const removeHttpExports = async (projectPath: string): Promise<void> => {\n // 1. Remove from utils/index.ts\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/http['\"];?.*$/gm, '');\n await writeFile(utilsIndexPath, content);\n }\n\n // 2. Remove from types/index.ts\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n\n // Check common types\n const commonTypesDir = path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR);\n if (!fileExists(commonTypesDir)) {\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/common['\"];?.*$/gm, '');\n } else {\n // If directory exists, check if we need to remove http.types export from common/index.ts\n const commonIndexPath = path.join(commonTypesDir, 'index.ts');\n if (fileExists(commonIndexPath)) {\n let commonContent = await readFile(commonIndexPath);\n commonContent = commonContent.replace(\n /^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/http\\.types['\"];?.*$/gm,\n '',\n );\n await writeFile(commonIndexPath, commonContent);\n }\n }\n\n // Check utility types\n if (!fileExists(path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR))) {\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/utility['\"];?.*$/gm, '');\n }\n await writeFile(typesIndexPath, content);\n }\n\n // 3. Remove from config/index.ts - Handled by performFullCleanup smart deletion\n // We don't blindly remove it here anymore because app-apis might be kept if used elsewhere.\n};\n\n/**\n * Check if a file or module is used in the project\n * @param projectPath Root project path\n * @param importPath Import path to search for (e.g., '@/lib/config/app-apis' or 'app-apis')\n * @param excludePaths Array of absolute paths to exclude from search results\n */\nexport const isFileUsed = async (\n projectPath: string,\n importPath: string,\n excludePaths: string[] = [],\n): Promise<boolean> => {\n const srcPath = path.join(projectPath, 'src');\n\n // Escape special characters in import path for grep\n const escapedImportPath = importPath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Search for the import string\n // We look for:\n // 1. from '...importPath...'\n // 2. from \"...importPath...\"\n const grepCommand = `grep -r \"from ['\\\\\"].*${escapedImportPath}.*['\\\\\"]\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n\n try {\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n return false;\n }\n\n const matches = stdout.trim().split('\\n');\n\n // Filter out matches from excluded files\n const validMatches = matches.filter((match) => {\n const [filePath] = match.split(':');\n // Check if file path is in excluded paths\n // We need to resolve relative paths from grep output if necessary,\n // but grep usually outputs full or relative to cwd.\n // Assuming grep runs from cwd, output is relative.\n const absoluteMatchPath = path.resolve(projectPath, filePath);\n\n return !excludePaths.some((exclude) => {\n // Simple check: is the match file the excluded file?\n if (absoluteMatchPath === exclude) return true;\n // Is the match file inside an excluded directory?\n if (absoluteMatchPath.startsWith(exclude + path.sep)) return true;\n return false;\n });\n });\n\n return validMatches.length > 0;\n } catch (error) {\n console.warn(`Warning: Failed to check usage for ${importPath}:`, error);\n // If check fails, assume used to be safe\n return true;\n }\n};\n\n/**\n * Check if a specific string (symbol, class name, etc.) is present in the project files\n * @param projectPath Root project path\n * @param searchString String to search for\n * @param excludePaths Array of absolute paths to exclude from search results\n */\nexport const isStringUsed = async (\n projectPath: string,\n searchString: string,\n excludePaths: string[] = [],\n): Promise<boolean> => {\n const srcPath = path.join(projectPath, 'src');\n\n // Escape special characters\n const escapedString = searchString.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Search for the string anywhere in the files\n // We use -w to match whole words if possible, but for imports it might be part of braces\n // Let's just search for the string.\n const grepCommand = `grep -r \"${escapedString}\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n\n try {\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n return false;\n }\n\n const matches = stdout.trim().split('\\n');\n\n // Filter out matches from excluded files\n const validMatches = matches.filter((match) => {\n const [filePath] = match.split(':');\n const absoluteMatchPath = path.resolve(projectPath, filePath);\n\n return !excludePaths.some((exclude) => {\n if (absoluteMatchPath === exclude) return true;\n if (absoluteMatchPath.startsWith(exclude + path.sep)) return true;\n return false;\n });\n });\n\n return validMatches.length > 0;\n } catch (error) {\n console.warn(`Warning: Failed to check usage for string ${searchString}:`, error);\n return true;\n }\n};\n", "import { Command } from 'commander';\nimport { registerCommands } from './commands/index';\nimport { error, setupCancellationHandlers } from './config';\n\n// Suppress the annoying enquirer localstorage warning\n/* eslint-disable @typescript-eslint/no-unused-vars, prefer-rest-params */\nconst originalEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, _type?: any, _code?: any, _ctor?: any) {\n if (\n typeof warning === 'string' &&\n warning.includes('--localstorage-file') &&\n warning.includes('was provided without a valid path')\n ) {\n return; // Suppress this specific warning\n }\n // @ts-expect-error - calling with variable arguments\n return originalEmitWarning.apply(process, arguments);\n};\n/* eslint-enable @typescript-eslint/no-unused-vars, prefer-rest-params */\n\nasync function main() {\n setupCancellationHandlers({ logger: (m: string) => error(m) });\n\n const program = new Command();\n\n program.name('next-maker').description('Teispace Next.js Project Generator').version('1.0.0');\n\n registerCommands(program);\n\n program.parse();\n}\n\nmain().catch((err) => {\n const message =\n err && typeof err === 'object' && 'message' in err ? (err as Error).message : String(err);\n error(`Unexpected error: ${message}`);\n});\n", "import { Command } from 'commander';\nimport path from 'node:path';\nimport pc from 'picocolors';\nimport { startSpinner } from '../config/spinner';\nimport { promptForProjectDetails } from '../prompts/create-app.prompt';\nimport { deleteDirectory, fileExists } from '../core/files';\nimport { initializeGit } from '../core/git';\nimport { installDependencies, runScript } from '../core/package-manager';\nimport { log, printBanner } from '../config';\nimport { cloneTemplate } from '../services/init/template.service';\nimport { configurePackageJson } from '../services/init/config.service';\nimport { cleanupFeatures } from '../services/init/cleanup.service';\nimport { generateRootProvider, generateLayout } from '../services/init/providers.service';\nimport { setupDevTools } from '../services/init/devtools.service';\n\nexport const registerAppCommand = (program: Command) => {\n program\n .command('init')\n .description('Initialize a new Next.js project')\n .argument('[name]', 'Project name')\n .action(async (name) => {\n await createApp(name);\n });\n};\n\nconst createApp = async (initialName?: string): Promise<void> => {\n printBanner();\n log('Welcome to the Teispace Next.js App Creator!');\n log('');\n\n const answers = await promptForProjectDetails(initialName);\n const projectPath = path.resolve(process.cwd(), answers.projectName);\n\n if (fileExists(projectPath)) {\n console.error(pc.red(`Error: Directory ${answers.projectName} already exists.`));\n process.exit(1);\n }\n\n const spinner = startSpinner('Initializing project...');\n\n // Cleanup helper\n const performCleanup = async () => {\n if (fileExists(projectPath)) {\n spinner.stop(); // Stop spinner if running\n console.log(pc.yellow(`\\nCleaning up: Deleting directory ${answers.projectName}...`));\n try {\n await deleteDirectory(projectPath);\n console.log(pc.green('Cleanup successful.'));\n } catch (cleanupErr) {\n console.error(pc.red(`Failed to clean up directory ${answers.projectName}:`), cleanupErr);\n }\n }\n };\n\n // Signal handler\n const handleSignal = async () => {\n console.log(pc.red('\\nProcess interrupted. Cleaning up...'));\n await performCleanup();\n process.exit(1);\n };\n\n // Register signal listeners\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n try {\n // 1. Clone template\n await cloneTemplate(projectPath);\n\n // 2. Update package.json\n await configurePackageJson(projectPath, answers);\n\n // 3. Customize Features (Cleanup)\n await cleanupFeatures(projectPath, answers);\n\n // 4. Generate Code (Providers, Layout)\n spinner.text = 'Generating code...';\n await generateRootProvider(projectPath, answers);\n await generateLayout(projectPath, answers);\n\n // 5. Setup DevTools & Community Files\n spinner.text = 'Setting up developer tools...';\n await setupDevTools(projectPath, answers);\n\n // 6. Initialize Git\n spinner.text = 'Initializing Git...';\n // Pass gitRemote to initialize git with remote if provided\n await initializeGit(projectPath, answers.gitRemote);\n\n // 7. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installDependencies(projectPath, answers.packageManager);\n\n // 8. Format and Lint\n spinner.text = 'Formatting and Linting...';\n await runScript(projectPath, answers.packageManager, 'format');\n await runScript(projectPath, answers.packageManager, 'lint:fix');\n\n // 9. Copy .env.example to .env if requested\n if (answers.copyEnv) {\n spinner.text = 'Creating .env file...';\n const envExamplePath = path.join(projectPath, '.env.example');\n const envPath = path.join(projectPath, '.env');\n if (fileExists(envExamplePath)) {\n const fs = await import('node:fs/promises');\n await fs.copyFile(envExamplePath, envPath);\n }\n }\n\n // Remove signal listeners on success\n process.off('SIGINT', handleSignal);\n process.off('SIGTERM', handleSignal);\n\n spinner.succeed(pc.green(`Project ${answers.projectName} created successfully!`));\n log('');\n log('To get started:');\n log(pc.cyan(` cd ${answers.projectName}`));\n log(\n pc.cyan(\n ` ${answers.packageManager === 'npm' ? 'npm run dev' : answers.packageManager + ' dev'}`,\n ),\n );\n log('');\n } catch (err) {\n spinner.fail('Failed to create project.');\n console.error(err);\n await performCleanup();\n process.exit(1);\n }\n};\n", "import ora, { Ora, Options } from 'ora';\n\n// Create and start a spinner\nexport function startSpinner(text = '', options?: Options): Ora {\n const spinner = ora({ text, ...options });\n spinner.start();\n return spinner;\n}\n\n// Stop a spinner without changing its status\nexport function stopSpinner(spinner: Ora): void {\n spinner.stop();\n}\n\n// Mark spinner as succeeded\nexport function succeedSpinner(spinner: Ora, text?: string): void {\n spinner.succeed(text);\n}\n\n// Mark spinner as failed\nexport function failSpinner(spinner: Ora, text?: string): void {\n spinner.fail(text);\n}\n\n// Run an async function while showing a spinner; auto-succeed/fail\nexport async function withSpinner<T>(\n text: string,\n fn: () => Promise<T>,\n {\n successText,\n failText,\n options,\n }: { successText?: string; failText?: string; options?: Options } = {},\n): Promise<T> {\n const spinner = startSpinner(text, options);\n try {\n const result = await fn();\n spinner.succeed(successText ?? 'Done');\n return result;\n } catch (err) {\n spinner.fail(failText ?? 'Failed');\n throw err;\n }\n}\n\nexport default startSpinner;\n", "import Enquirer from 'enquirer';\nimport { PackageManager } from '../core/package-manager';\n\nconst { prompt } = Enquirer;\n\ntype PromptContext = {\n state?: { answers?: Partial<ProjectPrompts> };\n enquirer?: { answers?: Partial<ProjectPrompts> };\n};\n\nexport interface ProjectPrompts {\n projectName: string;\n description: string;\n author: string;\n version: string;\n packageManager: PackageManager;\n gitRemote: string;\n gitIssues: string;\n gitHomepage: string;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n reactSecureStorage?: boolean;\n email: string;\n company: string;\n keepTemplates: boolean;\n darkMode: boolean;\n redux: boolean;\n i18n: boolean;\n communityFiles: string[];\n readme: boolean;\n docker: boolean;\n containerName?: string;\n imageName?: string;\n imageTag?: string;\n ci: boolean;\n preCommitHooks: boolean;\n commitizen: boolean;\n copyEnv: boolean;\n}\n\nexport const promptForProjectDetails = async (initialName?: string): Promise<ProjectPrompts> => {\n const response = await prompt<ProjectPrompts>([\n {\n type: 'input',\n name: 'projectName',\n message: 'What is the project name?',\n initial: initialName || 'my-app',\n skip: !!initialName,\n validate: (value: string) => {\n if (!/^[a-z0-9-_]+$/.test(value)) {\n return 'Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores.';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'description',\n message: 'Project description:',\n initial: 'A Next.js application',\n },\n {\n type: 'input',\n name: 'author',\n message: 'Author:',\n initial: 'Teispace',\n },\n {\n type: 'input',\n name: 'version',\n message: 'Version:',\n initial: '0.1.0',\n validate: (value: string) => {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(value)) {\n return 'Version must be a valid semantic version (x.y.z).';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'email',\n message: 'Support email:',\n initial: 'support@example.com',\n validate: (value: string) => {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n return 'Please enter a valid email address.';\n }\n return true;\n },\n },\n {\n type: 'select',\n name: 'packageManager',\n message: 'Which package manager would you like to use?',\n choices: ['npm', 'yarn', 'pnpm', 'bun'],\n initial: 1,\n },\n {\n type: 'input',\n name: 'gitRemote',\n message: 'GitHub repository URL (optional):',\n validate: (value: string) => {\n if (!value) return true;\n // GitHub URL patterns: https://github.com/user/repo or git@github.com:user/repo.git\n const httpsPattern = /^https:\\/\\/github\\.com\\/[\\w-]+\\/[\\w.-]+$/;\n const sshPattern = /^git@github\\.com:[\\w-]+\\/[\\w.-]+\\.git$/;\n if (!httpsPattern.test(value) && !sshPattern.test(value)) {\n return 'Please enter a valid GitHub repository URL (e.g., https://github.com/user/repo)';\n }\n return true;\n },\n },\n {\n type: 'confirm',\n name: 'keepTemplates',\n message: 'Do you want to keep GitHub issue and pull request templates?',\n initial: false,\n },\n {\n type: 'select',\n name: 'httpClient',\n message: 'Which HTTP client do you want to use?',\n choices: ['axios', 'fetch', 'both', 'none'],\n initial: 1,\n },\n {\n type: 'confirm',\n name: 'reactSecureStorage',\n message: 'Do you want to include react-secure-storage?',\n initial: true,\n skip: function (this: PromptContext) {\n // Access answers from the prompt instance safely across versions\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n // If HTTP client is selected (not 'none'), we skip this question (it will be auto-included)\n return !!(answers.httpClient && answers.httpClient !== 'none');\n },\n },\n {\n type: 'confirm',\n name: 'darkMode',\n message: 'Do you want to include Dark Mode (Tailwind + next-themes)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'redux',\n message: 'Do you want to include Redux Toolkit?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'i18n',\n message: 'Do you want to include Internationalization (next-intl)?',\n initial: true,\n },\n {\n type: 'multiselect',\n name: 'communityFiles',\n message: 'Select community files to include:',\n choices: [\n { name: 'CODE_OF_CONDUCT.md', value: 'CODE_OF_CONDUCT.md' },\n { name: 'CONTRIBUTING.md', value: 'CONTRIBUTING.md' },\n { name: 'SECURITY.md', value: 'SECURITY.md' },\n ],\n initial: [],\n },\n {\n type: 'confirm',\n name: 'readme',\n message: 'Do you want to create a README.md?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'docker',\n message: 'Do you want to include Docker configuration?',\n initial: false,\n },\n {\n type: 'input',\n name: 'containerName',\n message: 'Docker Container Name:',\n initial: 'next-app',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(value)) {\n return 'Invalid Docker container name.';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'imageName',\n message: 'Docker Image Name:',\n initial: 'nextjs-starter',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(value)) {\n return 'Invalid Docker image name (must be lowercase).';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'imageTag',\n message: 'Docker Image Tag:',\n initial: 'latest',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(value)) {\n return 'Invalid Docker image tag.';\n }\n return true;\n },\n },\n {\n type: 'confirm',\n name: 'ci',\n message: 'Do you want to include GitHub Actions (CI/CD)?',\n initial: false,\n },\n {\n type: 'confirm',\n name: 'preCommitHooks',\n message: 'Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'commitizen',\n message: 'Do you want to setup Commitizen?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'copyEnv',\n message: 'Want to copy .env.example to .env?',\n initial: true,\n },\n ] as any);\n\n // Set company to be the same as author\n response.company = response.author;\n\n // Generate git URLs from gitRemote if provided\n if (response.gitRemote && !response.gitHomepage) {\n const baseUrl = response.gitRemote\n .replace('git@github.com:', 'https://github.com/')\n .replace(/\\.git$/, '');\n response.gitHomepage = `${baseUrl}#readme`;\n response.gitIssues = `${baseUrl}/issues`;\n }\n\n return response;\n};\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const initializeGit = async (cwd: string, gitRemote?: string): Promise<void> => {\n try {\n // Initialize git repository\n await execAsync('git init', { cwd });\n await execAsync('git add .', { cwd });\n await execAsync('git commit -m \"Initial commit from @teispace/next-maker\"', { cwd });\n\n // Add remote origin if GitHub URL is provided\n if (gitRemote) {\n await execAsync(`git remote add origin ${gitRemote}`, { cwd });\n }\n } catch (error) {\n // Ignore error if git is not installed or fails\n console.warn('Failed to initialize git repository', error);\n }\n};\n\nexport const addRemote = async (cwd: string, url: string): Promise<void> => {\n try {\n await execAsync(`git remote add origin ${url}`, { cwd });\n } catch (error) {\n console.warn('Failed to add remote origin', error);\n }\n};\n\nexport const isGitInstalled = async (): Promise<boolean> => {\n try {\n await execAsync('git --version');\n return true;\n } catch {\n return false;\n }\n};\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';\n\nexport const installDependencies = async (cwd: string, manager: PackageManager): Promise<void> => {\n const command = `${manager} install`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install dependencies with ${manager}: ${error}`);\n }\n};\n\nexport const runScript = async (\n cwd: string,\n manager: PackageManager,\n script: string,\n): Promise<void> => {\n // npm requires 'run' keyword, but yarn/pnpm/bun don't\n const command = manager === 'npm' ? `${manager} run ${script}` : `${manager} ${script}`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n // We don't want to fail the whole setup if linting fails, just warn\n console.warn(`Warning: Failed to run script '${script}': ${error}`);\n }\n};\n\nexport const getPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n if (userAgent.startsWith('yarn')) return 'yarn';\n if (userAgent.startsWith('pnpm')) return 'pnpm';\n if (userAgent.startsWith('bun')) return 'bun';\n }\n return 'npm';\n};\n\nexport const detectPackageManager = async (cwd: string): Promise<PackageManager> => {\n const { existsSync } = await import('node:fs');\n const path = await import('node:path');\n\n // Check for lock files\n if (existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\n if (existsSync(path.join(cwd, 'bun.lockb'))) return 'bun';\n if (existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\n\n // Fallback to environment variable\n return getPackageManager();\n};\n\nexport const installPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const installCommand = getInstallCommand(manager);\n const command = `${installCommand} ${packages.join(' ')}`;\n\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install packages with ${manager}: ${error}`);\n }\n};\n\nconst getInstallCommand = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return 'npm install';\n case 'yarn':\n return 'yarn add';\n case 'pnpm':\n return 'pnpm add';\n case 'bun':\n return 'bun add';\n default:\n return 'npm install';\n }\n};\n\nexport const installPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await installPackages(cwd, manager, [packageName]);\n};\n\nexport const uninstallPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const uninstallCommand = getUninstallCommand(manager);\n const command = `${uninstallCommand} ${packages.join(' ')}`;\n\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to uninstall packages with ${manager}: ${error}`);\n }\n};\n\nconst getUninstallCommand = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return 'npm uninstall';\n case 'yarn':\n return 'yarn remove';\n case 'pnpm':\n return 'pnpm remove';\n case 'bun':\n return 'bun remove';\n default:\n return 'npm uninstall';\n }\n};\n\nexport const uninstallPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await uninstallPackages(cwd, manager, [packageName]);\n};\n", "import pc from 'picocolors';\n\n// Define a type for allowed colors explicitly\nexport type Color =\n | 'reset'\n | 'red'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'cyan'\n | 'magenta'\n | 'white'\n | 'gray'\n | 'bright'\n | 'dim';\n\nconst colorMap: Record<Color, (s: string) => string> = {\n reset: (s: string) => s,\n red: pc.red,\n green: pc.green,\n yellow: pc.yellow,\n blue: pc.blue,\n cyan: pc.cyan,\n magenta: pc.magenta,\n white: pc.white,\n gray: pc.gray,\n bright: pc.bold,\n dim: pc.dim,\n};\n\n// Print with color\nexport function print(message: string, color: Color = 'reset'): void {\n const colorFn = colorMap[color] ?? ((text: string) => text);\n console.log(colorFn(message));\n}\n\n// Print section header\nexport function printHeader(title: string): void {\n console.log('');\n print('\u2550'.repeat(60), 'cyan');\n print(` ${title}`, 'bright');\n print('\u2550'.repeat(60), 'cyan');\n console.log('');\n}\n\n// Print success message\nexport function success(message: string): void {\n print(`\u2713 ${message}`, 'green');\n}\n\n// Print error message\nexport function error(message: string): void {\n print(`\u2716 ${message}`, 'red');\n}\n\n// Alias for error\nexport const logError = error;\n\n// Print warning message\nexport function warning(message: string): void {\n print(`\u26A0 ${message}`, 'yellow');\n}\n\n// Print info message\nexport function info(message: string): void {\n print(`\u2139 ${message}`, 'cyan');\n}\n\nexport function log(message: string): void {\n print(message);\n}\n\n// Print banner\nexport function printBanner(): void {\n console.log('');\n print('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557', 'cyan');\n print('\u2551 \u2551', 'cyan');\n print('\u2551 \uD83D\uDE80 Create Teispace Next.js App \uD83D\uDE80 \u2551', 'cyan');\n print('\u2551 \u2551', 'cyan');\n print('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D', 'cyan');\n console.log('');\n}\n", "export type SetupOptions = {\n logger?: (msg: string) => void;\n exitOnCancel?: boolean;\n};\n\nexport function setupCancellationHandlers(options?: SetupOptions): () => void {\n const {\n logger = (m: string) => console.error(m),\n exitOnCancel = process.env.NODE_ENV !== 'test',\n } = options ?? {};\n\n const onCancel = (): void => {\n console.log('');\n console.log('');\n logger('Setup cancelled by user');\n console.log('');\n if (exitOnCancel) process.exit(0);\n };\n\n const onUncaught = (err: unknown): void => {\n if (err !== null && typeof err === 'object' && 'code' in err) {\n const maybeErrWithCode = err as { code?: unknown };\n if (maybeErrWithCode.code === 'ERR_USE_AFTER_CLOSE') {\n onCancel();\n return;\n }\n }\n\n // Log uncaught exceptions instead of throwing so the CLI can report\n // the error and exit gracefully when appropriate.\n if (err instanceof Error) {\n logger(`Uncaught exception: ${err.message}`);\n return;\n }\n logger(`Uncaught exception: ${String(err)}`);\n };\n\n const onRejection = (reason: unknown): void => {\n // Log unhandled promise rejections rather than letting them crash the\n // process. This converts the reason to a readable string safely.\n if (reason instanceof Error) {\n logger(`Unhandled promise rejection: ${reason.message}`);\n return;\n }\n logger(`Unhandled promise rejection: ${String(reason)}`);\n };\n\n process.on('SIGINT', onCancel);\n process.on('SIGTERM', onCancel);\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection as (...args: unknown[]) => void);\n\n // Return a cleanup function to remove listeners (useful in tests).\n return (): void => {\n process.off('SIGINT', onCancel);\n process.off('SIGTERM', onCancel);\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection as (...args: unknown[]) => void);\n };\n}\n\nexport default setupCancellationHandlers;\n", "export const capitalize = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\nexport const kebabToCamel = (str: string): string => {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n};\n\nexport const kebabToPascal = (str: string): string => {\n return capitalize(kebabToCamel(str));\n};\n\nexport const camelToKebab = (str: string): string => {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n};\n", "export * from './output';\nexport * from './errorHandlers';\nexport * from './spinner';\nexport * from './utils';\n\n// Re-export spinner instance\nimport ora from 'ora';\nexport const spinner = ora();\n", "import degit from 'degit';\nimport { startSpinner } from '../../config/spinner';\n\nexport const cloneTemplate = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Downloading template...');\n try {\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: true,\n });\n await emitter.clone(projectPath);\n spinner.succeed('Template downloaded successfully.');\n } catch (error) {\n spinner.fail('Failed to download template.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport { updateJson } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { startSpinner } from '../../config/spinner';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { PACKAGES } from '../../config/packages';\n\nexport const configurePackageJson = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const spinner = startSpinner('Configuring package.json...');\n try {\n // Generate URLs from GitHub repository URL if provided\n let gitRemote = answers.gitRemote;\n let gitHomepage = answers.gitHomepage;\n let gitIssues = answers.gitIssues;\n\n if (answers.gitRemote) {\n // Convert SSH to HTTPS if needed\n if (answers.gitRemote.startsWith('git@github.com:')) {\n gitRemote = answers.gitRemote\n .replace('git@github.com:', 'https://github.com/')\n .replace(/\\.git$/, '');\n }\n\n // Generate homepage and issues URLs if not provided\n if (!gitHomepage) {\n gitHomepage = `${gitRemote.replace(/\\.git$/, '')}#readme`;\n }\n if (!gitIssues) {\n gitIssues = `${gitRemote.replace(/\\.git$/, '')}/issues`;\n }\n\n // Add .git suffix for repository URL if not present\n if (!gitRemote.endsWith('.git')) {\n gitRemote = `${gitRemote}.git`;\n }\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n pkg.name = answers.projectName;\n pkg.version = answers.version;\n pkg.description = answers.description;\n pkg.author = answers.author;\n\n // Remove packageManager field to avoid \"configured to use yarn\" errors\n // and let the user's environment handle it.\n delete pkg.packageManager;\n\n // Handle git-related fields based on whether GitHub URL was provided\n if (answers.gitRemote) {\n if (gitHomepage) pkg.homepage = gitHomepage;\n if (gitIssues) pkg.bugs = { url: gitIssues };\n if (gitRemote) pkg.repository = { type: 'git', url: gitRemote };\n } else {\n // If no GitHub URL provided, remove template's git-related fields\n delete pkg.homepage;\n delete pkg.bugs;\n delete pkg.repository;\n }\n\n // Remove dependencies based on choices\n if (!answers.redux) {\n delete pkg.dependencies[PACKAGES.REDUX_TOOLKIT];\n delete pkg.dependencies[PACKAGES.REACT_REDUX];\n delete pkg.dependencies[PACKAGES.REDUX_PERSIST];\n }\n\n // Handle react-secure-storage\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n if (!keepSecureStorage) {\n delete pkg.dependencies[PACKAGES.REACT_SECURE_STORAGE];\n }\n if (!answers.i18n) {\n delete pkg.dependencies[PACKAGES.NEXT_INTL];\n }\n if (!answers.darkMode) {\n delete pkg.dependencies[PACKAGES.NEXT_THEMES];\n }\n if (answers.httpClient === 'none') {\n delete pkg.dependencies[PACKAGES.AXIOS];\n } else if (answers.httpClient === 'fetch') {\n delete pkg.dependencies[PACKAGES.AXIOS];\n }\n\n return pkg;\n });\n spinner.succeed('package.json configured.');\n } catch (error) {\n spinner.fail('Failed to configure package.json.');\n throw error;\n }\n};\n", "export const PACKAGES = {\n // Dependencies\n REDUX_TOOLKIT: '@reduxjs/toolkit',\n REACT_REDUX: 'react-redux',\n REDUX_PERSIST: 'redux-persist',\n REACT_SECURE_STORAGE: 'react-secure-storage',\n NEXT_INTL: 'next-intl',\n NEXT_THEMES: 'next-themes',\n AXIOS: 'axios',\n\n // Dev Dependencies\n HUSKY: 'husky',\n COMMITLINT_CLI: '@commitlint/cli',\n COMMITLINT_CONFIG: '@commitlint/config-conventional',\n LINT_STAGED: 'lint-staged',\n COMMITIZEN: 'commitizen',\n CZ_CONVENTIONAL_CHANGELOG: 'cz-conventional-changelog',\n} as const;\n", "import path from 'node:path';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { startSpinner } from '../../config/spinner';\n\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { cleanupHttpTypes } from '../setup/http-client/injectors';\n\n// ... (imports)\n\nexport const cleanupFeatures = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const spinner = startSpinner('Customizing features...');\n try {\n await cleanupHttpClient(projectPath, answers);\n await cleanupSecureStorage(projectPath, answers);\n await cleanupRedux(projectPath, answers);\n await cleanupDarkMode(projectPath, answers);\n await cleanupI18n(projectPath, answers);\n await cleanupLicense(projectPath);\n await cleanupChangelog(projectPath);\n await cleanupConfig(projectPath);\n spinner.succeed('Features customized.');\n } catch (error) {\n spinner.fail('Failed to customize features.');\n throw error;\n }\n};\n\nconst cleanupHttpClient = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const httpUtilsPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS);\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n\n if (answers.httpClient === 'none') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT));\n\n if (keepSecureStorage) {\n await writeFile(path.join(httpUtilsPath, 'index.ts'), \"export * from './token-store';\\n\");\n // token-store.ts does not use client-utils, so we can remove it\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CLIENT_UTILS));\n\n // Ensure http.types.ts is clean (remove axios declaration)\n await cleanupHttpTypes(projectPath, []);\n } else {\n await deleteDirectory(httpUtilsPath);\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n content = content.replace(/export \\* from '\\.\\/http';\\n/, '');\n await writeFile(utilsIndexPath, content);\n }\n\n // Remove app-apis.ts if no client and no secure storage (likely no auth)\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_APIS));\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n content = content.replace(/export \\* from '\\.\\/app-apis';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n }\n\n // Remove API constants\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (fileExists(constantsPath)) {\n let content = await readFile(constantsPath);\n content = content.replace(/export const API_RESPONSE_DATA_KEY = 'data';\\n/, '');\n content = content.replace(/export const SAVE_AUTH_TOKENS = false;\\n/, '');\n await writeFile(constantsPath, content);\n }\n\n // Remove errors and types\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.ERRORS_DIR));\n\n // Only remove common types if we don't keep secure storage (TokenStore needs common/http.types.ts)\n if (!keepSecureStorage) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR));\n\n // Update types/index.ts\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n content = content.replace(/export \\* from '\\.\\/utility';\\n/, '');\n content = content.replace(/export \\* from '\\.\\/common';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n }\n } else if (answers.httpClient === 'axios') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT));\n let content = await readFile(path.join(httpUtilsPath, 'index.ts'));\n content = content.replace(/export .* from '\\.\\/fetch-client';\\n/g, '');\n await writeFile(path.join(httpUtilsPath, 'index.ts'), content);\n\n // Remove FetchClientOptions and ExtendedRequestInit from http.types.ts\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n // Remove FetchClientOptions interface\n typesContent = typesContent.replace(\n /export interface FetchClientOptions \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n // Remove ExtendedRequestInit interface\n typesContent = typesContent.replace(\n /export interface ExtendedRequestInit extends RequestInit \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n } else if (answers.httpClient === 'fetch') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT));\n let content = await readFile(path.join(httpUtilsPath, 'index.ts'));\n content = content.replace(/export .* from '\\.\\/axios-client';\\n/g, '');\n await writeFile(path.join(httpUtilsPath, 'index.ts'), content);\n\n // Remove axios module declaration and AxiosClientOptions from http.types.ts\n // Use the shared helper to ensure robust regex matching\n await cleanupHttpTypes(projectPath, ['fetch']);\n\n // Also remove AxiosClientOptions interface (cleanupHttpTypes only handles module declaration)\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n // Remove AxiosClientOptions interface\n typesContent = typesContent.replace(\n /export interface AxiosClientOptions \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n }\n};\n\nconst cleanupSecureStorage = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n if (!keepSecureStorage) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE));\n }\n};\n\nconst cleanupRedux = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.redux) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.STORE));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.COUNTER_FEATURE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.STORE_PROVIDER));\n\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersIndexContent = await readFile(providersIndexPath);\n providersIndexContent = providersIndexContent.replace(\n /export \\* from '\\.\\/StoreProvider';\\n/,\n '',\n );\n await writeFile(providersIndexPath, providersIndexContent);\n\n // Cleanup usage in pages\n const pagesToClean = [\n path.join(projectPath, PROJECT_PATHS.ROOT_PAGE),\n path.join(projectPath, PROJECT_PATHS.LOCALE_PAGE),\n ];\n\n for (const pagePath of pagesToClean) {\n if (fileExists(pagePath)) {\n let content = await readFile(pagePath);\n content = content.replace(\n /import\\s+\\{\\s*Counter\\s*\\}\\s+from\\s+['\"]@\\/features\\/counter['\"];\\n?/,\n '',\n );\n content = content.replace(/<Counter\\s*\\/>\\n?/g, '');\n await writeFile(pagePath, content);\n }\n }\n }\n};\n\nconst cleanupDarkMode = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.darkMode) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER));\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersIndexContent = await readFile(providersIndexPath);\n providersIndexContent = providersIndexContent.replace(\n /export \\* from '\\.\\/CustomThemeProvider';\\n/,\n '',\n );\n await writeFile(providersIndexPath, providersIndexContent);\n\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n if (fileExists(globalsCssPath)) {\n let cssContent = await readFile(globalsCssPath);\n // Remove dark mode custom variant\n cssContent = cssContent.replace(/@custom-variant dark \\(.*?\\);\\n\\n/, '');\n // Remove dark and light color definitions\n cssContent = cssContent.replace(/@theme \\{[\\s\\S]*?\\}\\n/, '');\n await writeFile(globalsCssPath, cssContent);\n }\n\n // Remove dark mode classes from layout if not using i18n\n if (!answers.i18n) {\n const layoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n if (fileExists(layoutPath)) {\n let layoutContent = await readFile(layoutPath);\n layoutContent = layoutContent.replace(/bg-light dark:bg-dark /g, '');\n await writeFile(layoutPath, layoutContent);\n }\n }\n }\n};\n\nconst cleanupI18n = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.i18n) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.I18N_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.LOCALE_DIR));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.PROXY));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.MIDDLEWARE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.I18N_TYPES));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_LOCALES));\n\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n content = content.replace(/export \\* from '\\.\\/i18n';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n content = content.replace(/export \\* from '\\.\\/app-locales';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let configContent = await readFile(nextConfigPath);\n configContent = configContent.replace(\n /import createNextIntlPlugin from 'next-intl\\/plugin';\\n/,\n '',\n );\n configContent = configContent.replace(/const withNextIntl = createNextIntlPlugin\\(\\);\\n/, '');\n configContent = configContent.replace(\n /export default withNextIntl\\(nextConfig\\);/,\n 'export default nextConfig;',\n );\n await writeFile(nextConfigPath, configContent);\n }\n\n // Cleanup Counter.tsx if Redux is enabled - remove i18n from Counter component\n const counterComponentPath = path.join(projectPath, PROJECT_PATHS.COUNTER_COMPONENT);\n if (fileExists(counterComponentPath)) {\n let content = await readFile(counterComponentPath);\n content = content.replace(\n /import\\s+\\{\\s*useTranslations\\s*\\}\\s+from\\s+['\"]next-intl['\"];\\n/,\n '',\n );\n content = content.replace(/\\s*const\\s+t\\s*=\\s*useTranslations\\(['\"]Count['\"]\\);\\n/, '');\n content = content.replace(/\\{t\\('currentCount',\\s*\\{\\s*count:\\s*value\\s*\\}\\)\\}/g, '{value}');\n content = content.replace(/\\{t\\(['\"]increment['\"]\\)\\}/g, 'Increment');\n content = content.replace(/\\{t\\(['\"]decrement['\"]\\)\\}/g, 'Decrement');\n content = content.replace(/\\{t\\(['\"]reset['\"]\\)\\}/g, 'Reset');\n await writeFile(counterComponentPath, content);\n }\n }\n};\n\nconst cleanupLicense = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LICENSE));\n};\n\nconst cleanupChangelog = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CHANGELOG));\n};\n\nconst cleanupConfig = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.NVM_RC));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.NPM_RC));\n};\n", "import path from 'node:path';\nimport { writeFile } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { PROJECT_PATHS } from '../../config/paths';\n\nexport const generateRootProvider = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const imports: string[] = [];\n const providers: string[] = [];\n\n if (answers.redux) {\n imports.push(\"import { StoreProvider } from '@/providers';\");\n providers.push('StoreProvider');\n }\n\n if (answers.darkMode) {\n imports.push(\"import { CustomThemeProvider } from '@/providers';\");\n providers.push('CustomThemeProvider');\n }\n\n if (answers.i18n) {\n imports.push(\"import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';\");\n imports.push(\"import { SupportedLocale } from '@/types/i18n';\");\n }\n\n let rootProviderContent = `'use client';\n${imports.join('\\n')}\n\nexport const RootProvider = ({\n children,\n ${answers.i18n ? 'locale,\\n messages,' : ''}\n}: {\n children: React.ReactNode;\n ${answers.i18n ? 'locale: SupportedLocale;\\n messages: AbstractIntlMessages;' : ''}\n}) => {\n return (\n`;\n\n // Build the nesting\n let content = '{children}';\n\n if (answers.i18n) {\n content = `<NextIntlClientProvider locale={locale} messages={messages}>\n ${content}\n </NextIntlClientProvider>`;\n }\n\n if (answers.darkMode) {\n content = `<CustomThemeProvider>\n ${content}\n </CustomThemeProvider>`;\n }\n\n if (answers.redux) {\n content = `<StoreProvider>\n ${content}\n </StoreProvider>`;\n }\n\n // If no providers are wrapped, ensure we return a valid JSX element (Fragment)\n if (content === '{children}') {\n content = `<>{children}</>`;\n }\n\n rootProviderContent += ` ${content}\n );\n};\n`;\n\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_PROVIDER), rootProviderContent);\n};\n\nexport const generateLayout = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (!answers.i18n) {\n const basicLayout = `import type { Metadata } from 'next';\nimport '@/styles/globals.css';\nimport { Livvic } from 'next/font/google';\nimport { RootProvider } from '@/providers';\n\nconst livvic = Livvic({\n subsets: ['latin'],\n variable: '--font-livvic',\n weight: ['100', '200', '300', '400', '500', '600', '700', '900'],\n display: 'swap',\n});\n\nexport const metadata: Metadata = {\n title: '${answers.projectName}',\n description: '${answers.description}',\n};\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n return (\n <html lang=\"en\" suppressHydrationWarning={${answers.darkMode ? 'true' : 'false'}}>\n <body className={\\`\\${livvic.variable} ${answers.darkMode ? 'bg-light dark:bg-dark ' : ''}antialiased\\`}>\n <RootProvider>\n {children}\n </RootProvider>\n </body>\n </html>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT), basicLayout);\n\n // Generate page.tsx with Counter if Redux is enabled\n const counterImport = answers.redux ? \"import { Counter } from '@/features/counter';\\n\\n\" : '';\n const counterComponent = answers.redux ? '\\n <Counter />' : '';\n\n const basicPage = `${counterImport}export default function Home() {\n return (\n <div className=\"flex min-h-screen flex-col items-center justify-center p-24\">\n <h1 className=\"text-4xl font-bold\">Welcome to ${answers.projectName}</h1>\n <p className=\"mt-4 text-xl\">Get started by editing src/app/page.tsx</p>${counterComponent}\n </div>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_PAGE), basicPage);\n }\n};\n", "import path from 'node:path';\nimport { readdir } from 'node:fs/promises';\nimport {\n deleteDirectory,\n deleteFile,\n fileExists,\n readFile,\n updateJson,\n writeFile,\n} from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { PACKAGES } from '../../config/packages';\n\nexport const setupDevTools = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n await setupPreCommitHooks(projectPath, answers);\n await setupCommitizen(projectPath, answers);\n await setupCiCd(projectPath, answers);\n await setupGithubTemplates(projectPath, answers);\n await setupCommunityFiles(projectPath, answers);\n await setupDocker(projectPath, answers);\n await setupReadme(projectPath, answers);\n};\n\nconst setupPreCommitHooks = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.preCommitHooks) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.HUSKY_DIR));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.COMMITLINT_CONFIG));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LINTSTAGED_RC));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n delete pkg.devDependencies[PACKAGES.HUSKY];\n delete pkg.devDependencies[PACKAGES.COMMITLINT_CLI];\n delete pkg.devDependencies[PACKAGES.COMMITLINT_CONFIG];\n delete pkg.devDependencies[PACKAGES.LINT_STAGED];\n delete pkg.scripts['prepare'];\n delete pkg.scripts['postinstall'];\n delete pkg.commitlint;\n delete pkg['lint-staged'];\n return pkg;\n });\n }\n};\n\nconst setupCommitizen = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.commitizen) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CZRC));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n delete pkg.devDependencies[PACKAGES.COMMITIZEN];\n delete pkg.devDependencies[PACKAGES.CZ_CONVENTIONAL_CHANGELOG];\n delete pkg.config?.commitizen;\n if (pkg.config && Object.keys(pkg.config).length === 0) {\n delete pkg.config;\n }\n delete pkg.scripts['commit'];\n return pkg;\n });\n }\n};\n\nconst setupCiCd = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.ci) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.GITHUB_WORKFLOWS));\n }\n};\n\nconst setupGithubTemplates = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const githubPath = path.join(projectPath, PROJECT_PATHS.GITHUB_DIR);\n if (!answers.keepTemplates) {\n await deleteDirectory(path.join(githubPath, PROJECT_PATHS.GITHUB_ISSUE_TEMPLATE));\n await deleteFile(path.join(githubPath, PROJECT_PATHS.GITHUB_PR_TEMPLATE));\n } else {\n const issueTemplatePath = path.join(githubPath, PROJECT_PATHS.GITHUB_ISSUE_TEMPLATE);\n const prTemplatePath = path.join(githubPath, PROJECT_PATHS.GITHUB_PR_TEMPLATE);\n\n const replacePlaceholders = (content: string) => {\n return content\n .replace(/Teispace/g, answers.company)\n .replace(/support@teispace\\.com/g, answers.email)\n .replace(/Next\\.js Starter/g, answers.projectName)\n .replace(/\\[AUTHOR\\]/g, answers.author)\n .replace(/\\[COMPANY\\]/g, answers.company)\n .replace(/\\[EMAIL\\]/g, answers.email);\n };\n\n if (fileExists(prTemplatePath)) {\n let content = await readFile(prTemplatePath);\n content = replacePlaceholders(content);\n await writeFile(prTemplatePath, content);\n }\n\n try {\n if (fileExists(issueTemplatePath)) {\n const files = await readdir(issueTemplatePath);\n for (const file of files) {\n const filePath = path.join(issueTemplatePath, file);\n let content = await readFile(filePath);\n content = replacePlaceholders(content);\n await writeFile(filePath, content);\n }\n }\n } catch {\n // Ignore\n }\n }\n};\n\nconst setupCommunityFiles = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const allCommunityFiles = [\n PROJECT_PATHS.CODE_OF_CONDUCT,\n PROJECT_PATHS.CONTRIBUTING,\n PROJECT_PATHS.SECURITY,\n ];\n for (const file of allCommunityFiles) {\n if (!answers.communityFiles.includes(file)) {\n await deleteFile(path.join(projectPath, file));\n }\n }\n};\n\nconst setupDocker = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.docker) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKERFILE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKER_COMPOSE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKERIGNORE));\n\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (fileExists(envPath)) {\n let envContent = await readFile(envPath);\n envContent = envContent.replace(/# Docker Compose Configuration\\n/, '');\n envContent = envContent.replace(/CONTAINER_NAME=.*\\n/, '');\n envContent = envContent.replace(/IMAGE_NAME=.*\\n/, '');\n envContent = envContent.replace(/IMAGE_TAG=.*\\n/, '');\n await writeFile(envPath, envContent);\n }\n } else {\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (fileExists(envPath)) {\n let envContent = await readFile(envPath);\n const updateEnvVar = (key: string, value: string) => {\n const regex = new RegExp(`${key}=.*`);\n if (regex.test(envContent)) {\n envContent = envContent.replace(regex, `${key}=${value}`);\n } else {\n envContent += `${key}=${value}\\n`;\n }\n };\n\n updateEnvVar('CONTAINER_NAME', answers.containerName || 'next-app');\n updateEnvVar('IMAGE_NAME', answers.imageName || 'nextjs-starter');\n updateEnvVar('IMAGE_TAG', answers.imageTag || 'latest');\n\n await writeFile(envPath, envContent);\n }\n }\n};\n\nconst setupReadme = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const findReadmes = async (dir: string): Promise<string[]> => {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git') {\n files.push(...(await findReadmes(fullPath)));\n } else if (entry.isFile() && entry.name.toLowerCase() === 'readme.md') {\n files.push(fullPath);\n }\n }\n return files;\n };\n\n const allReadmes = await findReadmes(projectPath);\n const rootReadmePath = path.join(projectPath, PROJECT_PATHS.README);\n\n for (const readmePath of allReadmes) {\n if (readmePath !== rootReadmePath) {\n await deleteFile(readmePath);\n }\n }\n\n if (answers.readme) {\n const simpleReadme = `# ${answers.projectName}\n\n${answers.description}\n\n## Getting Started\n\nFirst, run the development server:\n\n\\`\\`\\`bash\n${answers.packageManager === 'npm' ? 'npm run dev' : answers.packageManager + ' dev'}\n\\`\\`\\`\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n`;\n await writeFile(rootReadmePath, simpleReadme);\n } else {\n await deleteFile(rootReadmePath);\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { log, logError, spinner } from '../config';\nimport { promptForFeatureDetails } from '../prompts/feature.prompt';\nimport { detectProjectSetup, featureExists } from '../services/feature/detection.service';\nimport { generateFeatureStructure } from '../services/feature/templates.service';\nimport { registerFeatureInRootReducer } from '../services/feature/registration.service';\nimport { registerApiEndpoints } from '../services/common/api-registration.service';\n\ninterface FeatureCommandOptions {\n skipStore?: boolean;\n store?: 'persist' | 'no-persist';\n skipService?: boolean;\n service?: 'axios' | 'fetch';\n path?: string;\n}\n\nexport const registerFeatureCommand = (program: Command) => {\n program\n .command('feature [name]')\n .description('Generate a new feature module')\n .option('--skip-store', 'Skip Redux store generation')\n .option('--store <type>', 'Generate Redux store with persistence option (persist|no-persist)')\n .option('--skip-service', 'Skip API service generation')\n .option('--service <client>', 'Generate API service with specific HTTP client (axios|fetch)')\n .option('--path <path>', 'Custom path for feature generation (default: src/features)')\n .action(async (name: string | undefined, options: FeatureCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate store option\n if (options.store && !['persist', 'no-persist'].includes(options.store)) {\n logError('Invalid --store option. Use: persist or no-persist');\n process.exit(1);\n }\n\n // Validate service option\n if (options.service && !['axios', 'fetch'].includes(options.service)) {\n logError('Invalid --service option. Use: axios or fetch');\n process.exit(1);\n }\n\n // Validate conflicting options\n if (options.skipStore && options.store) {\n logError('Cannot use --skip-store and --store together');\n process.exit(1);\n }\n\n if (options.skipService && options.service) {\n logError('Cannot use --skip-service and --service together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83C\uDFAF Feature Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n log(pc.dim(` Redux: ${detection.hasRedux ? '\u2713' : '\u2717'}`));\n log(pc.dim(` HTTP Client: ${detection.httpClient}`));\n log(pc.dim(` i18n: ${detection.hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n // Step 2: Prompt for feature details\n const featureOptions = await promptForFeatureDetails(\n name,\n detection.hasRedux,\n detection.httpClient,\n options.skipStore,\n options.store,\n options.skipService,\n options.service,\n );\n\n // Step 3: Determine feature path\n const basePath = options.path || path.join('src', 'features');\n const featurePath = path.join(projectPath, basePath, featureOptions.featureName);\n\n // Check if feature already exists\n const exists = await featureExists(projectPath, featureOptions.featureName, basePath);\n if (exists) {\n logError(`Feature '${featureOptions.featureName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 4: Generate feature structure\n spinner.start('Generating feature files...');\n\n await generateFeatureStructure({\n featureName: featureOptions.featureName,\n featurePath,\n createStore: featureOptions.createStore,\n persistStore: featureOptions.persistStore,\n createService: featureOptions.createService,\n httpClient: featureOptions.selectedHttpClient,\n });\n\n spinner.succeed('Feature files generated');\n\n // Step 5: Register API endpoints if service was created\n if (featureOptions.createService) {\n spinner.start('Registering API endpoints...');\n await registerApiEndpoints({\n serviceName: featureOptions.featureName,\n projectPath,\n });\n spinner.succeed('API endpoints registered');\n }\n\n // Step 6: Register in rootReducer if store was created\n if (featureOptions.createStore && detection.hasRedux) {\n spinner.start('Registering feature in rootReducer...');\n await registerFeatureInRootReducer(\n projectPath,\n featureOptions.featureName,\n featureOptions.persistStore,\n basePath,\n );\n spinner.succeed('Feature registered in rootReducer');\n }\n\n // Success message\n const displayPath = path.join(basePath, featureOptions.featureName);\n log(pc.green(`\\n\u2728 Feature '${featureOptions.featureName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 components/`));\n log(pc.dim(` \u251C\u2500\u2500 hooks/`));\n log(pc.dim(` \u251C\u2500\u2500 types/`));\n if (featureOptions.createStore) log(pc.dim(` \u251C\u2500\u2500 store/`));\n if (featureOptions.createService) log(pc.dim(` \u251C\u2500\u2500 services/`));\n log(pc.dim(` \u2514\u2500\u2500 index.ts\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import and use the feature: import { ${featureOptions.featureName} } from '${importPath}/${featureOptions.featureName}'`,\n ),\n );\n if (featureOptions.createStore) {\n log(pc.dim(` 2. Customize your Redux slice in: ${displayPath}/store/`));\n }\n if (featureOptions.createService) {\n log(\n pc.dim(\n ` 3. Add API methods in: ${displayPath}/services/${featureOptions.featureName}.service.ts`,\n ),\n );\n }\n log('');\n } catch (error) {\n spinner.fail('Feature generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\nconst { prompt } = Enquirer;\n\nexport interface FeatureOptions {\n featureName: string;\n hasRedux: boolean;\n createStore: boolean;\n persistStore: boolean;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n createService: boolean;\n selectedHttpClient?: 'axios' | 'fetch';\n}\n\nexport const promptForFeatureDetails = async (\n featureName?: string,\n hasRedux?: boolean,\n httpClient?: 'axios' | 'fetch' | 'both' | 'none',\n skipStore?: boolean,\n storeOption?: 'persist' | 'no-persist',\n skipService?: boolean,\n serviceClient?: 'axios' | 'fetch',\n): Promise<FeatureOptions> => {\n const questions: any[] = [];\n\n // Feature name\n if (!featureName) {\n questions.push({\n type: 'input',\n name: 'featureName',\n message: 'What is the feature name?',\n initial: 'my-feature',\n validate: (value: string) => {\n if (!/^[a-z0-9-]+$/.test(value)) {\n return 'Feature name must be lowercase and contain only alphanumeric characters and hyphens.';\n }\n return true;\n },\n });\n }\n\n // Redux store questions\n if (hasRedux && skipStore === undefined && storeOption === undefined) {\n questions.push({\n type: 'confirm',\n name: 'createStore',\n message: 'Generate Redux store for this feature?',\n initial: true,\n });\n\n questions.push({\n type: 'confirm',\n name: 'persistStore',\n message: 'Enable persistence for this store?',\n initial: false,\n skip() {\n // Skip if createStore is false\n\n return !(this as any).state.answers.createStore;\n },\n });\n }\n\n // HTTP service questions\n if (\n httpClient &&\n httpClient !== 'none' &&\n skipService === undefined &&\n serviceClient === undefined\n ) {\n questions.push({\n type: 'confirm',\n name: 'createService',\n message: 'Generate API service for this feature?',\n initial: true,\n });\n\n if (httpClient === 'both') {\n questions.push({\n type: 'select',\n name: 'selectedHttpClient',\n message: 'Which HTTP client to use for the service?',\n choices: ['fetch', 'axios'],\n initial: 0,\n skip() {\n // Skip if createService is false\n\n return !(this as any).state.answers.createService;\n },\n });\n }\n }\n\n const answers: any = questions.length > 0 ? await prompt(questions) : {};\n\n return {\n featureName: featureName || (answers.featureName as string),\n hasRedux: hasRedux || false,\n createStore:\n skipStore === true\n ? false\n : storeOption !== undefined\n ? true\n : (answers.createStore as boolean) || false,\n persistStore:\n storeOption === 'persist'\n ? true\n : storeOption === 'no-persist'\n ? false\n : (answers.persistStore as boolean) || false,\n httpClient: httpClient || 'none',\n createService:\n skipService === true\n ? false\n : serviceClient !== undefined\n ? true\n : (answers.createService as boolean) || false,\n selectedHttpClient:\n serviceClient ||\n (answers.selectedHttpClient as 'axios' | 'fetch' | undefined) ||\n (httpClient === 'both' ? 'fetch' : httpClient !== 'none' ? httpClient : undefined),\n };\n};\n", "import { readFile, access } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface ProjectDetection {\n hasRedux: boolean;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n hasI18n: boolean;\n}\n\nexport const detectProjectSetup = async (projectPath: string): Promise<ProjectDetection> => {\n let hasRedux = false;\n let hasAxios = false;\n let hasFetch = false;\n let hasI18n = false;\n\n try {\n // Read package.json\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJsonContent = await readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n // Check for Redux\n hasRedux = !!(dependencies['@reduxjs/toolkit'] && dependencies['react-redux']);\n\n // Check for axios\n hasAxios = !!dependencies['axios'];\n\n // Check for i18n\n hasI18n = !!dependencies['next-intl'];\n\n // Check if axios client exists\n const axiosClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'axios-client');\n try {\n await access(axiosClientPath);\n hasAxios = hasAxios && true; // Confirm axios is both installed and client exists\n } catch {\n hasAxios = false; // Axios client doesn't exist\n }\n\n // Check if fetch client exists\n const fetchClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'fetch-client');\n try {\n await access(fetchClientPath);\n hasFetch = true;\n } catch {\n hasFetch = false; // Fetch client doesn't exist\n }\n\n // Determine HTTP client setup\n let httpClient: 'axios' | 'fetch' | 'both' | 'none';\n if (hasAxios && hasFetch) {\n httpClient = 'both';\n } else if (hasAxios) {\n httpClient = 'axios';\n } else if (hasFetch) {\n httpClient = 'fetch';\n } else {\n httpClient = 'none';\n }\n\n return {\n hasRedux,\n httpClient,\n hasI18n,\n };\n } catch (error) {\n throw new Error(`Failed to detect project setup: ${error}`);\n }\n};\n\nexport const featureExists = async (\n projectPath: string,\n featureName: string,\n basePath: string = path.join('src', 'features'),\n): Promise<boolean> => {\n const featurePath = path.join(projectPath, basePath, featureName);\n try {\n await access(featurePath);\n return true;\n } catch {\n return false;\n }\n};\n", "import { writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../../config/utils';\n\nexport interface FeatureGenerationOptions {\n featureName: string;\n featurePath: string;\n createStore: boolean;\n persistStore: boolean;\n createService: boolean;\n httpClient?: 'axios' | 'fetch';\n}\n\nexport const generateFeatureStructure = async (\n options: FeatureGenerationOptions,\n): Promise<void> => {\n const { featurePath } = options;\n\n // Create feature directories\n await mkdir(path.join(featurePath, 'components'), { recursive: true });\n await mkdir(path.join(featurePath, 'hooks'), { recursive: true });\n await mkdir(path.join(featurePath, 'types'), { recursive: true });\n\n if (options.createStore) {\n await mkdir(path.join(featurePath, 'store'), { recursive: true });\n }\n\n if (options.createService) {\n await mkdir(path.join(featurePath, 'services'), { recursive: true });\n }\n\n // Generate files\n await generateComponentFile(options);\n await generateHookFile(options);\n await generateTypesFile(options);\n await generateIndexFile(options);\n\n if (options.createStore) {\n await generateStoreFiles(options);\n }\n\n if (options.createService && options.httpClient) {\n await generateServiceFile(options);\n }\n};\n\nexport const getProjectPathFromFeaturePath = (featurePath: string): string => {\n // Extract project root from feature path\n // featurePath format: /path/to/project/src/features/featureName\n const srcIndex = featurePath.indexOf('/src/features');\n if (srcIndex === -1) {\n throw new Error('Could not determine project path from feature path');\n }\n return featurePath.substring(0, srcIndex);\n};\n\nconst generateComponentFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath } = options;\n const componentName = kebabToPascal(featureName);\n const hookName = `use${componentName}`;\n\n const content = `'use client';\nimport { ${hookName} } from '../hooks/${hookName}';\n\nexport function ${componentName}() {\n const {} = ${hookName}();\n\n return (\n <div>\n <h2>${componentName} Component</h2>\n {/* Add your component UI here */}\n </div>\n );\n}\n\nexport default ${componentName};\n`;\n\n await writeFile(path.join(featurePath, 'components', `${componentName}.tsx`), content);\n};\n\nconst generateHookFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore } = options;\n const componentName = kebabToPascal(featureName);\n const hookName = `use${componentName}`;\n\n let content: string;\n\n if (createStore) {\n content = `'use client';\nimport { useAppDispatch, useAppSelector } from '@/store/hooks';\nimport { select${componentName}State, setLoading, setError } from '../store/${featureName}.selectors';\n\nexport const ${hookName} = () => {\n const dispatch = useAppDispatch();\n const state = useAppSelector(select${componentName}State);\n\n const handleSetLoading = (loading: boolean) => {\n dispatch(setLoading(loading));\n console.log('Loading state updated:', loading);\n };\n\n const handleSetError = (error: string | null) => {\n dispatch(setError(error));\n console.log('Error state updated:', error);\n };\n\n return {\n state,\n setLoading: handleSetLoading,\n setError: handleSetError,\n } as const;\n};\n`;\n } else {\n content = `'use client';\nimport { useState } from 'react';\n\nexport const ${hookName} = () => {\n // Add your state and logic here\n const [state, setState] = useState({});\n\n return {\n state,\n // Add your methods here\n } as const;\n};\n`;\n }\n\n await writeFile(path.join(featurePath, 'hooks', `${hookName}.ts`), content);\n};\n\nconst generateTypesFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore } = options;\n const componentName = kebabToPascal(featureName);\n const typeName = `${componentName}State`;\n\n const content = `export interface ${typeName} {\n // Add your state properties here\n ${createStore ? 'loading: boolean;\\n error: string | null;' : '// example: value: string;'}\n}\n`;\n\n await writeFile(path.join(featurePath, 'types', `${featureName}.types.ts`), content);\n};\n\nconst generateStoreFiles = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, persistStore } = options;\n const componentName = kebabToPascal(featureName);\n const camelName = kebabToCamel(featureName);\n\n // Generate slice\n const sliceContent = `import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { ${componentName}State } from '../types/${featureName}.types';\n\nconst initialState: ${componentName}State = {\n loading: false,\n error: null,\n // Add your initial state here\n};\n\nexport const ${camelName}Slice = createSlice({\n name: '${camelName}',\n initialState,\n reducers: {\n setLoading: (state, action: PayloadAction<boolean>) => {\n state.loading = action.payload;\n },\n setError: (state, action: PayloadAction<string | null>) => {\n state.error = action.payload;\n },\n resetState: (state) => {\n state.loading = false;\n state.error = null;\n },\n },\n});\n\nexport const { setLoading, setError, resetState } = ${camelName}Slice.actions;\n\nexport const ${camelName}Reducer = ${camelName}Slice.reducer;\n`;\n\n await writeFile(path.join(featurePath, 'store', `${featureName}.slice.ts`), sliceContent);\n\n // Generate selectors\n const selectorsContent = `import { RootState } from '@/store/rootReducer';\n\nexport const select${componentName}State = (state: RootState) => state.${camelName};\nexport { setLoading, setError, resetState } from './${featureName}.slice';\n`;\n\n await writeFile(path.join(featurePath, 'store', `${featureName}.selectors.ts`), selectorsContent);\n\n // Generate persist config if needed\n if (persistStore) {\n const persistContent = `import { PersistConfig } from 'redux-persist';\nimport storage from 'redux-persist/lib/storage';\nimport { ${componentName}State } from '../types/${featureName}.types';\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n // whitelist: ['someField'], // Specify which fields to persist\n};\n`;\n\n await writeFile(path.join(featurePath, 'store', 'persist.ts'), persistContent);\n }\n\n // Generate store index\n const storeIndexContent = `export * from './${featureName}.slice';\nexport * from './${featureName}.selectors';${persistStore ? \"\\nexport * from './persist';\" : ''}\n`;\n\n await writeFile(path.join(featurePath, 'store', 'index.ts'), storeIndexContent);\n};\n\nconst generateServiceFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, httpClient } = options;\n const camelName = kebabToCamel(featureName);\n\n let content: string;\n\n if (httpClient === 'axios') {\n content = `import { AppApis } from '@/lib/config';\nimport { axiosClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return axiosClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n } else {\n // fetch\n content = `import { AppApis } from '@/lib/config';\nimport { fetchClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return fetchClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n }\n\n await writeFile(path.join(featurePath, 'services', `${featureName}.service.ts`), content);\n};\n\nconst generateIndexFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore, createService } = options;\n const componentName = kebabToPascal(featureName);\n\n const content = `export { default as ${componentName} } from './components/${componentName}';\nexport { use${componentName} } from './hooks/use${componentName}';\nexport * from './types/${featureName}.types';${createStore ? `\\nexport * from './store';` : ''}${createService ? `\\nexport * from './services/${featureName}.service';` : ''}\n`;\n\n await writeFile(path.join(featurePath, 'index.ts'), content);\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\nexport const registerFeatureInRootReducer = async (\n projectPath: string,\n featureName: string,\n withPersist: boolean,\n basePath: string = path.join('src', 'features'),\n): Promise<void> => {\n const rootReducerPath = path.join(projectPath, 'src', 'store', 'rootReducer.ts');\n\n try {\n let content = await readFile(rootReducerPath, 'utf-8');\n\n const camelName = kebabToCamel(featureName);\n const reducerName = `${camelName}Reducer`;\n const importName = withPersist ? `${camelName}PersistConfig` : '';\n\n // Convert path to import alias format (src/features -> @/features)\n const importPath = basePath.replace(/^src\\//, '@/');\n\n // Add import statement\n const importStatement = withPersist\n ? `import { ${reducerName}, ${importName} } from '${importPath}/${featureName}/store';`\n : `import { ${reducerName} } from '${importPath}/${featureName}/store';`;\n\n // Find the last import statement\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = content.match(importRegex);\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = content.lastIndexOf(lastImport);\n content =\n content.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n content.slice(lastImportIndex + lastImport.length);\n } else {\n // No imports found, add at the beginning\n content = importStatement + '\\n' + content;\n }\n\n // Add reducer to combineReducers\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = content.match(combineReducersRegex);\n\n if (match) {\n const reducersContent = match[1];\n const newReducerEntry = withPersist\n ? `\\n ${camelName}: persistReducer(${importName}, ${reducerName}),`\n : `\\n ${camelName}: ${reducerName},`;\n\n const updatedReducersContent = reducersContent.trimEnd() + newReducerEntry;\n content = content.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n } else {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register feature in rootReducer: ${error}`);\n }\n};\n\n/**\n * Register a slice in rootReducer (imports from index.ts, not store/)\n */\nexport const registerSliceInRootReducer = async (\n projectPath: string,\n sliceName: string,\n withPersist: boolean,\n basePath: string,\n): Promise<void> => {\n const rootReducerPath = path.join(projectPath, 'src', 'store', 'rootReducer.ts');\n\n try {\n let content = await readFile(rootReducerPath, 'utf-8');\n\n const camelName = kebabToCamel(sliceName);\n const reducerName = `${camelName}Reducer`;\n const importName = withPersist ? `${camelName}PersistConfig` : '';\n\n // Convert path to import alias format (src/store -> @/store)\n const importPath = basePath.replace(/^src\\//, '@/');\n\n // Add import statement (import from index, not /store)\n const importStatement = withPersist\n ? `import { ${reducerName}, ${importName} } from '${importPath}/${sliceName}';`\n : `import { ${reducerName} } from '${importPath}/${sliceName}';`;\n\n // Find the last import statement\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = content.match(importRegex);\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = content.lastIndexOf(lastImport);\n content =\n content.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n content.slice(lastImportIndex + lastImport.length);\n } else {\n // No imports found, add at the beginning\n content = importStatement + '\\n' + content;\n }\n\n // Add reducer to combineReducers\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = content.match(combineReducersRegex);\n\n if (match) {\n const reducersContent = match[1];\n const newReducerEntry = withPersist\n ? `\\n ${camelName}: persistReducer(${importName}, ${reducerName}),`\n : `\\n ${camelName}: ${reducerName},`;\n\n const updatedReducersContent = reducersContent.trimEnd() + newReducerEntry;\n content = content.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n } else {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register slice in rootReducer: ${error}`);\n }\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\ninterface RegisterApiOptions {\n serviceName: string;\n projectPath: string;\n}\n\nexport const registerApiEndpoints = async (options: RegisterApiOptions): Promise<void> => {\n const { serviceName, projectPath } = options;\n const camelName = kebabToCamel(serviceName);\n const apiConfigPath = path.join(projectPath, 'src', 'lib', 'config', 'app-apis.ts');\n\n try {\n // Read the current app-apis.ts file\n const content = await readFile(apiConfigPath, 'utf-8');\n\n // Check if the service already exists in the file\n if (content.includes(`${camelName}:`)) {\n // Service already registered, skip\n return;\n }\n\n // Find the position to insert the new API endpoint\n // Looking for the closing brace of AppApis object\n const appApisMatch = content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/);\n\n if (!appApisMatch) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n // Create the new API endpoint entry\n const newEndpoint = ` ${camelName}: {\n base: \\`\\${API_PREFIX}/${serviceName}\\`,\n getAll: \\`\\${API_PREFIX}/${serviceName}\\`,\n },`;\n\n // Find the position before the closing brace\n const closingBracePattern = /(\\s*)\\} as const;/;\n const match = content.match(closingBracePattern);\n\n if (!match) {\n throw new Error('Could not find closing brace of AppApis object');\n }\n\n // Insert the new endpoint before the closing brace\n const insertPosition = content.lastIndexOf('} as const;');\n const beforeClosing = content.substring(0, insertPosition);\n const afterClosing = content.substring(insertPosition);\n\n // Check if there's already content in AppApis\n const hasExistingEndpoints = beforeClosing.trim().endsWith(',');\n const needsComma = beforeClosing.match(/:\\s*\\{[^}]*\\},\\s*$/);\n\n let updatedContent: string;\n if (needsComma || hasExistingEndpoints) {\n // There are existing endpoints, add comma and new endpoint\n updatedContent = `${beforeClosing}\\n${newEndpoint}\\n${afterClosing}`;\n } else {\n // First endpoint after auth (or empty object), just add it\n updatedContent = beforeClosing.trimEnd() + '\\n' + newEndpoint + '\\n' + afterClosing;\n }\n\n // Write the updated content back\n await writeFile(apiConfigPath, updatedContent);\n } catch (error) {\n throw new Error(`Failed to register API endpoints: ${error}`);\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { log, logError, spinner } from '../config';\nimport { promptForSliceDetails } from '../prompts/slice.prompt';\nimport { detectProjectSetup } from '../services/feature/detection.service';\nimport { generateSliceFiles } from '../services/slice/slice.service';\nimport { registerSliceInRootReducer } from '../services/feature/registration.service';\nimport { sliceExists } from '../services/slice/detection.service';\n\ninterface SliceCommandOptions {\n path?: string;\n persist?: boolean;\n noPersist?: boolean;\n}\n\nexport const registerSliceCommand = (program: Command) => {\n program\n .command('slice [name]')\n .description('Generate a Redux slice')\n .option('--path <path>', 'Custom path for slice generation (default: create new feature)')\n .option('--persist', 'Enable persistence for this slice')\n .option('--no-persist', 'Disable persistence for this slice')\n .action(async (name: string | undefined, options: SliceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate conflicting options\n if (options.persist && options.noPersist === true) {\n logError('Cannot use --persist and --no-persist together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Slice Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Step 2: Check if Redux is setup\n if (!detection.hasRedux) {\n spinner.fail('Redux is not setup in this project');\n logError('Please install @reduxjs/toolkit and react-redux first');\n log(pc.dim('\\nRun: npm install @reduxjs/toolkit react-redux\\n'));\n process.exit(1);\n }\n\n log(pc.dim(` Redux: \u2713\\n`));\n\n // Step 3: Prompt for slice details\n const sliceOptions = await promptForSliceDetails(\n name,\n options.persist,\n options.noPersist === true ? false : undefined,\n );\n\n // Step 4: Determine slice path (feature-first approach)\n let basePath: string;\n let featureName: string;\n let slicePath: string;\n\n if (options.path) {\n // Custom path provided\n const customPath = options.path.replace(/^src\\//, '');\n\n // Check if custom path is a feature\n if (customPath.startsWith('features/')) {\n // Extract feature name and ensure store subdirectory\n const parts = customPath.split('/');\n featureName = parts[1]; // features/featureName/...\n basePath = path.join('src', 'features', featureName, 'store');\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n } else {\n // Non-feature custom path - use as-is but treat as feature store\n basePath = path.join('src', customPath);\n featureName = customPath.split('/')[0]; // First directory as feature name\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n }\n } else {\n // Default: Create new feature with store\n featureName = sliceOptions.sliceName;\n basePath = path.join('src', 'features', featureName, 'store');\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n }\n\n // Step 5: Ensure feature and store directories exist\n const featureStorePath = path.join(projectPath, basePath);\n if (!existsSync(featureStorePath)) {\n await mkdir(featureStorePath, { recursive: true });\n }\n\n // Check if slice already exists\n const exists = await sliceExists(projectPath, sliceOptions.sliceName, basePath);\n if (exists) {\n logError(`Slice '${sliceOptions.sliceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 6: Generate slice files\n spinner.start('Generating slice files...');\n await generateSliceFiles({\n sliceName: sliceOptions.sliceName,\n slicePath,\n persistSlice: sliceOptions.persistSlice,\n });\n spinner.succeed('Slice files generated');\n\n // Step 7: Register in rootReducer\n spinner.start('Registering slice in rootReducer...');\n // For features: basePath includes store (e.g., src/features/auth/store)\n // We need to register the slice at basePath/sliceName\n await registerSliceInRootReducer(\n projectPath,\n sliceOptions.sliceName,\n sliceOptions.persistSlice,\n basePath,\n );\n spinner.succeed('Slice registered in rootReducer');\n\n // Success message\n const displayPath = path.join(basePath, sliceOptions.sliceName);\n log(pc.green(`\\n\u2728 Slice '${sliceOptions.sliceName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.slice.ts`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.selectors.ts`));\n if (sliceOptions.persistSlice) log(pc.dim(` \u251C\u2500\u2500 persist.ts`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.types.ts`));\n log(pc.dim(` \u2514\u2500\u2500 index.ts\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import actions: import { setLoading, setError } from '${importPath}/${sliceOptions.sliceName}'`,\n ),\n );\n log(pc.dim(` 2. Use in component: dispatch(setLoading(true))`));\n log('');\n } catch (error) {\n spinner.fail('Slice generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\nconst { prompt } = Enquirer;\n\nexport interface SliceOptions {\n sliceName: string;\n persistSlice: boolean;\n}\n\nexport const promptForSliceDetails = async (\n sliceName?: string,\n persist?: boolean,\n noPersist?: boolean,\n): Promise<SliceOptions> => {\n const questions: any[] = [];\n\n // Slice name\n if (!sliceName) {\n questions.push({\n type: 'input',\n name: 'sliceName',\n message: 'What is the slice name?',\n initial: 'my-slice',\n validate: (value: string) => {\n if (!/^[a-z0-9-]+$/.test(value)) {\n return 'Slice name must be lowercase and contain only alphanumeric characters and hyphens.';\n }\n return true;\n },\n });\n }\n\n // Persistence question\n if (persist === undefined && noPersist === undefined) {\n questions.push({\n type: 'confirm',\n name: 'persistSlice',\n message: 'Enable persistence for this slice?',\n initial: false,\n });\n }\n\n const answers: any = questions.length > 0 ? await prompt(questions) : {};\n\n return {\n sliceName: sliceName || (answers.sliceName as string),\n persistSlice:\n persist === true\n ? true\n : noPersist === false\n ? false\n : (answers.persistSlice as boolean) || false,\n };\n};\n", "import { writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../../config/utils';\n\nexport interface SliceGenerationOptions {\n sliceName: string;\n slicePath: string;\n persistSlice: boolean;\n}\n\nexport const generateSliceFiles = async (options: SliceGenerationOptions): Promise<void> => {\n const { sliceName, slicePath, persistSlice } = options;\n\n // Create slice directory\n await mkdir(slicePath, { recursive: true });\n\n const componentName = kebabToPascal(sliceName);\n const camelName = kebabToCamel(sliceName);\n\n // Generate types file\n await generateTypesFile(sliceName, slicePath, componentName);\n\n // Generate slice file\n await generateSliceFile(sliceName, slicePath, componentName, camelName);\n\n // Generate selectors file\n await generateSelectorsFile(sliceName, slicePath, componentName, camelName);\n\n // Generate persist file if needed\n if (persistSlice) {\n await generatePersistFile(sliceName, slicePath, componentName, camelName);\n }\n\n // Generate index file\n await generateIndexFile(sliceName, slicePath, persistSlice);\n};\n\nconst generateTypesFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n): Promise<void> => {\n const content = `export interface ${componentName}State {\n loading: boolean;\n error: string | null;\n // Add your state properties here\n}\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.types.ts`), content);\n};\n\nconst generateSliceFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { ${componentName}State } from './${sliceName}.types';\n\nconst initialState: ${componentName}State = {\n loading: false,\n error: null,\n // Add your initial state here\n};\n\nexport const ${camelName}Slice = createSlice({\n name: '${camelName}',\n initialState,\n reducers: {\n setLoading: (state, action: PayloadAction<boolean>) => {\n state.loading = action.payload;\n },\n setError: (state, action: PayloadAction<string | null>) => {\n state.error = action.payload;\n },\n resetState: (state) => {\n state.loading = false;\n state.error = null;\n },\n },\n});\n\nexport const { setLoading, setError, resetState } = ${camelName}Slice.actions;\n\nexport const ${camelName}Reducer = ${camelName}Slice.reducer;\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.slice.ts`), content);\n};\n\nconst generateSelectorsFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { RootState } from '@/store/rootReducer';\n\nexport const select${componentName}State = (state: RootState) => state.${camelName};\nexport { setLoading, setError, resetState } from './${sliceName}.slice';\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.selectors.ts`), content);\n};\n\nconst generatePersistFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { PersistConfig } from 'redux-persist';\nimport storage from 'redux-persist/lib/storage';\nimport { ${componentName}State } from './${sliceName}.types';\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n // whitelist: ['someField'], // Specify which fields to persist\n};\n`;\n\n await writeFile(path.join(slicePath, 'persist.ts'), content);\n};\n\nconst generateIndexFile = async (\n sliceName: string,\n slicePath: string,\n persistSlice: boolean,\n): Promise<void> => {\n const content = `export * from './${sliceName}.slice';\nexport * from './${sliceName}.selectors';\nexport * from './${sliceName}.types';${persistSlice ? \"\\nexport * from './persist';\" : ''}\n`;\n\n await writeFile(path.join(slicePath, 'index.ts'), content);\n};\n", "import { access } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport const sliceExists = async (\n projectPath: string,\n sliceName: string,\n basePath: string = path.join('src', 'store', 'slices'),\n): Promise<boolean> => {\n const slicePath = path.join(projectPath, basePath, sliceName);\n try {\n await access(slicePath);\n return true;\n } catch {\n return false;\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { log, logError, spinner } from '../config';\nimport { promptForServiceDetails } from '../prompts/service.prompt';\nimport { detectProjectSetup } from '../services/feature/detection.service';\nimport { generateServiceFiles } from '../services/service/service.service';\nimport { serviceExists } from '../services/service/detection.service';\nimport { registerApiEndpoints } from '../services/common/api-registration.service';\n\ninterface ServiceCommandOptions {\n path?: string;\n axios?: boolean;\n fetch?: boolean;\n}\n\nexport const registerServiceCommand = (program: Command) => {\n program\n .command('service [name]')\n .description('Generate an API service')\n .option('--path <path>', 'Custom path for service generation (default: create new feature)')\n .option('--axios', 'Use Axios HTTP client')\n .option('--fetch', 'Use Fetch HTTP client')\n .action(async (name: string | undefined, options: ServiceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate conflicting options\n if (options.axios && options.fetch) {\n logError('Cannot use --axios and --fetch together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Service Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Step 2: Check if HTTP clients are setup\n if (detection.httpClient === 'none') {\n spinner.fail('No HTTP client is setup in this project');\n logError('Please setup either AxiosClient or FetchClient first');\n log(pc.dim('\\nCheck: lib/utils/http/axios-client or lib/utils/http/fetch-client\\n'));\n process.exit(1);\n }\n\n // Display available clients\n const availableClients: string[] = [];\n if (detection.httpClient === 'axios' || detection.httpClient === 'both') {\n availableClients.push('Axios \u2713');\n }\n if (detection.httpClient === 'fetch' || detection.httpClient === 'both') {\n availableClients.push('Fetch \u2713');\n }\n log(pc.dim(` HTTP Clients: ${availableClients.join(', ')}\\n`));\n\n // Step 3: Prompt for service details\n const serviceOptions = await promptForServiceDetails(\n name,\n options.axios,\n options.fetch,\n detection.httpClient,\n );\n\n // Step 4: Determine service path (feature-first approach)\n let basePath: string;\n let featureName: string;\n let servicePath: string;\n\n if (options.path) {\n // Custom path provided\n const customPath = options.path.replace(/^src\\//, '');\n\n // Check if custom path is a feature\n if (customPath.startsWith('features/')) {\n // Extract feature name and ensure services subdirectory\n const parts = customPath.split('/');\n featureName = parts[1]; // features/featureName/...\n basePath = path.join('src', 'features', featureName, 'services');\n servicePath = path.join(projectPath, basePath);\n } else {\n // Non-feature custom path - use as-is\n basePath = path.join('src', customPath);\n featureName = customPath.split('/')[0]; // First directory as feature name\n servicePath = path.join(projectPath, basePath);\n }\n } else {\n // Default: Create new feature with services\n featureName = serviceOptions.serviceName;\n basePath = path.join('src', 'features', featureName, 'services');\n servicePath = path.join(projectPath, basePath);\n }\n\n // Step 5: Ensure feature and services directories exist\n if (!existsSync(servicePath)) {\n await mkdir(servicePath, { recursive: true });\n }\n\n // Check if service already exists\n const exists = await serviceExists(projectPath, serviceOptions.serviceName, basePath);\n if (exists) {\n logError(`Service '${serviceOptions.serviceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 6: Generate service files\n spinner.start('Generating service files...');\n await generateServiceFiles({\n serviceName: serviceOptions.serviceName,\n servicePath,\n httpClient: serviceOptions.httpClient,\n });\n spinner.succeed('Service files generated');\n\n // Step 7: Register API endpoints\n spinner.start('Registering API endpoints...');\n await registerApiEndpoints({\n serviceName: serviceOptions.serviceName,\n projectPath,\n });\n spinner.succeed('API endpoints registered');\n\n // Success message\n const displayPath = path.join(basePath, `${serviceOptions.serviceName}.service.ts`);\n log(pc.green(`\\n\u2728 Service '${serviceOptions.serviceName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC4 ${displayPath}\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import service: import { ${serviceOptions.serviceName}Service } from '${importPath}/${serviceOptions.serviceName}.service'`,\n ),\n );\n log(\n pc.dim(\n ` 2. Use in component: const data = await ${serviceOptions.serviceName}Service.getAll()`,\n ),\n );\n log('');\n } catch (error) {\n spinner.fail('Service generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import enquirer from 'enquirer';\n\ninterface ServiceOptions {\n serviceName: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const promptForServiceDetails = async (\n name?: string,\n axiosFlag?: boolean,\n fetchFlag?: boolean,\n availableClients?: 'axios' | 'fetch' | 'both' | 'none',\n): Promise<ServiceOptions> => {\n const serviceName =\n name ||\n (\n await enquirer.prompt<{ serviceName: string }>({\n type: 'input',\n name: 'serviceName',\n message: 'Service name (kebab-case):',\n validate: (input: string) => {\n if (!input) return 'Service name is required';\n if (!/^[a-z0-9-]+$/.test(input))\n return 'Service name must be lowercase with hyphens only';\n return true;\n },\n })\n ).serviceName;\n\n let httpClient: 'axios' | 'fetch';\n\n // If flags are provided, use them\n if (axiosFlag !== undefined) {\n httpClient = 'axios';\n } else if (fetchFlag !== undefined) {\n httpClient = 'fetch';\n } else {\n // Prompt based on available clients\n if (availableClients === 'axios') {\n httpClient = 'axios';\n } else if (availableClients === 'fetch') {\n httpClient = 'fetch';\n } else if (availableClients === 'both') {\n // Let user choose\n const response = await enquirer.prompt<{ httpClient: 'axios' | 'fetch' }>({\n type: 'select',\n name: 'httpClient',\n message: 'Choose HTTP client:',\n choices: ['axios', 'fetch'],\n });\n httpClient = response.httpClient;\n } else {\n // This shouldn't happen as we check in the command\n httpClient = 'axios';\n }\n }\n\n return {\n serviceName,\n httpClient,\n };\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\ninterface GenerateServiceOptions {\n serviceName: string;\n servicePath: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const generateServiceFiles = async (options: GenerateServiceOptions): Promise<void> => {\n await generateServiceFile(options);\n};\n\nconst generateServiceFile = async (options: GenerateServiceOptions): Promise<void> => {\n const { serviceName, servicePath, httpClient } = options;\n const camelName = kebabToCamel(serviceName);\n\n let content: string;\n\n if (httpClient === 'axios') {\n content = `import { AppApis } from '@/lib/config';\nimport { axiosClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return axiosClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n } else {\n // fetch\n content = `import { AppApis } from '@/lib/config';\nimport { fetchClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return fetchClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n }\n\n const fileName = `${serviceName}.service.ts`;\n await writeFile(path.join(servicePath, fileName), content);\n};\n", "import { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nexport const serviceExists = async (\n projectPath: string,\n serviceName: string,\n basePath: string,\n): Promise<boolean> => {\n const servicePath = path.join(projectPath, basePath, `${serviceName}.service.ts`);\n return existsSync(servicePath);\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport Enquirer from 'enquirer';\nimport { log, logError, spinner } from '../config';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { setupRedux } from '../services/setup/redux';\nimport { setupI18n } from '../services/setup/i18n';\nimport { setupHttpClient } from '../services/setup/http-client';\n\nconst { prompt } = Enquirer;\n\ninterface SetupOptions {\n httpClient?: string;\n darkTheme?: boolean;\n redux?: boolean;\n i18n?: boolean;\n}\n\nexport const registerSetupCommand = (program: Command) => {\n program\n .command('setup')\n .description('Setup features in an existing Next.js project')\n .option('--http-client', 'Setup HTTP client (axios|fetch)')\n .option('--dark-theme', 'Setup Dark Theme (Tailwind + next-themes)')\n .option('--redux', 'Setup Redux Toolkit')\n .option('--i18n', 'Setup next-intl for internationalization')\n .action(async (options: SetupOptions) => {\n try {\n log(pc.cyan('\\n\uD83D\uDD27 Setup Wizard\\n'));\n\n // Direct setup via flags\n if (options.httpClient || options.darkTheme || options.redux || options.i18n) {\n if (options.httpClient) {\n await setupHttpClient(process.cwd());\n }\n if (options.darkTheme) {\n await setupDarkTheme(process.cwd());\n }\n if (options.redux) {\n await setupRedux(process.cwd());\n }\n if (options.i18n) {\n await setupI18n(process.cwd());\n }\n return;\n }\n\n // If no options provided, show interactive menu\n const setupChoice = await prompt<{ feature: string }>([\n {\n type: 'select',\n name: 'feature',\n message: 'What would you like to setup?',\n choices: [\n { name: 'Dark Theme', value: 'dark-theme' },\n { name: 'Redux Toolkit', value: 'redux' },\n { name: 'HTTP Client (Axios/Fetch)', value: 'http-client' },\n { name: 'Internationalization (next-intl)', value: 'i18n' },\n 'Cancel',\n ],\n },\n ]);\n const feature = setupChoice.feature;\n\n if (feature === 'Cancel') {\n log(pc.yellow('Setup cancelled.'));\n return;\n }\n\n if (feature === 'dark-theme') {\n await setupDarkTheme(process.cwd());\n } else if (feature === 'redux') {\n await setupRedux(process.cwd());\n } else if (feature === 'http-client') {\n await setupHttpClient(process.cwd());\n } else if (feature === 'i18n') {\n await setupI18n(process.cwd());\n } else {\n log(pc.yellow(`\\n\u26A0\uFE0F ${feature} setup is not implemented yet.`));\n log(pc.dim('This feature will be available in a future update.'));\n }\n } catch (error) {\n spinner.fail('Setup failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyThemeProvider } from './assets';\nimport {\n updateProvidersIndex,\n updateRootProvider,\n updateGlobalsCss,\n updateLayout,\n} from './injectors';\n\nexport const setupDarkTheme = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Dark Theme...');\n const tempDir = path.join(projectPath, '.next-maker-temp');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`Dark Theme is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n const layoutPath = await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n await copyThemeProvider(projectPath, tempDir);\n\n // 5. Inject Code\n await updateProvidersIndex(projectPath);\n await updateRootProvider(projectPath);\n await updateGlobalsCss(projectPath, tempDir);\n await updateLayout(layoutPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing next-themes...';\n await installPackage(projectPath, 'next-themes');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Dark Theme setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Dark Theme.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { findLayoutPath } from './utils';\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const themeProviderPath = path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER);\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(themeProviderPath)) {\n return { isSetup: true, reason: 'CustomThemeProvider.tsx exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['next-themes']) ||\n (packageJson.devDependencies && packageJson.devDependencies['next-themes'])\n ) {\n return { isSetup: true, reason: 'next-themes is installed' };\n }\n }\n\n if (fileExists(globalsCssPath)) {\n const globalsCss = await readFile(globalsCssPath);\n if (globalsCss.includes('@custom-variant dark')) {\n return { isSetup: true, reason: 'Dark theme CSS found in globals.css' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<string> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n const layoutPath = await findLayoutPath(projectPath);\n\n if (!fileExists(globalsCssPath) || !layoutPath || !fileExists(providersIndexPath)) {\n throw new Error(\n 'Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.',\n );\n }\n\n return layoutPath;\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const findLayoutPath = async (projectPath: string): Promise<string> => {\n const possibleLayoutPaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT),\n path.join(projectPath, 'src/app/[locale]/layout.tsx'),\n ];\n\n for (const p of possibleLayoutPaths) {\n if (fileExists(p)) {\n const content = await readFile(p);\n if (content.includes('<body')) {\n return p;\n }\n }\n }\n\n // Fallback: if no body tag found, just take the first one that exists\n for (const p of possibleLayoutPaths) {\n if (fileExists(p)) {\n return p;\n }\n }\n\n return '';\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyThemeProvider = async (projectPath: string, tempDir: string): Promise<void> => {\n const themeProviderPath = path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER);\n const sourceProviderPath = path.join(tempDir, 'src/providers/CustomThemeProvider.tsx');\n await copyFile(sourceProviderPath, themeProviderPath);\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const updateProvidersIndex = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersContent = await readFile(providersIndexPath);\n if (!providersContent.includes('CustomThemeProvider')) {\n providersContent += \"export * from './CustomThemeProvider';\\n\";\n await writeFile(providersIndexPath, providersContent);\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let rootProviderContent = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = rootProviderContent.includes(useClientDirective);\n\n if (hasUseClient) {\n rootProviderContent = rootProviderContent.replace(useClientDirective, '').trim();\n }\n\n // Add import if missing\n if (!rootProviderContent.includes('CustomThemeProvider')) {\n rootProviderContent = rootProviderContent.replace(\n /import \\{ StoreProvider \\} from '@\\/providers';\\n/,\n \"import { StoreProvider, CustomThemeProvider } from '@/providers';\\n\",\n );\n // Fallback if StoreProvider import is different or missing\n if (!rootProviderContent.includes('CustomThemeProvider')) {\n if (rootProviderContent.includes(\"from '@/providers'\")) {\n rootProviderContent = rootProviderContent.replace(\n /\\} from '@\\/providers'/,\n \", CustomThemeProvider } from '@/providers'\",\n );\n } else {\n rootProviderContent =\n \"import { CustomThemeProvider } from '@/providers';\\n\" + rootProviderContent;\n }\n }\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n rootProviderContent = useClientDirective + '\\n' + rootProviderContent;\n }\n\n // Wrap children\n if (!rootProviderContent.includes('<CustomThemeProvider>')) {\n if (rootProviderContent.includes('<StoreProvider>')) {\n rootProviderContent = rootProviderContent.replace(\n /<StoreProvider>/,\n '<StoreProvider>\\n <CustomThemeProvider>',\n );\n rootProviderContent = rootProviderContent.replace(\n /<\\/StoreProvider>/,\n '</CustomThemeProvider>\\n </StoreProvider>',\n );\n } else {\n // Match return statement with or without parentheses\n const returnMatch = rootProviderContent.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n rootProviderContent = rootProviderContent.replace(\n returnMatch[0],\n `return (\\n <CustomThemeProvider>\\n ${existingJsx}\\n </CustomThemeProvider>\\n );`,\n );\n }\n }\n await writeFile(rootProviderPath, rootProviderContent);\n }\n }\n};\n\nexport const updateGlobalsCss = async (projectPath: string, tempDir: string): Promise<void> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const sourceCssPath = path.join(tempDir, 'src/styles/globals.css');\n let darkThemeCss = '';\n\n if (fileExists(sourceCssPath)) {\n const sourceCss = await readFile(sourceCssPath);\n const variantMatch = sourceCss.match(/@custom-variant dark \\(.*?\\);/);\n const themeMatch = sourceCss.match(/@theme \\{[\\s\\S]*?\\}/);\n\n if (variantMatch) darkThemeCss += `\\n${variantMatch[0]}\\n`;\n if (themeMatch) darkThemeCss += `\\n${themeMatch[0]}\\n`;\n }\n\n if (!darkThemeCss) {\n darkThemeCss = `\n@custom-variant dark (&:where(.dark, .dark *));\n\n@theme {\n --color-dark: #202938;\n --color-light: #f5f5f5;\n}\n`;\n }\n\n let cssContent = await readFile(globalsCssPath);\n if (!cssContent.includes('@custom-variant dark')) {\n if (cssContent.includes('@import')) {\n const lastImportIndex = cssContent.lastIndexOf('@import');\n const endOfLineIndex = cssContent.indexOf('\\n', lastImportIndex);\n cssContent =\n cssContent.slice(0, endOfLineIndex + 1) +\n darkThemeCss +\n cssContent.slice(endOfLineIndex + 1);\n } else {\n cssContent = darkThemeCss + cssContent;\n }\n await writeFile(globalsCssPath, cssContent);\n }\n};\n\nexport const updateLayout = async (layoutPath: string): Promise<void> => {\n let layoutContent = await readFile(layoutPath);\n if (!layoutContent.includes('dark:bg-dark')) {\n layoutContent = layoutContent.replace(\n /className=\"([^\"]*)\"/,\n 'className=\"$1 bg-light dark:bg-dark\"',\n );\n await writeFile(layoutPath, layoutContent);\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyReduxFiles, createCounterFeature } from './assets';\nimport { updateProvidersIndex, updateRootProvider, updatePage } from './injectors';\n\nexport const setupRedux = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Redux Toolkit...');\n const tempDir = path.join(projectPath, '.next-maker-temp-redux');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`Redux is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n spinner.text = 'Copying Redux files...';\n await copyReduxFiles(projectPath, tempDir);\n\n spinner.text = 'Creating Counter feature...';\n await createCounterFeature(projectPath, tempDir);\n\n // 5. Inject Code\n spinner.text = 'Updating providers and pages...';\n await updateProvidersIndex(projectPath);\n await updateRootProvider(projectPath);\n await updatePage(projectPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installPackage(projectPath, '@reduxjs/toolkit');\n await installPackage(projectPath, 'react-redux');\n await installPackage(projectPath, 'redux-persist');\n // Check if react-secure-storage is needed (starter uses it in persist.ts? No, it used storage from redux-persist/lib/storage in the file I viewed)\n // But let's check if the starter has it in package.json just in case.\n // Based on previous view of package.json in test project, it had react-secure-storage.\n // Let's install it to be safe if the starter uses it elsewhere or if I missed it.\n await installPackage(projectPath, 'react-secure-storage');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Redux Toolkit setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Redux Toolkit.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { findLayoutPath } from '../dark-theme/utils'; // Reuse utility\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const storePath = path.join(projectPath, PROJECT_PATHS.STORE);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(storePath)) {\n return { isSetup: true, reason: 'src/store directory exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['@reduxjs/toolkit']) ||\n (packageJson.devDependencies && packageJson.devDependencies['@reduxjs/toolkit'])\n ) {\n return { isSetup: true, reason: '@reduxjs/toolkit is installed' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n // We check for layout just to ensure it's a valid next app, reusing the robust check\n const layoutPath = await findLayoutPath(projectPath);\n\n if (!layoutPath || !fileExists(providersIndexPath)) {\n throw new Error(\n 'Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.',\n );\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile, readFile, writeFile, fileExists } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyReduxFiles = async (projectPath: string, tempDir: string): Promise<void> => {\n // Copy StoreProvider\n const sourceProviderPath = path.join(tempDir, 'src/providers/StoreProvider.tsx');\n const destProviderPath = path.join(projectPath, PROJECT_PATHS.STORE_PROVIDER);\n await copyFile(sourceProviderPath, destProviderPath);\n\n // Copy src/store directory\n const sourceStoreDir = path.join(tempDir, 'src/store');\n const destStoreDir = path.join(projectPath, PROJECT_PATHS.STORE);\n await fs.cp(sourceStoreDir, destStoreDir, { recursive: true });\n};\n\nexport const createCounterFeature = async (projectPath: string, tempDir: string): Promise<void> => {\n const sourceFeatureDir = path.join(tempDir, 'src/features/counter');\n const destFeatureDir = path.join(projectPath, PROJECT_PATHS.COUNTER_FEATURE);\n\n // Copy the entire directory first\n await fs.cp(sourceFeatureDir, destFeatureDir, { recursive: true });\n\n // Modify Counter.tsx to remove i18n\n const counterComponentPath = path.join(destFeatureDir, 'components/Counter.tsx');\n if (await fileExists(counterComponentPath)) {\n let content = await readFile(counterComponentPath);\n\n // Remove imports\n content = content.replace(/import \\{ useTranslations \\} from 'next-intl';\\n?/, '');\n\n // Remove hook usage\n content = content.replace(/const t = useTranslations\\('Count'\\);\\n?/, '');\n\n // Replace translations with hardcoded strings\n // {t('currentCount', { count: value })} -> Current Count: {value}\n content = content.replace(\n /\\{t\\('currentCount', \\{ count: value \\}\\)\\}/g,\n 'Current Count: {value}',\n );\n\n // {t('increment')} -> Increment\n content = content.replace(/\\{t\\('increment'\\)\\}/g, 'Increment');\n\n // {t('decrement')} -> Decrement\n content = content.replace(/\\{t\\('decrement'\\)\\}/g, 'Decrement');\n\n // {t('reset')} -> Reset\n content = content.replace(/\\{t\\('reset'\\)\\}/g, 'Reset');\n\n await writeFile(counterComponentPath, content);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const updateProvidersIndex = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersContent = await readFile(providersIndexPath);\n if (!providersContent.includes('StoreProvider')) {\n providersContent += \"export * from './StoreProvider';\\n\";\n await writeFile(providersIndexPath, providersContent);\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let rootProviderContent = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = rootProviderContent.includes(useClientDirective);\n\n if (hasUseClient) {\n rootProviderContent = rootProviderContent.replace(useClientDirective, '').trim();\n }\n\n // Add import\n if (!rootProviderContent.includes('StoreProvider')) {\n rootProviderContent = rootProviderContent.replace(\n /import \\{ (.*?) \\} from '@\\/providers';/,\n \"import { $1, StoreProvider } from '@/providers';\",\n );\n // Fallback if regex didn't match (e.g. no named imports yet)\n if (!rootProviderContent.includes('StoreProvider')) {\n if (rootProviderContent.includes(\"from '@/providers'\")) {\n // Try to append to existing import\n rootProviderContent = rootProviderContent.replace(\n /\\} from '@\\/providers'/,\n \", StoreProvider } from '@/providers'\",\n );\n } else {\n rootProviderContent =\n \"import { StoreProvider } from '@/providers';\\n\" + rootProviderContent;\n }\n }\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n rootProviderContent = useClientDirective + '\\n' + rootProviderContent;\n }\n\n // Wrap children\n // We want StoreProvider to be the outermost (or close to it)\n if (!rootProviderContent.includes('<StoreProvider>')) {\n const returnMatch = rootProviderContent.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n rootProviderContent = rootProviderContent.replace(\n returnMatch[0],\n `return (\\n <StoreProvider>\\n ${existingJsx}\\n </StoreProvider>\\n );`,\n );\n await writeFile(rootProviderPath, rootProviderContent);\n }\n }\n }\n};\n\nexport const updatePage = async (projectPath: string): Promise<void> => {\n // Try to find the page file\n const possiblePagePaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_PAGE),\n path.join(projectPath, 'src/app/[locale]/page.tsx'),\n ];\n\n let pagePath = '';\n for (const p of possiblePagePaths) {\n if (fileExists(p)) {\n pagePath = p;\n break;\n }\n }\n\n if (pagePath) {\n let pageContent = await readFile(pagePath);\n\n // Add import\n if (!pageContent.includes('Counter')) {\n pageContent =\n \"import { Counter } from '@/features/counter/components/Counter';\\n\" + pageContent;\n }\n\n // Add Component\n if (!pageContent.includes('<Counter />')) {\n // Look for the closing tag of the main container (usually div or main)\n // We'll just append it to the end of the children of the first element\n // This is a bit risky but standard for simple injections\n const lastDivIndex = pageContent.lastIndexOf('</div>');\n const lastMainIndex = pageContent.lastIndexOf('</main>');\n\n const insertIndex = lastMainIndex !== -1 ? lastMainIndex : lastDivIndex;\n\n if (insertIndex !== -1) {\n pageContent =\n pageContent.slice(0, insertIndex) +\n '\\n <div className=\"mt-8\">\\n <h2 className=\"text-2xl font-bold mb-4\">Redux Counter</h2>\\n <Counter />\\n </div>\\n' +\n pageContent.slice(insertIndex);\n await writeFile(pagePath, pageContent);\n }\n }\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyI18nFiles } from './assets';\nimport {\n updateNextConfig,\n updateTypesIndex,\n updateConfigIndex,\n migrateToLocaleStructure,\n updateRootProvider,\n} from './injectors';\n\nexport const setupI18n = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Internationalization (next-intl)...');\n const tempDir = path.join(projectPath, '.next-maker-temp-i18n');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`i18n is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n spinner.text = 'Copying i18n files...';\n await copyI18nFiles(projectPath, tempDir);\n\n // 5. Inject Code & Migrate Structure\n spinner.text = 'Configuring project structure...';\n await updateNextConfig(projectPath);\n await updateTypesIndex(projectPath);\n await updateConfigIndex(projectPath);\n await updateRootProvider(projectPath);\n\n spinner.text = 'Migrating to [locale] structure...';\n await migrateToLocaleStructure(projectPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installPackage(projectPath, 'next-intl');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Internationalization setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Internationalization.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const i18nDir = path.join(projectPath, PROJECT_PATHS.I18N_DIR);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(i18nDir)) {\n return { isSetup: true, reason: 'src/i18n directory exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['next-intl']) ||\n (packageJson.devDependencies && packageJson.devDependencies['next-intl'])\n ) {\n return { isSetup: true, reason: 'next-intl is installed' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const rootLayoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n const localeLayoutPath = path.join(projectPath, 'src/app/[locale]/layout.tsx');\n\n if (!fileExists(rootLayoutPath) && !fileExists(localeLayoutPath)) {\n throw new Error('Project structure mismatch. Ensure src/app/layout.tsx exists.');\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyI18nFiles = async (projectPath: string, tempDir: string): Promise<void> => {\n // Copy src/i18n directory\n const sourceI18nDir = path.join(tempDir, 'src/i18n');\n const destI18nDir = path.join(projectPath, PROJECT_PATHS.I18N_DIR);\n await fs.cp(sourceI18nDir, destI18nDir, { recursive: true });\n\n // Copy src/proxy.ts\n const sourceProxyPath = path.join(tempDir, 'src/proxy.ts');\n const destProxyPath = path.join(projectPath, PROJECT_PATHS.PROXY);\n await copyFile(sourceProxyPath, destProxyPath);\n\n // Copy src/types/i18n.ts\n const sourceTypesPath = path.join(tempDir, 'src/types/i18n.ts');\n const destTypesPath = path.join(projectPath, PROJECT_PATHS.I18N_TYPES);\n await copyFile(sourceTypesPath, destTypesPath);\n\n // Copy src/lib/config/app-locales.ts\n const sourceLocalesPath = path.join(tempDir, 'src/lib/config/app-locales.ts');\n const destLocalesPath = path.join(projectPath, PROJECT_PATHS.APP_LOCALES);\n await copyFile(sourceLocalesPath, destLocalesPath);\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile, deleteFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport fs from 'node:fs/promises';\n\nexport const updateNextConfig = async (projectPath: string): Promise<void> => {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n if (!content.includes('createNextIntlPlugin')) {\n content = \"import createNextIntlPlugin from 'next-intl/plugin';\\n\" + content;\n\n const exportDefaultRegex = /export default (.*?);/;\n if (exportDefaultRegex.test(content)) {\n content = content.replace(\n exportDefaultRegex,\n '\\nconst withNextIntl = createNextIntlPlugin();\\nexport default withNextIntl($1);',\n );\n } else {\n // Fallback if no export default found (unlikely but safe)\n content += '\\nconst withNextIntl = createNextIntlPlugin();\\n';\n content += 'export default withNextIntl(nextConfig);\\n';\n }\n\n await writeFile(nextConfigPath, content);\n }\n }\n};\n\nexport const updateTypesIndex = async (projectPath: string): Promise<void> => {\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n if (!content.includes('./i18n')) {\n content += \"export * from './i18n';\\n\";\n await writeFile(typesIndexPath, content);\n }\n }\n};\n\nexport const updateConfigIndex = async (projectPath: string): Promise<void> => {\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n if (!content.includes('./app-locales')) {\n content += \"export * from './app-locales';\\n\";\n await writeFile(configIndexPath, content);\n }\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let content = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Add imports\n if (!content.includes('next-intl')) {\n const imports = `import { SupportedLocale } from '@/types/i18n';\nimport { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';\n`;\n content = imports + content;\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n content = useClientDirective + '\\n' + content;\n }\n\n // Update Props\n // Replace props type or signature\n if (!content.includes('locale: SupportedLocale')) {\n // Try to find the props definition\n // This assumes a specific structure, might need to be more robust\n // We'll look for the component definition\n const componentRegex = /export const RootProvider = \\(\\{([\\s\\S]*?)\\}: \\{([\\s\\S]*?)\\}\\) => \\{/;\n const match = content.match(componentRegex);\n\n if (match) {\n const newParams = `\\n children,\\n locale,\\n messages,`;\n const newTypes = `\\n children: React.ReactNode;\\n locale: SupportedLocale;\\n messages: AbstractIntlMessages;`;\n\n content = content.replace(\n match[0],\n `export const RootProvider = ({${newParams}\\n}: {${newTypes}\\n}) => {`,\n );\n }\n }\n\n // Wrap with NextIntlClientProvider\n if (!content.includes('<NextIntlClientProvider')) {\n const returnMatch = content.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n // We want NextIntlClientProvider to be inside CustomThemeProvider if possible, or just wrap children\n // But usually it wraps everything inside the provider\n // Let's wrap the inner content\n const existingJsx = returnMatch[1];\n\n // We need to be careful. If existingJsx contains {children}, we want to wrap THAT.\n // But replacing {children} might be safer if we can find it.\n // However, if we just wrap the whole thing, it might be double wrapping if not careful.\n // But here we are wrapping the *returned JSX*.\n\n // Wait, the previous logic was:\n // content = content.replace(/return \\(\\s*<([^>]+)([^>]*)>([\\s\\S]*)<\\/\\1>\\s*\\);/, (match) => {\n // return match.replace(\n // /\\{children\\}/,\n // `<NextIntlClientProvider locale={locale} messages={messages}>\\n {children}\\n </NextIntlClientProvider>`,\n // );\n // });\n\n // The previous logic tried to find {children} inside the returned JSX and wrap IT.\n // This is different from dark-theme/redux which wrap the *entire* returned JSX.\n // Why? Because NextIntlClientProvider should be close to children?\n // Or maybe just to avoid wrapping other providers?\n\n // If I use the new regex, I get the whole JSX.\n // I can try to replace {children} inside it.\n\n if (existingJsx.includes('{children}')) {\n const newJsx = existingJsx.replace(\n '{children}',\n `<NextIntlClientProvider locale={locale} messages={messages}>\\n {children}\\n </NextIntlClientProvider>`,\n );\n content = content.replace(returnMatch[0], `return (\\n ${newJsx}\\n );`);\n } else {\n // Fallback: wrap the whole thing if {children} not found (unlikely)\n content = content.replace(\n returnMatch[0],\n `return (\\n <NextIntlClientProvider locale={locale} messages={messages}>\\n ${existingJsx}\\n </NextIntlClientProvider>\\n );`,\n );\n }\n }\n }\n\n await writeFile(rootProviderPath, content);\n }\n};\n\nexport const migrateToLocaleStructure = async (projectPath: string): Promise<void> => {\n const rootLayoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n const rootPagePath = path.join(projectPath, PROJECT_PATHS.ROOT_PAGE);\n const localeDir = path.join(projectPath, 'src/app/[locale]');\n\n // Create [locale] directory\n await fs.mkdir(localeDir, { recursive: true });\n\n // Move Layout\n if (fileExists(rootLayoutPath)) {\n const destLayoutPath = path.join(localeDir, 'layout.tsx');\n let content = await readFile(rootLayoutPath);\n\n // Add imports\n if (!content.includes('next-intl')) {\n content =\n `import { routing } from '@/i18n/routing';\nimport { hasLocale } from 'next-intl';\nimport { notFound } from 'next/navigation';\nimport { setRequestLocale, getMessages } from 'next-intl/server';\n` + content;\n }\n\n // Add generateStaticParams\n if (!content.includes('generateStaticParams')) {\n const metadataEndIndex = content.indexOf('};', content.indexOf('export const metadata'));\n if (metadataEndIndex !== -1) {\n const insertPos = metadataEndIndex + 2;\n content =\n content.slice(0, insertPos) +\n `\\n\\nexport function generateStaticParams() {\n return routing.locales.map((locale) => ({ locale }));\n}` +\n content.slice(insertPos);\n }\n }\n\n // Update RootLayout signature and body\n // Replace props type\n content = content.replace(\n /Readonly<\\{\\s*children:\\s*React\\.ReactNode;\\s*}>/,\n `Readonly<{\n children: React.ReactNode;\n params: Promise<{ locale: string }>;\n}>`,\n );\n\n // Add logic inside function\n // Handle both async and non-async function definitions\n const functionBodyRegex =\n /export default (async )?function RootLayout\\(\\{\\s*children,?\\s*\\}\\s*:/;\n const functionMatch = content.match(functionBodyRegex);\n\n if (functionMatch) {\n const isAsync = functionMatch[1];\n\n // Ensure it's async\n if (!isAsync) {\n content = content.replace('export default function', 'export default async function');\n }\n\n // 1. Inject params destructuring\n content = content.replace(\n /export default (async )?function RootLayout\\(\\{\\s*children,?\\s*\\}\\s*:/,\n 'export default async function RootLayout({ children, params }:',\n );\n\n // 2. Inject logic at start of function\n const bodyStartRegex = /export default async function RootLayout[\\s\\S]*?\\)\\s*\\{/;\n const bodyMatch = content.match(bodyStartRegex);\n\n if (bodyMatch && bodyMatch.index !== undefined) {\n const bodyOpenBrace = bodyMatch.index + bodyMatch[0].length - 1;\n const logic = `\n const { locale } = await params;\n\n if (!hasLocale(routing.locales, locale)) {\n notFound();\n }\n\n setRequestLocale(locale);\n\n const messages = await getMessages();\n`;\n content = content.slice(0, bodyOpenBrace + 1) + logic + content.slice(bodyOpenBrace + 1);\n }\n\n // 3. Update RootProvider usage\n content = content.replace(\n /<RootProvider>/,\n '<RootProvider locale={locale} messages={messages}>',\n );\n\n // 4. Update html lang\n content = content.replace(/<html lang=\"en\"/, '<html lang={locale}');\n }\n\n await writeFile(destLayoutPath, content);\n await deleteFile(rootLayoutPath);\n }\n\n // Move Page\n if (fileExists(rootPagePath)) {\n const destPagePath = path.join(localeDir, 'page.tsx');\n let content = await readFile(rootPagePath);\n\n // Add imports\n if (!content.includes('next-intl')) {\n content =\n `import { SupportedLocale } from '@/types/i18n';\nimport { setRequestLocale } from 'next-intl/server';\n` + content;\n }\n\n // Update Page signature\n content = content.replace(\n /export default function Home\\(\\)/,\n `type Props = {\n params: Promise<{ locale: string }>;\n};\n\nexport default async function Home(props: Props)`,\n );\n\n // Inject logic\n const bodyOpenBrace = content.indexOf('export default async function Home(props: Props) {');\n if (bodyOpenBrace !== -1) {\n const logic = `\n const locale = (await props.params).locale as SupportedLocale;\n setRequestLocale(locale);\n`;\n const braceIndex = content.indexOf('{', bodyOpenBrace);\n content = content.slice(0, braceIndex + 1) + logic + content.slice(braceIndex + 1);\n }\n\n await writeFile(destPagePath, content);\n await deleteFile(rootPagePath);\n }\n};\n", "import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport pc from 'picocolors';\nimport Enquirer from 'enquirer';\nimport { deleteDirectory, fileExists } from '../../../core/files';\nimport {\n installPackage,\n runScript,\n detectPackageManager,\n uninstallPackage,\n} from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure, HttpClientType } from './checks';\nimport { fetchAssets, copyHttpClientFiles, performFullCleanup } from './assets';\nimport {\n updateHttpIndex,\n updateUtilsIndex,\n updateTypesIndex,\n updateConfigIndex,\n migrateClientUsages,\n cleanupHttpTypes,\n removeHttpExports,\n} from './injectors';\n\ntype ClientType = 'fetch' | 'axios';\n\ninterface SetupAction {\n type: 'install' | 'add' | 'replace' | 'remove-one' | 'remove-both' | 'cancel';\n clients: ClientType[];\n fromClient?: ClientType; // For replace action\n}\n\nexport const setupHttpClient = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Checking HTTP Client setup...');\n const tempDir = path.join(projectPath, '.next-maker-temp-http');\n\n try {\n // 1. Pre-check\n const { status, reason } = await checkIsAlreadySetup(projectPath);\n spinner.stop();\n\n const action = await determineAction(status, reason);\n\n if (action.type === 'cancel') {\n console.log(pc.yellow('Setup cancelled.'));\n return;\n }\n\n spinner.start(`Setting up HTTP client(s)...`);\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Execute action based on type\n if (action.type === 'replace' && action.fromClient) {\n // Replace: migrate imports before copying new files\n spinner.text = 'Migrating client usages...';\n await migrateClientUsages(projectPath, action.fromClient, action.clients[0]);\n }\n\n if (action.type !== 'remove-both' && action.type !== 'remove-one') {\n // Copy files for install/add/replace\n spinner.text = 'Copying client files...';\n const clientsToRemove =\n action.type === 'replace' && action.fromClient ? [action.fromClient] : undefined;\n await copyHttpClientFiles(projectPath, tempDir, action.clients, clientsToRemove);\n }\n\n if (action.type === 'remove-one' || action.type === 'remove-both') {\n // Remove specified clients\n spinner.text = 'Removing client files...';\n const { PROJECT_PATHS } = await import('../../../config/paths');\n for (const client of action.clients) {\n const clientPath = path.join(\n projectPath,\n client === 'fetch' ? PROJECT_PATHS.FETCH_CLIENT : PROJECT_PATHS.AXIOS_CLIENT,\n );\n await deleteDirectory(clientPath);\n }\n\n // Check if any clients remain\n const activeClients = getActiveClients(status, action);\n if (activeClients.length === 0) {\n spinner.text = 'Performing full cleanup...';\n await performFullCleanup(projectPath);\n await removeHttpExports(projectPath);\n }\n }\n\n // 5. Update exports in http/index.ts\n const activeClients = getActiveClients(status, action);\n\n // Only update exports if there are active clients remaining\n if (activeClients.length > 0) {\n spinner.text = 'Configuring client...';\n await updateHttpIndex(projectPath, activeClients);\n await updateUtilsIndex(projectPath);\n await updateTypesIndex(projectPath);\n await updateConfigIndex(projectPath);\n }\n\n // Always cleanup types (even if removing both, we need to strip client-specific types from the preserved http.types.ts)\n await cleanupHttpTypes(projectPath, activeClients);\n\n // 6. Dependency Management\n spinner.text = 'Managing dependencies...';\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Axios Management\n if (activeClients.includes('axios')) {\n if (!dependencies['axios']) {\n spinner.text = 'Installing Axios...';\n await installPackage(projectPath, 'axios');\n }\n } else {\n if (dependencies['axios']) {\n spinner.text = 'Uninstalling Axios...';\n await uninstallPackage(projectPath, 'axios');\n }\n }\n\n // React Secure Storage Management\n // Needed if ANY client exists (for token store), OR if used elsewhere (checked by file existence)\n const storageServicePath = path.join(projectPath, 'src/services/storage'); // Hardcoded path to match assets.ts usage\n const isStorageNeeded = activeClients.length > 0 || fileExists(storageServicePath);\n\n if (isStorageNeeded) {\n if (!dependencies['react-secure-storage']) {\n spinner.text = 'Installing react-secure-storage...';\n await installPackage(projectPath, 'react-secure-storage');\n }\n } else {\n if (dependencies['react-secure-storage']) {\n spinner.text = 'Uninstalling react-secure-storage...';\n await uninstallPackage(projectPath, 'react-secure-storage');\n }\n }\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green(getSuccessMessage(action)));\n } catch (error) {\n spinner.fail('Failed to setup HTTP Client.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n\nasync function determineAction(status: HttpClientType, reason?: string): Promise<SetupAction> {\n if (status === 'none') {\n // No clients exist - choose what to install\n const { choice } = await Enquirer.prompt<{ choice: string }>({\n type: 'select',\n name: 'choice',\n message: 'Which HTTP client(s) do you want to setup?',\n choices: [\n { name: 'fetch', message: 'Fetch (Native)' },\n { name: 'axios', message: 'Axios' },\n { name: 'both', message: 'Both (Fetch + Axios)' },\n ],\n });\n\n if (choice === 'both') {\n return { type: 'install', clients: ['fetch', 'axios'] };\n }\n return { type: 'install', clients: [choice as ClientType] };\n }\n\n if (status === 'fetch') {\n // Only fetch exists\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: `${reason}. What would you like to do?`,\n choices: [\n { name: 'cancel', message: 'Keep Fetch only (cancel)' },\n { name: 'add', message: 'Add Axios (have both)' },\n { name: 'replace', message: 'Replace with Axios only' },\n { name: 'remove', message: 'Remove Fetch' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'add') return { type: 'add', clients: ['axios'] };\n if (action === 'replace') return { type: 'replace', clients: ['axios'], fromClient: 'fetch' };\n if (action === 'remove') return { type: 'remove-one', clients: ['fetch'] };\n }\n\n if (status === 'axios') {\n // Only axios exists\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: `${reason}. What would you like to do?`,\n choices: [\n { name: 'cancel', message: 'Keep Axios only (cancel)' },\n { name: 'add', message: 'Add Fetch (have both)' },\n { name: 'replace', message: 'Replace with Fetch only' },\n { name: 'remove', message: 'Remove Axios' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'add') return { type: 'add', clients: ['fetch'] };\n if (action === 'replace') return { type: 'replace', clients: ['fetch'], fromClient: 'axios' };\n if (action === 'remove') return { type: 'remove-one', clients: ['axios'] };\n }\n\n // Both exist\n console.log(pc.yellow(`\u2716 ${reason}`));\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n { name: 'cancel', message: 'Keep both (cancel)' },\n { name: 'remove-fetch', message: 'Remove Fetch (keep Axios)' },\n { name: 'remove-axios', message: 'Remove Axios (keep Fetch)' },\n { name: 'remove-both', message: 'Remove both' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'remove-fetch') return { type: 'remove-one', clients: ['fetch'] };\n if (action === 'remove-axios') return { type: 'remove-one', clients: ['axios'] };\n if (action === 'remove-both') return { type: 'remove-both', clients: ['fetch', 'axios'] };\n\n return { type: 'cancel', clients: [] };\n}\n\nfunction getActiveClients(status: HttpClientType, action: SetupAction): ClientType[] {\n if (action.type === 'install') {\n return action.clients;\n }\n\n if (action.type === 'add') {\n const existing: ClientType[] = status === 'fetch' ? ['fetch'] : ['axios'];\n return [...existing, ...action.clients];\n }\n\n if (action.type === 'replace') {\n return action.clients;\n }\n\n if (action.type === 'remove-one') {\n if (status === 'both') {\n return action.clients[0] === 'fetch' ? ['axios'] : ['fetch'];\n }\n return [];\n }\n\n return [];\n}\n\nfunction getSuccessMessage(action: SetupAction): string {\n if (action.type === 'install') {\n const names = action.clients.map((c) => (c === 'fetch' ? 'Fetch' : 'Axios')).join(' + ');\n return `HTTP Client (${names}) setup successfully!`;\n }\n\n if (action.type === 'add') {\n const name = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `${name} client added successfully! Both clients are now available.`;\n }\n\n if (action.type === 'replace') {\n const from = action.fromClient === 'fetch' ? 'Fetch' : 'Axios';\n const to = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `Replaced ${from} with ${to} successfully! Imports automatically migrated.`;\n }\n\n if (action.type === 'remove-one') {\n const name = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `${name} client removed successfully!`;\n }\n\n if (action.type === 'remove-both') {\n return 'Both HTTP clients removed successfully!';\n }\n\n return 'HTTP Client setup completed!';\n}\n", "import path from 'node:path';\nimport { fileExists } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport type HttpClientType = 'fetch' | 'axios' | 'none' | 'both';\n\nexport interface HttpClientSetupStatus {\n status: HttpClientType;\n reason?: string;\n}\n\nexport const checkIsAlreadySetup = async (projectPath: string): Promise<HttpClientSetupStatus> => {\n const fetchClientPath = path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT_FILE);\n const axiosClientPath = path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT_FILE);\n\n const hasFetch = fileExists(fetchClientPath);\n const hasAxios = fileExists(axiosClientPath);\n\n if (hasFetch && hasAxios) {\n return { status: 'both', reason: 'Both Fetch and Axios clients are detected' };\n }\n\n if (hasFetch) {\n return { status: 'fetch', reason: 'Fetch client is already setup' };\n }\n\n if (hasAxios) {\n return { status: 'axios', reason: 'Axios client is already setup' };\n }\n\n return { status: 'none' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const requiredPaths = [\n path.join(projectPath, 'src/lib'),\n path.join(projectPath, 'src/types'),\n path.join(projectPath, 'src/lib/config'),\n ];\n\n const missingPaths = requiredPaths.filter((p) => !fileExists(p));\n\n if (missingPaths.length > 0) {\n throw new Error(\n `Invalid project structure. Missing directories:\\n${missingPaths.map((p) => `- ${p}`).join('\\n')}`,\n );\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile, deleteDirectory, fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Downloading assets from starter repository...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyHttpClientFiles = async (\n projectPath: string,\n tempDir: string,\n clients: ('fetch' | 'axios')[],\n removeClients?: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpUtilsPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS);\n const tempHttpUtilsPath = path.join(tempDir, PROJECT_PATHS.HTTP_UTILS);\n\n // 1. Copy Common Files\n // src/types/errors\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.ERRORS_DIR),\n path.join(projectPath, PROJECT_PATHS.ERRORS_DIR),\n { recursive: true },\n );\n\n // src/lib/config/app-apis.ts\n const appApisPath = path.join(projectPath, PROJECT_PATHS.APP_APIS);\n if (!fileExists(appApisPath)) {\n await copyFile(path.join(tempDir, PROJECT_PATHS.APP_APIS), appApisPath);\n }\n\n // src/lib/config/constants.ts (contains API_RESPONSE_DATA_KEY)\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (!fileExists(constantsPath)) {\n await copyFile(path.join(tempDir, PROJECT_PATHS.CONSTANTS), constantsPath);\n } else {\n // Ensure API_RESPONSE_DATA_KEY exists if file is kept\n let content = await readFile(constantsPath);\n let modified = false;\n\n if (!content.includes('API_RESPONSE_DATA_KEY')) {\n content += \"\\nexport const API_RESPONSE_DATA_KEY = 'data';\\n\";\n modified = true;\n }\n\n if (!content.includes('SAVE_AUTH_TOKENS')) {\n content += '\\nexport const SAVE_AUTH_TOKENS = false;\\n';\n modified = true;\n }\n\n if (modified) {\n await writeFile(constantsPath, content);\n }\n }\n\n // src/services/storage (needed by token-store.ts) - only if doesn't exist\n const storageServicePath = path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE);\n if (!fileExists(storageServicePath)) {\n await fs.cp(path.join(tempDir, PROJECT_PATHS.STORAGE_SERVICE), storageServicePath, {\n recursive: true,\n });\n }\n\n // Restore common and utility types (needed for http types)\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.COMMON_TYPES_DIR),\n path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR),\n { recursive: true },\n );\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.UTILITY_TYPES_DIR),\n path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR),\n { recursive: true },\n );\n\n // 2. Copy HTTP Shared Utilities\n // token-store.ts\n await copyFile(\n path.join(tempHttpUtilsPath, 'token-store.ts'),\n path.join(httpUtilsPath, 'token-store.ts'),\n );\n\n // client-utils.ts\n await copyFile(\n path.join(tempHttpUtilsPath, 'client-utils.ts'),\n path.join(httpUtilsPath, 'client-utils.ts'),\n );\n\n // 3. Remove specified clients if requested\n if (removeClients && removeClients.length > 0) {\n for (const client of removeClients) {\n const clientPath = path.join(\n projectPath,\n client === 'fetch' ? PROJECT_PATHS.FETCH_CLIENT : PROJECT_PATHS.AXIOS_CLIENT,\n );\n await deleteDirectory(clientPath);\n }\n }\n\n // 4. Copy specified client(s)\n for (const client of clients) {\n if (client === 'fetch') {\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.FETCH_CLIENT),\n path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT),\n { recursive: true },\n );\n } else {\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.AXIOS_CLIENT),\n path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT),\n { recursive: true },\n );\n }\n }\n\n // 5. Copy/Update http/index.ts\n await copyFile(path.join(tempHttpUtilsPath, 'index.ts'), path.join(httpUtilsPath, 'index.ts'));\n\n // 6. Copy http.types.ts\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.HTTP_TYPES),\n path.join(projectPath, PROJECT_PATHS.HTTP_TYPES),\n );\n};\n\nexport const performFullCleanup = async (projectPath: string): Promise<void> => {\n const { isFileUsed, isStringUsed } = await import('./injectors');\n\n // 1. Remove Directories (Unconditional for HTTP utils as they are client-specific)\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.HTTP_UTILS));\n\n // Check storage service usage before deletion\n const storageServicePath = path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE);\n if (fileExists(storageServicePath)) {\n // Check if SecureStorageService is used anywhere else (excluding the service itself)\n // Note: HTTP_UTILS is already deleted, so we don't need to exclude it.\n const isUsed = await isStringUsed(projectPath, 'SecureStorageService', [storageServicePath]);\n if (!isUsed) {\n await deleteDirectory(storageServicePath);\n }\n }\n\n // 2. Smart Cleanup for Shared Files\n\n // User requested to keep app-apis.ts even if unused\n // const appApisPath = path.join(projectPath, PROJECT_PATHS.APP_APIS);\n // const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n // await deleteIfUnused(...)\n\n // Check constants.ts - Check for 'API_RESPONSE_DATA_KEY' symbol usage\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (fileExists(constantsPath)) {\n let content = await readFile(constantsPath);\n let modified = false;\n\n // Check API_RESPONSE_DATA_KEY\n const isApiKeyUsed = await isStringUsed(projectPath, 'API_RESPONSE_DATA_KEY', [constantsPath]);\n if (!isApiKeyUsed) {\n content = content.replace(/export const API_RESPONSE_DATA_KEY = .*;\\n?/g, '');\n modified = true;\n }\n\n // Check SAVE_AUTH_TOKENS\n const isAuthTokenUsed = await isStringUsed(projectPath, 'SAVE_AUTH_TOKENS', [constantsPath]);\n if (!isAuthTokenUsed) {\n content = content.replace(/export const SAVE_AUTH_TOKENS = .*;\\n?/g, '');\n modified = true;\n }\n\n if (modified) {\n // Clean up extra newlines if any\n content = content.replace(/\\n\\s*\\n/g, '\\n\\n').trim() + '\\n';\n await writeFile(constantsPath, content);\n }\n }\n\n // Check errors directory\n const errorsDir = path.join(projectPath, PROJECT_PATHS.ERRORS_DIR);\n if (fileExists(errorsDir)) {\n // Check if any file in errors dir is used\n const errorFiles = await fs.readdir(errorsDir);\n let isAnyErrorUsed = false;\n\n for (const file of errorFiles) {\n const name = path.parse(file).name; // e.g. 'api-error'\n if (await isFileUsed(projectPath, name, [path.join(errorsDir, file)])) {\n isAnyErrorUsed = true;\n break;\n }\n }\n\n if (!isAnyErrorUsed) {\n await deleteDirectory(errorsDir);\n }\n }\n\n // 3. Remove http.types.ts\n // User requested to keep http.types.ts\n // const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n // if (fileExists(httpTypesPath)) {\n // await fs.unlink(httpTypesPath);\n // }\n\n // 4. Cleanup Types Directories if empty\n // Check common types\n const commonTypesPath = path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR);\n if (fileExists(commonTypesPath)) {\n const files = await fs.readdir(commonTypesPath);\n if (files.length === 0) {\n await deleteDirectory(commonTypesPath);\n }\n }\n\n // Check utility types\n const utilityTypesPath = path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR);\n if (fileExists(utilityTypesPath)) {\n const files = await fs.readdir(utilityTypesPath);\n if (files.length === 0) {\n await deleteDirectory(utilityTypesPath);\n }\n }\n};\n", "import { Command } from 'commander';\nimport { registerAppCommand } from './app';\nimport { registerFeatureCommand } from './feature';\nimport { registerSliceCommand } from './slice';\nimport { registerServiceCommand } from './service';\nimport { registerSetupCommand } from './setup';\n\nexport const registerCommands = (program: Command) => {\n registerAppCommand(program);\n registerSetupCommand(program);\n registerFeatureCommand(program);\n registerSliceCommand(program);\n registerServiceCommand(program);\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["fs", "path", "existsSync", "readFile", "writeFile", "copyFile", "deleteFile", "deleteDirectory", "updateJson", "fileExists", "init_files", "__esmMin", "filePath", "content", "source", "destination", "dirPath", "update", "json", "updatedJson", "paths_exports", "__export", "PROJECT_PATHS", "init_paths", "__esmMin", "injectors_exports", "__export", "cleanupHttpTypes", "isFileUsed", "isStringUsed", "migrateClientUsages", "removeHttpExports", "updateConfigIndex", "updateHttpIndex", "updateTypesIndex", "updateUtilsIndex", "path", "exec", "promisify", "execAsync", "init_injectors", "__esmMin", "init_files", "init_paths", "projectPath", "clients", "httpIndexPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "utilsIndexPath", "typesIndexPath", "configIndexPath", "httpTypesPath", "fromClient", "toClient", "fromName", "toName", "fromPath", "toPath", "srcPath", "grepCommand", "stdout", "filePaths", "f", "filePath", "modified", "namedImportRegex", "defaultImportRegex", "usageRegex", "standaloneRegex", "error", "commonTypesDir", "commonIndexPath", "commonContent", "importPath", "excludePaths", "match", "absoluteMatchPath", "exclude", "searchString", "Command", "path", "pc", "ora", "startSpinner", "text", "options", "spinner", "Enquirer", "prompt", "promptForProjectDetails", "initialName", "response", "value", "httpsPattern", "sshPattern", "answers", "baseUrl", "init_files", "exec", "promisify", "execAsync", "initializeGit", "cwd", "gitRemote", "error", "exec", "promisify", "execAsync", "installDependencies", "cwd", "manager", "command", "error", "runScript", "script", "getPackageManager", "userAgent", "detectPackageManager", "existsSync", "path", "installPackages", "packages", "getInstallCommand", "installPackage", "packageName", "uninstallPackages", "getUninstallCommand", "uninstallPackage", "pc", "colorMap", "s", "print", "message", "color", "colorFn", "text", "error", "message", "print", "logError", "log", "message", "print", "printBanner", "setupCancellationHandlers", "options", "logger", "m", "exitOnCancel", "onCancel", "onUncaught", "err", "onRejection", "reason", "capitalize", "str", "kebabToCamel", "_", "letter", "kebabToPascal", "ora", "spinner", "degit", "cloneTemplate", "projectPath", "spinner", "startSpinner", "degit", "error", "init_files", "path", "init_paths", "PACKAGES", "configurePackageJson", "projectPath", "answers", "spinner", "startSpinner", "gitRemote", "gitHomepage", "gitIssues", "updateJson", "path", "PROJECT_PATHS", "pkg", "PACKAGES", "error", "init_files", "path", "init_paths", "init_injectors", "cleanupFeatures", "projectPath", "answers", "spinner", "startSpinner", "cleanupHttpClient", "cleanupSecureStorage", "cleanupRedux", "cleanupDarkMode", "cleanupI18n", "cleanupLicense", "cleanupChangelog", "cleanupConfig", "error", "httpUtilsPath", "path", "PROJECT_PATHS", "keepSecureStorage", "deleteDirectory", "writeFile", "deleteFile", "cleanupHttpTypes", "utilsIndexPath", "fileExists", "content", "readFile", "configIndexPath", "constantsPath", "typesIndexPath", "httpTypesPath", "typesContent", "providersIndexPath", "providersIndexContent", "pagesToClean", "pagePath", "globalsCssPath", "cssContent", "layoutPath", "layoutContent", "nextConfigPath", "configContent", "counterComponentPath", "init_files", "init_paths", "path", "generateRootProvider", "projectPath", "answers", "imports", "providers", "rootProviderContent", "content", "writeFile", "PROJECT_PATHS", "generateLayout", "basicLayout", "counterImport", "counterComponent", "basicPage", "init_files", "init_paths", "path", "readdir", "setupDevTools", "projectPath", "answers", "setupPreCommitHooks", "setupCommitizen", "setupCiCd", "setupGithubTemplates", "setupCommunityFiles", "setupDocker", "setupReadme", "deleteDirectory", "path", "PROJECT_PATHS", "deleteFile", "updateJson", "pkg", "PACKAGES", "githubPath", "issueTemplatePath", "prTemplatePath", "replacePlaceholders", "content", "fileExists", "readFile", "writeFile", "files", "readdir", "file", "filePath", "allCommunityFiles", "envPath", "envContent", "updateEnvVar", "key", "value", "regex", "findReadmes", "dir", "entries", "entry", "fullPath", "allReadmes", "rootReadmePath", "readmePath", "simpleReadme", "registerAppCommand", "program", "name", "createApp", "initialName", "printBanner", "log", "answers", "promptForProjectDetails", "projectPath", "path", "fileExists", "pc", "spinner", "startSpinner", "performCleanup", "deleteDirectory", "cleanupErr", "handleSignal", "cloneTemplate", "configurePackageJson", "cleanupFeatures", "generateRootProvider", "generateLayout", "setupDevTools", "initializeGit", "installDependencies", "runScript", "envExamplePath", "envPath", "err", "pc", "path", "Enquirer", "prompt", "promptForFeatureDetails", "featureName", "hasRedux", "httpClient", "skipStore", "storeOption", "skipService", "serviceClient", "questions", "value", "answers", "readFile", "access", "path", "detectProjectSetup", "projectPath", "hasRedux", "hasAxios", "hasFetch", "hasI18n", "packageJsonPath", "packageJsonContent", "packageJson", "dependencies", "axiosClientPath", "fetchClientPath", "httpClient", "error", "featureExists", "featureName", "basePath", "featurePath", "writeFile", "mkdir", "path", "generateFeatureStructure", "options", "featurePath", "mkdir", "path", "generateComponentFile", "generateHookFile", "generateTypesFile", "generateIndexFile", "generateStoreFiles", "generateServiceFile", "generateComponentFile", "options", "featureName", "featurePath", "componentName", "kebabToPascal", "hookName", "content", "writeFile", "path", "generateHookFile", "createStore", "generateTypesFile", "generateStoreFiles", "persistStore", "camelName", "kebabToCamel", "sliceContent", "selectorsContent", "persistContent", "storeIndexContent", "generateServiceFile", "httpClient", "generateIndexFile", "createService", "readFile", "writeFile", "path", "registerFeatureInRootReducer", "projectPath", "featureName", "withPersist", "basePath", "path", "rootReducerPath", "content", "readFile", "camelName", "kebabToCamel", "reducerName", "importName", "importPath", "importStatement", "importRegex", "imports", "lastImport", "lastImportIndex", "combineReducersRegex", "match", "reducersContent", "newReducerEntry", "updatedReducersContent", "writeFile", "error", "registerSliceInRootReducer", "sliceName", "readFile", "writeFile", "path", "registerApiEndpoints", "options", "serviceName", "projectPath", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "closingBracePattern", "insertPosition", "beforeClosing", "afterClosing", "hasExistingEndpoints", "needsComma", "updatedContent", "writeFile", "error", "registerFeatureCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "featureOptions", "promptForFeatureDetails", "basePath", "path", "featurePath", "featureExists", "generateFeatureStructure", "registerApiEndpoints", "registerFeatureInRootReducer", "displayPath", "importPath", "error", "pc", "path", "existsSync", "mkdir", "Enquirer", "prompt", "promptForSliceDetails", "sliceName", "persist", "noPersist", "questions", "value", "answers", "writeFile", "mkdir", "path", "generateSliceFiles", "options", "sliceName", "slicePath", "persistSlice", "mkdir", "componentName", "kebabToPascal", "camelName", "kebabToCamel", "generateTypesFile", "generateSliceFile", "generateSelectorsFile", "generatePersistFile", "generateIndexFile", "content", "writeFile", "path", "access", "path", "sliceExists", "projectPath", "sliceName", "basePath", "slicePath", "registerSliceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "sliceOptions", "promptForSliceDetails", "basePath", "featureName", "slicePath", "customPath", "path", "featureStorePath", "existsSync", "mkdir", "sliceExists", "generateSliceFiles", "registerSliceInRootReducer", "displayPath", "importPath", "error", "pc", "path", "existsSync", "mkdir", "enquirer", "promptForServiceDetails", "name", "axiosFlag", "fetchFlag", "availableClients", "serviceName", "input", "httpClient", "writeFile", "path", "generateServiceFiles", "options", "generateServiceFile", "serviceName", "servicePath", "httpClient", "camelName", "kebabToCamel", "content", "fileName", "writeFile", "path", "existsSync", "path", "serviceExists", "projectPath", "serviceName", "basePath", "servicePath", "registerServiceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "availableClients", "serviceOptions", "promptForServiceDetails", "basePath", "featureName", "servicePath", "customPath", "path", "existsSync", "mkdir", "serviceExists", "generateServiceFiles", "registerApiEndpoints", "displayPath", "importPath", "error", "pc", "Enquirer", "init_files", "path", "pc", "init_files", "init_paths", "path", "init_files", "init_paths", "path", "findLayoutPath", "projectPath", "possibleLayoutPaths", "PROJECT_PATHS", "p", "fileExists", "readFile", "checkIsAlreadySetup", "projectPath", "themeProviderPath", "path", "PROJECT_PATHS", "globalsCssPath", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "layoutPath", "findLayoutPath", "init_files", "init_paths", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyThemeProvider", "projectPath", "themeProviderPath", "PROJECT_PATHS", "sourceProviderPath", "copyFile", "init_files", "init_paths", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "rootProviderContent", "useClientDirective", "hasUseClient", "returnMatch", "existingJsx", "updateGlobalsCss", "tempDir", "globalsCssPath", "sourceCssPath", "darkThemeCss", "sourceCss", "variantMatch", "themeMatch", "cssContent", "lastImportIndex", "endOfLineIndex", "updateLayout", "layoutPath", "layoutContent", "setupDarkTheme", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "layoutPath", "validateProjectStructure", "fetchAssets", "copyThemeProvider", "updateProvidersIndex", "updateRootProvider", "updateGlobalsCss", "updateLayout", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "pc", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "storePath", "path", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "findLayoutPath", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyReduxFiles", "projectPath", "sourceProviderPath", "destProviderPath", "PROJECT_PATHS", "copyFile", "sourceStoreDir", "destStoreDir", "createCounterFeature", "sourceFeatureDir", "destFeatureDir", "counterComponentPath", "fileExists", "content", "readFile", "writeFile", "init_files", "init_paths", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "rootProviderContent", "useClientDirective", "hasUseClient", "returnMatch", "existingJsx", "updatePage", "possiblePagePaths", "pagePath", "p", "pageContent", "lastDivIndex", "lastMainIndex", "insertIndex", "setupRedux", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyReduxFiles", "createCounterFeature", "updateProvidersIndex", "updateRootProvider", "updatePage", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "pc", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "i18nDir", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "rootLayoutPath", "localeLayoutPath", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyI18nFiles", "projectPath", "sourceI18nDir", "destI18nDir", "PROJECT_PATHS", "sourceProxyPath", "destProxyPath", "copyFile", "sourceTypesPath", "destTypesPath", "sourceLocalesPath", "destLocalesPath", "init_files", "init_paths", "path", "fs", "updateNextConfig", "projectPath", "nextConfigPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRegex", "writeFile", "updateTypesIndex", "typesIndexPath", "updateConfigIndex", "configIndexPath", "updateRootProvider", "rootProviderPath", "useClientDirective", "hasUseClient", "componentRegex", "match", "returnMatch", "existingJsx", "newJsx", "migrateToLocaleStructure", "rootLayoutPath", "rootPagePath", "localeDir", "destLayoutPath", "metadataEndIndex", "insertPos", "functionBodyRegex", "functionMatch", "bodyStartRegex", "bodyMatch", "bodyOpenBrace", "deleteFile", "destPagePath", "logic", "braceIndex", "setupI18n", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyI18nFiles", "updateNextConfig", "updateTypesIndex", "updateConfigIndex", "updateRootProvider", "migrateToLocaleStructure", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "fs", "pc", "Enquirer", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "fetchClientPath", "PROJECT_PATHS", "axiosClientPath", "hasFetch", "fileExists", "hasAxios", "validateProjectStructure", "missingPaths", "p", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyHttpClientFiles", "projectPath", "clients", "removeClients", "httpUtilsPath", "PROJECT_PATHS", "tempHttpUtilsPath", "appApisPath", "fileExists", "copyFile", "constantsPath", "content", "readFile", "modified", "writeFile", "storageServicePath", "client", "clientPath", "deleteDirectory", "performFullCleanup", "isFileUsed", "isStringUsed", "errorsDir", "errorFiles", "isAnyErrorUsed", "file", "name", "commonTypesPath", "utilityTypesPath", "init_injectors", "setupHttpClient", "projectPath", "spinner", "startSpinner", "tempDir", "path", "status", "reason", "checkIsAlreadySetup", "action", "determineAction", "pc", "validateProjectStructure", "fetchAssets", "migrateClientUsages", "clientsToRemove", "copyHttpClientFiles", "PROJECT_PATHS", "client", "clientPath", "deleteDirectory", "getActiveClients", "performFullCleanup", "removeHttpExports", "activeClients", "updateHttpIndex", "updateUtilsIndex", "updateTypesIndex", "updateConfigIndex", "cleanupHttpTypes", "packageJsonPath", "packageJson", "fs", "dependencies", "installPackage", "uninstallPackage", "storageServicePath", "fileExists", "packageManager", "detectPackageManager", "runScript", "getSuccessMessage", "error", "choice", "Enquirer", "c", "from", "to", "prompt", "Enquirer", "registerSetupCommand", "program", "options", "log", "pc", "setupHttpClient", "setupDarkTheme", "setupRedux", "setupI18n", "feature", "error", "spinner", "logError", "registerCommands", "program", "registerAppCommand", "registerSetupCommand", "registerFeatureCommand", "registerSliceCommand", "registerServiceCommand", "originalEmitWarning", "warning", "_type", "_code", "_ctor", "main", "setupCancellationHandlers", "m", "error", "program", "Command", "registerCommands", "err", "message"]
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\n\nexport const readFile = async (filePath: string): Promise<string> => {\n return fs.readFile(filePath, 'utf-8');\n};\n\nexport const writeFile = async (filePath: string, content: string): Promise<void> => {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf-8');\n};\n\nexport const copyFile = async (source: string, destination: string): Promise<void> => {\n await fs.mkdir(path.dirname(destination), { recursive: true });\n await fs.copyFile(source, destination);\n};\n\nexport const deleteFile = async (filePath: string): Promise<void> => {\n if (existsSync(filePath)) {\n await fs.unlink(filePath);\n }\n};\n\nexport const deleteDirectory = async (dirPath: string): Promise<void> => {\n if (existsSync(dirPath)) {\n await fs.rm(dirPath, { recursive: true, force: true });\n }\n};\n\nexport const updateJson = async <T = any>(\n filePath: string,\n update: (json: T) => T,\n): Promise<void> => {\n const content = await readFile(filePath);\n const json = JSON.parse(content) as T;\n const updatedJson = update(json);\n await writeFile(filePath, JSON.stringify(updatedJson, null, 2));\n};\n\nexport const fileExists = (filePath: string): boolean => {\n return existsSync(filePath);\n};\n", "export const PROJECT_PATHS = {\n // Config\n NEXT_CONFIG: 'next.config.ts',\n TAILWIND_CONFIG: 'tailwind.config.ts',\n POSTCSS_CONFIG: 'postcss.config.mjs',\n ESLINT_CONFIG: 'eslint.config.mjs',\n TS_CONFIG: 'tsconfig.json',\n PACKAGE_JSON: 'package.json',\n ENV_EXAMPLE: '.env.example',\n GITIGNORE: '.gitignore',\n README: 'README.md',\n LICENSE: 'LICENSE',\n CHANGELOG: 'CHANGELOG.md',\n NVM_RC: '.nvmrc',\n NPM_RC: '.npmrc',\n\n // Source\n SRC: 'src',\n APP: 'src/app',\n COMPONENTS: 'src/components',\n LIB: 'src/lib',\n PROVIDERS: 'src/providers',\n STYLES: 'src/styles',\n TYPES: 'src/types',\n UTILS: 'src/lib/utils',\n HOOKS: 'src/hooks',\n SERVICES: 'src/services',\n STORE: 'src/store',\n I18N: 'src/i18n',\n\n // Specific Files\n GLOBALS_CSS: 'src/styles/globals.css',\n ROOT_LAYOUT: 'src/app/layout.tsx',\n ROOT_PAGE: 'src/app/page.tsx',\n ROOT_PROVIDER: 'src/providers/RootProvider.tsx',\n PROVIDERS_INDEX: 'src/providers/index.ts',\n COMPONENTS_INDEX: 'src/components/index.ts',\n TYPES_INDEX: 'src/types/index.ts',\n UTILS_INDEX: 'src/lib/utils/index.ts',\n CONFIG_INDEX: 'src/lib/config/index.ts',\n CONSTANTS: 'src/lib/config/constants.ts',\n APP_LOCALES: 'src/lib/config/app-locales.ts',\n MIDDLEWARE: 'src/middleware.ts',\n PROXY: 'src/proxy.ts',\n I18N_TYPES: 'src/types/i18n.ts',\n\n // Directories to Cleanup\n HTTP_UTILS: 'src/lib/utils/http',\n AXIOS_CLIENT: 'src/lib/utils/http/axios-client',\n FETCH_CLIENT: 'src/lib/utils/http/fetch-client',\n AXIOS_CLIENT_FILE: 'src/lib/utils/http/axios-client/index.ts',\n FETCH_CLIENT_FILE: 'src/lib/utils/http/fetch-client/index.ts',\n CLIENT_UTILS: 'src/lib/utils/http/client-utils.ts',\n APP_APIS: 'src/lib/config/app-apis.ts',\n STORAGE_SERVICE: 'src/services/storage',\n COUNTER_FEATURE: 'src/features/counter',\n I18N_DIR: 'src/i18n',\n LOCALE_DIR: 'src/app/[locale]',\n ERRORS_DIR: 'src/lib/errors',\n UTILITY_TYPES_DIR: 'src/types/utility',\n COMMON_TYPES_DIR: 'src/types/common',\n HTTP_TYPES: 'src/types/common/http.types.ts',\n GITHUB_DIR: '.github',\n HUSKY_DIR: '.husky',\n STORE_PROVIDER: 'src/providers/StoreProvider.tsx',\n THEME_PROVIDER: 'src/providers/CustomThemeProvider.tsx',\n COUNTER_COMPONENT: 'src/features/counter/components/Counter.tsx',\n LOCALE_PAGE: 'src/app/[locale]/page.tsx',\n\n // Config files\n COMMITLINT_CONFIG: 'commitlint.config.mjs',\n LINTSTAGED_RC: '.lintstagedrc.mjs',\n CZRC: '.czrc',\n DOCKERIGNORE: '.dockerignore',\n DOCKERFILE: 'Dockerfile',\n DOCKER_COMPOSE: 'docker-compose.yml',\n\n // GitHub\n GITHUB_WORKFLOWS: '.github/workflows',\n GITHUB_ISSUE_TEMPLATE: 'ISSUE_TEMPLATE',\n GITHUB_PR_TEMPLATE: 'PULL_REQUEST_TEMPLATE.md',\n\n // Community files\n CODE_OF_CONDUCT: 'CODE_OF_CONDUCT.md',\n CONTRIBUTING: 'CONTRIBUTING.md',\n SECURITY: 'SECURITY.md',\n} as const;\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const updateHttpIndex = async (\n projectPath: string,\n clients: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpIndexPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS, 'index.ts');\n if (fileExists(httpIndexPath)) {\n let content = await readFile(httpIndexPath);\n\n // Remove all client exports first\n content = content.replace(/export .* from '\\.\\/axios-client';?\\n?/g, '');\n content = content.replace(/export .* from '\\.\\/fetch-client';?\\n?/g, '');\n\n // Add exports for active clients\n if (clients.includes('fetch') && !content.includes('fetch-client')) {\n content += \"export * from './fetch-client';\\n\";\n }\n if (clients.includes('axios') && !content.includes('axios-client')) {\n content += \"export * from './axios-client';\\n\";\n }\n\n await writeFile(httpIndexPath, content);\n }\n};\n\nexport const updateUtilsIndex = async (projectPath: string): Promise<void> => {\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n if (!content.includes('./http')) {\n content += \"export * from './http';\\n\";\n await writeFile(utilsIndexPath, content);\n }\n }\n};\n\nexport const updateTypesIndex = async (projectPath: string): Promise<void> => {\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n if (!content.includes('./common')) {\n content += \"export * from './common';\\n\";\n }\n if (!content.includes('./utility')) {\n content += \"export * from './utility';\\n\";\n }\n await writeFile(typesIndexPath, content);\n }\n};\n\nexport const updateConfigIndex = async (projectPath: string): Promise<void> => {\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n if (!content.includes('./app-apis')) {\n content += \"export * from './app-apis';\\n\";\n await writeFile(configIndexPath, content);\n }\n }\n};\n\nexport const cleanupHttpTypes = async (\n projectPath: string,\n clients: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let content = await readFile(httpTypesPath);\n\n // If axios is NOT in clients, remove the axios module declaration\n if (!clients.includes('axios')) {\n // Remove declare module 'axios' { ... } block\n // Matches: declare module 'axios' { export interface AxiosRequestConfig { ... } }\n content = content.replace(\n /declare module 'axios'\\s*\\{\\s*export interface AxiosRequestConfig\\s*\\{[\\s\\S]*?\\}\\s*\\}/g,\n '',\n );\n // Clean up any double newlines left behind\n content = content.replace(/\\n\\s*\\n/g, '\\n\\n').trim() + '\\n';\n await writeFile(httpTypesPath, content);\n }\n }\n};\n\n/**\n * Migrate all HTTP client import and usage patterns when replacing one client with another\n * Example: fetch -> axios will replace all fetchClient imports/usages with axiosClient\n */\nexport const migrateClientUsages = async (\n projectPath: string,\n fromClient: 'fetch' | 'axios',\n toClient: 'fetch' | 'axios',\n): Promise<void> => {\n if (fromClient === toClient) return;\n\n const fromName = fromClient === 'fetch' ? 'fetchClient' : 'axiosClient';\n const toName = toClient === 'fetch' ? 'fetchClient' : 'axiosClient';\n const fromPath = fromClient === 'fetch' ? 'fetch-client' : 'axios-client';\n const toPath = toClient === 'fetch' ? 'fetch-client' : 'axios-client';\n\n // Find all .ts and .tsx files in src directory\n const srcPath = path.join(projectPath, 'src');\n\n try {\n // Use grep to find files with HTTP client imports\n const grepCommand = `grep -rl \"${fromName}\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n // No files found with the client name\n return;\n }\n\n const filePaths = stdout\n .trim()\n .split('\\n')\n .filter((f) => f);\n\n for (const filePath of filePaths) {\n if (!fileExists(filePath)) continue;\n\n let content = await readFile(filePath);\n let modified = false;\n\n // Replace import statements\n // Pattern 1: import { fetchClient } from '@/lib/http'\n const namedImportRegex = new RegExp(\n `(import\\\\s*\\\\{[^}]*?)\\\\b${fromName}\\\\b([^}]*?\\\\}\\\\s*from\\\\s*['\"][^'\"]*?/http['\"])`,\n 'g',\n );\n if (namedImportRegex.test(content)) {\n content = content.replace(namedImportRegex, `$1${toName}$2`);\n modified = true;\n }\n\n // Pattern 2: import fetchClient from '@/lib/http/fetch-client'\n const defaultImportRegex = new RegExp(\n `import\\\\s+${fromName}\\\\s+from\\\\s+['\"]([^'\"]*?)/${fromPath}['\"]`,\n 'g',\n );\n if (defaultImportRegex.test(content)) {\n content = content.replace(defaultImportRegex, `import ${toName} from '$1/${toPath}'`);\n modified = true;\n }\n\n // Pattern 3: Replace all usage instances (e.g., fetchClient.get -> axiosClient.get)\n const usageRegex = new RegExp(`\\\\b${fromName}\\\\b(?=\\\\.)`, 'g');\n if (usageRegex.test(content)) {\n content = content.replace(usageRegex, toName);\n modified = true;\n }\n\n // Pattern 4: Replace standalone references (e.g., const api = fetchClient)\n const standaloneRegex = new RegExp(`\\\\b${fromName}\\\\b(?![.\\\\w])`, 'g');\n if (standaloneRegex.test(content)) {\n content = content.replace(standaloneRegex, toName);\n modified = true;\n }\n\n if (modified) {\n await writeFile(filePath, content);\n }\n }\n } catch (error) {\n // If grep fails or no matches found, silently continue\n console.warn('Warning: Could not scan for HTTP client usages:', error);\n }\n};\n\nexport const removeHttpExports = async (projectPath: string): Promise<void> => {\n // 1. Remove from utils/index.ts\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/http['\"];?.*$/gm, '');\n await writeFile(utilsIndexPath, content);\n }\n\n // 2. Remove from types/index.ts\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n\n // Check common types\n const commonTypesDir = path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR);\n if (!fileExists(commonTypesDir)) {\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/common['\"];?.*$/gm, '');\n } else {\n // If directory exists, check if we need to remove http.types export from common/index.ts\n const commonIndexPath = path.join(commonTypesDir, 'index.ts');\n if (fileExists(commonIndexPath)) {\n let commonContent = await readFile(commonIndexPath);\n commonContent = commonContent.replace(\n /^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/http\\.types['\"];?.*$/gm,\n '',\n );\n await writeFile(commonIndexPath, commonContent);\n }\n }\n\n // Check utility types\n if (!fileExists(path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR))) {\n content = content.replace(/^\\s*export\\s+\\*\\s+from\\s+['\"]\\.\\/utility['\"];?.*$/gm, '');\n }\n await writeFile(typesIndexPath, content);\n }\n\n // 3. Remove from config/index.ts - Handled by performFullCleanup smart deletion\n // We don't blindly remove it here anymore because app-apis might be kept if used elsewhere.\n};\n\n/**\n * Check if a file or module is used in the project\n * @param projectPath Root project path\n * @param importPath Import path to search for (e.g., '@/lib/config/app-apis' or 'app-apis')\n * @param excludePaths Array of absolute paths to exclude from search results\n */\nexport const isFileUsed = async (\n projectPath: string,\n importPath: string,\n excludePaths: string[] = [],\n): Promise<boolean> => {\n const srcPath = path.join(projectPath, 'src');\n\n // Escape special characters in import path for grep\n const escapedImportPath = importPath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Search for the import string\n // We look for:\n // 1. from '...importPath...'\n // 2. from \"...importPath...\"\n const grepCommand = `grep -r \"from ['\\\\\"].*${escapedImportPath}.*['\\\\\"]\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n\n try {\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n return false;\n }\n\n const matches = stdout.trim().split('\\n');\n\n // Filter out matches from excluded files\n const validMatches = matches.filter((match) => {\n const [filePath] = match.split(':');\n // Check if file path is in excluded paths\n // We need to resolve relative paths from grep output if necessary,\n // but grep usually outputs full or relative to cwd.\n // Assuming grep runs from cwd, output is relative.\n const absoluteMatchPath = path.resolve(projectPath, filePath);\n\n return !excludePaths.some((exclude) => {\n // Simple check: is the match file the excluded file?\n if (absoluteMatchPath === exclude) return true;\n // Is the match file inside an excluded directory?\n if (absoluteMatchPath.startsWith(exclude + path.sep)) return true;\n return false;\n });\n });\n\n return validMatches.length > 0;\n } catch (error) {\n console.warn(`Warning: Failed to check usage for ${importPath}:`, error);\n // If check fails, assume used to be safe\n return true;\n }\n};\n\n/**\n * Check if a specific string (symbol, class name, etc.) is present in the project files\n * @param projectPath Root project path\n * @param searchString String to search for\n * @param excludePaths Array of absolute paths to exclude from search results\n */\nexport const isStringUsed = async (\n projectPath: string,\n searchString: string,\n excludePaths: string[] = [],\n): Promise<boolean> => {\n const srcPath = path.join(projectPath, 'src');\n\n // Escape special characters\n const escapedString = searchString.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Search for the string anywhere in the files\n // We use -w to match whole words if possible, but for imports it might be part of braces\n // Let's just search for the string.\n const grepCommand = `grep -r \"${escapedString}\" \"${srcPath}\" --include=\"*.ts\" --include=\"*.tsx\" || true`;\n\n try {\n const { stdout } = await execAsync(grepCommand);\n\n if (!stdout.trim()) {\n return false;\n }\n\n const matches = stdout.trim().split('\\n');\n\n // Filter out matches from excluded files\n const validMatches = matches.filter((match) => {\n const [filePath] = match.split(':');\n const absoluteMatchPath = path.resolve(projectPath, filePath);\n\n return !excludePaths.some((exclude) => {\n if (absoluteMatchPath === exclude) return true;\n if (absoluteMatchPath.startsWith(exclude + path.sep)) return true;\n return false;\n });\n });\n\n return validMatches.length > 0;\n } catch (error) {\n console.warn(`Warning: Failed to check usage for string ${searchString}:`, error);\n return true;\n }\n};\n", "import { Command } from 'commander';\nimport { registerCommands } from './commands/index';\nimport { error, setupCancellationHandlers } from './config';\n\n// Suppress the annoying enquirer localstorage warning\n/* eslint-disable @typescript-eslint/no-unused-vars, prefer-rest-params */\nconst originalEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, _type?: any, _code?: any, _ctor?: any) {\n if (\n typeof warning === 'string' &&\n warning.includes('--localstorage-file') &&\n warning.includes('was provided without a valid path')\n ) {\n return; // Suppress this specific warning\n }\n // @ts-expect-error - calling with variable arguments\n return originalEmitWarning.apply(process, arguments);\n};\n/* eslint-enable @typescript-eslint/no-unused-vars, prefer-rest-params */\n\nasync function main() {\n setupCancellationHandlers({ logger: (m: string) => error(m) });\n\n const program = new Command();\n\n program.name('next-maker').description('Teispace Next.js Project Generator').version('1.0.0');\n\n registerCommands(program);\n\n program.parse();\n}\n\nmain().catch((err) => {\n const message =\n err && typeof err === 'object' && 'message' in err ? (err as Error).message : String(err);\n error(`Unexpected error: ${message}`);\n});\n", "import { Command } from 'commander';\nimport path from 'node:path';\nimport pc from 'picocolors';\nimport { startSpinner } from '../config/spinner';\nimport { promptForProjectDetails } from '../prompts/create-app.prompt';\nimport { deleteDirectory, fileExists } from '../core/files';\nimport { initializeGit } from '../core/git';\nimport { installDependencies, runScript } from '../core/package-manager';\nimport { log, printBanner } from '../config';\nimport { cloneTemplate } from '../services/init/template.service';\nimport { configurePackageJson } from '../services/init/config.service';\nimport { cleanupFeatures } from '../services/init/cleanup.service';\nimport { generateRootProvider, generateLayout } from '../services/init/providers.service';\nimport { setupDevTools } from '../services/init/devtools.service';\n\nexport const registerAppCommand = (program: Command) => {\n program\n .command('init')\n .description('Initialize a new Next.js project')\n .argument('[name]', 'Project name')\n .action(async (name) => {\n await createApp(name);\n });\n};\n\nconst createApp = async (initialName?: string): Promise<void> => {\n printBanner();\n log('Welcome to the Teispace Next.js App Creator!');\n log('');\n\n const answers = await promptForProjectDetails(initialName);\n const projectPath = path.resolve(process.cwd(), answers.projectName);\n\n if (fileExists(projectPath)) {\n console.error(pc.red(`Error: Directory ${answers.projectName} already exists.`));\n process.exit(1);\n }\n\n const spinner = startSpinner('Initializing project...');\n\n // Cleanup helper\n const performCleanup = async () => {\n if (fileExists(projectPath)) {\n spinner.stop(); // Stop spinner if running\n console.log(pc.yellow(`\\nCleaning up: Deleting directory ${answers.projectName}...`));\n try {\n await deleteDirectory(projectPath);\n console.log(pc.green('Cleanup successful.'));\n } catch (cleanupErr) {\n console.error(pc.red(`Failed to clean up directory ${answers.projectName}:`), cleanupErr);\n }\n }\n };\n\n // Signal handler\n const handleSignal = async () => {\n console.log(pc.red('\\nProcess interrupted. Cleaning up...'));\n await performCleanup();\n process.exit(1);\n };\n\n // Register signal listeners\n process.on('SIGINT', handleSignal);\n process.on('SIGTERM', handleSignal);\n\n try {\n // 1. Clone template\n await cloneTemplate(projectPath);\n\n // 2. Update package.json\n await configurePackageJson(projectPath, answers);\n\n // 3. Customize Features (Cleanup)\n await cleanupFeatures(projectPath, answers);\n\n // 4. Generate Code (Providers, Layout)\n spinner.text = 'Generating code...';\n await generateRootProvider(projectPath, answers);\n await generateLayout(projectPath, answers);\n\n // 5. Setup DevTools & Community Files\n spinner.text = 'Setting up developer tools...';\n await setupDevTools(projectPath, answers);\n\n // 6. Initialize Git\n spinner.text = 'Initializing Git...';\n // Pass gitRemote to initialize git with remote if provided\n await initializeGit(projectPath, answers.gitRemote, answers.pushToRemote);\n\n // 7. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installDependencies(projectPath, answers.packageManager);\n\n // 8. Format and Lint\n spinner.text = 'Formatting and Linting...';\n await runScript(projectPath, answers.packageManager, 'format');\n await runScript(projectPath, answers.packageManager, 'lint:fix');\n\n // 9. Copy .env.example to .env if requested\n if (answers.copyEnv) {\n spinner.text = 'Creating .env file...';\n const envExamplePath = path.join(projectPath, '.env.example');\n const envPath = path.join(projectPath, '.env');\n if (fileExists(envExamplePath)) {\n const fs = await import('node:fs/promises');\n await fs.copyFile(envExamplePath, envPath);\n }\n }\n\n // Remove signal listeners on success\n process.off('SIGINT', handleSignal);\n process.off('SIGTERM', handleSignal);\n\n spinner.succeed(pc.green(`Project ${answers.projectName} created successfully!`));\n log('');\n log('To get started:');\n log(pc.cyan(` cd ${answers.projectName}`));\n log(\n pc.cyan(\n ` ${answers.packageManager === 'npm' ? 'npm run dev' : answers.packageManager + ' dev'}`,\n ),\n );\n log('');\n } catch (err) {\n spinner.fail('Failed to create project.');\n console.error(err);\n await performCleanup();\n process.exit(1);\n }\n};\n", "import ora, { Ora, Options } from 'ora';\n\n// Create and start a spinner\nexport function startSpinner(text = '', options?: Options): Ora {\n const spinner = ora({ text, ...options });\n spinner.start();\n return spinner;\n}\n\n// Stop a spinner without changing its status\nexport function stopSpinner(spinner: Ora): void {\n spinner.stop();\n}\n\n// Mark spinner as succeeded\nexport function succeedSpinner(spinner: Ora, text?: string): void {\n spinner.succeed(text);\n}\n\n// Mark spinner as failed\nexport function failSpinner(spinner: Ora, text?: string): void {\n spinner.fail(text);\n}\n\n// Run an async function while showing a spinner; auto-succeed/fail\nexport async function withSpinner<T>(\n text: string,\n fn: () => Promise<T>,\n {\n successText,\n failText,\n options,\n }: { successText?: string; failText?: string; options?: Options } = {},\n): Promise<T> {\n const spinner = startSpinner(text, options);\n try {\n const result = await fn();\n spinner.succeed(successText ?? 'Done');\n return result;\n } catch (err) {\n spinner.fail(failText ?? 'Failed');\n throw err;\n }\n}\n\nexport default startSpinner;\n", "import Enquirer from 'enquirer';\nimport { PackageManager } from '../core/package-manager';\n\nconst { prompt } = Enquirer;\n\ntype PromptContext = {\n state?: { answers?: Partial<ProjectPrompts> };\n enquirer?: { answers?: Partial<ProjectPrompts> };\n};\n\nexport interface ProjectPrompts {\n projectName: string;\n description: string;\n author: string;\n version: string;\n packageManager: PackageManager;\n gitRemote: string;\n pushToRemote: boolean;\n gitIssues: string;\n gitHomepage: string;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n reactSecureStorage?: boolean;\n email: string;\n company: string;\n keepTemplates: boolean;\n darkMode: boolean;\n redux: boolean;\n i18n: boolean;\n communityFiles: string[];\n readme: boolean;\n docker: boolean;\n containerName?: string;\n imageName?: string;\n imageTag?: string;\n ci: boolean;\n preCommitHooks: boolean;\n commitizen: boolean;\n copyEnv: boolean;\n}\n\nexport const promptForProjectDetails = async (initialName?: string): Promise<ProjectPrompts> => {\n const response = await prompt<ProjectPrompts>([\n {\n type: 'input',\n name: 'projectName',\n message: 'What is the project name?',\n initial: initialName || 'my-app',\n skip: !!initialName,\n validate: (value: string) => {\n if (!/^[a-z0-9-_]+$/.test(value)) {\n return 'Project name must be lowercase and contain only alphanumeric characters, hyphens, and underscores.';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'description',\n message: 'Project description:',\n initial: 'A Next.js application',\n },\n {\n type: 'input',\n name: 'author',\n message: 'Author:',\n initial: 'Teispace',\n },\n {\n type: 'input',\n name: 'version',\n message: 'Version:',\n initial: '0.1.0',\n validate: (value: string) => {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(value)) {\n return 'Version must be a valid semantic version (x.y.z).';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'email',\n message: 'Support email:',\n initial: 'support@example.com',\n validate: (value: string) => {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n return 'Please enter a valid email address.';\n }\n return true;\n },\n },\n {\n type: 'select',\n name: 'packageManager',\n message: 'Which package manager would you like to use?',\n choices: ['npm', 'yarn', 'pnpm', 'bun'],\n initial: 1,\n },\n {\n type: 'input',\n name: 'gitRemote',\n message: 'GitHub repository URL (optional):',\n initial: '',\n },\n {\n type: 'confirm',\n name: 'pushToRemote',\n message: 'Would you like to push the changes to the remote repository?',\n initial: true,\n skip: function (this: PromptContext) {\n return !this.state?.answers?.gitRemote;\n },\n },\n {\n type: 'input',\n name: 'gitIssues',\n message: 'GitHub issues URL (optional):',\n initial: '',\n skip: function (this: PromptContext) {\n return !this.state?.answers?.gitRemote;\n },\n validate: (value: string) => {\n if (!value) return true;\n // GitHub issues URL pattern: https://github.com/user/repo/issues\n const httpsPattern = /^https:\\/\\/github\\.com\\/[\\w-]+\\/[\\w.-]+\\/issues$/;\n if (!httpsPattern.test(value)) {\n return 'Please enter a valid GitHub issues URL (e.g., https://github.com/user/repo/issues)';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'gitHomepage',\n message: 'GitHub homepage URL (optional):',\n initial: '',\n skip: function (this: PromptContext) {\n return !this.state?.answers?.gitRemote;\n },\n validate: (value: string) => {\n if (!value) return true;\n // GitHub homepage URL pattern: https://github.com/user/repo#readme\n const httpsPattern = /^https:\\/\\/github\\.com\\/[\\w-]+\\/[\\w.-]+#readme$/;\n if (!httpsPattern.test(value)) {\n return 'Please enter a valid GitHub homepage URL (e.g., https://github.com/user/repo#readme)';\n }\n return true;\n },\n },\n {\n type: 'confirm',\n name: 'keepTemplates',\n message: 'Do you want to keep GitHub issue and pull request templates?',\n initial: false,\n },\n {\n type: 'select',\n name: 'httpClient',\n message: 'Which HTTP client do you want to use?',\n choices: ['axios', 'fetch', 'both', 'none'],\n initial: 1,\n },\n {\n type: 'confirm',\n name: 'reactSecureStorage',\n message: 'Do you want to include react-secure-storage?',\n initial: true,\n skip: function (this: PromptContext) {\n // Access answers from the prompt instance safely across versions\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n // If HTTP client is selected (not 'none'), we skip this question (it will be auto-included)\n return !!(answers.httpClient && answers.httpClient !== 'none');\n },\n },\n {\n type: 'confirm',\n name: 'darkMode',\n message: 'Do you want to include Dark Mode (Tailwind + next-themes)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'redux',\n message: 'Do you want to include Redux Toolkit?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'i18n',\n message: 'Do you want to include Internationalization (next-intl)?',\n initial: true,\n },\n {\n type: 'multiselect',\n name: 'communityFiles',\n message: 'Select community files to include:',\n choices: [\n { name: 'CODE_OF_CONDUCT.md', value: 'CODE_OF_CONDUCT.md' },\n { name: 'CONTRIBUTING.md', value: 'CONTRIBUTING.md' },\n { name: 'SECURITY.md', value: 'SECURITY.md' },\n ],\n initial: [],\n },\n {\n type: 'confirm',\n name: 'readme',\n message: 'Do you want to create a README.md?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'docker',\n message: 'Do you want to include Docker configuration?',\n initial: false,\n },\n {\n type: 'input',\n name: 'containerName',\n message: 'Docker Container Name:',\n initial: 'next-app',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(value)) {\n return 'Invalid Docker container name.';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'imageName',\n message: 'Docker Image Name:',\n initial: 'nextjs-starter',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(value)) {\n return 'Invalid Docker image name (must be lowercase).';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'imageTag',\n message: 'Docker Image Tag:',\n initial: 'latest',\n skip: function (this: PromptContext) {\n const answers = this.state?.answers ?? this.enquirer?.answers ?? {};\n return !answers.docker;\n },\n validate: (value: string) => {\n if (!/^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/.test(value)) {\n return 'Invalid Docker image tag.';\n }\n return true;\n },\n },\n {\n type: 'confirm',\n name: 'ci',\n message: 'Do you want to include GitHub Actions (CI/CD)?',\n initial: false,\n },\n {\n type: 'confirm',\n name: 'preCommitHooks',\n message: 'Do you want to setup pre-commit hooks (Husky, Commitlint, Lint-staged)?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'commitizen',\n message: 'Do you want to setup Commitizen?',\n initial: true,\n },\n {\n type: 'confirm',\n name: 'copyEnv',\n message: 'Want to copy .env.example to .env?',\n initial: true,\n },\n ] as any);\n\n // Set company to be the same as author\n response.company = response.author;\n\n // Generate git URLs from gitRemote if provided\n if (response.gitRemote && !response.gitHomepage) {\n const baseUrl = response.gitRemote\n .replace('git@github.com:', 'https://github.com/')\n .replace(/\\.git$/, '');\n response.gitHomepage = `${baseUrl}#readme`;\n response.gitIssues = `${baseUrl}/issues`;\n }\n\n return response;\n};\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const initializeGit = async (\n cwd: string,\n gitRemote?: string,\n pushToRemote?: boolean,\n): Promise<void> => {\n try {\n // Initialize git repository\n await execAsync('git init', { cwd });\n await execAsync('git add .', { cwd });\n await execAsync('git commit -m \"Initial commit from @teispace/next-maker\"', { cwd });\n\n // Add remote origin if GitHub URL is provided\n if (gitRemote) {\n await execAsync(`git remote add origin ${gitRemote}`, { cwd });\n if (pushToRemote) {\n await execAsync(`git fetch origin`, { cwd });\n\n let remoteBranch = 'main';\n try {\n await execAsync('git show-branch origin/main', { cwd });\n } catch {\n try {\n await execAsync('git show-branch origin/master', { cwd });\n remoteBranch = 'master';\n } catch {\n // If neither main nor master exists, we can default to main and let it fail if it doesn't exist.\n remoteBranch = 'main';\n }\n }\n\n await execAsync(`git merge origin/${remoteBranch} --allow-unrelated-histories -X ours`, {\n cwd,\n });\n await execAsync(`git push origin HEAD:${remoteBranch}`, { cwd });\n }\n }\n } catch (error) {\n // Ignore error if git is not installed or fails\n console.warn('Failed to initialize git repository', error);\n }\n};\n\nexport const addRemote = async (cwd: string, url: string): Promise<void> => {\n try {\n await execAsync(`git remote add origin ${url}`, { cwd });\n } catch (error) {\n console.warn('Failed to add remote origin', error);\n }\n};\n\nexport const isGitInstalled = async (): Promise<boolean> => {\n try {\n await execAsync('git --version');\n return true;\n } catch {\n return false;\n }\n};\n", "import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';\n\nexport const installDependencies = async (cwd: string, manager: PackageManager): Promise<void> => {\n const command = `${manager} install`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install dependencies with ${manager}: ${error}`);\n }\n};\n\nexport const runScript = async (\n cwd: string,\n manager: PackageManager,\n script: string,\n): Promise<void> => {\n // npm requires 'run' keyword, but yarn/pnpm/bun don't\n const command = manager === 'npm' ? `${manager} run ${script}` : `${manager} ${script}`;\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n // We don't want to fail the whole setup if linting fails, just warn\n console.warn(`Warning: Failed to run script '${script}': ${error}`);\n }\n};\n\nexport const getPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent;\n if (userAgent) {\n if (userAgent.startsWith('yarn')) return 'yarn';\n if (userAgent.startsWith('pnpm')) return 'pnpm';\n if (userAgent.startsWith('bun')) return 'bun';\n }\n return 'npm';\n};\n\nexport const detectPackageManager = async (cwd: string): Promise<PackageManager> => {\n const { existsSync } = await import('node:fs');\n const path = await import('node:path');\n\n // Check for lock files\n if (existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\n if (existsSync(path.join(cwd, 'bun.lockb'))) return 'bun';\n if (existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\n\n // Fallback to environment variable\n return getPackageManager();\n};\n\nexport const installPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const installCommand = getInstallCommand(manager);\n const command = `${installCommand} ${packages.join(' ')}`;\n\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to install packages with ${manager}: ${error}`);\n }\n};\n\nconst getInstallCommand = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return 'npm install';\n case 'yarn':\n return 'yarn add';\n case 'pnpm':\n return 'pnpm add';\n case 'bun':\n return 'bun add';\n default:\n return 'npm install';\n }\n};\n\nexport const installPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await installPackages(cwd, manager, [packageName]);\n};\n\nexport const uninstallPackages = async (\n cwd: string,\n manager: PackageManager,\n packages: string[],\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const uninstallCommand = getUninstallCommand(manager);\n const command = `${uninstallCommand} ${packages.join(' ')}`;\n\n try {\n await execAsync(command, { cwd });\n } catch (error) {\n throw new Error(`Failed to uninstall packages with ${manager}: ${error}`);\n }\n};\n\nconst getUninstallCommand = (manager: PackageManager): string => {\n switch (manager) {\n case 'npm':\n return 'npm uninstall';\n case 'yarn':\n return 'yarn remove';\n case 'pnpm':\n return 'pnpm remove';\n case 'bun':\n return 'bun remove';\n default:\n return 'npm uninstall';\n }\n};\n\nexport const uninstallPackage = async (cwd: string, packageName: string): Promise<void> => {\n const manager = await detectPackageManager(cwd);\n await uninstallPackages(cwd, manager, [packageName]);\n};\n", "import pc from 'picocolors';\n\n// Define a type for allowed colors explicitly\nexport type Color =\n | 'reset'\n | 'red'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'cyan'\n | 'magenta'\n | 'white'\n | 'gray'\n | 'bright'\n | 'dim';\n\nconst colorMap: Record<Color, (s: string) => string> = {\n reset: (s: string) => s,\n red: pc.red,\n green: pc.green,\n yellow: pc.yellow,\n blue: pc.blue,\n cyan: pc.cyan,\n magenta: pc.magenta,\n white: pc.white,\n gray: pc.gray,\n bright: pc.bold,\n dim: pc.dim,\n};\n\n// Print with color\nexport function print(message: string, color: Color = 'reset'): void {\n const colorFn = colorMap[color] ?? ((text: string) => text);\n console.log(colorFn(message));\n}\n\n// Print section header\nexport function printHeader(title: string): void {\n console.log('');\n print('\u2550'.repeat(60), 'cyan');\n print(` ${title}`, 'bright');\n print('\u2550'.repeat(60), 'cyan');\n console.log('');\n}\n\n// Print success message\nexport function success(message: string): void {\n print(`\u2713 ${message}`, 'green');\n}\n\n// Print error message\nexport function error(message: string): void {\n print(`\u2716 ${message}`, 'red');\n}\n\n// Alias for error\nexport const logError = error;\n\n// Print warning message\nexport function warning(message: string): void {\n print(`\u26A0 ${message}`, 'yellow');\n}\n\n// Print info message\nexport function info(message: string): void {\n print(`\u2139 ${message}`, 'cyan');\n}\n\nexport function log(message: string): void {\n print(message);\n}\n\n// Print banner\nexport function printBanner(): void {\n console.log('');\n print('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557', 'cyan');\n print('\u2551 \u2551', 'cyan');\n print('\u2551 \uD83D\uDE80 Create Teispace Next.js App \uD83D\uDE80 \u2551', 'cyan');\n print('\u2551 \u2551', 'cyan');\n print('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D', 'cyan');\n console.log('');\n}\n", "export type SetupOptions = {\n logger?: (msg: string) => void;\n exitOnCancel?: boolean;\n};\n\nexport function setupCancellationHandlers(options?: SetupOptions): () => void {\n const {\n logger = (m: string) => console.error(m),\n exitOnCancel = process.env.NODE_ENV !== 'test',\n } = options ?? {};\n\n const onCancel = (): void => {\n console.log('');\n console.log('');\n logger('Setup cancelled by user');\n console.log('');\n if (exitOnCancel) process.exit(0);\n };\n\n const onUncaught = (err: unknown): void => {\n if (err !== null && typeof err === 'object' && 'code' in err) {\n const maybeErrWithCode = err as { code?: unknown };\n if (maybeErrWithCode.code === 'ERR_USE_AFTER_CLOSE') {\n onCancel();\n return;\n }\n }\n\n // Log uncaught exceptions instead of throwing so the CLI can report\n // the error and exit gracefully when appropriate.\n if (err instanceof Error) {\n logger(`Uncaught exception: ${err.message}`);\n return;\n }\n logger(`Uncaught exception: ${String(err)}`);\n };\n\n const onRejection = (reason: unknown): void => {\n // Log unhandled promise rejections rather than letting them crash the\n // process. This converts the reason to a readable string safely.\n if (reason instanceof Error) {\n logger(`Unhandled promise rejection: ${reason.message}`);\n return;\n }\n logger(`Unhandled promise rejection: ${String(reason)}`);\n };\n\n process.on('SIGINT', onCancel);\n process.on('SIGTERM', onCancel);\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onRejection as (...args: unknown[]) => void);\n\n // Return a cleanup function to remove listeners (useful in tests).\n return (): void => {\n process.off('SIGINT', onCancel);\n process.off('SIGTERM', onCancel);\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onRejection as (...args: unknown[]) => void);\n };\n}\n\nexport default setupCancellationHandlers;\n", "export const capitalize = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\nexport const kebabToCamel = (str: string): string => {\n return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n};\n\nexport const kebabToPascal = (str: string): string => {\n return capitalize(kebabToCamel(str));\n};\n\nexport const camelToKebab = (str: string): string => {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n};\n", "export * from './output';\nexport * from './errorHandlers';\nexport * from './spinner';\nexport * from './utils';\n\n// Re-export spinner instance\nimport ora from 'ora';\nexport const spinner = ora();\n", "import degit from 'degit';\nimport { startSpinner } from '../../config/spinner';\n\nexport const cloneTemplate = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Downloading template...');\n try {\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: true,\n });\n await emitter.clone(projectPath);\n spinner.succeed('Template downloaded successfully.');\n } catch (error) {\n spinner.fail('Failed to download template.');\n throw error;\n }\n};\n", "import path from 'node:path';\nimport { updateJson } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { startSpinner } from '../../config/spinner';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { PACKAGES } from '../../config/packages';\n\nexport const configurePackageJson = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const spinner = startSpinner('Configuring package.json...');\n try {\n // Generate URLs from GitHub repository URL if provided\n let gitRemote = answers.gitRemote;\n let gitHomepage = answers.gitHomepage;\n let gitIssues = answers.gitIssues;\n\n if (answers.gitRemote) {\n // Convert SSH to HTTPS if needed\n if (answers.gitRemote.startsWith('git@github.com:')) {\n gitRemote = answers.gitRemote\n .replace('git@github.com:', 'https://github.com/')\n .replace(/\\.git$/, '');\n }\n\n // Generate homepage and issues URLs if not provided\n if (!gitHomepage) {\n gitHomepage = `${gitRemote.replace(/\\.git$/, '')}#readme`;\n }\n if (!gitIssues) {\n gitIssues = `${gitRemote.replace(/\\.git$/, '')}/issues`;\n }\n\n // Add .git suffix for repository URL if not present\n if (!gitRemote.endsWith('.git')) {\n gitRemote = `${gitRemote}.git`;\n }\n }\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n pkg.name = answers.projectName;\n pkg.version = answers.version;\n pkg.description = answers.description;\n pkg.author = answers.author;\n\n // Remove packageManager field to avoid \"configured to use yarn\" errors\n // and let the user's environment handle it.\n delete pkg.packageManager;\n\n // Handle git-related fields based on whether GitHub URL was provided\n if (answers.gitRemote) {\n if (gitHomepage) pkg.homepage = gitHomepage;\n if (gitIssues) pkg.bugs = { url: gitIssues };\n if (gitRemote) pkg.repository = { type: 'git', url: gitRemote };\n } else {\n // If no GitHub URL provided, remove template's git-related fields\n delete pkg.homepage;\n delete pkg.bugs;\n delete pkg.repository;\n }\n\n // Remove dependencies based on choices\n if (!answers.redux) {\n delete pkg.dependencies[PACKAGES.REDUX_TOOLKIT];\n delete pkg.dependencies[PACKAGES.REACT_REDUX];\n delete pkg.dependencies[PACKAGES.REDUX_PERSIST];\n }\n\n // Handle react-secure-storage\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n if (!keepSecureStorage) {\n delete pkg.dependencies[PACKAGES.REACT_SECURE_STORAGE];\n }\n if (!answers.i18n) {\n delete pkg.dependencies[PACKAGES.NEXT_INTL];\n }\n if (!answers.darkMode) {\n delete pkg.dependencies[PACKAGES.NEXT_THEMES];\n }\n if (answers.httpClient === 'none') {\n delete pkg.dependencies[PACKAGES.AXIOS];\n } else if (answers.httpClient === 'fetch') {\n delete pkg.dependencies[PACKAGES.AXIOS];\n }\n\n return pkg;\n });\n spinner.succeed('package.json configured.');\n } catch (error) {\n spinner.fail('Failed to configure package.json.');\n throw error;\n }\n};\n", "export const PACKAGES = {\n // Dependencies\n REDUX_TOOLKIT: '@reduxjs/toolkit',\n REACT_REDUX: 'react-redux',\n REDUX_PERSIST: 'redux-persist',\n REACT_SECURE_STORAGE: 'react-secure-storage',\n NEXT_INTL: 'next-intl',\n NEXT_THEMES: 'next-themes',\n AXIOS: 'axios',\n\n // Dev Dependencies\n HUSKY: 'husky',\n COMMITLINT_CLI: '@commitlint/cli',\n COMMITLINT_CONFIG: '@commitlint/config-conventional',\n LINT_STAGED: 'lint-staged',\n COMMITIZEN: 'commitizen',\n CZ_CONVENTIONAL_CHANGELOG: 'cz-conventional-changelog',\n} as const;\n", "import path from 'node:path';\nimport { deleteDirectory, deleteFile, fileExists, readFile, writeFile } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { startSpinner } from '../../config/spinner';\n\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { cleanupHttpTypes } from '../setup/http-client/injectors';\n\n// ... (imports)\n\nexport const cleanupFeatures = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const spinner = startSpinner('Customizing features...');\n try {\n await cleanupHttpClient(projectPath, answers);\n await cleanupSecureStorage(projectPath, answers);\n await cleanupRedux(projectPath, answers);\n await cleanupDarkMode(projectPath, answers);\n await cleanupI18n(projectPath, answers);\n await cleanupLicense(projectPath);\n await cleanupChangelog(projectPath);\n await cleanupConfig(projectPath);\n spinner.succeed('Features customized.');\n } catch (error) {\n spinner.fail('Failed to customize features.');\n throw error;\n }\n};\n\nconst cleanupHttpClient = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const httpUtilsPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS);\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n\n if (answers.httpClient === 'none') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT));\n\n if (keepSecureStorage) {\n await writeFile(path.join(httpUtilsPath, 'index.ts'), \"export * from './token-store';\\n\");\n // token-store.ts does not use client-utils, so we can remove it\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CLIENT_UTILS));\n\n // Ensure http.types.ts is clean (remove axios declaration)\n await cleanupHttpTypes(projectPath, []);\n } else {\n await deleteDirectory(httpUtilsPath);\n const utilsIndexPath = path.join(projectPath, PROJECT_PATHS.UTILS_INDEX);\n if (fileExists(utilsIndexPath)) {\n let content = await readFile(utilsIndexPath);\n content = content.replace(/export \\* from '\\.\\/http';\\n/, '');\n await writeFile(utilsIndexPath, content);\n }\n\n // Remove app-apis.ts if no client and no secure storage (likely no auth)\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_APIS));\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n content = content.replace(/export \\* from '\\.\\/app-apis';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n }\n\n // Remove API constants\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (fileExists(constantsPath)) {\n let content = await readFile(constantsPath);\n content = content.replace(/export const API_RESPONSE_DATA_KEY = 'data';\\n/, '');\n content = content.replace(/export const SAVE_AUTH_TOKENS = false;\\n/, '');\n await writeFile(constantsPath, content);\n }\n\n // Remove errors and types\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.ERRORS_DIR));\n\n // Only remove common types if we don't keep secure storage (TokenStore needs common/http.types.ts)\n if (!keepSecureStorage) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR));\n\n // Update types/index.ts\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n content = content.replace(/export \\* from '\\.\\/utility';\\n/, '');\n content = content.replace(/export \\* from '\\.\\/common';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n }\n } else if (answers.httpClient === 'axios') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT));\n let content = await readFile(path.join(httpUtilsPath, 'index.ts'));\n content = content.replace(/export .* from '\\.\\/fetch-client';\\n/g, '');\n await writeFile(path.join(httpUtilsPath, 'index.ts'), content);\n\n // Remove FetchClientOptions and ExtendedRequestInit from http.types.ts\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n // Remove FetchClientOptions interface\n typesContent = typesContent.replace(\n /export interface FetchClientOptions \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n // Remove ExtendedRequestInit interface\n typesContent = typesContent.replace(\n /export interface ExtendedRequestInit extends RequestInit \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n } else if (answers.httpClient === 'fetch') {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT));\n let content = await readFile(path.join(httpUtilsPath, 'index.ts'));\n content = content.replace(/export .* from '\\.\\/axios-client';\\n/g, '');\n await writeFile(path.join(httpUtilsPath, 'index.ts'), content);\n\n // Remove axios module declaration and AxiosClientOptions from http.types.ts\n // Use the shared helper to ensure robust regex matching\n await cleanupHttpTypes(projectPath, ['fetch']);\n\n // Also remove AxiosClientOptions interface (cleanupHttpTypes only handles module declaration)\n const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n if (fileExists(httpTypesPath)) {\n let typesContent = await readFile(httpTypesPath);\n // Remove AxiosClientOptions interface\n typesContent = typesContent.replace(\n /export interface AxiosClientOptions \\{[\\s\\S]*?\\}\\n\\n/,\n '',\n );\n await writeFile(httpTypesPath, typesContent);\n }\n }\n};\n\nconst cleanupSecureStorage = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const keepSecureStorage = answers.httpClient !== 'none' || answers.reactSecureStorage;\n if (!keepSecureStorage) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE));\n }\n};\n\nconst cleanupRedux = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.redux) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.STORE));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.COUNTER_FEATURE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.STORE_PROVIDER));\n\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersIndexContent = await readFile(providersIndexPath);\n providersIndexContent = providersIndexContent.replace(\n /export \\* from '\\.\\/StoreProvider';\\n/,\n '',\n );\n await writeFile(providersIndexPath, providersIndexContent);\n\n // Cleanup usage in pages\n const pagesToClean = [\n path.join(projectPath, PROJECT_PATHS.ROOT_PAGE),\n path.join(projectPath, PROJECT_PATHS.LOCALE_PAGE),\n ];\n\n for (const pagePath of pagesToClean) {\n if (fileExists(pagePath)) {\n let content = await readFile(pagePath);\n content = content.replace(\n /import\\s+\\{\\s*Counter\\s*\\}\\s+from\\s+['\"]@\\/features\\/counter['\"];\\n?/,\n '',\n );\n content = content.replace(/<Counter\\s*\\/>\\n?/g, '');\n await writeFile(pagePath, content);\n }\n }\n }\n};\n\nconst cleanupDarkMode = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.darkMode) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER));\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersIndexContent = await readFile(providersIndexPath);\n providersIndexContent = providersIndexContent.replace(\n /export \\* from '\\.\\/CustomThemeProvider';\\n/,\n '',\n );\n await writeFile(providersIndexPath, providersIndexContent);\n\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n if (fileExists(globalsCssPath)) {\n let cssContent = await readFile(globalsCssPath);\n // Remove dark mode custom variant\n cssContent = cssContent.replace(/@custom-variant dark \\(.*?\\);\\n\\n/, '');\n // Remove dark and light color definitions\n cssContent = cssContent.replace(/@theme \\{[\\s\\S]*?\\}\\n/, '');\n await writeFile(globalsCssPath, cssContent);\n }\n\n // Remove dark mode classes from layout if not using i18n\n if (!answers.i18n) {\n const layoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n if (fileExists(layoutPath)) {\n let layoutContent = await readFile(layoutPath);\n layoutContent = layoutContent.replace(/bg-light dark:bg-dark /g, '');\n await writeFile(layoutPath, layoutContent);\n }\n }\n }\n};\n\nconst cleanupI18n = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.i18n) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.I18N_DIR));\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.LOCALE_DIR));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.PROXY));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.MIDDLEWARE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.I18N_TYPES));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.APP_LOCALES));\n\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n content = content.replace(/export \\* from '\\.\\/i18n';\\n/, '');\n await writeFile(typesIndexPath, content);\n }\n\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n content = content.replace(/export \\* from '\\.\\/app-locales';\\n/, '');\n await writeFile(configIndexPath, content);\n }\n\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let configContent = await readFile(nextConfigPath);\n configContent = configContent.replace(\n /import createNextIntlPlugin from 'next-intl\\/plugin';\\n/,\n '',\n );\n configContent = configContent.replace(/const withNextIntl = createNextIntlPlugin\\(\\);\\n/, '');\n configContent = configContent.replace(\n /export default withNextIntl\\(nextConfig\\);/,\n 'export default nextConfig;',\n );\n await writeFile(nextConfigPath, configContent);\n }\n\n // Cleanup Counter.tsx if Redux is enabled - remove i18n from Counter component\n const counterComponentPath = path.join(projectPath, PROJECT_PATHS.COUNTER_COMPONENT);\n if (fileExists(counterComponentPath)) {\n let content = await readFile(counterComponentPath);\n content = content.replace(\n /import\\s+\\{\\s*useTranslations\\s*\\}\\s+from\\s+['\"]next-intl['\"];\\n/,\n '',\n );\n content = content.replace(/\\s*const\\s+t\\s*=\\s*useTranslations\\(['\"]Count['\"]\\);\\n/, '');\n content = content.replace(/\\{t\\('currentCount',\\s*\\{\\s*count:\\s*value\\s*\\}\\)\\}/g, '{value}');\n content = content.replace(/\\{t\\(['\"]increment['\"]\\)\\}/g, 'Increment');\n content = content.replace(/\\{t\\(['\"]decrement['\"]\\)\\}/g, 'Decrement');\n content = content.replace(/\\{t\\(['\"]reset['\"]\\)\\}/g, 'Reset');\n await writeFile(counterComponentPath, content);\n }\n }\n};\n\nconst cleanupLicense = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LICENSE));\n};\n\nconst cleanupChangelog = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CHANGELOG));\n};\n\nconst cleanupConfig = async (projectPath: string): Promise<void> => {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.NVM_RC));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.NPM_RC));\n};\n", "import path from 'node:path';\nimport { writeFile } from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { PROJECT_PATHS } from '../../config/paths';\n\nexport const generateRootProvider = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const imports: string[] = [];\n const providers: string[] = [];\n\n if (answers.redux) {\n imports.push(\"import { StoreProvider } from '@/providers';\");\n providers.push('StoreProvider');\n }\n\n if (answers.darkMode) {\n imports.push(\"import { CustomThemeProvider } from '@/providers';\");\n providers.push('CustomThemeProvider');\n }\n\n if (answers.i18n) {\n imports.push(\"import { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';\");\n imports.push(\"import { SupportedLocale } from '@/types/i18n';\");\n }\n\n let rootProviderContent = `'use client';\n${imports.join('\\n')}\n\nexport const RootProvider = ({\n children,\n ${answers.i18n ? 'locale,\\n messages,' : ''}\n}: {\n children: React.ReactNode;\n ${answers.i18n ? 'locale: SupportedLocale;\\n messages: AbstractIntlMessages;' : ''}\n}) => {\n return (\n`;\n\n // Build the nesting\n let content = '{children}';\n\n if (answers.i18n) {\n content = `<NextIntlClientProvider locale={locale} messages={messages}>\n ${content}\n </NextIntlClientProvider>`;\n }\n\n if (answers.darkMode) {\n content = `<CustomThemeProvider>\n ${content}\n </CustomThemeProvider>`;\n }\n\n if (answers.redux) {\n content = `<StoreProvider>\n ${content}\n </StoreProvider>`;\n }\n\n // If no providers are wrapped, ensure we return a valid JSX element (Fragment)\n if (content === '{children}') {\n content = `<>{children}</>`;\n }\n\n rootProviderContent += ` ${content}\n );\n};\n`;\n\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_PROVIDER), rootProviderContent);\n};\n\nexport const generateLayout = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n if (!answers.i18n) {\n const basicLayout = `import type { Metadata } from 'next';\nimport '@/styles/globals.css';\nimport { Livvic } from 'next/font/google';\nimport { RootProvider } from '@/providers';\n\nconst livvic = Livvic({\n subsets: ['latin'],\n variable: '--font-livvic',\n weight: ['100', '200', '300', '400', '500', '600', '700', '900'],\n display: 'swap',\n});\n\nexport const metadata: Metadata = {\n title: '${answers.projectName}',\n description: '${answers.description}',\n};\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n return (\n <html lang=\"en\" suppressHydrationWarning={${answers.darkMode ? 'true' : 'false'}}>\n <body className={\\`\\${livvic.variable} ${answers.darkMode ? 'bg-light dark:bg-dark ' : ''}antialiased\\`}>\n <RootProvider>\n {children}\n </RootProvider>\n </body>\n </html>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT), basicLayout);\n\n // Generate page.tsx with Counter if Redux is enabled\n const counterImport = answers.redux ? \"import { Counter } from '@/features/counter';\\n\\n\" : '';\n const counterComponent = answers.redux ? '\\n <Counter />' : '';\n\n const basicPage = `${counterImport}export default function Home() {\n return (\n <div className=\"flex min-h-screen flex-col items-center justify-center p-24\">\n <h1 className=\"text-4xl font-bold\">Welcome to ${answers.projectName}</h1>\n <p className=\"mt-4 text-xl\">Get started by editing src/app/page.tsx</p>${counterComponent}\n </div>\n );\n}\n`;\n await writeFile(path.join(projectPath, PROJECT_PATHS.ROOT_PAGE), basicPage);\n }\n};\n", "import path from 'node:path';\nimport { readdir } from 'node:fs/promises';\nimport {\n deleteDirectory,\n deleteFile,\n fileExists,\n readFile,\n updateJson,\n writeFile,\n} from '../../core/files';\nimport { ProjectPrompts } from '../../prompts/create-app.prompt';\nimport { PROJECT_PATHS } from '../../config/paths';\nimport { PACKAGES } from '../../config/packages';\n\nexport const setupDevTools = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n await setupPreCommitHooks(projectPath, answers);\n await setupCommitizen(projectPath, answers);\n await setupCiCd(projectPath, answers);\n await setupGithubTemplates(projectPath, answers);\n await setupCommunityFiles(projectPath, answers);\n await setupDocker(projectPath, answers);\n await setupReadme(projectPath, answers);\n};\n\nconst setupPreCommitHooks = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.preCommitHooks) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.HUSKY_DIR));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.COMMITLINT_CONFIG));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.LINTSTAGED_RC));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n delete pkg.devDependencies[PACKAGES.HUSKY];\n delete pkg.devDependencies[PACKAGES.COMMITLINT_CLI];\n delete pkg.devDependencies[PACKAGES.COMMITLINT_CONFIG];\n delete pkg.devDependencies[PACKAGES.LINT_STAGED];\n delete pkg.scripts['prepare'];\n delete pkg.scripts['postinstall'];\n delete pkg.commitlint;\n delete pkg['lint-staged'];\n return pkg;\n });\n }\n};\n\nconst setupCommitizen = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.commitizen) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.CZRC));\n\n await updateJson(path.join(projectPath, PROJECT_PATHS.PACKAGE_JSON), (pkg) => {\n delete pkg.devDependencies[PACKAGES.COMMITIZEN];\n delete pkg.devDependencies[PACKAGES.CZ_CONVENTIONAL_CHANGELOG];\n delete pkg.config?.commitizen;\n if (pkg.config && Object.keys(pkg.config).length === 0) {\n delete pkg.config;\n }\n delete pkg.scripts['commit'];\n return pkg;\n });\n }\n};\n\nconst setupCiCd = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.ci) {\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.GITHUB_WORKFLOWS));\n }\n};\n\nconst setupGithubTemplates = async (\n projectPath: string,\n answers: ProjectPrompts,\n): Promise<void> => {\n const githubPath = path.join(projectPath, PROJECT_PATHS.GITHUB_DIR);\n if (!answers.keepTemplates) {\n await deleteDirectory(path.join(githubPath, PROJECT_PATHS.GITHUB_ISSUE_TEMPLATE));\n await deleteFile(path.join(githubPath, PROJECT_PATHS.GITHUB_PR_TEMPLATE));\n } else {\n const issueTemplatePath = path.join(githubPath, PROJECT_PATHS.GITHUB_ISSUE_TEMPLATE);\n const prTemplatePath = path.join(githubPath, PROJECT_PATHS.GITHUB_PR_TEMPLATE);\n\n const replacePlaceholders = (content: string) => {\n return content\n .replace(/Teispace/g, answers.company)\n .replace(/support@teispace\\.com/g, answers.email)\n .replace(/Next\\.js Starter/g, answers.projectName)\n .replace(/\\[AUTHOR\\]/g, answers.author)\n .replace(/\\[COMPANY\\]/g, answers.company)\n .replace(/\\[EMAIL\\]/g, answers.email);\n };\n\n if (fileExists(prTemplatePath)) {\n let content = await readFile(prTemplatePath);\n content = replacePlaceholders(content);\n await writeFile(prTemplatePath, content);\n }\n\n try {\n if (fileExists(issueTemplatePath)) {\n const files = await readdir(issueTemplatePath);\n for (const file of files) {\n const filePath = path.join(issueTemplatePath, file);\n let content = await readFile(filePath);\n content = replacePlaceholders(content);\n await writeFile(filePath, content);\n }\n }\n } catch {\n // Ignore\n }\n }\n};\n\nconst setupCommunityFiles = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const allCommunityFiles = [\n PROJECT_PATHS.CODE_OF_CONDUCT,\n PROJECT_PATHS.CONTRIBUTING,\n PROJECT_PATHS.SECURITY,\n ];\n for (const file of allCommunityFiles) {\n if (!answers.communityFiles.includes(file)) {\n await deleteFile(path.join(projectPath, file));\n }\n }\n};\n\nconst setupDocker = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n if (!answers.docker) {\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKERFILE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKER_COMPOSE));\n await deleteFile(path.join(projectPath, PROJECT_PATHS.DOCKERIGNORE));\n\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (fileExists(envPath)) {\n let envContent = await readFile(envPath);\n envContent = envContent.replace(/# Docker Compose Configuration\\n/, '');\n envContent = envContent.replace(/CONTAINER_NAME=.*\\n/, '');\n envContent = envContent.replace(/IMAGE_NAME=.*\\n/, '');\n envContent = envContent.replace(/IMAGE_TAG=.*\\n/, '');\n await writeFile(envPath, envContent);\n }\n } else {\n const envPath = path.join(projectPath, PROJECT_PATHS.ENV_EXAMPLE);\n if (fileExists(envPath)) {\n let envContent = await readFile(envPath);\n const updateEnvVar = (key: string, value: string) => {\n const regex = new RegExp(`${key}=.*`);\n if (regex.test(envContent)) {\n envContent = envContent.replace(regex, `${key}=${value}`);\n } else {\n envContent += `${key}=${value}\\n`;\n }\n };\n\n updateEnvVar('CONTAINER_NAME', answers.containerName || 'next-app');\n updateEnvVar('IMAGE_NAME', answers.imageName || 'nextjs-starter');\n updateEnvVar('IMAGE_TAG', answers.imageTag || 'latest');\n\n await writeFile(envPath, envContent);\n }\n }\n};\n\nconst setupReadme = async (projectPath: string, answers: ProjectPrompts): Promise<void> => {\n const findReadmes = async (dir: string): Promise<string[]> => {\n const entries = await readdir(dir, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git') {\n files.push(...(await findReadmes(fullPath)));\n } else if (entry.isFile() && entry.name.toLowerCase() === 'readme.md') {\n files.push(fullPath);\n }\n }\n return files;\n };\n\n const allReadmes = await findReadmes(projectPath);\n const rootReadmePath = path.join(projectPath, PROJECT_PATHS.README);\n\n for (const readmePath of allReadmes) {\n if (readmePath !== rootReadmePath) {\n await deleteFile(readmePath);\n }\n }\n\n if (answers.readme) {\n const simpleReadme = `# ${answers.projectName}\n\n${answers.description}\n\n## Getting Started\n\nFirst, run the development server:\n\n\\`\\`\\`bash\n${answers.packageManager === 'npm' ? 'npm run dev' : answers.packageManager + ' dev'}\n\\`\\`\\`\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n`;\n await writeFile(rootReadmePath, simpleReadme);\n } else {\n await deleteFile(rootReadmePath);\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { log, logError, spinner } from '../config';\nimport { promptForFeatureDetails } from '../prompts/feature.prompt';\nimport { detectProjectSetup, featureExists } from '../services/feature/detection.service';\nimport { generateFeatureStructure } from '../services/feature/templates.service';\nimport { registerFeatureInRootReducer } from '../services/feature/registration.service';\nimport { registerApiEndpoints } from '../services/common/api-registration.service';\n\ninterface FeatureCommandOptions {\n skipStore?: boolean;\n store?: 'persist' | 'no-persist';\n skipService?: boolean;\n service?: 'axios' | 'fetch';\n path?: string;\n}\n\nexport const registerFeatureCommand = (program: Command) => {\n program\n .command('feature [name]')\n .description('Generate a new feature module')\n .option('--skip-store', 'Skip Redux store generation')\n .option('--store <type>', 'Generate Redux store with persistence option (persist|no-persist)')\n .option('--skip-service', 'Skip API service generation')\n .option('--service <client>', 'Generate API service with specific HTTP client (axios|fetch)')\n .option('--path <path>', 'Custom path for feature generation (default: src/features)')\n .action(async (name: string | undefined, options: FeatureCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate store option\n if (options.store && !['persist', 'no-persist'].includes(options.store)) {\n logError('Invalid --store option. Use: persist or no-persist');\n process.exit(1);\n }\n\n // Validate service option\n if (options.service && !['axios', 'fetch'].includes(options.service)) {\n logError('Invalid --service option. Use: axios or fetch');\n process.exit(1);\n }\n\n // Validate conflicting options\n if (options.skipStore && options.store) {\n logError('Cannot use --skip-store and --store together');\n process.exit(1);\n }\n\n if (options.skipService && options.service) {\n logError('Cannot use --skip-service and --service together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83C\uDFAF Feature Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n log(pc.dim(` Redux: ${detection.hasRedux ? '\u2713' : '\u2717'}`));\n log(pc.dim(` HTTP Client: ${detection.httpClient}`));\n log(pc.dim(` i18n: ${detection.hasI18n ? '\u2713' : '\u2717'}\\n`));\n\n // Step 2: Prompt for feature details\n const featureOptions = await promptForFeatureDetails(\n name,\n detection.hasRedux,\n detection.httpClient,\n options.skipStore,\n options.store,\n options.skipService,\n options.service,\n );\n\n // Step 3: Determine feature path\n const basePath = options.path || path.join('src', 'features');\n const featurePath = path.join(projectPath, basePath, featureOptions.featureName);\n\n // Check if feature already exists\n const exists = await featureExists(projectPath, featureOptions.featureName, basePath);\n if (exists) {\n logError(`Feature '${featureOptions.featureName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 4: Generate feature structure\n spinner.start('Generating feature files...');\n\n await generateFeatureStructure({\n featureName: featureOptions.featureName,\n featurePath,\n createStore: featureOptions.createStore,\n persistStore: featureOptions.persistStore,\n createService: featureOptions.createService,\n httpClient: featureOptions.selectedHttpClient,\n });\n\n spinner.succeed('Feature files generated');\n\n // Step 5: Register API endpoints if service was created\n if (featureOptions.createService) {\n spinner.start('Registering API endpoints...');\n await registerApiEndpoints({\n serviceName: featureOptions.featureName,\n projectPath,\n });\n spinner.succeed('API endpoints registered');\n }\n\n // Step 6: Register in rootReducer if store was created\n if (featureOptions.createStore && detection.hasRedux) {\n spinner.start('Registering feature in rootReducer...');\n await registerFeatureInRootReducer(\n projectPath,\n featureOptions.featureName,\n featureOptions.persistStore,\n basePath,\n );\n spinner.succeed('Feature registered in rootReducer');\n }\n\n // Success message\n const displayPath = path.join(basePath, featureOptions.featureName);\n log(pc.green(`\\n\u2728 Feature '${featureOptions.featureName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 components/`));\n log(pc.dim(` \u251C\u2500\u2500 hooks/`));\n log(pc.dim(` \u251C\u2500\u2500 types/`));\n if (featureOptions.createStore) log(pc.dim(` \u251C\u2500\u2500 store/`));\n if (featureOptions.createService) log(pc.dim(` \u251C\u2500\u2500 services/`));\n log(pc.dim(` \u2514\u2500\u2500 index.ts\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import and use the feature: import { ${featureOptions.featureName} } from '${importPath}/${featureOptions.featureName}'`,\n ),\n );\n if (featureOptions.createStore) {\n log(pc.dim(` 2. Customize your Redux slice in: ${displayPath}/store/`));\n }\n if (featureOptions.createService) {\n log(\n pc.dim(\n ` 3. Add API methods in: ${displayPath}/services/${featureOptions.featureName}.service.ts`,\n ),\n );\n }\n log('');\n } catch (error) {\n spinner.fail('Feature generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\nconst { prompt } = Enquirer;\n\nexport interface FeatureOptions {\n featureName: string;\n hasRedux: boolean;\n createStore: boolean;\n persistStore: boolean;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n createService: boolean;\n selectedHttpClient?: 'axios' | 'fetch';\n}\n\nexport const promptForFeatureDetails = async (\n featureName?: string,\n hasRedux?: boolean,\n httpClient?: 'axios' | 'fetch' | 'both' | 'none',\n skipStore?: boolean,\n storeOption?: 'persist' | 'no-persist',\n skipService?: boolean,\n serviceClient?: 'axios' | 'fetch',\n): Promise<FeatureOptions> => {\n const questions: any[] = [];\n\n // Feature name\n if (!featureName) {\n questions.push({\n type: 'input',\n name: 'featureName',\n message: 'What is the feature name?',\n initial: 'my-feature',\n validate: (value: string) => {\n if (!/^[a-z0-9-]+$/.test(value)) {\n return 'Feature name must be lowercase and contain only alphanumeric characters and hyphens.';\n }\n return true;\n },\n });\n }\n\n // Redux store questions\n if (hasRedux && skipStore === undefined && storeOption === undefined) {\n questions.push({\n type: 'confirm',\n name: 'createStore',\n message: 'Generate Redux store for this feature?',\n initial: true,\n });\n\n questions.push({\n type: 'confirm',\n name: 'persistStore',\n message: 'Enable persistence for this store?',\n initial: false,\n skip() {\n // Skip if createStore is false\n\n return !(this as any).state.answers.createStore;\n },\n });\n }\n\n // HTTP service questions\n if (\n httpClient &&\n httpClient !== 'none' &&\n skipService === undefined &&\n serviceClient === undefined\n ) {\n questions.push({\n type: 'confirm',\n name: 'createService',\n message: 'Generate API service for this feature?',\n initial: true,\n });\n\n if (httpClient === 'both') {\n questions.push({\n type: 'select',\n name: 'selectedHttpClient',\n message: 'Which HTTP client to use for the service?',\n choices: ['fetch', 'axios'],\n initial: 0,\n skip() {\n // Skip if createService is false\n\n return !(this as any).state.answers.createService;\n },\n });\n }\n }\n\n const answers: any = questions.length > 0 ? await prompt(questions) : {};\n\n return {\n featureName: featureName || (answers.featureName as string),\n hasRedux: hasRedux || false,\n createStore:\n skipStore === true\n ? false\n : storeOption !== undefined\n ? true\n : (answers.createStore as boolean) || false,\n persistStore:\n storeOption === 'persist'\n ? true\n : storeOption === 'no-persist'\n ? false\n : (answers.persistStore as boolean) || false,\n httpClient: httpClient || 'none',\n createService:\n skipService === true\n ? false\n : serviceClient !== undefined\n ? true\n : (answers.createService as boolean) || false,\n selectedHttpClient:\n serviceClient ||\n (answers.selectedHttpClient as 'axios' | 'fetch' | undefined) ||\n (httpClient === 'both' ? 'fetch' : httpClient !== 'none' ? httpClient : undefined),\n };\n};\n", "import { readFile, access } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface ProjectDetection {\n hasRedux: boolean;\n httpClient: 'axios' | 'fetch' | 'both' | 'none';\n hasI18n: boolean;\n}\n\nexport const detectProjectSetup = async (projectPath: string): Promise<ProjectDetection> => {\n let hasRedux = false;\n let hasAxios = false;\n let hasFetch = false;\n let hasI18n = false;\n\n try {\n // Read package.json\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJsonContent = await readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n // Check for Redux\n hasRedux = !!(dependencies['@reduxjs/toolkit'] && dependencies['react-redux']);\n\n // Check for axios\n hasAxios = !!dependencies['axios'];\n\n // Check for i18n\n hasI18n = !!dependencies['next-intl'];\n\n // Check if axios client exists\n const axiosClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'axios-client');\n try {\n await access(axiosClientPath);\n hasAxios = hasAxios && true; // Confirm axios is both installed and client exists\n } catch {\n hasAxios = false; // Axios client doesn't exist\n }\n\n // Check if fetch client exists\n const fetchClientPath = path.join(projectPath, 'src', 'lib', 'utils', 'http', 'fetch-client');\n try {\n await access(fetchClientPath);\n hasFetch = true;\n } catch {\n hasFetch = false; // Fetch client doesn't exist\n }\n\n // Determine HTTP client setup\n let httpClient: 'axios' | 'fetch' | 'both' | 'none';\n if (hasAxios && hasFetch) {\n httpClient = 'both';\n } else if (hasAxios) {\n httpClient = 'axios';\n } else if (hasFetch) {\n httpClient = 'fetch';\n } else {\n httpClient = 'none';\n }\n\n return {\n hasRedux,\n httpClient,\n hasI18n,\n };\n } catch (error) {\n throw new Error(`Failed to detect project setup: ${error}`);\n }\n};\n\nexport const featureExists = async (\n projectPath: string,\n featureName: string,\n basePath: string = path.join('src', 'features'),\n): Promise<boolean> => {\n const featurePath = path.join(projectPath, basePath, featureName);\n try {\n await access(featurePath);\n return true;\n } catch {\n return false;\n }\n};\n", "import { writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../../config/utils';\n\nexport interface FeatureGenerationOptions {\n featureName: string;\n featurePath: string;\n createStore: boolean;\n persistStore: boolean;\n createService: boolean;\n httpClient?: 'axios' | 'fetch';\n}\n\nexport const generateFeatureStructure = async (\n options: FeatureGenerationOptions,\n): Promise<void> => {\n const { featurePath } = options;\n\n // Create feature directories\n await mkdir(path.join(featurePath, 'components'), { recursive: true });\n await mkdir(path.join(featurePath, 'hooks'), { recursive: true });\n await mkdir(path.join(featurePath, 'types'), { recursive: true });\n\n if (options.createStore) {\n await mkdir(path.join(featurePath, 'store'), { recursive: true });\n }\n\n if (options.createService) {\n await mkdir(path.join(featurePath, 'services'), { recursive: true });\n }\n\n // Generate files\n await generateComponentFile(options);\n await generateHookFile(options);\n await generateTypesFile(options);\n await generateIndexFile(options);\n\n if (options.createStore) {\n await generateStoreFiles(options);\n }\n\n if (options.createService && options.httpClient) {\n await generateServiceFile(options);\n }\n};\n\nexport const getProjectPathFromFeaturePath = (featurePath: string): string => {\n // Extract project root from feature path\n // featurePath format: /path/to/project/src/features/featureName\n const srcIndex = featurePath.indexOf('/src/features');\n if (srcIndex === -1) {\n throw new Error('Could not determine project path from feature path');\n }\n return featurePath.substring(0, srcIndex);\n};\n\nconst generateComponentFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath } = options;\n const componentName = kebabToPascal(featureName);\n const hookName = `use${componentName}`;\n\n const content = `'use client';\nimport { ${hookName} } from '../hooks/${hookName}';\n\nexport function ${componentName}() {\n const {} = ${hookName}();\n\n return (\n <div>\n <h2>${componentName} Component</h2>\n {/* Add your component UI here */}\n </div>\n );\n}\n\nexport default ${componentName};\n`;\n\n await writeFile(path.join(featurePath, 'components', `${componentName}.tsx`), content);\n};\n\nconst generateHookFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore } = options;\n const componentName = kebabToPascal(featureName);\n const hookName = `use${componentName}`;\n\n let content: string;\n\n if (createStore) {\n content = `'use client';\nimport { useAppDispatch, useAppSelector } from '@/store/hooks';\nimport { select${componentName}State, setLoading, setError } from '../store/${featureName}.selectors';\n\nexport const ${hookName} = () => {\n const dispatch = useAppDispatch();\n const state = useAppSelector(select${componentName}State);\n\n const handleSetLoading = (loading: boolean) => {\n dispatch(setLoading(loading));\n console.log('Loading state updated:', loading);\n };\n\n const handleSetError = (error: string | null) => {\n dispatch(setError(error));\n console.log('Error state updated:', error);\n };\n\n return {\n state,\n setLoading: handleSetLoading,\n setError: handleSetError,\n } as const;\n};\n`;\n } else {\n content = `'use client';\nimport { useState } from 'react';\n\nexport const ${hookName} = () => {\n // Add your state and logic here\n const [state, setState] = useState({});\n\n return {\n state,\n // Add your methods here\n } as const;\n};\n`;\n }\n\n await writeFile(path.join(featurePath, 'hooks', `${hookName}.ts`), content);\n};\n\nconst generateTypesFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore } = options;\n const componentName = kebabToPascal(featureName);\n const typeName = `${componentName}State`;\n\n const content = `export interface ${typeName} {\n // Add your state properties here\n ${createStore ? 'loading: boolean;\\n error: string | null;' : '// example: value: string;'}\n}\n`;\n\n await writeFile(path.join(featurePath, 'types', `${featureName}.types.ts`), content);\n};\n\nconst generateStoreFiles = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, persistStore } = options;\n const componentName = kebabToPascal(featureName);\n const camelName = kebabToCamel(featureName);\n\n // Generate slice\n const sliceContent = `import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { ${componentName}State } from '../types/${featureName}.types';\n\nconst initialState: ${componentName}State = {\n loading: false,\n error: null,\n // Add your initial state here\n};\n\nexport const ${camelName}Slice = createSlice({\n name: '${camelName}',\n initialState,\n reducers: {\n setLoading: (state, action: PayloadAction<boolean>) => {\n state.loading = action.payload;\n },\n setError: (state, action: PayloadAction<string | null>) => {\n state.error = action.payload;\n },\n resetState: (state) => {\n state.loading = false;\n state.error = null;\n },\n },\n});\n\nexport const { setLoading, setError, resetState } = ${camelName}Slice.actions;\n\nexport const ${camelName}Reducer = ${camelName}Slice.reducer;\n`;\n\n await writeFile(path.join(featurePath, 'store', `${featureName}.slice.ts`), sliceContent);\n\n // Generate selectors\n const selectorsContent = `import { RootState } from '@/store/rootReducer';\n\nexport const select${componentName}State = (state: RootState) => state.${camelName};\nexport { setLoading, setError, resetState } from './${featureName}.slice';\n`;\n\n await writeFile(path.join(featurePath, 'store', `${featureName}.selectors.ts`), selectorsContent);\n\n // Generate persist config if needed\n if (persistStore) {\n const persistContent = `import { PersistConfig } from 'redux-persist';\nimport storage from 'redux-persist/lib/storage';\nimport { ${componentName}State } from '../types/${featureName}.types';\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n // whitelist: ['someField'], // Specify which fields to persist\n};\n`;\n\n await writeFile(path.join(featurePath, 'store', 'persist.ts'), persistContent);\n }\n\n // Generate store index\n const storeIndexContent = `export * from './${featureName}.slice';\nexport * from './${featureName}.selectors';${persistStore ? \"\\nexport * from './persist';\" : ''}\n`;\n\n await writeFile(path.join(featurePath, 'store', 'index.ts'), storeIndexContent);\n};\n\nconst generateServiceFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, httpClient } = options;\n const camelName = kebabToCamel(featureName);\n\n let content: string;\n\n if (httpClient === 'axios') {\n content = `import { AppApis } from '@/lib/config';\nimport { axiosClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return axiosClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n } else {\n // fetch\n content = `import { AppApis } from '@/lib/config';\nimport { fetchClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return fetchClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n }\n\n await writeFile(path.join(featurePath, 'services', `${featureName}.service.ts`), content);\n};\n\nconst generateIndexFile = async (options: FeatureGenerationOptions): Promise<void> => {\n const { featureName, featurePath, createStore, createService } = options;\n const componentName = kebabToPascal(featureName);\n\n const content = `export { default as ${componentName} } from './components/${componentName}';\nexport { use${componentName} } from './hooks/use${componentName}';\nexport * from './types/${featureName}.types';${createStore ? `\\nexport * from './store';` : ''}${createService ? `\\nexport * from './services/${featureName}.service';` : ''}\n`;\n\n await writeFile(path.join(featurePath, 'index.ts'), content);\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\nexport const registerFeatureInRootReducer = async (\n projectPath: string,\n featureName: string,\n withPersist: boolean,\n basePath: string = path.join('src', 'features'),\n): Promise<void> => {\n const rootReducerPath = path.join(projectPath, 'src', 'store', 'rootReducer.ts');\n\n try {\n let content = await readFile(rootReducerPath, 'utf-8');\n\n const camelName = kebabToCamel(featureName);\n const reducerName = `${camelName}Reducer`;\n const importName = withPersist ? `${camelName}PersistConfig` : '';\n\n // Convert path to import alias format (src/features -> @/features)\n const importPath = basePath.replace(/^src\\//, '@/');\n\n // Add import statement\n const importStatement = withPersist\n ? `import { ${reducerName}, ${importName} } from '${importPath}/${featureName}/store';`\n : `import { ${reducerName} } from '${importPath}/${featureName}/store';`;\n\n // Find the last import statement\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = content.match(importRegex);\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = content.lastIndexOf(lastImport);\n content =\n content.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n content.slice(lastImportIndex + lastImport.length);\n } else {\n // No imports found, add at the beginning\n content = importStatement + '\\n' + content;\n }\n\n // Add reducer to combineReducers\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = content.match(combineReducersRegex);\n\n if (match) {\n const reducersContent = match[1];\n const newReducerEntry = withPersist\n ? `\\n ${camelName}: persistReducer(${importName}, ${reducerName}),`\n : `\\n ${camelName}: ${reducerName},`;\n\n const updatedReducersContent = reducersContent.trimEnd() + newReducerEntry;\n content = content.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n } else {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register feature in rootReducer: ${error}`);\n }\n};\n\n/**\n * Register a slice in rootReducer (imports from index.ts, not store/)\n */\nexport const registerSliceInRootReducer = async (\n projectPath: string,\n sliceName: string,\n withPersist: boolean,\n basePath: string,\n): Promise<void> => {\n const rootReducerPath = path.join(projectPath, 'src', 'store', 'rootReducer.ts');\n\n try {\n let content = await readFile(rootReducerPath, 'utf-8');\n\n const camelName = kebabToCamel(sliceName);\n const reducerName = `${camelName}Reducer`;\n const importName = withPersist ? `${camelName}PersistConfig` : '';\n\n // Convert path to import alias format (src/store -> @/store)\n const importPath = basePath.replace(/^src\\//, '@/');\n\n // Add import statement (import from index, not /store)\n const importStatement = withPersist\n ? `import { ${reducerName}, ${importName} } from '${importPath}/${sliceName}';`\n : `import { ${reducerName} } from '${importPath}/${sliceName}';`;\n\n // Find the last import statement\n const importRegex = /import\\s+.*\\s+from\\s+['\"].*['\"];?\\n/g;\n const imports = content.match(importRegex);\n if (imports && imports.length > 0) {\n const lastImport = imports[imports.length - 1];\n const lastImportIndex = content.lastIndexOf(lastImport);\n content =\n content.slice(0, lastImportIndex + lastImport.length) +\n importStatement +\n '\\n' +\n content.slice(lastImportIndex + lastImport.length);\n } else {\n // No imports found, add at the beginning\n content = importStatement + '\\n' + content;\n }\n\n // Add reducer to combineReducers\n const combineReducersRegex = /combineReducers\\(\\{([^}]*)\\}\\)/s;\n const match = content.match(combineReducersRegex);\n\n if (match) {\n const reducersContent = match[1];\n const newReducerEntry = withPersist\n ? `\\n ${camelName}: persistReducer(${importName}, ${reducerName}),`\n : `\\n ${camelName}: ${reducerName},`;\n\n const updatedReducersContent = reducersContent.trimEnd() + newReducerEntry;\n content = content.replace(\n combineReducersRegex,\n `combineReducers({${updatedReducersContent}\\n})`,\n );\n } else {\n throw new Error('Could not find combineReducers in rootReducer.ts');\n }\n\n await writeFile(rootReducerPath, content);\n } catch (error) {\n throw new Error(`Failed to register slice in rootReducer: ${error}`);\n }\n};\n", "import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\ninterface RegisterApiOptions {\n serviceName: string;\n projectPath: string;\n}\n\nexport const registerApiEndpoints = async (options: RegisterApiOptions): Promise<void> => {\n const { serviceName, projectPath } = options;\n const camelName = kebabToCamel(serviceName);\n const apiConfigPath = path.join(projectPath, 'src', 'lib', 'config', 'app-apis.ts');\n\n try {\n // Read the current app-apis.ts file\n const content = await readFile(apiConfigPath, 'utf-8');\n\n // Check if the service already exists in the file\n if (content.includes(`${camelName}:`)) {\n // Service already registered, skip\n return;\n }\n\n // Find the position to insert the new API endpoint\n // Looking for the closing brace of AppApis object\n const appApisMatch = content.match(/export const AppApis = \\{[\\s\\S]*?\\} as const;/);\n\n if (!appApisMatch) {\n throw new Error('Could not find AppApis object in app-apis.ts');\n }\n\n // Create the new API endpoint entry\n const newEndpoint = ` ${camelName}: {\n base: \\`\\${API_PREFIX}/${serviceName}\\`,\n getAll: \\`\\${API_PREFIX}/${serviceName}\\`,\n },`;\n\n // Find the position before the closing brace\n const closingBracePattern = /(\\s*)\\} as const;/;\n const match = content.match(closingBracePattern);\n\n if (!match) {\n throw new Error('Could not find closing brace of AppApis object');\n }\n\n // Insert the new endpoint before the closing brace\n const insertPosition = content.lastIndexOf('} as const;');\n const beforeClosing = content.substring(0, insertPosition);\n const afterClosing = content.substring(insertPosition);\n\n // Check if there's already content in AppApis\n const hasExistingEndpoints = beforeClosing.trim().endsWith(',');\n const needsComma = beforeClosing.match(/:\\s*\\{[^}]*\\},\\s*$/);\n\n let updatedContent: string;\n if (needsComma || hasExistingEndpoints) {\n // There are existing endpoints, add comma and new endpoint\n updatedContent = `${beforeClosing}\\n${newEndpoint}\\n${afterClosing}`;\n } else {\n // First endpoint after auth (or empty object), just add it\n updatedContent = beforeClosing.trimEnd() + '\\n' + newEndpoint + '\\n' + afterClosing;\n }\n\n // Write the updated content back\n await writeFile(apiConfigPath, updatedContent);\n } catch (error) {\n throw new Error(`Failed to register API endpoints: ${error}`);\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { log, logError, spinner } from '../config';\nimport { promptForSliceDetails } from '../prompts/slice.prompt';\nimport { detectProjectSetup } from '../services/feature/detection.service';\nimport { generateSliceFiles } from '../services/slice/slice.service';\nimport { registerSliceInRootReducer } from '../services/feature/registration.service';\nimport { sliceExists } from '../services/slice/detection.service';\n\ninterface SliceCommandOptions {\n path?: string;\n persist?: boolean;\n noPersist?: boolean;\n}\n\nexport const registerSliceCommand = (program: Command) => {\n program\n .command('slice [name]')\n .description('Generate a Redux slice')\n .option('--path <path>', 'Custom path for slice generation (default: create new feature)')\n .option('--persist', 'Enable persistence for this slice')\n .option('--no-persist', 'Disable persistence for this slice')\n .action(async (name: string | undefined, options: SliceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate conflicting options\n if (options.persist && options.noPersist === true) {\n logError('Cannot use --persist and --no-persist together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Slice Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Step 2: Check if Redux is setup\n if (!detection.hasRedux) {\n spinner.fail('Redux is not setup in this project');\n logError('Please install @reduxjs/toolkit and react-redux first');\n log(pc.dim('\\nRun: npm install @reduxjs/toolkit react-redux\\n'));\n process.exit(1);\n }\n\n log(pc.dim(` Redux: \u2713\\n`));\n\n // Step 3: Prompt for slice details\n const sliceOptions = await promptForSliceDetails(\n name,\n options.persist,\n options.noPersist === true ? false : undefined,\n );\n\n // Step 4: Determine slice path (feature-first approach)\n let basePath: string;\n let featureName: string;\n let slicePath: string;\n\n if (options.path) {\n // Custom path provided\n const customPath = options.path.replace(/^src\\//, '');\n\n // Check if custom path is a feature\n if (customPath.startsWith('features/')) {\n // Extract feature name and ensure store subdirectory\n const parts = customPath.split('/');\n featureName = parts[1]; // features/featureName/...\n basePath = path.join('src', 'features', featureName, 'store');\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n } else {\n // Non-feature custom path - use as-is but treat as feature store\n basePath = path.join('src', customPath);\n featureName = customPath.split('/')[0]; // First directory as feature name\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n }\n } else {\n // Default: Create new feature with store\n featureName = sliceOptions.sliceName;\n basePath = path.join('src', 'features', featureName, 'store');\n slicePath = path.join(projectPath, basePath, sliceOptions.sliceName);\n }\n\n // Step 5: Ensure feature and store directories exist\n const featureStorePath = path.join(projectPath, basePath);\n if (!existsSync(featureStorePath)) {\n await mkdir(featureStorePath, { recursive: true });\n }\n\n // Check if slice already exists\n const exists = await sliceExists(projectPath, sliceOptions.sliceName, basePath);\n if (exists) {\n logError(`Slice '${sliceOptions.sliceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 6: Generate slice files\n spinner.start('Generating slice files...');\n await generateSliceFiles({\n sliceName: sliceOptions.sliceName,\n slicePath,\n persistSlice: sliceOptions.persistSlice,\n });\n spinner.succeed('Slice files generated');\n\n // Step 7: Register in rootReducer\n spinner.start('Registering slice in rootReducer...');\n // For features: basePath includes store (e.g., src/features/auth/store)\n // We need to register the slice at basePath/sliceName\n await registerSliceInRootReducer(\n projectPath,\n sliceOptions.sliceName,\n sliceOptions.persistSlice,\n basePath,\n );\n spinner.succeed('Slice registered in rootReducer');\n\n // Success message\n const displayPath = path.join(basePath, sliceOptions.sliceName);\n log(pc.green(`\\n\u2728 Slice '${sliceOptions.sliceName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC2 ${displayPath}/`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.slice.ts`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.selectors.ts`));\n if (sliceOptions.persistSlice) log(pc.dim(` \u251C\u2500\u2500 persist.ts`));\n log(pc.dim(` \u251C\u2500\u2500 ${sliceOptions.sliceName}.types.ts`));\n log(pc.dim(` \u2514\u2500\u2500 index.ts\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import actions: import { setLoading, setError } from '${importPath}/${sliceOptions.sliceName}'`,\n ),\n );\n log(pc.dim(` 2. Use in component: dispatch(setLoading(true))`));\n log('');\n } catch (error) {\n spinner.fail('Slice generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import Enquirer from 'enquirer';\nconst { prompt } = Enquirer;\n\nexport interface SliceOptions {\n sliceName: string;\n persistSlice: boolean;\n}\n\nexport const promptForSliceDetails = async (\n sliceName?: string,\n persist?: boolean,\n noPersist?: boolean,\n): Promise<SliceOptions> => {\n const questions: any[] = [];\n\n // Slice name\n if (!sliceName) {\n questions.push({\n type: 'input',\n name: 'sliceName',\n message: 'What is the slice name?',\n initial: 'my-slice',\n validate: (value: string) => {\n if (!/^[a-z0-9-]+$/.test(value)) {\n return 'Slice name must be lowercase and contain only alphanumeric characters and hyphens.';\n }\n return true;\n },\n });\n }\n\n // Persistence question\n if (persist === undefined && noPersist === undefined) {\n questions.push({\n type: 'confirm',\n name: 'persistSlice',\n message: 'Enable persistence for this slice?',\n initial: false,\n });\n }\n\n const answers: any = questions.length > 0 ? await prompt(questions) : {};\n\n return {\n sliceName: sliceName || (answers.sliceName as string),\n persistSlice:\n persist === true\n ? true\n : noPersist === false\n ? false\n : (answers.persistSlice as boolean) || false,\n };\n};\n", "import { writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel, kebabToPascal } from '../../config/utils';\n\nexport interface SliceGenerationOptions {\n sliceName: string;\n slicePath: string;\n persistSlice: boolean;\n}\n\nexport const generateSliceFiles = async (options: SliceGenerationOptions): Promise<void> => {\n const { sliceName, slicePath, persistSlice } = options;\n\n // Create slice directory\n await mkdir(slicePath, { recursive: true });\n\n const componentName = kebabToPascal(sliceName);\n const camelName = kebabToCamel(sliceName);\n\n // Generate types file\n await generateTypesFile(sliceName, slicePath, componentName);\n\n // Generate slice file\n await generateSliceFile(sliceName, slicePath, componentName, camelName);\n\n // Generate selectors file\n await generateSelectorsFile(sliceName, slicePath, componentName, camelName);\n\n // Generate persist file if needed\n if (persistSlice) {\n await generatePersistFile(sliceName, slicePath, componentName, camelName);\n }\n\n // Generate index file\n await generateIndexFile(sliceName, slicePath, persistSlice);\n};\n\nconst generateTypesFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n): Promise<void> => {\n const content = `export interface ${componentName}State {\n loading: boolean;\n error: string | null;\n // Add your state properties here\n}\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.types.ts`), content);\n};\n\nconst generateSliceFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { ${componentName}State } from './${sliceName}.types';\n\nconst initialState: ${componentName}State = {\n loading: false,\n error: null,\n // Add your initial state here\n};\n\nexport const ${camelName}Slice = createSlice({\n name: '${camelName}',\n initialState,\n reducers: {\n setLoading: (state, action: PayloadAction<boolean>) => {\n state.loading = action.payload;\n },\n setError: (state, action: PayloadAction<string | null>) => {\n state.error = action.payload;\n },\n resetState: (state) => {\n state.loading = false;\n state.error = null;\n },\n },\n});\n\nexport const { setLoading, setError, resetState } = ${camelName}Slice.actions;\n\nexport const ${camelName}Reducer = ${camelName}Slice.reducer;\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.slice.ts`), content);\n};\n\nconst generateSelectorsFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { RootState } from '@/store/rootReducer';\n\nexport const select${componentName}State = (state: RootState) => state.${camelName};\nexport { setLoading, setError, resetState } from './${sliceName}.slice';\n`;\n\n await writeFile(path.join(slicePath, `${sliceName}.selectors.ts`), content);\n};\n\nconst generatePersistFile = async (\n sliceName: string,\n slicePath: string,\n componentName: string,\n camelName: string,\n): Promise<void> => {\n const content = `import { PersistConfig } from 'redux-persist';\nimport storage from 'redux-persist/lib/storage';\nimport { ${componentName}State } from './${sliceName}.types';\n\nexport const ${camelName}PersistConfig: PersistConfig<${componentName}State> = {\n key: '${camelName}',\n storage,\n // whitelist: ['someField'], // Specify which fields to persist\n};\n`;\n\n await writeFile(path.join(slicePath, 'persist.ts'), content);\n};\n\nconst generateIndexFile = async (\n sliceName: string,\n slicePath: string,\n persistSlice: boolean,\n): Promise<void> => {\n const content = `export * from './${sliceName}.slice';\nexport * from './${sliceName}.selectors';\nexport * from './${sliceName}.types';${persistSlice ? \"\\nexport * from './persist';\" : ''}\n`;\n\n await writeFile(path.join(slicePath, 'index.ts'), content);\n};\n", "import { access } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport const sliceExists = async (\n projectPath: string,\n sliceName: string,\n basePath: string = path.join('src', 'store', 'slices'),\n): Promise<boolean> => {\n const slicePath = path.join(projectPath, basePath, sliceName);\n try {\n await access(slicePath);\n return true;\n } catch {\n return false;\n }\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { log, logError, spinner } from '../config';\nimport { promptForServiceDetails } from '../prompts/service.prompt';\nimport { detectProjectSetup } from '../services/feature/detection.service';\nimport { generateServiceFiles } from '../services/service/service.service';\nimport { serviceExists } from '../services/service/detection.service';\nimport { registerApiEndpoints } from '../services/common/api-registration.service';\n\ninterface ServiceCommandOptions {\n path?: string;\n axios?: boolean;\n fetch?: boolean;\n}\n\nexport const registerServiceCommand = (program: Command) => {\n program\n .command('service [name]')\n .description('Generate an API service')\n .option('--path <path>', 'Custom path for service generation (default: create new feature)')\n .option('--axios', 'Use Axios HTTP client')\n .option('--fetch', 'Use Fetch HTTP client')\n .action(async (name: string | undefined, options: ServiceCommandOptions) => {\n try {\n const projectPath = process.cwd();\n\n // Validate conflicting options\n if (options.axios && options.fetch) {\n logError('Cannot use --axios and --fetch together');\n process.exit(1);\n }\n\n log(pc.cyan('\\n\uD83D\uDD27 Service Generator\\n'));\n\n // Step 1: Detect project setup\n spinner.start('Detecting project setup...');\n const detection = await detectProjectSetup(projectPath);\n spinner.succeed('Project setup detected');\n\n // Step 2: Check if HTTP clients are setup\n if (detection.httpClient === 'none') {\n spinner.fail('No HTTP client is setup in this project');\n logError('Please setup either AxiosClient or FetchClient first');\n log(pc.dim('\\nCheck: lib/utils/http/axios-client or lib/utils/http/fetch-client\\n'));\n process.exit(1);\n }\n\n // Display available clients\n const availableClients: string[] = [];\n if (detection.httpClient === 'axios' || detection.httpClient === 'both') {\n availableClients.push('Axios \u2713');\n }\n if (detection.httpClient === 'fetch' || detection.httpClient === 'both') {\n availableClients.push('Fetch \u2713');\n }\n log(pc.dim(` HTTP Clients: ${availableClients.join(', ')}\\n`));\n\n // Step 3: Prompt for service details\n const serviceOptions = await promptForServiceDetails(\n name,\n options.axios,\n options.fetch,\n detection.httpClient,\n );\n\n // Step 4: Determine service path (feature-first approach)\n let basePath: string;\n let featureName: string;\n let servicePath: string;\n\n if (options.path) {\n // Custom path provided\n const customPath = options.path.replace(/^src\\//, '');\n\n // Check if custom path is a feature\n if (customPath.startsWith('features/')) {\n // Extract feature name and ensure services subdirectory\n const parts = customPath.split('/');\n featureName = parts[1]; // features/featureName/...\n basePath = path.join('src', 'features', featureName, 'services');\n servicePath = path.join(projectPath, basePath);\n } else {\n // Non-feature custom path - use as-is\n basePath = path.join('src', customPath);\n featureName = customPath.split('/')[0]; // First directory as feature name\n servicePath = path.join(projectPath, basePath);\n }\n } else {\n // Default: Create new feature with services\n featureName = serviceOptions.serviceName;\n basePath = path.join('src', 'features', featureName, 'services');\n servicePath = path.join(projectPath, basePath);\n }\n\n // Step 5: Ensure feature and services directories exist\n if (!existsSync(servicePath)) {\n await mkdir(servicePath, { recursive: true });\n }\n\n // Check if service already exists\n const exists = await serviceExists(projectPath, serviceOptions.serviceName, basePath);\n if (exists) {\n logError(`Service '${serviceOptions.serviceName}' already exists at ${basePath}!`);\n process.exit(1);\n }\n\n // Step 6: Generate service files\n spinner.start('Generating service files...');\n await generateServiceFiles({\n serviceName: serviceOptions.serviceName,\n servicePath,\n httpClient: serviceOptions.httpClient,\n });\n spinner.succeed('Service files generated');\n\n // Step 7: Register API endpoints\n spinner.start('Registering API endpoints...');\n await registerApiEndpoints({\n serviceName: serviceOptions.serviceName,\n projectPath,\n });\n spinner.succeed('API endpoints registered');\n\n // Success message\n const displayPath = path.join(basePath, `${serviceOptions.serviceName}.service.ts`);\n log(pc.green(`\\n\u2728 Service '${serviceOptions.serviceName}' created successfully!\\n`));\n log(pc.dim('Generated files:'));\n log(pc.dim(` \uD83D\uDCC4 ${displayPath}\\n`));\n\n log(pc.cyan('Next steps:'));\n const importPath = basePath.replace(/^src\\//, '@/');\n log(\n pc.dim(\n ` 1. Import service: import { ${serviceOptions.serviceName}Service } from '${importPath}/${serviceOptions.serviceName}.service'`,\n ),\n );\n log(\n pc.dim(\n ` 2. Use in component: const data = await ${serviceOptions.serviceName}Service.getAll()`,\n ),\n );\n log('');\n } catch (error) {\n spinner.fail('Service generation failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import enquirer from 'enquirer';\n\ninterface ServiceOptions {\n serviceName: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const promptForServiceDetails = async (\n name?: string,\n axiosFlag?: boolean,\n fetchFlag?: boolean,\n availableClients?: 'axios' | 'fetch' | 'both' | 'none',\n): Promise<ServiceOptions> => {\n const serviceName =\n name ||\n (\n await enquirer.prompt<{ serviceName: string }>({\n type: 'input',\n name: 'serviceName',\n message: 'Service name (kebab-case):',\n validate: (input: string) => {\n if (!input) return 'Service name is required';\n if (!/^[a-z0-9-]+$/.test(input))\n return 'Service name must be lowercase with hyphens only';\n return true;\n },\n })\n ).serviceName;\n\n let httpClient: 'axios' | 'fetch';\n\n // If flags are provided, use them\n if (axiosFlag !== undefined) {\n httpClient = 'axios';\n } else if (fetchFlag !== undefined) {\n httpClient = 'fetch';\n } else {\n // Prompt based on available clients\n if (availableClients === 'axios') {\n httpClient = 'axios';\n } else if (availableClients === 'fetch') {\n httpClient = 'fetch';\n } else if (availableClients === 'both') {\n // Let user choose\n const response = await enquirer.prompt<{ httpClient: 'axios' | 'fetch' }>({\n type: 'select',\n name: 'httpClient',\n message: 'Choose HTTP client:',\n choices: ['axios', 'fetch'],\n });\n httpClient = response.httpClient;\n } else {\n // This shouldn't happen as we check in the command\n httpClient = 'axios';\n }\n }\n\n return {\n serviceName,\n httpClient,\n };\n};\n", "import { writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { kebabToCamel } from '../../config/utils';\n\ninterface GenerateServiceOptions {\n serviceName: string;\n servicePath: string;\n httpClient: 'axios' | 'fetch';\n}\n\nexport const generateServiceFiles = async (options: GenerateServiceOptions): Promise<void> => {\n await generateServiceFile(options);\n};\n\nconst generateServiceFile = async (options: GenerateServiceOptions): Promise<void> => {\n const { serviceName, servicePath, httpClient } = options;\n const camelName = kebabToCamel(serviceName);\n\n let content: string;\n\n if (httpClient === 'axios') {\n content = `import { AppApis } from '@/lib/config';\nimport { axiosClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return axiosClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n } else {\n // fetch\n content = `import { AppApis } from '@/lib/config';\nimport { fetchClient } from '@/lib/utils/http';\nimport { ResultAsync } from '@/types';\n\nexport const ${camelName}Service = {\n getAll: (): ResultAsync<string> => {\n return fetchClient.get<string>(AppApis.${camelName}.getAll);\n },\n};\n`;\n }\n\n const fileName = `${serviceName}.service.ts`;\n await writeFile(path.join(servicePath, fileName), content);\n};\n", "import { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nexport const serviceExists = async (\n projectPath: string,\n serviceName: string,\n basePath: string,\n): Promise<boolean> => {\n const servicePath = path.join(projectPath, basePath, `${serviceName}.service.ts`);\n return existsSync(servicePath);\n};\n", "import { Command } from 'commander';\nimport pc from 'picocolors';\nimport Enquirer from 'enquirer';\nimport { log, logError, spinner } from '../config';\nimport { setupDarkTheme } from '../services/setup/dark-theme';\nimport { setupRedux } from '../services/setup/redux';\nimport { setupI18n } from '../services/setup/i18n';\nimport { setupHttpClient } from '../services/setup/http-client';\n\nconst { prompt } = Enquirer;\n\ninterface SetupOptions {\n httpClient?: string;\n darkTheme?: boolean;\n redux?: boolean;\n i18n?: boolean;\n}\n\nexport const registerSetupCommand = (program: Command) => {\n program\n .command('setup')\n .description('Setup features in an existing Next.js project')\n .option('--http-client', 'Setup HTTP client (axios|fetch)')\n .option('--dark-theme', 'Setup Dark Theme (Tailwind + next-themes)')\n .option('--redux', 'Setup Redux Toolkit')\n .option('--i18n', 'Setup next-intl for internationalization')\n .action(async (options: SetupOptions) => {\n try {\n log(pc.cyan('\\n\uD83D\uDD27 Setup Wizard\\n'));\n\n // Direct setup via flags\n if (options.httpClient || options.darkTheme || options.redux || options.i18n) {\n if (options.httpClient) {\n await setupHttpClient(process.cwd());\n }\n if (options.darkTheme) {\n await setupDarkTheme(process.cwd());\n }\n if (options.redux) {\n await setupRedux(process.cwd());\n }\n if (options.i18n) {\n await setupI18n(process.cwd());\n }\n return;\n }\n\n // If no options provided, show interactive menu\n const setupChoice = await prompt<{ feature: string }>([\n {\n type: 'select',\n name: 'feature',\n message: 'What would you like to setup?',\n choices: [\n { name: 'Dark Theme', value: 'dark-theme' },\n { name: 'Redux Toolkit', value: 'redux' },\n { name: 'HTTP Client (Axios/Fetch)', value: 'http-client' },\n { name: 'Internationalization (next-intl)', value: 'i18n' },\n 'Cancel',\n ],\n },\n ]);\n const feature = setupChoice.feature;\n\n if (feature === 'Cancel') {\n log(pc.yellow('Setup cancelled.'));\n return;\n }\n\n if (feature === 'dark-theme') {\n await setupDarkTheme(process.cwd());\n } else if (feature === 'redux') {\n await setupRedux(process.cwd());\n } else if (feature === 'http-client') {\n await setupHttpClient(process.cwd());\n } else if (feature === 'i18n') {\n await setupI18n(process.cwd());\n } else {\n log(pc.yellow(`\\n\u26A0\uFE0F ${feature} setup is not implemented yet.`));\n log(pc.dim('This feature will be available in a future update.'));\n }\n } catch (error) {\n spinner.fail('Setup failed');\n logError(`${error}`);\n process.exit(1);\n }\n });\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyThemeProvider } from './assets';\nimport {\n updateProvidersIndex,\n updateRootProvider,\n updateGlobalsCss,\n updateLayout,\n} from './injectors';\n\nexport const setupDarkTheme = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Dark Theme...');\n const tempDir = path.join(projectPath, '.next-maker-temp');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`Dark Theme is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n const layoutPath = await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n await copyThemeProvider(projectPath, tempDir);\n\n // 5. Inject Code\n await updateProvidersIndex(projectPath);\n await updateRootProvider(projectPath);\n await updateGlobalsCss(projectPath, tempDir);\n await updateLayout(layoutPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing next-themes...';\n await installPackage(projectPath, 'next-themes');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Dark Theme setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Dark Theme.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { findLayoutPath } from './utils';\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const themeProviderPath = path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER);\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(themeProviderPath)) {\n return { isSetup: true, reason: 'CustomThemeProvider.tsx exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['next-themes']) ||\n (packageJson.devDependencies && packageJson.devDependencies['next-themes'])\n ) {\n return { isSetup: true, reason: 'next-themes is installed' };\n }\n }\n\n if (fileExists(globalsCssPath)) {\n const globalsCss = await readFile(globalsCssPath);\n if (globalsCss.includes('@custom-variant dark')) {\n return { isSetup: true, reason: 'Dark theme CSS found in globals.css' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<string> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n const layoutPath = await findLayoutPath(projectPath);\n\n if (!fileExists(globalsCssPath) || !layoutPath || !fileExists(providersIndexPath)) {\n throw new Error(\n 'Project structure mismatch. Ensure src/styles/globals.css, src/app/layout.tsx (or src/app/[locale]/layout.tsx), and src/providers/index.ts exist.',\n );\n }\n\n return layoutPath;\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const findLayoutPath = async (projectPath: string): Promise<string> => {\n const possibleLayoutPaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT),\n path.join(projectPath, 'src/app/[locale]/layout.tsx'),\n ];\n\n for (const p of possibleLayoutPaths) {\n if (fileExists(p)) {\n const content = await readFile(p);\n if (content.includes('<body')) {\n return p;\n }\n }\n }\n\n // Fallback: if no body tag found, just take the first one that exists\n for (const p of possibleLayoutPaths) {\n if (fileExists(p)) {\n return p;\n }\n }\n\n return '';\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyThemeProvider = async (projectPath: string, tempDir: string): Promise<void> => {\n const themeProviderPath = path.join(projectPath, PROJECT_PATHS.THEME_PROVIDER);\n const sourceProviderPath = path.join(tempDir, 'src/providers/CustomThemeProvider.tsx');\n await copyFile(sourceProviderPath, themeProviderPath);\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const updateProvidersIndex = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersContent = await readFile(providersIndexPath);\n if (!providersContent.includes('CustomThemeProvider')) {\n providersContent += \"export * from './CustomThemeProvider';\\n\";\n await writeFile(providersIndexPath, providersContent);\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let rootProviderContent = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = rootProviderContent.includes(useClientDirective);\n\n if (hasUseClient) {\n rootProviderContent = rootProviderContent.replace(useClientDirective, '').trim();\n }\n\n // Add import if missing\n if (!rootProviderContent.includes('CustomThemeProvider')) {\n rootProviderContent = rootProviderContent.replace(\n /import \\{ StoreProvider \\} from '@\\/providers';\\n/,\n \"import { StoreProvider, CustomThemeProvider } from '@/providers';\\n\",\n );\n // Fallback if StoreProvider import is different or missing\n if (!rootProviderContent.includes('CustomThemeProvider')) {\n if (rootProviderContent.includes(\"from '@/providers'\")) {\n rootProviderContent = rootProviderContent.replace(\n /\\} from '@\\/providers'/,\n \", CustomThemeProvider } from '@/providers'\",\n );\n } else {\n rootProviderContent =\n \"import { CustomThemeProvider } from '@/providers';\\n\" + rootProviderContent;\n }\n }\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n rootProviderContent = useClientDirective + '\\n' + rootProviderContent;\n }\n\n // Wrap children\n if (!rootProviderContent.includes('<CustomThemeProvider>')) {\n if (rootProviderContent.includes('<StoreProvider>')) {\n rootProviderContent = rootProviderContent.replace(\n /<StoreProvider>/,\n '<StoreProvider>\\n <CustomThemeProvider>',\n );\n rootProviderContent = rootProviderContent.replace(\n /<\\/StoreProvider>/,\n '</CustomThemeProvider>\\n </StoreProvider>',\n );\n } else {\n // Match return statement with or without parentheses\n const returnMatch = rootProviderContent.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n rootProviderContent = rootProviderContent.replace(\n returnMatch[0],\n `return (\\n <CustomThemeProvider>\\n ${existingJsx}\\n </CustomThemeProvider>\\n );`,\n );\n }\n }\n await writeFile(rootProviderPath, rootProviderContent);\n }\n }\n};\n\nexport const updateGlobalsCss = async (projectPath: string, tempDir: string): Promise<void> => {\n const globalsCssPath = path.join(projectPath, PROJECT_PATHS.GLOBALS_CSS);\n const sourceCssPath = path.join(tempDir, 'src/styles/globals.css');\n let darkThemeCss = '';\n\n if (fileExists(sourceCssPath)) {\n const sourceCss = await readFile(sourceCssPath);\n const variantMatch = sourceCss.match(/@custom-variant dark \\(.*?\\);/);\n const themeMatch = sourceCss.match(/@theme \\{[\\s\\S]*?\\}/);\n\n if (variantMatch) darkThemeCss += `\\n${variantMatch[0]}\\n`;\n if (themeMatch) darkThemeCss += `\\n${themeMatch[0]}\\n`;\n }\n\n if (!darkThemeCss) {\n darkThemeCss = `\n@custom-variant dark (&:where(.dark, .dark *));\n\n@theme {\n --color-dark: #202938;\n --color-light: #f5f5f5;\n}\n`;\n }\n\n let cssContent = await readFile(globalsCssPath);\n if (!cssContent.includes('@custom-variant dark')) {\n if (cssContent.includes('@import')) {\n const lastImportIndex = cssContent.lastIndexOf('@import');\n const endOfLineIndex = cssContent.indexOf('\\n', lastImportIndex);\n cssContent =\n cssContent.slice(0, endOfLineIndex + 1) +\n darkThemeCss +\n cssContent.slice(endOfLineIndex + 1);\n } else {\n cssContent = darkThemeCss + cssContent;\n }\n await writeFile(globalsCssPath, cssContent);\n }\n};\n\nexport const updateLayout = async (layoutPath: string): Promise<void> => {\n let layoutContent = await readFile(layoutPath);\n if (!layoutContent.includes('dark:bg-dark')) {\n layoutContent = layoutContent.replace(\n /className=\"([^\"]*)\"/,\n 'className=\"$1 bg-light dark:bg-dark\"',\n );\n await writeFile(layoutPath, layoutContent);\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyReduxFiles, createCounterFeature } from './assets';\nimport { updateProvidersIndex, updateRootProvider, updatePage } from './injectors';\n\nexport const setupRedux = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Redux Toolkit...');\n const tempDir = path.join(projectPath, '.next-maker-temp-redux');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`Redux is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n spinner.text = 'Copying Redux files...';\n await copyReduxFiles(projectPath, tempDir);\n\n spinner.text = 'Creating Counter feature...';\n await createCounterFeature(projectPath, tempDir);\n\n // 5. Inject Code\n spinner.text = 'Updating providers and pages...';\n await updateProvidersIndex(projectPath);\n await updateRootProvider(projectPath);\n await updatePage(projectPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installPackage(projectPath, '@reduxjs/toolkit');\n await installPackage(projectPath, 'react-redux');\n await installPackage(projectPath, 'redux-persist');\n // Check if react-secure-storage is needed (starter uses it in persist.ts? No, it used storage from redux-persist/lib/storage in the file I viewed)\n // But let's check if the starter has it in package.json just in case.\n // Based on previous view of package.json in test project, it had react-secure-storage.\n // Let's install it to be safe if the starter uses it elsewhere or if I missed it.\n await installPackage(projectPath, 'react-secure-storage');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Redux Toolkit setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Redux Toolkit.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { findLayoutPath } from '../dark-theme/utils'; // Reuse utility\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const storePath = path.join(projectPath, PROJECT_PATHS.STORE);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(storePath)) {\n return { isSetup: true, reason: 'src/store directory exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['@reduxjs/toolkit']) ||\n (packageJson.devDependencies && packageJson.devDependencies['@reduxjs/toolkit'])\n ) {\n return { isSetup: true, reason: '@reduxjs/toolkit is installed' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n // We check for layout just to ensure it's a valid next app, reusing the robust check\n const layoutPath = await findLayoutPath(projectPath);\n\n if (!layoutPath || !fileExists(providersIndexPath)) {\n throw new Error(\n 'Project structure mismatch. Ensure src/app/layout.tsx (or src/app/[locale]/layout.tsx) and src/providers/index.ts exist.',\n );\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile, readFile, writeFile, fileExists } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyReduxFiles = async (projectPath: string, tempDir: string): Promise<void> => {\n // Copy StoreProvider\n const sourceProviderPath = path.join(tempDir, 'src/providers/StoreProvider.tsx');\n const destProviderPath = path.join(projectPath, PROJECT_PATHS.STORE_PROVIDER);\n await copyFile(sourceProviderPath, destProviderPath);\n\n // Copy src/store directory\n const sourceStoreDir = path.join(tempDir, 'src/store');\n const destStoreDir = path.join(projectPath, PROJECT_PATHS.STORE);\n await fs.cp(sourceStoreDir, destStoreDir, { recursive: true });\n};\n\nexport const createCounterFeature = async (projectPath: string, tempDir: string): Promise<void> => {\n const sourceFeatureDir = path.join(tempDir, 'src/features/counter');\n const destFeatureDir = path.join(projectPath, PROJECT_PATHS.COUNTER_FEATURE);\n\n // Copy the entire directory first\n await fs.cp(sourceFeatureDir, destFeatureDir, { recursive: true });\n\n // Modify Counter.tsx to remove i18n\n const counterComponentPath = path.join(destFeatureDir, 'components/Counter.tsx');\n if (await fileExists(counterComponentPath)) {\n let content = await readFile(counterComponentPath);\n\n // Remove imports\n content = content.replace(/import \\{ useTranslations \\} from 'next-intl';\\n?/, '');\n\n // Remove hook usage\n content = content.replace(/const t = useTranslations\\('Count'\\);\\n?/, '');\n\n // Replace translations with hardcoded strings\n // {t('currentCount', { count: value })} -> Current Count: {value}\n content = content.replace(\n /\\{t\\('currentCount', \\{ count: value \\}\\)\\}/g,\n 'Current Count: {value}',\n );\n\n // {t('increment')} -> Increment\n content = content.replace(/\\{t\\('increment'\\)\\}/g, 'Increment');\n\n // {t('decrement')} -> Decrement\n content = content.replace(/\\{t\\('decrement'\\)\\}/g, 'Decrement');\n\n // {t('reset')} -> Reset\n content = content.replace(/\\{t\\('reset'\\)\\}/g, 'Reset');\n\n await writeFile(counterComponentPath, content);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const updateProvidersIndex = async (projectPath: string): Promise<void> => {\n const providersIndexPath = path.join(projectPath, PROJECT_PATHS.PROVIDERS_INDEX);\n let providersContent = await readFile(providersIndexPath);\n if (!providersContent.includes('StoreProvider')) {\n providersContent += \"export * from './StoreProvider';\\n\";\n await writeFile(providersIndexPath, providersContent);\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let rootProviderContent = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = rootProviderContent.includes(useClientDirective);\n\n if (hasUseClient) {\n rootProviderContent = rootProviderContent.replace(useClientDirective, '').trim();\n }\n\n // Add import\n if (!rootProviderContent.includes('StoreProvider')) {\n rootProviderContent = rootProviderContent.replace(\n /import \\{ (.*?) \\} from '@\\/providers';/,\n \"import { $1, StoreProvider } from '@/providers';\",\n );\n // Fallback if regex didn't match (e.g. no named imports yet)\n if (!rootProviderContent.includes('StoreProvider')) {\n if (rootProviderContent.includes(\"from '@/providers'\")) {\n // Try to append to existing import\n rootProviderContent = rootProviderContent.replace(\n /\\} from '@\\/providers'/,\n \", StoreProvider } from '@/providers'\",\n );\n } else {\n rootProviderContent =\n \"import { StoreProvider } from '@/providers';\\n\" + rootProviderContent;\n }\n }\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n rootProviderContent = useClientDirective + '\\n' + rootProviderContent;\n }\n\n // Wrap children\n // We want StoreProvider to be the outermost (or close to it)\n if (!rootProviderContent.includes('<StoreProvider>')) {\n const returnMatch = rootProviderContent.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n const existingJsx = returnMatch[1];\n rootProviderContent = rootProviderContent.replace(\n returnMatch[0],\n `return (\\n <StoreProvider>\\n ${existingJsx}\\n </StoreProvider>\\n );`,\n );\n await writeFile(rootProviderPath, rootProviderContent);\n }\n }\n }\n};\n\nexport const updatePage = async (projectPath: string): Promise<void> => {\n // Try to find the page file\n const possiblePagePaths = [\n path.join(projectPath, PROJECT_PATHS.ROOT_PAGE),\n path.join(projectPath, 'src/app/[locale]/page.tsx'),\n ];\n\n let pagePath = '';\n for (const p of possiblePagePaths) {\n if (fileExists(p)) {\n pagePath = p;\n break;\n }\n }\n\n if (pagePath) {\n let pageContent = await readFile(pagePath);\n\n // Add import\n if (!pageContent.includes('Counter')) {\n pageContent =\n \"import { Counter } from '@/features/counter/components/Counter';\\n\" + pageContent;\n }\n\n // Add Component\n if (!pageContent.includes('<Counter />')) {\n // Look for the closing tag of the main container (usually div or main)\n // We'll just append it to the end of the children of the first element\n // This is a bit risky but standard for simple injections\n const lastDivIndex = pageContent.lastIndexOf('</div>');\n const lastMainIndex = pageContent.lastIndexOf('</main>');\n\n const insertIndex = lastMainIndex !== -1 ? lastMainIndex : lastDivIndex;\n\n if (insertIndex !== -1) {\n pageContent =\n pageContent.slice(0, insertIndex) +\n '\\n <div className=\"mt-8\">\\n <h2 className=\"text-2xl font-bold mb-4\">Redux Counter</h2>\\n <Counter />\\n </div>\\n' +\n pageContent.slice(insertIndex);\n await writeFile(pagePath, pageContent);\n }\n }\n }\n};\n", "import path from 'node:path';\nimport pc from 'picocolors';\nimport { deleteDirectory } from '../../../core/files';\nimport { installPackage, runScript, detectPackageManager } from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure } from './checks';\nimport { fetchAssets, copyI18nFiles } from './assets';\nimport {\n updateNextConfig,\n updateTypesIndex,\n updateConfigIndex,\n migrateToLocaleStructure,\n updateRootProvider,\n} from './injectors';\n\nexport const setupI18n = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Setting up Internationalization (next-intl)...');\n const tempDir = path.join(projectPath, '.next-maker-temp-i18n');\n\n try {\n // 1. Pre-check\n const { isSetup, reason } = await checkIsAlreadySetup(projectPath);\n if (isSetup) {\n spinner.fail(`i18n is already set up (${reason}).`);\n return;\n }\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Copy Files\n spinner.text = 'Copying i18n files...';\n await copyI18nFiles(projectPath, tempDir);\n\n // 5. Inject Code & Migrate Structure\n spinner.text = 'Configuring project structure...';\n await updateNextConfig(projectPath);\n await updateTypesIndex(projectPath);\n await updateConfigIndex(projectPath);\n await updateRootProvider(projectPath);\n\n spinner.text = 'Migrating to [locale] structure...';\n await migrateToLocaleStructure(projectPath);\n\n // 6. Install Dependencies\n spinner.text = 'Installing dependencies...';\n await installPackage(projectPath, 'next-intl');\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green('Internationalization setup successfully!'));\n } catch (error) {\n spinner.fail('Failed to setup Internationalization.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n", "import path from 'node:path';\nimport { fileExists, readFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport const checkIsAlreadySetup = async (\n projectPath: string,\n): Promise<{ isSetup: boolean; reason: string }> => {\n const i18nDir = path.join(projectPath, PROJECT_PATHS.I18N_DIR);\n const packageJsonPath = path.join(projectPath, 'package.json');\n\n if (fileExists(i18nDir)) {\n return { isSetup: true, reason: 'src/i18n directory exists' };\n }\n\n if (fileExists(packageJsonPath)) {\n const packageJson = JSON.parse(await readFile(packageJsonPath));\n if (\n (packageJson.dependencies && packageJson.dependencies['next-intl']) ||\n (packageJson.devDependencies && packageJson.devDependencies['next-intl'])\n ) {\n return { isSetup: true, reason: 'next-intl is installed' };\n }\n }\n\n return { isSetup: false, reason: '' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const rootLayoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n const localeLayoutPath = path.join(projectPath, 'src/app/[locale]/layout.tsx');\n\n if (!fileExists(rootLayoutPath) && !fileExists(localeLayoutPath)) {\n throw new Error('Project structure mismatch. Ensure src/app/layout.tsx exists.');\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Fetching assets from starter repo...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyI18nFiles = async (projectPath: string, tempDir: string): Promise<void> => {\n // Copy src/i18n directory\n const sourceI18nDir = path.join(tempDir, 'src/i18n');\n const destI18nDir = path.join(projectPath, PROJECT_PATHS.I18N_DIR);\n await fs.cp(sourceI18nDir, destI18nDir, { recursive: true });\n\n // Copy src/proxy.ts\n const sourceProxyPath = path.join(tempDir, 'src/proxy.ts');\n const destProxyPath = path.join(projectPath, PROJECT_PATHS.PROXY);\n await copyFile(sourceProxyPath, destProxyPath);\n\n // Copy src/types/i18n.ts\n const sourceTypesPath = path.join(tempDir, 'src/types/i18n.ts');\n const destTypesPath = path.join(projectPath, PROJECT_PATHS.I18N_TYPES);\n await copyFile(sourceTypesPath, destTypesPath);\n\n // Copy src/lib/config/app-locales.ts\n const sourceLocalesPath = path.join(tempDir, 'src/lib/config/app-locales.ts');\n const destLocalesPath = path.join(projectPath, PROJECT_PATHS.APP_LOCALES);\n await copyFile(sourceLocalesPath, destLocalesPath);\n};\n", "import path from 'node:path';\nimport { fileExists, readFile, writeFile, deleteFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport fs from 'node:fs/promises';\n\nexport const updateNextConfig = async (projectPath: string): Promise<void> => {\n const nextConfigPath = path.join(projectPath, PROJECT_PATHS.NEXT_CONFIG);\n if (fileExists(nextConfigPath)) {\n let content = await readFile(nextConfigPath);\n if (!content.includes('createNextIntlPlugin')) {\n content = \"import createNextIntlPlugin from 'next-intl/plugin';\\n\" + content;\n\n const exportDefaultRegex = /export default (.*?);/;\n if (exportDefaultRegex.test(content)) {\n content = content.replace(\n exportDefaultRegex,\n '\\nconst withNextIntl = createNextIntlPlugin();\\nexport default withNextIntl($1);',\n );\n } else {\n // Fallback if no export default found (unlikely but safe)\n content += '\\nconst withNextIntl = createNextIntlPlugin();\\n';\n content += 'export default withNextIntl(nextConfig);\\n';\n }\n\n await writeFile(nextConfigPath, content);\n }\n }\n};\n\nexport const updateTypesIndex = async (projectPath: string): Promise<void> => {\n const typesIndexPath = path.join(projectPath, PROJECT_PATHS.TYPES_INDEX);\n if (fileExists(typesIndexPath)) {\n let content = await readFile(typesIndexPath);\n if (!content.includes('./i18n')) {\n content += \"export * from './i18n';\\n\";\n await writeFile(typesIndexPath, content);\n }\n }\n};\n\nexport const updateConfigIndex = async (projectPath: string): Promise<void> => {\n const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n if (fileExists(configIndexPath)) {\n let content = await readFile(configIndexPath);\n if (!content.includes('./app-locales')) {\n content += \"export * from './app-locales';\\n\";\n await writeFile(configIndexPath, content);\n }\n }\n};\n\nexport const updateRootProvider = async (projectPath: string): Promise<void> => {\n const rootProviderPath = path.join(projectPath, 'src/providers/RootProvider.tsx');\n if (fileExists(rootProviderPath)) {\n let content = await readFile(rootProviderPath);\n\n // Handle 'use client'\n const useClientDirective = \"'use client';\";\n const hasUseClient = content.includes(useClientDirective);\n\n if (hasUseClient) {\n content = content.replace(useClientDirective, '').trim();\n }\n\n // Add imports\n if (!content.includes('next-intl')) {\n const imports = `import { SupportedLocale } from '@/types/i18n';\nimport { NextIntlClientProvider, AbstractIntlMessages } from 'next-intl';\n`;\n content = imports + content;\n }\n\n // Re-add 'use client' at the top\n if (hasUseClient) {\n content = useClientDirective + '\\n' + content;\n }\n\n // Update Props\n // Replace props type or signature\n if (!content.includes('locale: SupportedLocale')) {\n // Try to find the props definition\n // This assumes a specific structure, might need to be more robust\n // We'll look for the component definition\n const componentRegex = /export const RootProvider = \\(\\{([\\s\\S]*?)\\}: \\{([\\s\\S]*?)\\}\\) => \\{/;\n const match = content.match(componentRegex);\n\n if (match) {\n const newParams = `\\n children,\\n locale,\\n messages,`;\n const newTypes = `\\n children: React.ReactNode;\\n locale: SupportedLocale;\\n messages: AbstractIntlMessages;`;\n\n content = content.replace(\n match[0],\n `export const RootProvider = ({${newParams}\\n}: {${newTypes}\\n}) => {`,\n );\n }\n }\n\n // Wrap with NextIntlClientProvider\n if (!content.includes('<NextIntlClientProvider')) {\n const returnMatch = content.match(/return\\s*(?:\\(\\s*)?([\\s\\S]*?)(?:\\s*\\))?;/);\n if (returnMatch) {\n // We want NextIntlClientProvider to be inside CustomThemeProvider if possible, or just wrap children\n // But usually it wraps everything inside the provider\n // Let's wrap the inner content\n const existingJsx = returnMatch[1];\n\n // We need to be careful. If existingJsx contains {children}, we want to wrap THAT.\n // But replacing {children} might be safer if we can find it.\n // However, if we just wrap the whole thing, it might be double wrapping if not careful.\n // But here we are wrapping the *returned JSX*.\n\n // Wait, the previous logic was:\n // content = content.replace(/return \\(\\s*<([^>]+)([^>]*)>([\\s\\S]*)<\\/\\1>\\s*\\);/, (match) => {\n // return match.replace(\n // /\\{children\\}/,\n // `<NextIntlClientProvider locale={locale} messages={messages}>\\n {children}\\n </NextIntlClientProvider>`,\n // );\n // });\n\n // The previous logic tried to find {children} inside the returned JSX and wrap IT.\n // This is different from dark-theme/redux which wrap the *entire* returned JSX.\n // Why? Because NextIntlClientProvider should be close to children?\n // Or maybe just to avoid wrapping other providers?\n\n // If I use the new regex, I get the whole JSX.\n // I can try to replace {children} inside it.\n\n if (existingJsx.includes('{children}')) {\n const newJsx = existingJsx.replace(\n '{children}',\n `<NextIntlClientProvider locale={locale} messages={messages}>\\n {children}\\n </NextIntlClientProvider>`,\n );\n content = content.replace(returnMatch[0], `return (\\n ${newJsx}\\n );`);\n } else {\n // Fallback: wrap the whole thing if {children} not found (unlikely)\n content = content.replace(\n returnMatch[0],\n `return (\\n <NextIntlClientProvider locale={locale} messages={messages}>\\n ${existingJsx}\\n </NextIntlClientProvider>\\n );`,\n );\n }\n }\n }\n\n await writeFile(rootProviderPath, content);\n }\n};\n\nexport const migrateToLocaleStructure = async (projectPath: string): Promise<void> => {\n const rootLayoutPath = path.join(projectPath, PROJECT_PATHS.ROOT_LAYOUT);\n const rootPagePath = path.join(projectPath, PROJECT_PATHS.ROOT_PAGE);\n const localeDir = path.join(projectPath, 'src/app/[locale]');\n\n // Create [locale] directory\n await fs.mkdir(localeDir, { recursive: true });\n\n // Move Layout\n if (fileExists(rootLayoutPath)) {\n const destLayoutPath = path.join(localeDir, 'layout.tsx');\n let content = await readFile(rootLayoutPath);\n\n // Add imports\n if (!content.includes('next-intl')) {\n content =\n `import { routing } from '@/i18n/routing';\nimport { hasLocale } from 'next-intl';\nimport { notFound } from 'next/navigation';\nimport { setRequestLocale, getMessages } from 'next-intl/server';\n` + content;\n }\n\n // Add generateStaticParams\n if (!content.includes('generateStaticParams')) {\n const metadataEndIndex = content.indexOf('};', content.indexOf('export const metadata'));\n if (metadataEndIndex !== -1) {\n const insertPos = metadataEndIndex + 2;\n content =\n content.slice(0, insertPos) +\n `\\n\\nexport function generateStaticParams() {\n return routing.locales.map((locale) => ({ locale }));\n}` +\n content.slice(insertPos);\n }\n }\n\n // Update RootLayout signature and body\n // Replace props type\n content = content.replace(\n /Readonly<\\{\\s*children:\\s*React\\.ReactNode;\\s*}>/,\n `Readonly<{\n children: React.ReactNode;\n params: Promise<{ locale: string }>;\n}>`,\n );\n\n // Add logic inside function\n // Handle both async and non-async function definitions\n const functionBodyRegex =\n /export default (async )?function RootLayout\\(\\{\\s*children,?\\s*\\}\\s*:/;\n const functionMatch = content.match(functionBodyRegex);\n\n if (functionMatch) {\n const isAsync = functionMatch[1];\n\n // Ensure it's async\n if (!isAsync) {\n content = content.replace('export default function', 'export default async function');\n }\n\n // 1. Inject params destructuring\n content = content.replace(\n /export default (async )?function RootLayout\\(\\{\\s*children,?\\s*\\}\\s*:/,\n 'export default async function RootLayout({ children, params }:',\n );\n\n // 2. Inject logic at start of function\n const bodyStartRegex = /export default async function RootLayout[\\s\\S]*?\\)\\s*\\{/;\n const bodyMatch = content.match(bodyStartRegex);\n\n if (bodyMatch && bodyMatch.index !== undefined) {\n const bodyOpenBrace = bodyMatch.index + bodyMatch[0].length - 1;\n const logic = `\n const { locale } = await params;\n\n if (!hasLocale(routing.locales, locale)) {\n notFound();\n }\n\n setRequestLocale(locale);\n\n const messages = await getMessages();\n`;\n content = content.slice(0, bodyOpenBrace + 1) + logic + content.slice(bodyOpenBrace + 1);\n }\n\n // 3. Update RootProvider usage\n content = content.replace(\n /<RootProvider>/,\n '<RootProvider locale={locale} messages={messages}>',\n );\n\n // 4. Update html lang\n content = content.replace(/<html lang=\"en\"/, '<html lang={locale}');\n }\n\n await writeFile(destLayoutPath, content);\n await deleteFile(rootLayoutPath);\n }\n\n // Move Page\n if (fileExists(rootPagePath)) {\n const destPagePath = path.join(localeDir, 'page.tsx');\n let content = await readFile(rootPagePath);\n\n // Add imports\n if (!content.includes('next-intl')) {\n content =\n `import { SupportedLocale } from '@/types/i18n';\nimport { setRequestLocale } from 'next-intl/server';\n` + content;\n }\n\n // Update Page signature\n content = content.replace(\n /export default function Home\\(\\)/,\n `type Props = {\n params: Promise<{ locale: string }>;\n};\n\nexport default async function Home(props: Props)`,\n );\n\n // Inject logic\n const bodyOpenBrace = content.indexOf('export default async function Home(props: Props) {');\n if (bodyOpenBrace !== -1) {\n const logic = `\n const locale = (await props.params).locale as SupportedLocale;\n setRequestLocale(locale);\n`;\n const braceIndex = content.indexOf('{', bodyOpenBrace);\n content = content.slice(0, braceIndex + 1) + logic + content.slice(braceIndex + 1);\n }\n\n await writeFile(destPagePath, content);\n await deleteFile(rootPagePath);\n }\n};\n", "import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport pc from 'picocolors';\nimport Enquirer from 'enquirer';\nimport { deleteDirectory, fileExists } from '../../../core/files';\nimport {\n installPackage,\n runScript,\n detectPackageManager,\n uninstallPackage,\n} from '../../../core/package-manager';\nimport { startSpinner } from '../../../config/spinner';\nimport { checkIsAlreadySetup, validateProjectStructure, HttpClientType } from './checks';\nimport { fetchAssets, copyHttpClientFiles, performFullCleanup } from './assets';\nimport {\n updateHttpIndex,\n updateUtilsIndex,\n updateTypesIndex,\n updateConfigIndex,\n migrateClientUsages,\n cleanupHttpTypes,\n removeHttpExports,\n} from './injectors';\n\ntype ClientType = 'fetch' | 'axios';\n\ninterface SetupAction {\n type: 'install' | 'add' | 'replace' | 'remove-one' | 'remove-both' | 'cancel';\n clients: ClientType[];\n fromClient?: ClientType; // For replace action\n}\n\nexport const setupHttpClient = async (projectPath: string): Promise<void> => {\n const spinner = startSpinner('Checking HTTP Client setup...');\n const tempDir = path.join(projectPath, '.next-maker-temp-http');\n\n try {\n // 1. Pre-check\n const { status, reason } = await checkIsAlreadySetup(projectPath);\n spinner.stop();\n\n const action = await determineAction(status, reason);\n\n if (action.type === 'cancel') {\n console.log(pc.yellow('Setup cancelled.'));\n return;\n }\n\n spinner.start(`Setting up HTTP client(s)...`);\n\n // 2. Validation\n await validateProjectStructure(projectPath);\n\n // 3. Fetch Assets\n await fetchAssets(tempDir, spinner);\n\n // 4. Execute action based on type\n if (action.type === 'replace' && action.fromClient) {\n // Replace: migrate imports before copying new files\n spinner.text = 'Migrating client usages...';\n await migrateClientUsages(projectPath, action.fromClient, action.clients[0]);\n }\n\n if (action.type !== 'remove-both' && action.type !== 'remove-one') {\n // Copy files for install/add/replace\n spinner.text = 'Copying client files...';\n const clientsToRemove =\n action.type === 'replace' && action.fromClient ? [action.fromClient] : undefined;\n await copyHttpClientFiles(projectPath, tempDir, action.clients, clientsToRemove);\n }\n\n if (action.type === 'remove-one' || action.type === 'remove-both') {\n // Remove specified clients\n spinner.text = 'Removing client files...';\n const { PROJECT_PATHS } = await import('../../../config/paths');\n for (const client of action.clients) {\n const clientPath = path.join(\n projectPath,\n client === 'fetch' ? PROJECT_PATHS.FETCH_CLIENT : PROJECT_PATHS.AXIOS_CLIENT,\n );\n await deleteDirectory(clientPath);\n }\n\n // Check if any clients remain\n const activeClients = getActiveClients(status, action);\n if (activeClients.length === 0) {\n spinner.text = 'Performing full cleanup...';\n await performFullCleanup(projectPath);\n await removeHttpExports(projectPath);\n }\n }\n\n // 5. Update exports in http/index.ts\n const activeClients = getActiveClients(status, action);\n\n // Only update exports if there are active clients remaining\n if (activeClients.length > 0) {\n spinner.text = 'Configuring client...';\n await updateHttpIndex(projectPath, activeClients);\n await updateUtilsIndex(projectPath);\n await updateTypesIndex(projectPath);\n await updateConfigIndex(projectPath);\n }\n\n // Always cleanup types (even if removing both, we need to strip client-specific types from the preserved http.types.ts)\n await cleanupHttpTypes(projectPath, activeClients);\n\n // 6. Dependency Management\n spinner.text = 'Managing dependencies...';\n const packageJsonPath = path.join(projectPath, 'package.json');\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Axios Management\n if (activeClients.includes('axios')) {\n if (!dependencies['axios']) {\n spinner.text = 'Installing Axios...';\n await installPackage(projectPath, 'axios');\n }\n } else {\n if (dependencies['axios']) {\n spinner.text = 'Uninstalling Axios...';\n await uninstallPackage(projectPath, 'axios');\n }\n }\n\n // React Secure Storage Management\n // Needed if ANY client exists (for token store), OR if used elsewhere (checked by file existence)\n const storageServicePath = path.join(projectPath, 'src/services/storage'); // Hardcoded path to match assets.ts usage\n const isStorageNeeded = activeClients.length > 0 || fileExists(storageServicePath);\n\n if (isStorageNeeded) {\n if (!dependencies['react-secure-storage']) {\n spinner.text = 'Installing react-secure-storage...';\n await installPackage(projectPath, 'react-secure-storage');\n }\n } else {\n if (dependencies['react-secure-storage']) {\n spinner.text = 'Uninstalling react-secure-storage...';\n await uninstallPackage(projectPath, 'react-secure-storage');\n }\n }\n\n // 7. Format Code\n spinner.text = 'Formatting code...';\n const packageManager = await detectPackageManager(projectPath);\n await runScript(projectPath, packageManager, 'format');\n\n spinner.succeed(pc.green(getSuccessMessage(action)));\n } catch (error) {\n spinner.fail('Failed to setup HTTP Client.');\n throw error;\n } finally {\n await deleteDirectory(tempDir);\n }\n};\n\nasync function determineAction(status: HttpClientType, reason?: string): Promise<SetupAction> {\n if (status === 'none') {\n // No clients exist - choose what to install\n const { choice } = await Enquirer.prompt<{ choice: string }>({\n type: 'select',\n name: 'choice',\n message: 'Which HTTP client(s) do you want to setup?',\n choices: [\n { name: 'fetch', message: 'Fetch (Native)' },\n { name: 'axios', message: 'Axios' },\n { name: 'both', message: 'Both (Fetch + Axios)' },\n ],\n });\n\n if (choice === 'both') {\n return { type: 'install', clients: ['fetch', 'axios'] };\n }\n return { type: 'install', clients: [choice as ClientType] };\n }\n\n if (status === 'fetch') {\n // Only fetch exists\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: `${reason}. What would you like to do?`,\n choices: [\n { name: 'cancel', message: 'Keep Fetch only (cancel)' },\n { name: 'add', message: 'Add Axios (have both)' },\n { name: 'replace', message: 'Replace with Axios only' },\n { name: 'remove', message: 'Remove Fetch' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'add') return { type: 'add', clients: ['axios'] };\n if (action === 'replace') return { type: 'replace', clients: ['axios'], fromClient: 'fetch' };\n if (action === 'remove') return { type: 'remove-one', clients: ['fetch'] };\n }\n\n if (status === 'axios') {\n // Only axios exists\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: `${reason}. What would you like to do?`,\n choices: [\n { name: 'cancel', message: 'Keep Axios only (cancel)' },\n { name: 'add', message: 'Add Fetch (have both)' },\n { name: 'replace', message: 'Replace with Fetch only' },\n { name: 'remove', message: 'Remove Axios' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'add') return { type: 'add', clients: ['fetch'] };\n if (action === 'replace') return { type: 'replace', clients: ['fetch'], fromClient: 'axios' };\n if (action === 'remove') return { type: 'remove-one', clients: ['axios'] };\n }\n\n // Both exist\n console.log(pc.yellow(`\u2716 ${reason}`));\n const { action } = await Enquirer.prompt<{ action: string }>({\n type: 'select',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n { name: 'cancel', message: 'Keep both (cancel)' },\n { name: 'remove-fetch', message: 'Remove Fetch (keep Axios)' },\n { name: 'remove-axios', message: 'Remove Axios (keep Fetch)' },\n { name: 'remove-both', message: 'Remove both' },\n ],\n });\n\n if (action === 'cancel') return { type: 'cancel', clients: [] };\n if (action === 'remove-fetch') return { type: 'remove-one', clients: ['fetch'] };\n if (action === 'remove-axios') return { type: 'remove-one', clients: ['axios'] };\n if (action === 'remove-both') return { type: 'remove-both', clients: ['fetch', 'axios'] };\n\n return { type: 'cancel', clients: [] };\n}\n\nfunction getActiveClients(status: HttpClientType, action: SetupAction): ClientType[] {\n if (action.type === 'install') {\n return action.clients;\n }\n\n if (action.type === 'add') {\n const existing: ClientType[] = status === 'fetch' ? ['fetch'] : ['axios'];\n return [...existing, ...action.clients];\n }\n\n if (action.type === 'replace') {\n return action.clients;\n }\n\n if (action.type === 'remove-one') {\n if (status === 'both') {\n return action.clients[0] === 'fetch' ? ['axios'] : ['fetch'];\n }\n return [];\n }\n\n return [];\n}\n\nfunction getSuccessMessage(action: SetupAction): string {\n if (action.type === 'install') {\n const names = action.clients.map((c) => (c === 'fetch' ? 'Fetch' : 'Axios')).join(' + ');\n return `HTTP Client (${names}) setup successfully!`;\n }\n\n if (action.type === 'add') {\n const name = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `${name} client added successfully! Both clients are now available.`;\n }\n\n if (action.type === 'replace') {\n const from = action.fromClient === 'fetch' ? 'Fetch' : 'Axios';\n const to = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `Replaced ${from} with ${to} successfully! Imports automatically migrated.`;\n }\n\n if (action.type === 'remove-one') {\n const name = action.clients[0] === 'fetch' ? 'Fetch' : 'Axios';\n return `${name} client removed successfully!`;\n }\n\n if (action.type === 'remove-both') {\n return 'Both HTTP clients removed successfully!';\n }\n\n return 'HTTP Client setup completed!';\n}\n", "import path from 'node:path';\nimport { fileExists } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\n\nexport type HttpClientType = 'fetch' | 'axios' | 'none' | 'both';\n\nexport interface HttpClientSetupStatus {\n status: HttpClientType;\n reason?: string;\n}\n\nexport const checkIsAlreadySetup = async (projectPath: string): Promise<HttpClientSetupStatus> => {\n const fetchClientPath = path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT_FILE);\n const axiosClientPath = path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT_FILE);\n\n const hasFetch = fileExists(fetchClientPath);\n const hasAxios = fileExists(axiosClientPath);\n\n if (hasFetch && hasAxios) {\n return { status: 'both', reason: 'Both Fetch and Axios clients are detected' };\n }\n\n if (hasFetch) {\n return { status: 'fetch', reason: 'Fetch client is already setup' };\n }\n\n if (hasAxios) {\n return { status: 'axios', reason: 'Axios client is already setup' };\n }\n\n return { status: 'none' };\n};\n\nexport const validateProjectStructure = async (projectPath: string): Promise<void> => {\n const requiredPaths = [\n path.join(projectPath, 'src/lib'),\n path.join(projectPath, 'src/types'),\n path.join(projectPath, 'src/lib/config'),\n ];\n\n const missingPaths = requiredPaths.filter((p) => !fileExists(p));\n\n if (missingPaths.length > 0) {\n throw new Error(\n `Invalid project structure. Missing directories:\\n${missingPaths.map((p) => `- ${p}`).join('\\n')}`,\n );\n }\n};\n", "import path from 'node:path';\nimport degit from 'degit';\nimport { copyFile, deleteDirectory, fileExists, readFile, writeFile } from '../../../core/files';\nimport { PROJECT_PATHS } from '../../../config/paths';\nimport { Ora } from 'ora';\nimport fs from 'node:fs/promises';\n\nexport const fetchAssets = async (tempDir: string, spinner: Ora): Promise<void> => {\n spinner.text = 'Downloading assets from starter repository...';\n const emitter = degit('teispace/nextjs-starter', {\n cache: false,\n force: true,\n verbose: false,\n });\n await emitter.clone(tempDir);\n};\n\nexport const copyHttpClientFiles = async (\n projectPath: string,\n tempDir: string,\n clients: ('fetch' | 'axios')[],\n removeClients?: ('fetch' | 'axios')[],\n): Promise<void> => {\n const httpUtilsPath = path.join(projectPath, PROJECT_PATHS.HTTP_UTILS);\n const tempHttpUtilsPath = path.join(tempDir, PROJECT_PATHS.HTTP_UTILS);\n\n // 1. Copy Common Files\n // src/types/errors\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.ERRORS_DIR),\n path.join(projectPath, PROJECT_PATHS.ERRORS_DIR),\n { recursive: true },\n );\n\n // src/lib/config/app-apis.ts\n const appApisPath = path.join(projectPath, PROJECT_PATHS.APP_APIS);\n if (!fileExists(appApisPath)) {\n await copyFile(path.join(tempDir, PROJECT_PATHS.APP_APIS), appApisPath);\n }\n\n // src/lib/config/constants.ts (contains API_RESPONSE_DATA_KEY)\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (!fileExists(constantsPath)) {\n await copyFile(path.join(tempDir, PROJECT_PATHS.CONSTANTS), constantsPath);\n } else {\n // Ensure API_RESPONSE_DATA_KEY exists if file is kept\n let content = await readFile(constantsPath);\n let modified = false;\n\n if (!content.includes('API_RESPONSE_DATA_KEY')) {\n content += \"\\nexport const API_RESPONSE_DATA_KEY = 'data';\\n\";\n modified = true;\n }\n\n if (!content.includes('SAVE_AUTH_TOKENS')) {\n content += '\\nexport const SAVE_AUTH_TOKENS = false;\\n';\n modified = true;\n }\n\n if (modified) {\n await writeFile(constantsPath, content);\n }\n }\n\n // src/services/storage (needed by token-store.ts) - only if doesn't exist\n const storageServicePath = path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE);\n if (!fileExists(storageServicePath)) {\n await fs.cp(path.join(tempDir, PROJECT_PATHS.STORAGE_SERVICE), storageServicePath, {\n recursive: true,\n });\n }\n\n // Restore common and utility types (needed for http types)\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.COMMON_TYPES_DIR),\n path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR),\n { recursive: true },\n );\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.UTILITY_TYPES_DIR),\n path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR),\n { recursive: true },\n );\n\n // 2. Copy HTTP Shared Utilities\n // token-store.ts\n await copyFile(\n path.join(tempHttpUtilsPath, 'token-store.ts'),\n path.join(httpUtilsPath, 'token-store.ts'),\n );\n\n // client-utils.ts\n await copyFile(\n path.join(tempHttpUtilsPath, 'client-utils.ts'),\n path.join(httpUtilsPath, 'client-utils.ts'),\n );\n\n // 3. Remove specified clients if requested\n if (removeClients && removeClients.length > 0) {\n for (const client of removeClients) {\n const clientPath = path.join(\n projectPath,\n client === 'fetch' ? PROJECT_PATHS.FETCH_CLIENT : PROJECT_PATHS.AXIOS_CLIENT,\n );\n await deleteDirectory(clientPath);\n }\n }\n\n // 4. Copy specified client(s)\n for (const client of clients) {\n if (client === 'fetch') {\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.FETCH_CLIENT),\n path.join(projectPath, PROJECT_PATHS.FETCH_CLIENT),\n { recursive: true },\n );\n } else {\n await fs.cp(\n path.join(tempDir, PROJECT_PATHS.AXIOS_CLIENT),\n path.join(projectPath, PROJECT_PATHS.AXIOS_CLIENT),\n { recursive: true },\n );\n }\n }\n\n // 5. Copy/Update http/index.ts\n await copyFile(path.join(tempHttpUtilsPath, 'index.ts'), path.join(httpUtilsPath, 'index.ts'));\n\n // 6. Copy http.types.ts\n await copyFile(\n path.join(tempDir, PROJECT_PATHS.HTTP_TYPES),\n path.join(projectPath, PROJECT_PATHS.HTTP_TYPES),\n );\n};\n\nexport const performFullCleanup = async (projectPath: string): Promise<void> => {\n const { isFileUsed, isStringUsed } = await import('./injectors');\n\n // 1. Remove Directories (Unconditional for HTTP utils as they are client-specific)\n await deleteDirectory(path.join(projectPath, PROJECT_PATHS.HTTP_UTILS));\n\n // Check storage service usage before deletion\n const storageServicePath = path.join(projectPath, PROJECT_PATHS.STORAGE_SERVICE);\n if (fileExists(storageServicePath)) {\n // Check if SecureStorageService is used anywhere else (excluding the service itself)\n // Note: HTTP_UTILS is already deleted, so we don't need to exclude it.\n const isUsed = await isStringUsed(projectPath, 'SecureStorageService', [storageServicePath]);\n if (!isUsed) {\n await deleteDirectory(storageServicePath);\n }\n }\n\n // 2. Smart Cleanup for Shared Files\n\n // User requested to keep app-apis.ts even if unused\n // const appApisPath = path.join(projectPath, PROJECT_PATHS.APP_APIS);\n // const configIndexPath = path.join(projectPath, PROJECT_PATHS.CONFIG_INDEX);\n // await deleteIfUnused(...)\n\n // Check constants.ts - Check for 'API_RESPONSE_DATA_KEY' symbol usage\n const constantsPath = path.join(projectPath, PROJECT_PATHS.CONSTANTS);\n if (fileExists(constantsPath)) {\n let content = await readFile(constantsPath);\n let modified = false;\n\n // Check API_RESPONSE_DATA_KEY\n const isApiKeyUsed = await isStringUsed(projectPath, 'API_RESPONSE_DATA_KEY', [constantsPath]);\n if (!isApiKeyUsed) {\n content = content.replace(/export const API_RESPONSE_DATA_KEY = .*;\\n?/g, '');\n modified = true;\n }\n\n // Check SAVE_AUTH_TOKENS\n const isAuthTokenUsed = await isStringUsed(projectPath, 'SAVE_AUTH_TOKENS', [constantsPath]);\n if (!isAuthTokenUsed) {\n content = content.replace(/export const SAVE_AUTH_TOKENS = .*;\\n?/g, '');\n modified = true;\n }\n\n if (modified) {\n // Clean up extra newlines if any\n content = content.replace(/\\n\\s*\\n/g, '\\n\\n').trim() + '\\n';\n await writeFile(constantsPath, content);\n }\n }\n\n // Check errors directory\n const errorsDir = path.join(projectPath, PROJECT_PATHS.ERRORS_DIR);\n if (fileExists(errorsDir)) {\n // Check if any file in errors dir is used\n const errorFiles = await fs.readdir(errorsDir);\n let isAnyErrorUsed = false;\n\n for (const file of errorFiles) {\n const name = path.parse(file).name; // e.g. 'api-error'\n if (await isFileUsed(projectPath, name, [path.join(errorsDir, file)])) {\n isAnyErrorUsed = true;\n break;\n }\n }\n\n if (!isAnyErrorUsed) {\n await deleteDirectory(errorsDir);\n }\n }\n\n // 3. Remove http.types.ts\n // User requested to keep http.types.ts\n // const httpTypesPath = path.join(projectPath, PROJECT_PATHS.HTTP_TYPES);\n // if (fileExists(httpTypesPath)) {\n // await fs.unlink(httpTypesPath);\n // }\n\n // 4. Cleanup Types Directories if empty\n // Check common types\n const commonTypesPath = path.join(projectPath, PROJECT_PATHS.COMMON_TYPES_DIR);\n if (fileExists(commonTypesPath)) {\n const files = await fs.readdir(commonTypesPath);\n if (files.length === 0) {\n await deleteDirectory(commonTypesPath);\n }\n }\n\n // Check utility types\n const utilityTypesPath = path.join(projectPath, PROJECT_PATHS.UTILITY_TYPES_DIR);\n if (fileExists(utilityTypesPath)) {\n const files = await fs.readdir(utilityTypesPath);\n if (files.length === 0) {\n await deleteDirectory(utilityTypesPath);\n }\n }\n};\n", "import { Command } from 'commander';\nimport { registerAppCommand } from './app';\nimport { registerFeatureCommand } from './feature';\nimport { registerSliceCommand } from './slice';\nimport { registerServiceCommand } from './service';\nimport { registerSetupCommand } from './setup';\n\nexport const registerCommands = (program: Command) => {\n registerAppCommand(program);\n registerSetupCommand(program);\n registerFeatureCommand(program);\n registerSliceCommand(program);\n registerServiceCommand(program);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fs", "path", "existsSync", "readFile", "writeFile", "copyFile", "deleteFile", "deleteDirectory", "updateJson", "fileExists", "init_files", "__esmMin", "filePath", "content", "source", "destination", "dirPath", "update", "json", "updatedJson", "paths_exports", "__export", "PROJECT_PATHS", "init_paths", "__esmMin", "injectors_exports", "__export", "cleanupHttpTypes", "isFileUsed", "isStringUsed", "migrateClientUsages", "removeHttpExports", "updateConfigIndex", "updateHttpIndex", "updateTypesIndex", "updateUtilsIndex", "path", "exec", "promisify", "execAsync", "init_injectors", "__esmMin", "init_files", "init_paths", "projectPath", "clients", "httpIndexPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "writeFile", "utilsIndexPath", "typesIndexPath", "configIndexPath", "httpTypesPath", "fromClient", "toClient", "fromName", "toName", "fromPath", "toPath", "srcPath", "grepCommand", "stdout", "filePaths", "f", "filePath", "modified", "namedImportRegex", "defaultImportRegex", "usageRegex", "standaloneRegex", "error", "commonTypesDir", "commonIndexPath", "commonContent", "importPath", "excludePaths", "match", "absoluteMatchPath", "exclude", "searchString", "Command", "path", "pc", "ora", "startSpinner", "text", "options", "spinner", "Enquirer", "prompt", "promptForProjectDetails", "initialName", "response", "value", "answers", "baseUrl", "init_files", "exec", "promisify", "execAsync", "initializeGit", "cwd", "gitRemote", "pushToRemote", "remoteBranch", "error", "exec", "promisify", "execAsync", "installDependencies", "cwd", "manager", "command", "error", "runScript", "script", "getPackageManager", "userAgent", "detectPackageManager", "existsSync", "path", "installPackages", "packages", "getInstallCommand", "installPackage", "packageName", "uninstallPackages", "getUninstallCommand", "uninstallPackage", "pc", "colorMap", "s", "print", "message", "color", "colorFn", "text", "error", "message", "print", "logError", "log", "message", "print", "printBanner", "setupCancellationHandlers", "options", "logger", "m", "exitOnCancel", "onCancel", "onUncaught", "err", "onRejection", "reason", "capitalize", "str", "kebabToCamel", "_", "letter", "kebabToPascal", "ora", "spinner", "degit", "cloneTemplate", "projectPath", "spinner", "startSpinner", "degit", "error", "init_files", "path", "init_paths", "PACKAGES", "configurePackageJson", "projectPath", "answers", "spinner", "startSpinner", "gitRemote", "gitHomepage", "gitIssues", "updateJson", "path", "PROJECT_PATHS", "pkg", "PACKAGES", "error", "init_files", "path", "init_paths", "init_injectors", "cleanupFeatures", "projectPath", "answers", "spinner", "startSpinner", "cleanupHttpClient", "cleanupSecureStorage", "cleanupRedux", "cleanupDarkMode", "cleanupI18n", "cleanupLicense", "cleanupChangelog", "cleanupConfig", "error", "httpUtilsPath", "path", "PROJECT_PATHS", "keepSecureStorage", "deleteDirectory", "writeFile", "deleteFile", "cleanupHttpTypes", "utilsIndexPath", "fileExists", "content", "readFile", "configIndexPath", "constantsPath", "typesIndexPath", "httpTypesPath", "typesContent", "providersIndexPath", "providersIndexContent", "pagesToClean", "pagePath", "globalsCssPath", "cssContent", "layoutPath", "layoutContent", "nextConfigPath", "configContent", "counterComponentPath", "init_files", "init_paths", "path", "generateRootProvider", "projectPath", "answers", "imports", "providers", "rootProviderContent", "content", "writeFile", "PROJECT_PATHS", "generateLayout", "basicLayout", "counterImport", "counterComponent", "basicPage", "init_files", "init_paths", "path", "readdir", "setupDevTools", "projectPath", "answers", "setupPreCommitHooks", "setupCommitizen", "setupCiCd", "setupGithubTemplates", "setupCommunityFiles", "setupDocker", "setupReadme", "deleteDirectory", "path", "PROJECT_PATHS", "deleteFile", "updateJson", "pkg", "PACKAGES", "githubPath", "issueTemplatePath", "prTemplatePath", "replacePlaceholders", "content", "fileExists", "readFile", "writeFile", "files", "readdir", "file", "filePath", "allCommunityFiles", "envPath", "envContent", "updateEnvVar", "key", "value", "regex", "findReadmes", "dir", "entries", "entry", "fullPath", "allReadmes", "rootReadmePath", "readmePath", "simpleReadme", "registerAppCommand", "program", "name", "createApp", "initialName", "printBanner", "log", "answers", "promptForProjectDetails", "projectPath", "path", "fileExists", "pc", "spinner", "startSpinner", "performCleanup", "deleteDirectory", "cleanupErr", "handleSignal", "cloneTemplate", "configurePackageJson", "cleanupFeatures", "generateRootProvider", "generateLayout", "setupDevTools", "initializeGit", "installDependencies", "runScript", "envExamplePath", "envPath", "err", "pc", "path", "Enquirer", "prompt", "promptForFeatureDetails", "featureName", "hasRedux", "httpClient", "skipStore", "storeOption", "skipService", "serviceClient", "questions", "value", "answers", "readFile", "access", "path", "detectProjectSetup", "projectPath", "hasRedux", "hasAxios", "hasFetch", "hasI18n", "packageJsonPath", "packageJsonContent", "packageJson", "dependencies", "axiosClientPath", "fetchClientPath", "httpClient", "error", "featureExists", "featureName", "basePath", "featurePath", "writeFile", "mkdir", "path", "generateFeatureStructure", "options", "featurePath", "mkdir", "path", "generateComponentFile", "generateHookFile", "generateTypesFile", "generateIndexFile", "generateStoreFiles", "generateServiceFile", "generateComponentFile", "options", "featureName", "featurePath", "componentName", "kebabToPascal", "hookName", "content", "writeFile", "path", "generateHookFile", "createStore", "generateTypesFile", "generateStoreFiles", "persistStore", "camelName", "kebabToCamel", "sliceContent", "selectorsContent", "persistContent", "storeIndexContent", "generateServiceFile", "httpClient", "generateIndexFile", "createService", "readFile", "writeFile", "path", "registerFeatureInRootReducer", "projectPath", "featureName", "withPersist", "basePath", "path", "rootReducerPath", "content", "readFile", "camelName", "kebabToCamel", "reducerName", "importName", "importPath", "importStatement", "importRegex", "imports", "lastImport", "lastImportIndex", "combineReducersRegex", "match", "reducersContent", "newReducerEntry", "updatedReducersContent", "writeFile", "error", "registerSliceInRootReducer", "sliceName", "readFile", "writeFile", "path", "registerApiEndpoints", "options", "serviceName", "projectPath", "camelName", "kebabToCamel", "apiConfigPath", "path", "content", "readFile", "newEndpoint", "closingBracePattern", "insertPosition", "beforeClosing", "afterClosing", "hasExistingEndpoints", "needsComma", "updatedContent", "writeFile", "error", "registerFeatureCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "featureOptions", "promptForFeatureDetails", "basePath", "path", "featurePath", "featureExists", "generateFeatureStructure", "registerApiEndpoints", "registerFeatureInRootReducer", "displayPath", "importPath", "error", "pc", "path", "existsSync", "mkdir", "Enquirer", "prompt", "promptForSliceDetails", "sliceName", "persist", "noPersist", "questions", "value", "answers", "writeFile", "mkdir", "path", "generateSliceFiles", "options", "sliceName", "slicePath", "persistSlice", "mkdir", "componentName", "kebabToPascal", "camelName", "kebabToCamel", "generateTypesFile", "generateSliceFile", "generateSelectorsFile", "generatePersistFile", "generateIndexFile", "content", "writeFile", "path", "access", "path", "sliceExists", "projectPath", "sliceName", "basePath", "slicePath", "registerSliceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "sliceOptions", "promptForSliceDetails", "basePath", "featureName", "slicePath", "customPath", "path", "featureStorePath", "existsSync", "mkdir", "sliceExists", "generateSliceFiles", "registerSliceInRootReducer", "displayPath", "importPath", "error", "pc", "path", "existsSync", "mkdir", "enquirer", "promptForServiceDetails", "name", "axiosFlag", "fetchFlag", "availableClients", "serviceName", "input", "httpClient", "writeFile", "path", "generateServiceFiles", "options", "generateServiceFile", "serviceName", "servicePath", "httpClient", "camelName", "kebabToCamel", "content", "fileName", "writeFile", "path", "existsSync", "path", "serviceExists", "projectPath", "serviceName", "basePath", "servicePath", "registerServiceCommand", "program", "name", "options", "projectPath", "logError", "log", "pc", "spinner", "detection", "detectProjectSetup", "availableClients", "serviceOptions", "promptForServiceDetails", "basePath", "featureName", "servicePath", "customPath", "path", "existsSync", "mkdir", "serviceExists", "generateServiceFiles", "registerApiEndpoints", "displayPath", "importPath", "error", "pc", "Enquirer", "init_files", "path", "pc", "init_files", "init_paths", "path", "init_files", "init_paths", "path", "findLayoutPath", "projectPath", "possibleLayoutPaths", "PROJECT_PATHS", "p", "fileExists", "readFile", "checkIsAlreadySetup", "projectPath", "themeProviderPath", "path", "PROJECT_PATHS", "globalsCssPath", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "layoutPath", "findLayoutPath", "init_files", "init_paths", "path", "degit", "fetchAssets", "tempDir", "spinner", "copyThemeProvider", "projectPath", "themeProviderPath", "PROJECT_PATHS", "sourceProviderPath", "copyFile", "init_files", "init_paths", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "rootProviderContent", "useClientDirective", "hasUseClient", "returnMatch", "existingJsx", "updateGlobalsCss", "tempDir", "globalsCssPath", "sourceCssPath", "darkThemeCss", "sourceCss", "variantMatch", "themeMatch", "cssContent", "lastImportIndex", "endOfLineIndex", "updateLayout", "layoutPath", "layoutContent", "setupDarkTheme", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "layoutPath", "validateProjectStructure", "fetchAssets", "copyThemeProvider", "updateProvidersIndex", "updateRootProvider", "updateGlobalsCss", "updateLayout", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "pc", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "storePath", "path", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "providersIndexPath", "findLayoutPath", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyReduxFiles", "projectPath", "sourceProviderPath", "destProviderPath", "PROJECT_PATHS", "copyFile", "sourceStoreDir", "destStoreDir", "createCounterFeature", "sourceFeatureDir", "destFeatureDir", "counterComponentPath", "fileExists", "content", "readFile", "writeFile", "init_files", "init_paths", "path", "updateProvidersIndex", "projectPath", "providersIndexPath", "PROJECT_PATHS", "providersContent", "readFile", "writeFile", "updateRootProvider", "rootProviderPath", "fileExists", "rootProviderContent", "useClientDirective", "hasUseClient", "returnMatch", "existingJsx", "updatePage", "possiblePagePaths", "pagePath", "p", "pageContent", "lastDivIndex", "lastMainIndex", "insertIndex", "setupRedux", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyReduxFiles", "createCounterFeature", "updateProvidersIndex", "updateRootProvider", "updatePage", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "pc", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "i18nDir", "PROJECT_PATHS", "packageJsonPath", "fileExists", "packageJson", "readFile", "validateProjectStructure", "rootLayoutPath", "localeLayoutPath", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyI18nFiles", "projectPath", "sourceI18nDir", "destI18nDir", "PROJECT_PATHS", "sourceProxyPath", "destProxyPath", "copyFile", "sourceTypesPath", "destTypesPath", "sourceLocalesPath", "destLocalesPath", "init_files", "init_paths", "path", "fs", "updateNextConfig", "projectPath", "nextConfigPath", "PROJECT_PATHS", "fileExists", "content", "readFile", "exportDefaultRegex", "writeFile", "updateTypesIndex", "typesIndexPath", "updateConfigIndex", "configIndexPath", "updateRootProvider", "rootProviderPath", "useClientDirective", "hasUseClient", "componentRegex", "match", "returnMatch", "existingJsx", "newJsx", "migrateToLocaleStructure", "rootLayoutPath", "rootPagePath", "localeDir", "destLayoutPath", "metadataEndIndex", "insertPos", "functionBodyRegex", "functionMatch", "bodyStartRegex", "bodyMatch", "bodyOpenBrace", "deleteFile", "destPagePath", "logic", "braceIndex", "setupI18n", "projectPath", "spinner", "startSpinner", "tempDir", "path", "isSetup", "reason", "checkIsAlreadySetup", "validateProjectStructure", "fetchAssets", "copyI18nFiles", "updateNextConfig", "updateTypesIndex", "updateConfigIndex", "updateRootProvider", "migrateToLocaleStructure", "installPackage", "packageManager", "detectPackageManager", "runScript", "pc", "error", "deleteDirectory", "init_files", "path", "fs", "pc", "Enquirer", "init_files", "init_paths", "path", "checkIsAlreadySetup", "projectPath", "fetchClientPath", "PROJECT_PATHS", "axiosClientPath", "hasFetch", "fileExists", "hasAxios", "validateProjectStructure", "missingPaths", "p", "init_files", "init_paths", "path", "degit", "fs", "fetchAssets", "tempDir", "spinner", "copyHttpClientFiles", "projectPath", "clients", "removeClients", "httpUtilsPath", "PROJECT_PATHS", "tempHttpUtilsPath", "appApisPath", "fileExists", "copyFile", "constantsPath", "content", "readFile", "modified", "writeFile", "storageServicePath", "client", "clientPath", "deleteDirectory", "performFullCleanup", "isFileUsed", "isStringUsed", "errorsDir", "errorFiles", "isAnyErrorUsed", "file", "name", "commonTypesPath", "utilityTypesPath", "init_injectors", "setupHttpClient", "projectPath", "spinner", "startSpinner", "tempDir", "path", "status", "reason", "checkIsAlreadySetup", "action", "determineAction", "pc", "validateProjectStructure", "fetchAssets", "migrateClientUsages", "clientsToRemove", "copyHttpClientFiles", "PROJECT_PATHS", "client", "clientPath", "deleteDirectory", "getActiveClients", "performFullCleanup", "removeHttpExports", "activeClients", "updateHttpIndex", "updateUtilsIndex", "updateTypesIndex", "updateConfigIndex", "cleanupHttpTypes", "packageJsonPath", "packageJson", "fs", "dependencies", "installPackage", "uninstallPackage", "storageServicePath", "fileExists", "packageManager", "detectPackageManager", "runScript", "getSuccessMessage", "error", "choice", "Enquirer", "c", "from", "to", "prompt", "Enquirer", "registerSetupCommand", "program", "options", "log", "pc", "setupHttpClient", "setupDarkTheme", "setupRedux", "setupI18n", "feature", "error", "spinner", "logError", "registerCommands", "program", "registerAppCommand", "registerSetupCommand", "registerFeatureCommand", "registerSliceCommand", "registerServiceCommand", "originalEmitWarning", "warning", "_type", "_code", "_ctor", "main", "setupCancellationHandlers", "m", "error", "program", "Command", "registerCommands", "err", "message"]
|
|
7
7
|
}
|